2.20's BIOS architecture is fundamentally different from 2.23's
Stage 2’s emulator devlog found that in 2.23, the 6502 boot leaves $FA00-$FFFF empty — every BIOS handler is runtime-generated by the Z-80. Today’s experiment runs the same emulator against the 2.20 disk image. The result is the opposite: 2.20’s 6502 does write thousands of bytes into LC RAM during boot.
What 2.20 boot does differently
Running the Stage-2 emulator against CPM220Disk1.po with the slot-scanner $3E patch installed at the 2.20-specific address ($1063), the 6502 completes its boot phase. After 2.3 M instructions:
- 6620 writes to
$D000-$FFFF(vs ~6 in 2.23) - 6614 of those come from PC
$0BD8— inside the RWTS write loop in the 6502 LOAD_CPM_PRIM area - Pages
$EB-$FFare heavily populated (160-254 non-zero bytes per page)
The first writes are at $E400:
$E400: C3 5C C7 C3 58 C7 7F 00 20 20 20 20 20 20 20 20 ...
Those are Z-80 JP $C75C; JP $C758; ... entries — Pascal firmware vector targets in slot 7. Followed by a “COPYRIGHT” string at $E418. So $E400 is the start of a Z-80 dispatch / device-driver region.
The contrast with 2.23 is total. 2.23’s LOAD_CPM writes to a staging area at $8000-$9CFF and PREP_HANDOFF redistributes it. 2.20’s LOAD_CPM writes destinations directly to LC RAM at $E400+, fitting ~7 KB worth into pages $E4-$FF.
What’s still unexplained
The Z-80 reset vector planted by 2.20 is $C3 $00 $DA — i.e. JP $DA00. But after boot:
$DA00-$DA20: all zeros
$DACC-$DAEC: all zeros (the supposed BIOS jump table area)
So the same puzzle that 2.23 has applies to 2.20: the planted Z-80 reset vector points at empty memory. The Z-80 still needs the cold-boot generator to run before it can do useful work.
One difference that may explain this: 2.20’s heavily-populated $EB-$FF region likely contains the cold-boot generator. The Z-80 might start at $DA00 (empty), walk forward through more empty space, eventually hit $E400+ populated code, and the generator there writes to $DA00-$DAFF afterwards. Or the SoftCard switch picks up the Z-80 PC at the 6502’s last fetch address ($0E36), not at $DA00 or $0000.
The Stage-3 emulator (with bidirectional CPU switch and Videx slot-3 model) will trace both candidates.
What this confirms
The 2.20 → 2.23 architectural shift documented in Part 9 goes deeper than just adding 11 bytes for Pascal 1.1 detection. Microsoft restructured the entire BIOS-load mechanism between the two versions:
- 2.20: 6502 RWTS writes BIOS code directly to LC RAM during LOAD_CPM. Cold-boot generator’s role is smaller.
- 2.23: 6502 RWTS writes to staging only. PREP_HANDOFF redistributes to specific main-RAM regions. Cold-boot generator at runtime builds the BIOS proper at
$FAxx-$FFxx(the “BIOS factory” pattern documented in Part 6).
The 2.23 architecture is more flexible — runtime-built handlers can vary per detected hardware (which is exactly what enables the Pascal 1.1 / Videx fix). 2.20’s “everything is on disk” approach is simpler but less extensible.
Status
Confirmed: 2.20 and 2.23 have fundamentally different BIOS-load architectures. 2.20 puts most BIOS bytes on disk; 2.23 generates them at runtime. Open: how exactly the Z-80 reaches its actual entry point in either version.