DOSPLUS 3.5 for the Model III - SYS7/SYS Disassembled

Page Customization

Introduction/Summary

DOSPLUS 3.5 SYS7/SYS Disassembly - EVAL@, WILD@ and LOCDEV@ (Model III)

SYS7/SYS is the low overlay of the command line routines that the library commands and the utilities share: EVAL@ (4479H, request code 63H), the command evaluator, WILD@ (447CH, 64H), the wildmask, and LOCDEV@ (447FH, 65H), the lookup of a device or drive name. Its routine 6, which takes one field of a command line, is requested by SYS11/SYS (66H). The file is a load module of 4 blocks, 997 bytes, from 4E00H to 51E4H, with the transfer address 4E00H. The wildmask is kept outside the overlay, at 42B0HH-42BAHH, so that it lasts while other overlays load.

The Parts of SYS7/SYS

AddressContents
4E00H-4E0DHThe routine table (routines 2-7) and routine 2 (4E00H, 4E0CH).
4E0EH-4EC7HEVAL@: the fields, the keywords FROM, TO and USING, the choice of block, the error return (4E0EH).
4EC8H-4EDAHA compare with a pattern in which ? matches any byte (4EC8H).
4EDBH-4F3BHWILD@: set the wildmask or compare a name with it (4EDBH, 4F14H, 4F2DH).
4F3CH-4FEDHRoutine 6, one field of a command line, and the copy of one part of a field (4F3CH, 4FABH).
4FEEH-506CHThe parameter name lookup, the end of line and file name character tests and their list (4FEEH, 503AH, 5043H).
506DH-50D6HLOCDEV@ (506DH).
50D7H-51D5HThe parameters: names, logical values, strings and numbers (50D7H, 5164H, 518EH, 51A9H).
51D7H-51E4HThe keywords FROM, TO and USING (51D7H).

EVAL@

EVAL@ takes Register Pair HL = the command line and Index Register IX = the 9 byte evaluation block: a flag byte (bit 0 source, bit 1 destination, bit 2 wildmask, bit 3 parameters filled) and the addresses of the source, destination and wildmask blocks and of the parameter block. Each block is 33 bytes: a flag byte and up to 32 bytes of text ended by 03H. Fields are separated by spaces or commas. Each one is first taken into 4300HH by routine 6; when it is the word FROM, TO or USING, the field after it goes straight into that block (4E94H); otherwise a field with a wildcard (?, * or !) goes to the wildmask block, and any other to the source block, then the destination block, then the wildmask block, and is copied there (4EB6H). A field given twice is an error. A comma or a left parenthesis starts the parameters, which end the evaluation: anything after their closing parenthesis is not looked at.

Routine 6 (4F3CH) copies NAME/EXT.PASSWORD:DRIVE, @XX or :D, letters made upper case, and sets the block's flag byte: bit 6 a name, bit 5 a wildcard, bit 7 a device or a drive, with the number LOCDEV@ returns in bits 0-3. A name is up to 8 characters, an extension 3, a password 8, a device or drive name 2; longer parts are cut. A drive after a name with a wildcard is not taken into that field: it becomes the next field, which is how COPY !/TXT:1 :0 gives !/TXT as the wildmask and :1 as the source, as the manual says.

The parameter block has 9 byte entries: a six character name, the address for the value, and a type byte (bit 7 a string, bit 6 a number, bit 5 a logical value), ended by 00H. A name may be shortened to its first letters (4FEEH). A name alone stores FFFFH; NAME=Y, YES or ON stores FFFFH and N, NO or OFF 0000H (5164H); a value in quotation marks stores the address of its first character (5142H); a number ending in H is hexadecimal (51A9H), any other is decimal (518EH). A value whose type bit is clear is an error.

Every error of EVAL@ returns Register A = 2EH, Invalid parameter, with the NZ FLAG, whatever routine found it: an empty part, an unknown device, a second source, an unknown parameter name or a value of the wrong type.

WILD@ and LOCDEV@

WILD@ with Register B not 00H takes a file specification at Register Pair HL and makes the wildmask at 42B0HH from it: the name and the extension, upper case and padded with spaces; a * fills the rest of its part with ?, a ! the rest of the name and the whole extension (4F14H). A part that is not given stays spaces. With Register B = 00H, WILD@ compares the 11 bytes at Register Pair HL, a name and an extension as a directory entry holds them, with the wildmask, each ? matching any character (4F0AH).

LOCDEV@ takes Register Pair DE pointing to a prefix and a two character name. After a colon the name is a drive, looked up in DCTTBL (44E8HH), and Register A returns 08H plus the drive number; after anything else it is a device, looked up in the DCB table (44A6HH), and Register A returns the device number, 0 (KI) to 5 (U2). A one character name matches a table name whose second character is a space. A name not found returns error 29H, Device not available (506DH).

Differences from the Manual

EVAL@ returns one error code, 2EH, for every error. WILD@ compares a name and an extension in directory form, 11 bytes, not a file specification ended by 03H or 0DH, and setting a wildmask always returns the Z FLAG: no wildmask is refused. LOCDEV@ does not check the @ before a device name and compares the names as they are, without making them upper case.

Differences from the Model I

The code is the Model I SYS7/SYS at the same addresses; only the addresses in SYS0/SYS differ: the wildmask is at 42B0H-42BAH (Model I 435EH-4368H), the system buffer at 4300H (4200H), the register saving wrapper is called through 4485H (4525H), DCTTBL is at 44E8H (43ABH) and the DCB table at 44A6H (4369H).

Variables

The Wildmask ({435E}H-{4368}H)

Address
Size
Contents
42B0HH-42B7HH
8 bytes
Name Part
42B0H
42B8HH-42BAHH
3 bytes
Extension Part
42B8H

Other Memory

Address
Size
Contents
4300HH-4220HH
33 bytes
Field Block
The block each field is taken into first (flag byte and text); a parameter name is copied to 4300HH too (4E39H, 50DAH).
4FE7H
1 byte
Part Empty
The operand of the LD A,n at 4FE6H: the part's length until a character is copied, then 00H.
5063H-506CH
10 bytes
File Name Characters
5063H
51D7H-51E4H
14 bytes
Keywords
51D7H

Outside Routines and Tables

AddressContents
4485HSYS0/SYS: call the routine after the CALL with the registers other than AF saved.
44E8HSYS0/SYS: DCTTBL, the drive names (5077H).
44A6HSYS0/SYS: the DCB table, the device names (50A7H).

Disassembly

42B0H - WILD@'s Wildmask

Not in the file: WILD@ keeps the wildmask it was given in SYS0/SYS's RAM at 42B0H-42BAH, between BREAK$ (42ADH-42AFH) and the saved date (42BBH-42BDH), so the mask lasts from the call that sets it to the calls that compare with it, while other overlays load.

42B0-42B7
DEFS 8
The name part of the wildmask: eight characters, upper case, padded with spaces, a ? matching any character. WILD@ fills it with spaces (4EE3H-4EEFH) and copies the name in (4EF6H).
42B8-42BA
DEFS 3
The extension part of the wildmask, three characters padded with spaces (4EFFH-4F05H). The compare checks all 11 bytes from 42B0H (4F0BH).

4E00H - The Routine Table

Data: SYS7/SYS's table of routines 2-7, one word each, used by SYS0/SYS's overlay request handler (its 49D3H-49E6H) for the request codes 62H-67H. EVAL@ (4479H) requests 63H, WILD@ (447CH) 64H, LOCDEV@ (447FH) 65H, and SYS11/SYS requests 66H (its 5409H); no file of the diskette requests 62H or 67H.

4E00-4E01
DEFW 4E0CH 0C 4E
Routine 2: 4E0CH, XOR A and RET, which SYS0/SYS's record locator requests when it loads SYS7/SYS back (its 4D5FH-4D6CH).
4E02-4E03
DEFW 4E0EH 0E 4E
Routine 3: 4E0EH, EVAL@, the command evaluator, which takes the FROM, TO, USING and parameter fields of a command line.
4E04-4E05
DEFW 4EDBH DB 4E
Routine 4: 4EDBH, WILD@, which sets the wildmask or compares a name and extension with it.
4E06-4E07
DEFW 506DH 6D 50
Routine 5: 506DH, LOCDEV@, which finds the number of a drive or a device from its two character name.
4E08-4E09
DEFW 4F3CH 3C 4F
Routine 6: 4F3CH, which takes one field of a command line into a 33 byte block; EVAL@ calls it too.
4E0A-4E0B
DEFW 50D7H D7 50
Routine 7: 50D7H, the parameter part of EVAL@, which EVAL@ jumps to; no file requests it by its code 67H.

4E0CH - Routine 2

Nothing to do when SYS0/SYS's record locator brings SYS7/SYS back.

4E0C
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: routine 2 has no work to do.
4E0D
RET C9
RETurn to SYS0/SYS's overlay request handler (49E7H) with Register A = 00H.

4E0EH - EVAL@ - The Command Evaluator

Routine 3, requested by EVAL@ (4479H). Register Pair HL points to the command line (ended by 03H, 0DH, any other control character or a semicolon), Index Register IX to the 9 byte evaluation block: +00H the flags (bit 0 source, bit 1 destination, bit 2 wildmask, bit 3 parameters), +01H, +03H and +05H the addresses of the source, destination and wildmask blocks (33 bytes each: a flag byte and the field's text), +07H the address of the parameter block. Each field is taken into 4300H first; after the word FROM, TO or USING the next field goes straight into that block, otherwise a field with a wildcard goes to the wildmask block and any other to the first of the source and destination blocks still free. A comma or a left parenthesis starts the parameters (50D7H), which end the evaluation. Returns the Z FLAG and Register A = 00H, or the NZ FLAG and Register A = 2EH (Invalid parameter) for every error, with Register Pair HL where the scan stopped.

4E0E
LD (IX+00H),00H DD 36 00 00
Store 00H to the flag byte of the evaluation block at Index Register IX+00H: no field is filled yet.

4E12H - The Next Field

Skips spaces; a comma or a left parenthesis starts the parameters, the end of the line ends EVAL@, anything else is a field.

4E12
LD A,(HL) 7E
Load Register A with the next character of the command line at Register Pair HL.
4E13
INC HL 23
INCrement Register Pair HL by 1 to the character after it.
4E14
CP 20H FE 20
Compare Register A against 20H, a space, which is skipped.
4E16
If the Z FLAG is set (a space), JUMP back to 4E12H for the next character.
4E18
DEC HL 2B
DECrement Register Pair HL by 1, back to the first character that is not a space.
4E19
CP 2CH FE 2C
Compare Register A against 2CH, a comma, which starts the parameter field.
4E1B
If the Z FLAG is set (a comma), JUMP to 4E21H to take the parameters.
4E1D
CP 28H FE 28
Compare Register A against 28H, a left parenthesis, the other start of the parameter field.
4E1F
If the NZ FLAG is set (neither), JUMP to 4E2EH to take a file or device field.
4E21
SET 3,(IX+00H) DD CB 00 DE
Set bit 3 of the flag byte at Index Register IX+00H: the parameter field is filled.
4E25
LD E,(IX+07H) DD 5E 07
Load Register E with the low byte of the parameter block's address from Index Register IX+07H.
4E28
LD D,(IX+08H) DD 56 08
Load Register D with the high byte from Index Register IX+08H: Register Pair DE = the parameter block.
4E2B
JUMP to 50D7H to take the parameters into the parameter block; its RETurn ends EVAL@.
4E2E
GOSUB to 503AH, which sets the C FLAG when Register A is a control character or a semicolon, the end of the line.
4E31
If the NC FLAG is set (more to evaluate), JUMP to 4E35H.
4E33
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: the end of the line, no error.
4E34
RET C9
RETurn to the caller of EVAL@ with the Z FLAG set and Register A = 00H.
4E35
LD DE,4E94H 11 94 4E
Point Register Pair DE to 4E94H, the code that takes the field after a FROM, TO or USING.
4E38
PUSH DE D5
Save Register Pair DE (4E94H) to the top of the stack, as the return address of the block choice below.
4E39
LD DE,4300H 11 00 43
Point Register Pair DE to 4300H, SYS0/SYS's system buffer, where each field is taken first.
4E3C
GOSUB to 4F3CH to take the next field into the block at Register Pair DE (its flag byte at 4300H, its text from 4301H).
4E3F
INC DE 13
INCrement Register Pair DE (4300H on return) by 1 to 4301H, the field's text; the flags are kept.
4E40
If the NZ FLAG is set (the field is wrong), JUMP to 4EC3H to drop the return address and return error 2EH.
4E43
LD BC,51D7H 01 D7 51
Point Register Pair BC to 51D7H, the word FROM and the 03H that ends a field.
4E46
LD A,05H 3E 05
Load Register A with 05H, the four letters and the 03H, the bytes to compare.
4E48
GOSUB to 4EC8H to compare Register A bytes of the field at Register Pair DE with the word at Register Pair BC.
4E4B
If the NZ FLAG is set (the field is not FROM), JUMP to 4E5EH to try TO.

4E4DH - The Source Block

Reached after FROM, or for a field without a keyword while the source is free (4EACH): sets bit 0 of the flags and returns Register Pair DE = the source block to the address on the stack. A second source is an error.

4E4D
BIT 0,(IX+00H) DD CB 00 46
Test bit 0 of the flag byte at Index Register IX+00H, set when the source field is filled.
4E51
If the NZ FLAG is set (a second source), JUMP to 4EC3H to return error 2EH.
4E53
SET 0,(IX+00H) DD CB 00 C6
Set bit 0 of the flag byte at Index Register IX+00H: the source field is filled.
4E57
LD E,(IX+01H) DD 5E 01
Load Register E with the low byte of the source block's address from Index Register IX+01H.
4E5A
LD D,(IX+02H) DD 56 02
Load Register D with the high byte from Index Register IX+02H: Register Pair DE = the source block.
4E5D
RET C9
RETurn to the address on the stack: 4E94H after FROM, which takes the next field into the block, or 4EB6H, which copies the field there.
4E5E
LD BC,51DCH 01 DC 51
Point Register Pair BC to 51DCH, the word TO and the 03H that ends a field.
4E61
LD A,03H 3E 03
Load Register A with 03H, the two letters and the 03H, the bytes to compare.
4E63
GOSUB to 4EC8H to compare Register A bytes of the field at Register Pair DE with the word at Register Pair BC.
4E66
If the NZ FLAG is set (the field is not TO), JUMP to 4E79H to try USING.

4E68H - The Destination Block

Reached after TO, or for a field without a keyword while the source is filled and the destination free (4EB2H). A second destination is an error.

4E68
BIT 1,(IX+00H) DD CB 00 4E
Test bit 1 of the flag byte at Index Register IX+00H, set when the destination field is filled.
4E6C
If the NZ FLAG is set (a second destination), JUMP to 4EC3H to return error 2EH.
4E6E
SET 1,(IX+00H) DD CB 00 CE
Set bit 1 of the flag byte at Index Register IX+00H: the destination field is filled.
4E72
LD E,(IX+03H) DD 5E 03
Load Register E with the low byte of the destination block's address from Index Register IX+03H.
4E75
LD D,(IX+04H) DD 56 04
Load Register D with the high byte from Index Register IX+04H: Register Pair DE = the destination block.
4E78
RET C9
RETurn to the address on the stack, 4E94H or 4EB6H, with Register Pair DE = the destination block.
4E79
LD BC,51DFH 01 DF 51
Point Register Pair BC to 51DFH, the word USING and the 03H that ends a field.
4E7C
LD A,06H 3E 06
Load Register A with 06H, the five letters and the 03H, the bytes to compare.
4E7E
GOSUB to 4EC8H to compare Register A bytes of the field at Register Pair DE with the word at Register Pair BC.
4E81
If the NZ FLAG is set (no keyword), JUMP to 4E9CH to choose the block by the field's contents.

4E83H - The Wildmask Block

Reached after USING, for a field with a wildcard character, or for a third field without a keyword. A second wildmask is an error.

4E83
BIT 2,(IX+00H) DD CB 00 56
Test bit 2 of the flag byte at Index Register IX+00H, set when the wildmask field is filled.
4E87
If the NZ FLAG is set (a second wildmask), JUMP to 4EC3H to return error 2EH.
4E89
SET 2,(IX+00H) DD CB 00 D6
Set bit 2 of the flag byte at Index Register IX+00H: the wildmask field is filled.
4E8D
LD E,(IX+05H) DD 5E 05
Load Register E with the low byte of the wildmask block's address from Index Register IX+05H.
4E90
LD D,(IX+06H) DD 56 06
Load Register D with the high byte from Index Register IX+06H: Register Pair DE = the wildmask block.
4E93
RET C9
RETurn to the address on the stack, 4E94H or 4EB6H, with Register Pair DE = the wildmask block.

4E94H - The Field After a Keyword

Reached by the RETurn of 4E5DH, 4E78H or 4E93H after FROM, TO or USING, with Register Pair DE = the chosen block: the field after the keyword goes straight into it.

4E94
GOSUB to 4F3CH to take the next field of the command line into the block at Register Pair DE.
4E97
If the NZ FLAG is set (the field is wrong or missing), JUMP to 4EC4H to return error 2EH.
4E99
JUMP back to 4E12H to evaluate the next field of the command line.

4E9CH - A Field Without a Keyword

The field in 4300H goes to the wildmask block when it has a wildcard (bit 5 of its flag byte), else to the source block when that is free, else to the destination block when that is free, else to the wildmask block; 4EB6H then copies it there.

4E9C
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer (4E94H) with Register Pair HL, the command line pointer, which goes to the stack.
4E9D
LD HL,4EB6H 21 B6 4E
Point Register Pair HL to 4EB6H, the code that copies the field from 4300H to the chosen block.
4EA0
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL: 4EB6H is the return address and Register Pair HL the command line again.
4EA1
DEC DE 1B
DECrement Register Pair DE by 1, from 4301H to 4300H, the field's flag byte.
4EA2
LD A,(DE) 1A
Load Register A with the field's flag byte at Register Pair DE.
4EA3
INC DE 13
INCrement Register Pair DE by 1, back to 4301H.
4EA4
BIT 5,A CB 6F
Test bit 5 of Register A, set when the field has a wildcard character: a question mark, an asterisk or an exclamation mark.
4EA6
If the NZ FLAG is set (a wildcard), JUMP to 4E83H to make the field the wildmask.
4EA8
BIT 0,(IX+00H) DD CB 00 46
Test bit 0 of the flag byte at Index Register IX+00H, set when the source field is filled.
4EAC
If the Z FLAG is set (no source yet), JUMP to 4E4DH to make the field the source.
4EAE
BIT 1,(IX+00H) DD CB 00 4E
Test bit 1 of the flag byte at Index Register IX+00H, set when the destination field is filled.
4EB2
If the Z FLAG is set (no destination yet), JUMP to 4E68H to make the field the destination.
4EB4
JUMP to 4E83H to make the field the wildmask, which is an error when that is filled too.

4EB6H - Copy the Field

Reached by the RETurn of 4E5DH, 4E78H or 4E93H for a field without a keyword: copies its flag byte and 32 bytes of text from 4300H to the block at Register Pair DE.

4EB6
PUSH HL E5
Save Register Pair HL, the command line pointer, to the top of the stack.
4EB7
LD HL,4300H 21 00 43
Point Register Pair HL to 4300H, the flag byte of the field just taken.
4EBA
LD BC,0021H 01 21 00
Load Register Pair BC with 0021H, the 33 bytes of a block: the flag byte and 32 bytes of text.
4EBD
LDIR ED B0
Copy Register Pair BC bytes from Register Pair HL (4300H) to Register Pair DE, the chosen block.
4EBF
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
4EC0
JUMP back to 4E12H to evaluate the next field of the command line.

4EC3H - The Error Return

4EC3H also drops the return address pushed at 4E38H. EVAL@ returns error 2EH (Invalid parameter) for every error, whatever the routine that found it.

4EC3
POP AF F1
Restore Register Pair AF from the top of the stack: it drops the return address 4E94H or 4EB6H.
4EC4
LD A,2EH 3E 2E
Load Register A with 2EH, the error code of Invalid parameter.
4EC6
OR A B7
OR Register A with itself, to set the NZ FLAG for the error.
4EC7
RET C9
RETurn to the caller of EVAL@ with the NZ FLAG set and Register A = 2EH.

4EC8H - Compare With a Pattern

Register Pair DE = a text, Register Pair BC = a pattern, Register A = the number of bytes. Each byte of the pattern must equal the text's byte, except that a ? matches any byte. Returns the Z FLAG when all match, else the NZ FLAG; the registers other than Register Pair AF are saved (4485H).

4EC8
GOSUB to 4485H, which calls 4ECBH with Register Pairs BC, DE, HL and Index Registers IX and IY saved, and returns to the caller of 4EC8H.
4ECB
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the text to compare.
4ECC
LD D,B 50
Load Register D with Register B, the high byte of the pattern's address.
4ECD
LD E,C 59
Load Register E with Register C: Register Pair DE = the pattern.
4ECE
LD B,A 47
Load Register B with Register A, the number of bytes to compare.
4ECF
LD A,(DE) 1A
Load Register A with the pattern's byte at Register Pair DE.
4ED0
CP 3FH FE 3F
Compare Register A against 3FH, a question mark, which matches any character.
4ED2
If the Z FLAG is set (a ?), JUMP to 4ED6H and skip the compare.
4ED4
CP (HL) BE
Compare Register A against the text's byte at Register Pair HL.
4ED5
RET NZ C0
If the NZ FLAG is set (they differ), RETurn with the NZ FLAG: no match.
4ED6
INC DE 13
INCrement Register Pair DE by 1 to the next byte of the pattern.
4ED7
INC HL 23
INCrement Register Pair HL by 1 to the next byte of the text.
4ED8
DECrement Register B and loop back to 4ECFH while Register B is not zero.
4EDA
RET C9
RETurn with the Z FLAG set: every byte matched.

4EDBH - WILD@

Routine 4, requested by WILD@ (447CH). Register B = 00H: compare the 11 bytes at Register Pair HL, a name and an extension as a directory entry holds them (padded with spaces), with the wildmask at 42B0H; the Z FLAG when they match. Register B not 00H: Register Pair HL points to a file specification NAME/EXT, whose two parts become the wildmask, upper case and padded with spaces (a * fills the rest of its part with ?, a ! the rest of the name and the whole extension); a part not given stays spaces. Setting the mask always returns the Z FLAG. The registers other than Register Pair AF are saved (4485H).

4EDB
GOSUB to 4485H, which calls 4EDEH with Register Pairs BC, DE, HL and Index Registers IX and IY saved, and returns to the caller of WILD@.
4EDE
INC B 04
INCrement Register B by 1; with the DECrement after it, this sets the Z FLAG when Register B is 00H.
4EDF
DEC B 05
DECrement Register B by 1, back to its value: the Z FLAG when Register B is 00H, a compare.
4EE0
If the Z FLAG is set (Register B = 00H), JUMP to 4F0AH to compare with the wildmask.
4EE2
PUSH HL E5
Save Register Pair HL, the file specification of the new wildmask, to the top of the stack.
4EE3
LD HL,42B0H 21 B0 42
Point Register Pair HL to 42B0H, the 11 bytes of the wildmask.
4EE6
PUSH HL E5
Save Register Pair HL (42B0H) to the top of the stack.
4EE7
LD DE,42B1H 11 B1 42
Point Register Pair DE to 42B1H, one byte on, for the fill.
4EEA
LD (HL),20H 36 20
Store 20H, a space, to the first byte of the wildmask at Register Pair HL.
4EEC
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH, the ten other bytes of the wildmask.
4EEF
LDIR ED B0
Copy Register Pair BC bytes from Register Pair HL to Register Pair DE: 42B0H-42BAH are all spaces.
4EF1
POP DE D1
Restore Register Pair DE (42B0H, the name part) from the top of the stack.
4EF2
POP HL E1
Restore Register Pair HL, the file specification, from the top of the stack.
4EF3
LD BC,0803H 01 03 08
Load Register Pair BC with 0803H: Register B = 8, the length of a name, Register C = 3, the extension a ! fills too.
4EF6
GOSUB to 4F14H to copy up to Register B characters of the name from Register Pair HL to Register Pair DE.
4EF9
LD A,(HL) 7E
Load Register A with the character at Register Pair HL that ended the name.
4EFA
INC HL 23
INCrement Register Pair HL by 1 past the character that ended the name.
4EFB
CP 2FH FE 2F
Compare Register A against 2FH, the slash before an extension.
4EFD
If the NZ FLAG is set (no extension), JUMP to 4F08H.
4EFF
LD DE,42B8H 11 B8 42
Point Register Pair DE to 42B8H, the extension part of the wildmask.
4F02
LD BC,0300H 01 00 03
Load Register Pair BC with 0300H: Register B = 3, the length of an extension, Register C = 0, nothing more for a !.
4F05
GOSUB to 4F14H to copy up to Register B characters of the extension from Register Pair HL to Register Pair DE.
4F08
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: the wildmask is set.
4F09
RET C9
RETurn through 4485H, which restores the registers, to the caller of WILD@ with the Z FLAG set.
4F0A
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the name and extension to compare.
4F0B
LD BC,42B0H 01 B0 42
Point Register Pair BC to 42B0H, the wildmask, as the pattern.
4F0E
LD A,0BH 3E 0B
Load Register A with 0BH, the 11 bytes of a name and an extension.
4F10
GOSUB to 4EC8H to compare Register A bytes at Register Pair DE with the wildmask at Register Pair BC.
4F13
RET C9
RETurn through 4485H to the caller of WILD@: the Z FLAG when the name matches the wildmask.

4F14H - Copy a Part of the Wildmask

Copies up to Register B characters from Register Pair HL to Register Pair DE, letters upper case, ending at the first character a file name may not have (5043H). A * fills the rest of the part with ?, a ! fills it and Register C bytes more.

4F14
LD A,(HL) 7E
Load Register A with the character at Register Pair HL, the file specification.
4F15
GOSUB to 5043H, which sets the C FLAG for a letter (made upper case), a digit or one of the ten characters at 5063H.
4F18
RET NC D0
If the NC FLAG is set (the part ends), RETurn.
4F19
LD (DE),A 12
Store Register A, the character, to the wildmask at Register Pair DE.
4F1A
CP 2AH FE 2A
Compare Register A against 2AH, an asterisk, which fills the rest of the part.
4F1C
PUSH BC C5
Save Register Pair BC to the top of the stack; the flags of the compare are kept.
4F1D
LD C,00H 0E 00
Load Register C with 00H, so an asterisk fills only the rest of this part.
4F1F
If the Z FLAG is set (an asterisk), GOSUB to 4F2DH to fill Register B bytes from Register Pair DE with ?.
4F22
POP BC C1
Restore Register Pair BC (Register C = the bytes a ! adds) from the top of the stack.
4F23
CP 21H FE 21
Compare Register A against 21H, an exclamation mark, which also fills the extension.
4F25
If the Z FLAG is set (a !), GOSUB to 4F2DH to fill Register B plus Register C bytes from Register Pair DE with ?.
4F28
INC DE 13
INCrement Register Pair DE by 1 to the next byte of the wildmask.
4F29
INC HL 23
INCrement Register Pair HL by 1 to the next character of the file specification.
4F2A
DECrement Register B and loop back to 4F14H while Register B is not zero.
4F2C
RET C9
RETurn to the caller with the part of the wildmask full.

4F2DH - Fill With Question Marks

Stores Register B plus Register C question marks from Register Pair DE on; every register is saved (4485H and Register Pair AF on the stack).

4F2D
GOSUB to 4485H, which calls 4F30H with Register Pairs BC, DE, HL and Index Registers IX and IY saved, and returns to the caller of 4F2DH.
4F30
PUSH AF F5
Save Register Pair AF, the wildcard character and its flags, to the top of the stack.
4F31
LD A,B 78
Load Register A with Register B, the bytes left in this part of the wildmask.
4F32
ADD A,C 81
ADD Register C to Register A: 3 more for a ! in the name, to fill the extension too.
4F33
LD B,A 47
Load Register B with Register A, the number of bytes to fill.
4F34
LD A,3FH 3E 3F
Load Register A with 3FH, a question mark, which matches any character.
4F36
LD (DE),A 12
Store Register A (?) to the wildmask at Register Pair DE.
4F37
INC DE 13
INCrement Register Pair DE by 1 to the next byte of the wildmask.
4F38
DECrement Register B and loop back to 4F34H while Register B is not zero.
4F3A
POP AF F1
Restore Register Pair AF, the wildcard character and its flags, from the top of the stack.
4F3B
RET C9
RETurn through 4485H to the caller with the registers restored.

4F3CH - Take a Field

Routine 6 (request 66H, made by SYS11/SYS), also called by EVAL@ (4E3CH, 4E94H). Register Pair HL points into the command line, Register Pair DE to a 33 byte block. Skips spaces and commas, then copies one field into the block from +01H, ended by 03H: a file specification NAME/EXT.PASSWORD:DRIVE (any part after the name may be missing) or a device @XX or a drive :D, and sets the flag byte at +00H: bit 6 a name, bit 5 a wildcard in the name or extension, bit 7 a device or drive with the number LOCDEV@ gives in bits 0-3 (bit 3 for a drive). After a name with a wildcard a colon is not taken: the drive is left as the next field. Returns the Z FLAG with Register Pair DE = the block, or the NZ FLAG when the field or one of its parts is empty or the device is not found.

4F3C
PUSH DE D5
Save Register Pair DE, the block's address, to the top of the stack; the flag byte is set through it.
4F3D
XOR A AF
Set Register A to 00H by XORing it with itself, for the flag byte.
4F3E
LD (DE),A 12
Store Register A (00H) to the flag byte at Register Pair DE: nothing found yet.
4F3F
INC DE 13
INCrement Register Pair DE by 1 to +01H, where the field's text goes.
4F40
GOSUB to 502CH to skip spaces and commas; Register A = the first other character.
4F43
LD B,08H 06 08
Load Register B with 08H, the length of a name.
4F45
GOSUB to 4FABH to copy the name (up to Register B characters) from Register Pair HL to Register Pair DE.
4F48
If the NZ FLAG is set (no name), JUMP to 4FA1H, where a device or a drive may follow.
4F4A
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL: Register Pair HL = the block's flag byte.
4F4B
SET 6,(HL) CB F6
Set bit 6 of the flag byte at Register Pair HL: the field has a file name.
4F4D
If the NC FLAG is set (no wildcard in the name), JUMP to 4F51H.
4F4F
SET 5,(HL) CB EE
Set bit 5 of the flag byte at Register Pair HL: the field has a wildcard character.
4F51
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL, the command line pointer again.
4F52
CP 2FH FE 2F
Compare Register A, the character that ended the name, against 2FH, a slash.
4F54
If the NZ FLAG is set (no extension), JUMP to 4F65H.
4F56
LD (DE),A 12
Store Register A (/) to the block at Register Pair DE, over the 03H after the name.
4F57
INC DE 13
INCrement Register Pair DE by 1 past the slash.
4F58
LD B,03H 06 03
Load Register B with 03H, the length of an extension.
4F5A
GOSUB to 4FABH to copy the extension from Register Pair HL to Register Pair DE.
4F5D
If the NZ FLAG is set (an empty extension), JUMP to 4FA9H to return the NZ FLAG.
4F5F
If the NC FLAG is set (no wildcard in the extension), JUMP to 4F65H.
4F61
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL: Register Pair HL = the block's flag byte.
4F62
SET 5,(HL) CB EE
Set bit 5 of the flag byte at Register Pair HL: the extension has a wildcard character.
4F64
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL, the command line pointer again.
4F65
CP 2EH FE 2E
Compare Register A against 2EH, the period before a password.
4F67
If the NZ FLAG is set (no password), JUMP to 4F72H.
4F69
LD (DE),A 12
Store Register A (.) to the block at Register Pair DE, over the 03H.
4F6A
INC DE 13
INCrement Register Pair DE by 1 past the period.
4F6B
LD B,08H 06 08
Load Register B with 08H, the length of a password.
4F6D
GOSUB to 4FABH to copy the password from Register Pair HL to Register Pair DE.
4F70
If the NZ FLAG is set (an empty password), JUMP to 4FA9H to return the NZ FLAG.
4F72
CP 3AH FE 3A
Compare Register A against 3AH, the colon before a drive.
4F74
If the NZ FLAG is set (no drive), JUMP to 4F9BH to end the field.
4F76
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL: Register Pair HL = the block's flag byte.
4F77
BIT 5,(HL) CB 6E
Test bit 5 of the flag byte at Register Pair HL, set when the name or extension has a wildcard.
4F79
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL, the command line pointer; the flags are kept.
4F7A
If the NZ FLAG is set (a wildcard), JUMP to 4F9AH: the drive is left in the command line as the next field.

4F7CH - A Device or a Drive

Register A = the @ or the colon, after a name or (from 4FA1H) at the start of the field. The two character name is copied after it and looked up by LOCDEV@.

4F7C
PUSH DE D5
Save Register Pair DE, where the @ or colon goes in the block, to the top of the stack.
4F7D
LD (DE),A 12
Store Register A (@ or colon) to the block at Register Pair DE.
4F7E
INC DE 13
INCrement Register Pair DE by 1 past the @ or colon.
4F7F
LD B,02H 06 02
Load Register B with 02H, the length of a device or drive name.
4F81
GOSUB to 4FABH to copy the name from Register Pair HL to Register Pair DE.
4F84
POP BC C1
Restore Register Pair BC (the address of the @ or colon in the block) from the top of the stack.
4F85
If the NZ FLAG is set (no name after it), JUMP to 4FA9H to return the NZ FLAG.
4F87
LD A,03H 3E 03
Load Register A with 03H, the byte that ends a field.
4F89
LD (DE),A 12
Store Register A (03H) to the block at Register Pair DE, after the device name.
4F8A
LD D,B 50
Load Register D with Register B, the high byte of the address of the @ or colon.
4F8B
LD E,C 59
Load Register E with Register C: Register Pair DE = the device name with its prefix.
4F8C
GOSUB to 506DH, LOCDEV@, for the number of the device or drive in Register A (bit 3 for a drive).
4F8F
If the NZ FLAG is set (no such device), JUMP to 4FA9H to return the NZ FLAG.
4F91
EX (SP),HL E3
Exchange the word at the top of the Stack Pointer with Register Pair HL: Register Pair HL = the block's flag byte.
4F92
OR 80H F6 80
OR Register A with 80H, bit 7 for a device or drive in the field.
4F94
OR (HL) B6
OR Register A with the flag byte at Register Pair HL, to keep bits 6 and 5 of a name.
4F95
LD (HL),A 77
Store Register A to the flag byte at Register Pair HL: bit 7, the number in bits 0-3 and the name's flags.
4F96
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the block's flag byte.
4F97
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
4F98
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: the field is taken.
4F99
RET C9
RETurn with the Z FLAG set and Register Pair DE = the block.
4F9A
DEC HL 2B
DECrement Register Pair HL by 1, back to the colon, which starts the next field.
4F9B
LD A,03H 3E 03
Load Register A with 03H, the byte that ends a field.
4F9D
LD (DE),A 12
Store Register A (03H) to the block at Register Pair DE, over the character that ended the field.
4F9E
POP DE D1
Restore Register Pair DE, the block's address, from the top of the stack.
4F9F
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: the field is taken.
4FA0
RET C9
RETurn with the Z FLAG set and Register Pair DE = the block.
4FA1
CP 40H FE 40
Compare Register A, the character after the empty name, against 40H, the @ of a device.
4FA3
If the Z FLAG is set (a device), JUMP to 4F7CH.
4FA5
CP 3AH FE 3A
Compare Register A against 3AH, the colon of a drive.
4FA7
If the Z FLAG is set (a drive), JUMP to 4F7CH.
4FA9
POP DE D1
Restore Register Pair DE, the block's address, from the top of the stack; the flags are kept.
4FAA
RET C9
RETurn to the caller with the NZ FLAG set: the field is wrong or empty.

4FABH - Copy One Part of a Field

Copies up to Register B characters (letters made upper case, digits and #$%&+<>?*!) from Register Pair HL to Register Pair DE and puts 03H after them; characters beyond Register B are passed over. The part ends at the end of the line, a left parenthesis or a comma, which stay at Register Pair HL, or at any other character, which is passed. Returns Register A = the character that ended the part, and the NZ FLAG when the part is empty, else the Z FLAG with the C FLAG set when it had a ?, * or !.

4FAB
LD A,B 78
Load Register A with Register B, the length of the part (never 00H).
4FAC
LD (4FE7H),A 32 E7 4F
Store Register A into the operand of the LD A,n at 4FE6H (4FE7H): not 00H while the part is empty.
4FAF
INC B 04
INCrement Register B by 1, as the loop counts down before each store.
4FB0
LD C,00H 0E 00
Load Register C with 00H; bit 0 of Register C is set for a wildcard character.
4FB2
LD A,(HL) 7E
Load Register A with the character at Register Pair HL.
4FB3
GOSUB to 503AH, which sets the C FLAG when Register A is a control character or a semicolon, the end of the line.
4FB6
If the C FLAG is set (the end of the line), JUMP to 4FE2H.
4FB8
CP 28H FE 28
Compare Register A against 28H, a left parenthesis, which starts the parameters.
4FBA
If the Z FLAG is set, JUMP to 4FE2H; the parenthesis stays at Register Pair HL.
4FBC
CP 2CH FE 2C
Compare Register A against 2CH, a comma, which starts the parameters or separates fields.
4FBE
If the Z FLAG is set, JUMP to 4FE2H; the comma stays at Register Pair HL.
4FC0
INC HL 23
INCrement Register Pair HL by 1 to the next character of the command line.
4FC1
GOSUB to 5043H, which sets the C FLAG for a character a file name may have (a letter made upper case).
4FC4
If the NC FLAG is set (any other character), JUMP to 4FE2H: it ends the part and is passed.
4FC6
CP 3FH FE 3F
Compare Register A against 3FH, a question mark, a wildcard character.
4FC8
If the Z FLAG is set, JUMP to 4FD2H to note the wildcard.
4FCA
CP 2AH FE 2A
Compare Register A against 2AH, an asterisk, a wildcard character.
4FCC
If the Z FLAG is set, JUMP to 4FD2H to note the wildcard.
4FCE
CP 21H FE 21
Compare Register A against 21H, an exclamation mark, a wildcard character.
4FD0
If the NZ FLAG is set (not a wildcard), JUMP to 4FD4H.
4FD2
SET 0,C CB C1
Set bit 0 of Register C: the part has a wildcard character.
4FD4
DEC B 05
DECrement Register B by 1, the places left in the part.
4FD5
If the Z FLAG is set (the part is full), JUMP to 4FDFH to pass over the character.
4FD7
LD (DE),A 12
Store Register A, the character, to the block at Register Pair DE.
4FD8
XOR A AF
Set Register A to 00H by XORing it with itself, for the operand at 4FE7H.
4FD9
LD (4FE7H),A 32 E7 4F
Store Register A (00H) into the operand at 4FE7H: the part is not empty.
4FDC
INC DE 13
INCrement Register Pair DE by 1 to the next place in the block.
4FDD
JUMP back to 4FB2H for the next character of the command line.
4FDF
INC B 04
INCrement Register B by 1, back to 1, so further characters are passed over too.
4FE0
JUMP back to 4FB2H for the next character of the command line.
4FE2
LD B,A 47
Load Register B with Register A, the character that ended the part.
4FE3
LD A,03H 3E 03
Load Register A with 03H, the byte that ends a field.
4FE5
LD (DE),A 12
Store Register A (03H) to the block at Register Pair DE, after the part.
4FE6
LD A,00H 3E 00
Load Register A with the operand stored at 4FE7H: 00H when a character was copied, else the part's length.
4FE8
OR A B7
OR Register A with itself: the NZ FLAG when the part is empty, and the NC FLAG.
4FE9
LD A,B 78
Load Register A with Register B, the character that ended the part; the flags are kept.
4FEA
RET NZ C0
If the NZ FLAG is set (an empty part), RETurn with the NZ FLAG.
4FEB
RR C CB 19
Rotate Register C right through the C FLAG: the C FLAG = bit 0, a wildcard; the result 00H sets the Z FLAG.
4FED
RET C9
RETurn with the Z FLAG set and the C FLAG set when the part has a wildcard character.

4FEEH - Find a Parameter Name

Register Pair DE = the name (at 4300H, ended by 03H), Register Pair BC = the parameter block, 9 byte entries (a six character name padded with spaces, the address for the value, the type byte) ended by 00H. A name may be shortened: the first entry whose name starts with the given characters is taken. Returns the Z FLAG with Register Pair DE = the entry's type byte (+08H), or the NZ FLAG and Register A = FFH when no entry matches.

4FEE
PUSH HL E5
Save Register Pair HL, the command line pointer, to the top of the stack.
4FEF
LD H,B 60
Load Register H with Register B, the high byte of the parameter block's address.
4FF0
LD L,C 69
Load Register L with Register C: Register Pair HL = the first entry of the parameter block.
4FF1
LD A,(DE) 1A
Load Register A with the first character of the name at Register Pair DE.
4FF2
GOSUB to 504AH to make Register A upper case if it is a letter.
4FF5
CP (HL) BE
Compare Register A against the first character of the entry's name at Register Pair HL.
4FF6
If the Z FLAG is set (the same), JUMP to 5004H to compare the rest of the name.
4FF8
LD BC,0009H 01 09 00
Load Register Pair BC with 0009H, the length of a parameter entry.
4FFB
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL, to point to the next entry.
4FFC
LD A,(HL) 7E
Load Register A with the first byte of the entry at Register Pair HL.
4FFD
OR A B7
OR Register A with itself: the Z FLAG for the 00H that ends the parameter block.
4FFE
If the NZ FLAG is set (another entry), JUMP back to 4FF1H.
5000
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
5001
OR FFH F6 FF
OR Register A with FFH: Register A = FFH and the NZ FLAG, no such parameter.
5003
RET C9
RETurn to the caller with the NZ FLAG set and Register A = FFH.
5004
PUSH HL E5
Save Register Pair HL, the entry, to the top of the stack.
5005
PUSH DE D5
Save Register Pair DE, the name, to the top of the stack.
5006
LD B,05H 06 05
Load Register B with 05H, the five characters after the first.
5008
INC DE 13
INCrement Register Pair DE by 1 to the next character of the name.
5009
INC HL 23
INCrement Register Pair HL by 1 to the next character of the entry's name.
500A
LD A,(DE) 1A
Load Register A with the character of the name at Register Pair DE.
500B
GOSUB to 503AH, which sets the C FLAG for a control character (the 03H after the name) or a semicolon.
500E
If the C FLAG is set (the name ends), JUMP to 5018H: the entry matches.
5010
GOSUB to 504AH to make Register A upper case if it is a letter.
5013
CP (HL) BE
Compare Register A against the character of the entry's name at Register Pair HL.
5014
If the NZ FLAG is set (they differ), JUMP to 5022H.
5016
DECrement Register B and loop back to 5008H while Register B is not zero.
5018
POP DE D1
Restore Register Pair DE, the name, from the top of the stack.
5019
POP BC C1
Restore Register Pair BC, the matching entry, from the top of the stack.
501A
LD HL,0008H 21 08 00
Load Register Pair HL with 0008H, the offset of the type byte in an entry.
501D
ADD HL,BC 09
ADD Register Pair BC (the entry) to Register Pair HL: Register Pair HL = the entry's type byte.
501E
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair DE = the type byte.
501F
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
5020
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: the parameter is found.
5021
RET C9
RETurn to the caller with the Z FLAG set and Register Pair DE = the entry's type byte.
5022
GOSUB to 5043H, which sets the C FLAG when Register A, the name's character, is one a name may have.
5025
If the NC FLAG is set (it is not), JUMP to 5018H: the name has ended and the entry matches.
5027
POP DE D1
Restore Register Pair DE, the name, from the top of the stack.
5028
POP HL E1
Restore Register Pair HL, the entry, from the top of the stack.
5029
JUMP to 4FF8H to try the next entry of the parameter block.

502BH - Skip Spaces and Commas

502CH returns Register A = the first character at Register Pair HL that is not a space or a comma, with Register Pair HL at it; the C FLAG when it ends the line.

502B
INC HL 23
INCrement Register Pair HL by 1 past a space or a comma.
502C
LD A,(HL) 7E
Load Register A with the character at Register Pair HL, the command line.
502D
GOSUB to 503AH, which sets the C FLAG when Register A is a control character or a semicolon, the end of the line.
5030
RET C D8
If the C FLAG is set (the end of the line), RETurn with the C FLAG.
5031
CP 2CH FE 2C
Compare Register A against 2CH, a comma, which is skipped.
5033
If the Z FLAG is set (a comma), JUMP back to 502BH to skip it.
5035
CP 20H FE 20
Compare Register A against 20H, a space, which is skipped.
5037
If the Z FLAG is set (a space), JUMP back to 502BH to skip it.
5039
RET C9
RETurn with the NC FLAG and Register A = the first character of the field.

503AH - The End of the Line

Sets the C FLAG when Register A is below 20H (03H, 0DH or another control character) or is 3BH, a semicolon; else the NC FLAG.

503A
CP 20H FE 20
Compare Register A against 20H, a space: the C FLAG for a control character.
503C
RET C D8
If the C FLAG is set (a control character), RETurn with the C FLAG.
503D
CP 3BH FE 3B
Compare Register A against 3BH, a semicolon, which also ends the line.
503F
SCF 37
Set the C FLAG; the Z FLAG of the compare is kept.
5040
RET Z C8
If the Z FLAG is set (a semicolon), RETurn with the C FLAG.
5041
CCF 3F
Complement the C FLAG to the NC FLAG: Register A does not end the line.
5042
RET C9
RETurn to the caller with the NC FLAG: not the end of the line.

5043H - A File Name Character

Sets the C FLAG when Register A is a digit, a letter (returned upper case: 504AH ANDs it with 5FH) or one of #$%&+<>?*! (5053H); else the NC FLAG. 504AH is the entry that only makes a letter upper case (other characters below 41H are tested against the list too).

5043
CP 30H FE 30
Compare Register A against 30H, the digit 0, the lowest digit.
5045
If the C FLAG is set (below 0), JUMP to 5053H to look for Register A in the list of characters.
5047
CP 3AH FE 3A
Compare Register A against 3AH, one above the digit 9.
5049
RET C D8
If the C FLAG is set (a digit), RETurn with the C FLAG.
504A
CP 41H FE 41
Compare Register A against 41H, the letter A.
504C
If the C FLAG is set (below A), JUMP to 5053H to look for Register A in the list of characters.
504E
AND 5FH E6 5F
AND Register A with 5FH, to make a lower case letter upper case.
5050
CP 5BH FE 5B
Compare Register A against 5BH, one above the letter Z: the C FLAG for a letter.
5052
RET C9
RETurn with the C FLAG for a letter and Register A upper case.
5053
PUSH BC C5
Save Register Pair BC to the top of the stack, for the search counter.
5054
PUSH HL E5
Save Register Pair HL to the top of the stack, for the search pointer.
5055
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH, the ten characters of the list.
5058
LD HL,5063H 21 63 50
Point Register Pair HL to 5063H, the list of the ten characters besides letters and digits.
505B
CPIR ED B1
Compare Register A with the bytes at Register Pair HL, counting Register Pair BC down, until one matches (the Z FLAG) or the list ends.
505D
POP HL E1
Restore Register Pair HL from the top of the stack; the flags are kept.
505E
POP BC C1
Restore Register Pair BC from the top of the stack; the flags are kept.
505F
SCF 37
Set the C FLAG; the Z FLAG of the search is kept.
5060
RET Z C8
If the Z FLAG is set (in the list), RETurn with the C FLAG.
5061
CCF 3F
Complement the C FLAG to the NC FLAG: not a file name character.
5062
RET C9
RETurn to the caller with the NC FLAG: not a file name character.
5063-506C
DEFM "#$%&+<>?*!" 23 24 25 26 2B 3C 3E 3F 2A 21
The ten characters besides letters and digits that a file name, extension or password may have (5058H); the question mark, the asterisk and the exclamation mark are the wildcard characters (4FC6H-4FCEH).

506DH - LOCDEV@

Routine 5, requested by LOCDEV@ (447FH), and called by 4F8CH. Register Pair DE points to a two character device name after a prefix: after a colon it is a drive, looked up by the names in DCTTBL (44E8H), else a device, looked up in the DCB table (44A6H); the prefix itself (@) is not checked, and the names are compared as they are, without making them upper case. A one character name matches a table name whose second character is a space. Returns the Z FLAG with Register A = the device number (0-5) or 08H plus the drive number (0-7), or the NZ FLAG with Register A = 29H (Device not available). The registers other than Register Pair AF are saved (4485H).

506D
GOSUB to 4485H, which calls 5070H with Register Pairs BC, DE, HL and Index Registers IX and IY saved, and returns to the caller of LOCDEV@.
5070
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the prefix of the device name.
5071
LD A,(HL) 7E
Load Register A with the prefix at Register Pair HL, a colon or the @ of a device.
5072
INC HL 23
INCrement Register Pair HL by 1 to the first character of the name.
5073
CP 3AH FE 3A
Compare Register A against 3AH, the colon of a drive.
5075
If the NZ FLAG is set (not a drive), JUMP to 50A7H to look for a device.
5077
LD IX,44E8H DD 21 E8 44
Point Index Register IX to 44E8H, DCTTBL: eight 4 byte entries, each the address of a drive control table and the drive's two character name.
507B
LD DE,0004H 11 04 00
Load Register Pair DE with 0004H, the length of a DCTTBL entry.
507E
LD B,08H 06 08
Load Register B with 08H, the eight drives of DCTTBL.
5080
LD A,(IX+02H) DD 7E 02
Load Register A with the first character of the drive's name from Index Register IX+02H.
5083
CP (HL) BE
Compare Register A against the first character of the name at Register Pair HL.
5084
If the NZ FLAG is set (they differ), JUMP to 509AH for the next drive.
5086
INC HL 23
INCrement Register Pair HL by 1 to the second character of the name.
5087
LD A,(HL) 7E
Load Register A with the second character of the name at Register Pair HL.
5088
CP (IX+03H) DD BE 03
Compare Register A against the second character of the drive's name at Index Register IX+03H.
508B
DEC HL 2B
DECrement Register Pair HL by 1, back to the first character of the name; the flags are kept.
508C
If the Z FLAG is set (both characters match), JUMP to 50A2H: the drive is found.
508E
GOSUB to 5043H, which sets the C FLAG when Register A, the name's second character, is one a name may have.
5091
If the C FLAG is set (a second character that differs), JUMP to 509AH for the next drive.
5093
LD A,(IX+03H) DD 7E 03
Load Register A with the second character of the drive's name from Index Register IX+03H.
5096
CP 20H FE 20
Compare Register A against 20H, a space: a one character name matches a drive name with a space after it.
5098
If the Z FLAG is set (a space), JUMP to 50A2H: the drive is found.
509A
ADD IX,DE DD 19
ADD Register Pair DE (the entry length) to Index Register IX, to point to the next DCTTBL entry.
509C
DECrement Register B and loop back to 5080H while Register B is not zero.
509E
LD A,29H 3E 29
Load Register A with 29H, the error code of Device not available.
50A0
OR A B7
OR Register A with itself, to set the NZ FLAG for the error.
50A1
RET C9
RETurn through 4485H to the caller of LOCDEV@ with the NZ FLAG set and Register A = 29H.
50A2
LD A,10H 3E 10
Load Register A with 10H, from which the count of drives left is taken.
50A4
SUB B 90
SUBtract Register B (8 for drive 0, down to 1 for drive 7) from Register A: Register A = 08H plus the drive number.
50A5
CP A BF
Compare Register A against itself, to set the Z FLAG: the drive is found.
50A6
RET C9
RETurn through 4485H to the caller of LOCDEV@ with the Z FLAG set and Register A = the drive's number with bit 3 set.
50A7
LD IX,44A6H DD 21 A6 44
Point Index Register IX to 44A6H, the DCB table: six 11 byte entries, the device's two character name at +09H.
50AB
LD DE,000BH 11 0B 00
Load Register Pair DE with 000BH, the length of a DCB table entry.
50AE
LD B,06H 06 06
Load Register B with 06H, the six devices of the DCB table.
50B0
LD A,(IX+09H) DD 7E 09
Load Register A with the first character of the device's name from Index Register IX+09H.
50B3
CP (HL) BE
Compare Register A against the first character of the name at Register Pair HL.
50B4
If the NZ FLAG is set (they differ), JUMP to 50CAH for the next device.
50B6
INC HL 23
INCrement Register Pair HL by 1 to the second character of the name.
50B7
LD A,(HL) 7E
Load Register A with the second character of the name at Register Pair HL.
50B8
DEC HL 2B
DECrement Register Pair HL by 1, back to the first character of the name.
50B9
CP (IX+0AH) DD BE 0A
Compare Register A against the second character of the device's name at Index Register IX+0AH.
50BC
If the Z FLAG is set (both characters match), JUMP to 50D2H: the device is found.
50BE
GOSUB to 5043H, which sets the C FLAG when Register A, the name's second character, is one a name may have.
50C1
If the C FLAG is set (a second character that differs), JUMP to 50CAH for the next device.
50C3
LD A,(IX+0AH) DD 7E 0A
Load Register A with the second character of the device's name from Index Register IX+0AH.
50C6
CP 20H FE 20
Compare Register A against 20H, a space: a one character name matches a device name with a space after it.
50C8
If the Z FLAG is set (a space), JUMP to 50D2H: the device is found.
50CA
ADD IX,DE DD 19
ADD Register Pair DE (the entry length) to Index Register IX, to point to the next DCB table entry.
50CC
DECrement Register B and loop back to 50B0H while Register B is not zero.
50CE
LD A,29H 3E 29
Load Register A with 29H, the error code of Device not available.
50D0
OR A B7
OR Register A with itself, to set the NZ FLAG for the error.
50D1
RET C9
RETurn through 4485H to the caller of LOCDEV@ with the NZ FLAG set and Register A = 29H.
50D2
LD A,06H 3E 06
Load Register A with 06H, from which the count of devices left is taken.
50D4
SUB B 90
SUBtract Register B (6 for device 0, down to 1 for device 5) from Register A: Register A = the device number, 0-5.
50D5
CP A BF
Compare Register A against itself, to set the Z FLAG: the device is found.
50D6
RET C9
RETurn through 4485H to the caller of LOCDEV@ with the Z FLAG set and Register A = the device number.

50D7H - The Parameters

Routine 7 (request 67H, which no file of the diskette makes), reached by the JUMP at 4E2BH with Register Pair HL at the comma or left parenthesis and Register Pair DE = the parameter block: 9 byte entries (a six character name, the address for the value, the type byte: bit 7 a string, bit 6 a number, bit 5 a logical value), ended by 00H. A parameter is NAME or NAME=value; the values are Y, YES or ON (FFFFH), N, NO or OFF (0000H), a number (hexadecimal when it ends in H, else decimal), or a string in double or single quotation marks, whose address is stored. A name alone stores FFFFH and needs bit 5. Parameters are separated by commas and end at the end of the line or a right parenthesis. Returns the Z FLAG, or the NZ FLAG with Register A = 2EH (Invalid parameter) for an unknown name, a value of a type the entry does not allow, or anything else after a parameter.

50D7
PUSH DE D5
Save Register Pair DE, the parameter block, to the top of the stack.
50D8
LD B,06H 06 06
Load Register B with 06H, the length of a parameter name.
50DA
LD DE,4300H 11 00 43
Point Register Pair DE to 4300H, SYS0/SYS's system buffer, for the parameter name.
50DD
INC HL 23
INCrement Register Pair HL by 1 past the comma or the left parenthesis.
50DE
GOSUB to 4FABH to copy the parameter name from Register Pair HL to Register Pair DE (4300H), with 03H after it.
50E1
POP DE D1
Restore Register Pair DE, the parameter block, from the top of the stack; the flags are kept.
50E2
If the NZ FLAG is set (no name), JUMP to 50FAH to return error 2EH.
50E4
GOSUB to 503AH, which sets the C FLAG when Register A, the character after the name, ends the line.
50E7
If the C FLAG is set (the end of the line), JUMP to 50EEH; Register Pair HL is at that character.
50E9
CP 2CH FE 2C
Compare Register A against 2CH, a comma, which 4FABH also leaves at Register Pair HL.
50EB
If the Z FLAG is set (a comma), JUMP to 50EEH.
50ED
DEC HL 2B
DECrement Register Pair HL by 1, back to the character 4FABH passed (an equal sign or a right parenthesis).
50EE
PUSH DE D5
Save Register Pair DE, the parameter block, to the top of the stack.
50EF
LD B,D 42
Load Register B with Register D, the high byte of the parameter block's address.
50F0
LD C,E 4B
Load Register C with Register E: Register Pair BC = the parameter block.
50F1
LD DE,4300H 11 00 43
Point Register Pair DE to 4300H, the parameter name just copied.
50F4
GOSUB to 4FEEH to find the name in the parameter block; Register Pair DE = the entry's type byte.
50F7
If the Z FLAG is set (the parameter is found), JUMP to 50FEH.
50F9
POP DE D1
Restore Register Pair DE, the parameter block, from the top of the stack.
50FA
LD A,2EH 3E 2E
Load Register A with 2EH, the error code of Invalid parameter.
50FC
OR A B7
OR Register A with itself, to set the NZ FLAG for the error.
50FD
RET C9
RETurn to the caller of EVAL@ with the NZ FLAG set and Register A = 2EH.
50FE
LD A,(HL) 7E
Load Register A with the character after the name at Register Pair HL.
50FF
CP 3DH FE 3D
Compare Register A against 3DH, an equal sign before a value.
5101
If the Z FLAG is set (a value follows), JUMP to 5128H.
5103
LD BC,FFFFH 01 FF FF
Load Register Pair BC with FFFFH, the value TRUE of a parameter given by its name alone.
5106
LD A,(DE) 1A
Load Register A with the entry's type byte at Register Pair DE.
5107
BIT 5,A CB 6F
Test bit 5 of Register A, set when the parameter may have a logical value.
5109
If the Z FLAG is set (not allowed), JUMP to 50F9H to return error 2EH.

510BH - Store the Value

Register Pair BC = the value or a string's address, Register Pair DE = the entry's type byte, after the word with the address for the value. Then a comma starts the next parameter; the end of the line or a right parenthesis ends EVAL@.

510B
PUSH HL E5
Save Register Pair HL, the command line pointer, to the top of the stack.
510C
EX DE,HL EB
Exchange Register Pairs DE and HL: Register Pair HL = the entry's type byte.
510D
DEC HL 2B
DECrement Register Pair HL by 1 to the high byte of the address for the value (+07H).
510E
LD A,(HL) 7E
Load Register A with the high byte of the address at Register Pair HL.
510F
DEC HL 2B
DECrement Register Pair HL by 1 to the low byte of the address (+06H).
5110
LD L,(HL) 6E
Load Register L with the low byte of the address at Register Pair HL.
5111
LD H,A 67
Load Register H with Register A: Register Pair HL = the address for the value.
5112
LD (HL),C 71
Store Register C, the low byte of the value, to the memory at Register Pair HL.
5113
INC HL 23
INCrement Register Pair HL by 1 to the high byte of the value's place.
5114
LD (HL),B 70
Store Register B, the high byte of the value, to the memory at Register Pair HL.
5115
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
5116
POP DE D1
Restore Register Pair DE, the parameter block, from the top of the stack.
5117
LD A,(HL) 7E
Load Register A with the character at Register Pair HL, after the parameter.
5118
CP 2CH FE 2C
Compare Register A against 2CH, a comma before another parameter.
511A
If the Z FLAG is set (a comma), JUMP back to 50D7H for the next parameter.
511C
GOSUB to 503AH, which sets the C FLAG when Register A ends the line.
511F
If the C FLAG is set (the end of the line), JUMP to 5126H.
5121
CP 29H FE 29
Compare Register A against 29H, a right parenthesis, which ends the parameters.
5123
If the NZ FLAG is set (anything else), JUMP to 50FAH to return error 2EH.
5125
INC HL 23
INCrement Register Pair HL by 1 past the right parenthesis.
5126
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: the parameters are done.
5127
RET C9
RETurn to the caller of EVAL@ with the Z FLAG set: nothing after the parameters is evaluated.

5128H - A Value

After the equal sign: a logical value, a string in quotation marks or a number, each allowed only when its bit of the type byte is set.

5128
INC HL 23
INCrement Register Pair HL by 1 past the equal sign.
5129
PUSH HL E5
Save Register Pair HL, the start of the value, to the top of the stack.
512A
GOSUB to 5164H to read Y, YES, ON, N, NO or OFF into Register Pair BC (FFFFH or 0000H).
512D
If the NZ FLAG is set (not a logical value), JUMP to 5132H.
512F
POP AF F1
Restore Register Pair AF from the top of the stack: it drops the start of the value.
5130
JUMP to 5106H to check that the parameter takes a logical value and store it.
5132
POP HL E1
Restore Register Pair HL, the start of the value, from the top of the stack.
5133
LD A,(HL) 7E
Load Register A with the first character of the value at Register Pair HL.
5134
CP 22H FE 22
Compare Register A against 22H, a double quotation mark, which starts a string.
5136
If the Z FLAG is set (a string), JUMP to 513CH.
5138
CP 27H FE 27
Compare Register A against 27H, a single quotation mark, which starts a string.
513A
If the NZ FLAG is set (no string), JUMP to 5150H for a number.
513C
LD B,A 47
Load Register B with Register A, the quotation mark that ends the string.
513D
LD A,(DE) 1A
Load Register A with the entry's type byte at Register Pair DE.
513E
BIT 7,A CB 7F
Test bit 7 of Register A, set when the parameter may have a string value.
5140
If the Z FLAG is set (not allowed), JUMP to 50F9H to return error 2EH.
5142
INC HL 23
INCrement Register Pair HL by 1 past the quotation mark.
5143
PUSH HL E5
Save Register Pair HL, the start of the string, to the top of the stack.
5144
LD A,(HL) 7E
Load Register A with the character of the string at Register Pair HL.
5145
CP 20H FE 20
Compare Register A against 20H, a space: the C FLAG for a control character.
5147
If the C FLAG is set (the line ends before the closing mark), JUMP to 514DH.
5149
INC HL 23
INCrement Register Pair HL by 1 to the next character of the string.
514A
CP B B8
Compare Register A against Register B, the quotation mark that ends the string.
514B
If the NZ FLAG is set (not the end), JUMP back to 5144H.
514D
POP BC C1
Restore Register Pair BC, the start of the string, from the top of the stack: the value stored is its address.
514E
JUMP to 510BH to store the string's address in Register Pair BC.
5150
LD A,(DE) 1A
Load Register A with the entry's type byte at Register Pair DE.
5151
BIT 6,A CB 77
Test bit 6 of Register A, set when the parameter may have a numeric value.
5153
If the Z FLAG is set (not allowed), JUMP to 50F9H to return error 2EH.
5155
PUSH HL E5
Save Register Pair HL, the start of the number, to the top of the stack.
5156
GOSUB to 51A9H to read a hexadecimal number ending in H into Register Pair BC.
5159
If the NZ FLAG is set (no H at its end), JUMP to 515EH to read it as decimal.
515B
POP AF F1
Restore Register Pair AF from the top of the stack: it drops the start of the number.
515C
JUMP to 510BH to store the value in Register Pair BC.
515E
POP HL E1
Restore Register Pair HL, the start of the number, from the top of the stack.
515F
GOSUB to 518EH to read a decimal number into Register Pair BC.
5162
JUMP to 510BH to store the value in Register Pair BC.

5164H - A Logical Value

Reads a word starting with Y, N, ON or OF at Register Pair HL: Register Pair BC = FFFFH for Y and ON, 0000H for N and OF, then the rest of the word is skipped and the Z FLAG returned. Anything else returns the NZ FLAG.

5164
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the value FALSE.
5167
LD A,(HL) 7E
Load Register A with the character at Register Pair HL, the first of the value.
5168
GOSUB to 504AH to make Register A upper case if it is a letter.
516B
CP 59H FE 59
Compare Register A against 59H, the letter Y of Y or YES.
516D
If the Z FLAG is set (a Y), JUMP to 5182H for the value TRUE.
516F
CP 4EH FE 4E
Compare Register A against 4EH, the letter N of N or NO.
5171
If the Z FLAG is set (an N), JUMP to 5185H for the value FALSE.
5173
CP 4FH FE 4F
Compare Register A against 4FH, the letter O of ON or OFF.
5175
RET NZ C0
If the NZ FLAG is set (no logical value), RETurn with the NZ FLAG.
5176
INC HL 23
INCrement Register Pair HL by 1 to the second letter of the value.
5177
LD A,(HL) 7E
Load Register A with the second character at Register Pair HL.
5178
GOSUB to 504AH to make Register A upper case if it is a letter.
517B
CP 46H FE 46
Compare Register A against 46H, the letter F of OFF.
517D
If the Z FLAG is set (OF), JUMP to 5185H for the value FALSE.
517F
CP 4EH FE 4E
Compare Register A against 4EH, the letter N of ON.
5181
RET NZ C0
If the NZ FLAG is set (neither), RETurn with the NZ FLAG.
5182
LD BC,FFFFH 01 FF FF
Load Register Pair BC with FFFFH, the value TRUE.
5185
INC HL 23
INCrement Register Pair HL by 1 to the next character of the word.
5186
LD A,(HL) 7E
Load Register A with the character at Register Pair HL.
5187
GOSUB to 5043H, which sets the C FLAG for a character a name may have.
518A
If the C FLAG is set, JUMP back to 5185H to skip the rest of the word.
518C
XOR A AF
Set Register A to 00H by XORing it with itself, and set the Z FLAG: a logical value.
518D
RET C9
RETurn with the Z FLAG set and the value in Register Pair BC.

518EH - A Decimal Number

Reads the digits at Register Pair HL into Register Pair BC (the number times 10 plus each digit, without an overflow test), stopping at the first other character.

518E
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the number so far.
5191
LD A,(HL) 7E
Load Register A with the character at Register Pair HL.
5192
SUB 30H D6 30
SUBtract 30H from Register A, the value of a digit.
5194
RET C D8
If the C FLAG is set (below 0), RETurn with the number in Register Pair BC.
5195
CP 0AH FE 0A
Compare Register A against 0AH: the C FLAG for a digit.
5197
RET NC D0
If the NC FLAG is set (not a digit), RETurn with the number in Register Pair BC.
5198
PUSH HL E5
Save Register Pair HL, the command line pointer, to the top of the stack.
5199
LD H,B 60
Load Register H with Register B, the high byte of the number so far.
519A
LD L,C 69
Load Register L with Register C: Register Pair HL = the number so far.
519B
ADD HL,HL 29
ADD Register Pair HL to itself: Register Pair HL = twice the number.
519C
ADD HL,HL 29
ADD Register Pair HL to itself: Register Pair HL = four times the number.
519D
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: Register Pair HL = five times the number.
519E
ADD HL,HL 29
ADD Register Pair HL to itself: Register Pair HL = ten times the number.
519F
LD B,00H 06 00
Load Register B with 00H, the high byte of the digit.
51A1
LD C,A 4F
Load Register C with Register A, the digit: Register Pair BC = the digit.
51A2
ADD HL,BC 09
ADD Register Pair BC to Register Pair HL: the number times ten plus the digit.
51A3
LD B,H 44
Load Register B with Register H, the high byte of the new number.
51A4
LD C,L 4D
Load Register C with Register L: Register Pair BC = the new number.
51A5
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
51A6
INC HL 23
INCrement Register Pair HL by 1 to the next character.
51A7
JUMP back to 5191H for the next digit of the decimal number.

51A9H - A Hexadecimal Number

Reads the hexadecimal digits at Register Pair HL into Register Pair BC; returns the Z FLAG only when an H follows them (Register Pair HL past the H), else the NZ FLAG.

51A9
LD BC,0000H 01 00 00
Load Register Pair BC with 0000H, the number so far.
51AC
LD A,(HL) 7E
Load Register A with the character at Register Pair HL.
51AD
GOSUB to 504AH to make Register A upper case if it is a letter.
51B0
SUB 30H D6 30
SUBtract 30H from Register A, the value of a digit 0-9.
51B2
RET C D8
If the C FLAG is set (below 0), RETurn with the NZ FLAG: no H.
51B3
CP 0AH FE 0A
Compare Register A against 0AH: the C FLAG for a digit 0-9.
51B5
If the C FLAG is set (a digit), JUMP to 51C9H to add it to the number.
51B7
SUB 07H D6 07
SUBtract 07H from Register A, so the letters A-F become 0AH-0FH.
51B9
CP 0AH FE 0A
Compare Register A against 0AH: the C FLAG for 3AH-40H.
51BB
RET C D8
If the C FLAG is set (3AH-40H), RETurn with the NZ FLAG: no H.
51BC
CP 10H FE 10
Compare Register A against 10H: the C FLAG for A-F.
51BE
If the C FLAG is set (A-F), JUMP to 51C9H to add it to the number.
51C0
LD A,(HL) 7E
Load Register A with the character at Register Pair HL again, the one after the digits.
51C1
GOSUB to 504AH to make Register A upper case if it is a letter.
51C4
CP 48H FE 48
Compare Register A against 48H, the letter H that ends a hexadecimal number.
51C6
RET NZ C0
If the NZ FLAG is set (no H), RETurn with the NZ FLAG.
51C7
INC HL 23
INCrement Register Pair HL by 1 past the H that ends the number.
51C8
RET C9
RETurn with the Z FLAG set and the number in Register Pair BC.
51C9
PUSH HL E5
Save Register Pair HL, the command line pointer, to the top of the stack.
51CA
LD H,B 60
Load Register H with Register B, the high byte of the number so far.
51CB
LD L,C 69
Load Register L with Register C: Register Pair HL = the number so far.
51CC
ADD HL,HL 29
ADD Register Pair HL to itself: Register Pair HL = twice the number.
51CD
ADD HL,HL 29
ADD Register Pair HL to itself: Register Pair HL = four times the number.
51CE
ADD HL,HL 29
ADD Register Pair HL to itself: Register Pair HL = eight times the number.
51CF
ADD HL,HL 29
ADD Register Pair HL to itself: Register Pair HL = sixteen times the number.
51D0
LD B,H 44
Load Register B with Register H, the high byte of the new number.
51D1
ADD A,L 85
ADD Register L (its low four bits are 0) to Register A, the digit.
51D2
LD C,A 4F
Load Register C with Register A: Register Pair BC = the number times 16 plus the digit.
51D3
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
51D4
INC HL 23
INCrement Register Pair HL by 1 to the next character.
51D5
JUMP back to 51ACH for the next digit of the hexadecimal number.

51D7H - The Keywords

Data: the three words that name the next field, each followed by the 03H that ends a field, so that only a field that is the whole word matches (4E43H, 4E5EH, 4E79H).

51D7-51DB
DEFM "FROM" / DEFB 03H 46 52 4F 4D 03
FROM and 03H: the next field is the source (4E43H-4E48H).
51DC-51DE
DEFM "TO" / DEFB 03H 54 4F 03
TO and 03H: the next field is the destination (4E5EH-4E63H).
51DF-51E4
DEFM "USING" / DEFB 03H 55 53 49 4E 47 03
USING and 03H: the next field is the wildmask (4E79H-4E7EH).