Skip to content

firmware: the GEOS installer and boot-file reader use the shared disk image engine - #90

Draft
wesbiggs wants to merge 3 commits into
SensoriumEmbedded:mainfrom
wesbiggs:shared-disk-geos
Draft

wesbiggs wants to merge 3 commits into
SensoriumEmbedded:mainfrom
wesbiggs:shared-disk-geos

Conversation

@wesbiggs

@wesbiggs wesbiggs commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

This is part 3 of a series of PRs to streamline and consolidate disk image (.d64/.d71/.d81) access, which will then be used to power the VDrive Special IO. It moves the GEOS installer and boot-file reader onto the shared engine from #88, after #89 moved the TR block device. In the next PR, the TR menu's own D64/D71/D81 loading and directory listing move over.

Depends on #88 and #89. Only the last commit (81b2e06c) is new here, so please review that one. Once those two merge, I'll rebase this branch onto main and it will shrink to that commit.

Rationale

GeosDiskPatch.h carried a second implementation of what the shared engine does: BAM places, allocation, directory chains and growth, and file chains. Two copies of that code can disagree about the same image, and only the engine's handles error bytes and 40-track D64s.

State of affairs after this PR

  • GeosDiskPatch.h asks the engine for all of the above and keeps only what is GEOS's own: the info block, the GEOS bytes of the directory entry, and moving the TR driver ahead of the other input drivers. It goes from 596 lines to 362.
  • GeosBoot.h reads the boot file, brings an old TR mouse driver up to date and sets up CONFIGURE through the engine too.
  • The driver now lands where 1541 DOS would put it (on the data track nearest the directory, interleave 10) rather than in the first free sector from track 1. That leaves the firmware with one allocator, and GEOS does not care where its files are. tools/geos/trmouse.py models the same allocator, so the byte-for-byte test still holds.
  • The room checks still come before the first write, now from the engine. d64_blocks_allocatable counts exactly what the allocator can hand out, so a BAM whose count is below its bitmap is no longer refused and can no longer run the write out of room partway.
  • Images with error bytes and 40-track D64s are accepted.
  • The engine gains d64_dir_check, d64_dir_room, d64_blocks_allocatable and d64_alloc_next, which VDrive can use as well. It also no longer grows a D81 directory into BAM sector 40/1 or 40/2 when a damaged BAM shows one free.

Memory

  • New GEOS functions are FLASHMEM, and the engine's are VD_COLD, which is FLASHMEM on the firmware. None of it is on the PHI2 path: it runs when the menu launches a GEOS disk.
  • No new strings outside PSTR() and no new tables outside PROGMEM.
  • No malloc and no new RAM2 use. The engine's state lives in the existing GeosDisk struct on the launcher's stack.
  • RAM, from the link report of the shipping builds (npm run build:tr, npm run build:tr-plus), at firmware: the block device maps sectors through the shared disk image engine #89's tip (f2e7a9e0) and at this branch's tip: no change. TR and TR+ main, MinimalBoot and the TR+ extension image report the same RAM1 free for local variables and padding and RAM2 variables before and after (TR main 122748 / 6008 / 17600, TR+ main 79836 / 25864 / 17600).

Docs

  • docs/Architecture/Disk-Images.md: GEOS as the engine's second caller, the one allocator and where it puts sectors, and which refusals come before the first write.
  • docs/GEOS64_Usage.md: the "not a disk image" message now includes images with error bytes.

Testing

  • Source/Teensy/tests/geos-disk-patch.test.js holds the installer's result to trmouse.py's byte for byte, and adds cases for a 40-track D64, a D81 whose growing directory must not take a BAM sector, and an image of no known size.
  • Source/Teensy/tests/geos-boot.test.js runs the boot-file reader, the TR mouse driver refresh and the CONFIGURE setup on synthetic boot disks, unchanged by this PR.
  • npm test passes at this commit.
  • Host build only, not hardware tested. A GEOS 64 or GEOS 128 launch from the TR menu goes through this path, as does installing the TR mouse driver on a boot disk.

Compatibility

No change to the remote protocol (docs/ControlComms.md), the cartridge register map, the EEPROM settings or any timing. A boot disk set up by an earlier firmware keeps working: its TR mouse driver is found by name, wherever it was placed.

License

My own work, MIT licensed like the rest of the repository.

🤖 Generated with Claude Code

wesbiggs and others added 3 commits November 3, 2026 22:06
…VDrive will share

The GEOS installer and the TR block device each carry their own image
geometry, BAM and directory code, and VDrive brings a third, more
complete engine (40-track D64s, error bytes, BAM and directory growth
for all three kinds, tested against c1541). Bring VDrive's engine in
under Source/Teensy/DiskImage so the other two can move onto it.

Nothing uses it yet. The copy differs from teensyrom-vdrive's d64/ only
in what the firmware needs: SPDX lines, the placement macros moving into
d64.h, and its three constant tables marked D64_FLASH so they land in
PROGMEM rather than DTCM. DiskImage.h includes the code once for the
single translation unit the firmware and the host harnesses build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X5t9wWXadFkQgKaCnjreF7
… engine

TRBlockImage did its own track/sector arithmetic on top of GEOS's format
table, which knows only the three plain sizes. A D64 with the error
bytes copiers append, or a 40-track D64, therefore mounted as no image.

The backend now opens the image with d64_open_exact and reads and writes
through d64_block_read/d64_block_write, so those images mount and the
geometry is the one VDrive uses. The error table is left unread: the
driver has no status for a bad sector, so it gets the sector's bytes.
Files of any other size still mount as no image; the harness now reads
one byte past the largest image so an oversized file cannot pass as one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X5t9wWXadFkQgKaCnjreF7
… image engine

GeosDiskPatch.h carried a second implementation of what the shared
engine does: BAM places, allocation, directory chains and growth, file
chains. It now asks the engine for all of it and keeps only what is
GEOS's own: the info block, the GEOS bytes of the directory entry, and
moving the TR driver ahead of the other input drivers. GeosBoot.h reads
the boot file, refreshes an old TR mouse driver and sets up CONFIGURE
through the engine too. The header goes from 596 lines to 362.

The driver now lands where 1541 DOS would put it (nearest the directory,
interleave 10) rather than first-free from track 1: one allocator in the
firmware, and GEOS does not care where its files are. trmouse.py models
the same allocator so the byte-for-byte test still holds, and
docs/Architecture/Disk-Images.md records the choice.

The room checks happen before the first write, now from the engine:
d64_blocks_allocatable counts exactly what the allocator can hand out,
so a BAM count below its bitmap is no longer refused and can no longer
run the write out of room partway. Images with error bytes and 40-track
D64s are accepted.

The engine gains d64_dir_check, d64_dir_room, d64_blocks_allocatable and
d64_alloc_next, which VDrive can use as well, and no longer grows a D81
directory into BAM sector 40/1 or 40/2 when a damaged BAM shows one free.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X5t9wWXadFkQgKaCnjreF7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant