TRS-80 DOS - NEWDOS/80 v2.0 for the Model I - SYS14/SYS Disassembled
Page Customization
Page Index
SYS14/SYS
Other Navigation
Introduction/Summary
NEWDOS/80 v2.0 SYS14/SYS Disassembly - ROUTE, CREATE, CLEAR, LIST, PRINT and ERROR (Model I)
SYS14/SYS holds six DOS commands: ROUTE, CREATE, CLEAR, LIST, PRINT and ERROR. It loads into the overlay area at 4D00H-51E7H (1,256 bytes in five load records, transfer address 4D00H); 5175H-51E7H are unused zero bytes. SYS1's command table sends the commands here with RST 28H code F0H (function 7 of directory slot 10H) and the sub-function in Register C.
The page shows every byte of the file once, in address order.
Sub-Functions of Code F0H
| C | Command | What it does (from the code) |
|---|---|---|
| 1 | ROUTE | Routes KB, DO or PR to KB, DO, PR, NL or a device in memory (MM=addr); ROUTE,CLEAR ends all routes; ROUTE alone lists them (4D4DH). |
| 2 | CREATE | Makes a file with LRL=, and with REC= pre-allocates and zero-fills REC x LRL bytes; ASE= and ASC= set the FPDE flags (4F7CH). |
| 3 | - | The way back after 4D27H has called another overlay (4D27H). |
| 4 | CLEAR | Ends routes, the *name routine list and the timer chain except the clock, sets HIMEM, zeroes memory from START to END (505FH). |
| 5 | LIST | Shows a text file, from a given line, for a given number of lines (50D3H). |
| 6 | The same on the printer. | |
| 7 | ERROR | Shows the DOS error message n, through SYS4 function 3 (4D39H). |
Errors: 2AH (other codes), 2FH BAD PARAMETER(S), 34H ILLEGAL KEYWORD OR SEPARATOR OR TERMINATOR, 3BH INSUFFICIENT MEMORY (no free ROUTE entry), and any DOS error of the file work.
Variables
Locations inside SYS14 whose contents change while it runs:
| Address Range | Purpose |
|---|---|
| 4D34H-4D35H 2 bytes | The routine 4D27H calls: 0000H in the file, 4439H (SYS0's sector write) stored by CREATE at 5008H. |
| 4D4DH-4E4CH 256 bytes | ROUTE's own code, used by CREATE as a zeroed sector buffer after the file is allocated (5015H). |
| 4DA5H 1 byte | ROUTE: the routed device's attribute (operand of 4DA4H; written at 4D61H). |
| 4DCEH-4DCFH 2 bytes | ROUTE: the routed device's DCB (operand of 4DCDH; written at 4D64H). |
| 4DD9H 1 byte | ROUTE: the routed DCB's own type byte (operand of 4DD8H; written at 4D6DH). |
| 4DE2H-4DE3H 2 bytes | ROUTE: the target DCB (operand of 4DE1H; written at 4DABH). |
| 4F48H-4F4DH 6 bytes | Hex buffer for an MM= address (written by SYS0 4063H at 4E8DH). |
| 508CH-508DH 2 bytes | CLEAR: MEM (operand of 508BH; FFFFH in the file, written at 506FH). |
| 509CH-509DH 2 bytes | CLEAR: END (operand of 509BH; FFFFH in the file, written at 506FH). |
| 50A3H-50A4H 2 bytes | CLEAR: START (operand of 50A2H; 5200H in the file, written at 506FH). |
| 5170H 1 byte | Low byte of the output routine called at 516FH: 33H (display) in the file, 3BH (printer) for PRINT (written at 50D5H). |
Locations outside SYS14 that it reads or writes:
| Address Range | Purpose |
|---|---|
| 3840H 1 byte | Keyboard row 6: ENTER (bit 0), up arrow (bit 3), right arrow (bit 6), read by LIST and PRINT. |
| 4015H, 401DH, 4025H DCBs | The KB, DO and PR device control blocks; a routed DCB's type byte is C0H. |
| 4049H-404AH 2 bytes | SYS0's HIMEM, set by CLEAR (5098H). |
| 4051H-4052H 2 bytes | Head of SYS0's *name routine list, emptied by CLEAR (507FH). |
| 4370H 1 byte | SYS0's copy of the SYSTEM option AX: the highest character LIST shows as it is (513CH). |
| 43A9H-43AAH 2 bytes | The top of memory found at reset (5088H). |
| 43B2H-43CDH 28 bytes | The four 7-byte route entries (free when the link is FFFFH). |
| 436BH 1 byte | SYS0 flags; bit 1 stops SYS2's extra granules while CREATE allocates (500EH). |
| 4480H-449FH 32 bytes | The FCB of CREATE, LIST and PRINT: buffer 4483H, EOF byte 4488H, NEXT 448AH, EOF sector 448CH. |
| 461DH-461EH 2 bytes | Head of SYS0's timer chain, set to the clock routine 44C9H by CLEAR (5085H). |
| 4ADCH-4ADDH 2 bytes | Operand at SYS0 4ADBH: the head of the route chain. |
ROUTE Entries
Each route is a 7-byte entry: +0 the routed DCB, +2 its own type byte, +3 the link to the next entry (0000H = the last, FFFFH = a free entry), +5 the target DCB. The four entries at SYS0 43B2H-43CDH are used unless the target is MM=addr, whose block holds its own entry at addr, a DCB at addr+8 and the driver at addr+10H. The chain starts at the operand at SYS0 4ADCH; a routed DCB gets the type byte C0H, so that SYS0 4ADBH passes its input and output along the chain (Part 5 section 3).
Disassembly
4D00H - Function Dispatcher
SYS14 is entered by the SYS0 RST 28H dispatcher (4BC2H) with Register A = the RST 28H code and Register C = the sub-function. SYS1's command table sends ROUTE (1), CREATE (2), CLEAR (4), LIST (5), PRINT (6) and ERROR (7) here with code F0H (function 7 of directory slot 10H); sub-function 3 is only reached through the SYS0 49D3H chain, to come back after another overlay has run (4D27H). For every command, Register Pair HL points at the command line after the command word (and, for CREATE, LIST and PRINT, the file named there is already in the FCB at 4480H, opened by SYS1 for LIST and PRINT).
4D27H - Call Another Overlay and Come Back
4D27H runs the DOS routine whose address is in the operand 4D34H (Register A = 0); 4D28H runs RST 28H with the code in Register A. Either may load another overlay into 4D00H-51FFH over SYS14, so the word F003H (code F0H, sub-function 3) and 49D3H are pushed first: SYS0 49D3H then reloads SYS14 at sub-function 3, which drops the dispatcher's return address and returns straight to the caller. An error goes to 4409H instead (Part 5, section 2).
If the Z FLAG is set, JUMP to the routine in the operand 4D34H (0000H in the file; 4439H, SYS0's sector write, stored at 5008H).
4D39H - ERROR
ERROR n shows the DOS error message n (0-63) through SYS4 function 3. Register Pair HL points at n.
4D4DH - ROUTE
ROUTE alone lists the routes. ROUTE,dev,dev2[,dev3...] sends a device's input or output to the others too: dev is KB, DO or PR; a target is KB, DO, PR, NL or MM=addr (a device of your own: a 16-byte block at addr, 5200H or above, whose route entry is at addr, DCB at addr+8 and driver at addr+10H). ROUTE,CLEAR ends all routes. Routes are 7-byte entries (DCB, saved type byte, link, target DCB) in the table at 43B2H (four of them) or in an MM block, chained from the operand at SYS0 4ADCH; the routed DCB's type byte becomes C0H, which makes SYS0 4ADBH follow the chain. 4D4DH-4E4CH is also the zeroed sector buffer of CREATE (5015H). Register Pair HL points at the command line after ROUTE.
Store Register A (the routed device's attribute) at 4DA5H, the operand of the AND 00H at 4DA4H.
Store Register Pair DE (the routed device's DCB) at 4DCEH, the operand of the LD DE,0000H at 4DCDH.
Store Register A (the DCB's type byte) at 4DD9H, the operand of the LD A,00H at 4DD8H, to be kept in each route entry.
TARGET LOOP
Register Pair HL = the command line at the next target.
AND Register A (the target's attribute) with the routed device's attribute, the operand 4DA5H (00H in the file, stored at 4D61H).
Store Register Pair DE (the target DCB) at 4DE2H, the operand of the LD DE,0000H at 4DE1H.
FIND A FREE ENTRY
Register Pair HL steps through the four 7-byte entries at 43B2H; a free one has the link FFFFH.
Load Register Pair DE with the routed device's DCB; the operand 4DCEH (0000H in the file) was stored at 4D64H.
Load Register A with the DCB's own type byte; the operand 4DD9H (00H in the file) was stored at 4D6DH.
Load Register Pair DE with the target DCB; the operand 4DE2H (0000H in the file) was stored at 4DABH.
FIND THE END OF THE CHAIN
Register Pair DE = the entry whose link is looked at (4AD9H stands for the head).
4E0AH - List the Routes
One line per routed device: its name, TO, and the target; the entry at SYS0's chain head (4ADCH) comes first.
ENTRY LOOP
Register Pair HL = the route entry being shown.
4E56H - Print a Device Name
Register Pair DE = a DCB. Prints its name from the table at 4F53H, or MM= and the block's address (the DCB minus 8) in hexadecimal for any other DCB.
TABLE SEARCH LOOP
Register Pair HL walks the device table; the entry's start is saved on the stack.
PRINT THE NAME
Register Pair HL = the name, ended by 00H.
4E94H - End Routes
Register Pair DE = the DCB whose routes end (0000H = all of them). Each entry of the chain for it is unlinked, marked free (link FFFFH) and the DCB's own type byte is put back. Register Pair BC holds the address of the link that points at the entry being looked at.
CHAIN LOOP
Register Pair HL = the entry before (its link at +3), Register Pair BC = the address of that link.
4EC6H - Look Up a Word
4EC6H looks up a device name in the table at 4F53H; 4EC9H takes the table in Register Pair BC and the number of bytes after each name in Register D (3). A table entry is a name ended by 00H, an attribute byte and a word; 00H ends the table. Returns Register A = the attribute, Register Pair DE = the word and Register Pair HL past the name; a name not in the table is error 34H.
SEARCH LOOP
Register Pair BC = the table entry, Register Pair HL = the command line, Register D = the bytes after each name's 00H.
4EEFH - Read a Number
A decimal number, or a hexadecimal one ended by H (a letter A-H after the digits makes it start again as hexadecimal). Returns it in Register Pair DE; no digit, a missing H, or a number past FFFFH is error 2FH. Register Pair HL is the command line.
DIGIT LOOP
Register Pair HL = the command line, Register Pair DE = the number so far, Register B = the flags (bit 0 hexadecimal, bit 1 a digit read).
4F48H - Texts and the Device Table
Data, not code.
4F7CH - CREATE
CREATE filespec[,LRL=n][,REC=n][,ASE=Y/N][,ASC=Y/N]. The file is opened (made if it does not exist) through SYS2; its FPDE gets the LRL (1-256) and the ASE/ASC flags (FPDE byte 1 bits 7 and 6 set for N); and with REC the file is given REC times LRL bytes: all its granules are taken at once (SYS0 436BH bit 1 stops SYS2's three extra granules), every sector is written with zeros and the end of file is set. SYS1 has put the filespec into the FCB at 4480H; Register Pair HL points at the command line after it. The options are kept on the stack: the number of records, and a word with the flags (Register C) and the LRL (Register B).
OPTION LOOP
Register Pair HL = the command line; the options word and the number of records are on the stack.
Store Register Pair HL (4439H) at 4D34H, the operand of the JP Z at 4D33H, so 4D27H calls it.
CLEAR THE BUFFER
Register Pair HL = the buffer (4D4DH-4E4CH), Register B counts 256 bytes.
WRITE LOOP
Register Pair BC = the sectors left to write; SYS0 4439H moves NEXT on after each.
503EH - CREATE's Options
Data, not code. Each entry is the keyword, 00H, a flag byte (for ASE and ASC, the FPDE byte 1 bit set for N) and the handler's address.
505FH - CLEAR
CLEAR[,START=a][,END=b][,MEM=c]. Ends all routes, empties the *name routine list (4051H) and the timer chain (only the clock routine 44C9H is left in 461DH), sets HIMEM (4049H) to MEM (at least 7000H) or the top of memory found at reset (43A9H), whichever is lower, and fills START (5200H or above, default 5200H) to END (default HIMEM) with zeros. Each option's number is stored straight into the operand it sets.
Store Register E (the number's low byte) at Register Pair HL, the operand at 50A3H, 509CH or 508CH.
Load Register Pair DE with MEM; the operand 508CH holds FFFFH unless MEM= stored a value at 506FH.
Load Register Pair DE with END; the operand 509CH holds FFFFH unless END= stored a value.
Load Register Pair HL with START; the operand 50A3H holds 5200H unless START= stored a value.
FILL LOOP
Register Pair HL = the byte cleared, Register Pair DE = the end.
50D3H - LIST and PRINT
LIST filespec[,first[,count]] shows a text file from line first (default 1) for count lines (default all); PRINT does the same on the printer. SYS1 has opened the file (FCB 4480H) and left the command line pointer on the stack. Characters above option AX (4370H) and control characters other than a carriage return are shown as a period. The up arrow key stops; the up or right arrow key held at the end of a line (or after 256 characters) pauses until ENTER (go on) or the up arrow (stop). The keyboard row 3840H holds ENTER in bit 0, the up arrow in bit 3, the right arrow in bit 6.
Store Register A (3BH) at 5170H, the operand of the CALL 0033H at 516FH: the characters go to the printer (003BH) instead of the display.
SKIP LINES
Register Pair BC counts down the lines before the first one shown.
SHOW LOOP
Register Pair DE = the lines left to show, Register C counts characters (a key check every 256).
GOSUB to the ROM's display routine at 0033H, or its printer routine at 003BH for PRINT; the operand's low byte 5170H is 33H in the file and 3BH after 50D5H.
5175H - Unused Bytes
5175H-51E7H fill the last load record; nothing reads or executes them.