DOSPLUS 3.5 for the Model III - CRUNCH/CMD Disassembled

Page Customization

Introduction/Summary

DOSPLUS 3.5 CRUNCH/CMD Disassembly - The BASIC Program Cruncher (Model III)

CRUNCH/CMD makes a BASIC program smaller: it copies a program file to a new file without the spaces and the remarks. It is run from the DOS command level as CRUNCH source destination (LINE); its heading reads CRUNCH - BASIC program cruncher - 1.7. It is a load module of 2 blocks, 431 bytes, at 5200H-53AEH with the transfer address 5200H, after the two comment records (the name CRUNCH and the copyright notice). CRUNCH/CMD is on the Model III master only.

The Parts of CRUNCH/CMD

AddressContents
5200H-5258HThe heading, the two file specifications, LINE, the files and the test for a BASIC program (5200H).
5259H-52B1HThe lines: the link, the number, empty lines and remarks (5259H).
52B2H-52EAHThe text of a line: spaces, DATA and strings (52B2H).
52EBH-5330HRemarks and colons, reading past spaces, reading and writing a byte (52EBH, 530DH, 5319H).
5331H-53AEHThe errors, the texts and the parameter table (5331H, 533BH, 53A6H).

How CRUNCH Works

FSPEC@ takes the source and the destination; a device (@) for either is the error Illegal filespec (5211H). PARAM@ takes LINE, whose value goes straight into the operand of an LD BC (528BH). The source is opened by OPEN@ and the destination by INIT@, both with a buffer of 256 bytes; the source must start with FFH, the mark of a tokenized BASIC program, else Incorrect file type is shown and CRUNCH ends through ABORT@ (524CH). The program is read and written a byte at a time through the ROM's 0013H and 001BH.

For each line (525CH) the link is read and dropped: the destination gets FFFFH for every link, for BASIC to rebuild when it loads the program, and the line number is kept. Outside strings and DATA statements every space is left out (530DH). A string in quotation marks, and DATA with everything after it on the line, are copied as they are (52BBH, 52D8H). REM (93H), and a colon before it, as in the apostrophe (stored :REM'), end the line: the remark is left out (52EFH). Colons in a row are written as one (52F6H). A line that is empty, or holds only a remark, is left out of the program; with LINE given (any value but 0) it is kept with its number and no text, so that a GOTO or GOSUB to it still finds it (528BH). At the link 0000H CRUNCH writes the end of the program, closes the destination and returns to the DOS; the source file is not closed (5266H).

A Line That Starts With a Colon

The test for remarks and colons writes the one colon it keeps as soon as it has passed the colons (5304H). For the first character of a line this happens before the link and the number of the line are written (5283H): a line whose text starts with a colon that is not followed by a remark (10 :PRINT, or a line of colons only) puts a colon byte in front of its link in the destination, or, when the line is then left out, in front of the next line's link, so that the destination is no longer a valid program. A line that starts with a remark after a colon, as the apostrophe, is not affected.

Differences from the Manual

The manual has no section on CRUNCH; it names the utility only in a JCL example (CRUNCH $FILE/BAS $FILE/CRN). Everything on this page comes from the bytes.

Variables

CRUNCH/CMD Variables

Address
Size
Contents
528CH-528DH
2 bytes
LINE
The operand of LD BC at 528BH, set by PARAM@ (5226H).
52A6H, 52ABH
1 byte each
Line number
The operands of LD A at 52A5H and 52AAH (527AH, 5280H).
53AFH-53CEH
32 bytes
Source FCB
The file control block of the source program (5208H).
53CFH-53EEH
32 bytes
Destination FCB
The file control block of the destination program (5217H).
53EFH-54EEH
256 bytes
Source buffer
Given to OPEN@ (5232H).
54EFH-55EEH
256 bytes
Destination buffer
Given to INIT@ (5240H).

Outside Routines

AddressContents
4467HSYS0/SYS: DSPLY@ (5204H, 5253H).
441CHSYS0/SYS: FSPEC@ (520BH, 521AH).
4454HSYS0/SYS: PARAM@ (5229H).
4424HSYS0/SYS: OPEN@ (5235H).
4420HSYS0/SYS: INIT@ (5243H).
4428HSYS0/SYS: CLOSE@ (5270H).
4409HSYS0/SYS: ERROR@ (5338H).
4030HSYS0/SYS: ABORT@ (5256H).
0013HROM: read a byte from a file (531DH).
001BHROM: write a byte to a file (5329H).

Disassembly

5200H - CRUNCH

CRUNCH/CMD's transfer address, entered from the DOS command level with Register Pair HL at the command line after the word CRUNCH: CRUNCH source destination (LINE). Both files are BASIC programs in the tokenized form of Disk BASIC (the first byte FFH). CRUNCH copies the source to the destination line by line without the spaces outside strings and DATA statements, without the remarks (REM and the apostrophe), and with repeated colons made one; a line that is empty or only a remark is left out, or kept with its number and no text when LINE is given. It ends at RET to the DOS after closing the destination.

5200
PUSH HL E5
Save Register Pair HL, the command line pointer after CRUNCH, to the top of the stack while the heading is shown.
5201
LD HL,533BH 21 3B 53
Point Register Pair HL to 533BH, CRUNCH's heading (CRUNCH - BASIC program cruncher - 1.7) 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
LD DE,53AFH 11 AF 53
Point Register Pair DE to 53AFH, the file control block of the source program.
520B
GOSUB to 441CH, FSPEC@, to move the first file specification at Register Pair HL into the file control block at Register Pair DE.
520E
If the NZ FLAG is set (no valid file specification), JUMP to 5331H for the error 2CH, Illegal filespec.
5211
LD A,(DE) 1A
Load Register A with the first character of the file control block at Register Pair DE.
5212
CP 40H FE 40
Compare Register A against 40H, the character @ that starts a device name.
5214
If the Z FLAG is set (a device, not a file), JUMP to 5331H for the error 2CH, Illegal filespec.
5217
LD DE,53CFH 11 CF 53
Point Register Pair DE to 53CFH, the file control block of the destination program.
521A
GOSUB to 441CH, FSPEC@, to move the second file specification at Register Pair HL into the file control block at Register Pair DE.
521D
If the NZ FLAG is set (no valid file specification), JUMP to 5331H for the error 2CH, Illegal filespec.
5220
LD A,(DE) 1A
Load Register A with the first character of the file control block at Register Pair DE.
5221
CP 40H FE 40
Compare Register A against 40H, the character @ that starts a device name.
5223
If the Z FLAG is set (a device, not a file), JUMP to 5331H for the error 2CH, Illegal filespec.
5226
LD DE,53A6H 11 A6 53
Point Register Pair DE to 53A6H, CRUNCH's table of parameters for PARAM@: LINE only.
5229
GOSUB to 4454H, PARAM@, to take the parameters at Register Pair HL into the words the table at Register Pair DE names.
522C
If the NZ FLAG is set (a parameter not in the table, or a bad value), JUMP to 5334H for the error 2EH, Invalid parameter.
522F
LD DE,53AFH 11 AF 53
Point Register Pair DE to 53AFH, the file control block of the source program, for OPEN@.
5232
LD HL,53EFH 21 EF 53
Point Register Pair HL to 53EFH, the 256 byte buffer of the source file.
5235
GOSUB to 4424H, OPEN@, to open the existing file of the file control block at Register Pair DE with the buffer at Register Pair HL.
5238
If the NZ FLAG is set (OPEN@ failed, its error code in Register A), JUMP to 5336H to post the error.
523B
LD B,00H 06 00
Load Register B with 00H, the logical record length 256 for INIT@.
523D
LD DE,53CFH 11 CF 53
Point Register Pair DE to 53CFH, the file control block of the destination program, for INIT@.
5240
LD HL,54EFH 21 EF 54
Point Register Pair HL to 54EFH, the 256 byte buffer of the destination file.
5243
GOSUB to 4420H, INIT@, to open or create the file of the file control block at Register Pair DE with the buffer at Register Pair HL and the record length in Register B.
5246
If the NZ FLAG is set (INIT@ failed, its error code in Register A), JUMP to 5336H to post the error.
5249
GOSUB to 5319H to read the first byte of the source into Register A.
524C
CP FFH FE FF
Compare Register A against FFH, the first byte of a tokenized BASIC program file.
524E
If the Z FLAG is set (a BASIC program), JUMP to 5259H to write the FFH and take the first line.
5250
LD HL,5392H 21 92 53
Point Register Pair HL to 5392H, the message Incorrect file type, ended by its 0DH.
5253
GOSUB to 4467H, DSPLY@, to display the message at Register Pair HL.
5256
JUMP to 4030H, ABORT@: the source is not a BASIC program, and the destination stays open and empty.

5259H - The Lines

5259H writes the byte in Register A: the FFH of the file, and after each line its ending 00H. Each line of the source starts with its link (two bytes) and its number (two bytes); a link of 0000H ends the program. The link is not copied: each line of the destination gets the link FFFFH, which BASIC rebuilds when it loads the program.

5259
GOSUB to 5325H to write the byte in Register A to the destination: the FFH, or the 00H that ends a line.
525C
GOSUB to 5319H to read the low byte of the next line's link from the source into Register A.
525F
LD C,A 4F
Load Register C with Register A, the low byte of the link.
5260
GOSUB to 5319H to read the high byte of the link from the source into Register A.
5263
OR C B1
OR Register A with Register C: the Z FLAG for a link of 0000H, the end of the program.
5264
If the NZ FLAG is set (another line), JUMP to 5277H to take its number.
5266
GOSUB to 5325H to write Register A (00H) to the destination, the low byte of the ending link 0000H.
5269
XOR A AF
Set Register A to 00H by XORing it with itself, for the high byte of the ending link.
526A
GOSUB to 5325H to write Register A (00H) to the destination: the program ends with the link 0000H.
526D
LD DE,53CFH 11 CF 53
Point Register Pair DE to 53CFH, the file control block of the destination program, for CLOSE@.
5270
GOSUB to 4428H, CLOSE@, to close the destination file at Register Pair DE; the source file is not closed.
5273
If the NZ FLAG is set (CLOSE@ failed, its error code in Register A), JUMP to 5336H to post the error.
5276
RET C9
RETurn to the DOS, which called CRUNCH from the command level: the program is crunched.
5277
GOSUB to 5319H to read the low byte of the line number from the source into Register A.
527A
LD (52A6H),A 32 A6 52
Store Register A, the low byte of the line number, into 52A6H, the operand of LD A at 52A5H.
527D
GOSUB to 5319H to read the high byte of the line number from the source into Register A.
5280
LD (52ABH),A 32 AB 52
Store Register A, the high byte of the line number, into 52ABH, the operand of LD A at 52AAH.
5283
GOSUB to 52EBH for the first character of the text: the C FLAG for an empty line, the Z FLAG for a remark, else Register A. A text that starts with a colon not followed by a remark gets its colon written by 5304H here, before the link and the number of the line.
5286
If the C FLAG is set (an empty line), JUMP to 528AH to leave the line out or keep it empty.
5288
If the NZ FLAG is set (the line has text), JUMP to 529AH to write the link and the number.
528A
PUSH AF F5
Save Register Pair AF, the flags of the empty line or the remark, to the top of the stack.
528B
LD BC,0000H 01 00 00
Load Register Pair BC with the value of LINE: the operand 528CH-528DH, which PARAM@ sets (0000H as loaded).
528E
LD A,B 78
Load Register A with Register B, the high byte of the value of LINE.
528F
OR C B1
OR Register A with Register C: the NZ FLAG when LINE was given with a value other than 0.
5290
If the NZ FLAG is set (LINE), JUMP to 529BH to keep the line with its number and no text.
5292
POP AF F1
Restore Register Pair AF, the flags of the empty line or the remark, from the top of the stack.
5293
If the C FLAG is set (the end of the line), JUMP to 525CH for the next line: this one is left out.
5295
GOSUB to 530DH to read the next character of the remark, past spaces; the C FLAG at the 00H that ends the line.
5298
JUMP to 5293H to test for the end of the line that is being passed over.
529A
PUSH AF F5
Save Register Pair AF, the first character of the text in Register A and its flags, to the top of the stack.
529B
LD A,FFH 3E FF
Load Register A with FFH, the low byte of the link FFFFH written for every line.
529D
GOSUB to 5325H to write Register A (FFH) to the destination, the low byte of the link.
52A0
LD A,FFH 3E FF
Load Register A with FFH, the high byte of the link FFFFH.
52A2
GOSUB to 5325H to write Register A (FFH) to the destination, the high byte of the link.
52A5
LD A,00H 3E 00
Load Register A with the low byte of the line number, the operand 52A6H set at 527AH (00H as loaded).
52A7
GOSUB to 5325H to write Register A, the low byte of the line number, to the destination.
52AA
LD A,00H 3E 00
Load Register A with the high byte of the line number, the operand 52ABH set at 5280H (00H as loaded).
52AC
GOSUB to 5325H to write Register A, the high byte of the line number, to the destination.
52AF
POP AF F1
Restore Register Pair AF, the first character of the text in Register A and its flags, from the top of the stack.
52B0
JUMP to 52B5H to deal with the character in Register A.

52B2H - The Text of a Line

The characters of a line, past spaces (530DH); 00H ends the line (written at 5259H). The DATA token (88H) and a string in quotation marks are copied as they are, spaces and all; a remark (REM, 93H, or a colon before it) ends the line; repeated colons are written as one.

52B2
GOSUB to 530DH to read the next character of the line into Register A, past spaces; the C FLAG at the 00H that ends it.
52B5
If the C FLAG is set (the end of the line, Register A = 00H), JUMP to 5259H to write the 00H and take the next line.
52B7
CP 88H FE 88
Compare Register A against 88H, the token of DATA.
52B9
If the NZ FLAG is set (not DATA), JUMP to 52C6H.
52BB
GOSUB to 5325H to write the character in Register A to the destination: DATA and the rest of the line as they are.
52BE
GOSUB to 5319H to read the next byte of the line into Register A, spaces included.
52C1
OR A B7
OR Register A against itself: the Z FLAG at the 00H that ends the line.
52C2
If the Z FLAG is set (the end of the line), JUMP to 5259H to write the 00H and take the next line.
52C4
JUMP to 52BBH to write the byte in Register A and read the next one.
52C6
GOSUB to 52EFH to test the character in Register A for a remark and for colons.
52C9
If the C FLAG is set (the end of the line after colons), JUMP to 5259H to write the 00H in Register A.
52CB
If the NZ FLAG is set (no remark), JUMP to 52D4H with the character in Register A.
52CD
GOSUB to 530DH to read the next character of the remark into Register A; the C FLAG at the 00H that ends the line.
52D0
If the NC FLAG is set (the remark goes on), LOOP BACK to 52CDH to pass its next character.
52D2
JUMP to 5259H to write the 00H in Register A that ends the line: the remark is left out.
52D4
CP 22H FE 22
Compare Register A against 22H, a quotation mark, the start of a string.
52D6
If the NZ FLAG is set (not a string), JUMP to 52E6H to write the character.
52D8
GOSUB to 5325H to write the character in Register A to the destination: the string as it is.
52DB
GOSUB to 5319H to read the next byte of the string into Register A, spaces included.
52DE
OR A B7
OR Register A against itself: the Z FLAG at the 00H that ends the line inside the string.
52DF
If the Z FLAG is set (the end of the line), JUMP to 5259H to write the 00H and take the next line.
52E2
CP 22H FE 22
Compare Register A against 22H, the quotation mark that ends the string.
52E4
If the NZ FLAG is set (the string goes on), LOOP BACK to 52D8H to write the byte and read the next.
52E6
GOSUB to 5325H to write the character in Register A to the destination: a character, a token or the closing quotation mark.
52E9
JUMP to 52B2H for the next character of the line past spaces.

52EBH - Remarks and Colons

52EBH reads the next character past spaces first; 52EFH tests the character in Register A. Returns the C FLAG at the end of the line (Register A = 00H), the Z FLAG for a remark (REM, 93H, also after a colon, as in the apostrophe :REM'), else the NZ FLAG with a character in Register A. A colon and the colons right after it are written as one colon (5304H) before the character that follows them.

52EB
GOSUB to 530DH to read the next character into Register A, past spaces; the C FLAG at the 00H that ends the line.
52EE
RET C D8
If the C FLAG is set (the end of the line), RETurn to the caller with Register A = 00H.
52EF
CP 93H FE 93
Compare Register A against 93H, the token of REM: the Z FLAG for a remark.
52F1
RET Z C8
If the Z FLAG is set (REM), RETurn to the caller with the Z FLAG and no C FLAG.
52F2
CP 3AH FE 3A
Compare Register A against 3AH, a colon, which ends a statement.
52F4
If the NZ FLAG is set (not a colon), JUMP to 530BH to return the character in Register A with the NZ FLAG.
52F6
GOSUB to 530DH to read the character after the colon into Register A, past spaces; the C FLAG at the 00H.
52F9
If the C FLAG is set (the end of the line), JUMP to 5303H to write one colon and return the C FLAG.
52FB
CP 3AH FE 3A
Compare Register A against 3AH: another colon right after the first.
52FD
If the Z FLAG is set (a colon), LOOP BACK to 52F6H: colons in a row are taken as one.
52FF
CP 93H FE 93
Compare Register A against 93H, the token of REM after the colon, as in the apostrophe.
5301
RET Z C8
If the Z FLAG is set (a remark), RETurn to the caller with the Z FLAG: the colon is left out with the remark.
5302
OR A B7
OR Register A against itself, to clear the C FLAG and set the NZ FLAG for the character in Register A.
5303
PUSH AF F5
Save Register Pair AF, the character after the colons in Register A and its flags, to the top of the stack.
5304
LD A,3AH 3E 3A
Load Register A with 3AH, the one colon written for the colons.
5306
GOSUB to 5325H to write the colon in Register A to the destination.
5309
POP AF F1
Restore Register Pair AF, the character after the colons in Register A and its flags, from the top of the stack.
530A
RET C9
RETurn to the caller with the character after the colons in Register A, or the C FLAG at the end of the line.
530B
OR A B7
OR Register A against itself, to clear the C FLAG and set the NZ FLAG for the character in Register A.
530C
RET C9
RETurn to the caller with the character in Register A and the NZ FLAG.

530DH - Read Past Spaces

Reads the bytes of the source until one is not a space: Register A returns it, with the C FLAG and the Z FLAG for the 00H that ends a line, else the NZ FLAG and no C FLAG.

530D
GOSUB to 5319H to read the next byte of the source into Register A.
5310
OR A B7
OR Register A against itself: the Z FLAG for the 00H that ends a line; the C FLAG is cleared.
5311
SCF 37
Set the C FLAG (SCF), the mark of the end of the line for a 00H in Register A.
5312
RET Z C8
If the Z FLAG is set (00H), RETurn to the caller with the C FLAG and the Z FLAG.
5313
CP 20H FE 20
Compare Register A against 20H, a space, which CRUNCH leaves out of the line.
5315
If the Z FLAG is set (a space), LOOP BACK to 530DH to read the next byte: spaces are left out.
5317
OR A B7
OR Register A against itself, to clear the C FLAG left by the compare; the NZ FLAG for the character in Register A.
5318
RET C9
RETurn to the caller with the character in Register A, the NZ FLAG and no C FLAG.

5319H - Read and Write a Byte

5319H reads a byte of the source through the ROM's 0013H with the file control block at 53AFH, 5325H writes Register A to the destination through 001BH with the file control block at 53CFH; an error goes to 5336H.

5319
PUSH DE D5
Save Register Pair DE to the top of the stack while the byte is read.
531A
LD DE,53AFH 11 AF 53
Point Register Pair DE to 53AFH, the file control block of the source program.
531D
GOSUB to 0013H, the ROM's input of a byte into Register A from the device or file of the block at Register Pair DE.
5320
POP DE D1
Restore Register Pair DE from the top of the stack, as it was before the read.
5321
If the NZ FLAG is set (the read failed, its error code in Register A), JUMP to 5336H to post the error.
5324
RET C9
RETurn to the caller with the byte of the source in Register A.
5325
PUSH DE D5
Save Register Pair DE to the top of the stack while the byte is written.
5326
LD DE,53CFH 11 CF 53
Point Register Pair DE to 53CFH, the file control block of the destination program.
5329
GOSUB to 001BH, the ROM's output of the byte in Register A to the device or file of the block at Register Pair DE.
532C
POP DE D1
Restore Register Pair DE from the top of the stack, as it was before the write.
532D
If the NZ FLAG is set (the write failed, its error code in Register A), JUMP to 5336H to post the error.
5330
RET C9
RETurn to the caller once the byte in Register A is written to the destination.

5331H - The Errors

5331H the error 2CH, Illegal filespec; 5334H, inside the LD BC at 5333H, the error 2EH, Invalid parameter; 5336H any error code in Register A. Each is posted with bit 6 set, so ERROR@ shows the message without its frame, and with bit 7 clear, so ERROR@ ends through ABORT@.

5331
LD A,2CH 3E 2C
Load Register A with 2CH, the error code of Illegal filespec, and fall into the LD BC below.
5333
LD BC,2E3EH 01 3E 2E
5334H enters inside this LD BC,2E3EH: its bytes 3EH 2EH read as LD A,2EH, the code of Invalid parameter; from above it only loads Register Pair BC.
5336
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.
5338
JUMP to 4409H, ERROR@, with the error code in Register A; with bit 7 clear ERROR@ does not return but ends through ABORT@.
533B-5391
DEFM "CRUNCH - BASIC program cruncher - 1.7" / DEFB 0AH / DEFM "(c) Copyright 1983, Micro-Systems Software Inc." / DEFB 0AH,0DH 43 52 55 4E 43 48 20 2D 20 42 41 53 49 43 20 70 72 6F 67 72 61 6D 20 63 72 75 6E 63 68 65 72 20 2D 20 31 2E 37 0A 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 0A 0D
The heading (5201H): CRUNCH - BASIC program cruncher - 1.7, a line feed, the copyright line, a line feed and the 0DH at which DSPLY@ stops.
5392-53A5
DEFM "Incorrect file type" / DEFB 0DH 49 6E 63 6F 72 72 65 63 74 20 66 69 6C 65 20 74 79 70 65 0D
The message for a source whose first byte is not FFH (5250H), ended by the 0DH at which DSPLY@ stops.
53A6-53AB
DEFM "LINE " 4C 49 4E 45 20 20
The parameter table of PARAM@ (5226H): the name LINE, padded to 6 characters; L is enough on the command line.
53AC-53AD
DEFW 528CH 8C 52
The word where the value of LINE goes: 528CH, the operand of LD BC at 528BH.
53AE
DEFB 00H 00
The 00H after the one entry that ends the parameter table of PARAM@.
53AF-53CE
DEFS 32
The file control block of the source program (5208H, FSPEC@, OPEN@ and the reads at 5319H).
53CF-53EE
DEFS 32
The file control block of the destination program (5217H, FSPEC@, INIT@, the writes at 5325H and CLOSE@).
53EF-54EE
DEFS 256
The 256 byte buffer of the source file, given to OPEN@ in Register Pair HL at 5232H.
54EF-55EE
DEFS 256
The 256 byte buffer of the destination file, given to INIT@ in Register Pair HL at 5240H.