# Display Board 1408 — outputs, and what the RIO shows on it Complete definition of the RIO External Display board (P/N 1408 Rev. 1, `DSP_1408` sheet 7), from the schematic, the board photos, the GAL decode, and the firmware disassembly (`RIOv4_2.disasm.asm`). ## Outputs: light only — the board is electrically write-only No signal leaves the board toward the RIO or anything else. J1 has no readback line, matching the GAL's write-only `DSP_SEL*` decode, and the PC↔RIO protocol has no display command — only the firmware writes it. ### 1. Eight multiplexed 7-segment digits (U2–U9, LTS313A, red, common-cathode) The ICM7228B (U1) does all driving. `HEX/B/SHD` is strapped high via 2.7 K (R1): **hexadecimal decode mode, always enabled** — each digit renders 0–F plus a decimal point; no raw-segment access exists as built. - **Segment bus** — U1 pins 16, 17, 20, 18, 21, 22, 23, 15 drive `SEGA`–`SEGG`, `SEGDP`, shared by all digits (digit pins A–G, DP = 10, 9, 8, 5, 4, 2, 3, 7). Segments source the multiplexed current (~20 mA peak). - **Digit commons** — U1 outputs `DSP1`–`DSP8` (pins 4, 25, 3, 1, 26, 2, 27, 24) each sink one digit's tied-together commons (CC1+CC2, pins 6+1). `DSP1`→U2 (leftmost) … `DSP8`→U9 (rightmost). - Multiplex scanning is internal to the ICM7228; the host only writes digit registers. From the 68HC11 the digits are bytes at **`$A000`–`$A007`** (`AS0-2` = A0–A2, strobed by `DSP_SEL*` = `E & /R/W`-qualified, arriving as the 7228's `/WR` on J1 pin 7). Data format per write: bits 0–3 = hex value (`MD[00:03]`→`ID0-3`), bit 4 = decimal point (`MD[04]`→`ID7`; DP lights when the bit is **low** — the firmware always sets it, so the DP is never used). **`$A000` = leftmost digit (U2), `$A007` = rightmost (U9)**; the firmware's render buffer (`$2038`, routine `$CB49`) fills right-to-left so multi-digit hex numbers read naturally. ### 2. Twelve passive monitor LEDs on the "IBM printer port" header (J2) — an input, not an output J2 (26-pin IDC, standard LPT-ribbon mapping to a DB25) is electrically isolated from the display circuit; its `DD` nets touch nothing but LEDs and 1 K resistors referenced to the PC's own ground (`IBM_GND`). With a PC parallel port plugged in, the LEDs show: **D0–D7** = data bits (J2 pins 3, 5, 7, 9, 11, 13, 15, 17), **D8** = `/STROBE` (pin 1), **D9–D11** = `/AUTOFD`, `/INIT`, `/SELECTIN` (pins 2, 6, 8). The LPT status returns are strapped to ground so a PC streams without waiting. It is a built-in parallel-port activity monitor / bench tool, powered entirely by the PC. ### 3. Nothing else J1 (14-pin, from the RIO's EXTERNAL DISPLAY port) is all input: `MD[00:04]` on pins 2, 4, 6, 8, 10; `AS0-2` on 1, 3, 5; `BF_DSP_SEL*` on 7; GND on 9, 11, 13; VCC on 12, 14. ## What the RIO firmware displays (v4.2) All display writes go through `$CB49` (buffer render) or five canned patterns at `$CB7C–$CC52`, driven from three contexts: initialization, the built-in **test mode**, and the **serial error/crash displays** (below). During normal, healthy gameplay the display is static. **Normal operation:** `F0000000` — written at cold boot (`$C068`) and warm re-init (`$C64B`), then left alone. **Test mode** — entered by typing the keypad sequence **A, 9, E** on a cockpit keypad (`$C1CB` tracks the sequence at `$20F8`); entry sets flag `$2421`, shows `F1000000`, and notifies the PC (`TestModeChange`, cmd `0x8C` — see [PROTOCOL.md](../PROTOCOL.md)). Within test mode the next keypad digit selects a sub-test; **F** ends a sub-test (back to `F1000000`), **D** exits test mode (back to `F0000000`). Display format convention: **left pair = test number, right = value**, zeros as filler; the decimal points are never used. | Key | Display | Test | |-----|---------|------| | *(entry)* | `F1000000` | test-mode banner | | `0` | `00000000` | encoder-counter reset: presets the five 16-bit accumulators to `$FAFA` and re-reads all HCTL-2016s (`$C446`) | | `1` | `0100hhll` | axis test, channel 01 — counter at `$A028/$A038` | | `2` | `0200hhll` | axis test, channel 02 — `$A020/$A030` | | `3` | `0300hhll` | axis test, channel 03 — `$A022/$A032` | | `C` | `0C00hhll` | axis test, channel 0C — `$A024/$A034` | | `4` | `0400hhll` | axis test, channel 04 — `$A026/$A036` | | `5` | `050000nn` | button test — `nn` = index of the pressed input (scan at `$D004` over the pod input state at `$2152`), with lamp feedback | | `6` | `06000003` | lamp test, pattern 3 (`$D34A`) — right digit is the pattern code | | `7` | `07000001` | lamp test, pattern 1 (`$D370`) | | `8` | `080000kk` | keypad test — `kk` = keypad status byte `$204B`, refreshed while scanning (`$CC7E`) | In the axis tests `hhll` is the **live 16-bit quadrature count in hex** (high:low = `$201D:$201E`, alternating with the raw latched bytes `$2026:$2025` as the loop runs) — spin the stick/throttle/pedal encoder and watch the number move. The channel IDs are literally the keypad keys that start them, which is why the fourth axis reads `0C`. ## Error displays (the third use) Two more display writers live in the serial machinery — the display is also the RIO's **error annunciator**: - **`E0` serial-diagnostics readout** (`$D5F2`) — `E0xxyyzz` where `xx` = TX-ring overflow count (`$3187`, outbound byte dropped because the ring was full, `$D66A`), `yy` = reply-retransmit count (`$3184`, the game failed to ACK a reply, `$D96A`), `zz` = reply-teardown/give-up count (`$3185`, `$DA2F`). Each increment site immediately re-renders, so the display live-updates as serial trouble accumulates. If a cockpit's display reads `E0…` instead of `F0000000`, the serial link has been dropping or retrying. Note there is **no threshold in stock firmware** — the first event paints `E0000001` permanently; the `_e0t5` patched images (`make_patch.py --e0thresh`, see [RIOv4_2-ANALYSIS.md](../../rio-firmware/RIOv4_2-ANALYSIS.md)) keep the display quiet until a counter reaches 5. - **`dEAd` crash screen** (`$DAB8`, loop at `$DAB2`) — the TX-ISR ring drain (`$D8C2`) looks each outgoing command byte up in an 8-entry dispatch table at `$3158`; an unmatched byte means internal state corruption, and the firmware jumps to an infinite loop that renders `#$DE #$AD` → **`dEAd`** followed by RAM bytes `$0000/$0001` (nothing in this build writes them — vestigial debug data). The board is dead until reset; there is no watchdog to rescue it (the MAX690's WDI is not connected to the CPU and no strobe code exists in the firmware). ## Cross-references - [README.md](README.md) — board family, photos, schematic page map - [gal/README.md](gal/README.md) — `DSP_SEL*` decode (`$A000-$A00F`, write-only) recovered from the GAL fuse map - [`rio-firmware/RIOv4_2.disasm.asm`](../../rio-firmware/RIOv4_2.disasm.asm) — display routines `$CB20/$CB36/$CB49` (buffer render), `$CB7C` (`F0`), `$CBA7` (`F1`), `$CBD2`/`$CBFD` (lamp-test banners), `$CC28` (zeros), test dispatcher `$C241`, entry-sequence tracker `$C1CB`