Read, write, create and format Commodore 1541 D64 disk images from Jennifer.
A D64 is a byte-for-byte copy of a 5.25" floppy: 683 blocks of 256 bytes,
holding CBM DOS 2.6 - a Block Availability Map in sector 18/0, a chain of
32-byte directory slots from 18/1, one linked list of blocks per file. This
deck implements all of it in pure Jennifer: build images for an emulator or a
real drive, inspect or repair existing ones, bulk-extract an archive, without
c1541.
use io;
import "@mplx/d64/" as d64;
def img as d64.Image init d64.formatDisk("sample disk", "01");
$img = d64.writeText($img, "readme", d64.FileType.Seq, "hello from jennifer\n");
$img = d64.writeProgram($img, "demo", 0x0801, $code);
io.printf("%s", d64.directoryText($img));
# 0 "sample disk " 01 2a
# 1 "readme" seq
# 3 "demo" prg
# 660 blocks free.
d64.save($img, "sample.d64");
- Format -
formatDiskisNEW0:NAME,ID.formatDiskWithtakes the geometry (35/40/42 tracks, optional error table) and the BAM layout. Full format wipes every block to a fill byte;quickFormaterases the BAM and directory only, asN0:NAMEdoes. - Four BAM layouts - stock 35-track, plus the three incompatible 40-track extensions: SpeedDOS, DolphinDOS, PrologicDOS. Detected on load, overridable.
- List -
directoryTextrendersLOAD"$",8;listFilesgives typed entries;findFilesfilters with the drive's*and?patterns. - Read and write - SEQ, PRG, USR as raw bytes, PETSCII text, or a program
split at its load address.
updateFilereplaces,deleteFilescratches; rename and lock. - PETSCII - UTF-8 ↔ PETSCII in the
petcatconvention, exact round trip for anything the character set can spell. - Metadata -
fileInforeturns the directory entry, the block chain, the real byte size and the PRG load address, and flags an entry whose recorded length the chain does not back up. - Edit -
patchSectorandpatchFileoverwrite bytes in place,readAt/writeAtgive a flat byte view, andfindByteslocates a pattern anywhere on the disk. - Blocks -
readSector/writeSectorandreadBlocks/writeBlocksfor runs, all independent of the BAM, plus the BAM calls themselves.
Value-semantic throughout: a mutator returns a fresh Image and leaves its
argument alone.
jvc add @mplx/d64Or vendor the src/ subtree by hand from a release archive.
Jennifer 0.25.0 or newer. No network, subprocess or database: the filesystem
is built from bytes and bitwise operations, so the deck runs unchanged on
jennifer-tiny. Only open and save touch the disk, through fs.
tools/version.sh # the version the git tags imply
tools/inject-version.sh # stamp it into src/topics/version.j
jennifer test src/d64_test.j # the white-box overlay
jennifer lint src/d64.j # the compilable unit
jennifer fmt -l src examples # formatting
tools/check-headers.sh # SPDX + interpreter floor
tools/check-overlays.sh # every topic has a test
tools/check-docs.sh # docs match the code: signatures,
# docblocks, links, claimed values
tools/check-examples.sh # every example still runs
tools/pack.sh dist # the release archive, as CI builds it
grimoire build # the documentation siteLGPL-3.0-only. Every source file carries the SPDX header, and
tools/check-headers.sh keeps those in step with deck.toml.