SYS10/SYS handles DISPLAY DIR ($DSPDIR) and BASIC Error Messages.
TRS-80 DOS - TRSDOS v1.3 - SYS10/SYS Disassembled
General:
Program Overview
SYS10/SYS is a transient TRSDOS 1.3 overlay loaded into the SYSLOW overlay area at 4E00H. It is invoked via the system vector mechanism using two service codes:
Vector 80H — DODIR (Display Directory): entered by Disk BASIC's CMD"D" directive. SYS10 reads the directory track of the requested drive, sector by sector, into the disk I/O buffer at 4300H (BUFF1) and prints the visible filenames four per screen line, skipping any directory entry whose first byte is zero or whose attribute byte indicates a SYSTEM or INVISIBLE file. The drive number originates from D10SAV (4271H), masked against TOPDRV-1 (03H) to retain only the drive bits.
Vector 90H — DOERR (BASIC Error Message Display): entered when Disk BASIC encounters an error condition. SYS10 looks up the error code (passed in Register E) in the embedded ERRTAB string table, walks past the appropriate number of zero-terminated message strings, and then jumps to BASIC's error handler at 1A01H with HL pointing at the chosen message.
Memory Map
| Address Range | Label | Contents |
|---|---|---|
| 4E00H | START | Entry point — masks the request vector and dispatches to DODIR (80H) or DOERR (90H) |
| 4E07H–4E29H | DODIR / DIRGET | Directory display setup: validates the drive number, clears the screen, turns the cursor on, and falls through to DIRLOP |
| 4E2AH–4E45H | DIRLOP | Per-drive directory loop: locates the directory track via TRKGET, formats the drive header line, and prints "DRIVE :n" |
| 4E46H–4E63H | DIRLO1 / DIRLO2 | Per-sector loop: reads each directory sector into BUFF1 by calling XREAD; bails to ERROR (4409H) on read failure |
| 4E64H–4ED9H | NOERR / LOOP0 / LOOP1 / LOOP2 / LOOP3 | Per-entry loop: skips empty/system/invisible entries, prints up to 8 filename characters, optional "/EXT", and pads to 15 columns; ends a screen line every 4 names |
| 4EDAH–4EEFH | DRIVE / TRK / DRVMSG / DRV / SAVE3 / S10SEC / NUM | Workspace area for the directory display: drive byte, track byte, "DRIVE :0 \x03" printable header, sector counter, line-count tracker, and pointer into BUFF1 |
| 4EF0H–4F10H | DOERR / START1 / START2 / START3 / START4 | Error-message dispatcher: classifies the error code into three ranges (≥8BH unprintable, ≥63H disk error, <2FH BASIC error), computes a 1-based table index, walks ERRTAB by counting zero-terminators, and JPs to the BASIC error handler at 1A01H |
| 4F11H–51D1H | ERRTAB | Embedded BASIC error message table — 47 zero-terminated strings indexed by adjusted error code |
Complete Variable List
SYS10 has one self-modifying-code target and seven workspace storage bytes/words. Per the JSON conventions used across this site, self-modifying targets within transient overlays (SYS10 lives at 4E00H–51D1H and is overwritten when other SYSn overlays load) are documented here in the HTML but are not added to the global RAM-addresses JSON.
| Address | Label | Description |
|---|---|---|
| 4E56H | SAVTRK | Self-modifying target (declared SAVTRK EQU $+1): the operand byte of LD D,0 at 4E55H. Patched by LD (SAVTRK),A at 4E32H to inject the directory-track number returned by TRKGET into the subsequent XREAD call. |
| 4EDAH | DRIVE | Storage byte for the drive number currently being displayed (0–3). |
| 4EDBH | TRK | Storage byte for the directory track of the current drive (declared but not actively used in the shipped code path). |
| 4EDCH | DRVMSG | Start of the printable drive-header literal "DRIVE :". |
| 4EE3H | DRV | The single ASCII digit slot inside DRVMSG — patched at 4E38H with LD (DRV),A to display the current drive number. |
| 4EECH | SAVE3 | Word-sized pointer into BUFF1; tracks the current 30H-byte directory entry being processed. |
| 4EEEH | S10SEC | Current directory-sector number being read (initialized to 02H, incremented through 13H). |
| 4EEFH | NUM | Counter for filenames already displayed on the current screen line; resets every 4 names so a CR can be emitted. |
Major Routine List
| Address | Label | Description / Entry-Exit |
|---|---|---|
| 4E00H | START | Overlay entry. In: A = vector code (80H or 90H), E = error code (DOERR path). Out: dispatches to DODIR or DOERR. |
| 4E07H | DODIR | Directory-display setup. Reads D10SAV (4271H), masks against TOPDRV-1, stores the drive into DRIVE. |
| 4E10H | DIRGET | Drive validation. Compares against MAXDRV (4413H); on out-of-range, jumps to ERROR with code EDNS+0C0H. |
| 4E2AH | DIRLOP | Per-drive top-of-loop. Calls TRKGET (4B3EH) to find the directory track, patches SAVTRK, and prints the drive header line. |
| 4E46H | DIRLO1 | Initialize sector counter S10SEC to 02H. |
| 4E4BH | DIRLO2 | Per-sector loop. Increments S10SEC, calls XREAD (4675H) to read one sector into BUFF1. |
| 4E64H | NOERR | Successful read: initialize SAVE3 pointer to BUFF1. |
| 4E6AH | LOOP0 | Per-entry top: skip blank/SYSTEM/INVISIBLE entries; otherwise begin printing the filename. |
| 4E7DH | LOOP1 | Print up to 8 filename characters until a SPACE is found. |
| 4E89H | OUT0 | Branch target when LOOP1 terminated early on SPACE. |
| 4E8EH | OUT00 | Skip-spaces sub-loop to position HL at the file extension. |
| 4E91H | OUT1 | Examine the extension's first character; skip the "/EXT" if it's blank. |
| 4E9EH | LOOP2 | Print the 3-character extension after a "/" separator. |
| 4EA6H | OUT2 | Pad the printed name to 15 total columns with spaces. |
| 4EA7H | LOOP3 | Per-pad-character print loop. |
| 4EBCH | NXTNAM | Update the per-line name counter NUM. |
| 4EBFH | TOTNXT | Advance SAVE3 by 30H to the next directory entry; loop back to LOOP0 unless the sector is exhausted. |
| 4EF0H | DOERR | BASIC error-message lookup. In: E = error code. Classifies and computes a 1-based message index in B. |
| 4EFDH | START1 | Forced unprintable-error path: A := 5AH. |
| 4EFFH | START2 | Disk-error path entry: A := A − 34H. |
| 4F01H | START3 | Generic-error path entry: rotate A right then INC A → 1-based table index. |
| 4F07H | START4 | Walks ERRTAB skipping (B−1) zero-terminated strings; then JP 1A01H to BASIC. |
| 4F11H | ERRTAB | Start of the embedded zero-delimited BASIC error-message table (47 strings, ending at 51D1H). |
Cross-references and Analysis Notes
The supplied SYS10.SRC source contains one line — LD C,A ;INTO C ALSO at the source's line 32, between PUSH AF and CALL TRKGET inside DIRLOP — that is not present in the shipped binary. The walker accounts for this 1-byte source-vs-binary difference; without it, every label after DIRLOP would drift by +1, and every label after the DCL macro definition (which itself is a non-emitting MACRO/ENDM block) would drift by +3. With the diff applied and the MACRO/ENDM body excluded, the walker's emit cursor lands exactly at 51D2H, one past the final DEFB 0 of the last error message at 51D1H.
SAVTRK at 4E56H is SYS10's only self-modifying target. It is documented in this page but, per the project conventions, is not added to the site-wide RAM addresses JSON because SYS10 is a transient overlay whose code space is reused by other SYSn overlays.
The source labels the BASIC error-message table ERRTAB; an earlier revision of this HTML labeled it ERRSTR. The source is authoritative, so all references to that table now use ERRTAB.
Three error-message strings in the existing HTML differed from the source text: "Bad field number" (HTML) is "Bad file number" in the source at 50D3H, "Bad filename" (HTML) is "Bad file name" in the source at 5166H, and "Mode mismatch" (HTML) is "Mode-mismatch" in the source at 5174H. The HTML strings have been corrected to match the source.
SYS10 calls one SYS0-resident routine that is not yet present in the site-wide RAM addresses JSON: XREAD at 4675H. It is part of the same SYS0 disk-I/O cluster as the already-tracked READIT (45B8H) and XWRITE (45F7H), so it should be added when the SYS0 session is next revised. It is not added from this SYS10 session because the project conventions reserve SYS0 entries to the SYS0 session.
The earlier HTML at 4E55H displayed the instruction as LD D,(SAVTRK). That form is not a valid Z80 instruction — the actual binary at 4E55H is the 2-byte LD D,nn immediate-load (16 00), and the source writes it as LD D,0 with SAVTRK EQU $+1 on the line above to label the operand byte at 4E56H as the self-modifying target. The displayed mnemonic is now corrected to LD D,00H with the source form preserved in the origrom2 span.
Disassembly:
Original Source Code Comment: MASK SYSTEM NUMBER
Original Source Code Comment: ERROR MESSAGES?
Original Source Code Comment: YES
Original Source Code Comment: SHOW SYS 6 NOT IN MEMORY
Original Source Code Comment: GET THE DRIVE NUMBER
Original Source Code Comment: MASK ALL BUT DRIVE
Original Source Code Comment: SAVE THE DRIVE NUMBER
NOTE: 01C9H is the Model III ROM routine to to CLEAR THE SCREEN and RETurn.
Original Source Code Comment: CLEAR SCREEN
Original Source Code Comment: CURSOR ON CHAR
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
Original Source Code Comment: TURN CURSOR BACK ON
Original Source Code Comment: GET THE DRIVE NUMBER
Original Source Code Comment: INTO (B)
NOTE: 4413H is the storage location for the NUMBER OF DISK DRIVES in the system.
Original Source Code Comment: GET THE MAXIMUM DRIVE IN SYSTEM
Original Source Code Comment: WE TRYING FOR A NON-EXISTANT DRIVE?
Original Source Code Comment: NO, CONTINUE
Original Source Code Comment: DRIVE NOT IN SYSTEM ERROR
Original Source Code Comment: REPORT AND RETURN
4E2AH - DIRLOP - Read the directory track into a Buffer in RAM.
Original Source Code Comment: GET BINARY DRIVE
Original Source Code Comment: SAVE IT
NOTE: 4B3EH is the SYS00/SYS routine to identify the track number of the directory. Routine exits with the director track number in Register D.
Original Source Code Comment: GET THE DIRECTORY S10SEC FOR THIS DRIVE
Original Source Code Comment: GET IT
Original Source Code Comment: SAVE THE TRACK NUMBER
Original Source Code Comment: MAKE IT ASCII
Original Source Code Comment: STORE IN DRIVE MESSAGE
Original Source Code Comment: POINT TO DRIVE # MSG
NOTE: 021BH is the Model III ROM routine to display the character at (HL) until a 03H is found.
Original Source Code Comment: PRINT IT
Original Source Code Comment: SET FOR SECTOR 2
Original Source Code Comment: STORE FOR USE
Original Source Code Comment: POINT TO TRACK
Original Source Code Comment: GET SEC NUM
Original Source Code Comment: SET FOR NEXT SEC, NXT LOOP
Original Source Code Comment: PUT IN E FOR CALL
Original Source Code Comment: GET PRESENT DRIVE
Original Source Code Comment: PUT IN C FOR CALL
Original Source Code Comment: DIRECTORY TRACK SAVED HERE
NOTE: 4300H is a memory buffer (referred to as Memory Buffer 1) where diskette contents are stored in RAM.
NOTE: 4300H is the storage location for the 256 Byte Storage Area for Disk I/O.
Original Source Code Comment: WHERE TO STORE IT
Original Source Code Comment: READ DIR TRACK IN MEM
Original Source Code Comment: GOOD READ
Original Source Code Comment: SET DETAIL MESSAGE BIT ON
NOTE: 4409H is the SYS00/SYS routine to process DOS errors.
Original Source Code Comment: REPORT ERROR AND EXIT
4E64H - NOERR - Process the directory track now in RAM to find the filename.
NOTE: 4300H is a memory buffer (referred to as Memory Buffer 1) where diskette contents are stored in RAM.
NOTE: 4300H is the storage location for the 256 Byte Storage Area for Disk I/O.
Original Source Code Comment: POINT TO BUFFER
Original Source Code Comment: SAVE IT
Original Source Code Comment: GET POINTER
Original Source Code Comment: GET CHARACTER FROM DIR
Original Source Code Comment: BLANK FILE?
Original Source Code Comment: YES
Original Source Code Comment: SYSTEM OR INVISIBLE FILE?
Original Source Code Comment: SKIP IF SO
Original Source Code Comment: MAX LENGTH OF NAME
Original Source Code Comment: NAME/EXT+SPACES
The next 3 instructions function as HL = HL + 05H
Original Source Code Comment: GET LSB INTO A
Original Source Code Comment: SET FOR BEGIN OF NAME
Original Source Code Comment: PUT BACK FOR ADDRESS
Original Source Code Comment: GET A CHARACTER FROM NAME
Original Source Code Comment: SPACE?
Original Source Code Comment: DONE IF SO
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
Original Source Code Comment: PRINT OTHERWISE
Original Source Code Comment: DEC TOTAL COUNTER
Original Source Code Comment: PRINT ALL OF NAME
Original Source Code Comment: GET COUNT
Original Source Code Comment: SET FLAGS
Original Source Code Comment: NOTHING TO DO
Original Source Code Comment: BACK POINT UP ONE
At this point, HL is now positioned at the file's EXTENSION in the directory sector.
Original Source Code Comment: NOW AT EXT
Original Source Code Comment: ANY EXT?
Original Source Code Comment: IF NOT, SKIP
Original Source Code Comment: PRINT A SEPERATOR
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
Original Source Code Comment: DEC TOTAL COUNTER
Original Source Code Comment: 3 CHARS IN EXT
Original Source Code Comment: GET A CHAR OF EXT
Original Source Code Comment: POINT TO NEXT
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
Original Source Code Comment: PRINT IT
Original Source Code Comment: DEC TOTAL COUNTER
Original Source Code Comment: PRINT ALL OF EXT
Original Source Code Comment: GET TOTAL NUMBER
Original Source Code Comment: OUTPUT SPACES
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
Original Source Code Comment: GET HOW MANY THIS LINE
Original Source Code Comment: ADD ONE TO IT
Original Source Code Comment: 3 NAMES ON SCREEN?
Original Source Code Comment: IF NOT, KEEP GOING THIS LINE
If we are here, then we have already displayed 4 filenames on a line, so we need to end that line and reset everything that monitors that count and start again.
Original Source Code Comment: OUT A CR FOR NEXT LINE
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position.
Original Source Code Comment: CLEAR NUMBER COUNTER
Original Source Code Comment: SAVE COUNTER
Original Source Code Comment: GET BUFFER POINTER
The next 3 instructions function as HL = HL + 30H
Original Source Code Comment: PUT LSB INTO A
Original Source Code Comment: POINT TO NEXT NAME
Original Source Code Comment: PUT BACK FOR ADDRESS
Original Source Code Comment: PUT ADJUSTED BACK
Original Source Code Comment: WE AT END OF THIS SECTOR?
Original Source Code Comment: NEXT NAME IF NOT DONE
If we are here, then we have exhausted all filenames in the current sector, and need to move to the next sector of the directory.
Original Source Code Comment: GET PRESENT TRACK
Original Source Code Comment: ALL DIR TRACKS YET?
Original Source Code Comment: IF NOT, KEEP GOING
Original Source Code Comment: NEW LINE PLEASE
NOTE: 0033H is the Model III ROM character print routine; displays the character held in Register A at the current cursor position. Since this was JUMPED to instead of CALLed, the RET at the end of this ROM routine will then RETurn to the caller of this subroutine instead of returning to this place.
Original Source Code Comment: DISPLAY AND EXIT
4EDAH - DRIVE - BYTE STORAGE.
4EF0H - DOERR - Process an Error.
Original Source Code Comment: HIGHER THAN ALLOWABLE ERROR?
Original Source Code Comment: YES, FORCE TO 'UNPRINTABLE' ERROR
Original Source Code Comment: DISK ERROR?
Original Source Code Comment: YES, DO IT
If we pass through, then we wind up at the UNPRINTABLE ERROR jump point. How clever!
Original Source Code Comment: FORCE TO 'UNPRINTABLE' ERROR
Original Source Code Comment: HL => TABLE
At this point, Register B is holding the number of error messages we need to skip before we get to the one we want.
Original Source Code Comment: GET A CHARACTER
Original Source Code Comment: BUMP TO NEXT CHARACTER
Original Source Code Comment: END OF THIS ERROR MESSAGE?
Original Source Code Comment: NO, LOOP TILL FOUND
We fall through to here when an entire error message has been read and its time to move to the next one.
Original Source Code Comment: LOOP FOR ERROR NUMBER
4F11H - ERRTAB - ERROR MESSAGE STORAGE AREA.
Original Source Code Comment: START OF TABLE