KB_NEW:                         ;INSTALL NEW KEYBOARD
        TPA
        PSH     A
        SEI
        BSR     GETP
        XGDX
        OS      UT$CPYB         ;COPY OLD VECTORS TO SAVEVCT
        BSR     GETP
        LDX     #NEWVCT
        OS      UT$CPYB         ;COPY NEW VECTORS IN
        PUL     A
        TAP
        RTS

KB_OLD:                         ;RESTORE OLD KEYBOARD
        TPA
        PSH     A
        SEI
        BSR     GETP
        OS      UT$CPYB         ;RESTORE OLD VECTORS
        PUL     A
        TAP
        RTS     

NEWVCT:
        .WORD   NEWPOLL,NEWTRAN,NEWTABL         ;ADDRESSES OF NEW ROUTINES
SAVEVCT:
        .WORD   0,0,0           ;6 BYTES TO SAVE OLD VECTORS IN.

GETP:   LDD     #6
        STD     UTW_S0:
        LDD     #BTA_POLL
        LDX     #SAVEVCT
        RTS


NEWPOLL:

;TURBO CHARGED KEYBOARD POLL ROUTINE
;CHECKS FOR A/C FIRST
;CHECKS FOR ANY KEY QUICKLY, THEN FINDS WHICH KEY WITH DOUBLE COUNTING
;A := KEY PRESSED (0-36, 0=NOKEY)
;KTABPOSN POINTS TO LAST CHAR IN EACH COLUMN IN TURN
;PRESERVES X

        TST     SCA_COUNTERRESET                        ;CLEAR COUNTER
        AIM     #<$FF->,KBB_STAT:
        CLR     A                                       ;NO KEY YET
        LDA     B,POB_PORT5:
        BPL     NOAC
        LDA     A,#36
RTS5:   RTS

NOAC:   STA     A,KBB_KNUM:     ;TABPOSN:=0
        PSH     A
        BSR     LOOKKEY         ;ZERO IF NO KEY FOUND
        PUL     A
        BEQ     ENDKYBD         ;BRANCH IF NO KEY FOUND
        LDA     B,#$40
        PSH     B
        DEC     B
        BRA     PP      

GOCOL:  PSH     B
PP:     PSH     A
1$:     TST     SCA_COUNTERCLOCK        ;CLOCK COUNTER B TIMES
        DEC     B
        BNE     1$
        BSR     LOOKKEY         ;B:= OFFSET IN COL (IF KEY FOUND)
        PUL     A
        BEQ     NOPSH           ;BRANCH IF NO KEY IN THIS COL
        ADD     B,KBB_KNUM:     
        TBA                     ;GOT KEY BUT MUST CHECK IF SHIFT
NOPSH:  LDA     B,KBB_KNUM:
        ADD     B,#5
        STA     B,KBB_KNUM:     ;POINT TO NEXT COL
        PUL     B
        LSR     B               ;SELECT NEXT COL
        BNE     GOCOL
ENDKYBD:
        RTS                             



LOOKKEY:

;B:=KEY OFFSET IN COL (1-5)
;B:=0 IF NOKEY IN THIS COL (OR JUST SHIFT)
;SETS KY_SHFT FLAG IF SHIFT PRESSED
;SETS KY_SHFT2 IF  PRESSED
;SETS KY_SHFT3 IF  PRESSED
;SETS Z ON B
;PRESERVES X

        LDA     B,#5
        LDA     A,POB_PORT5:
        ASL     A
NEXTROW:
        ASL     A               ;ROTATE KEY INTO CARRY
        BCC     GOTKEY          ;CARRY CLEAR IF KEY PRESSED
        DEC     B
        BNE     NEXTROW
        RTS

GOTKEY:                         ;B IS POSITION IN COL
        TST     KBB_SHFK        ;CLR IF SHIFT ENABLED
        BNE     13$             ;B IS NOT ZERO
        PSH     A
        LDA     A,KBB_KNUM:
        CMP     A,#25           ;IS IT COL 6 (COL CONTAINING SHIFT) ?
        BNE     11$             ;B IS NOT ZERO
        PUL     A
        DEC     B
        BEQ     10$             ;BRANCH IF B WAS 1 IE SHIFT

        PSH     B               ;ELSE CHECK IF SHIFT PRESSED AS WELL
1$:     ASL     A
        DEC     B
        BNE     1$
        PUL     B
        INC     B               ;RESTORE B
        BCS     13$             ;BRANCH IF C SET FROM ASL A

10$:    OIM     #KY_SHFT,KBB_STAT:
        TST     B
        RTS

11$:    CMP     A,#30           ;COL CONTAINING ,  ARROWS ?
        PUL     A
        BNE     13$             ;B IS NON-ZERO
        CMP     B,#4            ;LEFT ?
        BEQ     12$
        CMP     B,#5            ;RIGHT ?
        BNE     13$
        OIM     #KY_SHFT3,KBB_STAT:
        CLR     B               ;SET Z
        RTS
12$:
        OIM     #KY_SHFT2,KBB_STAT:
        CLR     B               ;SET Z
13$:    RTS     


NEWTRAN:

;TRANSLATE KEY NUMBER IN A (0-36) INTO ASCII KEY USING KBB_STAT
;SETS DPB_CUST APPROPRIATELY + REFRESHES CURSOR STATE
;SETS Z=1 IF A=0 (NOKEY)
;SETS KY_CPNM IF CAP OR NUM

        AIM     #<$FF-KY_CPNM>,KBB_STAT:
        TAB
        TST     KBB_STAT
        BPL     2$                      ;BRANCH IF CAN'T BE CAP OR NUM
        CMP     A,KBB_CAPK              ; - CAPS KEY
        BNE     1$
        EIM     #KY_CAPS,KBB_STAT:
        OIM     #KY_CPNM,KBB_STAT:
        CLR     B
1$:     CMP     A,KBB_NUMK              ; - NUM KEY
        BNE     2$
        EIM     #KY_NUMB,KBB_STAT:
        OIM     #KY_CPNM,KBB_STAT:
        CLR     B
2$:     BSR     KCUST                   ;FIX CURSOR STATE FOR KBB_STAT
                                        ;RETURNS X POINTING TO APPROPRIATE 
                                        ;KEYBOARD TABLE !
                                        ;DISPLAYS CURSOR TYPE. PRESERVES B
        TST     B
        BEQ     9$
        ABX
        LDA     B,0,X                   ;GET ASCII KEY FROM TABLE
        LDA     A,KBB_STAT:
        LSR     A
        BCS     4$                      ;IF SET LEAVE AS LOWER CASE
        CMP     B,#^A/A/
        BCS     21$
        CMP     B,#^A/Z/
        BHI     21$
        ADD     B,#^A/a/-^A/A/          ;CONVERT TO UPPER CASE
21$:
4$:     CMP     B,#K_DEL
        BNE     9$
        LDA     A,KBB_STAT:
        BPL     9$
        LDA     B,#$7F          ;DEL
9$:     TBA
        RTS

KCUST:
        LDX     BTA_TABL                ;ADDRESS OF KEYBOARD TABLE
        DEX
        LDA     A,KBB_STAT:
        ASL     A
        ASL     A
        BMI     DO2
        ASL     A
        BMI     DO3
        LDA     A,KBB_STAT:
        ASL     A
        BVS     DOSHFT

        AIM     #<$FF-CURSOR_LINE>,DPB_CUST:    ;BLOCK CURSOR
        BRA     DP_CTYP                 ;REFRESH CURSOR TYPE ON LCD

DO3:    BSR     ADD36
DO2:    BSR     ADD36   
DOSHFT: OIM     #CURSOR_LINE,DPB_CUST:  ;LINE CURSOR FOR SHIFTED CHARS
        BSR     ADD36

DP_CTYP:
        LDA     A,#$0C
        TIM     #CURS_ON,DPB_CUST:
        BEQ     1$                      ;BRANCH IF CURSOR OFF
        ORA     A,#$02
        TIM     #CURSOR_LINE,DPB_CUST:
        BNE     1$                      ;BRANCH IF CURSOR IN LINE FORM
        ORA     A,#$01
1$:     TST     SCA_LCDCONTROL
        BMI     1$
        STA     A,SCA_LCDCONTROL
        RTS

ADD36:
        PSH     B
        LDA     B,#36
        ABX     
        PUL     B
        RTS


NEWTABL:
        .ASCII  /ZVPJD/
        .BYTE   K_EXE   
        .ASCII  /XRLF/
        .ASCII  / WQKE/ 
        .ASCII  /YUOIC/ 
        .BYTE   K_DEL
        .ASCII  /TNHB/
        .BYTE   0                       
        .ASCII  /SMGA/  
        .BYTE   $81
        .BYTE   $82,$83
        .BYTE   K_LEFT,K_RGHT
        .BYTE   $80

SHFT1:
        .ASCII  /.258)/ 
        .BYTE   K_EXE
                   $
        .ASCII  $+-$
        .ASCII  $/$
        .ASCII  / 369%/ 
        .ASCII  /0147(/ 
        .BYTE   K_DEL
        .ASCII  /:$">/
        .BYTE   0
        .ASCII  /;,=