From b1969ac16a656d9cd18e755b9e0e6b07085befe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= Date: Thu, 19 Feb 2015 22:19:21 +0100 Subject: [PATCH 1/3] kbhit() function and scrolling. Patch provided by Jeff Tranter. --- libsrc/osic1p/cputc.s | 12 ++++++++++-- libsrc/osic1p/kbhit.s | 28 ++++++++++++++++++++++++++++ libsrc/osic1p/osic1p.inc | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 libsrc/osic1p/kbhit.s diff --git a/libsrc/osic1p/cputc.s b/libsrc/osic1p/cputc.s index f6f285301..47969df15 100644 --- a/libsrc/osic1p/cputc.s +++ b/libsrc/osic1p/cputc.s @@ -48,8 +48,16 @@ newline: lda CURS_Y cmp #SCR_HEIGHT ; screen height bne plot - lda #0 ; wrap around to line 0 - sta CURS_Y + dec CURS_Y ; bottom of screen reached, scroll + ldx #0 +scroll: lda SCRNBASE+$00A5,x + sta SCRNBASE+$0085,x + lda SCRNBASE+$01A5,x + sta SCRNBASE+$0185,x + lda SCRNBASE+$02A5,x + sta SCRNBASE+$0285,x + inx + bne scroll plot: ldy CURS_Y lda ScrLo,y diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s new file mode 100644 index 000000000..c064fec47 --- /dev/null +++ b/libsrc/osic1p/kbhit.s @@ -0,0 +1,28 @@ +; +; unsigned char kbhit (void); +; + + .export _kbhit + .include "osic1p.inc" + +_kbhit: + lda #%11111110 ; Select first keyboard row +scan: + sta KBD ; Select keyboard row + tax ; Save A + lda KBD ; Read keyboard columns + ora #$01 ; Mask out lsb (Shift Lock), since we ignore it + cmp #$FF ; No keys pressed? + bne keypressed + 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 + ldx #$00 ; High byte of return is always zero + lda #$00 ; Return false + rts +keypressed: + ldx #$00 ; High byte of return is always zero + lda #$01 ; Return true + rts diff --git a/libsrc/osic1p/osic1p.inc b/libsrc/osic1p/osic1p.inc index 9a0c346b6..e95db637e 100644 --- a/libsrc/osic1p/osic1p.inc +++ b/libsrc/osic1p/osic1p.inc @@ -2,6 +2,7 @@ SCRNBASE := $D000 ; Base of video RAM INPUTC := $FD00 ; Input character from keyboard RESET := $FF00 ; Reset address, show boot prompt +KBD := $DF00 ; Polled keyboard register ; Other definitions VIDEORAMSIZE = $0400 ; Size of C1P video RAM (1 kB) From 222668c016897eea23df781ec619bc288be83502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= Date: Sat, 21 Feb 2015 20:24:58 +0100 Subject: [PATCH 2/3] Implemented a one-character buffer for kbhit() and cgetc(). If kbhit() detects that a key is pressed, it fetches and buffers the character. If cgetc() detects a buffered character, this one is returned instead of fetching one with the PROM routine. --- cfg/osic1p.cfg | 2 +- libsrc/osic1p/cgetc.s | 19 ++++++++++++++++++- libsrc/osic1p/extzp.inc | 2 +- libsrc/osic1p/extzp.s | 5 +++-- libsrc/osic1p/kbhit.s | 5 ++++- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/cfg/osic1p.cfg b/cfg/osic1p.cfg index 10ce827fd..4771639a6 100644 --- a/cfg/osic1p.cfg +++ b/cfg/osic1p.cfg @@ -7,7 +7,7 @@ SYMBOLS { } MEMORY { # for size of ZP see runtime/zeropage.s and c1p/extzp.s - ZP: file = "", define = yes, start = $0002, size = $001A + $0004; + ZP: file = "", define = yes, start = $0002, size = $001A + $0005; RAM: file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S; } SEGMENTS { diff --git a/libsrc/osic1p/cgetc.s b/libsrc/osic1p/cgetc.s index 3c9dd4381..82857f4c6 100644 --- a/libsrc/osic1p/cgetc.s +++ b/libsrc/osic1p/cgetc.s @@ -1,6 +1,8 @@ ; ; char cgetc (void); ; + + .constructor initcgetc .export _cgetc .import cursor @@ -8,8 +10,21 @@ .include "extzp.inc" .include "zeropage.inc" +; Initialize one-character buffer that is filled by kbhit() +initcgetc: + lda #$00 + sta CHARBUF ; No character in buffer initially + rts + ; Input routine from 65V PROM MONITOR, show cursor if enabled _cgetc: + lda CHARBUF ; character in buffer available? + beq nobuffer + tax ; save character in X + lda #$00 + sta CHARBUF ; empty buffer + jmp restorex ; restore X and return +nobuffer: lda cursor ; show cursor? beq nocursor ldy CURS_X @@ -25,7 +40,9 @@ nocursor: lda tmp1 ; fetch saved character ldy CURS_X sta (SCREEN_PTR),y ; store at cursor position + +restorex: txa ; restore saved character from X - ldx #$00 ; high byte of int return value done: + ldx #$00 ; high byte of int return value rts diff --git a/libsrc/osic1p/extzp.inc b/libsrc/osic1p/extzp.inc index 06498d1a6..5e85e0b74 100644 --- a/libsrc/osic1p/extzp.inc +++ b/libsrc/osic1p/extzp.inc @@ -4,4 +4,4 @@ ; ------------------------------------------------------------------------ - .globalzp CURS_X, CURS_Y, SCREEN_PTR + .globalzp CURS_X, CURS_Y, SCREEN_PTR, CHARBUF diff --git a/libsrc/osic1p/extzp.s b/libsrc/osic1p/extzp.s index 7dc8e3a53..b3bdaa0b7 100644 --- a/libsrc/osic1p/extzp.s +++ b/libsrc/osic1p/extzp.s @@ -14,6 +14,7 @@ CURS_X: .res 1 CURS_Y: .res 1 SCREEN_PTR: .res 2 +CHARBUF: .res 1 -; size 4 -; Adjust size of this segment in osic1p.cfg if the size changes +; size 5 +; Adjust size of the ZP segment in osic1p.cfg if the size changes diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s index c064fec47..67f3c86ed 100644 --- a/libsrc/osic1p/kbhit.s +++ b/libsrc/osic1p/kbhit.s @@ -19,10 +19,13 @@ scan: rol a ; Rotate row select to next bit position cmp #$FF ; Done? bne scan ; If not, continue - ldx #$00 ; High byte of return is always zero lda #$00 ; Return false + tax ; High byte of return is also zero + sta CHARBUF ; No character in buffer rts keypressed: + jsr INPUTC ; Get input character in A + sta CHARBUF ; Save in buffer ldx #$00 ; High byte of return is always zero lda #$01 ; Return true rts From 7a975fa182134b7f1c1bb026cae4900e458bce8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20M=C3=BChlstrasser?= Date: Sat, 21 Feb 2015 22:52:01 +0100 Subject: [PATCH 3/3] Mask control keys from first keyboard scan row. --- libsrc/osic1p/kbhit.s | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/libsrc/osic1p/kbhit.s b/libsrc/osic1p/kbhit.s index 67f3c86ed..b616b4a3f 100644 --- a/libsrc/osic1p/kbhit.s +++ b/libsrc/osic1p/kbhit.s @@ -1,19 +1,35 @@ ; ; unsigned char kbhit (void); +; +; The method to detect a pressed key is based on the documentation in +; "Section 3 Programmed Key Functions" in "The Challenger Character Graphics +; Reference Manual" +; We only want to return true for characters that can be returned by cgetc(), +; but not for keys like or . Therefore a special handling is +; needed for the first row. This is implemented by a bit mask that is stored +; in tmp1 and that is set to zero after the first round. ; .export _kbhit .include "osic1p.inc" + .include "extzp.inc" + .include "zeropage.inc" _kbhit: - lda #%11111110 ; Select first keyboard row + 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 #$01 ; Mask out lsb (Shift Lock), since we ignore it + 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