| | Eyeth Account closed
Registered: Apr 2002 Posts: 98 |
Q&D Keyboard Routine?
Hello.
I would like to know if there's a quick and dirty route to scanning the keyboard via $dc00/$dc01?
My problem is that I want to check for the cursor up/down keypress. I want to test if the user has pressed 'shift' key in combination with the cursor up/down key and then branch to a routine that deals with going 'up'. Sometimes, my routine will think the user pressed down instead, as if the user didn't press the shift key. Pretty annoying if a user pressed shift+cursor up/down and the routines behave differently sometimes.
For now, I've resorted to the IJKM (like Bard's Tale) keypress method to subsitute for the cursor key presses. That one worked effectively, but is not very intuitive.
Thanks,
-Todd Elliott |
|
| | Stryyker
Registered: Dec 2001 Posts: 468 |
I found using $DC00/$DC01 is not too hard. Somewhere there exists a table for all 64 (in 8x8 grid) but shouldn't be too hard to to write code to display them all. The value written to $DC00 if you want to scan for 1 line is reset and all others are set. It is possible to write $FF to $DC00 (or was it $00?) that way you can do a read of $DC01 to test if any key is pressed. I think the $DC00 values used are $7F (the default last one used by the ROM routines), $BF, $DF, $EF, $F7, $FB, $FD,$FE. The value you read from $DC01 will be reset if the key is pressed, all unpressed keys the other 7) are set.
Clear as mud? something like below will give some table. Draw it on a 8x8 grid. Also there is limitations with the C64 hardware which sometimes clever coding can get around, in the resulting grid pick a group of keys in a 2x2 fashion. Now with the below code press 3 if the keys and it magically things the 4th one is being pressed. the code is untested.
start ;
ldx #$07
lda table,x
sta $0400,x
eor #$ff
sta $dc00
lda $dc01
sta $0428,x
dex
bpl start+2
jmp start
table .byte $80,$40,$20,$10,$08,$04,$02,$01
Maybe changing to binary strings will make it more clearer but you could (should) end up with a table something like:
$01 $02 $04 $08 $10 $20 $40 $80
$FE del rtn l/r f7 f1 f3 f5 u/d
$FD 3 w a 4 z s e l/s
$FB 5 r d 6 c f t x
$F7 7 y g 8 b h u v
$EF 9 i j 0 m k o n
$DF + p l - . : @ ,
$BF pnd * ; hme r/s = up /
$7F 1 lft ctr 2 spc cbm q run
down the left is $DC00 value written, along the top is the bit that is cleared to indicated the key is pressed. Reading $DC01 when no keys for the line returns $FF
del = delete, rtn = return, l/r = left/right cursor
u/d = up/down cursor, pnd = pound key (maybe some countries are different?), hme = home
r/s = right shift, l/s = left show/shift lock (64doc or something has a clever way of testing between left shift and shift lock), up = up arrow near *
lft = left arrow next to 1, ctr = control, spc = space bar
cbm = Commodore key, run = run/stop key.
for line $EF, the value of 8 is number 0, while 64 = letter o.
For what you want, lda #$FD, sta $DC00, lda $DC01 eor #$ff, sta shift. lda #$bf sta $DC00, lda $DC01, eor #$ff, ora shift, sta shift.lda #$fe, sta $DC00, lda $dc00, lda $DC01, eor #$FF, and #$84. Now you have a value in the accumulator that stores $80 for down pressed, $04 if right is pressed or $84 if down and right are pressed or $00 if nothing of interest is pressed. Now a simple lda shift, beq noshift or whatever. |
| | yago
Registered: May 2002 Posts: 333 |
As I experienced with the keyboard, I detected some
"jitter" with the keys.
While pressing shift and cursor down, there
is a period at the beginning, where all combinations of shift and cursor down are possible.
(A similar Effect comes, if the user releases the keys)
You might wait a small amount of time, until that jitter disappears, to get "sharp" cursor up.
I think, the correct term is to debounce the keys.
Naturally, if you code your own keyboard-routine, you MUST disable the standard cbm-kernel keyboard handling.
|
| | WVL
Registered: Mar 2002 Posts: 902 |
yes, whenever you detect something, wait one frame and test again. Only acknowledge keypresses if they're held at least one frame. You can also check out the sourcecode of Pinball Dreams. There's a small routine in there to check for certain keys. |
| | chatGPZ
Registered: Dec 2001 Posts: 11386 |
checking again half a frame later is enough though....maybe important for something (game?) that requires to be able to recieve input both immediatly and also every frame.
|
| | WVL
Registered: Mar 2002 Posts: 902 |
well, I just check once each frame, but then again I don't have to check for combinations of keys...
if you want to check for shift+crsr, better make the check twice.
cursor=off
if keyboard.cursor!=0 : wait one frame : read cursor again + read shift key
loop
something like that ;)
|
| | St0fF
Registered: Oct 2002 Posts: 40 |
is the above what is meant with 'ghost-presses' ? Or differently, like multiple keys are hit (i need to acknowledge !together! 3 at a time) and some other key than actually pressed appears? |
| | WVL
Registered: Mar 2002 Posts: 902 |
COULD be, if your routine isn't fast enough... again as I said : check out the sourcecode for pinball dreams and look at the keyboard routine, check out how it reads a lot of keys at the same time...
but really : it's almost impossible (if at all) to read the 'wrong' keys from the keyboard. |
|