DOSPLUS 3.5 for the Model I - SR/CMD Disassembled

Page Customization

Introduction/Summary

DOSPLUS 3.5 SR/CMD Disassembly - Global Search and Replace of BASIC Text (Model I)

SR/CMD is the BASIC global search and replace utility of DOSPLUS 3.5, version 1.7. It is a load module of 3 blocks, 551 bytes, from 5200H to 5426H, with the transfer address 5200H, after the two comment records (the name SR and the copyright notice). The Model I and Model III files are identical byte for byte, and so are the two pages apart from their links.

SR works only from Extended Disk BASIC, as CMD"SR",search[,replace][,first-last]: BASIC/CMD's CMD (5C48H) passes the two characters SR to CMNDI@ as a DOS command, the DOS loads SR/CMD at 5200H, in the overlay area that BASIC/CMD leaves free, and calls it. SR finds BASIC's text pointer after "SR" on the stack, under the return address of CMNDI@ (5212H). Run from the DOS command level (return address 402DH) it only shows its heading (5209H). TBASIC cannot run it, since its CMD runs no DOS commands. SR never returns to CMNDI@: it ends at the ROM's READY, which also resets the stack.

The Parts of SR/CMD

AddressContents
5200H-5240HThe start: the caller test, the search and replace strings, the line range (5200H).
5241H-5285HThe loop over the lines in the range, each expanded into the input buffer (5241H).
5286H-52FCHThe search and the replacement in the buffer (5286H).
52FDH-5356HA changed line is put back into the program (52FDH).
5357H-53B7HRoutines: take a string (5357H), list a line (5377H), pass a 00H (538EH), the room check (5394H), the line too long (53AFH).
53B8H-5628HThe texts and the variables (53B8H).

How SR Works

The search string must not be empty (Illegal function call). A second string after a comma turns on the replace mode; a number after the comma instead is the line range, given as for LIST (the ROM's 1B10H): n, n-, -n, n-m, or none for the whole program. The current line number is set to FFFFH, so that an error shows as in the direct mode (523AH). Each line in the range is expanded into the input buffer by the ROM's LIST code (2B7EH), so the search compares the text as LIST shows it, keywords spelled out, and not the tokenized bytes. In the search mode a line with a match is listed once (its number, a space and its text) and BREAK and SHIFT @ are tested between the lines (524CH). In the replace mode every match in the line is replaced, the search going on after the replace string, so that a replace string that holds the search string is not searched again (52F2H). A changed line is listed, taken out of the program, tokenized again by the ROM (1BC0H) and put back with its line number; at the end the line links are rebuilt (1AF8H) and the variables cleared (1B5DH), and SR ends at READY.

Differences from the Manual

The manual (Disk BASIC, page 5-51) does not say that a search string or a range is compared with the listed text of the lines, that the search mode lists a line only once however many matches it has, or that the variables are cleared after a replacement. Two limits are not in the manual: a line that would grow past 255 characters shows Line too long to edit and keeps its old text, though the line listed shows the replacements made before the one that was too long (53AFH); and when the memory is too small for a changed line, the ROM's Out of memory is shown after the old line was already taken out of the program, so that line is lost (5394H).

Variables

SR/CMD Variables

Address
Size
Contents
5426H
1 byte
Replace mode
00H: search only; otherwise the first character of the replace string's expression (5226H).
5427H
1 byte
Line length
The length of the text in the buffer with its 00H (5282H).
5428H
1 byte
Change flag
Not 00H once a match in the line was replaced (52D5H).
5429H-5528H
256 bytes
Search string
Its length, then the characters (5216H).
5529H-5628H
256 bytes
Replace string
Its length, then the characters (5229H).

Memory Outside SR/CMD

Address
Size
Contents
40A2H-40A3H
2 bytes
Current line number
Set to FFFFH, the direct mode (523DH).
40A7H-40A8H
2 bytes
Input buffer
The ROM's input buffer, which holds the listed text of the line (5277H).
40ECH-40EDH
2 bytes
Current line
The number of the line being searched (526CH).
40F9H-40FAH
2 bytes
VARTAB
The end of the program, moved with each changed line (532EH).

Outside Routines

AddressContents
4467HSYS0/SYS: DSPLY@, the heading (520CH).
402DHSYS0/SYS: EXIT@ (520FH).
1B10HROM: the line range of LIST (5236H).
2B7EHROM: expand a line into the input buffer (5274H).
1BC0HROM: tokenize the input buffer (5324H).
1AF8HROM: rebuild the line links (5261H, 53A3H).
1B5DHROM: the set-up of RUN, which clears the variables (5264H).
2337HROM: evaluate an expression (5358H).
1D9BHROM: test BREAK and SHIFT @ (524CH).
1A19HROM: READY (525EH, 5267H).

Disassembly

5200H - SR

SR/CMD's transfer address. SR is run from Extended Disk BASIC as CMD"SR",search[,replace][,range]: BASIC/CMD's CMD passes "SR" to CMNDI@ as a DOS command, and the DOS loads SR/CMD at 5200H and calls it. A call from the DOS command level, whose return address is 402DH, only shows the heading and goes back to the DOS. From BASIC the text pointer after "SR" is on the stack: SR takes the search string (5429H), the replace string (5529H, which turns on the replace mode, 5426H) and the line range (the ROM's 1B10H), and walks the lines in the range. It never returns to CMNDI@: it ends at the ROM's READY.

5200
POP HL E1
Restore Register Pair HL with the return address on the top of the stack: 402DH (EXIT@) from the DOS command level, else the return into the caller of CMNDI@.
5201
LD DE,402DH 11 2D 40
Load Register Pair DE with 402DH, EXIT@, the return address that the DOS command level gives a program.
5204
OR A B7
OR Register A against itself, to clear the C FLAG for the SBC below.
5205
SBC HL,DE ED 52
SUBtract Register Pair DE (402DH) from Register Pair HL with the C FLAG: the Z FLAG when SR was run from the DOS command level.
5207
If the NZ FLAG is set (run from a program, BASIC's CMD), JUMP to 5212H.
5209
LD HL,53B8H 21 B8 53
Point Register Pair HL to 53B8H, SR's heading and copyright line, ended by 0DH.
520C
GOSUB to 4467H, DSPLY@, to show the text at Register Pair HL.
520F
JUMP to 402DH, EXIT@, back to the DOS: SR does its work only from BASIC.
5212
POP HL E1
Restore Register Pair HL from the top of the stack: BASIC's text pointer after the string "SR", saved by its CMD (5C4EH in BASIC/CMD).
5213
POP AF F1
Restore Register Pair AF with the next word of the stack, the ROM's return into its statement loop, which SR does not use.
5214
RST 08H => 2CH CF 2C
RST 08H: the next character of the text at Register Pair HL must be 2CH, the comma before the search string, or the ROM shows a Syntax error.
5216
LD DE,5429H 11 29 54
Point Register Pair DE to 5429H, where the search string is kept: its length, then its characters.
5219
GOSUB to 5357H to evaluate the string expression at Register Pair HL into 5429H: the Z FLAG when it is empty.
521C
If the Z FLAG is set (an empty search string), JUMP to 1E4AH, the ROM's Illegal function call error.
521F
RST 10H D7
RST 10H: increment Register Pair HL and load Register A with the next character of the text: the Z FLAG at the end of the statement.
5220
If the Z FLAG is set (the search string only), JUMP to 5236H to take the whole program as the range.
5222
RST 08H => 2CH CF 2C
RST 08H: the next character of the text at Register Pair HL must be 2CH, a comma; RST 08H fetches the character after it into Register A, with the C FLAG for a digit.
5224
If the C FLAG is set (a digit: a line range, no replace string), JUMP to 5236H.
5226
LD (5426H),A 32 26 54
Store Register A, the first character of the replace string's expression (not 00H), to 5426H: the replace mode is on.
5229
LD DE,5529H 11 29 55
Point Register Pair DE to 5529H, where the replace string is kept: its length, then its characters.
522C
GOSUB to 5357H to evaluate the string expression at Register Pair HL into 5529H (an empty replace string deletes the search string).
522F
RST 10H D7
RST 10H: increment Register Pair HL and load Register A with the next character of the text: the Z FLAG at the end of the statement.
5230
If the Z FLAG is set (no line range), JUMP to 5236H to take the whole program.
5232
RST 08H => 2CH CF 2C
RST 08H: the next character of the text at Register Pair HL must be 2CH, the comma before the line range.
5234
If the C FLAG is set (a digit), JUMP to 5236H: the next instruction either way, so the flag decides nothing.
5236
GOSUB to 1B10H, the ROM's line range of LIST (n, n-, -n, n-m or none): Register Pair BC returns the address of the first line, the last line number is left on the stack.
5239
PUSH BC C5
Save Register Pair BC, the address of the first line, to the top of the stack.
523A
LD HL,FFFFH 21 FF FF
Load Register Pair HL with FFFFH, the line number of the direct mode.
523D
LD (40A2H),HL 22 A2 40
Store Register Pair HL (FFFFH) into 40A2H-40A3H, the ROM's current line number: an error from now on is shown as in the direct mode.
5240
POP HL E1
Restore Register Pair HL, the address of the first line in the range, from the top of the stack.

5241H - The Next Line

The loop over the lines. Register Pair HL is the address of a line, the last line number of the range is on the stack. The end of the program, or a line past the range, ends the work: in the search mode at READY; in the replace mode after the ROM has rebuilt the line links (1AF8H) and cleared the variables (1B5DH), since the program text moved. A line in the range is expanded into the input buffer by the ROM's LIST code (2B7EH) and searched (5286H).

5241
POP DE D1
Restore Register Pair DE, the last line number of the range, from the top of the stack.
5242
LD A,(HL) 7E
Load Register A with the low byte of the line's link at Register Pair HL.
5243
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the link.
5244
OR (HL) B6
OR Register A with the high byte of the link at Register Pair HL: the Z FLAG for the link 0000H, the end of the program.
5245
INC HL 23
INCrement Register Pair HL by 1, to the line number.
5246
If the Z FLAG is set (the end of the program), JUMP to 525AH to finish.
5248
LD A,(5426H) 3A 26 54
Load Register A with the replace mode from 5426H: 00H for the search mode.
524B
OR A B7
OR Register A against itself: the Z FLAG in the search mode.
524C
If the Z FLAG is set (the search mode), GOSUB to 1D9BH, the ROM's test of BREAK and of SHIFT @ (a pause) between the lines listed.
524F
LD C,(HL) 4E
Load Register C with the low byte of the line number at Register Pair HL.
5250
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the line number.
5251
LD B,(HL) 46
Load Register B with the high byte of the line number at Register Pair HL: Register Pair BC = the line number.
5252
INC HL 23
INCrement Register Pair HL by 1, to the text of the line.
5253
PUSH BC C5
Save Register Pair BC, the line number, to the top of the stack.
5254
EX (SP),HL E3
EXchange Register Pair HL with the top of the stack (the Stack Pointer's word): Register Pair HL = the line number, the stack holds the text address.
5255
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the last line number of the range, Register Pair DE = the line number.
5256
RST 18H DF
RST 18H: compare Register Pair HL, the last line number, with Register Pair DE, the line number: the C FLAG when the line is past the range.
5257
If the NC FLAG is set (the line is in the range), JUMP to 526AH.
5259
POP BC C1
Restore Register Pair BC, the text address of the line, from the top of the stack: it is not used.
525A
LD A,(5426H) 3A 26 54
Load Register A with the replace mode from 5426H.
525D
OR A B7
OR Register A against itself: the Z FLAG in the search mode, where nothing was changed.
525E
If the Z FLAG is set (the search mode), JUMP to 1A19H, the ROM's READY.
5261
GOSUB to 1AF8H, the ROM's rebuilding of the line links from the start of the program, after the lines were moved.
5264
GOSUB to 1B5DH, the ROM's set-up of RUN, which clears the variables: they lay above the old end of the program.
5267
JUMP to 1A19H, the ROM's READY, after the changed program was relinked and its variables cleared.
526A
EX (SP),HL E3
EXchange Register Pair HL with the top of the stack (the Stack Pointer's word): Register Pair HL = the text address, the stack holds the last line number again.
526B
PUSH HL E5
Save Register Pair HL, the text address of the line, to the top of the stack.
526C
LD (40ECH),DE ED 53 EC 40
Store Register Pair DE, the line number, into 40ECH-40EDH, the ROM's current line of EDIT and LIST (shown by 5377H).
5270
XOR A AF
Set Register A to 00H by XORing it with itself, for the change flag.
5271
LD (5428H),A 32 28 54
Store Register A (00H) to 5428H: nothing changed in this line yet.
5274
GOSUB to 2B7EH, the ROM's LIST code, which expands the tokenized text at Register Pair HL into the input buffer, ended by 00H.
5277
LD HL,(40A7H) 2A A7 40
Load Register Pair HL with the address of the input buffer from 40A7H-40A8H.
527A
PUSH HL E5
Save Register Pair HL, the input buffer, to the top of the stack.
527B
GOSUB to 538EH to move Register Pair HL past the 00H that ends the text in the input buffer.
527E
POP DE D1
Restore Register Pair DE, the input buffer, from the top of the stack.
527F
SBC HL,DE ED 52
SUBtract Register Pair DE, the buffer, from Register Pair HL with the C FLAG (clear): the length of the text with its 00H.
5281
LD A,L 7D
Load Register A with Register L, the length of the text with its 00H.
5282
LD (5427H),A 32 27 54
Store Register A, the length of the text with its 00H, to 5427H for the replace mode.
5285
LD C,A 4F
Load Register C with Register A: the count of the bytes left in the buffer, the 00H included.

5286H - The Search

Compares the search string with the text in the buffer at each place, from Register Pair DE on, with Register C the count of the bytes left (the 00H included). In the search mode the first match lists the line (5377H) and the next line follows. In the replace mode every match is replaced: the search string is taken out of the buffer, the replace string put in its place, and the search goes on after the replace string, so that the new text is not searched again. A line that would become longer than 255 characters shows Line too long to edit (53AFH) and is listed, but the program keeps the old line. At the end of a changed line the program is changed (52FDH).

5286
LD HL,5429H 21 29 54
Point Register Pair HL to 5429H, the search string.
5289
LD B,(HL) 46
Load Register B with the length of the search string at Register Pair HL.
528A
INC HL 23
INCrement Register Pair HL by 1, to the first character of the search string.
528B
PUSH HL E5
Save Register Pair HL, the search string's characters, to the top of the stack.
528C
PUSH BC C5
Save Register Pair BC, the length in Register B and the bytes left in Register C, to the top of the stack.
528D
PUSH DE D5
Save Register Pair DE, the place in the buffer, to the top of the stack.
528E
DEC C 0D
DECrement Register C by 1, the bytes left in the buffer.
528F
If the Z FLAG is set (the end of the text), JUMP to 529BH: no match at this place.
5291
LD A,(DE) 1A
Load Register A with the character of the buffer at Register Pair DE.
5292
CP (HL) BE
Compare Register A with the character of the search string at Register Pair HL.
5293
If the NZ FLAG is set (they differ), JUMP to 529BH: no match at this place.
5295
INC DE 13
INCrement Register Pair DE by 1, to the next character of the buffer.
5296
INC HL 23
INCrement Register Pair HL by 1, to the next character of the search string.
5297
DECrement Register B and LOOP back to 528EH while characters of the search string are left.
5299
JUMP to 52A4H: the whole search string matched, and Register Pair DE is past it.
529B
POP DE D1
Restore Register Pair DE, the place in the buffer, from the top of the stack.
529C
POP BC C1
Restore Register Pair BC, the length and the bytes left, from the top of the stack.
529D
POP HL E1
Restore Register Pair HL, the search string's characters, from the top of the stack.
529E
INC DE 13
INCrement Register Pair DE by 1, to the next place in the buffer.
529F
DEC C 0D
DECrement Register C by 1, the count of the bytes left in the buffer from the new place.
52A0
If the NZ FLAG is set (bytes left), LOOP BACK to 528BH to compare at the next place.
52A2
JUMP to 52FDH: the end of the line's text, no more matches.
52A4
LD A,(5426H) 3A 26 54
Load Register A with the replace mode from 5426H.
52A7
OR A B7
OR Register A against itself: the NZ FLAG in the replace mode.
52A8
If the NZ FLAG is set (the replace mode), JUMP to 52B6H to replace the match.
52AA
POP AF F1
Restore Register Pair AF from the top of the stack, dropping the saved place in the buffer.
52AB
POP AF F1
Restore Register Pair AF from the top of the stack, dropping the saved length and count.
52AC
POP AF F1
Restore Register Pair AF from the top of the stack, dropping the saved search string address.
52AD
POP HL E1
Restore Register Pair HL, the text address of the line, from the top of the stack.
52AE
GOSUB to 5377H to list the line: its number and the text in the buffer.
52B1
GOSUB to 538EH to move Register Pair HL past the 00H that ends the line's text: the next line.
52B4
JUMP to 5241H for the next line: in the search mode a line is listed once, at its first match.
52B6
LD A,(5429H) 3A 29 54
Load Register A with the length of the search string from 5429H.
52B9
LD B,A 47
Load Register B with Register A, the length of the search string.
52BA
LD A,(5427H) 3A 27 54
Load Register A with the length of the text with its 00H from 5427H.
52BD
DEC A 3D
DECrement Register A by 1: the length of the text without the 00H.
52BE
SUB B 90
SUBtract Register B, the search string's length, from Register A: the text without the match.
52BF
LD B,A 47
Load Register B with Register A, the length without the match.
52C0
LD A,(5529H) 3A 29 55
Load Register A with the length of the replace string from 5529H.
52C3
ADD A,B 80
ADD Register B to Register A: the length of the new text; the C FLAG when it passes 255.
52C4
If the C FLAG is set (too long), JUMP to 53AFH to show Line too long to edit.
52C7
INC A 3C
INCrement Register A by 1, for the 00H at the end of the text.
52C8
LD (5427H),A 32 27 54
Store Register A, the new length with the 00H, to 5427H.
52CB
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the buffer after the match.
52CC
POP DE D1
Restore Register Pair DE, the start of the match, from the top of the stack.
52CD
POP AF F1
Restore Register Pair AF with the saved Register Pair BC: Register A = the length of the search string.
52CE
LD B,A 47
Load Register B with Register A, the length of the search string; Register C holds the bytes after the match, the 00H included.
52CF
PUSH BC C5
Save Register Pair BC, the length of the search string and the bytes after the match, to the top of the stack.
52D0
PUSH DE D5
Save Register Pair DE, the start of the match, to the top of the stack.
52D1
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the bytes after the match.
52D3
LDIR ED B0
Move the text after the match down to the start of the match by LDIR, from Register Pair HL to Register Pair DE, counted by Register Pair BC: the match is taken out.
52D5
LD (5428H),A 32 28 54
Store Register A, the length of the search string (not 00H), to 5428H: the line has changed.
52D8
LD A,(5529H) 3A 29 55
Load Register A with the length of the replace string from 5529H.
52DB
OR A B7
OR Register A against itself: the Z FLAG for an empty replace string.
52DC
If the Z FLAG is set (nothing to put in), JUMP to 52F8H to search on from the start of the match.
52DE
LD C,A 4F
Load Register C with Register A, the length of the replace string (Register B is 00H after the LDIR).
52DF
POP AF F1
Restore Register Pair AF from the top of the stack, dropping the start of the match.
52E0
DEC DE 1B
DECrement Register Pair DE by 1, to the 00H at the end of the text after the move.
52E1
LD L,E 6B
Load Register L with Register E, the low byte of the end of the text.
52E2
LD H,D 62
Load Register H with Register D: Register Pair HL = the end of the text.
52E3
ADD HL,BC 09
ADD Register Pair BC, the length of the replace string, to Register Pair HL: the new end of the text.
52E4
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair DE = the new end, Register Pair HL = the old end.
52E5
POP BC C1
Restore Register Pair BC, the length of the search string and the bytes after the match, from the top of the stack.
52E6
PUSH BC C5
Save Register Pair BC to the top of the stack again, for the search after the replacement.
52E7
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the bytes after the match, the 00H included.
52E9
LDDR ED B8
Move those bytes up by the length of the replace string by LDDR, from Register Pair HL to Register Pair DE, counted by Register Pair BC: a gap opens at the match.
52EB
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair DE = the byte before the gap.
52EC
INC DE 13
INCrement Register Pair DE by 1, to the start of the gap.
52ED
LD HL,5529H 21 29 55
Point Register Pair HL to 5529H, the replace string.
52F0
LD C,(HL) 4E
Load Register C with the length of the replace string at Register Pair HL.
52F1
INC HL 23
INCrement Register Pair HL by 1, to the first character of the replace string.
52F2
LDIR ED B0
Copy the replace string into the gap by LDIR, from Register Pair HL to Register Pair DE, counted by Register Pair BC: Register Pair DE ends after it.
52F4
POP BC C1
Restore Register Pair BC, the length of the search string and the bytes after the replace string, from the top of the stack.
52F5
POP HL E1
Restore Register Pair HL, the search string's characters, from the top of the stack.
52F6
JUMP to 528BH to search on after the replace string.
52F8
POP DE D1
Restore Register Pair DE, the start of the match, from the top of the stack: the search goes on there.
52F9
POP BC C1
Restore Register Pair BC, the length of the search string and the bytes from there on, from the top of the stack.
52FA
POP HL E1
Restore Register Pair HL, the search string's characters, from the top of the stack.
52FB
JUMP to 528BH to search on from the start of the match.

52FDH - Change the Line

The end of a line's text. A line with no change goes on to the next line. A changed line is listed (5377H), the old line is taken out of the program by moving the rest of the program down, the new text in the buffer is tokenized by the ROM (1BC0H), the room is checked (5394H), the rest of the program is moved up again and the new line (a link, the line number of 40ECH and the tokenized text) is put in its place. The line links are rebuilt only at the end (5261H); the new line's link gets a high byte that is not 00H, so that the line is not taken as the end of the program in the meantime.

52FD
POP HL E1
Restore Register Pair HL, the text address of the line, from the top of the stack.
52FE
LD D,H 54
Load Register D with Register H, the high byte of the text address.
52FF
LD E,L 5D
Load Register E with Register L: Register Pair DE = the text address.
5300
DEC DE 1B
DECrement Register Pair DE by 1, back over the line number's high byte.
5301
DEC DE 1B
DECrement Register Pair DE by 1, back over the line number's low byte.
5302
DEC DE 1B
DECrement Register Pair DE by 1, back over the link's high byte.
5303
DEC DE 1B
DECrement Register Pair DE by 1, back over the link's low byte: Register Pair DE = the start of the line.
5304
GOSUB to 538EH to move Register Pair HL past the 00H that ends the line's text: the start of the next line.
5307
LD A,(5428H) 3A 28 54
Load Register A with the change flag from 5428H: 00H when nothing was replaced.
530A
OR A B7
OR Register A against itself: the Z FLAG for a line that did not change.
530B
If the Z FLAG is set (no change), JUMP to 5241H for the next line.
530E
PUSH DE D5
Save Register Pair DE, the start of the line, to the top of the stack.
530F
GOSUB to 5377H to list the changed line: its number and the new text in the buffer.
5312
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair DE = the next line, Register Pair HL = the start of this line.
5313
LD HL,(40F9H) 2A F9 40
Load Register Pair HL with VARTAB from 40F9H-40FAH, the end of the program (the start of the simple variables).
5316
OR A B7
OR Register A against itself, to clear the C FLAG for the SBC below.
5317
SBC HL,DE ED 52
SUBtract Register Pair DE, the next line, from Register Pair HL with the C FLAG: the bytes from the next line to the end of the program.
5319
LD B,H 44
Load Register B with Register H, the high byte of the count.
531A
LD C,L 4D
Load Register C with Register L: Register Pair BC = the bytes after this line.
531B
POP HL E1
Restore Register Pair HL, the start of this line, from the top of the stack.
531C
PUSH BC C5
Save Register Pair BC, the bytes after this line, to the top of the stack.
531D
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the next line, Register Pair DE = the start of this line.
531E
LDIR ED B0
Move the rest of the program down over this line by LDIR, from Register Pair HL to Register Pair DE, counted by Register Pair BC: the old line is gone.
5320
PUSH DE D5
Save Register Pair DE, the new end of the program, to the top of the stack.
5321
LD HL,(40A7H) 2A A7 40
Load Register Pair HL with the address of the input buffer from 40A7H-40A8H, the new text of the line.
5324
GOSUB to 1BC0H, the ROM's tokenizer, which tokenizes the text in the input buffer: Register Pair BC returns the length of the line it makes.
5327
POP DE D1
Restore Register Pair DE, the end of the program, from the top of the stack.
5328
LD H,D 62
Load Register H with Register D, the high byte of the end of the program.
5329
LD L,E 6B
Load Register L with Register E: Register Pair HL = the end of the program.
532A
ADD HL,BC 09
ADD Register Pair BC, the length of the new line, to Register Pair HL: the end of the program with the new line.
532B
GOSUB to 5394H to check that the program still ends at least 58 bytes below the stack, else Out of memory.
532E
LD (40F9H),HL 22 F9 40
Store Register Pair HL, the new end of the program, into VARTAB at 40F9H-40FAH.
5331
DEC DE 1B
DECrement Register Pair DE by 1, to the last byte of the program as it is now.
5332
DEC HL 2B
DECrement Register Pair HL by 1, to the last byte of the program after the move.
5333
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the last byte now, Register Pair DE = its place after the move.
5334
POP AF F1
Restore Register Pair AF with the count of the bytes after the line, saved at 531CH.
5335
PUSH BC C5
Save Register Pair BC, the length of the new line, to the top of the stack.
5336
PUSH AF F5
Save Register Pair AF, the count of the bytes after the line, to the top of the stack.
5337
POP BC C1
Restore Register Pair BC with that count from the top of the stack.
5338
LDDR ED B8
Move the rest of the program up by the length of the new line by LDDR, from Register Pair HL to Register Pair DE, counted by Register Pair BC: the gap for the line opens.
533A
INC HL 23
INCrement Register Pair HL by 1, to the start of the gap, the low byte of the new line's link.
533B
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the link.
533C
LD (HL),H 74
Store Register H at Register Pair HL: a link high byte that is not 00H (the ROM's 1AF8H sets the real link at the end).
533D
INC HL 23
INCrement Register Pair HL by 1, to the line number.
533E
LD BC,(40ECH) ED 4B EC 40
Load Register Pair BC with the line number from 40ECH-40EDH, stored at 526CH.
5342
LD (HL),C 71
Store Register C, the low byte of the line number, at Register Pair HL.
5343
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the line number.
5344
LD (HL),B 70
Store Register B, the high byte of the line number, at Register Pair HL.
5345
INC HL 23
INCrement Register Pair HL by 1, to the text of the new line.
5346
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair DE = the place of the new line's text.
5347
LD HL,(40A7H) 2A A7 40
Load Register Pair HL with the address of the input buffer from 40A7H-40A8H.
534A
DEC HL 2B
DECrement Register Pair HL by 1, back from the start of the input buffer.
534B
DEC HL 2B
DECrement Register Pair HL by 1: two bytes before the buffer, where the tokenized text begins.
534C
POP BC C1
Restore Register Pair BC, the length of the new line, from the top of the stack.
534D
DEC BC 0B
DECrement Register Pair BC by 1, for the link's low byte.
534E
DEC BC 0B
DECrement Register Pair BC by 1, for the link's high byte.
534F
DEC BC 0B
DECrement Register Pair BC by 1, for the line number's low byte.
5350
DEC BC 0B
DECrement Register Pair BC by 1, for the line number's high byte: the length of the tokenized text.
5351
LDIR ED B0
Copy the tokenized text into the line by LDIR, from Register Pair HL to Register Pair DE, counted by Register Pair BC.
5353
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the byte after the new line, the next line.
5354
JUMP to 5241H for the next line, which follows the new line in the program.

5357H - Take a String

Evaluates the string expression at Register Pair HL (the ROM's 2337H; not a string: Type mismatch) and copies it to Register Pair DE as a length byte and the characters. Returns Register Pair HL at the text after the expression, less 1 (so that the RST 10H after the call reads the next character), and the Z FLAG for an empty string.

5357
PUSH DE D5
Save Register Pair DE, the place for the string, to the top of the stack.
5358
GOSUB to 2337H, the ROM's expression evaluator, for the expression at Register Pair HL.
535B
GOSUB to 0AF4H, the ROM's test that the value is a string, else Type mismatch.
535E
DEC HL 2B
DECrement Register Pair HL by 1, so that the next RST 10H reads the character after the expression.
535F
EX (SP),HL E3
EXchange Register Pair HL with the top of the stack (the Stack Pointer's word): Register Pair HL = the place for the string, the stack holds the text pointer.
5360
PUSH HL E5
Save Register Pair HL, the place for the string, to the top of the stack.
5361
GOSUB to 29D7H, the ROM's routine that frees the string's temporary descriptor: Register Pair HL returns the descriptor.
5364
POP DE D1
Restore Register Pair DE, the place for the string, from the top of the stack.
5365
LD A,(HL) 7E
Load Register A with the length of the string from the descriptor at Register Pair HL.
5366
LD (DE),A 12
Store Register A, the length, at Register Pair DE.
5367
OR A B7
OR Register A against itself: the Z FLAG for an empty string.
5368
If the Z FLAG is set (empty), JUMP to 5375H with the Z FLAG.
536A
INC DE 13
INCrement Register Pair DE by 1, to the place of the first character.
536B
INC HL 23
INCrement Register Pair HL by 1, to the address of the string in the descriptor.
536C
LD C,A 4F
Load Register C with Register A, the length of the string.
536D
LD B,00H 06 00
Load Register B with 00H: Register Pair BC = the length.
536F
LD A,(HL) 7E
Load Register A with the low byte of the string's address at Register Pair HL.
5370
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the string's address.
5371
LD H,(HL) 66
Load Register H with the high byte of the string's address at Register Pair HL.
5372
LD L,A 6F
Load Register L with Register A: Register Pair HL = the string.
5373
LDIR ED B0
Copy the characters by LDIR, from Register Pair HL to Register Pair DE, counted by Register Pair BC (LDIR keeps the Z FLAG of the OR above).
5375
POP HL E1
Restore Register Pair HL, the text pointer, from the top of the stack.
5376
RET C9
RETurn with the NZ FLAG for a string that is not empty.

5377H - List the Line

Shows the line number of 40ECH, a space, the text in the input buffer and a carriage return.

5377
PUSH HL E5
Save Register Pair HL to the top of the stack.
5378
LD HL,(40ECH) 2A EC 40
Load Register Pair HL with the line number from 40ECH-40EDH.
537B
GOSUB to 0FAFH, the ROM's output of the integer in Register Pair HL as a number.
537E
LD A,20H 3E 20
Load Register A with 20H, the space after the line number.
5380
GOSUB to 032AH, the ROM's output of the character in Register A to the selected device.
5383
LD HL,(40A7H) 2A A7 40
Load Register Pair HL with the address of the input buffer from 40A7H-40A8H.
5386
GOSUB to 2B75H, the ROM's output of the text at Register Pair HL up to its 00H.
5389
GOSUB to 20FEH, the ROM's output of a carriage return.
538C
POP HL E1
Restore Register Pair HL from the top of the stack.
538D
RET C9
RETurn to the caller with Register Pair HL unchanged.

538EH - Past the 00H

Moves Register Pair HL past the next 00H byte.

538E
XOR A AF
Set Register A to 00H by XORing it with itself, the byte looked for.
538F
CP (HL) BE
Compare Register A (00H) with the byte at Register Pair HL: the Z FLAG for the 00H.
5390
INC HL 23
INCrement Register Pair HL by 1, to the next byte (the flags are kept).
5391
If the NZ FLAG is set (not the 00H), LOOP BACK to 538FH.
5393
RET C9
RETurn with Register Pair HL just past the 00H.

5394H - The Room Check

Register Pair HL is the new end of the program. Returns when the end is at least 58 bytes (3AH) below the Stack Pointer. Otherwise the line links are rebuilt, VARTAB is set after the program and the ROM shows Out of memory; the changed line is then lost, since its old text was already taken out of the program (531EH).

5394
PUSH DE D5
Save Register Pair DE to the top of the stack.
5395
PUSH HL E5
Save Register Pair HL, the new end of the program, to the top of the stack.
5396
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair DE = the new end of the program.
5397
LD HL,FFC6H 21 C6 FF
Load Register Pair HL with FFC6H, minus 58, the room that must stay free below the stack.
539A
OR A B7
OR Register A against itself, to clear the C FLAG for the SBC below.
539B
SBC HL,DE ED 52
SUBtract Register Pair DE, the new end, from Register Pair HL with the C FLAG: minus 58 less the end; the C FLAG when the end is above FFC6H.
539D
If the C FLAG is set, JUMP to 53A3H: Out of memory.
539F
ADD HL,SP 39
ADD the Stack Pointer to Register Pair HL: the C FLAG when the Stack Pointer is at least 58 bytes above the new end.
53A0
POP HL E1
Restore Register Pair HL, the new end, from the top of the stack.
53A1
POP DE D1
Restore Register Pair DE from the top of the stack.
53A2
RET C D8
If the C FLAG is set (room enough), RETurn with Register Pair HL the new end of the program.
53A3
GOSUB to 1AF8H, the ROM's rebuilding of the line links: Register Pair HL returns the end of the program.
53A6
INC HL 23
INCrement Register Pair HL by 1, past the end of the program.
53A7
LD (40F9H),HL 22 F9 40
Store Register Pair HL into VARTAB at 40F9H-40FAH, the end of the program.
53AA
LD E,0CH 1E 0C
Load Register E with 0CH, the offset of the error Out of memory.
53AC
JUMP to 19A2H, the ROM's error routine, with the offset in Register E.

53AFH - Too Long

The replacement would make the line longer than 255 characters: the message Line too long to edit is shown, and the line is listed as in the search mode (52AAH) with the replacements made before this one; the program keeps the old line.

53AF
LD HL,540FH 21 0F 54
Point Register Pair HL to 540FH, the text Line too long to edit.
53B2
GOSUB to 2B75H, the ROM's output of the text at Register Pair HL up to its 00H.
53B5
JUMP to 52AAH to list the line and go on with the next one.

53B8H - The Texts and the Variables

Data.

53B8-53DD
DEFM "SR - BASIC Global search/replace - 1.7" 53 52 20 2D 20 42 41 53 49 43 20 47 6C 6F 62 61 6C 20 73 65 61 72 63 68 2F 72 65 70 6C 61 63 65 20 2D 20 31 2E 37
The heading that SR shows when it is run from the DOS command level (5209H).
53DE
DEFB 0AH 0A
A line feed, which starts the second line of the heading for DSPLY@.
53DF-540D
DEFM "(c) Copyright 1983, Micro-Systems Software Inc." 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 20 49 6E 63 2E
The copyright line of the heading, the second line that DSPLY@ shows.
540E
DEFB 0DH 0D
The carriage return that ends the heading for DSPLY@.
540F-5423
DEFM "Line too long to edit" 4C 69 6E 65 20 74 6F 6F 20 6C 6F 6E 67 20 74 6F 20 65 64 69 74
The message of a replacement that would make a line longer than 255 characters (53AFH).
5424-5425
DEFB 0DH,00H 0D 00
A carriage return and the 00H that ends the message for the ROM's 2B75H.
5426
DEFB 00H 00
The replace mode: 00H (as loaded) for the search mode; the first character of the replace string's expression when one is given (5226H).
5427
DEFS 1
The length of the line's text in the buffer with its 00H (5282H, 52C8H).
5428
DEFS 1
The change flag of the line: 00H, or not 00H once a match was replaced (5271H, 52D5H).
5429-5528
DEFS 256
The search string: its length, then up to 255 characters (5216H).
5529-5628
DEFS 256
The replace string: its length, then up to 255 characters (5229H).