DOSPLUS 3.5 for the Model III - LABEL/CMD Disassembled
Page Customization
Page Index
LABEL/CMD
Other Navigation
Introduction/Summary
DOSPLUS 3.5 LABEL/CMD Disassembly - The BASIC Label Resolver (Model III)
LABEL/CMD turns a BASIC program that uses labels into one that uses only line numbers, run from the DOS command level as LABEL filespec1 filespec2; its heading reads LABEL - DOSPLUS Label resolver - 3.50. It is a load module of 4 blocks, 998 bytes, at 5700H-5AE5H with the transfer address 5700H, after the two comment records (the name LABEL and the copyright notice). LABEL/CMD is on the Model III master only, and its manual is the addendum, which describes labels with the BASIC keyword NAME.
LABEL works on the program file as BASIC saves it in the tokenized form: the byte FFH, then each line as a link, a line number and the tokens and characters ended by 00H, and a link of 0000H at the end. The file control blocks and buffers of the source and the destination, and the table of labels, lie above the load module at 5AE6H on.
The Parts of LABEL/CMD
| Address | Contents |
|---|---|
| 5700H-576DH | The heading, the two file specifications or the prompts, OPEN@ and the FFH test (5700H, 571AH, 574EH). |
| 576EH-5802H | The first pass: the table of labels (576EH). |
| 5803H-5871H | The second pass: INIT@, the links and line numbers (5803H). |
| 5872H-5920H | The bytes of a line, NAME, the keywords and their lists, a label (5872H, 58A1H, 58E5H). |
| 5921H-59EDH | The look up, the prompt, reading and writing a byte, a number in decimal, Out of memory and the errors (5921H, 5972H, 5993H, 59D6H). |
| 59EEH-5AE5H | The texts, the keywords, the line number (59EEH). |
How LABEL Works
The two file specifications come from the command line; a missing one is asked for with Source filespec : or Destination filespec : (up to 25 characters; BREAK returns to the DOS; a bad reply is Improper file name and the prompt again, 571AH). The source is opened, and its first byte must be FFH, else Invalid file type! (574EH). Every error later shows its message and starts again at the prompts; the files are not closed then.
The first pass (Scanning -) reads each line and shows Line #: and its number over the one before (576EH). A line whose first statement, after any spaces, is NAME gives an entry to the table at 5E26H: the label up to a space, a colon or the end of the line, a 00H, and the line number. The source is then read again (REW@) for the second pass (Resolving -), and the destination is made by INIT@ (5803H). The FFH, each link and each line number are copied unchanged: BASIC makes the links again when it loads the program, so the shorter lines do no harm.
In the second pass each byte of a line is tested (5872H). NAME and everything after it up to a colon or the end of the line is left out, the colon too, wherever NAME stands. A keyword of the table at 5ADBH (GOTO, GOSUB, EDIT, RESUME, LIST, LLIST, DELETE, AUTO) is written and starts a list (58A1H): an item starting with a digit is copied, any other item is a label, taken up to a space, a comma, an apostrophe, a colon or the end of the line and looked up (58E5H, 5921H). A label in the table is replaced by its line number in decimal; one that is not is written unchanged and Undefined Label: and the label are shown beside the Line #: of the line. The end link closes the destination and LABEL returns to the DOS.
Differences from the Manual
The addendum says that LABEL replaces all label references. The bytes resolve only labels after the eight keywords of the table: a label after THEN, ELSE, RUN or RESTORE is written unchanged and no message is shown for it. A label must match a table entry in full, and NAME is looked for in the first pass only at the start of a line, while the second pass leaves out a NAME statement wherever it stands. Strings and remarks are not passed over: a byte equal to NAME or to a keyword of the table inside them is taken as that keyword.
The test for Out of memory (59D6H) compares the end of the table with Register Pair DE, which the first pass loads with HMEM$ (5777H) but replaces with the line number of each line (5793H). The table is never stopped at HMEM$; Out of memory comes only when the end of the table happens to equal the number of the line being scanned.
Variables
LABEL/CMD Variables
| Address Size | Contents |
|---|---|
| 5AE4H-5AE5H 2 bytes | Line number The line of the first pass (578DH). |
| 5AE6H-5BE5H 256 bytes | Buffer Replies, digits and the label looked up (5975H, 58E5H). |
| 5BE6H-5C05H 32 bytes | Source FCB The source program (5708H). |
| 5C06H-5D05H 256 bytes | Source buffer (5751H). |
| 5D06H-5D25H 32 bytes | Destination FCB The program written (5710H). |
| 5D26H-5E25H 256 bytes | Destination buffer (5814H). |
| 5E26H to the top | Labels The table of labels: label, 00H, line number (5774H). |
Memory Outside LABEL/CMD
| Address Size | Contents |
|---|---|
| 4411H-4412H 2 bytes | HMEM$ Loaded as the limit of the table (5777H). |
Outside Routines
| Address | Contents |
|---|---|
| 4467H | SYS0/SYS: DSPLY@ (5704H, 5972H). |
| 441CH | SYS0/SYS: FSPEC@ (570BH). |
| 4424H | SYS0/SYS: OPEN@ (5756H). |
| 4420H | SYS0/SYS: INIT@ (5819H). |
| 443FH | SYS0/SYS: REW@ (5808H). |
| 4428H | SYS0/SYS: CLOSE@ (583AH). |
| 4409H | SYS0/SYS: ERROR@ (572FH, 59E8H). |
| 0013H | ROM: input a byte from a control block (597FH). |
| 001BH | ROM: output a byte to a control block (598BH). |
| 0033H | ROM: display a character (57A9H). |
| 0040H | ROM: line input (5978H). |
Disassembly
5700H - LABEL
LABEL/CMD's transfer address, entered from the DOS command level with Register Pair HL at the command line after the word LABEL: LABEL filespec1 filespec2. LABEL is the label resolver of the addendum: it reads a BASIC program saved in the tokenized form (first byte FFH) that uses labels (NAME label at the start of a line, and labels in place of line numbers after GOTO and the other keywords of its table), makes a table of the labels and their line numbers in a first pass, and writes in a second pass a copy without the NAME statements, each label reference replaced by its line number. LABEL loads at 5700H, above the buffers it does not use.
571AH - The Prompts
Source filespec : and Destination filespec : take up to 25 characters each into 5AE6H; BREAK returns to the DOS, and a reply FSPEC@ refuses is the error 13H, Improper file name, and the same prompt again. Every error of LABEL comes back here.
574EH - Open the Source
OPEN@ of the source with 256 byte records and the buffer 5C06H; its first byte must be FFH, the mark of a BASIC program in the tokenized form, else Invalid file type! and the prompts again.
576EH - The First Pass
Scanning -. For each line: the link (0000H ends the program), the line number (kept in 5AE4H and shown as Line #: n over itself), then the first byte after the spaces. NAME (A9H) followed by a label adds the entry label, 00H, line number to the table at 5E26H; the rest of the line is passed over.
5803H - The Second Pass
An empty label (00H) ends the table; the source is read again from its start; Resolving -; the destination is made by INIT@ with the buffer 5D26H, and the FFH mark and each line's link are copied unchanged. The end link 0000H closes the destination and LABEL returns to the DOS.
5872H - A Byte of the Line
Outside a list of line numbers each byte is read and tested: NAME (A9H) drops itself and the bytes after it up to a colon (dropped too) or the end of the line; a keyword of the table at 5ADBH (GOTO, GOSUB, EDIT, RESUME, LIST, LLIST, DELETE, AUTO) is written and starts a list (bit 0 of Register B); any other byte is written. Strings and remarks are not passed over.
58A1H - An Item of a List
Spaces are written; a colon, an apostrophe (27H) or the end of the line ends the list; an item starting with a digit is a line number, written as it is; any other item is a label, looked up and replaced (58E5H). A comma goes on with the list.
58E5H - A Label in a List
The label's characters up to the end of the line, a space, an apostrophe, a comma or a colon go into 5AE6H (Register C keeps the byte that ended it); 5921H writes the line number of the label, or the label itself when it is not in the table. The end of the line, an apostrophe or a colon ends the list.
5921H - Look Up a Label
Compares the label at 5AE6H with each label of the table at 5E26H (each ended by 00H and followed by its line number); the whole label must match. Found: the line number is written in decimal. Not found: the label is written unchanged and Undefined Label: and the label are shown beside the Line #: of the line.
5972H - Prompt, Read a Byte, Write a Byte
5972H shows the prompt and takes a reply of up to Register B characters into 5AE6H by the ROM's 0040H. 597BH reads a byte of the source by 0013H and 5987H writes one to the destination by 001BH; on an error each drops its own return address and goes to 59E6H.
5993H - A Number in Decimal
Register Pair DE = the number, Register Pair HL = the buffer: five digits by subtracting the powers of ten of the table at 59CAH, then 00H; Register Pair HL returns past up to four leading zeros. Register Pair BC and Index Register IX are saved.
59D6H - Out of Memory and the Errors
59D6H returns when Register Pair HL is not Register Pair DE; when they are equal it drops its return address and shows Out of memory, then the prompts. 59E6H posts the error in Register A with bits 7 and 6 set (ERROR@ returns, no frame) and goes to the prompts.
59EEH - The Texts and the Variables
Data: the heading, the prompts and messages (ended by 03H or 0DH), the table of the keywords that take line numbers, and the line number of the first pass. 5AE6H on is not loaded: the buffer, the two file control blocks and buffers, and the table of labels.