; 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 <RESET C>.  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:

;   <RESET> performs normally and executes a CP/M warm boot
;   <RESET> followed by <C> clears the printer buffer and warm boots the sytem
;   <RESET> followed by <M> enters the Apple monitor
;   <RESET> followed by <R> executes a cold boot of the system.
;   <RESET> leaves the monitor and enters CP/M command level
;   <RESET> 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
