TRS-80 DOS - LDOS 5.3.1 for the Model I - SYS4/SYS Disassembled
Page Customization
Page Index
SYS4/SYS
Other Navigation
Summary:
LDOS 5.3.1 SYS4/SYS Disassembly - System Error Dictionary (Model I)
SYS4/SYS is the LDOS system error dictionary. It is the overlay that services the @ERROR system call, reached through RST 28H with request code 96H in the accumulator. Its job is to turn a numeric error code into readable English text such as "Directory read error" or "File not in directory", frame that text as *** Error code = NN, message ***, and display it. If SYS4/SYS is purged from a working system disk, the resident kernel has no message text to draw on and every system error instead prints the terse fallback "SYS ERROR". Because the whole overlay occupies only a single granule it is recommended that it be kept.
To fit 46 distinct messages into one granule, LDOS does not store the messages as literal strings. Instead it stores a dictionary of 56 English words once (5088H-51AEH), a compact per-error definition table that lists each message as a short sequence of word numbers (4E03H-4EADH), and a one-byte-per-error index (505AH-5087H) that locates each definition. The display routine walks the word-number list for the requested error, copies each dictionary word into a work buffer with a separating space, and so reconstructs the full sentence on demand. Every word in the dictionary is stored with the high bit (80H) set on its final character, which marks the end of that word.
Beyond the message text, the routine optionally appends the identity of the offending object - either <Device=*XX> for a logical device or <File=NAME/EXT:D> for a disk file (read from the directory) - and a Referenced at X'NNNN' line giving the address from which the failing service was called. Option bits in the caller's accumulator select how much of this framing is produced and whether control returns to the caller or aborts to DOS. Because SYS4/SYS is a transient overlay it loads and runs at 4E00H and reaches the resident kernel (SYS0/SYS) only through fixed entry points.
Memory and Variable Map
| Address Range | Purpose |
|---|---|
| 4E00H-4E02H 3 bytes | Overlay entry point - a single JP that skips over the definition-table data to the executable code at 4EAEH. |
| 4E03H-4EADH 171 bytes | Error message definition table. For each of the 46 error codes, a short run of bytes: bits 0-5 of each byte are a word index into the dictionary, and bit 7 marks the last word of the message. |
| 4EAEH-500CH 351 bytes | The @ERROR display code: option decode, prefix builder, message decompression loop, framing/display, and the device/file and referenced-at builders. |
| 4F64H-4F65H 2 bytes | Self-modified operand of the JP M at 4F63H. Patched at 4EB2H with the caller's return address so the routine can return to the caller when bit 7 of the code is set. |
| 5028H-5029H 2 bytes | Self-modified '*XX' field inside the Device template. Patched at 4F82H with the two-character logical-device name. |
| 500DH-5059H 77 bytes | Message template literals: the '*** Error code =' prefix, the '<Device=*XX>' and '<File=NNNNNNNN/EEE:D>' fill-in templates, and the 'Referenced at X''NNNN''' line. |
| 505AH-5087H 46 bytes | Error-code index table: one byte per error code (0-45) giving the offset into the 4E00H page at which that error's definition begins. |
| 5088H-51AEH 295 bytes | Compressed word dictionary: 56 English words, each terminated by having bit 7 set on its final character. |
| 4200H (SYS0 buffer) | Resident shared sector/message buffer in SYS0/SYS. SYS4 assembles the finished message text here before display. |
Major Routines
| Address | Routine |
|---|---|
| 4E00H | Overlay Entry Point Jumps over the error-definition data table to the real entry at 4EAEH. |
| 4EAEH | @ERROR Service Entry Masks the request code, recovers the caller's error code and option bits from the stack, factors in the resident SYS1 status byte at 4758H, and decides whether and how much of the message to build and display. |
| 4EE4H | Error-Code Prefix Builder Copies the '*** Error code =' literal into the work buffer and converts the error number to two decimal digits, producing '*** Error code =NN, '. |
| 4F02H | Message Decompression Loop Reads the error's word-index list, skips to each referenced word in the dictionary, and copies it into the buffer followed by a space. |
| 4F33H | Frame and Display Capitalizes the first letter, appends the trailing '***' and a carriage return, and displays the assembled buffer through the SYS0 string-display routine at 447BH unless display is suppressed. |
| 4F69H | Device / File Specification Builder Builds '<Device=*XX>' from a logical-device control block or '<File=NAME/EXT:D>' from the file's directory record, then displays it. |
| 4FF7H | Referenced-At Address Line Converts the saved caller address at 430CH to four hex digits and displays the 'Referenced at X''NNNN''' line. |
Cross-Reference Notes
SYS4/SYS is invoked by the resident RST 28H supervisor dispatcher in SYS0/SYS when a caller issues the @ERROR request (code 96H). It calls the following resident SYS0/SYS entry points: 4B10H (DIRRD, read a directory record), 447BH (display a carriage-return-terminated string), 4D76H (store the value in register pair DE as four hexadecimal ASCII digits), and 4030H (@ABORT, return to DOS on the no-return path). It reads the resident variables 430AH (address of the current file/device control block), 430CH (address from which the failing service was called), 430FH (system flag byte), and 4758H (SYS1 status byte), and assembles its output in the resident shared buffer at 4200H.
Disassembly:
4E00H - Overlay Entry Point
SYS4/SYS is loaded to 4E00H and entered here. The first three bytes are a jump over the read-only error-definition table that follows, landing on the executable @ERROR code at 4EAEH.
4E03H - Error Message Definition Table
Data, not code. One entry per error code. Each byte holds a dictionary word number in bits 0-5; bit 7 set marks the final word of that message. The decompression loop at 4F02H expands these lists into text. (The disassembler mis-reads these data bytes as instructions; they are shown here as DEFB data with the decoded message.)
Word numbers 1, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 4, 2, 5, 6, 9 from the dictionary at 5088H; the final byte 89H has bit 7 set to end the message.
Word numbers 8, 2, 5, 9 from the dictionary at 5088H; the final byte 89H has bit 7 set to end the message.
Word numbers 11, 7, 5, 9 from the dictionary at 5088H; the final byte 89H has bit 7 set to end the message.
Word numbers 4, 2, 5, 9 from the dictionary at 5088H; the final byte 89H has bit 7 set to end the message.
Word numbers 7, 27, 12, 44, 5, 9 from the dictionary at 5088H; the final byte 89H has bit 7 set to end the message.
Word numbers 13, 9, 15, 7, 27 from the dictionary at 5088H; the final byte 9BH has bit 7 set to end the message.
Word numbers 13, 9, 14, 7, 27 from the dictionary at 5088H; the final byte 9BH has bit 7 set to end the message.
Word numbers 42, 12, 51 from the dictionary at 5088H; the final byte F3H has bit 7 set to end the message.
Word numbers 4, 2, 5, 6, 10 from the dictionary at 5088H; the final byte 8AH has bit 7 set to end the message.
Word numbers 8, 2, 5, 10 from the dictionary at 5088H; the final byte 8AH has bit 7 set to end the message.
Word numbers 11, 7, 5, 10 from the dictionary at 5088H; the final byte 8AH has bit 7 set to end the message.
Word numbers 4, 2, 5, 10 from the dictionary at 5088H; the final byte 8AH has bit 7 set to end the message.
Word numbers 7, 27, 12, 44, 5, 10 from the dictionary at 5088H; the final byte 8AH has bit 7 set to end the message.
Word numbers 10, 21, 18, 19, 48 from the dictionary at 5088H; the final byte B0H has bit 7 set to end the message.
Word numbers 10, 22, 19 from the dictionary at 5088H; the final byte 93H has bit 7 set to end the message.
Word numbers 23, 24, 26, 25 from the dictionary at 5088H; the final byte 99H has bit 7 set to end the message.
Word numbers 16, 9, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 16, 10, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 23, 26, 41 from the dictionary at 5088H; the final byte E9H has bit 7 set to end the message.
Word numbers 34, 9, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 34, 10, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 35, 9, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 35, 10, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 26, 12, 45, 16 from the dictionary at 5088H; the final byte D0H has bit 7 set to end the message.
Word numbers 26, 46, 49 from the dictionary at 5088H; the final byte F1H has bit 7 set to end the message.
Word numbers 47, 55, 10, 22, 19 from the dictionary at 5088H; the final byte D3H has bit 7 set to end the message.
Word numbers 19, 39, 47 from the dictionary at 5088H; the final byte AFH has bit 7 set to end the message.
Word numbers 28, 29, 26, 32 from the dictionary at 5088H; the final byte A0H has bit 7 set to end the message.
Word numbers 27, 25, 30, 29, 31 from the dictionary at 5088H; the final byte 9FH has bit 7 set to end the message.
Word numbers 16, 47, 52, 26 from the dictionary at 5088H; the final byte 9AH has bit 7 set to end the message.
Word numbers 50, 12, 44 from the dictionary at 5088H; the final byte ECH has bit 7 set to end the message.
Word numbers 23, 48, 25 from the dictionary at 5088H; the final byte D9H has bit 7 set to end the message.
Word numbers 1, 42, 39, 51 from the dictionary at 5088H; the final byte F3H has bit 7 set to end the message.
Word numbers 38, 26, 43, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 17, 21 from the dictionary at 5088H; the final byte 95H has bit 7 set to end the message.
Word numbers 13, 38, 9, 40, 17 from the dictionary at 5088H; the final byte 91H has bit 7 set to end the message.
Word numbers 23, 46, 13, 22, 26 from the dictionary at 5088H; the final byte 9AH has bit 7 set to end the message.
Word numbers 26, 12, 53 from the dictionary at 5088H; the final byte F5H has bit 7 set to end the message.
Word numbers 42, 45, 54 from the dictionary at 5088H; the final byte B6H has bit 7 set to end the message.
Word numbers 22, 15, 42 from the dictionary at 5088H; the final byte AAH has bit 7 set to end the message.
Word numbers 37, 2, 33 from the dictionary at 5088H; the final byte A1H has bit 7 set to end the message.
Word numbers 37, 2, 33 from the dictionary at 5088H; the final byte A1H has bit 7 set to end the message.
Word numbers 37, 2, 33 from the dictionary at 5088H; the final byte A1H has bit 7 set to end the message.
Word numbers 20, 2 from the dictionary at 5088H; the final byte 82H has bit 7 set to end the message.
Word numbers 37, 2, 33 from the dictionary at 5088H; the final byte A1H has bit 7 set to end the message.
4EAEH - @ERROR Service Entry, Option Decode and Display Gating
Entry from the JP at 4E00H. On entry the accumulator holds the RST 28H request code (96H). The caller's own accumulator - the error number in bits 0-5, with option bits 6 and 7 - was saved on the stack by the resident dispatcher and is recovered here. The resident SYS1 status byte at 4758H can force message-only mode or suppress the display entirely.
Store the caller's return address (register pair HL) into the two operand bytes of the JP M instruction at 4F63H (operand at 4F64H-4F65H). On the return-to-caller path the JP M will jump here.
Set bit 6 of the effective code in register B, forcing message-only mode (suppresses the 'Error code =NN' prefix and the device/file and referenced-at lines).
4EE4H - Error-Code Prefix Builder
Reached only when message-only mode is off. Copies the '*** Error code =' literal into the work buffer, then converts the error number to two decimal digits followed by a comma and a space, producing '*** Error code =NN, '.
Increment the tens-digit character in the buffer. Each pass raises it toward the correct ASCII digit as ten is repeatedly subtracted from register A.
4F02H - Message Decompression Loop
Reached with register C holding the error number and register pair DE pointing at the buffer position for the message text. Looks up the error's definition, then for each word number copies the matching dictionary word into the buffer followed by a space.
Load register A with the current definition byte (bits 0-5 = word number, bit 7 = last word).
Load register A with a dictionary byte to test for the end-of-word marker.
Load register A with the next character of the requested dictionary word.
4F33H - Frame and Display the Message
The message text is now in the buffer with a trailing space. This block capitalizes the first letter, optionally appends the trailing '***', terminates with a carriage return, and displays the buffer through the resident string routine at 447BH - unless SYS1 status bit 7 suppressed the display.
Recover the effective code (register A) whose bit 7 decides return versus abort. Also reached from 4ECCH when display was disabled.
If bit 7 of the code is set (sign flag minus), jump to the caller's return address. The 0000H operand shown here is a placeholder; it was overwritten at 4EB2H with the caller's actual return address.
4F69H - Device / File Specification Builder
Called when the full framing is wanted. Uses the resident pointer at 430AH to the control block of the object that failed. For a logical device it patches the '*XX' name into the Device template; for an open disk file it reads the directory record and builds NAME/EXT:D into the File template. Then it appends the 'Referenced at' line.
Restore the caller's register IX from the stack.
Store the two-character device name (registers B and C) into the '*XX' field of the Device template at 5028H-5029H.
Load register C with the byte at offset 01H of the control block (register IX) - the first character of a logical-device name.
Load register A with the next character of the device-name text at (HL).
Load register C with the drive number at offset 06H of the file control block (register IX).
Load register A with the next file-name character from the directory record at (HL).
Load register A with the next extension character from the directory record at (HL).
Load register A with '>' (3EH) to close the '<Device=...>' or '<File=...>' field.
4FF7H - Referenced-At Address Line
Displays the device or file specification, then converts the saved caller address at 430CH to four hex digits and displays the 'Referenced at X'NNNN'' line before returning.
500DH - Message Template Literals
Data. The fixed text fragments the display code copies or fills in. Bytes shown are the raw literal; the 'NN', '*XX', 'NNNNNNNN/EEE:D' and 'NNNN' fields are overwritten at run time. (The disassembler mis-reads these as instructions.)
505AH - Error-Code Index Table
Data. One byte per error code (0 through 45). Each byte is the offset within the 4E00H page at which that error's definition begins (base 4E00H). The decompression loop indexes this table with the error number at 4F09H.
5088H - Compressed Word Dictionary
Data. The 56 English words shared by all messages. Each word's final character carries bit 7 (80H) set to mark the end of the word; the decompression loop uses that marker to count and copy words. (The disassembler mis-reads these as instructions.)
The final byte D2H is the character 'R' with bit 7 set to mark the end of the word.
The final byte EFH is the character 'o' with bit 7 set to mark the end of the word.
The final byte F2H is the character 'r' with bit 7 set to mark the end of the word.
The final byte EFH is the character 'o' with bit 7 set to mark the end of the word.
The final byte F9H is the character 'y' with bit 7 set to mark the end of the word.
The final byte E7H is the character 'g' with bit 7 set to mark the end of the word.
The final byte F2H is the character 'r' with bit 7 set to mark the end of the word.
The final byte E1H is the character 'a' with bit 7 set to mark the end of the word.
The final byte EBH is the character 'k' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte F4H is the character 't' with bit 7 set to mark the end of the word.
The final byte F4H is the character 't' with bit 7 set to mark the end of the word.
The final byte EFH is the character 'o' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte EDH is the character 'm' with bit 7 set to mark the end of the word.
The final byte F9H is the character 'y' with bit 7 set to mark the end of the word.
The final byte F9H is the character 'y' with bit 7 set to mark the end of the word.
The final byte EEH is the character 'n' with bit 7 set to mark the end of the word.
The final byte EBH is the character 'k' with bit 7 set to mark the end of the word.
The final byte F2H is the character 'r' with bit 7 set to mark the end of the word.
The final byte F4H is the character 't' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte ECH is the character 'l' with bit 7 set to mark the end of the word.
The final byte ECH is the character 'l' with bit 7 set to mark the end of the word.
The final byte F2H is the character 'r' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte E6H is the character 'f' with bit 7 set to mark the end of the word.
The final byte F4H is the character 't' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte D4H is the character 'T' with bit 7 set to mark the end of the word.
The final byte D4H is the character 'T' with bit 7 set to mark the end of the word.
The final byte F9H is the character 'y' with bit 7 set to mark the end of the word.
The final byte EEH is the character 'n' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte F9H is the character 'y' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte F4H is the character 't' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte EEH is the character 'n' with bit 7 set to mark the end of the word.
The final byte F3H is the character 's' with bit 7 set to mark the end of the word.
The final byte ECH is the character 'l' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte EDH is the character 'm' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte E4H is the character 'd' with bit 7 set to mark the end of the word.
The final byte EEH is the character 'n' with bit 7 set to mark the end of the word.
The final byte E5H is the character 'e' with bit 7 set to mark the end of the word.
The final byte F2H is the character 'r' with bit 7 set to mark the end of the word.