1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 00:29:31 +00:00

Design change: Do keyboard polling internally without calling the kernal

in the system bank. For one this performs better (several %), second it
allows to handle the function keys in conformance with other platforms.
Without the custom keyboard routine, we would have to apply some more
magic to the function keys to make them work as with other cc65 targets.


git-svn-id: svn://svn.cc65.org/cc65/trunk@2811 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-12-21 18:43:25 +00:00
parent 028d03b482
commit 97494bc1f3
11 changed files with 313 additions and 99 deletions

View File

@ -37,14 +37,17 @@ OBJS = _scrsize.o \
crtc.o \ crtc.o \
extzp.o \ extzp.o \
kbhit.o \ kbhit.o \
kclose.o \
kernal.o \ kernal.o \
kiobase.o \ kiobase.o \
kopen.o \ kopen.o \
krdtim.o \ krdtim.o \
kreadst.o \ kreadst.o \
kscnkey.o \
kscreen.o \ kscreen.o \
ksetnam.o \ ksetnam.o \
ksettim.o \ ksettim.o \
kudtim.o \
mainargs.o \ mainargs.o \
peeksys.o \ peeksys.o \
pokesys.o \ pokesys.o \

View File

@ -5,69 +5,46 @@
; ;
.export _cgetc .export _cgetc
.import plot, write_crtc, sys_bank, restore_bank .import plot, write_crtc
.import cursor .import cursor
.import sysp0: zp, sysp3: zp
.include "cbm610.inc" .import keyidx: zp, keybuf: zp, config: zp
_cgetc: lda IndReg
pha
lda #$0F
sta IndReg ; Switch to the system bank
ldy #$D1 _cgetc: lda keyidx ; Get number of characters
lda (sysp0),y ; Get number of keys in keyboard buffer bne L2 ; Jump if there are already chars waiting
bne L2 ; Jump if there are already chars waiting
; Switch on the cursor if needed ; Switch on the cursor if needed
lda cursor lda cursor
beq L0 ; Jump if no cursor beq L1 ; Jump if no cursor
jsr plot ; Set the current cursor position jsr plot ; Set the current cursor position
ldy #$D4
lda (sysp0),y ; Get the cursor format
ldy #10 ldy #10
jsr write_crtc ; Set the cursor format lda config ; Cursor format
jsr write_crtc ; Set the cursor formar
L0: ldy #$D1 L1: lda keyidx
L1: lda (sysp0),y ; Get the number of keys in the buffer beq L1
beq L1 ; Wait until we have some keys
ldy #10 ldy #10
lda #$20 ; Cursor off lda #$20 ; Cursor off
jsr write_crtc jsr write_crtc
L2: ldy #$D1 L2: ldx #$00 ; Get index
lda (sysp0),y ; Get number of chars in buffer ldy keybuf ; Get first character in the buffer
tax sei
ldy #$AB L3: lda keybuf+1,x ; Move up the remaining chars
lda (sysp3),y ; Get first char from keyboard buffer sta keybuf,x
sta c ; Save for return inx
dex cpx keyidx
txa bne L3
ldy #$D1 dec keyidx
sta (sysp0),y cli
sei
jmp L4
L3: iny
lda (sysp3),y
dey
sta (sysp3),y
iny
L4: dex
bpl L3
cli
pla ldx #$00 ; High byte
sta IndReg ; Restore old segment tya ; First char from buffer
ldx #$00 ; High byte
lda c ; First char from buffer
rts rts
.bss
c: .byte 0

View File

@ -7,9 +7,11 @@
.export _cputcxy, _cputc, cputdirect, putchar .export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot .export newline, plot
.destructor setsyscursor
.import _gotoxy .import _gotoxy
.import popa .import popa
.import PLOT
.import ktmp: zp, crtc: zp, CURS_X: zp, CURS_Y: zp, RVS: zp .import ktmp: zp, crtc: zp, CURS_X: zp, CURS_Y: zp, RVS: zp
.import CharPtr: zp .import CharPtr: zp
@ -132,6 +134,17 @@ plot: ldx CURS_Y
sta IndReg sta IndReg
rts rts
; -------------------------------------------------------------------------
; Cleanup routine that sets the kernal cursor position to ours
.segment "PAGE2"
setsyscursor:
ldy CURS_X
ldx CURS_Y
clc
jmp PLOT ; Set the new cursor
; ------------------------------------------------------------------------- ; -------------------------------------------------------------------------
; Low bytes of the start address of the screen lines ; Low bytes of the start address of the screen lines

View File

@ -4,13 +4,13 @@
; This must be the *first* file on the linker command line ; This must be the *first* file on the linker command line
; ;
.export _exit, BRKVec, UDTIM .export _exit, BRKVec
.import condes, initlib, donelib .import condes, initlib, donelib
.import push0, callmain .import push0, callmain
.import __BSS_RUN__, __BSS_SIZE__, __EXTZP_RUN__ .import __BSS_RUN__, __BSS_SIZE__, __EXTZP_RUN__
.import __IRQFUNC_TABLE__, __IRQFUNC_COUNT__ .import __IRQFUNC_TABLE__, __IRQFUNC_COUNT__
.import SCNKEY .import scnkey, UDTIM
.include "zeropage.inc" .include "zeropage.inc"
.include "extzp.inc" .include "extzp.inc"
@ -54,6 +54,24 @@
.byte $32,$00,$9e,$20,$32,$35,$36,$00,$4f,$00,$3c,$00,$83,$20,$31,$32 .byte $32,$00,$9e,$20,$32,$35,$36,$00,$4f,$00,$3c,$00,$83,$20,$31,$32
.byte $30,$2c,$31,$36,$39,$2c,$31,$2c,$31,$33,$33,$2c,$30,$00,$00,$00 .byte $30,$2c,$31,$36,$39,$2c,$31,$2c,$31,$33,$33,$2c,$30,$00,$00,$00
;------------------------------------------------------------------------------
; A table that contains values that must be transfered from the system zero
; page into out zero page. Contains pairs of bytes, first one is the address
; in the system ZP, second one is our ZP address. The table goes into page 2,
; but is declared here, because it is needed earlier.
.SEGMENT "PAGE2"
.proc transfer_table
.byte $CA, CURS_Y
.byte $CB, CURS_X
.byte $CC, graphmode
.byte $D4, config
.endproc
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; The code in the target bank when switching back will be put at the bottom ; The code in the target bank when switching back will be put at the bottom
; of the stack. We will jump here to switch segments. The range $F2..$FF is ; of the stack. We will jump here to switch segments. The range $F2..$FF is
@ -67,7 +85,6 @@ Back: sei
lda IndReg lda IndReg
sta ExecReg sta ExecReg
;------------------------------------------------------------------------------
; We are at $100 now. The following snippet is a copy of the code that is poked ; We are at $100 now. The following snippet is a copy of the code that is poked
; in the system bank memory by the basic header program, it's only for ; in the system bank memory by the basic header program, it's only for
; documentation and not actually used here: ; documentation and not actually used here:
@ -130,6 +147,11 @@ Origin: tsx
ldx #$FE ; Leave $1FF untouched for cross bank calls ldx #$FE ; Leave $1FF untouched for cross bank calls
txs ; Set up our own stack txs ; Set up our own stack
; Switch the indirect segment to the system bank
lda #$0F
sta IndReg
; Initialize the extended zeropage ; Initialize the extended zeropage
ldx #.sizeof(extzp)-1 ldx #.sizeof(extzp)-1
@ -138,23 +160,32 @@ L1: lda extzp,x
dex dex
bpl L1 bpl L1
; Copy stuff from the system zeropage to ours
lda #.sizeof(transfer_table)
sta ktmp
L2: ldx ktmp
ldy transfer_table-2,x
lda transfer_table-1,x
tax
lda (sysp0),y
sta $00,x
dec ktmp
dec ktmp
bne L2
; Set the interrupt, NMI and other vectors ; Set the interrupt, NMI and other vectors
ldy #.sizeof(vectors)-1 ldx #.sizeof(vectors)-1
L2: lda vectors,y L3: lda vectors,x
sta $10000 - .sizeof(vectors),y sta $10000 - .sizeof(vectors),x
dey dex
bpl L2 bpl L3
; Switch the indirect segment to the system bank
lda #$0F
sta IndReg
; Setup the C stack ; Setup the C stack
lda #.lobyte($FEB5 - .sizeof(callsysbank_15)) lda #.lobyte($FEB5 - .sizeof(callsysbank_15))
sta sp sta sp
lda #.hibyte($FEB5 - .sizeof(callsysbank_15)) lda #.hibyte($FEB5 - .sizeof(callsysbank_15))
sta sp+1 sta sp+1
@ -207,7 +238,7 @@ L4: lda (sysp1),y
; Set the indirect segment to bank we're executing in ; Set the indirect segment to bank we're executing in
lda ExecReg lda ExecReg
sta IndReg sta IndReg
; Zero the BSS segment. We will do that here instead calling the routine ; Zero the BSS segment. We will do that here instead calling the routine
@ -229,7 +260,7 @@ Z1: sta (ptr1),y
iny iny
bne Z1 bne Z1
inc ptr1+1 ; Next page inc ptr1+1 ; Next page
dex dex
bne Z1 bne Z1
; Clear the remaining page ; Clear the remaining page
@ -269,11 +300,27 @@ _exit: lda #$00
sta irqcount ; Disable custom irq handlers sta irqcount ; Disable custom irq handlers
jsr donelib ; Run module destructors jsr donelib ; Run module destructors
; Adress the system bank ; Address the system bank
lda #$0F lda #$0F
sta IndReg sta IndReg
; Copy stuff back from our zeropage to the systems
.if 0
lda #.sizeof(transfer_table)
sta ktmp
@L0: ldx ktmp
ldy transfer_table-2,x
lda transfer_table-1,x
tax
lda $00,x
sta (sysp0),y
dec ktmp
dec ktmp
bne @L0
.endif
; Copy back the old system bank stack contents ; Copy back the old system bank stack contents
ldy #$FF ldy #$FF
@ -345,7 +392,7 @@ irqskip:lda #$0F
cmp #%00000001 ; ticker irq? cmp #%00000001 ; ticker irq?
bne irqend bne irqend
jsr SCNKEY ; Poll the keyboard jsr scnkey ; Poll the keyboard
jsr UDTIM ; Bump the time jsr UDTIM ; Bump the time
; Done ; Done
@ -364,24 +411,6 @@ nmi: rti
dobrk: jmp (BRKVec) dobrk: jmp (BRKVec)
; -------------------------------------------------------------------------
; udtim routine for the 610. We will not check for the stop key here, since
; C programs will not use it.
;
.proc UDTIM
inc time
bne L9
inc time+1
bne L9
inc time+2
bne L9
inc time+3
L9: rts
.endproc
; ------------------------------------------------------------------------- ; -------------------------------------------------------------------------
; Page 3 ; Page 3

View File

@ -9,6 +9,8 @@
.globalzp sysp1, sysp3, crtc, sid, ipccia, cia, acia, tpi1, tpi2 .globalzp sysp1, sysp3, crtc, sid, ipccia, cia, acia, tpi1, tpi2
.globalzp ktab1, ktab2, ktab3, ktab4 .globalzp ktab1, ktab2, ktab3, ktab4
.globalzp sysp0, time, segsave, ktmp, CURS_X, CURS_Y, RVS .globalzp sysp0, time, segsave, ktmp, CURS_X, CURS_Y, RVS, config
.globalzp CharPtr .globalzp CharPtr, keyidx, keybuf, keyscanbuf, keysave, modkey
.globalzp norkey, graphmode, lastidx, rptdelay, rptcount

View File

@ -33,14 +33,23 @@ ktab4: .word $0000
sysp0: .word $0000 sysp0: .word $0000
time: .dword $0000 time: .dword $0000
segsave: .byte 0 segsave: .byte 0
scanbuf: .byte 0
ktmp: .byte 0 ktmp: .byte 0
CURS_X: .byte 0 CURS_X: .byte 0
CURS_Y: .byte 0 CURS_Y: .byte 0
RVS: .byte 0 RVS: .byte 0
config: .byte 0
CharPtr: .word 0 CharPtr: .word 0
; Stuff for our own kbd polling routine
keyidx: .byte 0 ; Number of keys in keyboard buffer
keybuf: .res 10 ; Keyboard buffer
keyscanbuf: .byte 0
keysave: .byte 0
modkey: .byte 0
norkey: .byte 0
graphmode: .byte 0
lastidx: .byte 0
rptdelay: .byte 0
rptcount: .byte 0

View File

@ -1,23 +1,16 @@
; ;
; Ullrich von Bassewitz, 2003-12-20 ; Ullrich von Bassewitz, 06.08.1998
; ;
; int kbhit (void); ; int kbhit (void);
; ;
.export _kbhit .export _kbhit
.importzp sysp0
.import return0, return1 .import return0, return1
.import keyidx: zp
.include "cbm610.inc"
.proc _kbhit .proc _kbhit
ldx IndReg lda keyidx ; Get number of characters
lda #$0F
sta IndReg
ldy #$D1 ; Number of keys in kbd buffer
lda (sysp0),y
stx IndReg
bne L1 bne L1
jmp return0 jmp return0
L1: jmp return1 L1: jmp return1

21
libsrc/cbm610/kclose.s Normal file
View File

@ -0,0 +1,21 @@
;
; Ullrich von Bassewitz, 2003-12-21
;
; CLOSE kernal call.
;
; NOTE: The CLOSE system call in the CBM610 kernal will only remove the file
; entry and not close the file on IEC if the carry is clear on entry. To make
; this somewhat compatible withthe C64, set the carry before jumping to the
; kernal.
.export CLOSE
.proc CLOSE
sec
jmp $FFC3
.endproc

View File

@ -23,7 +23,6 @@
.export LISTEN .export LISTEN
.export TALK .export TALK
.export SETLFS .export SETLFS
.export CLOSE
.export CHKIN .export CHKIN
.export CKOUT .export CKOUT
.export CLRCH .export CLRCH
@ -64,7 +63,7 @@ TALK = $FFB4
SETLFS = $FFBA SETLFS = $FFBA
;SETNAM = $FFBD ;SETNAM = $FFBD
;OPEN = $FFC0 ;OPEN = $FFC0
CLOSE = $FFC3 ;CLOSE = $FFC3
CHKIN = $FFC6 CHKIN = $FFC6
CKOUT = $FFC9 CKOUT = $FFC9
CLRCH = $FFCC CLRCH = $FFCC

145
libsrc/cbm610/kscnkey.s Normal file
View File

@ -0,0 +1,145 @@
;
; Ullrich von Bassewitz, 28.09.1998
;
; Keyboard polling stuff for the 610.
;
.export scnkey
.importzp tpi2, ktab1, ktab2, ktab3, ktab4
.importzp keyidx, keybuf, keyscanbuf, keysave, modkey, norkey
.importzp graphmode, lastidx, rptdelay, rptcount
.include "cbm610.inc"
.proc scnkey
lda #$FF
sta modkey
sta norkey
lda #$00
sta keyscanbuf
ldy #TPI::PRB
sta (tpi2),y
ldy #TPI::PRA
sta (tpi2),y
jsr Poll
and #$3F
eor #$3F
bne L1
jmp NoKey
L1: lda #$FF
ldy #TPI::PRA
sta (tpi2),y
asl a
ldy #TPI::PRB
sta (tpi2),y
jsr Poll
pha
sta modkey
ora #$30
bne L3 ; Branch always
L2: jsr Poll
L3: ldx #$05
ldy #$00
L4: lsr a
bcc L5
inc keyscanbuf
dex
bpl L4
sec
ldy #TPI::PRB
lda (tpi2),y
rol a
sta (tpi2),y
ldy #TPI::PRA
lda (tpi2),y
rol a
sta (tpi2),y
bcs L2
pla
bcc NoKey ; Branch always
L5: ldy keyscanbuf
sty norkey
pla
asl a
asl a
asl a
bcc L6
bmi L7
lda (ktab2),y ; Shifted normal key
ldx graphmode
beq L8
lda (ktab3),y ; Shifted key in graph mode
bne L8
L6: lda (ktab4),y ; Key with ctrl pressed
bne L8
L7: lda (ktab1),y ; Normal key
L8: tax
cpx #$FF ; Valid key?
beq Done
cpy lastidx
beq Repeat
ldx #$13
stx rptdelay
ldx keyidx
cpx #$09
beq NoKey
cpy #$59
bne PutKey
cpx #$08
beq NoKey
sta keybuf,x
inx
bne PutKey
NoKey: ldy #$FF
Done: sty lastidx
End: lda #$7F
ldy #TPI::PRA
sta (tpi2),y
ldy #TPI::PRB
lda #$FF
sta (tpi2),y
rts
Repeat: dec rptdelay
bpl End
inc rptdelay
dec rptcount
bpl End
inc rptcount
ldx keyidx
bne End
PutKey: sta keybuf,x
inx
stx keyidx
ldx #$03
stx rptcount
bne Done
.endproc
; Poll the keyboard port until it's stable
; This code goes into page 2, since it is included in every program and
; there's space left in p2
.segment "PAGE2"
.proc Poll
ldy #TPI::PRC
L1: lda (tpi2),y
sta keysave
lda (tpi2),y
cmp keysave
bne L1
rts
.endproc

23
libsrc/cbm610/kudtim.s Normal file
View File

@ -0,0 +1,23 @@
;
; Ullrich von Bassewitz, 2003-12-21
;
; udtim routine for the 610. We will not check for the stop key here, since
; C programs will not use it.
;
.export UDTIM
.import time: zp
.proc UDTIM
inc time
bne L9
inc time+1
bne L9
inc time+2
bne L9
inc time+3
L9: rts
.endproc