DOSPLUS 3.5 for the Model III - PATCH/CMD Disassembled

Page Customization

Introduction/Summary

DOSPLUS 3.5 PATCH/CMD Disassembly - Patching Load Modules (Model III)

PATCH/CMD changes a program file in load module form, run from the DOS command level as PATCH filespec1 filespec2 (the patch lines from a patch file), PATCH filespec1 (the lines from the keyboard) or PATCH filespec1 patname (KILL) (a patch taken out again); its heading reads PATCH - DOSPLUS Patch Utility - 3.50. It is a load module of 6 blocks, 1236 bytes, at 5200H-56C9H and 59D1H-59DAH, with the transfer address 5200H, after the two comment records (the name PATCH and the copyright notice). PATCH/CMD is on the Model III master only.

PATCH never changes a byte of the program's own records. Each patch line A=address,F=find,C=change becomes a type 01H load record of the new bytes at the address; the records of one run are written in front of the transfer record, behind a type 07H record that holds the patch's 8 character name, and a new transfer record follows. When the program loads, the new bytes come last and lie over the old ones. To take a patch out, KILL drops its 07H record and the 01H records after it, and the program loads as before. The second block of the file, at 59D1H, is the 07H record itself with the name used for keyboard patches; the records of the patch are built on from 59DBH.

The Parts of PATCH/CMD

AddressContents
5200H-527BHThe heading, EVAL@, the module opened, KILL, the patch file and the patch's name (5200H, 521DH).
527CH-52EEHEach patch line: the address found, the F string tested, the record added (527CH).
52EFH-5341HThe patch written before the transfer record (52EFH).
5342H-53D7HKILL: the patch removed (5342H).
53D8H-5493HA patch record found, a byte compared, read or written, the next byte of the load module (53D8H, 5414H, 5428H).
5494H-55DFHThe patch line, its letters, strings and numbers, the errors (5494H, 54FBH, 5511H, 555EH, 55CDH).
55E0H-56C9H, 59D1H-59DAHThe texts, the parameters, the variables and the name record (55E0H).

How PATCH Works

The module (the first field, which must be a file name) is opened with records of one byte, so that BKSP@ can step back over single bytes (521DH). With a second field the patch file is opened, and its name up to a slash, a period or a colon becomes the patch's name; without one the lines are typed after an asterisk, BREAK ending them, and the name stays NONAME between two asterisks (5494H). A line from the file may be 64 bytes, a typed one 63 characters; a line starting with a period is a comment.

In a line, A=, F= and C= may stand in any order: each is found by scanning the whole line for the letter directly followed by the equal sign (54FBH). The address is a number whose last letter picks the base, B, O, H, or decimal for D or none (555EH); F and C are strings in single or double quotation marks, or pairs of hexadecimal digits with spaces allowed between pairs (5511H). For each line the module is read from its start, byte by byte with the load address of each (5428H), until the byte that loads at the address: none, and Address not found ends PATCH; then the bytes from there must equal F (an empty F tests nothing), else String not found. Either message ends PATCH by ABORT@ before anything is written, so the patch is installed whole or not at all. The new record is added in memory (52C9H).

After the last line the module is read to its transfer record, set back onto its four bytes, and the name record, the new records and the transfer record are written there; CLOSE@, Patch(es) installed (52EFH). With KILL the second field names the patch (5342H): its 07H record is looked for up to the transfer record (53D8H), Patch not found otherwise. A second file control block reads on from after the name record while the first, set back ten bytes onto it, writes: the 01H records that follow are dropped, and everything from the next record on is copied down; CLOSE@, Patch removed.

Differences from the Manual

The manual gives KILL alone; the parameter table has five names for the same switch, PULL, REMOVE, KILL, OUT and YANK. It does not say that a patch run with no patch line is the error Terminated, that a line longer than 64 bytes is Invalid data provided, that an odd last hexadecimal digit is dropped, that the F test follows the bytes as the module loads them without looking at where a new record starts, or that KILL removes the first patch of the name, taking all the 01H records up to the next other record with it. The manual's own example line C =760000, with a space before the equal sign, is refused as Invalid parameter, and its address 7E3D, with no H, is the decimal 7.

A C string that is empty (C=) makes a count of 0000H for the LDIR that copies the new bytes into the record (52E6H), and LDIR with a count of 0000H copies 65536 bytes, over the whole of memory. The patch is built upwards from 59DBH with no test of its size.

Variables

PATCH/CMD Variables

Address
Size
Contents
5233H-5234H
2 bytes
KILL
The value of KILL and its other names, the operand of LD DE (5232H).
56C3H-56C6H
4 bytes
Transfer record
Written after the patch (532AH).
56C7H-56C8H
2 bytes
Patch end
The end of the patch built so far (52C9H).
56C9H-56CCH
4 bytes
Reader
The flags, the bytes left and the address of the load module's reader (5428H).
56CDH-570CH
64 bytes
Line
The patch line (54A2H).
570DH-570EH
2 bytes
Address
A= (54DBH).
570FH-574EH
64 bytes
F string
Its length and bytes (54E6H).
574FH-578EH
64 bytes
C string
Its length and bytes (54F3H).
578FH-57AFH
33 bytes
Source block
The module's file control block from 5790H (521DH).
57B0H-57D0H
33 bytes
Destination block
The patch file, the patch name or KILL's second file control block (5241H, 537DH).
57D1H-58D0H
256 bytes
Module buffer
(5227H).
58D1H-59D0H
256 bytes
Second buffer
The patch file's, or KILL's reader's (5271H, 5388H).
59D1H-59DAH
10 bytes
Name record
The 07H record of the patch's name (524BH).
59DBH
upwards
Patch
The 01H records of the patch (52EFH).

Outside Routines

AddressContents
4467HSYS0/SYS: DSPLY@ (5204H).
4479HSYS0/SYS: EVAL@ (5210H).
4424HSYS0/SYS: OPEN@ (522CH, 5276H).
443FHSYS0/SYS: REW@ (5285H).
4445HSYS0/SYS: BKSP@ (5310H, 539CH).
4428HSYS0/SYS: CLOSE@ (5336H).
4409HSYS0/SYS: ERROR@ (55DDH).
4030HSYS0/SYS: ABORT@ (52A6H).
0013HROM: input a byte from a control block (5421H).
001BHROM: output a byte to a control block (541AH).
0033HROM: display a character (549DH).
0040HROM: line input (54A5H).

Disassembly

5200H - PATCH

PATCH/CMD's transfer address, entered from the DOS command level with Register Pair HL at the command line after the word PATCH: PATCH filespec1 [filespec2], or PATCH filespec1 patname (KILL). PATCH changes a load module without touching its own records: each patch line (A=address,F=find,C=change) becomes a type 01H record with the new bytes, and the set of them is written before the transfer record behind a type 07H record that names the patch, so the loader puts the new bytes over the old ones. KILL removes a named patch by dropping its 07H record and the 01H records after it.

5200
PUSH HL E5
Save Register Pair HL, the command line pointer after PATCH, to the top of the stack while the heading is shown.
5201
LD HL,55E0H 21 E0 55
Point Register Pair HL to 55E0H, PATCH's heading (PATCH - DOSPLUS Patch Utility - 3.50) and the copyright line.
5204
GOSUB to 4467H, DSPLY@, to display the text at Register Pair HL up to and with the 0DH after the copyright line.
5207
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
5208
XOR A AF
Set Register A to 00H (XOR A), the mark of no patch file.
5209
LD (57B1H),A 32 B1 57
Store Register A (00H) into 57B1H, the first byte of the destination field: 80H only once a patch file is open.
520C
LD IX,568CH DD 21 8C 56
Point Index Register IX to 568CH, PATCH's evaluation block for EVAL@ (the module, the patch file or name, the parameters).
5210
GOSUB to 4479H, EVAL@, to take the fields and the parameters of the command line at Register Pair HL into the blocks.
5213
If the NZ FLAG is set (EVAL@ found an error, 2EH in Register A), JUMP to 55DBH to post the error.
5216
BIT 0,(IX+00H) DD CB 00 46
Test bit 0 of the flag byte at Index Register IX+00H, set by EVAL@ when a source field, the module, was given.
521A
If the Z FLAG is set (no module), JUMP to 55CDH for the error 2EH, Invalid parameter.

521DH - Open the Module

The first field must be a file specification (bit 6, a name), else the error 2CH. The module is opened with records of one byte, so that BKSP@ moves back one byte. KILL (or PULL, REMOVE, OUT, YANK) goes to 5342H; with a second field the patch file is opened and its name, up to 8 characters before a slash, period or colon, becomes the name of the patch at 59D3H; without one the lines come from the keyboard and the name stays NONAME between two asterisks.

521D
LD DE,578FH 11 8F 57
Point Register Pair DE to 578FH, the flag byte of the source block, the module to patch.
5220
LD A,(DE) 1A
Load Register A with the flag byte of the source block at Register Pair DE: bit 6 set for a file name.
5221
INC DE 13
INCrement Register Pair DE by 1, to 5790H, the text of the field, which OPEN@ takes as the file control block.
5222
AND 40H E6 40
AND Register A with 40H, keeping bit 6, a file name.
5224
If the Z FLAG is set (no file name), JUMP to 55D9H for the error 2CH, Illegal filespec.
5227
LD HL,57D1H 21 D1 57
Point Register Pair HL to 57D1H, the 256 byte buffer of the module.
522A
LD B,01H 06 01
Load Register B with 01H, the logical record length for OPEN@: records of one byte.
522C
GOSUB to 4424H, OPEN@, to open the module of the file control block at Register Pair DE.
522F
If the NZ FLAG is set (OPEN@ failed, its error code in Register A), JUMP to 55DBH to post the error.
5232
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the operand 5233H-5234H where EVAL@ stores the value of KILL and its other names: FFFFH for Y.
5235
INC E 1C
INCrement Register E by 1, the first half of a test of Register E for zero.
5236
DEC E 1D
DECrement Register E by 1, back to the value of KILL: the NZ FLAG when it is FFH.
5237
If the NZ FLAG is set (KILL), JUMP to 5342H to remove a patch.
523A
LD A,06H 3E 06
Load Register A with 06H, the bits of the destination and the wildmask in the evaluation block's flags.
523C
AND (IX+00H) DD A6 00
AND Register A with the flag byte at Index Register IX+00H: the Z FLAG when no second field was given.
523F
If the Z FLAG is set (no patch file), JUMP to 527CH for the patch lines from the keyboard.
5241
LD DE,57B0H 11 B0 57
Point Register Pair DE to 57B0H, the flag byte of the destination block, the patch file.
5244
LD A,(DE) 1A
Load Register A with the flag byte of the destination block at Register Pair DE: bit 6 set for a file name.
5245
INC DE 13
INCrement Register Pair DE by 1, to 57B1H, the text of the field.
5246
AND 40H E6 40
AND Register A with 40H, keeping bit 6, a file name.
5248
If the Z FLAG is set (no file name), JUMP to 55D9H for the error 2CH, Illegal filespec.
524B
LD HL,59D3H 21 D3 59
Point Register Pair HL to 59D3H, the name of the patch in the type 07H record at 59D1H.
524E
LD B,08H 06 08
Load Register B with 08H, the eight characters of a patch name.
5250
PUSH DE D5
Save Register Pair DE, the text of the patch file's specification, to the top of the stack.
5251
LD A,(DE) 1A
Load Register A with the next character of the specification at Register Pair DE.
5252
CP 20H FE 20
Compare Register A against 20H: the C FLAG for a control code, the end of the text.
5254
If the C FLAG is set (the end), JUMP to 5267H to pad the name with spaces.
5256
CP 2FH FE 2F
Compare Register A against 2FH, the slash before an extension.
5258
If the Z FLAG is set (the slash), JUMP to 5267H to pad the name with spaces.
525A
CP 2EH FE 2E
Compare Register A against 2EH, the period before a password.
525C
If the Z FLAG is set (the period), JUMP to 5267H to pad the name with spaces.
525E
CP 3AH FE 3A
Compare Register A against 3AH, the colon before a drive.
5260
If the Z FLAG is set (the colon), JUMP to 5267H to pad the name with spaces.
5262
LD (HL),A 77
Store Register A, a character of the name, into the patch's name at Register Pair HL.
5263
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the patch's name.
5264
INC DE 13
INCrement Register Pair DE by 1, to the next character of the specification.
5265
DECrement Register B and, while it is not zero, LOOP BACK to 5251H for the next character (DJNZ).
5267
INC B 04
INCrement Register B by 1, the first half of a test of Register B for zero.
5268
DEC B 05
DECrement Register B by 1, back to the places left: the Z FLAG when the name is full.
5269
If the Z FLAG is set (eight characters), JUMP to 5270H to open the patch file.
526B
LD (HL),20H 36 20
Store 20H, a space, into the rest of the patch's name at Register Pair HL.
526D
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the patch's name.
526E
DECrement Register B and, while it is not zero, LOOP BACK to 526BH for the next space (DJNZ).
5270
POP DE D1
Restore Register Pair DE, 57B1H, the patch file's specification, from the top of the stack.
5271
LD HL,58D1H 21 D1 58
Point Register Pair HL to 58D1H, the 256 byte buffer of the patch file.
5274
LD B,00H 06 00
Load Register B with 00H, the logical record length for OPEN@: 256 byte records.
5276
GOSUB to 4424H, OPEN@, to open the patch file of the file control block at Register Pair DE.
5279
If the NZ FLAG is set (OPEN@ failed, its error code in Register A), JUMP to 55DBH to post the error.

527CH - Each Patch Line

5494H takes the next line (from the patch file or the keyboard) and its A, F and C values; the C FLAG ends the lines. The module is read again from its start, byte by byte with the load address of each (5428H), until the address A; the transfer record first is Address not found. The bytes from there must equal the F string, else String not found; both end PATCH by ABORT@, with nothing written. Then a type 01H record with the C bytes at address A is added to the patch at (56C7H).

527C
GOSUB to 5494H for the next patch line, its address at 570DH and the F and C strings at 570FH and 574FH; the C FLAG at the end.
527F
If the C FLAG is set (no more lines), JUMP to 52EFH to write the patch to the module.
5282
LD DE,5790H 11 90 57
Point Register Pair DE to 5790H, the file control block of the module.
5285
GOSUB to 443FH, REW@, to set the module at Register Pair DE back to its start.
5288
XOR A AF
Set Register A to 00H (XOR A), the state of the reader of the load module: no record begun.
5289
LD (56C9H),A 32 C9 56
Store Register A (00H) into 56C9H, the flags of the reader, for the first record.
528C
GOSUB to 5428H for the next byte of the module in Register A and its load address in Register Pair HL; the NC FLAG at the transfer record.
528F
LD B,A 47
Load Register B with Register A, the byte of the module.
5290
If the NC FLAG is set (the transfer record: the address is not loaded), JUMP to 52A0H for Address not found.
5292
LD A,(570DH) 3A 0D 57
Load Register A with the low byte of the patch address from 570DH.
5295
SUB L 95
SUBtract Register L, the low byte of the load address, from Register A: the Z FLAG when they match.
5296
If the NZ FLAG is set (another address), JUMP to 528CH for the next byte of the module.
5298
LD A,(570EH) 3A 0E 57
Load Register A with the high byte of the patch address from 570EH.
529B
SUB H 94
SUBtract Register H, the high byte of the load address, from Register A: the Z FLAG when they match.
529C
If the Z FLAG is set (the byte that loads at the patch address), JUMP to 52A9H to test the F string.
529E
JUMP to 528CH for the next byte of the module, the high byte of the address differing.
52A0
LD HL,5637H 21 37 56
Point Register Pair HL to 5637H, the message Address not found.
52A3
GOSUB to 4467H, DSPLY@, to display the message at Register Pair HL.
52A6
JUMP to 4030H, ABORT@, which ends PATCH and returns to the DOS with nothing written.
52A9
LD A,B 78
Load Register A with Register B, the byte of the module at the patch address.
52AA
LD HL,570FH 21 0F 57
Point Register Pair HL to 570FH, the F string: its length, then its bytes.
52AD
LD B,(HL) 46
Load Register B with the length of the F string at Register Pair HL.
52AE
INC HL 23
INCrement Register Pair HL by 1, to the first byte of the F string.
52AF
INC B 04
INCrement Register B by 1, the first half of a test of the length for zero.
52B0
DEC B 05
DECrement Register B by 1, back to the length: the Z FLAG for an empty F string.
52B1
If the Z FLAG is set (no bytes to find), JUMP to 52C9H to add the patch.
52B3
CP (HL) BE
Compare Register A, the byte of the module, against the byte of the F string at Register Pair HL.
52B4
If the NZ FLAG is set (they differ), JUMP to 52C0H for String not found.
52B6
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the F string.
52B7
PUSH HL E5
Save Register Pair HL, the place in the F string, to the top of the stack.
52B8
GOSUB to 5428H for the next byte of the module in Register A and its load address in Register Pair HL.
52BB
POP HL E1
Restore Register Pair HL, the place in the F string, from the top of the stack.
52BC
DECrement Register B and, while it is not zero, LOOP BACK to 52B3H for the next byte of the F string (DJNZ).
52BE
JUMP to 52C9H to add the patch, the F string found.
52C0
LD HL,5649H 21 49 56
Point Register Pair HL to 5649H, the message String not found.
52C3
GOSUB to 4467H, DSPLY@, to display the message at Register Pair HL.
52C6
JUMP to 4030H, ABORT@, which ends PATCH and returns to the DOS with nothing written.
52C9
LD HL,(56C7H) 2A C7 56
Load Register Pair HL with the end of the patch so far from 56C7H-56C8H, where the new record goes.
52CC
LD DE,574FH 11 4F 57
Point Register Pair DE to 574FH, the C string: its length, then its bytes.
52CF
LD (HL),01H 36 01
Store 01H, the type of a load record, into the patch at Register Pair HL.
52D1
INC HL 23
INCrement Register Pair HL by 1, to the length byte of the record.
52D2
LD A,(DE) 1A
Load Register A with the length of the C string at Register Pair DE.
52D3
LD C,A 4F
Load Register C with Register A, the length of the C string, for the LDIR count.
52D4
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the length of the C string.
52D6
INC DE 13
INCrement Register Pair DE by 1, to the first byte of the C string.
52D7
INC A 3C
INCrement Register A by 1, the first of two for the address bytes of the record.
52D8
INC A 3C
INCrement Register A by 1: the record's length byte, the C bytes and two address bytes.
52D9
LD (HL),A 77
Store Register A, the length byte, into the record at Register Pair HL.
52DA
INC HL 23
INCrement Register Pair HL by 1, to the address of the record.
52DB
LD A,(570DH) 3A 0D 57
Load Register A with the low byte of the patch address from 570DH.
52DE
LD (HL),A 77
Store Register A, the low byte of the address, into the record at Register Pair HL.
52DF
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
52E0
LD A,(570EH) 3A 0E 57
Load Register A with the high byte of the patch address from 570EH.
52E3
LD (HL),A 77
Store Register A, the high byte of the address, into the record at Register Pair HL.
52E4
INC HL 23
INCrement Register Pair HL by 1, to the data of the record.
52E5
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair HL = the C string, Register Pair DE = the record's data.
52E6
LDIR ED B0
Copy the C string into the record: Register Pair BC bytes from Register Pair HL to Register Pair DE (LDIR; a count of 0000H copies 65536 bytes).
52E8
LD (56C7H),DE ED 53 C7 56
Store Register Pair DE, the new end of the patch, into 56C7H-56C8H.
52EC
JUMP to 527CH for the next patch line, the record of this one added to the patch.

52EFH - Write the Patch

No line at all is the error 30H. The module is read to its transfer record, whose address goes into the record at 56C3H, and set back four bytes onto it; the patch (the 07H name record at 59D1H and the 01H records) and then the transfer record are written there, and CLOSE@ ends the module: Patch(es) installed.

52EF
LD HL,59DBH 21 DB 59
Point Register Pair HL to 59DBH, the end of the 07H name record, where the first patch record begins.
52F2
LD DE,(56C7H) ED 5B C7 56
Load Register Pair DE with the end of the patch from 56C7H-56C8H.
52F6
GOSUB to 5414H to compare Register Pair HL with Register Pair DE: the Z FLAG when no record was added.
52F9
If the Z FLAG is set (no patch line), JUMP to 55D6H for the error 30H, Terminated.
52FC
LD DE,5790H 11 90 57
Point Register Pair DE to 5790H, the file control block of the module.
52FF
GOSUB to 443FH, REW@, to set the module at Register Pair DE back to its start.
5302
XOR A AF
Set Register A to 00H (XOR A), the state of the reader of the load module: no record begun.
5303
LD (56C9H),A 32 C9 56
Store Register A (00H) into 56C9H, the flags of the reader, for the first record.
5306
GOSUB to 5428H for the next byte of the module and its address; the NC FLAG at the transfer record.
5309
If the C FLAG is set (not yet the transfer record), JUMP to 5306H for the next byte.
530B
LD (56C5H),HL 22 C5 56
Store Register Pair HL, the transfer address, into 56C5H-56C6H, the address of the transfer record to write.
530E
LD B,04H 06 04
Load Register B with 04H, the four bytes of the transfer record already read.
5310
GOSUB to 4445H, BKSP@, to set the module at Register Pair DE back one byte.
5313
DECrement Register B and, while it is not zero, LOOP BACK to 5310H for the next byte (DJNZ).
5315
LD HL,59D1H 21 D1 59
Point Register Pair HL to 59D1H, the start of the patch: the 07H record with its name.
5318
PUSH DE D5
Save Register Pair DE, the file control block of the module, to the top of the stack.
5319
LD DE,(56C7H) ED 5B C7 56
Load Register Pair DE with the end of the patch from 56C7H-56C8H.
531D
GOSUB to 5414H to compare Register Pair HL with Register Pair DE: the Z FLAG at the end of the patch.
5320
POP DE D1
Restore Register Pair DE, the file control block of the module, from the top of the stack.
5321
If the Z FLAG is set (the whole patch written), JUMP to 532AH for the transfer record.
5323
LD A,(HL) 7E
Load Register A with the next byte of the patch at Register Pair HL.
5324
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the patch.
5325
GOSUB to 541AH to write the byte in Register A to the module at Register Pair DE.
5328
JUMP to 5318H for the next byte of the patch.
532A
LD HL,56C3H 21 C3 56
Point Register Pair HL to 56C3H, the transfer record: 02H, 02H and the transfer address.
532D
LD B,04H 06 04
Load Register B with 04H, the four bytes of the transfer record.
532F
LD A,(HL) 7E
Load Register A with the next byte of the transfer record at Register Pair HL.
5330
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the transfer record.
5331
GOSUB to 541AH to write the byte in Register A to the module at Register Pair DE.
5334
DECrement Register B and, while it is not zero, LOOP BACK to 532FH for the next byte (DJNZ).
5336
GOSUB to 4428H, CLOSE@, to close the module at Register Pair DE.
5339
If the NZ FLAG is set (CLOSE@ failed, its error code in Register A), JUMP to 55DBH to post the error.
533C
LD HL,565AH 21 5A 56
Point Register Pair HL to 565AH, the message Patch(es) installed.
533F
JUMP to 4467H, DSPLY@, which displays the message and returns to the DOS.

5342H - KILL, Remove a Patch

The second field is the patch's name: its text is cut at a slash, period or colon and padded with spaces to 8 characters in place. 53D8H finds its 07H record; not found is Patch not found. A second file control block (57B1H, with its own buffer 58D1H holding a copy of the first's) reads on from after the name record, while the first is set back the 10 bytes of the record and writes: the 01H records of the patch are dropped, and the rest of the file, from the next record on, is copied down. Patch removed.

5342
LD DE,57B0H 11 B0 57
Point Register Pair DE to 57B0H, the flag byte of the destination block, the name of the patch.
5345
LD A,(DE) 1A
Load Register A with the flag byte of the destination block at Register Pair DE: bit 6 set for a name.
5346
INC DE 13
INCrement Register Pair DE by 1, to 57B1H, the text of the field.
5347
AND 40H E6 40
AND Register A with 40H, keeping bit 6, a name.
5349
If the Z FLAG is set (no name), JUMP to 55CDH for the error 2EH, Invalid parameter.
534C
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair HL = the text of the patch's name.
534D
LD B,08H 06 08
Load Register B with 08H, the eight characters of a patch name.
534F
PUSH HL E5
Save Register Pair HL, the start of the name, to the top of the stack.
5350
LD A,(HL) 7E
Load Register A with the next character of the name at Register Pair HL.
5351
CP 20H FE 20
Compare Register A against 20H: the C FLAG for a control code, the end of the text.
5353
If the C FLAG is set (the end), JUMP to 5366H to pad the name with spaces.
5355
CP 2FH FE 2F
Compare Register A against 2FH, the slash before an extension.
5357
If the Z FLAG is set (the slash), JUMP to 5366H to pad the name with spaces.
5359
CP 2EH FE 2E
Compare Register A against 2EH, the period before a password.
535B
If the Z FLAG is set (the period), JUMP to 5366H to pad the name with spaces.
535D
CP 3AH FE 3A
Compare Register A against 3AH, the colon before a drive.
535F
If the Z FLAG is set (the colon), JUMP to 5366H to pad the name with spaces.
5361
INC HL 23
INCrement Register Pair HL by 1, to the next character of the name.
5362
DECrement Register B and, while it is not zero, LOOP BACK to 5350H for the next character (DJNZ).
5364
JUMP to 536BH with the eight characters of the name in place.
5366
LD (HL),20H 36 20
Store 20H, a space, into the rest of the name at Register Pair HL.
5368
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the name.
5369
DECrement Register B and, while it is not zero, LOOP BACK to 5366H for the next space (DJNZ).
536B
POP HL E1
Restore Register Pair HL, the start of the name, from the top of the stack.
536C
LD DE,5790H 11 90 57
Point Register Pair DE to 5790H, the file control block of the module.
536F
GOSUB to 53D8H to find the 07H record of the name at Register Pair HL in the module; the Z FLAG when found.
5372
If the Z FLAG is set (found), JUMP to 537DH to remove the patch.
5374
LD HL,567CH 21 7C 56
Point Register Pair HL to 567CH, the message Patch not found.
5377
GOSUB to 4467H, DSPLY@, to display the message at Register Pair HL.
537A
JUMP to 4030H, ABORT@, which ends PATCH and returns to the DOS.
537D
LD HL,57B1H 21 B1 57
Point Register Pair HL to 57B1H, the place of the second file control block.
5380
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair HL = 5790H, Register Pair DE = 57B1H.
5381
LD BC,0020H 01 20 00
Load Register Pair BC with 0020H, the 32 bytes of a file control block.
5384
PUSH HL E5
Save Register Pair HL, 5790H, to the top of the stack.
5385
PUSH DE D5
Save Register Pair DE, 57B1H, to the top of the stack.
5386
LDIR ED B0
Copy the file control block of the module to 57B1H: Register Pair BC bytes from Register Pair HL to Register Pair DE (LDIR).
5388
LD HL,58D1H 21 D1 58
Point Register Pair HL to 58D1H, the buffer of the second file control block.
538B
LD (57B4H),HL 22 B4 57
Store Register Pair HL (58D1H) into 57B4H-57B5H, FCB+03H of the copy, its buffer address.
538E
LD DE,57D1H 11 D1 57
Point Register Pair DE to 57D1H, the buffer of the module's first file control block.
5391
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair HL = 57D1H, Register Pair DE = 58D1H.
5392
LD BC,0100H 01 00 01
Load Register Pair BC with 0100H, the 256 bytes of a buffer.
5395
LDIR ED B0
Copy the buffer to the copy's buffer: Register Pair BC bytes from Register Pair HL to Register Pair DE (LDIR).
5397
POP DE D1
Restore Register Pair DE, 57B1H, from the top of the stack.
5398
POP HL E1
Restore Register Pair HL, 5790H, from the top of the stack.
5399
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = 5790H, the writer; Register Pair HL = 57B1H, the reader.
539A
LD B,0AH 06 0A
Load Register B with 0AH, the ten bytes of the name record: the type, the length and eight characters.
539C
GOSUB to 4445H, BKSP@, to set the module at Register Pair DE back one byte.
539F
DECrement Register B and, while it is not zero, LOOP BACK to 539CH for the next byte (DJNZ).
53A1
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = 57B1H, the reader after the name record.
53A2
GOSUB to 5421H to read the next byte of the module at Register Pair DE: the type of a record.
53A5
PUSH AF F5
Save Register Pair AF, the type, to the top of the stack.
53A6
GOSUB to 5421H to read the next byte of the module at Register Pair DE: the length of the record.
53A9
LD B,A 47
Load Register B with Register A, the length of the record.
53AA
POP AF F1
Restore Register Pair AF, the type, from the top of the stack.
53AB
CP 01H FE 01
Compare Register A against 01H, the type of a load record, a record of the patch.
53AD
If the NZ FLAG is set (the end of the patch), JUMP to 53B6H to copy the rest of the module.
53AF
GOSUB to 5421H to read the next byte of the record at Register Pair DE, which is dropped.
53B2
DECrement Register B and, while it is not zero, LOOP BACK to 53AFH for the next byte (DJNZ).
53B4
JUMP to 53A2H for the next record after the patch's record.
53B6
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = 5790H, the writer.
53B7
GOSUB to 541AH to write the type of the record in Register A to the module at Register Pair DE.
53BA
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = 57B1H, the reader.
53BB
LD A,B 78
Load Register A with Register B, the length of the record.
53BC
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = 5790H, the writer.
53BD
GOSUB to 541AH to write the byte in Register A to the module at Register Pair DE.
53C0
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = 57B1H, the reader.
53C1
GOSUB to 0013H, the ROM's input of a byte from the control block at Register Pair DE, the next byte of the module.
53C4
If the Z FLAG is set (a byte was read), JUMP to 53BCH to write it.
53C6
CP 1CH FE 1C
Compare Register A against 1CH, the error code of Attempted to read past eof: the end of the module.
53C8
If the NZ FLAG is set (another error), JUMP to 55DBH to post the error.
53CB
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = 5790H, the writer.
53CC
GOSUB to 4428H, CLOSE@, to close the module at Register Pair DE.
53CF
If the NZ FLAG is set (CLOSE@ failed, its error code in Register A), JUMP to 55DBH to post the error.
53D2
LD HL,566EH 21 6E 56
Point Register Pair HL to 566EH, the message Patch removed.
53D5
JUMP to 4467H, DSPLY@, which displays the message and returns to the DOS.

53D8H - Find a Patch Record

Reads the records of the module at Register Pair DE: a 07H record is compared byte for byte with the 8 character name at Register Pair HL (the Z FLAG when equal); the transfer record (02H) returns the NZ FLAG; other records are passed over.

53D8
GOSUB to 5421H to read the next byte of the module at Register Pair DE: the type of a record.
53DB
PUSH AF F5
Save Register Pair AF, the type, to the top of the stack.
53DC
GOSUB to 5421H to read the next byte of the module at Register Pair DE: the length of the record.
53DF
LD B,A 47
Load Register B with Register A, the length of the record.
53E0
POP AF F1
Restore Register Pair AF, the type, from the top of the stack.
53E1
CP 07H FE 07
Compare Register A against 07H, the type of a patch name record.
53E3
If the Z FLAG is set (a patch name), JUMP to 53FBH to compare it.
53E5
CP 02H FE 02
Compare Register A against 02H, the type of the transfer record that ends the module.
53E7
If the Z FLAG is set (the end), JUMP to 53F8H to return the NZ FLAG.
53E9
GOSUB to 5421H to read the first byte of the record at Register Pair DE, which is passed over.
53EC
DEC B 05
DECrement Register B by 1, one byte of the record read.
53ED
GOSUB to 5421H to read the second byte of the record at Register Pair DE, which is passed over.
53F0
DEC B 05
DECrement Register B by 1, the second byte of the record read.
53F1
GOSUB to 5421H to read the next byte of the record at Register Pair DE, which is passed over.
53F4
DECrement Register B and, while it is not zero, LOOP BACK to 53F1H for the next byte (DJNZ).
53F6
JUMP to 53D8H for the next record of the module.
53F8
OR FFH F6 FF
OR Register A with FFH, which makes the NZ FLAG: the name was not found.
53FA
RET C9
RETurn to the caller with the NZ FLAG: no patch of the name.
53FB
LD B,08H 06 08
Load Register B with 08H, the eight characters of a patch name.
53FD
PUSH HL E5
Save Register Pair HL, the name looked for, to the top of the stack.
53FE
GOSUB to 5421H to read the next character of the record's name from the module at Register Pair DE.
5401
CP (HL) BE
Compare Register A against the character of the name looked for at Register Pair HL.
5402
INC HL 23
INCrement Register Pair HL by 1, to the next character of the name looked for.
5403
If the NZ FLAG is set (they differ), JUMP to 540AH to pass over the rest of the record.
5405
DECrement Register B and, while it is not zero, LOOP BACK to 53FEH for the next character (DJNZ).
5407
POP HL E1
Restore Register Pair HL, the name looked for, from the top of the stack.
5408
CP A BF
Compare Register A against itself, which sets the Z FLAG: the patch is found.
5409
RET C9
RETurn to the caller with the Z FLAG and the module just after the name record.
540A
POP HL E1
Restore Register Pair HL, the name looked for, from the top of the stack.
540B
JUMP to 5410H to count the character that differed.
540D
GOSUB to 5421H to read the next character of the record at Register Pair DE, which is passed over.
5410
DECrement Register B and, while it is not zero, LOOP BACK to 540DH for the next character (DJNZ).
5412
JUMP to 53D8H for the next record of the module.

5414H - Compare, Write and Read a Byte

5414H compares Register Pair HL with Register Pair DE (the Z FLAG when equal). 541AH writes Register A to the control block at Register Pair DE by 001BH, 5421H reads one by 0013H; an error goes to 55DBH.

5414
PUSH HL E5
Save Register Pair HL to the top of the stack around the compare.
5415
OR A B7
OR Register A with itself, to clear the C FLAG for the SBC below.
5416
SBC HL,DE ED 52
SUBtract Register Pair DE from Register Pair HL with the C FLAG: the Z FLAG when they are equal.
5418
POP HL E1
Restore Register Pair HL from the top of the stack, as it was before the compare.
5419
RET C9
RETurn to the caller with the Z FLAG when Register Pair HL equals Register Pair DE.
541A
GOSUB to 001BH, the ROM's output of the byte in Register A to the control block at Register Pair DE.
541D
If the NZ FLAG is set (the write failed, its error code in Register A), JUMP to 55DBH to post the error.
5420
RET C9
RETurn to the caller with the byte written to the file at Register Pair DE.
5421
GOSUB to 0013H, the ROM's input of a byte from the control block at Register Pair DE: Register A = the byte.
5424
If the NZ FLAG is set (the read failed, its error code in Register A), JUMP to 55DBH to post the error.
5427
RET C9
RETurn to the caller with the byte read from the file at Register Pair DE in Register A.

5428H - The Next Byte of the Load Module

Index Register IX = 56C9H: +00H the flags (bit 0 inside a record, bit 1 a load or transfer record, bit 2 the transfer record), +01H the bytes left, +02H-+03H the address of the next byte. At the start of a record its type (20H or more is the error 22H), length and the two bytes after it are read. Returns the C FLAG with Register A = the next byte and Register Pair HL = its load address (0000H in a record that is not loaded), or at the transfer record the NC FLAG with Register Pair HL = the transfer address.

5428
LD IX,56C9H DD 21 C9 56
Point Index Register IX to 56C9H, the state of the reader of the load module.
542C
BIT 0,(IX+00H) DD CB 00 46
Test bit 0 of the flags at Index Register IX+00H, set inside a record.
5430
If the NZ FLAG is set (inside a record), JUMP to 5471H for its next byte.
5432
GOSUB to 5421H to read the next byte of the module at Register Pair DE: the type of a record.
5435
CP 02H FE 02
Compare Register A against 02H, the type of the transfer record.
5437
RES 2,(IX+00H) DD CB 00 96
Reset bit 2 of the flags at Index Register IX+00H: not the transfer record.
543B
If the NZ FLAG is set (not 02H), JUMP to 5441H.
543D
SET 2,(IX+00H) DD CB 00 D6
Set bit 2 of the flags at Index Register IX+00H: the transfer record.
5441
CP 20H FE 20
Compare Register A against 20H: the NC FLAG for a type no load module has.
5443
If the NC FLAG is set (not a load module), JUMP to 55D3H for the error 22H, Attempted to use non program file as a program.
5446
CP 03H FE 03
Compare Register A against 03H: the C FLAG for the types 01H and 02H.
5448
RES 1,(IX+00H) DD CB 00 8E
Reset bit 1 of the flags at Index Register IX+00H: not a record with an address.
544C
If the NC FLAG is set (type 03H or more), JUMP to 5452H.
544E
SET 1,(IX+00H) DD CB 00 CE
Set bit 1 of the flags at Index Register IX+00H: a load or transfer record, with an address.
5452
GOSUB to 5421H to read the length byte of the record from the module at Register Pair DE.
5455
DEC A 3D
DECrement Register A by 1, the first of two for the two bytes after the length.
5456
DEC A 3D
DECrement Register A by 1: the bytes of the record after those two.
5457
LD (IX+01H),A DD 77 01
Store Register A, the bytes left, into +01H at Index Register IX+01H.
545A
GOSUB to 5421H to read the first byte after the length: the low byte of a load address.
545D
LD (IX+02H),A DD 77 02
Store Register A, the low byte of the address, into +02H at Index Register IX+02H.
5460
GOSUB to 5421H to read the second byte after the length: the high byte of a load address.
5463
LD (IX+03H),A DD 77 03
Store Register A, the high byte of the address, into +03H at Index Register IX+03H.
5466
SET 0,(IX+00H) DD CB 00 C6
Set bit 0 of the flags at Index Register IX+00H: inside a record.
546A
OR A B7
OR Register A with itself, to clear the C FLAG.
546B
BIT 2,(IX+00H) DD CB 00 56
Test bit 2 of the flags at Index Register IX+00H, set for the transfer record.
546F
If the NZ FLAG is set (the transfer record), JUMP to 5486H to return its address with the NC FLAG.
5471
GOSUB to 5421H to read the next byte of the record from the module at Register Pair DE.
5474
DEC (IX+01H) DD 35 01
DECrement the bytes left at Index Register IX+01H by 1: the Z FLAG at the last byte of the record.
5477
If the NZ FLAG is set (more bytes), JUMP to 547DH.
5479
RES 0,(IX+00H) DD CB 00 86
Reset bit 0 of the flags at Index Register IX+00H: the record is done.
547D
BIT 1,(IX+00H) DD CB 00 4E
Test bit 1 of the flags at Index Register IX+00H, set for a load record.
5481
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, the address given for a byte that is not loaded.
5484
SCF 37
Set the C FLAG (SCF): a byte of the module, not the transfer record.
5485
RET Z C8
If the Z FLAG is set (not a load record), RETurn to the caller with the C FLAG and Register Pair HL = 0000H.
5486
LD L,(IX+02H) DD 6E 02
Load Register L with the low byte of the address at Index Register IX+02H.
5489
LD H,(IX+03H) DD 66 03
Load Register H with the high byte at Index Register IX+03H: Register Pair HL = the load address of the byte.
548C
INC (IX+02H) DD 34 02
INCrement the low byte of the address at Index Register IX+02H, for the next byte.
548F
RET NZ C0
If the NZ FLAG is set (no carry into the high byte), RETurn to the caller.
5490
INC (IX+03H) DD 34 03
INCrement the high byte of the address at Index Register IX+03H.
5493
RET C9
RETurn to the caller with the byte in Register A and its address in Register Pair HL.

5494H - The Next Patch Line

From the patch file (57B1H is 80H once it is open): up to 64 bytes into 56CDH, to the 0DH (longer is the error 2DH); the end of the file returns the C FLAG. From the keyboard: an asterisk and up to 63 characters; BREAK returns the C FLAG. A line starting with a period is a comment. Then A= (a number), F= and C= (strings) are found, each anywhere in the line, and taken into 570DH, 570FH and 574FH; a missing one is the error 2EH.

5494
LD A,(57B1H) 3A B1 57
Load Register A with the first byte of the destination field from 57B1H: 80H when the patch file is open.
5497
CP 80H FE 80
Compare Register A against 80H, the type byte of an open file control block.
5499
If the Z FLAG is set (a patch file), JUMP to 54ABH to read the next line from it.
549B
LD A,2AH 3E 2A
Load Register A with 2AH, the asterisk shown as the prompt for a patch line.
549D
GOSUB to 0033H, the ROM's display of the character in Register A, the prompt.
54A0
LD B,3FH 06 3F
Load Register B with 3FH, the most characters of the line: 63.
54A2
LD HL,56CDH 21 CD 56
Point Register Pair HL to 56CDH, the buffer of the patch line.
54A5
GOSUB to 0040H, the ROM's line input of up to Register B characters into the buffer at Register Pair HL; the C FLAG for BREAK.
54A8
RET C D8
If the C FLAG is set (BREAK), RETurn to the caller with the C FLAG: the lines are done.
54A9
JUMP to 54CAH to take the patch line from the buffer.
54AB
LD DE,57B1H 11 B1 57
Point Register Pair DE to 57B1H, the file control block of the patch file.
54AE
LD HL,56CDH 21 CD 56
Point Register Pair HL to 56CDH, the buffer of the patch line.
54B1
LD B,40H 06 40
Load Register B with 40H, the most bytes of a line: 64.
54B3
GOSUB to 0013H, the ROM's input of a byte from the control block at Register Pair DE, the patch file.
54B6
If the Z FLAG is set (a byte was read), JUMP to 54BFH to keep it.
54B8
CP 1CH FE 1C
Compare Register A against 1CH, the error code of Attempted to read past eof: the end of the patch file.
54BA
If the NZ FLAG is set (another error), JUMP to 55DBH to post the error.
54BD
SCF 37
Set the C FLAG (SCF): the lines of the patch file are done.
54BE
RET C9
RETurn to the caller with the C FLAG at the end of the patch file.
54BF
LD (HL),A 77
Store Register A, the byte of the line, into the buffer at Register Pair HL.
54C0
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the buffer.
54C1
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends a line.
54C3
If the Z FLAG is set (the end of the line), JUMP to 54CAH to take the patch line.
54C5
DECrement Register B and, while it is not zero, LOOP BACK to 54B3H for the next byte (DJNZ).
54C7
JUMP to 55D0H for the error 2DH, Invalid data provided: the line is longer than 64 bytes.
54CA
LD HL,56CDH 21 CD 56
Point Register Pair HL to 56CDH, the start of the patch line.
54CD
LD A,2EH 3E 2E
Load Register A with 2EH, the period that starts a comment line.
54CF
CP (HL) BE
Compare Register A against the first character of the line at Register Pair HL.
54D0
If the Z FLAG is set (a comment), JUMP to 5494H for the next line.
54D2
LD B,41H 06 41
Load Register B with 41H, the letter A of the address.
54D4
PUSH HL E5
Save Register Pair HL, the start of the line, to the top of the stack.
54D5
GOSUB to 54FBH to find A= in the line; Register Pair HL returns after the equal sign.
54D8
GOSUB to 555EH for the number at Register Pair HL in Register Pair DE.
54DB
LD (570DH),DE ED 53 0D 57
Store Register Pair DE, the address of the patch, into 570DH-570EH.
54DF
POP HL E1
Restore Register Pair HL, the start of the line, from the top of the stack.
54E0
PUSH HL E5
Save Register Pair HL, the start of the line, to the top of the stack again.
54E1
LD B,46H 06 46
Load Register B with 46H, the letter F of the find string.
54E3
GOSUB to 54FBH to find F= in the line; Register Pair HL returns after the equal sign.
54E6
LD DE,570FH 11 0F 57
Point Register Pair DE to 570FH, the place of the F string.
54E9
GOSUB to 5511H to take the string at Register Pair HL to Register Pair DE: its length, then its bytes.
54EC
POP HL E1
Restore Register Pair HL, the start of the line, from the top of the stack.
54ED
PUSH HL E5
Save Register Pair HL, the start of the line, to the top of the stack again.
54EE
LD B,43H 06 43
Load Register B with 43H, the letter C of the change string.
54F0
GOSUB to 54FBH to find C= in the line; Register Pair HL returns after the equal sign.
54F3
LD DE,574FH 11 4F 57
Point Register Pair DE to 574FH, the place of the C string.
54F6
GOSUB to 5511H to take the string at Register Pair HL to Register Pair DE: its length, then its bytes.
54F9
POP HL E1
Restore Register Pair HL, the start of the line, from the top of the stack.
54FA
RET C9
RETurn to the caller with the NC FLAG and the line taken.

54FBH - Find a Letter and the Equal Sign

Register B = the letter: scans the line for it, upper case or lower case, directly followed by =; Register Pair HL returns after the equal sign. Reaching the 0DH is the error 2EH, Invalid parameter.

54FB
LD A,(HL) 7E
Load Register A with the next character of the line at Register Pair HL.
54FC
GOSUB to 55C4H to make a lower case letter in Register A upper case.
54FF
CP B B8
Compare Register A against Register B, the letter looked for.
5500
INC HL 23
INCrement Register Pair HL by 1, to the next character of the line.
5501
If the Z FLAG is set (the letter), JUMP to 550AH to test for the equal sign.
5503
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return that ends the line.
5505
If the NZ FLAG is set (not the end), JUMP to 54FBH for the next character.
5507
JUMP to 55CDH for the error 2EH, Invalid parameter: the letter and the equal sign are not in the line.
550A
LD A,(HL) 7E
Load Register A with the character after the letter at Register Pair HL.
550B
CP 3DH FE 3D
Compare Register A against 3DH, the equal sign.
550D
If the NZ FLAG is set (no equal sign), JUMP to 54FBH to scan on.
550F
INC HL 23
INCrement Register Pair HL by 1, past the equal sign.
5510
RET C9
RETurn to the caller with Register Pair HL at the value.

5511H - A String

Register Pair HL = the value, Register Pair DE = the place: a string in single or double quotation marks is copied as it is up to the closing mark or the 0DH (5545H); otherwise pairs of hexadecimal digits make bytes, spaces between pairs passed over, up to the first other character (a single last digit is dropped). The count goes to the first byte at Register Pair DE.

5511
LD A,(HL) 7E
Load Register A with the first character of the value at Register Pair HL.
5512
CP 27H FE 27
Compare Register A against 27H, the single quotation mark.
5514
If the Z FLAG is set (a quoted string), JUMP to 5545H to copy it.
5516
CP 22H FE 22
Compare Register A against 22H, the double quotation mark.
5518
If the Z FLAG is set (a quoted string), JUMP to 5545H to copy it.
551A
LD BC,1000H 01 00 10
Load Register Pair BC with 1000H: Register B = 10H, the base 16 of the digits, Register C = 00H, the count of bytes.
551D
PUSH DE D5
Save Register Pair DE, the place of the count, to the top of the stack.
551E
INC DE 13
INCrement Register Pair DE by 1, to the place of the first byte.
551F
GOSUB to 5526H to make the bytes of the hexadecimal digits at Register Pair HL; Register C counts them.
5522
POP DE D1
Restore Register Pair DE, the place of the count, from the top of the stack.
5523
LD A,C 79
Load Register A with Register C, the count of bytes.
5524
LD (DE),A 12
Store Register A, the count, into the first byte of the string at Register Pair DE.
5525
RET C9
RETurn to the caller with the hexadecimal string taken and counted.
5526
GOSUB to 5598H for the next character as a digit of base Register B; the C FLAG for a digit.
5529
If the C FLAG is set (a digit), JUMP to 5534H for the high half of a byte.
552B
DEC HL 2B
DECrement Register Pair HL by 1, back to the character that is not a digit.
552C
LD A,(HL) 7E
Load Register A with the character at Register Pair HL.
552D
INC HL 23
INCrement Register Pair HL by 1, past the character that is not a digit.
552E
CP 20H FE 20
Compare Register A against 20H, a space between bytes.
5530
If the Z FLAG is set (a space), JUMP to 5526H for the next byte.
5532
OR A B7
OR Register A with itself, which clears the C FLAG.
5533
RET C9
RETurn to the caller at the end of the hexadecimal string.
5534
RLCA 07
Rotate Register A left one bit, the first of four that make the digit the high half (RLCA).
5535
RLCA 07
Rotate Register A left one bit, the second of four (RLCA).
5536
RLCA 07
Rotate Register A left one bit, the third of four (RLCA).
5537
RLCA 07
Rotate Register A left one bit, the fourth: the digit in bits 7-4 (RLCA).
5538
LD (DE),A 12
Store Register A, the high half of the byte, into the string at Register Pair DE.
5539
GOSUB to 5598H for the next character as a digit of base Register B; the C FLAG for a digit.
553C
RET NC D0
If the NC FLAG is set (no second digit), RETurn to the caller: the half byte is not counted.
553D
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair HL = the byte of the string.
553E
OR (HL) B6
OR Register A, the low digit, into the byte of the string at Register Pair HL.
553F
LD (HL),A 77
Store Register A, the whole byte, into the string at Register Pair HL.
5540
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair HL = the value again.
5541
INC DE 13
INCrement Register Pair DE by 1, to the place of the next byte.
5542
INC C 0C
INCrement Register C by 1, one more byte in the string.
5543
JUMP to 5526H for the next byte of the hexadecimal string.
5545
LD B,A 47
Load Register B with Register A, the quotation mark that ends the string.
5546
LD C,00H 0E 00
Load Register C with 00H, the count of characters.
5548
INC HL 23
INCrement Register Pair HL by 1, past the opening quotation mark.
5549
PUSH DE D5
Save Register Pair DE, the place of the count, to the top of the stack.
554A
INC DE 13
INCrement Register Pair DE by 1, to the place of the first character.
554B
GOSUB to 5552H to copy the characters up to the closing mark; Register C counts them.
554E
POP DE D1
Restore Register Pair DE, the place of the count, from the top of the stack.
554F
LD A,C 79
Load Register A with Register C, the count of characters.
5550
LD (DE),A 12
Store Register A, the count, into the first byte of the string at Register Pair DE.
5551
RET C9
RETurn to the caller with the quoted string taken.
5552
LD A,(HL) 7E
Load Register A with the next character of the value at Register Pair HL.
5553
CP B B8
Compare Register A against Register B, the closing quotation mark.
5554
RET Z C8
If the Z FLAG is set (the closing mark), RETurn to the caller.
5555
CP 0DH FE 0D
Compare Register A against 0DH, the carriage return at the end of the line.
5557
RET Z C8
If the Z FLAG is set (the end of the line), RETurn to the caller.
5558
LD (DE),A 12
Store Register A, a character of the string, into the string at Register Pair DE.
5559
INC DE 13
INCrement Register Pair DE by 1, to the place of the next character.
555A
INC HL 23
INCrement Register Pair HL by 1, to the next character of the value.
555B
INC C 0C
INCrement Register C by 1, one more character in the string.
555C
JUMP to 5552H for the next character of the quoted string.

555EH - A Number

Register Pair HL = the number: its last character before a space, a comma or the end picks the base (B binary, O octal, H hexadecimal, anything else decimal), then the digits are taken from the start into Register Pair DE.

555E
PUSH HL E5
Save Register Pair HL, the start of the number, to the top of the stack.
555F
LD A,(HL) 7E
Load Register A with the next character of the number at Register Pair HL.
5560
CP 21H FE 21
Compare Register A against 21H: the C FLAG for a space or a control code, the end of the number.
5562
If the C FLAG is set (the end), JUMP to 556BH for its last character.
5564
CP 2CH FE 2C
Compare Register A against 2CH, the comma after the number.
5566
If the Z FLAG is set (the comma), JUMP to 556BH for its last character.
5568
INC HL 23
INCrement Register Pair HL by 1, to the next character of the number.
5569
JUMP to 555FH for the next character of the number.
556B
DEC HL 2B
DECrement Register Pair HL by 1, back to the last character of the number.
556C
LD A,(HL) 7E
Load Register A with the last character of the number at Register Pair HL.
556D
GOSUB to 55C4H to make a lower case letter in Register A upper case.
5570
LD B,02H 06 02
Load Register B with 02H, the base for B, binary.
5572
CP 42H FE 42
Compare Register A against 42H, the letter B.
5574
If the Z FLAG is set (B), JUMP to 5584H with the base 2.
5576
LD B,08H 06 08
Load Register B with 08H, the base for O, octal.
5578
CP 4FH FE 4F
Compare Register A against 4FH, the letter O.
557A
If the Z FLAG is set (O), JUMP to 5584H with the base 8.
557C
LD B,10H 06 10
Load Register B with 10H, the base for H, hexadecimal.
557E
CP 48H FE 48
Compare Register A against 48H, the letter H.
5580
If the Z FLAG is set (H), JUMP to 5584H with the base 16.
5582
LD B,0AH 06 0A
Load Register B with 0AH, the base 10, decimal, for D or no letter.
5584
POP HL E1
Restore Register Pair HL, the start of the number, from the top of the stack.
5585
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H, the number before its first digit.
5588
GOSUB to 5598H for the next character as a digit of base Register B; the C FLAG for a digit.
558B
RET NC D0
If the NC FLAG is set (not a digit), RETurn to the caller with the number in Register Pair DE.
558C
PUSH AF F5
Save Register Pair AF, the digit in Register A, to the top of the stack.
558D
GOSUB to 55A7H to multiply Register Pair DE by the base in Register B.
5590
POP AF F1
Restore Register Pair AF, the digit in Register A, from the top of the stack.
5591
ADD A,E 83
ADD Register E to Register A, the digit: the low byte of the new number.
5592
LD E,A 5F
Load Register E with Register A, the low byte of the new number.
5593
If the NC FLAG is set (no carry), JUMP to 5588H for the next digit.
5595
INC D 14
INCrement Register D by 1, the carry into the high byte.
5596
JUMP to 5588H for the next digit of the number.
5598
LD A,(HL) 7E
Load Register A with the next character at Register Pair HL.
5599
INC HL 23
INCrement Register Pair HL by 1, past the character.
559A
GOSUB to 55C4H to make a lower case letter in Register A upper case.
559D
SUB 30H D6 30
SUBtract 30H from Register A, the character 0: the value of a digit 0-9.
559F
CP 0AH FE 0A
Compare Register A against 0AH: the C FLAG for 0-9.
55A1
If the C FLAG is set (0-9), JUMP to 55A5H to compare it with the base.
55A3
SUB 07H D6 07
SUBtract 07H from Register A: A-F become 0AH-0FH.
55A5
CP B B8
Compare Register A against Register B, the base: the C FLAG for a digit of the base.
55A6
RET C9
RETurn to the caller with the C FLAG for a digit, its value in Register A.
55A7
LD A,0AH 3E 0A
Load Register A with 0AH, the base 10, which is multiplied another way.
55A9
CP B B8
Compare Register A against Register B, the base.
55AA
If the Z FLAG is set (decimal), JUMP to 55B9H to multiply by 10.
55AC
PUSH BC C5
Save Register Pair BC, the base, to the top of the stack.
55AD
SLA E CB 23
Shift Register E left one bit (SLA), the low byte of the number times 2.
55AF
RL D CB 12
Rotate Register D left through the C FLAG (RL): Register Pair DE times 2.
55B1
RRC B CB 08
Rotate Register B right one bit (RRC), the base halved for the count of shifts.
55B3
BIT 0,B CB 40
Test bit 0 of Register B, set when the shifts for the base are done.
55B5
If the Z FLAG is set (more shifts), JUMP to 55ADH for the next shift.
55B7
POP BC C1
Restore Register Pair BC, the base, from the top of the stack.
55B8
RET C9
RETurn to the caller with Register Pair DE times the base.
55B9
PUSH HL E5
Save Register Pair HL to the top of the stack around the multiply by 10.
55BA
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair HL = the number.
55BB
ADD HL,HL 29
ADD Register Pair HL to itself: two times the number (ADD HL,HL).
55BC
PUSH HL E5
Save Register Pair HL, two times the number, to the top of the stack.
55BD
POP DE D1
Restore Register Pair DE from the top of the stack: Register Pair DE = two times the number.
55BE
ADD HL,HL 29
ADD Register Pair HL to itself: four times the number (ADD HL,HL).
55BF
ADD HL,HL 29
ADD Register Pair HL to itself: eight times the number (ADD HL,HL).
55C0
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: ten times the number.
55C1
EX DE,HL EB
Exchange Register Pair DE and Register Pair HL: Register Pair DE = ten times the number.
55C2
POP HL E1
Restore Register Pair HL from the top of the stack.
55C3
RET C9
RETurn to the caller with Register Pair DE times 10.
55C4
CP 61H FE 61
Compare Register A against 61H, the letter a: the C FLAG below it.
55C6
RET C D8
If the C FLAG is set (below a), RETurn to the caller with the character unchanged.
55C7
CP 7BH FE 7B
Compare Register A against 7BH, the character after z: the NC FLAG from it on.
55C9
RET NC D0
If the NC FLAG is set (after z), RETurn to the caller with the character unchanged.
55CA
RES 5,A CB AF
Reset bit 5 of Register A: a lower case letter becomes upper case.
55CC
RET C9
RETurn to the caller with the character in Register A.

55CDH - The Errors

55CDH the error 2EH, Invalid parameter; 55D0H, 55D3H, 55D6H and 55D9H, each inside an LD BC, the errors 2DH Invalid data provided, 22H Attempted to use non program file as a program, 30H Terminated and 2CH Illegal filespec; 55DBH any error code in Register A. Each is posted with bit 6 set (no frame) and bit 7 clear, so ERROR@ ends through ABORT@.

55CD
LD A,2EH 3E 2E
Load Register A with 2EH, the error code of Invalid parameter, and fall into the LD BC below.
55CF
LD BC,2D3EH 01 3E 2D
55D0H enters inside this LD BC,2D3EH: its bytes 3EH 2DH read as LD A,2DH, Invalid data provided; from above it only loads Register Pair BC.
55D2
LD BC,223EH 01 3E 22
55D3H enters inside this LD BC,223EH: its bytes 3EH 22H read as LD A,22H, the error of a file that is not a load module; from above it only loads Register Pair BC.
55D5
LD BC,303EH 01 3E 30
55D6H enters inside this LD BC,303EH: its bytes 3EH 30H read as LD A,30H, Terminated; from above it only loads Register Pair BC.
55D8
LD BC,2C3EH 01 3E 2C
55D9H enters inside this LD BC,2C3EH: its bytes 3EH 2CH read as LD A,2CH, Illegal filespec; from above it only loads Register Pair BC.
55DB
OR 40H F6 40
OR Register A with 40H, setting bit 6 of the error code: ERROR@ shows the message without the frame of asterisks.
55DD
JUMP to 4409H, ERROR@, with the error code in Register A; with bit 7 clear ERROR@ does not return but ends through ABORT@.

55E0H - The Texts, the Parameters and the Variables

Data: the heading and the messages, the evaluation block and its parameter block (five names, PULL, REMOVE, KILL, OUT and YANK, all storing into 5233H, type 20H), the transfer record to write, the end of the patch, the reader's flags; then, not loaded, the line, the address and the strings, the two file blocks and buffers; and the second block of the file, the 07H record of the default patch name at 59D1H.

55E0-5604
DEFM "PATCH - DOSPLUS Patch Utility - 3.50" / DEFB 0AH 50 41 54 43 48 20 2D 20 44 4F 53 50 4C 55 53 20 50 61 74 63 68 20 55 74 69 6C 69 74 79 20 2D 20 33 2E 35 30 0A
The heading (5201H): PATCH - DOSPLUS Patch Utility - 3.50 and a line feed.
5605-5636
DEFM "(c) Copyright 1983, Micro-Systems Software, Inc." / DEFB 0AH,0DH 28 63 29 20 43 6F 70 79 72 69 67 68 74 20 31 39 38 33 2C 20 4D 69 63 72 6F 2D 53 79 73 74 65 6D 73 20 53 6F 66 74 77 61 72 65 2C 20 49 6E 63 2E 0A 0D
The copyright line (with a comma after Software, unlike the other utilities), a line feed and the 0DH.
5637-5648
DEFM "Address not found" / DEFB 0DH 41 64 64 72 65 73 73 20 6E 6F 74 20 66 6F 75 6E 64 0D
The message when the patch address is not loaded by the module (52A0H).
5649-5659
DEFM "String not found" / DEFB 0DH 53 74 72 69 6E 67 20 6E 6F 74 20 66 6F 75 6E 64 0D
The message when the bytes at the address are not the F string (52C0H).
565A-566D
DEFM "Patch(es) installed" / DEFB 0DH 50 61 74 63 68 28 65 73 29 20 69 6E 73 74 61 6C 6C 65 64 0D
The message after the patch is written (533CH).
566E-567B
DEFM "Patch removed" / DEFB 0DH 50 61 74 63 68 20 72 65 6D 6F 76 65 64 0D
The message after KILL has removed a patch (53D2H).
567C-568B
DEFM "Patch not found" / DEFB 0DH 50 61 74 63 68 20 6E 6F 74 20 66 6F 75 6E 64 0D
The message when KILL finds no 07H record of the name (5374H).
568C
DEFB 00H 00
The flags of the evaluation block, set by EVAL@: bit 0 the source, 1 the destination, 2 the wildmask, 3 the parameters.
568D-568E
DEFW 578FH 8F 57
The address of the source field's block, 578FH, the module.
568F-5690
DEFW 57B0H B0 57
The address of the destination field's block, 57B0H, the patch file or the name of a patch.
5691-5692
DEFW 57B0H B0 57
The address of the wildmask field's block, the destination block again.
5693-5694
DEFW 5695H 95 56
The address of the parameter block, 5695H, the five names of KILL.
5695-569A
DEFM "PULL " 50 55 4C 4C 20 20
The name of the parameter PULL, one of the five names of KILL.
569B-569C
DEFW 5233H 33 52
The address for PULL's value, the operand of LD DE at 5232H.
569D
DEFB 20H 20
The type byte of PULL: a logical value only (bit 5).
569E-56A3
DEFM "REMOVE" 52 45 4D 4F 56 45
The name of the parameter REMOVE, one of the five names of KILL.
56A4-56A5
DEFW 5233H 33 52
The address for REMOVE's value, the operand of LD DE at 5232H.
56A6
DEFB 20H 20
The type byte of REMOVE: a logical value only (bit 5).
56A7-56AC
DEFM "KILL " 4B 49 4C 4C 20 20
The name of the parameter KILL (or K), the one the manual gives.
56AD-56AE
DEFW 5233H 33 52
The address for KILL's value, the operand of LD DE at 5232H.
56AF
DEFB 20H 20
The type byte of KILL: a logical value only (bit 5).
56B0-56B5
DEFM "OUT " 4F 55 54 20 20 20
The name of the parameter OUT, one of the five names of KILL.
56B6-56B7
DEFW 5233H 33 52
The address for OUT's value, the operand of LD DE at 5232H.
56B8
DEFB 20H 20
The type byte of OUT: a logical value only (bit 5).
56B9-56BE
DEFM "YANK " 59 41 4E 4B 20 20
The name of the parameter YANK, one of the five names of KILL.
56BF-56C0
DEFW 5233H 33 52
The address for YANK's value, the operand of LD DE at 5232H.
56C1
DEFB 20H 20
The type byte of YANK: a logical value only (bit 5).
56C2
DEFB 00H 00
The 00H that ends the parameter block of PATCH's five parameters.
56C3-56C6
DEFB 02H,02H,00H,00H 02 02 00 00
The transfer record written after the patch (532AH): type 02H, length 02H and the transfer address, set at 530BH.
56C7-56C8
DEFW 59DBH DB 59
The end of the patch built so far (52C9H, 52E8H), 59DBH after the name record.
56C9
DEFB 00H 00
The flags of the reader of the load module (5428H), Index Register IX+00H.
56CA-56CC
DEFS 3
The reader's bytes left of the record (+01H) and the address of its next byte (+02H-+03H).
56CD-570C
DEFS 64
The patch line, from the patch file or the keyboard (54A2H, 54AEH).
570D-570E
DEFS 2
The address of the patch line, the value of A= (54DBH).
570F-574E
DEFS 64
The F string: its length, then its bytes (54E6H).
574F-578E
DEFS 64
The C string: its length, then its bytes (54F3H).
578F-57AF
DEFS 33
The source field's block (568DH): the flag byte, and from 5790H the file control block of the module.
57B0-57D0
DEFS 33
The destination field's block (568FH): the flag byte, and from 57B1H the file control block of the patch file, the name of a patch, or the second file control block of KILL (537DH).
57D1-58D0
DEFS 256
The 256 byte buffer of the module being patched (5227H).
58D1-59D0
DEFS 256
The buffer of the patch file (5271H) or of KILL's second file control block (5388H).
59D1-59D2
DEFB 07H,08H 07 08
The patch's name record: type 07H and its length, 8 (5315H).
59D3-59DA
DEFM "*NONAME*" 2A 4E 4F 4E 41 4D 45 2A
The name of a patch from the keyboard, replaced by the patch file's name (524BH).
59DB
DEFS 1
The first byte after the name record, where the patch's 01H records are built upwards (52EFH).