mirror of
https://github.com/alfishe/amiga-bootcamp.git
synced 2026-06-13 00:26:28 +00:00
Phase 1: enrich 07_dos and 10_devices (highest FPGA priority)
07_dos: - file_io.md: 108→240+ lines — buffered I/O (FRead/FWrite/SetVBuf), access mode comparison, FileHandle struct with offsets, standard handles, Printf %ld warning, FileInfoBlock, practical patterns (copy file, get size, load to RAM), error code table - filesystem.md: 91→270+ lines — full disk geometry (ADF/HDF), all 8 DOS\x filesystem IDs, root block byte-level layout, file header layout with reverse-order pointer quirk, OFS vs FFS data blocks with efficiency numbers, bitmap blocks, extension blocks, checksum algorithm, Python ADF reader - locks_examine.md: 113→270+ lines — lock semantics diagram, FileLock struct with handler discovery, ExAll bulk scan, practical patterns (atomic write, path resolution, volume info), 4 antipatterns (leaked locks, exclusive too long, unchecked IoErr, DupLock), pattern matching 10_devices: - audio.md: 73→240+ lines — hardware architecture diagram, channel registers with offsets, period/frequency table, priority allocation, double-buffering, audio interrupts, AM/PM modulation, direct HW - timer.md: 80→230+ lines — CIA timer hardware, all 5 units with decision flowchart, non-blocking delays, signal-based waiting, time arithmetic, ReadEClock, periodic game loop pattern, pitfalls - trackdisk.md: 82→210+ lines — MFM encoding, track format, disk geometry, read/write/motor, change notification, track caching, direct hardware access, FPGA timing implications - keyboard.md: 58→220+ lines — CIA-A serial handshake protocol with sequence diagram, bit rotation quirk, complete key code map, key matrix bitmap, reset sequence, FPGA notes
This commit is contained in:
parent
aeaea88d75
commit
da9e7d3b63
7 changed files with 1599 additions and 301 deletions
|
|
@ -1,48 +1,179 @@
|
|||
[← Home](../README.md) · [Devices](README.md)
|
||||
|
||||
# keyboard.device — Keyboard Input
|
||||
# keyboard.device — Keyboard Hardware and Raw Key Codes
|
||||
|
||||
## Overview
|
||||
|
||||
`keyboard.device` provides raw keycode events from the keyboard controller (8520 CIA-A). Normally used indirectly via `input.device`, but can be accessed directly for keymap-independent scanning.
|
||||
`keyboard.device` provides access to the Amiga keyboard via the CIA-A serial port handshake protocol. The keyboard controller (a dedicated 6500/1 or 68HC05 microcontroller inside the keyboard) transmits **raw key codes** as serial data through CIA-A. Understanding this protocol is essential for FPGA core implementation.
|
||||
|
||||
---
|
||||
|
||||
## Keycodes
|
||||
## Hardware Protocol
|
||||
|
||||
Amiga keycodes are 7-bit values (0–127). Bit 7 indicates key-up:
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant KB as Keyboard MCU
|
||||
participant CIA as CIA-A (SP/CNT pins)
|
||||
participant CPU as 68000 (interrupt)
|
||||
|
||||
KB->>CIA: Serial data (8 bits, MSB first)
|
||||
Note over CIA: CIA-A SP register latches byte
|
||||
CIA->>CPU: CIA-A ICR bit 3 (SP interrupt)
|
||||
CPU->>CIA: Read $BFEC01 (SP data register)
|
||||
CPU->>CIA: Pulse KDAT line low for ~85µs
|
||||
Note over CIA: Handshake acknowledges receipt
|
||||
KB->>KB: Ready for next key
|
||||
```
|
||||
|
||||
### CIA-A Registers Used
|
||||
|
||||
| Register | Address | Bit | Function |
|
||||
|---|---|---|---|
|
||||
| `CIASDR` | `$BFEC01` | 7:0 | Serial data register — receives raw key code |
|
||||
| `CIACRA` | `$BFEE01` | 6 | SP direction: 0=input (keyboard), 1=output |
|
||||
| `CIAICR` | `$BFED01` | 3 | SP interrupt flag — set when byte received |
|
||||
|
||||
### Raw Key Code Format
|
||||
|
||||
The keyboard sends an 8-bit value where:
|
||||
- **Bit 7** = key state: 0 = **pressed**, 1 = **released**
|
||||
- **Bits 6:0** = key code (0–127)
|
||||
|
||||
```c
|
||||
/* Decode a raw key event: */
|
||||
UBYTE raw = ~(cia->ciaSDR); /* invert (active low) */
|
||||
raw = (raw >> 1) | (raw << 7); /* rotate right 1 bit */
|
||||
UBYTE keycode = raw & 0x7F;
|
||||
BOOL keyup = raw & 0x80;
|
||||
```
|
||||
|
||||
> **Bit rotation**: The keyboard transmits bits in a rotated format. The software must rotate the received byte right by 1 bit to get the actual key code. This is a hardware design quirk.
|
||||
|
||||
### Handshake Timing
|
||||
|
||||
After reading the key code, the CPU must acknowledge by pulsing the KDAT line:
|
||||
|
||||
```asm
|
||||
; Acknowledge key reception:
|
||||
OR.B #$40, $BFEE01 ; CIACRA — set SP to output
|
||||
; Wait at least 85 µs
|
||||
MOVE.B #0, $BFEC01 ; drive KDAT low
|
||||
; (timer or loop delay ~85 µs)
|
||||
AND.B #~$40, $BFEE01 ; CIACRA — set SP back to input
|
||||
; Keyboard is now ready to send next key
|
||||
```
|
||||
|
||||
> **FPGA note**: If the handshake acknowledgement is too fast (<75µs) or too slow (>200ms), the keyboard MCU will resend the key code or initiate a reset sequence.
|
||||
|
||||
---
|
||||
|
||||
## Raw Key Code Map
|
||||
|
||||
### Main Keys
|
||||
|
||||
| Code | Key | Code | Key | Code | Key |
|
||||
|---|---|---|---|---|---|
|
||||
| $00 | `` ` `` (backtick) | $01 | `1` | $02 | `2` |
|
||||
| $03 | `3` | $04 | `4` | $05 | `5` |
|
||||
| $06 | `6` | $07 | `7` | $08 | `8` |
|
||||
| $09 | `9` | $0A | `0` | $0B | `-` |
|
||||
| $0C | `=` | $0D | `\` | $10 | `Q` |
|
||||
| $11 | `W` | $12 | `E` | $13 | `R` |
|
||||
| $14 | `T` | $15 | `Y` | $16 | `U` |
|
||||
| $17 | `I` | $18 | `O` | $19 | `P` |
|
||||
| $1A | `[` | $1B | `]` | $20 | `A` |
|
||||
| $21 | `S` | $22 | `D` | $23 | `F` |
|
||||
| $24 | `G` | $25 | `H` | $26 | `J` |
|
||||
| $27 | `K` | $28 | `L` | $29 | `;` |
|
||||
| $2A | `'` | $31 | `Z` | $32 | `X` |
|
||||
| $33 | `C` | $34 | `V` | $35 | `B` |
|
||||
| $36 | `N` | $37 | `M` | $38 | `,` |
|
||||
| $39 | `.` | $3A | `/` | $40 | `Space` |
|
||||
| $41 | `Backspace` | $42 | `Tab` | $43 | `Numpad Enter` |
|
||||
| $44 | `Return` | $45 | `Escape` | $46 | `Delete` |
|
||||
|
||||
### Modifier and Special Keys
|
||||
|
||||
| Code | Key | Code | Key |
|
||||
|---|---|---|---|
|
||||
| `$00` | \` (backtick) | `$40` | Space |
|
||||
| `$01`–`$0A` | 1–0 | `$41` | Backspace |
|
||||
| `$10`–`$19` | Q–P | `$42` | Tab |
|
||||
| `$20`–`$28` | A–L | `$43` | Enter (keypad) |
|
||||
| `$31`–`$39` | Z–/ | `$44` | Return |
|
||||
| `$45` | Escape | `$46` | Delete |
|
||||
| `$4C` | Cursor Up | `$4D` | Cursor Down |
|
||||
| `$4E` | Cursor Right | `$4F` | Cursor Left |
|
||||
| `$50`–`$59` | F1–F10 | `$5F` | Help |
|
||||
| `$60` | Left Shift | `$61` | Right Shift |
|
||||
| `$62` | Caps Lock | `$63` | Control |
|
||||
| `$64` | Left Alt | `$65` | Right Alt |
|
||||
| `$66` | Left Amiga | `$67` | Right Amiga |
|
||||
| $60 | `Left Shift` | $61 | `Right Shift` |
|
||||
| $62 | `Caps Lock` | $63 | `Ctrl` |
|
||||
| $64 | `Left Alt` | $65 | `Right Alt` |
|
||||
| $66 | `Left Amiga` | $67 | `Right Amiga` |
|
||||
|
||||
### Cursor and Function Keys
|
||||
|
||||
| Code | Key | Code | Key |
|
||||
|---|---|---|---|
|
||||
| $4C | `Cursor Up` | $4D | `Cursor Down` |
|
||||
| $4E | `Cursor Right` | $4F | `Cursor Left` |
|
||||
| $50–$59 | `F1`–`F10` | $5F | `Help` |
|
||||
|
||||
### Special Codes
|
||||
|
||||
| Code | Meaning |
|
||||
|---|---|
|
||||
| $78 | **Reset warning** — Ctrl+Amiga+Amiga pressed (keyboard sends this before resetting) |
|
||||
| $F9 | Last key code was bad (parity error) — resend |
|
||||
| $FA | Keyboard buffer overflow |
|
||||
| $FC | Keyboard self-test failed |
|
||||
| $FD | Initiate power-up key stream |
|
||||
| $FE | Terminate power-up key stream |
|
||||
|
||||
---
|
||||
|
||||
## Commands
|
||||
## Using keyboard.device (OS Level)
|
||||
|
||||
| Code | Constant | Description |
|
||||
|---|---|---|
|
||||
| 2 | `CMD_READ` | Read raw keycodes |
|
||||
| 5 | `CMD_CLEAR` | Clear keyboard buffer |
|
||||
| 9 | `KBD_READMATRIX` | Read full key matrix state |
|
||||
| 10 | `KBD_ADDRESETHANDLER` | Add Ctrl-Amiga-Amiga handler |
|
||||
| 11 | `KBD_REMRESETHANDLER` | Remove reset handler |
|
||||
| 12 | `KBD_RESETHANDLERDONE` | Acknowledge reset handler completion |
|
||||
Most applications receive key events through Intuition IDCMP (see [idcmp.md](../09_intuition/idcmp.md)). Direct keyboard.device use is for system-level software:
|
||||
|
||||
```c
|
||||
struct MsgPort *kbPort = CreateMsgPort();
|
||||
struct IOStdReq *kbReq = (struct IOStdReq *)
|
||||
CreateIORequest(kbPort, sizeof(struct IOStdReq));
|
||||
|
||||
OpenDevice("keyboard.device", 0, (struct IORequest *)kbReq, 0);
|
||||
|
||||
/* Read raw key events: */
|
||||
struct InputEvent ie;
|
||||
kbReq->io_Command = KBD_READMATRIX;
|
||||
kbReq->io_Data = &keyMatrix; /* 16-byte key matrix bitmap */
|
||||
kbReq->io_Length = 16;
|
||||
DoIO((struct IORequest *)kbReq);
|
||||
/* keyMatrix bit N = 1 if key code N is currently held down */
|
||||
|
||||
/* Reset keyboard (force self-test): */
|
||||
kbReq->io_Command = KBD_RESETHANDLER;
|
||||
DoIO((struct IORequest *)kbReq);
|
||||
```
|
||||
|
||||
### Key Matrix
|
||||
|
||||
The `KBD_READMATRIX` command returns a 16-byte (128-bit) bitmap where each bit corresponds to a raw key code:
|
||||
|
||||
```c
|
||||
UBYTE keyMatrix[16];
|
||||
/* Bit test: is key $45 (Escape) pressed? */
|
||||
BOOL escPressed = keyMatrix[0x45 / 8] & (1 << (0x45 % 8));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Keyboard Reset Sequence
|
||||
|
||||
The Ctrl+Amiga+Amiga three-key combination triggers a hardware reset:
|
||||
|
||||
1. User presses Ctrl+Left Amiga+Right Amiga
|
||||
2. Keyboard MCU detects the combo
|
||||
3. Sends raw code `$78` (reset warning) — gives software ~10 seconds to clean up
|
||||
4. Pulls KBRST line low → triggers 68000 reset via RESET pin
|
||||
|
||||
> **FPGA**: The core must implement this reset path. The `$78` warning code allows software (e.g., debuggers) to save state before reset.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- NDK39: `devices/keyboard.h`
|
||||
- NDK39: `devices/keyboard.h`, `devices/inputevent.h`
|
||||
- HRM: *Amiga Hardware Reference Manual* — Keyboard chapter
|
||||
- See also: [input.md](input.md) — input.device handler chain
|
||||
- See also: [idcmp.md](../09_intuition/idcmp.md) — high-level key events via Intuition
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue