The Keyboard ############ Let's look at the keyboard .. image:: Speccy_keyboard_diagram.jpg The Next can support a few different keyboards, but from our point of view they're all the same. It doesn't matter whether you're using a 48k dead flesh keyboard, a 128k keyboard, a clone keyboard, PS2 or the official one on the retail machine. They all work the same. You can't read the extra keys off the PS/2 keyboard, and it's not possible to remap the keys. Z88DK has its own keyboard routines, but they mostly deal with scancodes and ASCII. It's possible to read the keyboard directly. It is arranged in rows, with each row being split into two parts of 5 keys which are accessed through specific IO ports. ====== ====== ====== ====== ====== ====== Port 0 1 2 3 4 ====== ====== ====== ====== ====== ====== 0xFEFE Shift z x c v 0xFDFE a s d f g 0xFBFE q w e r t 0xF7FE 1 2 3 4 5 0xEFFE 0 9 8 7 6 0xDFFE p o i u y 0xBFFE Enter l k j h 0x7FFE Space Sym m n b ====== ====== ====== ====== ====== ====== Bits are set to 0 for a key being pressed and 1 if the key is not pressed. Multiple key presses can be read together. What I have done is use ``z80_inp()`` to read each port in turn, storing the data into an array of bytes .. literalinclude:: keyboard.c :language: C :lines: 29-43 Then I have a list of defines for each key on the keyboard to index into those arrays The values are the index within the array for that key, based on its position within the table above, combined with an index for which row it is on. .. literalinclude:: input.h :language: C :lines: 20-31 Then there are two macros to extract the correct row array, and the correct bit from that array. This is done to turn key lookups into straight forward bitwise operations rather than conditional statements. .. literalinclude:: keyboard.c :language: C :lines: 19-20 To use this I have three functions to get the state of a key depending on what I want to find out .. literalinclude:: input.h :language: C :lines: 12-15