DOSPLUS 3.5 for the Model III - TAPE/CMD Disassembled
Page Customization
Page Index
TAPE/CMD
Other Navigation
Introduction/Summary
DOSPLUS 3.5 TAPE/CMD Disassembly - The Disk and Tape Manager (Model III)
TAPE/CMD moves machine language programs between system tapes and disk load modules, and can move them in memory on the way, run from the DOS command level as TAPE; its heading reads TAPE - DOSPLUS Disk/tape manager - 3.50. It is a load module of 7 blocks, 1728 bytes, at 5200H-58BFH with the transfer address 5200H, after the two comment records (the name TAPE and the copyright notice). TAPE/CMD is on the Model III master only.
TAPE keeps what it reads in a store from 5B42H up to 300 bytes below HMEM$: each block as the mark 01H, its address, the count of its bytes (00H for 256) and the bytes, and the end of each program as the mark 02H; up to ten programs, with their names in a table at 5948H. One transfer address is kept, that of the last program read, and one offset, which is added to every address when the programs are written. TAPE uses the ROM's cassette routines (0296H, 0235H, 0287H, 0264H, 01F8H) and its own stack at 41E5H.
The Parts of TAPE/CMD
| Address | Contents |
|---|---|
| 5200H-526DH | The start, the command loop and the table of commands (5200H, 5212H). |
| 526EH-52BCH | B, H and I (526EH). |
| 52BDH-5345H | L, a disk load module (52BDH). |
| 5346H-542CH | M, the map (5346H, 53FEH). |
| 542DH-54D0H | O, Q and R, a system tape (542DH). |
| 54D1H-560DH | S, a disk load module, and W, a system tape (54D1H, 5572H). |
| 560EH-57B8H | Room, a name, the loader of -A, the keys and output, the errors (560EH, 5638H, 56ECH, 577AH). |
| 57B9H-58BFH | The two loaders, the texts and the messages (57B9H, 57F1H). |
How TAPE Works
Each command is a letter after the asterisk; the line is up to 62 characters, and the stack is set again for each command (5212H). L name opens a disk file and keeps its 01H records; R name looks on the tape for the header 55H with the six character name and keeps its 3CH blocks, each checked against its checksum, up to the 78H record (52BDH, 543EH). Both take the transfer address of the program read. I empties the store; B H or B L sets the cassette speed (1500 or 500 baud); O nnnn sets the offset; Q returns to the DOS. M lists each program: its name, then each run of blocks that follow on in memory as start-end, and again with the offset added; then XFER= and OFFSET= (5346H).
S name writes every program in the store to one disk load module, W name to one system tape: each block at its address plus the offset, and at the end the transfer address plus the offset (54D1H, 5572H). With -A and an offset set, a 23 byte loader is added as one more block (5638H): it is placed just below the lowest block (for an offset below 0000H) or just after the highest, both with the offset, and it becomes the transfer address. When it runs it turns the interrupts off, makes RST 38H a RET, sets the I/O drivers back to the ROM's by 0069H, moves the program to the addresses it was read from (LDDR or LDIR, whichever is safe) and jumps to its transfer address (57B9H).
Differences from the Manual
The manual says M-P sends the map to the screen and the printer; the bytes send it to the printer only (56FBH). H shows only the ten command letters. -A adds nothing when the offset is 0000H, so a program that must load below the DOS needs an offset as well. B takes only upper case H or L. Only the last program's transfer address is kept, and S and W write all the programs in memory as one file with that one address. Neither L nor S tests the reads and writes of each byte, and L does not close the file.
R compares the tape's name with the name typed through Register Pair HL, which is not set back after a header with another name (546EH): when the wanted program is not the first on the tape, its name is compared with the wrong characters of the entry, and the search goes past it.
Variables
TAPE/CMD Variables
| Address Size | Contents |
|---|---|
| 58C0H 1 byte | Printer flag 00H the display, FFH the printer (5362H). |
| 58C1H 1 byte | Programs The count in memory (5344H). |
| 58C2H-58C3H 2 bytes | Transfer Of the last program read (533DH). |
| 58C4H-58C5H 2 bytes | Offset (5430H). |
| 58C6H 1 byte | To write Programs to write (54D4H). |
| 58C7H-58C8H 2 bytes | Store end (52B9H). |
| 58C9H-58CCH 4 bytes | Limits The highest end and lowest start, for -A (5640H). |
| 58CDH-58CEH 2 bytes | Transfer to write (54DBH, 56B1H). |
| 58CFH-58E7H 25 bytes | Name For S or W (54E1H). |
| 58E8H-5907H 32 bytes | FCB For L and S (52DEH). |
| 5908H-5947H 64 bytes | Line (5220H). |
| 5948H-5A41H 250 bytes | Names Ten entries of 25 bytes (52CEH). |
| 5A42H-5B41H 256 bytes | Disk buffer (52E9H). |
| 5B42H upwards | Store The programs (52B6H). |
Memory Outside TAPE/CMD
| Address Size | Contents |
|---|---|
| 4204H-4205H 2 bytes | BREAK vector The ROM's cassette BREAK vector, set to 57B3H (5206H). |
| 4211H 1 byte | Cassette speed The ROM's baud rate selector (5282H). |
Outside Routines
| Address | Contents |
|---|---|
| 441CH | SYS0/SYS: FSPEC@ (52E1H). |
| 4424H | SYS0/SYS: OPEN@ (52ECH). |
| 4420H | SYS0/SYS: INIT@ (550DH). |
| 4428H | SYS0/SYS: CLOSE@ (556BH). |
| 4409H | SYS0/SYS: ERROR@ (57ADH). |
| 402DH | SYS0/SYS: EXIT@ (543BH). |
| 0013H | ROM: input a byte from a control block (52FBH). |
| 001BH | ROM: output a byte to a control block (5526H). |
| 002BH | ROM: scan the keyboard (56EDH). |
| 0033H | ROM: display a character (5703H). |
| 003BH | ROM: print a character (5707H). |
| 0040H | ROM: line input (5223H). |
| 0069H | ROM: set the I/O drivers back, called by the loader (57C3H). |
| 0235H | ROM: read a byte from the cassette (5463H). |
| 0264H | ROM: write a byte to the cassette (55A2H). |
| 0287H | ROM: cassette on, leader and sync written (559DH). |
| 0296H | ROM: cassette on, leader and sync found (545EH). |
| 01F8H | ROM: cassette motor off (54ABH, 57B3H). |
Disassembly
5200H - TAPE
TAPE/CMD's transfer address, entered from the DOS command level (TAPE takes no parameters). TAPE keeps up to ten programs in memory, read from disk load modules (L) or system tapes (R), lists them (M), sets an offset (O) that moves every block when it is written, and writes them as one disk load module (S) or system tape (W), with -A a small loader that moves the program back to its own addresses and starts it. Each command is one letter after the asterisk prompt; the stack is set again at 5212H for every command, and every error comes back there.
5212H - The Command Loop
The stack is set again and the printer flag cleared; an asterisk, a line of up to 62 characters (BREAK asks again), and the first letter of the line, made upper case, is looked up in the table at 5250H. The command's routine is entered by RET with Register Pair HL after the letter and 5212H as its return address; a letter not in the table is Invalid command.
526EH - B, H and I
B H sets the fast cassette speed, B L the slow one (4211H, the ROM's baud rate selector); the letter must be upper case and end the line. H shows the ten command letters with commas. I clears the variables 58C0H-58C5H and empties the store (5B42H on); the start of TAPE calls it at 52ACH.
52BDH - L, Load a Disk Load Module
L filespec: the name (up to 24 characters, to the end of the line) goes into the program's 25 byte entry of the names table at 5948H; FSPEC@ and OPEN@ open the file, and its records are read by GET@ into the store: a type 01H block as 01H, its address, the count of its bytes and the bytes; the transfer record as 02H, its address kept at 58C2H. Other records are passed over; a type of 20H or more is Non program file. The file is not closed.
5346H - M, the Map
M, or M-P to send the map to the printer instead of the display. For each program its name, then each run of blocks that follow one another in memory as start-end and, after two spaces, start-end with the offset added; between runs the SHIFT and @ keys (60H) pause and BREAK ends the map. At the end XFER= the transfer address and OFFSET= the offset.
53FEH - A Run of the Map
Register Pair HL = the start, Register Pair DE = the last address: sends start-end, two spaces, and both again with the offset of 58C4H added, then a carriage return. Register Pair BC is saved.
542DH - O, Q and R
O nnnn: the offset, hexadecimal (only the last four digits count), stored at 58C4H. Q returns to the DOS by EXIT@. R name: a system tape is searched for the header 55H and the six character name; its 3CH blocks are checked (the sum of the address bytes and the data) and kept in the store, and the 78H record gives the transfer address.
54D1H - S, Save a Disk Load Module
S filespec, or S filespec-A with the loader of 5638H. The programs in memory (and the loader) are written to the file by INIT@ and PUT, each block as a type 01H record at its address plus the offset, then one transfer record with the transfer address plus the offset; CLOSE@. The PUTs are not tested.
5572H - W, Write a System Tape
W name or W name-A: the header 55H and the six character name, then each block as 3CH, the count, the address plus the offset, the bytes and the checksum (the sum of the address bytes and the data), and the end 78H with the transfer address plus the offset; the motor is turned off.
560EH - Room and a Name
560EH returns the C FLAG when Register Pair HL plus 300 (012CH) reaches HMEM$. 561EH copies a name of up to Register B characters from the command line to Register Pair DE, ending at the end of the line (the C FLAG) or a minus sign (the NC FLAG), and pads it with at least one space; a longer name is Bad filename.
5638H - -A, the Loader
Only when an offset is set. The lowest address and the address after the highest of all blocks give the length to move; with an offset below 0000H (the sum carries) the 28 byte record at 57B9H (LDDR, placed 17H bytes below the lowest address) is used, else the one at 57D5H (LDIR, placed at the address after the highest). Its operands get the addresses, the length and the transfer address; it is added to the store as one more program, and the transfer address to write becomes the loader's.
56ECH - Keys, Output and the Line
56ECH scans the keyboard (002BH), 56F3H waits for a key; 56F9H sends a carriage return and 56FBH Register A, to the display or (printer flag 58C0H set) to the printer only; 570DH sends a text up to 00H; 571AH takes the next character of the line after spaces (the C FLAG below 20H); 5721H compares Register Pair HL with Register Pair DE; 5727H multiplies; 5736H sends Register Pair HL in hexadecimal; 574FH takes a hexadecimal number.
577AH - The Errors
TAPE's own seven messages, numbered by Register E: 577AH Invalid command (1), and inside the LD BC instructions after it 577DH Checksum error (2), 5780H Bad filename (3), 5783H Non program file (4), 5786H File area full (5), 5789H Buffer area full (6), 578CH Parameter error (7). 578EH finds message Register E in the table at 5859H (each starts with a byte with bit 7 set) and shows it; a DOS error goes to ERROR@ (57ABH) with bits 7 and 6 set; both return to the command loop. 57B3H is the BREAK vector during cassette work.
57B9H - The Two Loaders
Each is a record for the store, 28 bytes: the mark 03H (bit 0 set, so S and W write it as a block), its address, the count 17H and 23 bytes of code, then 02H. The code turns the interrupts off, makes the RST 38H vector a RET, calls the ROM's 0069H, which sets all I/O drivers back to the ROM's, moves the program from the copy to its own addresses and jumps to its transfer address. 57B9H moves it down from the top (LDDR), for an offset below 0000H; 57D5H from the bottom (LDIR).
57F1H - The Texts and the Variables
Data: the heading, the texts of the map, the table of the messages (the first character of each with bit 7 set, an 80H after the last). 58C0H on is not loaded: the variables, the name, the file control block, the line, the names table, the buffer and the store.