AddrDecoder (Address Decoder)
Inputs
| Pin | Type | Description |
|---|---|---|
| Addr | bus8 | Memory address (0–255) from the operand or index register |
Outputs
| Pin | Type | Description |
|---|---|---|
| RAM_SEL | bit | 1 = address is in RAM range, enable RAM read/write |
| RAM_SEL8 | bus8 | 0xFF when RAM is selected, 0x00 when I/O is selected — for BusAND gating |
| IO_SEL | bit | 1 = address is in I/O range, enable peripheral access |
| DevAddr | bus8 | Device address within I/O range — Addr & 0x1F (0–31) |
How It Works
The AddrDecoder implements memory-mapped I/O by splitting the 256-address space into two regions:
| Address Range | Size | Region | RAM_SEL | IO_SEL | DevAddr |
|---|---|---|---|---|---|
| 0x00–0xDF (0–223) | 224 bytes | RAM | 1 | 0 | — |
| 0xE0–0xFF (224–255) | 32 bytes | I/O | 0 | 1 | Addr & 0x1F |
The key innovation is the RAM_SEL8 output. This 8-bit signal is used with a BusAND gate to gate the RAM data output:
- RAM access (Addr < 0xE0): RAM_SEL8 = 0xFF → BusAND passes through RAM data unchanged.
- I/O access (Addr ≥ 0xE0): RAM_SEL8 = 0x00 → BusAND outputs 0x00, silencing the RAM so it doesn't conflict with the peripheral driving the data bus.
This gating mechanism is essential because RAM and I/O peripherals share the same data bus. Without RAM_SEL8, both RAM and a peripheral could drive the bus simultaneously, causing a conflict.
In the I/O region, DevAddr = Addr & 0x1F extracts the lower 5 bits, yielding a device number from 0 to 31. Each peripheral compares its address against DevAddr and responds when it matches and IO_SEL = 1.
Usage
The AddrDecoder is the foundation of the I/O subsystem:
- Level 22: build the Address Decoder logic that splits RAM and I/O address spaces.
- Levels 23–29: use it with peripherals (Gamepad, Display, LFSR, MatrixDisplay, etc.).
In a complete CPU with I/O:
- Addr: connects to the memory address bus (from the instruction operand or index register).
- RAM_SEL: connects to RAM OE (output enable) and WE (write enable) gating.
- RAM_SEL8: connects to one input of a BusAND gate; the other input connects to the RAM data output. The BusAND output connects to the shared data bus.
- IO_SEL: connects to all I/O peripheral IO_SEL inputs.
- DevAddr: connects to all I/O peripheral DevAddr inputs — each peripheral checks if DevAddr matches its assigned port.