The keyboard device listens for user keypresses and then sends them to the processor for further handling.
The physical layout is modern, especially when compared with typical computers of the era where it often seemed as every computer had a different location for various symbols. Retroputer does have a few custom keys, but nothing that would be surprising to modern users.
Retroputer Key | macOS | Windows |
---|---|---|
fn | Cmd | Windows |
gr | Opt | Alt |
ctrl | Ctrl | Ctrl |
bksp | Delete | Backspace |
enter | Return | Enter |
caps | Caps Lock | Caps Lock |
Logically the keyboard is laid out in five rows of two quadrants. Each quadrant is represented by an I/O byte and can represent if a key is pressed by setting a bit (or a key is not pressed by clearing the bit).
This makes it possible to detect if multiple keys are currently being pressed.
The GR key enables you to type graphical characters with the keyboard. You can access an alternate set by pressing GR+SHIFT at the same time.
The CTRL key is used to translate keys to their corresponding control codes. This only works for alphabetical keys and a few numerical keys. CTRL+H will generate RetSCII code 08
, which corresponds to BACKSPACE.
The following maps the CTRL combination to the resulting control code.
CTRL + | RetSCII Code | Control Code |
---|---|---|
A | 01
|
N/A |
B | 02
|
N/A |
C | 03
|
Break |
D | 04
|
N/A |
E | 05
|
N/A |
F | 06
|
N/A |
G | 07
|
Bell |
H | 08
|
Backspace |
I | 09
|
Tab |
J | 0A
|
Line Feed |
K | 0B
|
N/A |
L | 0C
|
Form Feed / Clear Screen |
M | 0D
|
Carriage Return / Enter |
N | 0E
|
N/A |
O | 0F
|
N/A |
P | 10
|
Cursor Right |
Q | 11
|
Cursor Left |
R | 12
|
F1 |
S | 13
|
F2 |
T | 14
|
F3 |
U | 15
|
F4 |
V | 16
|
F5 |
W | 17
|
F6 |
X | 18
|
F7 |
Y | 19
|
F8 |
Z | 1A
|
F9 |
0 | 1B
|
F10 |
1 | 1C
|
N/A |
2 | 1D
|
Delete |
3 | 1E
|
Cursor Up |
4 | 1F
|
Cursor Down |
Because it's possible that the computer won't have a chance to check for a keyboard character being registered during long computations, the keyboard has a 256-character buffer that will store these until they are read back. Once the user reaches the end of the buffer, additional key presses are lost.
Port | Name | Notes |
---|---|---|
0x30 | RetSCII code of key pressed |
|
0x31 | Buffer Remaining | # of characters remaining in the buffer |
0x32 | r0:0-7 keys pressed | A set bit indicates the key is currently pressed. Zero indicates that it is up. |
0x33 | r0:8-F keys pressed | |
0x34 | r1:0-7 keys pressed | |
0x35 | r1:8-F keys pressed | |
0x36 | r2:0-7 keys pressed | |
0x37 | r2:8-F keys pressed | |
0x38 | r3:0-7 keys pressed | |
0x39 | r3:8-F keys pressed | |
0x3A | r4:0-7 keys pressed | |
0x3B | r4:8-F keys pressed | |
0x3C | – | |
0x3D | – | |
0x3E | – | |
0x3F | – |
You can poll the keyboard for input as follows:
- Read the value of port 0x30
- If it is non-zero, a key is in the buffer waiting to be processed
- You must immediately handle the key; checking the buffer will remove the key from the buffer.
- Repeat!
- Call
PUT_CHAR
if you'd like to echo the results on screen.
- Call
.segment code 0x02000 {
.const PUT_CHAR 0x0FE0C
top:
do {
in dl, 0x30
cmp dl, 0
} while z
call [PUT_CHAR]
br top
}