A complete 6502 disassembly of VisiCalc (VC-208B0-AP2) for the Apple II, with build systems for both Merlin32 and ca65 assemblers.
The original disassembly was produced by Brutal Deluxe Software using The Flaming Bird Disassembler. This project reorganizes it into a buildable form and provides tooling to assemble, link, and create a bootable Apple II disk image.
Install the cc65 cross-development suite (includes ca65 and ld65):
brew install cc65
Optional tools:
- Merlin32 β
brew install merlin32(for the Merlin build path) - a2kit β
cargo install a2kit(for creating.dskdisk images) - An Apple II emulator such as AppleWin or [Virtual ]
Or install everything at once:
make deps
Build with the ca65/ld65 toolchain (recommended):
make ca65
This assembles ca65/vc.s and produces three binaries:
| File | Load address | Description |
|---|---|---|
ca65/visicalc.bin |
$0800 |
Main program |
ca65/loader.bin |
$0200 |
Secondary loader routines |
ca65/zpinit.bin |
$0000 |
Zero-page initialization data |
Build with Merlin32 (if installed):
make merlin
make disk
This creates visicalc.dsk, a DOS 3.3 disk image with the assembled binary.
Load it in an Apple II emulator and run:
BRUN VC
If both assemblers are installed, verify they produce identical main binaries:
make verify
The ca65 source is mechanically converted from the Merlin source. To
regenerate it after editing merlin/vc.s:
make convert
The conversion script (scripts/merlin2ca65.py) handles:
- Comment syntax (
*β;) - Directives (EQU β
=, DB β.byte, DS β.res, etc.) - Label colons (Merlin labels have no colon; ca65 requires
:) - DCI strings β
.bytesequences with high-bit toggling - Force-absolute addressing (
|βa:) - Address gap detection and
.respadding - Auto-generation of equates for undefined labels
visicalc/
βββ merlin/
β βββ vc.s # Original Merlin syntax source
β βββ Makefile
βββ ca65/
β βββ vc.s # ca65 syntax source (generated)
β βββ visicalc.cfg # ld65 linker configuration
β βββ Makefile
βββ scripts/
β βββ merlin2ca65.py # Merlin β ca65 conversion script
β βββ fix_data_regions.py # Correct data-as-code in da65 output
βββ docs/
β βββ VisiSource.pdf # Brutal Deluxe disassembly notes
β βββ 10911-2212_VisiCalc_Apple_II_Jan82.pdf # VisiCalc User's Guide
βββ Makefile # Top-level build
βββ README.md
βββ .gitignore
The disassembly covers three memory regions:
- $0800β$6FFF β Main VisiCalc program (26,624 bytes)
- $0200β$0400 β Secondary routines (513 bytes)
- $0000β$00FF β Zero-page variables (256 bytes)
Two address ranges within the main segment ($2356β$2E97 and $49D3β$57B3) were not decoded by the original Flaming Bird Disassembler. These have been recovered by disassembling the original binary with da65, revealing 62 entry points including core routines like string output (L2905), character output (L28ED), and cell navigation.
This project is based on the Brutal Deluxe disassembly but uses a slightly later version of VisiCalc than the one Brutal Deluxe worked from. The differences are minimal β the binary layout and code structure are the same, with only minor byte-level variations in a few routines.
In addition to recovering the two undecoded regions above, the da65
disassembler initially misidentified several data areas as 6502 instructions.
These have been corrected by scripts/fix_data_regions.py, which replaces
~600 lines of nonsensical instructions with proper data directives:
- String table ($50D2β$53D4) β ~45 UI prompt strings (command menus,
replicate prompts, error messages) restored as
ASC/DBdirectives - Lookup tables ($505Dβ$50D1) β three indexed tables restored as
HEX - Function name table ($53D5β$5400) β DCI-encoded built-in function names
(SUM, SIN, COS, etc.) restored as
ASC/DB - Data tables ($2756β$2848) β dispatch/lookup table restored as
HEX - Inline data after JSR L2336 and JSR L63B9 β floating-point constants
and encoded command streams restored as
DBdirectives
All corrections produce byte-identical binaries β only the source representation changed.
VisiCalc (1979) was the first spreadsheet program for personal computers and is widely considered the Apple II's "killer app." It legitimized personal computers as serious business tools and created the entire spreadsheet software category.