TRS-80 DOS - NEWDOS/80 v2.0 for the Model III - SYS17/SYS Disassembled
Page Customization
Page Index
SYS17/SYS
Other Navigation
Introduction/Summary
NEWDOS/80 v2.0 SYS17/SYS Disassembly - SYSTEM, WRDIRP and the End of a Diskette COPY (Model III)
SYS17/SYS does the SYSTEM command (after SYS7/SYS has read its password and drive), the WRDIRP command, and the last part of a diskette COPY for SYS6/SYS. Its five load records fill 4D00H-51E7H of the overlay area (1,256 bytes) and its transfer address is 4D00H; 509FH-51E7H are 00H.
The page shows every byte of the file once, in address order.
Functions
| Code | Function |
|---|---|
| 33H | SYSTEM [password:]dn1[,xx=value]..., from SYS7/SYS with Register B = dn1, 4D0CH |
| 53H | WRDIRP dn1, from SYS1/SYS's command table, 4F6DH |
| Any other (F3H) | Returns at once with error 2AH: SYS6/SYS uses code F3H only to load SYS17/SYS, then jumps to 502CH at the end of a diskette COPY |
Both commands read their diskette through an FCB of their own (4F16H, 501EH) with FCB+0 bit 1 set, so that NEXT is a sector number of the whole diskette, and the buffer 4300H. WRDIRP's FCB also has FCB+0 bit 0, which makes SYS0/SYS write every sector with the directory mark. WRDIRP needs option BK (error 37H otherwise), checks the boot sector (bytes 00H FEH) and the entries of BOOT/SYS and DIR/SYS (error 2CH), and then reads and rewrites the GAT, the HIT and every FDE sector. The diskette COPY code at 502CH runs with SYS6/SYS still in memory from 5200H on and uses its routines and variables.
System Options
An option's code is (first letter - A) x 26 + (second letter - A); the table at 4F24H has one byte for each of the codes 0-71. The options live in the system data sector (sector 2): yes/no options as bits of bytes F0H-FFH, numbers as bytes at A0H-AFH or words at D0H-DFH. The reset copies bytes F0H and F1H to SYS0/SYS's 428CH and 428DH.
| Byte | Options |
|---|---|
| F0H | Bit 7 AA, 6 AB, 5 AG, 1 AR |
| F1H | Bit 7 AT, 6 BC, 5 BE, 4 BK |
| F8H | Bit 6 AD, 5 AE, 4 AF, 2 AQ, 1 AJ, 0 AU |
| F9H | Bit 7 AY, 6 AZ, 5 BA, 4 BB, 3 BD, 1 BG, 0 BH |
| A0H-A9H | AL, AW, AN, AO, (A4H none), BI, AM, AV, AX, BJ |
| D0H-D1H | AP, a 16-bit number |
AC, AH, AI, AK, AS, BF, BL, BM and BN are not on this machine (table byte FEH, error 34H); codes from BO on are FFH. After the options, option AL is set to 1 unless it is 1-4, and the sector is written back with a verify. The display shows every option as xx=Y or N, or xx=decimal/hexadecimalH.
Variables
Memory Outside SYS17/SYS
| Address Size | Contents |
|---|---|
| 4285H 1 byte | Granules per Lump Byte +5 of the selected drive's PDRIVE values: WRDIRP finds the GAT with it (4F9CH). |
| 428DH 1 byte | Options SYS0/SYS's copy of system data byte F1H: bit 4 option BK allows WRDIRP (4F6DH). |
| 4300H-43FFH 256 bytes | Sector Buffer The system data sector of SYSTEM (options at 43A0H-43AFH, 43D0H-43DFH and 43F0H-43FFH), WRDIRP's boot and directory sectors, and the destination GAT of a diskette COPY (43CEH password, 43D0H name, 43D8H date). |
| 5956H, 5994H-5995H 3 bytes | SYS6/SYS Control Block and Flags Used by the diskette COPY code: the destination's control block (5535H), the option flags (5036H). |
| 5981H, 5983H, 598BH 4 bytes | SYS6/SYS Password, Name, Date The new password code (505BH) and the name and date copied into the GAT (5076H). |
| 59B8H, 59BCH, 59C1H, 59C3H 6 bytes | SYS6/SYS Source Values Lumps (5049H), granules per lump (508AH), sectors (502FH) and granules (507BH, 5087H) of the source. |
| 59C6H, 59D1H 3 bytes | SYS6/SYS Destination Values Lumps (5043H) and granules (5078H) of the destination. |
SYS17/SYS Data
| Address Size | Contents |
|---|---|
| 4F08H-4F0FH 8 bytes | Powers of Ten Minus 10000, 1000, 100 and 10 for the decimal display. |
| 4F10H-4F15H 6 bytes | Hexadecimal Text "00000H"; 44D2H writes four digits at 4F11H. |
| 4F16H-4F23H 14 bytes | SYSTEM FCB The system data sector of dn1: drive 4F1CH, NEXT 4F20H. |
| 4F24H-4F6CH 73 bytes | Option Table One byte for each code AA-CT and an extra FFH. |
| 500FH-501DH 15 bytes | Names BOOT, DIR and four spaces with SYS. |
| 501EH-502BH 14 bytes | WRDIRP FCB Directory mark writes: drive 5024H, NEXT 5028H-5029H. |
Operands Changed at Run Time
| Address Size | Contents |
|---|---|
| 4D74H, 4D7AH 2 bytes | RES and SET Bit The second bytes of RES 0,(HL) at 4D73H and SET 0,(HL) at 4D79H, stored at 4D5EH and 4D63H. |
| 4E04H 1 byte | BIT Bit The second byte of BIT 0,(HL) at 4E03H, stored at 4DF6H. |
| 4F1CH, 4F20H 2 bytes | SYSTEM FCB The drive (4D0DH) and NEXT (4E23H). |
| 5024H, 5028H-5029H 3 bytes | WRDIRP FCB The drive (4F79H) and NEXT (4FA6H, 4FC5H, 4FCBH). |
Outside Routines and Addresses
| Address | Contents |
|---|---|
| 0033H | ROM: display a character (4E6DH). |
| 4409H | SYS0/SYS: the DOS error exit (4E81H). |
| 4436H, 443CH | SYS0/SYS: read the sector at NEXT (4D13H, 4F83H, 4FDEH), write it with a verify (4DBCH, 4FCEH). |
| 44D2H | SYS0/SYS: a word as four hexadecimal digits (4E4AH). |
| 48C4H | SYS0/SYS: write the directory sector in 4300H (5096H). |
| 4C37H, 4C39H, 4C59H | SYS0/SYS: multiply (4F99H, 4F9FH), divide (4DD4H, 508DH). |
| 4C7AH | SYS0/SYS: test for the end of the line or a separator (4D17H, 4DA7H, 4F7CH). |
| 5535H, 54CBH, 552DH, 56F9H, 5762H, 5784H | SYS6/SYS: switch to the destination, end with an error, end with DONE, read the GAT, free granules, verify the diskette. |
Disassembly
4D00H - Function Dispatcher
SYS17/SYS (directory slot 13H) is loaded by the SYS0/SYS RST 28H dispatcher (4B67H) into 4D00H-51E7H and entered at 4D00H by the CALL at 4BC2H, with Register A = the RST 28H code and 4BC5H (the dispatcher's tail) on top of the stack. Code 53H (function 2) is the WRDIRP command (SYS1/SYS's command table, Register Pair HL = the command line at dn1). Code 33H (function 1) is the SYSTEM command, called by SYS7/SYS after it has read the password and the drive, with Register B = the drive and Register Pair HL = the command line after it. Any other code, such as the F3H with which SYS6/SYS only loads SYS17/SYS for its diskette COPY (SYS6/SYS 62ADH, through its 568DH), returns at once with Register A = 2AH; SYS6/SYS then jumps to 502CH.
4D0CH - SYSTEM Command
SYSTEM [password:]dn1[,xx=value]... reads sector 2 of drive dn1, the system data sector, into 4300H through the FCB at 4F16H. Each option is two letters; its code (first letter - A) x 26 + (second letter - A) indexes the table at 4F24H. A table byte with bit 7 clear is a yes/no option: bit (byte bits 6-4) of system data byte F0H + (byte bits 3-0), set for Y. A byte with bit 7 set is a number: one byte at A0H + (bits 4-0), or with bit 6 a 16-bit number at D0H + (bits 4-0). FEH is an option this machine does not have (error 34H). After the options, option AL (byte A0H) is set to 1 unless it is 1-4, and the sector is written back with a verify. The options are then shown.
Store Register A (dn1) at 4F1CH, FCB+6 (the drive number) of the FCB at 4F16H.
Option Loop
Register Pair HL = the command line at the next option's first letter.
Store Register A at 4D74H, the second byte of the RES 0,(HL) at 4D73H, which then resets the option's bit.
Store Register A at 4D7AH, the second byte of the SET 0,(HL) at 4D79H, which then sets the option's bit.
Reset the option's bit of the byte at Register Pair HL: the second byte 4D74H (86H, bit 0, in the file) was stored at 4D5EH.
Set the option's bit of the byte at Register Pair HL: the second byte 4D7AH (C6H, bit 0, in the file) was stored at 4D63H.
4DC0H - Show the Options
Walks the table at 4F24H; every option this machine has (table byte below FEH) is shown as its two letters, an = sign and its value: Y or N, or a number as decimal/hexadecimal. The first item follows a carriage return, the others a comma; the table ends at its first FFH (4F4CH).
Show Loop
Register Pair HL = the table byte, Register Pair DE = its code, Register B = the separator to show first.
Store Register A at 4E04H, the second byte of the BIT 0,(HL) at 4E03H, which then tests the option's bit.
Test the option's bit of the byte at Register Pair HL: the second byte 4E04H (46H, bit 0, in the file) was stored at 4DF6H. The Z FLAG is set if the bit is clear.
4E21H - Point the FCB at Sector 2
Sets FCB+10 (4F20H) of the FCB at 4F16H to 02H, so that NEXT is sector 2 (the system data sector), and returns Register Pair DE = 4F16H for the read (4436H) or the write (443CH).
Store Register A (02H) at 4F20H, FCB+10 of the FCB at 4F16H: the middle byte of NEXT, so that NEXT = sector 2.
4E2AH - Show a Number Option
Register B = the table byte, Register Pair HL = the table pointer on the stack. The value (one byte at 43A0H + offset, or 16 bits at 43D0H + offset) is shown in decimal, a slash, then in hexadecimal with its leading zeros dropped (one 0 is kept before a first digit A-F) and an H.
Leading Zero Loop
Register Pair HL steps over the zeros before the first digit that is not 0.
4E6BH - Show a Character
Shows the character in Register A through the ROM routine 0033H, keeping Register Pairs AF and DE.
4E73H - Read a Number 0-255
Reads a number at Register Pair HL (decimal, or hexadecimal ended by H) and returns it in Register A with the Z FLAG; a number above 255 is error 2FH. 4E78H, an entry for decimal digits only, is never used. 4E7FH and 4E81H are the error exits.
4E84H - Read a Number
Reads a number at Register Pair HL into Register Pair DE: decimal digits, or hexadecimal digits ended by H. The digits are first read as decimal; if a letter A-H follows them, the number is read again from its start as hexadecimal and must then end with H. No digit or a missing H is error 2FH. A value above FFFFH stops the reading at the digit that caused it (4EDAH), so the caller's separator check then finds that digit.
Digit Loop
Register Pair HL = the next character, Register Pair DE = the value so far, Register B bit 0 = hexadecimal.
4EDEH - Show a Number in Decimal
Shows Register Pair DE in decimal without leading zeros, through 4E6BH.
Digit Loop
Register Pair DE = what is left of the number, Register Pair HL = the next power of ten in the table.
4F08H - Data
The powers of ten, the hexadecimal text, the FCB of the system data sector and the option table.
4F24H - Option Table (Data)
One byte per option code (first letter - A) x 26 + (second letter - A), read by 4D43H and 4DC0H. Bit 7 clear: a yes/no option, bit (bits 6-4) of system data byte F0H + (bits 3-0). Bit 7 set: a number at byte A0H + (bits 4-0), or with bit 6 a 16-bit number at D0H + (bits 4-0). FEH: an option this machine does not have. The first FFH (4F4CH) ends the display.
4F6DH - WRDIRP Command
WRDIRP dn1 rewrites every directory sector of the diskette in drive dn1 with the directory mark. It needs option BK (428DH bit 4, else error 37H). The boot sector (sector 0) must begin with 00H FEH; its byte 2 is the directory lump, so the GAT is sector lump x 5 x GPL (4285H, the drive's granules per lump). The first entry of the first FDE sector must be BOOT/SYS (a system file in use, first lump 0) and that of the second DIR/SYS (first lump = the directory lump), else error 2CH. Then the GAT, the HIT and the 8 + (HIT byte 1FH) FDE sectors are read (with or without the mark) and written back through the FCB at 501EH, whose FCB+0 bit 0 asks SYS0/SYS for the directory mark, with a verify.
Store Register A (dn1) at 5024H, FCB+6 (the drive number) of the FCB at 501EH.
Rewrite Loop
Register Pair HL = the directory sector, Register B = the sectors left.
4FDBH - Read a Directory Sector
Reads the sector at NEXT of the FCB at 501EH into 4300H. A good read, or error 06H (the sector has the directory mark), returns the Z FLAG; any other error leaves through 4E81H.
4FE7H - Check a System File's Entry
Reads the next directory sector (an FDE sector) and checks its first entry: byte 0 bits 6 and 4 set (a system file in use), byte 22 (the first lump of its first extent) = Register C, name = the 4 characters at Register Pair HL followed by the 7 characters at 5017H (four spaces and SYS). Any difference is error 2CH.
Compare Loop
Register Pair DE = the entry, Register Pair HL = the text, Register B = the bytes left.
502CH - End of a Diskette COPY
Not reached through 4D00H: SYS6/SYS loads SYS17/SYS (code F3H, which only returns) and its 54D4H jumps here when a diskette COPY has written every sector. SYS6/SYS stays in memory from 5200H on, so this code uses its routines and variables: the destination is verified from the source's last sector on, and unless BDU was given the destination's GAT gets the new password, name and date and, when the destination is larger than the source, its extra granules freed. It ends in SYS6/SYS at 552DH (DONE) or 54CBH (an error).
Fill Loop
GAT bytes 60H-BFH (lumps 96-191, beyond the source's lumps) are set to FFH, every granule in use, before the destination's real granules past the source are freed below.