; Uploaded to simtel-20 by Ralph Hyre (ralphw@c.cs.cmu.edu) ; Sent to Ralph by Chris Peck (chris@bingvaxb.bitnet) ; You will need one of the follwing items to use these drivers: ; the PCPI OEM package (bucks involved - order from PCPI) ; the assembled output of the PCPI OEM package assembler. ; (this will be made available here as soon as I can assemble it) ; ;Here's the printer buffer I mentioned earlier - it ;may be the one that PCPI based their's on - All I ;know is that it appears to work with your 64K Ramdisk - ;I can't test it since I don't have a serial card for ;printing in my Apple right now (thought I'd wait for ;the Alphabits // to appear)....I got this off of the RCPM that ;Doug Laing runs in Garden Grove.... ; .TITLE "BUFFER.A65 - Native Apple Printer Buffer" .WIDTH 120 .LINES 80 ;BUFFER.A65 - Native Apple Printer Buffer ;***************************************** ; designed and coded by: (with help from WLS) ; Fred Meyer ; Videotunes, Inc. ; 311 Ocean View Ave. ; Santa Cruz, CA 95062 ; ; 03/16/83 CREATED ; 04/14/83 Cleaned up code a bit ; 04/15/83 Added empty flag condition for increased speed ; 05/10/83 Added state flag to prevent recursion with POLL ; 06/14/83 Big overhaul for use with new SOFTVIDEO.DVR ; 06/15/83 Fixed bank switch bug and BANKPTR bug. ; Added conditional assembly for patching ; POLLROUTINE. This allows output of buffer to ; equal the speed of input.(approx 9600) ; 04/17/84 Fixed one more interrupt bug and a bug in the ; pollroutine initialization section. ;***************************************** ;This driver uses available main memory as a printer buffer. If a 16K ;language card is available in slot #0 then it will be included ;automatically in the buffer allocation. The size of the buffer ;allocation is printed to the console on cold boot and also upon ;resetting the buffer with . This message can be supressed ;by changing conditional equate SIZEMSG. The POLLROUTINE patch can also ;be disabled with the conditional equate POLLPATCH. ; ;After pressing RESET, another Apple key will be recognized for approximately ;1/2 second. The following command sequences are recognized: ; performs normally and executes a CP/M warm boot ; followed by clears the printer buffer and warm boots the sytem ; followed by enters the Apple monitor ; followed by executes a cold boot of the system. ; leaves the monitor and enters CP/M command level ; followed by any other key is ignored by the system .NOLIST .INCLUDE DRVREQUS.A65 ;SPECIFY DRIVE IF NECESSARY ON YOUR SYSTEM .LIST TRUE: .EQU 0FFH FALSE: .EQU 0 ;----------------USER EQUATES , Change if necessary------------------- POLLPATCH: .EQU TRUE ;PATCH POLLROUTINE FOR FASTER OPERATION SIZEMSG: .EQU TRUE ;ENABLE PRINTING OF BUFFER SIZE MESSAGE SLOT: .EQU 1 ;SLOT # OF PRINTER CARD CONSOLE: .EQU 3 ;CHARACTER DEV# & SLOT# FOR THE CONSOLE CANCEL: .EQU 17 ;COMMAND NUMBER FOR PRINT CANCELLING CONOUT: .EQU WCDEV+(CONSOLE*8) ;Console output vector ;Also see temporary data area below for printer device specification ;------------------------Page 0 Equates------------------------------- BASEP0: .QUERY "ENTER BASE OF PAGE 0: " POINTER: .EQU BASEP0 ;INPUT CHARACTER POINTER POINTER2: .EQU BASEP0+2 ;OUTPUT CHARACTER POINTER DATA: .EQU BASEP0+4 ;TEMPORARY OUTPUT DATA STORAGE LSTFLAG: .EQU BASEP0+5 ;BUFFER BUSY FLAG FF=BUSY 0=NOT BUSY BANKPTR: .EQU BASEP0+6 ;BANK INPUT POINTER LCARD: .EQU BASEP0+7 ;LANGAUGE CARD FLAG FF=LC PRESENT 0=NOT FOUND BANKPTR2: .EQU BASEP0+8 ;BANK OUTPUT POINTER ; 0=MAIN MEM 1=LC BANK1 2=LC BANK2 COUNTER: .EQU BASEP0+9 ;KEYPRESS COUNTDOWN REGISTER INDEX: .EQU BASEP0+11 ;INDEX TO MESSAGE STRING STATE: .EQU BASEP0+12 ;POLLING RECURSION FLAG FF=PREVENT 0=PERMIT EMPTY: .EQU BASEP0+13 ;BUFFER EMPTY FLAG 0=EMPTY <>0=NOT EMPTY LENP0: .EQU 14 ;14 BYTES OF PAGE 0 ;---------------------HEADER FOR RELOCATION--------------------------- TOP: .WORD 0 ;IF THIS WORD IS 0 THEN ; RELOCATABLE DRIVER ; AND A RELOCATING BIT MAP IS EXPECTED ;ELSE ; THE DRIVER STORED WHERE INDICATED .WORD ((BOTTOM-TOP)+0FFH) AND 0FF00H ;LENGTH OF THIS CODE ; TO NEXT PAGE BOUNDRY .BYTE LENP0 ;THIS IS THE NUMBER OF PAGE 0 BYTES ; REQUIRED. IF ITS NO ZERO THEN A RELOCATING ; BIT MAP IS EXPECTED FOR PAGE 0 .BYTE 0 ;TAG FIELD CURDEV: .WORD 01FH ;DEVICE NUMBER (01FH=DEV#31=CHAR DEV#15) .WORD 1 ;NUMBER OF DEVICES THIS DRIVER WILL SERVICE .WORD INITENTRY ;INIT ENTRY POINT .WORD INENTRY ;INPUT ENTRY POINT .WORD OUTENTRY ;OUTPUT ENTRY POINT .WORD OTHERENTRY ;OTHER ENTRY POINT .WORD POLLENTRY ;POLL ENTRY POINT ; 0 IF NO POLLING REQUIRED .WORD 8 ;VERSION NUMBER NAME: .BYTE 14,"PRINTER BUFFER",0 ;----------------TEMPORARY DATA SPACE-------------------------------- ;Put here to assure indirect jumps do not cross page boundries DEVICE: .BYTE 1 ;CHARACTER DEVICE # FOR THE BUFFER TO PATCH - ; THIS IS NORMALLY 1 FOR CHARACTER DEVICE #1 ; WHICH IS THE LPT: DEVICE. TO PATCH THE UL1: ; DEVICE CHANGE TO 4. ; Set proper device in MESSAGE below to correspond to your choice. .IF POLLPATCH POLLVEC: .BLOCK 2 ;CONTAINS JUMP ADDRESS FROM POLLROUTINE .ENDC BUFINDEX: .BLOCK 1 ;TEMPORARY PRTINDEX: .BLOCK 1 ;TEMPORARY RESETVEC: .BLOCK 2 ;ADDRESS TO CONTINUE AFTER RESET PROCESSING VECTOR: .WORD RESET ;ADDRESS OF CLEARBUFFER ROUTINE IDX: .BLOCK 1 ;TEMPORARY CNT: .BLOCK 1 ;TEMPORARY OTHERVEC: .BLOCK 2 ;OTHERENTRY JUMP FOR DEVICE# ;FF=VALUE DURING A COLD BOOT 0=VALUE AFTER A COLD BOOT MESSAGE: .BYTE " ",0,".25",0,".5",0,".75",0,"K Printer Buffer Reset" .BYTE " - LPT: buffered",0FFH ;************************************* ;ROUTINE: INITENTRY ;PURP: INITIALIZE ;ENTRY: NONE ;USED: ALL ;************************************* INITENTRY: LDA #0FFH STA IDX ;TEMPORARY FIRST TIME THROUGH FLAG ;------------------------ Begin Vector Patching -------------------------- LDA CURDEV ;GET DEV# OF THIS DRIVER AND #0FH ;MODULO 16 ASL A ;TIMES 2 ASL A ;TIMES 4 ASL A ;TIMES 8 STA BUFINDEX LDA DEVICE ;GET PRINTER DEVICE# AND #0FH ;MODULO 16 ASL A ;TIMES 2 ASL A ;TIMES 4 ASL A ;TIMES 8 STA PRTINDEX TAY LDA OCDEV,Y ;Printer 'Other' Device Pointer STA OTHERVEC INY LDA OCDEV,Y STA OTHERVEC+1 LDX BUFINDEX LDY PRTINDEX LDA OCDEV,X ;Current Device 'Other' Pointer STA OCDEV,Y INX INY LDA OCDEV,X STA OCDEV,Y LDY PRTINDEX LDA WCDEV,Y ;Printer 'Char-out' Device Pointer STA OUTPUT+1 INY LDA WCDEV,Y STA OUTPUT+2 LDX BUFINDEX LDY PRTINDEX LDA WCDEV,X ;Current Device 'Char-out' Pointer STA WCDEV,Y INX INY LDA WCDEV,X STA WCDEV,Y LDA AOTHRRESET ;Store jump address into this driver STA RESETVEC LDA AOTHRRESET+1 STA RESETVEC+1 LDA VECTOR ;Patch code which the reset routine STA AOTHRRESET ;of CP65 jumps to after 1/2 second LDA VECTOR+1 ;so it points RESET routine of this STA AOTHRRESET+1 ;driver. .IF POLLPATCH LDA POLLROUTINE+1 ;GET POLLROUTINE JUMP ADDRESS STA POLLVEC ; AND SAVE IN VARIABLE POLLVEC LDA POLLROUTINE+2 STA POLLVEC+1 LDA CURDEV ;GET BUFFER DEVICE # ASL A ;TIMES 2 TAX LDA POLLTBL,X ;INSTALL POLLENTRY ADDRESS OF THIS STA POLLROUTINE+1 ;BUFFER DRIVER INTO THE INX ;POLLROUTINE JUMP. LDA POLLTBL,X STA POLLROUTINE+2 .ENDC ;----------------------- End Vector Patching ------------------------ ;----------------- Begin Language Card Locator Code ----------------- LDA 0E000H PHA LDA 0C081H ;ENABLE ROM PLA PHA CMP 0E000H BNE NOFIND LDA 0C083H ;SELECT BANK2 R/W LDA 0C083H LDA #0A5H STA 0D000H CMP 0D000H BNE NOFIND LSR A STA 0D000H CMP 0D000H BNE NOFIND LDA 0C081H ;SELECT ROM WRITE ENABLE RAM LDA 0C081H LDA #0FFH ;Indicate LCard was found BNE FOUND ;branch unconditional NOFIND: LDA #0 FOUND: STA LCARD PLA CMP 0E000H BEQ INIT LDA 0C080H ;SELECT RAM READ BANK 2 ;---------------------- End Language Card locator code -------------------- ;------------------------ Begin Buffer Size Message ----------------------- INIT: LDA #0 STA STATE STA EMPTY ;SET BUFFER EMPTY FLAG TO SHOW EMPTY .IF SIZEMSG ;BEGIN CONDITIONAL SIZEMSG ############### SEC ; GENERAL INITIALIZATION ONLY (INIT2:) LDA HIMEM+1 ;GET SIZE IN PAGES OF AVAILABLE MEMORY SBC LOMEM+1 CLC ROR A ;Divide available pages by 4 to get "K" ROR A ;IF MSB=1 AND CARRY=0 then .25K additional ;IF MSB=0 AND CARRY=1 then .50K additional ;IF MSB=1 AND CARRY=1 then .75K additional PHA ;SAVE THE NUMBER, MSB MAY BE SET BMI K2575 ;IF MSB =1 MUST BE .75K OR .25K BCS K50 ;IF CARRY=1 and MSB=0 MUST BE .50K LDA #13 ;MUST BE EVEN "K", OFFSET 13 IN MESSAGE STRING BNE FRAC K50: LDA #6 ;MUST BE .50K, OFFSET 6 IN MESSAGE STRING BNE FRAC K2575: BCS K75 ;IF CARRY=1 MUST BE .75K LDA #2 ;MUST BE .25K, OFFSET 2 IN MESSAGE STRING BNE FRAC K75: LDA #9 ;MUST BE .75K, OFFSET 9 IN MESSAGE STRING FRAC: STA IDX ;INDEX INTO MESSAGE STRING PLA ;GET NUMBER BACK AND #7FH ;MASK OFF HI BIT IF SET LDX LCARD ;LANGUAGE CARD FLAG->0FFH IF LC PRESENT BPL CONVRT CLC ADC #16 ;Add 16K if language card is present CONVRT: LDY #30H ;Convert to 2 Ascii Digits LB1: SEC ; located at MESSAGE & MESSAGE+1 SBC #100 BCC LB2 INY BNE LB1 LB2: ADC #100 ;Hundreds character is in the Y register at ; this point. It is not used here, since LDY #30H ; 64 is the largest number which can be LB3: SEC ; converted from 8bits divided by 4. SBC #10 BCC LB4 INY BNE LB3 LB4: ADC #10 STY MESSAGE ORA #30H STA MESSAGE+1 ;----------Print Buffer Size Message on Console--------------- PRSIZE: LDA #0DH JSR CONSOLEOUT LDA #0FFH STA INDEX ;Reset string index PRINT: INC INDEX LDX INDEX ;Offset of fractional # in Message -1 LDA MESSAGE,X ;Message location BEQ SIZE ;Continue printing until a NULL is reached BMI INIT2 ;end of message was reached. JSR CONSOLEOUT ;Print Char in A register to DEVICE CLV BVC PRINT ;Unconditional Relative Jump SIZE: LDA IDX ;"First time through flag" BMI MSG ;Flag is set-go to phrase STA INDEX LDA #0FFH ;Set flag on Second Pass STA IDX BNE PRINT ;MUST BE A FRACTION TO PRINT MSG: LDA #13 ;Offset to phrase section of string STA INDEX BNE PRINT ;Unconditional relative jump .ENDC ;END CONDITIONAL SIZEMSG ############### ;------------------------ End Buffer Size Message ---------------------- ;---------------------- Begin General Initialization ------------------- INIT2: LDX #2 ;POINTER INDEX LDA LOMEM STA POINTER ;ADDRESS PTR TO LAST CHAR INTO BUFFER STA POINTER,X ;ADDRESS PTR TO LAST CHAR OUTPUT LDA LOMEM+1 STA POINTER+1 STA POINTER+1,X LDA #0 ;0=NO ERROR STA LSTFLAG STA BANKPTR STA BANKPTR,X RTS ;*********************************** ;ROUTINE: INENTRY: ;PURP: INPUT A CHARACTER ;ENTRY: Y = n0 ; X = Cn ; WHERE n IS THE SLOT NUMBER ;EXIT: A = CHARACTER ;USED: ALL ;*********************************** INENTRY: RTS ;*********************************** ;ROUTINE: OUTENTRY ;PURP: OUTPUT A CHARACTER TO THE DEVICE ;ENTRY: A = CHARACTER ; Y = n0 ; X = Cn ; WHERE n IS THE SLOT NUMBER ;EXIT: NONE ;USED: ALL ;************************************ OUTENTRY: STA DATA ;SAVE THE DATA LDX #0 ;INDEX VALUE FOR INPUT POINTER JSR SETUP LDX #2 STX EMPTY ;SET EMPTY FLAG TO SHOW NOT EMPTY LDA POINTER+1,X CMP POINTER+1 BNE STORECHAR LDA POINTER,X CMP POINTER BNE STORECHAR LDA BANKPTR ;SEE IF BANKS ARE EQUAL CMP BANKPTR,X BNE STORECHAR ;IF NOT STORE THE CHARACTER, ELSE...FULL ;The buffer must be full ==> So wait until printer can take a char LDA #0FFH STA LSTFLAG ;SET STATUS TO NOT READY WAIT: JSR POLLENTRY LDA LSTFLAG BMI WAIT ;WAIT UNTIL A CHARACTER IS PRINTED STORECHAR: LDA BANKPTR SEI ;DISABLE INTERRUPTS UNCONDITIONALLY JSR BANK ;SET UP PROPER BANK SWITCH LDA DATA LDX #0 STA (POINTER,X) TXA ;X=0 JSR BANK ;TURN OFF LC - TURN ON D000-FFFF ROMS CLI EXIT: RTS ;Return to caller-now at least one char is open ;*********************************** ;ROUTINE: OTHERENTRY ;PURP: HANDLE OTHER COMMANDS ;ENTRY: A = OTHER COMMAND ; X = N0 ; Y = CN ;EXIT: A = ERROR CODE ;USED: ALL ;*********************************** OTHERENTRY: CMP #0 BEQ OUTSTAT ;BRANCH IF OUTPUT STATUS COMMAND CMP #1 BEQ INSTAT ;BRANCH IF INTPUT STATUS COMMAND CMP #2 BEQ VIDEOON ;BRANCH IF VIDEO ON COMMAND CMP #3 BEQ APLEON ;BRANCH IF APPLE ON COMMAND CMP #4 BEQ WIDTH ;BRANCH IF WIDTH COMMAND CMP #SNDNAMECMD BEQ SENDNAME ;BRANCH IF SEND NAME COMMAND CMP #CANCEL BEQ CANCELCMD BNE ERROR ;BRANCH IF ERROR JMP INIT ;JUMP IF CANCEL PRINTING COMMAND ;ERROR BAD COMMAND ERROR: LDA #0FFH ;ELSE ERROR RTS CANCELCMD: JMP INIT ;RESET THE BUFFER SENDNAME: LDA NAME STA CNT JSR WR1Z80BYTE LDA #1 STA IDX LDA CNT BNE $LP CLC LDA #0 RTS $LP LDX IDX LDA NAME,X JSR WR1Z80BYTE INC IDX DEC CNT BNE $LP LDA #0 RTS OUTSTAT: LDA LSTFLAG ;IF LSTFLAG=FF THEN BUFFER IS FULL BMI CKSTAT ;FULL SO SEE IF PRINTER CAN TAKE A CHARACTER LDA #0FFH ;NOT FULL SO INDICATE READY RTS CKSTAT: LDA #0 ;Call the output status routine of the BEQ STAT ;printer driver. INSTAT: LDA #1 STAT: LDX #0C0H+SLOT LDY #SLOT*10H STATJMP: JMP (OTHERVEC) ;OTHERENTRY VECTOR VIDEOON: ;DO SOMETHING TO TURN ON YOUR VIDEO ; THIS IS PROBABLY NOTHING UNLESS THIS IS A CONSOLE DEVICE RTS APLEON: ;DO SOMETHING TO TURN ON THE APPLE VIDEO ON ; THIS IS PROBABLY NOTHING UNLESS THIS IS A CONSOLE DEVICE RTS WIDTH: ;RETURN THE WIDTH OF THIS DEVICE LDA #80 ;80 COLUMNS ? RTS ;*********************************** ;ROUTINE: POLLENTRY ;PURP: HANDLE POLLING, THIS ENTRY POINT ; IS CALLED PERIODICALY WHILE THE APPLE IS ; WAITING FOR A COMMAND FROM THE Z-80. THIS ; CODE SHOULD BE VERY SHORT AS THE Z-80 IS ; IGNORED WHILE THIS CODE IS BEING EXECUTED ;ENTRY: NONE ;EXIT: NONE ;USED: ALL ;*********************************** POLLENTRY: LDA EMPTY ;CHECK AND SEE IF BUFFER IS EMPTY BEQ RET ; IF SO DON'T WASTE ANY TIME HERE LDA STATE ;CHECK AND SEE IF POLLENTRY IS CALLING ITSELF BMI RET ; IF SO RETURN AND PREVENT RECURSION LDA #0FFH ; IF NOT SET FLAG FOR PROTECTION STA STATE ;SET STATE FLAG JSR CKSTAT ;CALL PRINTER STATUS VECTOR BPL ENDPOLL ;Not ready so leave routine LDX #2 LDA POINTER+1 ;IF INPUT AND OUTPUT POINTERS ARE EQUAL AND CMP POINTER+1,X ; IF BUFFER FULL FLAG IS NOT SET AND IF THE BNE SETJSR ; INPUT AND OUTPUT BANKS ARE EQUAL THEN LDA POINTER ; THE BUFFER MUST BE EMPTY - SO CALL THE CMP POINTER,X ; POLLING ROUTINE AND RESET EMPTY FLAG. BNE SETJSR ;NOT EQUAL - UPDATE THE POINTERS LDA BANKPTR CMP BANKPTR,X BNE SETJSR LDA LSTFLAG BPL BUFFEMPTY ;BUFFER IS NOT FULL-SO IT MUST BE EMPTY SETJSR: JSR SETUP ;UPDATE THE 16 BIT OUTPUT POINTER PRINTCHAR: LDA BANKPTR,X ;GET BANK # OF NEXT CHARACTER TO OUTPUT SEI ;DISABLE INTERRUPTS UNCONDITIONALLY JSR BANK ;SET THE BANK LDA (POINTER,X) ;GET THE CHARACTER PHA ;SAVE CHAR LDA #0 JSR BANK ;TURN OFF LC - TURN ON D000-FFFF ROM CLI PLA ;GET CHAR BACK LDX #0C0H+SLOT ;SLOT# OF PRINTER CARD LDY #SLOT*10H ;SLOT# OF PRINTER CARD OUTPUT: JSR 0000 ;Filled in at initial. with JSR to Device# out LDA #0 STA LSTFLAG ;RESET BUFFER FULL FLAG TO INDICATE NOT FULL ENDPOLL: LDA #0 STA STATE ;RESET RECURSION FLAG RET: .IF POLLPATCH JMP (POLLVEC) ;CONTINUE WITH NORMAL POLLING ROUTINE .ELSE RTS ;EXIT FROM POLLENTRY .ENDC BUFFEMPTY: LDA #0 ;SET BUFFER EMPTY FLAG TO SHOW EMPTY STA EMPTY ; TO SAVE TIME WHEN POLL IS CALLED NEXT TIME BEQ ENDPOLL BANK: ;On entry A=value of Bank to choose 0=Main Mem 1=LC Bank1 2=LC Bank2 BNE L30 ;If A<>0 continue LDA 0C082H ;Else... LDA 0C082H ; TURN ON ROM RTS L30: LSR A ;shift the 1's bit into carry BCC L31 ;If a<>1 continue LDA 0C08BH ;Else... LDA 0C08BH ; TURN ON BANK 1 RTS L31: LDA 0C083H ;a value of 2 is assumed here LDA 0C083H ;TURN ON BANK 2 (unconditionally) L32: RTS SETUP: ;On entry X=0 for Input pointer update X=2 for Output pointer update INC POINTER,X ;INCREMENT PTR ADDRESS BNE L10 INC POINTER+1,X L10: LDA LCARD BMI L11 ;IF MSB=1 THEN LANG CARD EXISTS LDA POINTER+1,X CMP HIMEM+1 BNE RETURN BEQ L40 ;RESET BACK TO LOMEM L11: LDA POINTER+1,X BNE L12 ;NOT=0 So continue ; LDA #0 ;IF=0 So last addr must have been FFH STA POINTER,X LDA #0D0H STA POINTER+1,X LDA #2 ;Set PTRs to Bank 2 of Lang Card STA BANKPTR,X L12: CMP HIMEM+1 BNE L13 ;IF=HIMEM so set PTR to Bank 1 of LC ; LDA #0 STA POINTER,X LDA #0D0H STA POINTER+1,X LDA #1 STA BANKPTR,X L13: CMP #0E0H BNE RETURN ;IF=0E0H maybe set PTR to Bank 0 LDA BANKPTR,X CMP #2 ;IF=0E0H of Bank 1 then ignore this point BNE RETURN L40: LDA LOMEM ;ELSE Set PTRs to Bank 0 STA POINTER,X LDA LOMEM+1 STA POINTER+1,X LDA #0 STA BANKPTR,X RETURN: RTS CONSOLEOUT: ;on entry A=character to print LDX #0C0H+CONSOLE ;Send character out to character device #3 LDY #CONSOLE*10H JMP (CONOUT) ;"CONSOLE OUT" ->Filled in at initialization ;---------------------- ;When RESET is pressed execution transfers to this point with the "A" register ;containing KEY value. RESET clears the keyboard strobe, so for a key ;to be recognized it must be pressed after RESET. RESET: ;ON ENTRY A=CHARACTER (if any) HI BIT SET MEANS VALID CHAR BPL NOCLEAR ;NO KEY WAS PRESSED TO CONTINUE RESET CYCLE AND #7FH ;MASK OFF HI ORDER BIT CMP #"C" ;="C" for 'Clear Printer Buffer' ? BNE NOCLEAR ;NOT A "C" SO CONTINUE RESET CYCLE BIT 0C010H ;..ELSE, CLEAR KEYBOARD STROBE JSR INIT ;..AND RESET THE PRINTER BUFFER NOCLEAR: LDA #0 STA STATE ;RESET STATE FLAG JSR BANK ;TURN OFF LC TURN ON ROMS JMP (RESETVEC) ;CONTINUE WITH RESET CYCLE IN CP65 ;------------------------ End Reset Key Command Processor----------------- BOTTOM: .END .WIDTH 96