The Mattel Intellivision (#67, 1979) and Fairchild Channel F (#68, 1976) push the fleet back to the origins of home gaming — the Channel F is the world's first programmable ROM-cartridge video game console. sigil-drivers completes the VGA driver stack with the Attribute Controller (0x3C0/3C1/3DA flip-flop, EGA palette mapping, overscan, blink) and adds PS/2 mouse (i8042 aux, 0xA8 enable, D4+F2 Get-ID → 0x00). sigil-fs lands NTFS non-resident file growth (ntfs_bitmap_alloc scanning $Bitmap MFT record 6, ntfs_append_nonres extending runlists) plus the mkimage build fix (btrfs stubs). (sigil-retropie 334e11c, bd68e43; sigil-drivers c31bdf6, 2fd0f97; sigil-fs 8449a6c, cb70a4c, 2352dc1)
Intellivision — System #67 PASS
Commit 334e11c. Core: cores/intellivision.sg. uart=67.
CPU: General Instrument CP1610
The CP1610 (1975) is a 16-bit processor — one of the earliest 16-bit CPUs deployed in a home game console, wider than the contemporary MOS 6502 and Zilog Z80. It runs at 894kHz under the NTSC clock rate. The register file has 10 registers: R0–R7 as general-purpose registers, with R5 serving as the program counter, R6 as the stack pointer, and R7 as an auxiliary register. The instruction set includes direct addressing, a hardware stack for subroutine calls, and the SDBD (Set Double-Byte Data) prefix for 16-bit immediate loads — the CP1610's mechanism for hinting the bus about 16-bit transfers.
Graphics: STIC (Standard Television Interface Circuit)
The STIC produces a 160×96 display with 16 colors. It manages two graphics layers: 8 moveable objects (sprites, called MOBs — Moveable OBjects) and a 20×12 background card grid. Each background card cell is 8×8 pixels, drawn from a character ROM or the cartridge graphics data. The STIC handles collision detection between MOBs and between MOBs and background cards in hardware.
Memory
- 4KB built-in EXEC ROM: the Intellivision's firmware, providing the BIOS and runtime library. The EXEC is the reason Intellivision carts are so compact — common routines live in the EXEC, not in cart ROM.
- 512 bytes IRAM (scratchpad): fast on-chip RAM for variables and the stack.
- 16-bit cartridge ROM slot: the Intellivoice and other peripherals are also mapped through this bus.
The Intellivision was the Atari 2600's main rival from 1979 through the early 1990s. It featured the first professional sports video games licensed from the major US sports leagues. Its 16-bit CPU gave it a genuine hardware advantage over the 2600's 8-bit 6507 — Mattel's marketing leaned heavily on "16-bit game system" years before 16-bit consoles became the industry standard.
Channel F — System #68 PASS
Commit bd68e43. Core: cores/channelf.sg. uart=68.
CPU: Fairchild F8
The Fairchild F8 (1974) is technically an 8-bit processor, but it is implemented as a two-chip set: the 3850 CPU and the 3851 PSU (Program Storage Unit). This two-chip architecture was unusual and arose from Fairchild's pin-count constraints. The F8 has several distinctive design choices:
- 64 bytes of on-chip scratchpad RAM: addressed indirectly via the ISAR (Indirect Scratchpad Address Register). The scratchpad holds variables, the stack, and frequently used working data without going off-chip.
- Accumulator (ACCU): a dedicated 8-bit accumulator for arithmetic and logic operations.
- 4 FLAGS: condition code flags for branching (sign, zero, carry, overflow).
Graphics: 128×64 VRAM
The Channel F outputs to a television via RF. Its display is 128×64 pixels, with 2 bits per pixel — four colors from a fixed palette (black, white, red, blue). The VRAM is directly mapped and written by the CPU; there is no sprite hardware or background layer. Every pixel is CPU-driven.
Memory
- 2KB built-in BIOS ROM: system firmware and the built-in hockey/tennis games (accessible without a cart).
- 2KB cartridge ROM (VideoCart): the ROM cartridge slot. Maximum 2KB per cart under the original addressing scheme (later extended by bank-switching in third-party carts).
- Total 4KB address space — the tightest address space in the RetroPie fleet.
The Fairchild VES (Video Entertainment System) — renamed Channel F in 1977 — is the world's first programmable ROM-cartridge video game console (1976), predating the Atari 2600 by a year. Every modern game console that uses ROM cartridges traces its lineage to the Channel F. The VideoCart format established the model: a self-contained game on a ROM chip in a plastic housing, swapped by the user. At system #68, the sigilOS RetroPie fleet now spans from the original cartridge console (1976) to the Nintendo Switch (2017) — 41 years of gaming history in a single emulation layer.
VGA Attribute Controller PASS
Commit c31bdf6. Driver: drivers/display/vga-ac. State at 0x940000.
The VGA Attribute Controller (AC) is the last of the five VGA register groups. Adding it completes the full VGA register surface in sigil-drivers. The AC bridges EGA palette registers to the VGA DAC — it maps the 4-bit EGA color index (from the plane data) to a 6-bit DAC entry index (which the DAC then maps to 18-bit RGB).
I/O and flip-flop protocol
The AC uses a shared index/data port at 0x3C0, controlled by a hardware flip-flop:
- 0x3C0: index + data mux (write). First write after a flip-flop reset is the index byte; second write is the data byte.
- 0x3C1: data read-only (the current value of the register indexed by the last index write).
- 0x3DA: INPUT_STATUS1 — reading this port also resets the flip-flop to index mode.
ac_reset_ff()reads 0x3DA before every access sequence to guarantee the flip-flop state. - PAS bit: bit 5 of the index byte must be set (value += 32) on all index writes. This enables display output (Palette Address Source). Clearing PAS blanks the screen — used to suppress display artifacts during palette programming.
Registers
Live QEMU text mode 3: MODE_CTRL=0x0C, OVERSCAN=0x00, COLOR_ENABLE=0x0F. Overscan r/w round-trip verified. Palette register 0 r/w verified (write 10, read 10). CLS_DISPLAY dispatcher wired.
VGA register surface: complete
| Subsystem | Registers | Function | Status |
|---|---|---|---|
| CRTC | CR0–CR18 | Timing, cursor, display start | PASS |
| DAC | Palette RAM (256×18-bit) | EGA/VGA index → RGB | PASS |
| Sequencer | SR0–SR4 | Plane mask, clocking, memory mode | PASS |
| GFX Controller | GR0–GR8 | Bit mask, read map, write mode | PASS |
| Attribute Controller | AR0–AR18 | EGA→DAC palette, overscan, blink | PASS |
PS/2 Mouse Driver PASS
Commit 2fd0f97. Driver: drivers/input/ps2-mouse. State at 0x930000.
The PS/2 mouse is routed through the i8042 KBC (Keyboard Controller) as the auxiliary (AUX) port — a separate channel from the keyboard path, gated by the KBC's AUX enable bit and AUX buffer flag.
Initialization sequence
kbc_flush(): drains stale bytes from the KBC output buffer before probing. Essential — a dirty buffer causes the Get-ID response to be misinterpreted.ps2ms_enable_aux(): sends command0xA8(Enable AUX Interface) to the KBC command port (0x64). Then writes the KBC command byte with bit 5 cleared to enable AUX IRQ routing to IRQ12.ps2ms_get_id(): issuesD4(Write Next Byte to AUX Port) +F2(Get Device ID) through the KBC. Waits for ACK (0xFA) followed by the device ID byte. Standard PS/2 mouse returns0x00; scroll-wheel mouse returns0x03; 5-button mouse returns0x04.kbc_wait_aux_data(): polls KBC status register until OBF=1 (output buffer full) AND AUXB=1 (bit 5 set, indicating data is from AUX port, not keyboard). Returns the byte.
Live QEMU: 0xA8 enable → D4+F2 Get-ID → ACK=0xFA + ID=0x00 (standard PS/2 mouse). PASS.
Dispatcher: CTL_GET_ID / CTL_ENABLE / CTL_DISABLE / CTL_RESET via ps2ms_probe.
NTFS Non-Resident File Growth PASS
Commit 8449a6c (sigil-fs). Functions: ntfs_bitmap_alloc + ntfs_append_nonres.
Small NTFS files store their data inline in the MFT record (resident $DATA attribute). Large files store their data in disk clusters and keep a runlist in the MFT record — a compact encoding that maps virtual cluster numbers (VCNs) to logical cluster numbers (LCNs) on disk. Until this commit, ntfs_append only handled the resident case. Non-resident files would fail silently.
ntfs_bitmap_alloc
Scans MFT record 6 ($Bitmap — the volume cluster allocation bitmap) byte by byte, searching for the first clear bit. Sets the bit (marks the cluster used) and writes the bitmap record back via ntfs_write_record. Returns the LCN (logical cluster number) of the allocated cluster, or -1 if the volume is full. This is the first cluster allocator in sigil-fs.
ntfs_append_nonres
Appends len bytes from src to a non-resident $DATA attribute:
- Decodes the existing runlist to find
last_end_lcn— the LCN immediately after the last run. - Calls
ntfs_bitmap_allocto get the new cluster LCN. - If the new LCN is consecutive (equals
last_end_lcn), extends the last run entry's length field in place — no new run header needed. - If non-consecutive (fragmented), inserts a new run header (
0x11= 1-byte length field + 1-byte offset field) followed by the delta LCN offset. - Writes the data bytes to the allocated cluster sectors via
blk_write. - Updates
AllocatedSize,DataSize, andValidDataSizein the $DATA attribute header. - Calls
ntfs_write_recordto persist the updated MFT record to disk.
Dispatch wiring
ntfs_append now checks the $DATA attribute's resident/non-resident flag and dispatches to ntfs_append_nonres for non-resident files. Previously only the resident path was wired — non-resident files would fall through to the resident handler and corrupt the attribute.
Test: empty non-resident file → append 100 bytes → verify DataSize=100 → read back 4 bytes → match source (ABCD). All 22 NTFS tests PASS.
mkimage Build Fix BUILD CLEAN
Commits 2352dc1 + cb70a4c (sigil-fs). Script: make-sigilos-img.sh.
The image build script was missing vfs_stubs_disk.sg and vfs_stubs_net.sg from its source list. At image-cut time the assembler emitted KS_ERR_ASM_SYMBOL_MISSING for btrfs_lookup_dir and btrfs_readdir_in — symbols defined in the stubs but absent from the build. The stubs implement the VFS contract for disabled providers by returning -1 or 0, and are required at link time even when the provider is not active.
Both stub files are now listed in the build manifest. The fix landed in time for the 0.5.0 image cut — the 0.5.0 image pipeline is clean (423KB, 0 bad, Director GREEN LIGHT). Verified clean at cb70a4c.