Program Overview
SYS7 is the TRSDOS v1.3 overlay that implements the BACKUP and FORMAT utility commands on the TRS-80 Model III. It is loaded into RAM at 4E00H and occupies the range 4E00H–5D71H, with trailing buffer workspace extending to 6300H. The overlay is invoked by SYS6 (the DOS command handler) when the user types FORMAT or BACKUP at the DOS prompt; control enters at BEGIN (57A1H), which parses the command line, selects between the BACKUP and FORMAT paths, prompts for source and destination drives as needed, and then dispatches to either BACKP (5739H) or FRMAT (5762H).
The BACKUP path performs a sector-by-sector mirror-image copy of one diskette to another. It reads the source directory track, optionally honors the backup-counter protection scheme (see CNT1 / CXFLAG below) by decrementing the restricted-file counter on the source and de-allocating "count-exhausted" files before they are copied, writes the copy to the destination, and verifies the result. The routines RGRAN/WGRAN/VGRAN (at 517DH/519AH/51BBH) handle granule-level disk I/O; a granule in TRSDOS v1.3 is 3 sectors.
The FORMAT path (entry FOMAT, 5803H) issues the WD1793 RESTORE command to position the heads at track 0, builds a 256-byte track image in RAM using the TRKIMG/TBLBMP/EXPAND table-driven generator (5C1FH/5C7BH/5C8CH), writes that image to every track on the destination diskette (via TRKWRT at 5AB0H and VERFIT at 5AEEH for verification), and finally writes a bootstrap program to track 0 sector 1 and a dummy directory to track 17. The bootstrap code itself is the ENT routine (physically stored at 5853H but assembled to run at 4300H via a SETLOC BUFF1 directive); see the Cross-references section for how the two-cursor assembly works.
SYS7 does not handle any SVC (supervisor call) vectors directly — it is a transient utility overlay rather than a resident DOS component. It calls into SYS0 services (sector I/O at XREAD/XWRITE, drive select DSEL0, delay SDELAY, error reporting, ROM character-print PRINT at 021BH) and exits back to DOS READY by executing RET from BEGIN.
Memory Map
| Range | Label | Contents |
|---|---|---|
| 4E00H–4E7BH | FATAL / error handlers | Error-exit, abort, retry, and buffer-clear routines (FATAL, N12, RESTRY, ABRT, EXIT, CLRBUF). These are always at the start of every overlay so that a jump to 4E00H with a status byte in A produces a uniform DOS error message. |
| 4E7CH–4EAAH | SDFLAG / workspace | Single-byte flags and word-sized workspace variables: drive numbers, side flags, flaw counts, compare flags, buffer pointer, memory top, date buffer, disk name buffer. |
| 4EABH–4EDEH | READM / WRITM / VERFM / REST / FTRACK / SEC | Status message strings embedded in code space (“Reading”, “Writing”, “Verifying”, with track/sector placeholders filled in by OUTHEX). |
| 4EE2H–516DH | ANALYZ / SRCMSG / DESMSG / ... | User-facing prompt messages: source disk, destination disk, data disk prompts, password prompts, invalid-password, N12M (“Cannot Backup”), ABMSG (“Operation ABORTED”), GEORGE (DEFE-encoded backup-count / restricted-files warnings), REFORM (re-format prompt), and the FORMATTING/TRACK display messages (FDSMSG, FDS, FDD). |
| 516EH–51D7H | SPRINT / RGRAN / WGRAN / VGRAN | Display helpers and granule-level disk I/O primitives. SPRINT decodes DEFE-encoded strings. RGRAN/WGRAN/VGRAN wrap a 3-sector DJNZ loop around the sector primitives at FUNCTA/B/C. |
| 51D8H–5237H | FUNCTA / FUNCTB / FUNCTC / GREAD / OUTHEX | Sector-level read/write/verify with status-message formatting; GREAD displays “Reading TT SS” / “Writing TT SS” / “Verifying TT SS” and invokes the SYS0 I/O. OUTHEX converts a byte to two ASCII decimal digits for the sector display. |
| 5238H–527BH | BUMP / GBUMP / RBOOT | Buffer-pointer advance helpers; RBOOT reads the source boot sector and processes the CUSTomer-protection counter (decrements it, checks for zero). |
| 52B4H–537BH | RDIR / WDIR / EXMGRN / DEALOC / RELEAS | Directory management: read directory into RAM, write directory back, examine each directory granule for count-protected files, de-allocate a file's granules, release a single segment descriptor. |
| 537CH–5464H | RELEAS / CLRBIT / MEMCHK / MWRIT / FALOC / MREAD | Low-level allocation helpers: clear a bit in a FAT/GAT byte, check memory availability, write a range of granules out, find the next allocated granule, read a range of granules in. |
| 5465H–548FH | FWAIT / LOOPY / LOOPX / LINOFF | “Flashing prompt” helpers that blink a message until the user hits a key. |
| 5492H–5558H | CKSRC / CKDES / DGAT / CKSYS | Source-diskette, destination-diskette, and system-diskette prompt routines that flash the appropriate message and wait for the disk change. |
| 5560H–5625H | BPREP / GETSRC / GETDES | Backup preparation loop; prompt for and validate source and destination drive numbers. |
| 5626H–5713H | GETFOR / INPUT / GETPSF / GETPSB / GETNAM / GETDAT / CLRGAT / SETDAT | FORMAT-specific prompts: which drive to format, disk name, date, master passwords; clear the new GAT; set the “data diskette” flag. |
| 5714H–5761H | DOTITL / COMON / BACKP | Clear screen, draw title banner, set up RAM buffers, BACKUP utility entry. |
| 5762H–57A0H | FRMAT | FORMAT utility entry; prompt for drive and issue FOMAT. |
| 5762H–57A0H (shared) | — | FORMAT/BACKUP common initialization. |
| 57A1H | BEGIN | Overlay entry point. Called by SYS6 when the user invokes FORMAT or BACKUP. |
| 57C3H–5802H | TRAP | Trap-door-code (password hash) calculation routine. |
| 5803H–5852H | FOMAT | FORMAT inner-loop entry: RESTORE to track 0, drive-ready wait loop, CALL FORM to build the track image, CALL BOTWRI to write the boot track, then RET. |
| 5853H–5952H | BOOT / ENT (relocated) | The 256-byte bootstrap program. Physically stored here, but the label ENT resolves to 4300H (via SETLOC BUFF1) so that JPs/CALLs within this block work when the code is copied to 4300H by the boot ROM. This code implements the load-file reader that pulls SYS0 off track 0 at power-on. |
| 5953H–5963H | SYST / NOSYS (relocated) | Three-byte header followed by the tiny “NO SYSTEM” routine that is written to sector 2 of freshly formatted disks with no system, assembled to run at 4D00H (via SETLOC BUFF2). |
| 5964H–5B54H | WRTDIR / VERMSG / FORMSG / STEPR / misc strings | Formatting-progress messages (“Writing System Information”, “Verifying Track nn Sector nn”, “Formatting Track nn Sector nn”), STEPR single-track step helper, and miscellaneous routines. |
| 5A53H–5AADH | BOTWRI | Writes the bootstrap (from 5853H), NOSYS (from 5953H), GAT, and HIT to track 0 and track 17 sector 1 of the destination diskette. |
| 5AB0H–5AEDH | TRKWRT | Issues a “write track” command to the WD1793 and streams the 4096-byte track image (from the BUFF area) through port F3H using INI instructions. |
| 5AEEH–5B34H | VERFIT | After writing a track, read back every sector and verify; calls CALL to ASCII+PDATA to display “Verifying Track nn Sector nn”. |
| 5B35H–5B54H | STEPR | Step the head one track inward and update the DOS track table. |
| 5B55H–5B66H | ASCII / SUB / ADD | Convert a byte 0–99 into two ASCII decimal digits at (HL). |
| 5B67H–5B6CH | PDATA | Display the string at (HL) via ROM PRINT, preserving DE. |
| 5B6DH–5C1EH | WRTDIR / VERMSG / FORMSG / TRKNN / DDST / DDTAB / DDREP / DDTRK / DDSID / DDSEC / DDDATA / COPY / DDTRL / SECTAB / CSECTB | String constants and the track-building data block used by TRKIMG/EXPAND to compose a formatted track image in RAM. |
| 5C1FH–5C8BH | TRKIMG / TBLBMP | Given a track number and side, build a full 256-byte track image in the BUFF area by expanding the DDST table. |
| 5C8CH–5CBBH | EXPAND | Inner loop of TRKIMG that expands a single table entry (count byte + data or repeat pattern). |
| 5CBDH–5D71H | FORM / FLAWX | Top-level FORMAT loop: fill a dummy directory buffer, iterate over every track on every side, call TRKIMG + TRKWRT + VERFIT, handle flawed-track reporting via the FLAW table. |
| 5E00H–5EFFH | SPAR_ | Scratch buffer (SECTOR bytes = 256). |
| 5F00H–5FFFH | DUM1 | Dummy directory sector buffer (256 bytes). |
| 6000H–60FFH | SGAT | Source GAT sector buffer (256 bytes). |
| 6100H–615FH | FGAT | Fresh GAT table with name and date (FLAW=96 bytes). |
| 6160H–61FFH | FLAWD | Destination flaw table (160 bytes). |
| 6200H–62FFH and beyond | BUFF | Main sector/track I/O buffer (256 bytes for sector I/O, extended to ~4KB for track-write operations). |
Complete Variable List
All single-byte flags, word-sized pointers, and message buffers defined in the SYS7 workspace. Per the site-wide convention, these overlay-internal variables are not included in the RAM addresses JSON (they are ephemeral workspace for the duration of a FORMAT or BACKUP), but they are documented here for reference during analysis.
| Address | Label | Description |
|---|---|---|
| 4E7CH | SDFLAG | Single-disk flag (non-zero when source and destination are the same drive). |
| 4E7DH | FDRIVE | Generic "current" drive number used by some shared code paths. |
| 4E7EH | FDRIVS | Source drive number for the current BACKUP operation. |
| 4E7FH | FDRIVD | Destination drive number for the current BACKUP or FORMAT operation. |
| 4E80H | FLAWC | Flaw count (number of bad tracks detected on the destination during FORMAT). |
| 4E81H | BSIDES | Source side number (0 or 1, for double-sided media). |
| 4E82H | BSIDED | Destination side number. |
| 4E83H | FLAG | General-purpose control flag. |
| 4E84H | CLFN | Current logical file number (while walking the directory). |
| 4E85H | CXFLAG | “Count flag” — set non-zero when the source boot's backup counter has reached zero; tells RDIR to de-allocate restricted files. |
| 4E86H | CCFLAG | “Copy count” flag — set when at least one restricted file was actually de-allocated, so that GEORGE's “Protected Files NOT Backed Up” message is displayed. |
| 4E87H | SINGLE | Single-density flag for the current operation. |
| 4E88H–4E89H | PTRAP | Two-byte trap-door code (password hash) for the current file. |
| 4E8AH–4E8BH | CSAVE | Two-byte saved HL (used by various subroutines as a scratch pointer save). |
| 4E8CH–4E8DH | BUFPNT | Current sector buffer pointer (BUFF, BUFF+SECTOR, BUFF+2*SECTOR as the granule advances). |
| 4E8EH–4E8FH | MEMTOP | Saved top-of-memory from DOS, restored at RET. |
| 4E90H–4E97H | DATBUF | Eight-byte date buffer (MM/DD/YY). |
| 4E98H–4EA0H | NAMEBF | Eight-byte disk-name buffer (shown in the directory header). |
| 4EA2H–4EAAH | NAMBUF | Nine-byte scratch buffer for collecting user-entered disk name (one extra byte for terminator). |
| 4EABH–4EB5H | READM | 11-byte “Reading Track nn Sector nn” message template. |
| 4EB6H–4EC0H | WRITM | 11-byte “Writing Track nn Sector nn” message template. |
| 4EC1H–4ECBH | VERFM | 11-byte “Verifying Track nn Sector nn” message template. |
| 4ECCH–4ED2H | REST | Rest-of-message trailer for the three templates above. |
| 4ED3H–4EDDH | FTRACK | “Track nn” ASCII placeholder (overwritten each sector). |
| 4EDEH–4EE1H | SEC | “Sec nn” ASCII placeholder. |
| 4EE2H–4F16H | ANALYZ | “Analyzing Destination” message. |
| 4EF7H–4F3BH | SRCMSG / DESMSG | “Insert SOURCE diskette” / “Insert DESTINATION diskette” messages. |
| 4F3CH–4F75H | SYSMSG / BCOMP | “Insert SYSTEM diskette” / “Backup Complete” messages. |
| 4F76H–4FA1H | TITLE1 / TITLE2 | Screen banners for FORMAT and BACKUP. |
| 4FA2H–4FF0H | FMSG / FDRV / DDATA | “Format which drive?”, drive-number prompt, and data-disk messages. |
| 4FF1H–5030H | NAMMES / PASMES / SPASS | Name, password, and master-password prompts. |
| 5031H–5078H | INVPAS / SDRV / DDRV | Invalid-password, source-drive, destination-drive prompts. |
| 507AH–50B2H | N12M | “Cannot Backup a TRSDOS 1.1 diskette” fatal message (DEFB length + text). |
| 50B3H–50DEH | ABMSG | “Operation ABORTED” message. |
| 50DFH–511CH | GEORGE | Two DEFE-encoded messages: “Maximum Backup Count Exceeded” and “Protected Files NOT Backed Up” (the tilde ~ acts as terminator; each byte is XORed with 55H). |
| 511DH–5144H | REFORM | “Do you wish to RE-FORMAT?” prompt. |
| 5145H–516DH | FDSMSG / FDS / FDD | Source-drive / destination-drive format messages. |
| 5875H | CNT1 | Backup protection counter embedded in the bootstrap. FFH = unlimited backups; any other value limits the number of backups for files flagged with bit 5 of the directory entry. |
| 593DH–593EH | TRKSAV | Two-byte save of current track/sector during boot-file reading. |
| 593FH | EOFBYT | Sentinel/flag set when the boot-load file end-of-program record (02H) is encountered. |
| 5940H–5946H | DSKERR | “ERROR” message embedded in the relocated ENT block. |
| 5947H–5951H | S1SER / S1SIDE / TYPES / TRACKS | Serial number, side, type, and tracks fields written into the boot sector. |
| 5953H–5955H | SEC3 / LEFT / NOSYS | Three-byte header (count byte + DEFB RIGHT + DEFW NOSYS) prefixed to the “NO SYSTEM” program. |
| 5B6DH–5BB4H | WRTDIR / VERMSG / VERASC / FORMSG / FORASC | “Writing System Information”, “Verifying Track”, “Formatting Track” message templates with ASCII placeholder slots. |
| 5BB5H–5C1EH | TRKNN / DDST / DDTAB / DDREP / DDTRK / DDSID / DDSEC / DDDATA / COPY / DDTRL / SECTAB / CSECTB | Track-building data block used by TRKIMG/EXPAND to compose the formatted-track image in RAM. |
| 5CBCH | WORK | One-byte work location inside EXPAND (current sector number being expanded). |
| 5D61H | FLAWX | Flaw-exception table pointer. |
Major Routine List
Entry point address, label, and the source-file HEADER description for every named routine in SYS7. Addresses in the 4E00H–57FFH range and the 5853H–5D71H range were cross-verified against the binary; addresses in the 5800H–5852H FOMAT block match the source-derived walker output exactly.
| Address | Label | Description / Purpose |
|---|---|---|
| 4E00H | FATAL | Error handler entry. Called with error code in A. Prints the DOS error message and exits to DOS READY. |
| 4E1DH | FATAL1 | Inner entry to the error handler (skips the initial PUSH AF). |
| 4E35H | N12 | Abort with “Cannot Backup a TRSDOS 1.1 diskette” message. |
| 4E41H | RESTRY | Reset the disk-retry counter in SYS0 workspace. |
| 4E4AH | ABRT | Display “Operation ABORTED” and exit. |
| 4E50H | EXIT | Clean exit: restore MEMTOP and return to DOS. |
| 4E6EH | CLRBUF | Clear the sector I/O buffer area. |
| 516EH | SPRINT | Decode a DEFE-encoded string (count byte + XOR-55H-scrambled chars) and display it. |
| 517AH | RNEXT | Read the next granule (advances BUFPNT first, then falls through to RGRAN). |
| 517DH | RGRAN | Read a granule (3 sectors) from disk. Entry: DE = starting track/sector, HL = buffer, C = drive. |
| 519AH | WGRAN | Write a granule (3 sectors) to disk. |
| 51BBH | VGRAN | Verify a granule (3 sectors) by reading back and comparing. |
| 51D8H | FUNCTA | Read a sector with message display. |
| 51E2H | FUNCTB | Write a sector with message display. |
| 51ECH | FUNCTC | Verify a sector with message display. |
| 522CH | OUTHEX | Convert register A (0–99) to two ASCII decimal digits at (HL). |
| 5238H | BUMP | Advance BUFPNT by one sector (256 bytes) and bump the sector number. |
| 5240H | GBUMP | Bump to the next granule (3 sectors), handling track wrap. |
| 5257H | RBOOT | Read the source boot sector. Under CUSTomer assembly, decrement and check the backup-count protection counter. |
| 52B4H | RDIR | Read the entire directory track into RAM. |
| 52F2H | WDIR | Write the directory track back to diskette. |
| 5312H | EXMGRN | Examine a directory granule for files flagged as count-restricted. |
| 5351H | DEALOC | De-allocate a restricted file that has exhausted its backup count. |
| 537CH | RELEAS | Release a single segment descriptor (SD) from the GAT. |
| 53ADH | CLRBIT | Clear bit A of register B (helper for FAT manipulation). |
| 53BAH | MEMCHK | Test whether enough memory is available for a RAM-buffered backup. |
| 53D3H | MWRIT | Write a range of granules from a RAM buffer to diskette. |
| 53FAH | FALOC | Find the next allocated granule on diskette. |
| 5438H | MREAD | Read a range of granules from diskette into a RAM buffer. |
| 5465H | FWAIT | Flash a message and wait for a keypress. |
| 5492H | CKSRC | Flash “Insert SOURCE diskette and press ENTER” and wait. |
| 54A5H | CKDES | Flash “Insert DESTINATION diskette and press ENTER” and wait. |
| 54B9H | DGAT | Destination GAT validation. |
| 5509H | CKSYS | Flash “Insert SYSTEM diskette” and wait. |
| 5560H | BPREP | Backup-preparation dispatcher (entered from BACKP). |
| 55CCH | GETSRC | Prompt for and validate the source drive number. |
| 55F4H | GETDES | Prompt for and validate the destination drive number. |
| 5626H | GETFOR | Prompt for the drive to FORMAT. |
| 5645H | INPUT | Display a prompt and collect one line of user input. |
| 5652H | GETPSF | Prompt for the FORMAT master password. |
| 5657H | GETPSB | Prompt for the BACKUP master password. |
| 5666H | GETNAM | Prompt for and collect the new disk name. |
| 568CH | GETDAT | Prompt for and collect the date. |
| 5693H | CLRGAT | Clear the new GAT and initialize it with the disk name and date. |
| 56ABH | SETDAT | Set the “data diskette” flag in the new GAT. |
| 56B1H | CHKFOR | Analyze the destination diskette to see whether it already has data (and prompt for RE-FORMAT confirmation if so). |
| 5714H | DOTITL | Clear screen and display the FORMAT or BACKUP title banner. |
| 5728H | COMON | Common initialization shared by both FORMAT and BACKUP paths. |
| 5739H | BACKP | BACKUP utility entry. Called by BEGIN when the command is BACKUP. |
| 5762H | FRMAT | FORMAT utility entry. Called by BEGIN when the command is FORMAT. |
| 57A1H | BEGIN | Overlay entry point. Parses the command line, dispatches to BACKP or FRMAT. |
| 57C3H | TRAP | Compute a trap-door code (password hash) from an input string. |
| 5803H | FOMAT | FORMAT engine: RESTORE head, drive-ready wait, CALL FORM to build the track image, CALL BOTWRI, CALL verify. |
| 5853H | BOOT | Physical address of the bootstrap program (emission cursor). Label ENT (which resolves to 4300H) marks the same bytes' intended run-time address. |
| 5A53H | BOTWRI | Write the bootstrap, NOSYS, GAT, and directory sectors to the destination disk. |
| 5AB0H | TRKWRT | Issue “write track” to the WD1793 and stream the track image out. |
| 5AEEH | VERFIT | Verify every sector on the just-written track by reading it back. |
| 5B35H | STEPR | Step the head one track inward; update the DOS track table entry. |
| 5B55H | ASCII | Convert an 8-bit value (0–99) to two ASCII digits at (HL). |
| 5B67H | PDATA | Display the string at (HL) via ROM PRINT, preserving DE. |
| 5C1FH | TRKIMG | Build a full 256-byte formatted track image in the BUFF area from the DDST template table. |
| 5C7BH | TBLBMP | Helper used by TRKIMG to fetch table pointers from the IY-indexed table descriptor. |
| 5C8CH | EXPAND | Inner loop that expands one table entry into the track image (count + pattern repetition). |
| 5CBDH | FORM | Top-level FORMAT routine: set up the track-building tables, iterate over every track, call TRKIMG + TRKWRT + VERFIT for each. |
Cross-references and Analysis Notes
During the source-to-binary cross-check for SYS7, the following observations were recorded. They are preserved here so that future sessions on this overlay do not repeat the same investigation.
- Two-cursor SETLOC assembly. The
BOOT: EQU $/SETLOC BUFF1/RESLOCpattern at the head of the bootstrap block causes two distinct address contexts to apply to the same bytes. The load-file emission cursor continues linearly from the end of FOMAT, so the bootstrap bytes live at5853H+ in the overlay image; but the$location counter is redirected toBUFF1 = 4300Hso that labels inside the block (ENT,TRYAGN,BOTLOP,GETBYT, etc.) resolve to the addresses the code will occupy at run-time. Any JP/CALL to those labels inside the block therefore encodes the 4300H target, which is correct because the DOS loader copies the block to4300Hbefore transferring control. - DEFE pseudo-op in GEORGE messages. The two DEFE strings at
50DFH(“Maximum Backup Count Exceeded~”) and at50FDH(“Protected Files NOT Backed Up~”) each emit a leading length byte followed by the string chars XORed with55H. Each string occupieslen(string) + 1bytes. SPRINT at516EHreads the count byte into B, INCs HL, then XORs each character on its way to the ROM print routine. The trailing~character is part of the string itself and serves as the user-facing end-of-message marker after decoding (~XOR55H=0DH= carriage return). - Copy-protection counter (CNT1). At
5875Hinside the bootstrap is a one-byte counter initialized toFFH(unlimited). A customer-site tool could set this to a small integer; RBOOT decrements it on each successful BACKUP read. When the counter reaches 0, theCXFLAGis set, and RDIR then calls DEALOC on every file flagged with bit 5 in its first directory byte — effectively removing those files from the backup.CCFLAGis set if any such file was actually removed, triggering the “Protected Files NOT Backed Up” warning.