Saturday, 12 December 2015

Day 12 - Commodore Amiga 500 USB keyboard

This is day 12 of the Advent Calendar of USB keyboards, half way through. Anyone still reading? Today, a new one, a Commodore Amiga 500 USB keyboard.
Or rather an Amiga 500 Plus. This is a later version of the A500 with the internal RAM increased to 1MB, and an integrated real time clock. And an integrated real time clock battery.
As with any 25 year old NiCad battery, these leak, and have a tendency to take out the surrounding area. There were many memory upgrades for the original A500, some with real time clocks (and batteries) but at least when they leaked, they only took out the upgrade.
That board may be repairable, but there are several tracks and component legs corroded through, so it's going to need quite a bit of work. Worse case it would provide a good source of spares for some faulty A500's I have.
The A500 keyboard was based on the A1000 before it, which had an external keyboard with a keyboard controller in the keyboard and a serial link to the main box. The A500 has kept the same separation, just moved it inside. The only connection on the keyboard is an 8 way cable.
This has the serial data, a way to hard reset the computer, and separate controls for the two LEDs on the keyboard (power and drive access). The caps lock LED is controlled internally by the keyboard.
Notice anything wrong between these schematics? There seems to be some disagreement on the order of clock and data. The consensus seems to be clock on pin 1, drawn upside down in the A500+ schematic to add further confusion.
I did find some Amiga 500 USB keyboard projects, all seem to be based around variations on the same code which used a state machine to poll the signal lines, I wasn't happy with the timing issues of that, it could easily miss some of the pulses, and it didn't fit with my USB keyboard framework, so I wrote my own.
There isn't much information on the keyboard protocol online, so I turned to the 'Revised and Updated' Amiga hardware reference manual. If it's printed on paper, it can't be wrong (?). This didn't have a pinout, but did have some nice ASCII art timing diagrams.
Unlike some of its contemporaries such as the Acorn Archimedes and Atari ST, this was not an asynchronous RS232 like serial protocol, but a synchronous one (i.e. it has it's own clock rather than relying on an agreed BAUD rate). This is all generated by the keyboard, all the receiving end has to do is acknowledge receipt. Rather than polling (occasionally checking the front door to see if there is anyone there), I used interrupts (fitting a doorbell). One to trigger on a clock pulse, and one to time the acknowledge pulse.
Here you can see the interrupt pulses when clock changes (PCI=Pin Change Interrupt), and the timed acknowledge pulse at the end. The data is read when the clock is low, so this shows 11111001, or rather 00000110 since the data is inverted, or rather 00000011 as the data is sent in the order 65432107. 0x03 is the 3/£ key on the keyboard being pressed.
This is followed by 10000011, 0x83, which is the 3 key being released. The data line is open collector, pulled high so either the keyboard or the receiver can pull it low. The protocol prescribes that the receiver should pull the data line low for 85uS after the last bit, this is what the timer interrupt is doing. If there is no suitable acknowledgement sent, the keyboard keeps sending 1's until the receiver sends a valid acknowledgement. This allows both ends to get back in sync if there is a loss of communication.
The keyboard mapping was fairly straightforward, by this point many of the keyboard layouts were converging on what became the standard PC layout. The few oddities were the hard reset, help and #/@ keys and caps lock. Help is carried over from the Commodore 264 series (+4/C16). I've mapped that to Insert, which is what the emulator expects. The #/@ key is the only one which needs to have a different key sent when shift is held, as it is two keys #/~ and '/@ on a modern keyboard. Caps lock is doesn't have up and down codes like the rest, just on and off, so these have to be handled separately.
When Ctrl + + A is pressed, this will send a warning to the Amiga that it is about to be reset, then it pulls the CPU reset line low, I've mapped this as Ctrl + Alt + Delete. Finally, numlock is printed on the numpad '(' key, and scroll lock on the ')' key, so these are activated with shift, and the floppy LED shows when numlock is on. The Amiga emulator uses F12, which isn't on the keyboard, so I have set the / key on the numpad to be F12, unless numlock is set, as that was unassigned.
I've designed a custom USB keyboard controller board for the A500, with 9 way D two joystick ports and the keyboard interface.
This allows two original Commodore or Atari 9 way D joysticks to be used as USB joysticks. I left space for a mode switch, in case it is required, but currently isn't.
The unpopulated area on the left of the controller PCB is a DC-DC converter to supply power to the Raspberry Pi version of this. Well, there's so much space in there, seems rude not to fit a Raspberry Pi at least, but that's another project, for another day. (update: Raspberry Pi 2 inside A500)
You can order one of these controllers below:
Commodore Amiga 500 USB keyboard kit
Tune in tomorrow to open another window on the Advent Calendar of USB keyboards.