I have been involved in a few project where a PC keyboard was to be used for the c64. VICE emulator and Ultimate64 reimplementation on the c64.

Let’s have a look at how the keyboard on a c64 works..

The CIA#1 chip has two registers that are associated with the physically keyboard. In order to scan the keyboard you poke a value in $DC00 and you put 0 on the line in the matrix you want to test. Then you read $DC01 to detect which of the eight keys in that column of the matrix you got a hit at. A zero in a line means that this key in the matrix was pressed.

Please mind that we are talking the physical button of the keyboard, and this is where it gets complex. The keys on national keyboards aren’t meant to produce the same output. National keyboard variants have other prints (or stickers) that is associated with a DC00/DC01 combination.

The support for DC00/DC01 -> which key is implemented using tables in Kernal, and they are then different in the different national variants.

$EB81 is ths unshifted table, Shifted is at $EBC2, Commodore “shifted” at $EC03 and control “shifted” at $EC78.

In the English edition of Kernal, the first table looks like this and my scribbly notes from my Commodore64 Whole Memory Guide shows the delta vs the Swedish Kernal.

Adding to this, national variants of the c64 also had updated character ROMs. That means that some international characters defined were hijacked and replaced with others. In the Swedish one, the characters [, libra/pound and ] are replaced with the Swedish chars ä, ö and å. The below shows the representation in upper/gfx mode, but naturally the Swedish chars exist in both upper and also lower case.

To summarise the process on the c64, this is it:

So if you make an interface that takes the position of a PC keyboards and generate a DC00/DC01 combination, then there are a lot of aspects you need to address.

I haven’t read up on what the physical keyboard sends on the cable, if it’s as complex as on the c64 but an opening link for this interested could be THIS ONE.

Under OSes, there tends to be drivers for the keyboards and emulators that return something to you which is a proper representation of the graphics printed on the keyboard (See HERE) . In Windows you can select language, which is the equivalent of changing Kernal keymap on the c64, but please mind that taking that value and poke something in the DC00/DC01 means that you are making assumptions on the Kernal matrix and char ROM.

If I run VICE, and I press “=” on my Swedish PC keyboard with Swedish keyboard set in my Windows keyboard setting, this feeds the “=” to VICE. VICE will then place #$DF in $DC01 when $BF is written to $DC00 to achieve char code $3D. Using an English/International Kernal, you will then get a “=” on the screen. All good. But if you have a Swedish Kernal, the same position on the key matrix yields $3B (“+”). If you want a “=”, then you need to return $F7 on $DC01 when you poke $DF to $DC00.

So in practice, emulators (VICE is the case I I know of – not sure about the others) only supports English/international Kernals.

There are two ways to mitigate this;
– Allow any Kernal to be loaded, but exchange the keymap portion with the one from the international Kernals.
– Get the key from the keyboard and look at what char that would be on the c64. Then lookup that key in the Kernal keymaps to tell what DC00/DC01 values it would need to return that keycode.

The first option would make alterations to the emulated environment, which isn’t really neat. The second option means producing new logics around the keyboard handling, and I guess that it “sort of works” now (even if it doesn’t – it’s just that it doesn’t show as long as you stay on international keymap kernals).

Thanks for rating this! Now tell the world how you feel - .
How does this post make you feel?
  • Excited
  • Fascinated
  • Amused
  • Bored
  • Sad
  • Angry