Blob Blame History Raw
From eb2317d01400f361c396b4626b41894139060983 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= <stephan.muehlstrasser@web.de>
Date: Mon, 2 Sep 2019 20:52:16 +0200
Subject: [PATCH 070/170] Restructured according to review

Restructured according to review in pull request #567.

The "inputc" function was moved in slightly modified form
to kbhit.s and replaces the old keyboard scanner.
cgetc() uses the new kbhit() to read a character.
---
 libsrc/osic1p/cgetc.s | 222 +++---------------------------------------
 libsrc/osic1p/kbhit.s | 214 ++++++++++++++++++++++++++++++++++------
 2 files changed, 199 insertions(+), 237 deletions(-)

diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s
index d99f69a7..56209ff6 100644
--- a/libsrc/osic1p/cgetc.s
+++ b/libsrc/osic1p/cgetc.s
@@ -2,236 +2,40 @@
 ; char cgetc (void);
 ;
 
-        .constructor    initcgetc
         .export         _cgetc
-        .export         inputc
         .import         cursor
+        .import         _kbhit
 
         .include        "osic1p.inc"
         .include        "extzp.inc"
         .include        "zeropage.inc"
 
-; Internal state that needs to be preserved across calls.
-; These variables are named after the original memory locations used by the
-; 65V PROM MONITOR, until the actual meaning is determined.
-.segment        "EXTZP" : zeropage
-
-KB0213:         .res    1
-KB0214:         .res    1
-KB0215:         .res    1
-KB0216:         .res    1
-
-; Initialize one-character buffer that is filled by kbhit()
-        .segment        "ONCE"
-initcgetc:
-        lda     #$00
-        sta     CHARBUF         ; No character in buffer initially
-
-        sta     KB0213          ; Initialize keyboard state
-        sta     KB0214
-        sta     KB0215
-        sta     KB0216
-
-        rts
-
-; Input routine from 65V PROM MONITOR, show cursor if enabled
+; Input routine, show cursor if enabled
         .code
 _cgetc:
-        lda     CHARBUF         ; character in buffer available?
-        beq     nobuffer
-        tax                     ; save character in X
-        lda     #$00
-        sta     CHARBUF         ; empty buffer
-        beq     restorex        ; restore X and return
-nobuffer:
+        ldx     CHARBUF         ; character in buffer available?
+        bne     done
         lda     cursor          ; show cursor?
         beq     nocursor
         ldy     CURS_X
         lda     (SCREEN_PTR),y  ; fetch current character
         sta     tmp1            ; save it
         lda     #$A1            ; full white square
-        sta     (SCREEN_PTR),y  ; store at cursor position
+        sta     (SCREEN_PTR),y  ; store at cursor position^
+
 nocursor:
-        jsr     inputc          ; get input character in A
-        ldx     cursor
+        jsr     _kbhit          ; get input character in A
+        tax                     ; save A in X, set flags
+        beq     nocursor        ; until a key is actually pressed
+        lda     cursor
         beq     done            ; was cursor on?
-        tax                     ; save A in X
         lda     tmp1            ; fetch saved character
         ldy     CURS_X
         sta     (SCREEN_PTR),y  ; store at cursor position
 
-restorex:
-        txa                     ; restore saved character from X
 done:
-        ldx     #$00            ; high byte of int return value
-        rts
-
-; Routine to get character from keyboard and return it in A.
-; Based on the OSI ROM routine at $FD00 but uses different
-; storage locations to avoid corrupting CC65 run-time code.
-
-inputc: txa                     ; Save X on stack.
-        pha
-        tya                     ; Save Y on stack.
-        pha
-LFD04:  lda     #$80            ; Bit mask for initial keyboard row
-LFD06:  jsr     LFCBE           ; Write keyboard row
-        jsr     LFCC6           ; Read keyboard column
-        bne     LFD13           ; Branch if a key in this column was pressed
-        lsr     a               ; Otherwise shift mask to next row
-        bne     LFD06           ; If not done yet, check next row
-        beq     LFD3A           ; Branch if last row reached and no key pressed
-LFD13:  lsr     a               ; Have a key press. Shift LSB into carry
-        bcc     LFD1F           ; Branch if no key pressed in column 0
-        txa                     ; Key pressed in row zero. Get the column data
-        and     #$20            ; Mask only the bit for <ESC> as it is the only key in row zero that returns key press
-        beq     LFD3A           ; Branch if <ESC> was not the key
-        lda     #$1B            ; Set character to <ESC>
-        bne     LFD50           ; Do more processing
-LFD1F:  jsr     LFE86           ; Shift to find bit that is set (in Y)
-        tya                     ; Get bit
-        sta     KB0215          ; Save it
-        asl     a               ; Multiply by 7 by shifting left three times (X8)...
-        asl     a
-        asl     a
-        sec                     ; ...then subtracting one
-        sbc     KB0215
-        sta     KB0215          ; Save value*7 for later lookup in table
-        txa                     ; Get the keyboard column
-        lsr     a               ; Shift out bit zero (only key there is <SHIFT LOCK>)
-        asl     a               ; And shift back
-        jsr     LFE86           ; Shift to find bit that is set (in Y)
-        beq     LFD47           ; Branch if no keys pressed
         lda     #$00
-LFD3A:  sta     KB0216          ; Save state of <CTRL> and shift keys
-LFD3D:  sta     KB0213
-        lda     #$02            ; Count used for key debouncing
-        sta     KB0214
-        bne     LFD04           ; Go back and scan keyboard again
-LFD47:  clc
-        tya                     ; Get bit number of pressed key
-        adc     KB0215          ; Add previously calculated offset for keyboard row*7
-        tay
-        lda     LFF3B,y         ; Read ASCII code for key from table
-LFD50:  cmp     KB0213          ; Debounce - same as last key scan?
-        bne     LFD3D           ; If not, try again
-        dec     KB0214          ; Decrement debounce counter
-        beq     LFD5F           ; Branch if done debouncing
-        jsr     LFCDF           ; Wait for short delay to debounce keyboard
-        beq     LFD04           ; Go back and scan keyboard.
-LFD5F:  ldx     #$64            ; Was <CONTROL> key down?
-        cmp     KB0216
-        bne     LFD68           ; Branch if not
-        ldx     #$0F
-LFD68:  stx     KB0214
-        sta     KB0216
-        cmp     #$21
-        bmi     LFDD0           ; Done, return key
-        cmp     #$5F
-        beq     LFDD0           ; Done, return key
-        lda     #$01
-        jsr     LFCBE           ; Write keyboard row
-        jsr     LFCCF           ; Read keyboard column
-        sta     KB0215
-        and     #$01
-        tax
-        lda     KB0215
-        and     #$06
-        bne     LFDA2
-        bit     KB0213
-        bvc     LFDBB
-        txa
-        eor     #$01
-        and     #$01
-        beq     LFDBB
-        lda     #$20
-        bit     KB0215
-        bvc     LFDC3
-        lda     #$C0
-        bne     LFDC3
-LFDA2:  bit     KB0213
-        bvc     LFDAA
-        txa
-        beq     LFDBB
-LFDAA:  ldy     KB0213
-        cpy     #$31
-        bcc     LFDB9
-        cpy     #$3C
-        bcs     LFDB9
-        lda     #$F0
-        bne     LFDBB
-LFDB9:  lda     #$10
-LFDBB:  bit     KB0215
-        bvc     LFDC3
-        clc
-        adc     #$C0
-LFDC3:  clc
-        adc     KB0213
-        and     #$7F
-        bit     KB0215
-        bpl     LFDD0
-        ora     #$80
-LFDD0:  sta     KB0215          ; Save pressed key
-        pla
-        tay                     ; Restore saved Y value
-        pla
-        tax                     ; Restore saved Y value
-        lda     KB0215          ; Get pressed key and return in A
-        rts
-
-; Write keyboard row with value in A.
-; Invert the bits before writing.
-; Returns original value of A.
-
-LFCBE:  eor     #$FF
-        sta     KBD
-        eor     #$FF
-        rts
-
-; Read keyboard column and return in X.
-; Sets Z flag if no keys were pressed.
-; Saves current value of A.
-
-LFCC6:  pha                     ; Save A
-        jsr     LFCCF           ; Read keyboard column
-        tax                     ; Save in X
-        pla                     ; Restore A
-        dex                     ; Decrement and then increment to
-        inx                     ; preserve value of X but set flags
-        rts
-
-; Read keyboard column.
-; Invert the bits (pressed key(s) will show up as ones).
-
-LFCCF:  lda     KBD             ; Read keyboard hardware
-        eor     #$FF            ; Invert the bits
-        rts
-
-; Short fixed delay routine.
-
-LFCDF:  ldy     #$10
-LFCE1:  ldx     #$40
-LFCE3:  dex
-        bne     LFCE3
-        dey
-        bne     LFCE1
-        rts
-
-; Shift A left until we find a 1 in the most significant bit.
-; Return the bit number in Y.
-
-LFE86:  ldy     #$08
-LFE88:  dey
-        asl     a
-        bcc     LFE88
+        sta     CHARBUF         ; empty buffer
+        txa                     ; restore saved character from X
+        ldx     #$00            ; high byte of int return value
         rts
-
-; Lookup table of keyboard keys for each scan row.
-LFF3B:  .byte   $BD
-        .byte   'P', ';', '/', ' ', 'Z', 'A', 'Q'
-        .byte   ',', 'M', 'N', 'B', 'V', 'C', 'X'
-        .byte   'K', 'J', 'H', 'G', 'F', 'D', 'S'
-        .byte   'I', 'U', 'Y', 'T', 'R', 'E', 'W'
-        .byte   $00, $00, $0D, $0A, 'O', 'L', '.'
-        .byte   $00, '_', '-', ':', '0', '9', '8'
-        .byte   '7', '6', '5', '4', '3', '2', '1'
diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s
index 1ecfa104..db28854f 100644
--- a/libsrc/osic1p/kbhit.s
+++ b/libsrc/osic1p/kbhit.s
@@ -10,39 +10,197 @@
 ; in tmp1 and that is set to zero after the first round.
 ;
 
+        .constructor    initkbhit
         .export _kbhit
-        .import inputc
         .include "osic1p.inc"
         .include "extzp.inc"
         .include "zeropage.inc"
 
-_kbhit:
-        lda     #%11011111      ; Mask for only checking the column for the
-        sta     tmp1            ; ESC key in the first keyboard row.
-
-        lda     #%11111110      ; Mask for first keyboard row
-scan:
-        sta     KBD             ; Select keyboard row
-        tax                     ; Save A
-        lda     KBD             ; Read keyboard columns
-        ora     tmp1            ; Mask out uninteresting keys (only relevant in
-                                ; first row)
-        cmp     #$FF            ; No keys pressed?
-        bne     keypressed
-        lda     #$00            ; For remaining rows no keys masked
-        sta     tmp1
-        txa                     ; Restore A
-        sec                     ; Want to shift in ones
-        rol     a               ; Rotate row select to next bit position
-        cmp     #$FF            ; Done?
-        bne     scan            ; If not, continue
-        lda     #$00            ; Return false
-        tax                     ; High byte of return is also zero
-        sta     CHARBUF         ; No character in buffer
+; Internal state that needs to be preserved across calls.
+.segment        "EXTZP" : zeropage
+
+LASTSCAN:       .res    1       ; Result of previous keyboard scan
+DBNCCNT:        .res    1       ; Debounce counter
+KBDTMP:         .res    1       ; Temporary values
+CTRLSHIFT:      .res    1       ; State of CTRL and SHIFT keys
+
+; Initialize one-character buffer that is filled by kbhit()
+        .segment        "ONCE"
+initkbhit:
+        lda     #$00
+        sta     CHARBUF         ; No character in buffer initially
+
+        sta     LASTSCAN        ; Initialize keyboard state
+        sta     DBNCCNT
+        sta     KBDTMP
+        sta     CTRLSHIFT
+
         rts
-keypressed:
-        jsr     inputc          ; Get input character in A
-        sta     CHARBUF         ; Save in buffer
+
+; Routine to get character from keyboard and return it in A.
+; Based on the OSI ROM routine at $FD00 but uses different
+; storage locations to avoid corrupting CC65 run-time code.
+
+_kbhit: lda     CHARBUF         ; Check for previously saved character
+        beq     LFD05
         ldx     #$00            ; High byte of return is always zero
-        lda     #$01            ; Return true
+        rts                     ; A contains non-zero character code meaning true
+LFD05:  lda     #$80            ; Bit mask for initial keyboard row
+LFD06:  jsr     LFCBE           ; Write keyboard row
+        jsr     LFCC6           ; Read keyboard column
+        bne     LFD13           ; Branch if a key in this column was pressed
+        lsr     a               ; Otherwise shift mask to next row
+        bne     LFD06           ; If not done yet, check next row
+        beq     LFD3A           ; Branch if last row reached and no key pressed
+LFD13:  lsr     a               ; Have a key press. Shift LSB into carry
+        bcc     LFD1F           ; Branch if no key pressed in column 0
+        txa                     ; Key pressed in row zero. Get the column data
+        and     #$20            ; Mask only the bit for <ESC> as it is the only key in row zero that returns key press
+        beq     LFD3A           ; Branch if <ESC> was not the key
+        lda     #$1B            ; Set character to <ESC>
+        bne     LFD50           ; Do more processing
+LFD1F:  jsr     LFE86           ; Shift to find bit that is set (in Y)
+        tya                     ; Get bit
+        sta     KBDTMP          ; Save it
+        asl     a               ; Multiply by 7 by shifting left three times (X8)...
+        asl     a
+        asl     a
+        sec                     ; ...then subtracting one
+        sbc     KBDTMP
+        sta     KBDTMP          ; Save value*7 for later lookup in table
+        txa                     ; Get the keyboard column
+        lsr     a               ; Shift out bit zero (only key there is <SHIFT LOCK>)
+        asl     a               ; And shift back
+        jsr     LFE86           ; Shift to find bit that is set (in Y)
+        beq     LFD47           ; Branch if no keys pressed STM: IS THIS CORRECT?
+        lda     #$00
+LFD3A:  sta     CTRLSHIFT       ; Save state of <CTRL> and shift keys
+LFD3D:  sta     LASTSCAN
+        lda     #$02            ; Count used for key debouncing
+        sta     DBNCCNT
+        ldx     #$00            ; High byte of return is always zero
+        lda     #$00            ; Return false
+        rts
+LFD47:  clc
+        tya                     ; Get bit number of pressed key
+        adc     KBDTMP          ; Add previously calculated offset for keyboard row*7
+        tay
+        lda     LFF3B,y         ; Read ASCII code for key from table
+LFD50:  cmp     LASTSCAN        ; Debounce - same as last key scan?
+        bne     LFD3D           ; If not, try again
+        dec     DBNCCNT         ; Decrement debounce counter
+        beq     LFD5F           ; Branch if done debouncing
+        jsr     LFCDF           ; Wait for short delay to debounce keyboard
+        beq     _kbhit          ; Go back and scan keyboard.
+LFD5F:  ldx     #$64            ; Was <CONTROL> key down?
+        cmp     CTRLSHIFT
+        bne     LFD68           ; Branch if not
+        ldx     #$0F
+LFD68:  stx     DBNCCNT
+        sta     CTRLSHIFT
+        cmp     #$21
+        bmi     LFDD0           ; Done, return key
+        cmp     #$5F
+        beq     LFDD0           ; Done, return key
+        lda     #$01
+        jsr     LFCBE           ; Write keyboard row
+        jsr     LFCCF           ; Read keyboard column
+        sta     KBDTMP
+        and     #$01
+        tax
+        lda     KBDTMP
+        and     #$06
+        bne     LFDA2
+        bit     LASTSCAN
+        bvc     LFDBB
+        txa
+        eor     #$01
+        and     #$01
+        beq     LFDBB
+        lda     #$20
+        bit     KBDTMP
+        bvc     LFDC3
+        lda     #$C0
+        bne     LFDC3
+LFDA2:  bit     LASTSCAN
+        bvc     LFDAA
+        txa
+        beq     LFDBB
+LFDAA:  ldy     LASTSCAN
+        cpy     #$31
+        bcc     LFDB9
+        cpy     #$3C
+        bcs     LFDB9
+        lda     #$F0
+        bne     LFDBB
+LFDB9:  lda     #$10
+LFDBB:  bit     KBDTMP
+        bvc     LFDC3
+        clc
+        adc     #$C0
+LFDC3:  clc
+        adc     LASTSCAN
+        and     #$7F
+        bit     KBDTMP
+        bpl     LFDD0
+        ora     #$80
+LFDD0:  sta     KBDTMP          ; Save pressed key and return in A
+        sta     CHARBUF
+        rts
+
+; Write keyboard row with value in A.
+; Invert the bits before writing.
+; Returns original value of A.
+
+LFCBE:  eor     #$FF
+        sta     KBD
+        eor     #$FF
         rts
+
+; Read keyboard column and return in X.
+; Sets Z flag if no keys were pressed.
+; Saves current value of A.
+
+LFCC6:  pha                     ; Save A
+        jsr     LFCCF           ; Read keyboard column
+        tax                     ; Save in X
+        pla                     ; Restore A
+        dex                     ; Decrement and then increment to
+        inx                     ; preserve value of X but set flags
+        rts
+
+; Read keyboard column.
+; Invert the bits (pressed key(s) will show up as ones).
+
+LFCCF:  lda     KBD             ; Read keyboard hardware
+        eor     #$FF            ; Invert the bits
+        rts
+
+; Short fixed delay routine.
+
+LFCDF:  ldy     #$10
+LFCE1:  ldx     #$40
+LFCE3:  dex
+        bne     LFCE3
+        dey
+        bne     LFCE1
+        rts
+
+; Shift A left until we find a 1 in the most significant bit.
+; Return the bit number in Y.
+
+LFE86:  ldy     #$08
+LFE88:  dey
+        asl     a
+        bcc     LFE88
+        rts
+
+; Lookup table of keyboard keys for each scan row.
+LFF3B:  .byte   $BD
+        .byte   'P', ';', '/', ' ', 'Z', 'A', 'Q'
+        .byte   ',', 'M', 'N', 'B', 'V', 'C', 'X'
+        .byte   'K', 'J', 'H', 'G', 'F', 'D', 'S'
+        .byte   'I', 'U', 'Y', 'T', 'R', 'E', 'W'
+        .byte   $00, $00, $0D, $0A, 'O', 'L', '.'
+        .byte   $00, '_', '-', ':', '0', '9', '8'
+        .byte   '7', '6', '5', '4', '3', '2', '1'
-- 
2.26.0