YACC1 disk operating system — the plan (decisions of 2026-09-22)¶
Bring the P8X system (a RAM-resident OS loaded from CompactFlash, a hierarchical filesystem, a shell, C commands in
/bin) to the YACC1. Serial console first; the video card and a PS/2 keyboard come later behind the same console
vectors. BASIC leaves the ROM and returns as a /bin command. The decisions are in this file; the phases at the end
are the order of work. Nothing here is built yet.
Decisions¶
- CF card in I/O space, two ports. P8 = register-select latch (write-only, the ATA register number 0-7 in
the low three bits), P9 = data port (reading or writing it strobes -IOR/-IOW on the selected task-file register).
The driver writes the select once per register access; a 512-byte transfer selects the data register once and
then loops
INP P9 / STAVR Rn / INCR Rn. Chosen over eight direct ports to keep six of the sixteen ports free: the I/O card already holds P0-P7 (its 74138 decodes IO-ADDR0..2; IO-ADDR3 goes to a strap) for the two it uses. Chips: 74245 data buffer, a 74LS174/273 select latch, the port decode (IO-ADDR3 high, IO-ADDR0..2 = 0/1), strobe gating from -IO-RD/-IO-WR, the CF status pull-ups, activity LED. True IDE 8-bit mode (SET FEATURES $EF/$01 at init), the P8X card's circuit otherwise (p8x/hardware/cf-card/). First KiCad-native card of the machine.
Note 2026-09-23/24: the ports were moved to P4/P5 for an I/O card v2.0 carrying the interface (commit
24378cb) and moved back the next day when that plan was dropped (65851b0). The CF stays on P8/P9 as above; the
circuit (the CF card v1.0, hardware/cards/cf/kicad/v1.0, docs/cards/cf.md) is now planned onto the memory card,
still I/O-mapped (schematic done 2026-09-24; the card is being laid out again with it, hardware/cards/memory/kicad/v2.0).
2. Video card v2 puts the 6845 registers on ports too (PA = address register, PB = data register: RS is
IO-ADDR0, no latch), so the card needs only its 2K of display RAM in the memory map. Until then the built card
stays as it is: 2K block, RS-to-A1 fix pending (hardware/cards/video/docs/fix-6845-register-select.md).
3. Port map (16 ports, IO-ADDR0..3, strobes -IO-RD/-IO-WR; yacc1.def had P8=9, fixed 2026-09-22):
| Port | Today | Proposed |
|---|---|---|
| P0 | I/O card select latch (write): UART = UARTCS $40 + register 0/8/…/$38, SWITCHLED $01, LCDENABLE $02, LCDREGISTER $04, TIL311 $80 |
unchanged |
| P1 | I/O card data port for the device selected in P0 (UART registers, switches in / LEDs out, LCD, TIL311) | unchanged |
| P2 | -IO-SEL2 on the I/O card's header, nothing wired; the emulator's console (OUTA P2/INP P2) |
stays the emulator console; reserved to the I/O card |
| P3-P7 | -IO-SEL3..7 on the I/O card's header (its 74138 decodes all eight, the card wires two) | reserved to the I/O card (a second UART, a printer port…); since nothing on the card uses them, probably usable by another card that decodes them itself - verify on the board first (BACKLOG, 2026-09-24) |
| P8 | free | CF register select (write-only latch): bits 0-2 = ATA register 0-7, bit 3 = CF reset (1 = held; 2026-09-23: the card design chose a hardware reset over the CS1 control block, docs/cards/cf.md section 5), bits 4-7 ignored |
| P9 | free | CF data: reading/writing it strobes -IOR/-IOW on the selected register |
| PA | free | video card v2: 6845 address register (RS = 0) |
| PB | free | video card v2: 6845 data register (RS = 1) |
| PC | free | PS/2 keyboard controller data (or on the video v2 card as a terminal card) |
| PD | free | PS/2 keyboard status/control |
| PE, PF | free | free (RTC, second CF select+data, sound) |
The I/O card's IO-ADDR3 strap puts it in P0-P7 or P8-P15; it stays in the low half. Every new device follows the select+data pattern when it has more than one register, so the port space lasts. 4. Memory map — two variants, both jumper-only on the hardware (memory card block jumpers, video 7485 SV3):
| Range | A: video stays at $D000 (no card change today) | B: video moved to $E000 |
|---|---|---|
| $0000-$0FFF | system page: monitor/BIOS variables, sector buffer, stack $0EFF down | same |
| $1000-$4FFF | OS, loaded from CF into RAM (16K reserve = LBA 1-32 as on P8X) | same |
| $5000-$CFFF | transient program area, 32K | $5000-$DFFF, 36K ($D000 jumper up = RAM) |
| $D000-$D7FF | video (2K); $D800-$DFFF unused | RAM |
| $E000-$EFFF | ROM (spare 4K: free for later, blank in the image) | video (2K used) |
| $F000-$FFFF | ROM: monitor + CF driver + boot loader, vectors $FFC0 | same |
Start with A (nothing to change on the cards); B is a jumper move later if the 4K of TPA is wanted. The
software must not care which: the OS's TPA top is one constant.
5. ROM holds only sectors, never the filesystem (the CP/M arrangement): monitor, CF init/read/write by LBA,
a B command that reads N sectors from LBA 1 to $1000 and JSRURs into them, three new $FFC0 vectors. The
monitor's T-menu tests (1,062 bytes) and BASIC entry points go; the boot code is ~300 bytes. The filesystem
primitives live in the RAM-resident OS, so an OS change never needs a ROM burn.
6. P8XFS v2 on the card, byte for byte as on the P8X, so p8x/tools/p8xfs.py and the disk images work
unchanged; the OS jump table at $1000 keeps the shape of P8X's $20xx syscalls so C commands port by
swapping lib_abi.c (P1/A on the P8X become R7/ACC here, the monitor's own convention).
7. The OS kernel is written in C with y1cc, not ported from the 5,200 lines of P8X assembly (no indexed
addressing here). Size is the risk (C is 2-3x assembly; a kernel without the window manager is ~10K of P8X
assembly): the compiler's size levers are on its backlog and pay off across the OS and every command.
8. Console = two BIOS vectors (charout/uartin today). The video card and PS/2 keyboard replace them later
without the OS or the commands knowing.
Status 2026-09-22 (evening)¶
Phases 1 and 2 (read-only) are done on both emulators: the CF model (software/cfmodel.h, -c disk.img), the ROM's
CF driver and O boot command (firmware/abi/README.md), tools/p8xfs.py + tools/img2bin.py, and os/y1os.c
(5.1K: dir/cd/pwd/cat/load/run, implicit /BIN programs with arguments; os/README.md). tests/os/run.py replays a
session on both emulators. Not started: write support, the file API for programs, the card itself.
Phases¶
- Emulator CF model on ports P8/P9 backed by a disk image (
-d disk.img, like p8xemu's-c), ~150 lines of C insoftware/emulator/main.c. ROM side: CF driver + B command inmonitor.asm, tests removed, vectors added; proven on the emulator with a P8XFS image whose LBA 1.. holds a test program. Burn = the same ROM burn already pending for the G fix. Hardware in parallel: the CF card in KiCad (rails and pull-ups checked first, this week's lesson), built, bench-tested with the bus tester before the CPU touches it. - OS kernel v0 in C: boot into a shell over P8XFS v2 read-only (dir, cd, cat, run, load), then write support
(save, del, mkdir, pack, format), fsck last. Host-side disk images from
p8xfs.py. - Commands:
lib_abi.cfor the YACC1 addresses, then the P8X C commands that fit y1cc (static frames: the recursive ones — tree, find — waited for recursion, which y1cc has since 2026-09-24, or got rewritten iteratively). BASIC re-assembled at a TPA address with its RAM equates moved, as/bin/basic. - Video console + PS/2 keyboard: video card v2 (6845 on PA/PB, 2K RAM), a keyboard controller on a free port, both behind the console vectors.
Still open¶
- Whether the OS load address stays $1000 if the OS grows past 16K (the map has room to move it; P8X's did twice).
- Dual CF (P8X supports two volumes); a second card at PC/PD would be the direct copy.
- The E-command RAM loader on the backlog becomes unnecessary once the CF card boots; until then it is the only way to run compiled programs on the machine.