1

I'm implementing non-KERNAL joystick and keyboard controls for my Commodore 64 game.

I used to use the KERNAL SCNKEY routine earlier to read keyboard and it worked well with my joystick port 2 code. However, I had to bank out ROM to implement stable raster IRQs and now I'm reading the keyboard matrix directly using $dc00/$dc01 (code copied from http://codebase64.org/doku.php?id=base:scanning_the_keyboard_the_correct_and_non_kernal_way)

However, the keyboard routine needs to write a row/column select bit into $dc00 when reading the keyboard state. This seems to mess up joystick port 2 state (keyboard state leaks into joystick port reads).

I noticed that if I save and restore $dc00 contents before/after calling the keyboard routine, joystick state works fine.

Is it OK to do something like

lda $dc00
sta tmp
jsr Keyboard
lda tmp
sta $dc00

to preserve joystick state or is there some other way to do this? This worked fine on VICE but I haven't tried on real C64 HW yet.

I did try to read the KERNAL SCNKEY source code to see if they're doing a $dc00 save/restore and didn't find an obvious place where they'd be doing this register state save/restore.

(Cross posting from https://stackoverflow.com/questions/50229204/reading-both-keyboard-and-joystick-with-non-kernal-code-on-c64)

EDIT:

JeremyP's answer is right about DDR regs. This code seems to work with joystick on port 2 and the keyboard code from http://codebase64.org/doku.php?id=base:scanning_the_keyboard_the_correct_and_non_kernal_way:

read_keyboard: {
    jsr Keyboard
    ldx #0
    stx $dc02 // put joystick port 2 register $dc00 to read mode
    rts 
}
  • 1
    Not commenting on what it might do to the hardware, but from a programming stylistic pov, you should save and restore the state inide the keyboard routine. – JeremyP May 8 '18 at 9:24
  • Sure and that’s more or less how my real code looks like. The example was just to illustrate what I do on the higher level. – Nurpax May 8 '18 at 10:25
2

Having read the C64 wiki on the CIA chip, I would say that your code probably isn't doing enough.

The port at DC02 controls the mode of the bits of port DC00. If a bit on DC02 is 1, the same bit of DC00 is in read/write mode and is used to control the keyboard and if it is 0, the bit on DC00 is in reads only mode and is used to read the joystick. DC03 provides the same function for DC01. I would expect your code. to:

  • save the state of DC02and DC03
  • set DC02 and DC03 to FF (read/write on all pins).
  • scan the keyboard
  • restore the states of DC02 and DC03
  • Sounds like you're on to something with the DDR registers! I notice that most keyboard routines set port A to all outputs (ones) and port B to all inputs (zeros). I'll try what happens if I just save/restore $dc02 and $dc03. – Nurpax May 8 '18 at 11:57
  • You're right about the DDR regs. I'd like to accept your answer although it's not quite what was needed for this particular keyboard case. – Nurpax May 8 '18 at 12:17
  • Added a snippet into my original question that fixes the problem. – Nurpax May 8 '18 at 12:27
  • @Nurpax Hi, your code snippet is a less general version of mine in which you assume you always want to monitor the joystick except when reading the keyboard. In your use-case, as long as it works, that's fine. The normal protocol on Stack Exchange sites if you come up with your own answer and no other answer is quite right is to write it up as an answer yourself and then accept it. Note, you may have to wait a bit (15 mins)? before accepting it. – JeremyP May 8 '18 at 13:45
  • Yep, I realize it is more general. I tried your save/restore version but it didn’t fix my joystick problem. I suppose I should’ve added DDR writes for my joystick code too and then use save/restore for keyboard. – Nurpax May 8 '18 at 13:58
1

An easy solution to my original problem of using this keyboard code while simultaneously reading joystick port 2 from $dc00 is as follows:

read_keyboard: {
    jsr Keyboard
    ldx #0
    stx $dc02 // put joystick port 2 register $dc00 to read mode
    rts 
}

The idea (as explained in JeremyP's answer) is to put the CIA#1 port A into read-only mode.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.