# C128 Display and Clock Probe Story: E01-S04 Status: observed in VICE x128 3.10; not a final compiler memory map ## Primary Platform Facts The *Commodore 128 Programmer's Reference Guide* documents: - `$00D7` (`MODE`) bit 7: `$00` selects the active 40-column editor and `$80` selects the active 80-column editor. - `$FF5F` (`SWAPPER`): switches the C128 editor's 40/80-column local state. - `$D030` bit 0: set selects 2 MHz and disables VIC video; clear selects 1 MHz and permits VIC video. - `$D030` bit 1 is a chip-test facility and must remain clear. - I/O accesses in 2 MHz mode are stretched to remain synchronized with 1 MHz I/O devices. Sources: - *Commodore 128 Programmer's Reference Guide*, SWAPPER, page 449. - Same guide, 8564 VIC “2 MHz Operation” and “System Clock Control,” pages 589–590: - Installed VICE 3.10 manual, C128 options `-40col` and `-80col`. ## Probe Policy `src/platform/display-clock.s` follows the policy approved by D112: 1. Respect the editor/display already selected by the user. 2. Send all text through KERNAL `CHROUT` (`$FFD2`). 3. Force the conservative 1 MHz baseline before inspecting the display. 4. In 40-column mode, stay at 1 MHz so VIC output remains visible. 5. In 80-column mode, set `$D030` bit 0, perform KERNAL output at 2 MHz, and then restore 1 MHz before returning to BASIC. 6. If display mode or fast-mode activation is uncertain, use 1 MHz. This is the deterministic fallback for the compiler. The probe does not call SWAPPER because the compiler must not override the user's selected display. SWAPPER remains the documented mechanism if a future, separately approved feature explicitly changes displays. ## Observed Results The verification script boots x128 independently with `-40col` and `-80col`. | Mode | MODE captured | Result | Fast observed | Final `$D030` bit 0 | Trace | |---|---:|---:|---:|---:|---| | 40-column | `$00` | `$44` | `$00` | `$00` | `$1C2E` then `$1C8C`; never `$1C49` | | 80-column | `$80` | `$85` | `$01` | `$00` | `$1C3D`, `$1C49`, then `$1C8C` | VICE reads `$FC` from `$D030` after fallback because unconnected upper bits read high; the meaningful speed bit 0 and test bit 1 are both clear. The probe's `final_clock` field stores the masked speed bit and is `$00` in both modes. Result bit meanings are probe-local: bit 7 is the 80-column path, bit 6 is the 40-column path, bit 2 proves ordinary semantic RAM markers survived, and bit 0 proves the 2 MHz control bit read back set. The 40-column screenshot contains: ```text NOVA128 40 COL KERNAL OK 1MHZ FALLBACK OK ``` The 80-column screenshot contains: ```text NOVA128 80 COL KERNAL OK 2MHZ KERNAL IO OK RESTORED 1MHZ ``` ## VDC RAM Boundary The probe never reads or writes VDC address/data registers `$D600/$D601`. Machine-readable state lives in normal CPU RAM at `$1D0F–$1D14`; the build script rejects executable source references to `$D600/$D601`. In 80-column mode, only the C128 KERNAL/editor owns display transfer to VDC-local RAM. This establishes the architectural rule: VDC RAM is display-only and never a home for compiler symbols, semantic tables, stacks, or intermediate data. ## Reproduction From `newLang/`: ```powershell ./scripts/build-display-clock.ps1 ./scripts/verify-display-clock.ps1 ``` Generated screenshots, remote-monitor trace transcripts, PRG, map, and labels remain under ignored `build/`.