~/wiseowl/articles

Articles

Long-form technical writing. Each article aims to be the definitive resource on its topic — not a tutorial, but a complete explanation of how something actually works.

27 articles

cpm-videx-series · Part 1 apple-ii6502z80
Why Microsoft CP/M Didn't Recognize an 80-Column Card
advanced

Microsoft SoftCard CP/M 2.20 won't boot when an Apple ][ has a Videx Videoterm 80-column card installed. Version 2.23 boots cleanly. The difference is eleven bytes of 6502 code in the boot loader — and a single byte the Videx ROM has been waiting to be asked about since 1980.

cpm-videx-series · Part 2 apple-ii6502z80
From the Disk II ROM to the Z-80's First Instruction
advanced

Beginning-to-end walk of the 6502 boot stage of SoftCard CP/M 2.23: boot stub, language card switch, slot scan, Z-80 reset vector planting. Three kilobytes of 6502 code between disk click and Z-80 takeover, plus the surprise that the loader contains no SoftCard CPU-switch write.

cpm-videx-series · Part 3 apple-ii6502z80
Apple Memory, Through Z-80 Eyes
advanced

How the Microsoft Z-80 SoftCard fits a Z-80 CPU into an Apple ][ that doesn't share its instruction set, and what the SoftCard CP/M BIOS looks like once you can read its first few hundred bytes. The address-line XOR nobody warns you about; a per-device dispatch table 2.20 didn't have.

cpm-videx-series · Part 4 apple-ii6502z80
The Handoff: 6502 to Z-80
advanced

What happens between the 6502's last instruction and the Z-80's first. The boot-finalization sequence, the embedded Z-80 install fragments inside the 6502 loader, and the still-mysterious SoftCard CPU-switch trigger that flips the bus between processors.

cpm-videx-series · Part 5 apple-ii6502z80
The BIOS That Half-Exists
advanced

How Microsoft SoftCard CP/M loads itself from disk into Z-80 memory — and the surprise that half the BIOS doesn't exist on disk at all. The other half is generated at runtime by code that runs after the SoftCard switch. A code-generation pattern that explains why 2.20 and 2.23 differ structurally.

cpm-videx-series · Part 6 apple-ii6502z80
The BIOS Factory
advanced

Microsoft SoftCard CP/M 2.23 doesn't ship a fixed BIOS. It ships a BIOS factory — code that builds the runtime BIOS from a slot-info table at boot. The factory is what got rewritten between 2.20 and 2.23, and seeing it explains why fixing Videx took more than 11 bytes.

cpm-videx-series · Part 7 apple-ii6502z80
From the Reset Vector to the Device Scan
advanced

What happens when the Z-80 first executes after the SoftCard switch. The path from JP $FA00 through cold-boot setup, the BIOS factory's generator, and into the device-scan dispatch — and an honest accounting of which mechanisms are still open.

cpm-videx-series · Part 8 apple-ii6502z80
The Cooperative-CPU Round-Trip
advanced

How the SoftCard's two CPUs share a disk drive. The Z-80 needs to read a sector, signals the 6502, the SoftCard switches buses, the 6502 services the request, signals back. Six Z-80 instructions implement the sync; the SoftCard hardware turns them into a controlled CPU switch.

cpm-videx-series · Part 9 apple-ii6502z80
Every Difference: A Complete Inventory of CP/M 2.20 vs 2.23
advanced

The Videx fix is 21 bytes. The release that contains it changes 8 KB. This article catalogs every category of difference between Microsoft SoftCard CP/M 2.20 and 2.23 — boot stub, loader, BIOS, CCP+BDOS — and shows how the small fix sits inside a much larger version-bump-driven rewrite.

cpm-videx-series · Part 10 apple-ii6502z80
The CPU Switch, and What's Left
advanced

The last open mechanism, found. The 6502's main loop is a 24-byte routine at Apple $03C0 that perpetually retriggers a CPU switch via JSR $0E36 — a fetch into Z-80 memory the SoftCard intercepts. Plus an honest accounting of what the investigation closed and what stays open.

cpm-videx-series · Part 11 apple-ii6502z80
Verifying It in the Emulator
advanced

Stage-1 and Stage-2 of a custom SoftCard CP/M emulator confirm what's true and reveal what's still wrong. Empirical proof that the 6502 never writes $FA00-$FFFF and that the BIOS jump table actually lives at Z-80 $1A00, not $FAB8.

a2fpga-series · Part 1 apple-iifpgaemulation
The Card That Made the Apple II Serious
advanced

The Videx VideoTerm was the 80-column card that turned the Apple II into a business machine. Emulating it on an FPGA means reverse-engineering a 1981 MC6845 CRTC design and understanding why slot 3 is unlike every other slot in the machine.

a2fpga-series · Part 2 apple-iifpgaemulation
Building the Rendering Pipeline
advanced

Getting 80 columns of text from VRAM to pixels on a modern HDMI display: the Videx VideoTerm rendering pipeline in SystemVerilog, C8-space ownership, and the Pascal boot hang that required reading a 1983 firmware disassembly to fix.

a2fpga-series · Part 3 apple-iifpgaemulation
The Clock Card That Just Works
intermediate

The ThunderClock Plus is the only Apple II clock card with a built-in ProDOS driver. Emulating it means implementing a NEC uPD1990AC serial calendar clock in SystemVerilog — and exploiting a USB-C power trick to give the FPGA battery-like time persistence.

a2fpga-series · Part 4 apple-iifpgaemulation
Four Bugs That Lived in the Dark
expert

Adding a second expansion-ROM-capable card to the A2FPGA exposed four latent bus timing bugs in the upstream codebase — bugs that had been present for approximately two years and went undetected because only one emulated card had ever used C8-space at the same time.

smalltalk-from-scratch · Part 1 smalltalklanguage-designretrocomputing DRAFT
The Object at the End of the Universe

Smalltalk-80's object model is the most consistent in computing history. Understanding it — metaclasses, live images, and all — is the first step toward building one from scratch.

smalltalk-from-scratch · Part 2 smalltalklanguage-designcompiler DRAFT
The Compiler That Couldn't Run Its Own Output

To build a Smalltalk-80 VM you need a compiler. But Smalltalk bytecode is useless without a running Smalltalk. The escape: a JSON intermediate representation and an empirically-discovered grammar.

smalltalk-from-scratch · Part 3 smalltalklanguage-designvirtual-machine DRAFT
Building a Universe from a Blueprint

The cold-start loader reads a JSON description of every Smalltalk class and builds a complete, correctly-linked heap from scratch. The garbage collector tells you when you got it wrong.

smalltalk-from-scratch · Part 4 smalltalklanguage-designinterpreter DRAFT
The Machine That Runs the Machine

The Smalltalk-80 bytecode interpreter: execution contexts, method lookup through the metaclass chain, non-local block returns, and the BlockClosure bug that took weeks to find.

smalltalk-from-scratch · Part 5 smalltalklanguage-designbootstrap DRAFT
The Ghost in the Source File

The Smalltalk-80 file-out is not a complete description of a running system. Some globals only ever existed interactively — they're not in any source file, but the code that uses them was written assuming they exist.

smalltalk-from-scratch · Part 6 smalltalklanguage-designgraphics DRAFT
First Pixels

Getting a Smalltalk-80 system to display something requires implementing BitBlt, the 1980 graphics primitive at the foundation of everything visible. Then saving the live heap so you never have to do cold start again.

smalltalk-from-scratch · Part 7 smalltalklanguage-designgraphics DRAFT
Forty Years of BitBlt

The decision to replace Smalltalk-80's 1980 display model with GPU-accelerated rendering: deleting Form, BitBlt, and Pen from the codebase and building Wise Owl Smalltalk on SDL2 and SkiaSharp.

apple-panic-series · Part 1 apple-ii6502copy-protection
The Disk That Couldn't Be Copied
intermediate

How the Disk II's radical hardware design made Apple II copy protection possible — and what a flux-level disk image reveals about a 1981 floppy that defeated nearly every copy tool of its era.

apple-panic-series · Part 2 apple-ii6502copy-protection
Reading Code That Lies
advanced

Disassembling the Apple Panic boot loader reveals self-modifying code, a mathematically elegant GCR table corruption, a custom post-decode permutation, and a per-track marker scheme that makes the disk illegible unless you already know the key.

apple-panic-series · Part 3 apple-ii6502copy-protection
The Bug Was in Our Own Code
advanced

Sector 1 fails its checksum every time. Three theories, each plausible, each wrong. The real cause turns out to be a fundamental property of how WOZ files represent circular disk tracks — and it was in our own bit-stream reader the whole time.

apple-panic-series · Part 4 apple-ii6502copy-protection
Forty-Five Kilobytes
intermediate

What a recursive-descent disassembler finds in 27KB of 1981 Apple II game code: an XOR sprite engine, speaker timing loops, enemy AI state machines with three behavioral trees, BCD scoring, 104 subroutines, and a memory layout where every byte has a reason.

apple-panic-series · Part 5 apple-ii6502copy-protection
nibbler: A WOZ Disk Analysis Toolkit
intermediate

Every nibbler command demonstrated against Apple Panic — actual outputs, what each line means, and how to read the results. The reference guide for analysing a copy-protected Apple II WOZ disk image from first scan to disassembled source.