DOSPLUS 3.5 for the Model I - O/CMD Disassembled

Page Customization

Introduction/Summary

DOSPLUS 3.5 O/CMD Disassembly - CMD"O", the Sort of BASIC Arrays (Model I)

O/CMD is the array sort of Extended Disk BASIC, CMD"O", whose heading names it SORT - BASIC Multi key/array sort - 1.7. It is a load module of 4 blocks, 835 bytes, at 5200H-554FH (54E8H-54F4H, its variables, are not in the file), with the transfer address 5200H, after the two comment records (the name O 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.

It runs only from Extended Disk BASIC: BASIC/CMD's CMD (5C48H) treats the one letter O, which is none of its own options, as a DOS command for CMNDI@, so the DOS loads O/CMD at 5200H and calls it. O takes BASIC's text pointer off the stack under CMNDI@'s return address (5212H) and, when the sort is done, returns straight into the ROM's statement loop (528DH), so the statement goes on after it. Run from the DOS command level it only shows its heading. TBASIC cannot run it, since its CMD runs no DOS commands.

The Statement

CMD"O",count,[+|-]primary(start)[+key|-key...][,tag,...]. The count must not be 0; the primary key array carries the subscript of the first element to sort, which holds for every array named; up to nine more key arrays follow, each after + (ascending) or - (descending), and then up to twenty tag arrays, each after a comma. A key decides the order of two elements when the keys before it are equal; tag arrays are moved with the keys and never compared. Every array must already exist (O does not dimension one) with one dimension and with the elements start to start + count - 1 (Illegal function call otherwise). The type of an array is its suffix (% $ ! #) or the DEF type of its first letter, as BASIC takes it (535EH).

The Parts of O/CMD

AddressContents
5200H-5279HThe start: the caller test, the count, the primary key, the other keys and the tags (5200H, 524EH, 5267H).
527AH-5323HThe Shell sort (527AH) and its compare and exchange (52B8H).
5324H-53EBHTaking an array: its name and type, its search in the array area, its entry in the table (5324H, 532FH, 535EH).
53ECH-548FHThe address of an element (53ECH, 53FDH) and the compare of two elements by type (5423H).
5490H-554FHThe heading, the variables and the table of the arrays (5490H).

The Sort

The sort is a Shell sort with the gaps n/2, n/4 and so on down to 1 (527AH). For each gap every element is compared with the one a gap after it; when they are out of order they are exchanged and the compare goes back by a gap. Two elements are compared by type (5423H): integers, single and double precision by the ROM's compare routines, strings character by character, a shorter string that is the start of the other being the lesser. An exchange swaps the elements of the deciding key array and of every array after it in the table, tags included; a string array has its descriptors swapped, not its text (52C2H). Keys before the deciding one are equal and are not swapped. Since a Shell sort is not stable, elements equal on every key may change their order.

Differences from the Manual

The manual (Disk BASIC, page 5-51) describes the statement as the bytes take it. What it does not say: at most ten key arrays (the primary one and nine more) and twenty tag arrays are taken, more being a Syntax error; the arrays must exist and have one dimension; the order of equal elements is not kept. One test in the bytes does not work as meant: an array named twice should be Illegal function call, but the test compares both bytes of each stored address with the high byte of the new one (532FH), so in practice an array named twice is accepted, and it is then exchanged twice, which undoes the move for that array.

Variables

O/CMD Variables

Address
Size
Contents
54E8H
1 byte
Type
The type of the array being looked for (53A5H).
54E9H-54EAH
2 bytes
Count
The number of elements to sort (5222H).
54EBH-54ECH
2 bytes
Start
The subscript of the first element to sort, for every array (5241H).
54EDH-54EEH
2 bytes
Limit
The count less the gap (5297H).
54EFH-54F0H
2 bytes
Index j
The compare's index (52A2H).
54F1H-54F2H
2 bytes
Gap
The gap of the Shell sort (5282H).
54F3H-54F4H
2 bytes
Index i
The pass's index (529CH).
54F5H-554FH
91 bytes
Array table
Thirty entries of flags and an array entry address, and an end byte 00H (54F5H).

Outside Routines

AddressContents
4467HSYS0/SYS: DSPLY@, the heading (520CH).
402DHSYS0/SYS: EXIT@ (520FH).
1E46HROM: evaluate a positive integer (5215H, 523CH).
1E3DHROM: test for a letter (535FH).
0A39HROM: compare two integers (545EH).
0A0CHROM: compare two single precision numbers (5450H).
0A78HROM: compare two double precision numbers, reversed (5440H).
1E4AHROM: Illegal function call (521AH and others).
1997HROM: Syntax error (525EH, 526EH, 5362H).

Disassembly

5200H - CMD"O"

O/CMD's transfer address. O sorts BASIC arrays, run from Extended Disk BASIC as CMD"O",count,[+|-]primary(start)[+key|-key...][,tag,...]: BASIC/CMD's CMD passes the one letter O to CMNDI@ as a DOS command, and the DOS loads O/CMD at 5200H and calls it. From the DOS command level (return address 402DH) it only shows its heading. From BASIC it takes the count (54E9H), the primary key array and its start subscript (54EBH), up to nine more key arrays and up to twenty tag arrays into its table (54F5H), sorts them (527AH), and returns straight into the ROM's statement loop with Register Pair HL at the end of the statement, past CMNDI@.

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 O 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,5490H 21 90 54
Point Register Pair HL to 5490H, O'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: O sorts only from BASIC.
5212
POP HL E1
Restore Register Pair HL from the top of the stack: BASIC's text pointer after the string "O"; the ROM's return into its statement loop is now on the top of the stack.
5213
RST 08H => 2CH CF 2C
RST 08H: the next character of the text at Register Pair HL must be 2CH, the comma before the count, or the ROM shows a Syntax error.
5215
GOSUB to 1E46H, the ROM's evaluation of a positive integer at Register Pair HL (else Illegal function call): Register Pair DE returns the count.
5218
LD A,D 7A
Load Register A with Register D, the high byte of the count.
5219
OR E B3
OR Register A with Register E, the low byte: the Z FLAG for a count of 0.
521A
If the Z FLAG is set (nothing to sort), JUMP to 1E4AH, the ROM's Illegal function call error.
521D
RST 08H => 2CH CF 2C
RST 08H: the next character of the text at Register Pair HL must be 2CH, the comma before the primary key array; Register A returns the character after it, the Z FLAG at the end of the statement.
521F
If the Z FLAG is set (no array), JUMP to 1E4AH, the ROM's Illegal function call error.
5222
LD (54E9H),DE ED 53 E9 54
Store Register Pair DE, the count, into 54E9H-54EAH.
5226
LD B,03H 06 03
Load Register B with 03H, the flags of a key array: bit 0 in use, bit 1 a key; bit 7 will be set for a descending key.
5228
CP CDH FE CD
Compare Register A against CDH, the token of the plus sign: an ascending key, as without a sign.
522A
If the Z FLAG is set (+), JUMP to 5232H to pass over the sign.
522C
CP CEH FE CE
Compare Register A against CEH, the token of the minus sign: a descending key.
522E
If the NZ FLAG is set (no sign), JUMP to 5233H: Register A is the first letter of the array's name.
5230
SET 7,B CB F8
SET bit 7 of Register B: the primary key array is sorted in descending order.
5232
RST 10H D7
RST 10H: increment Register Pair HL and load Register A with the character after the sign.
5233
PUSH BC C5
Save Register Pair BC, the flags in Register B, to the top of the stack.
5234
GOSUB to 535EH to take the array's name at Register Pair HL and find the array: Register Pair DE its entry, Register Pair BC its number of elements.
5237
PUSH BC C5
Save Register Pair BC, the number of elements, to the top of the stack.
5238
PUSH DE D5
Save Register Pair DE, the array's entry, to the top of the stack.
5239
RST 10H D7
RST 10H: increment Register Pair HL and load Register A with the character after the name.
523A
RST 08H => 28H CF 28
RST 08H: the next character of the text at Register Pair HL must be 28H, the ( of the start subscript, or the ROM shows a Syntax error.
523C
GOSUB to 1E46H, the ROM's evaluation of a positive integer: Register Pair DE returns the subscript of the first element to sort.
523F
RST 08H => 29H CF 29
RST 08H: the next character of the text at Register Pair HL must be 29H, the ) after the subscript.
5241
LD (54EBH),DE ED 53 EB 54
Store Register Pair DE, the start subscript, into 54EBH-54ECH: it holds for every array named.
5245
POP DE D1
Restore Register Pair DE, the array's entry, from the top of the stack.
5246
POP BC C1
Restore Register Pair BC, the number of elements, from the top of the stack.
5247
POP AF F1
Restore Register Pair AF with the flags saved at 5233H: Register A = the flags of the primary key.
5248
GOSUB to 532FH to check the range of the array and enter it into the table at 54F5H.
524B
LD C,0AH 0E 0A
Load Register C with 0AH, the count of the key arrays allowed: nine more after the primary one.
524D
DEC HL 2B
DECrement Register Pair HL by 1, so that the RST 10H below reads the character after the ) again.

524EH - More Key Arrays

Each further key array is +name or -name (no subscript: the start subscript of the primary one holds for all). At most nine more are taken (Register C), then a comma starts the tag arrays.

524E
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.
524F
If the Z FLAG is set (the end of the statement), JUMP to 527AH to sort.
5251
LD B,03H 06 03
Load Register B with 03H, the flags of an ascending key array.
5253
CP CDH FE CD
Compare Register A against CDH, the token of the plus sign: another ascending key array.
5255
If the Z FLAG is set (+), JUMP to 525DH with the flags of an ascending key.
5257
CP CEH FE CE
Compare Register A against CEH, the token of the minus sign: another descending key array.
5259
If the NZ FLAG is set (neither sign), JUMP to 5267H: the tag arrays start.
525B
SET 7,B CB F8
SET bit 7 of Register B: the key array is sorted in descending order.
525D
DEC C 0D
DECrement Register C by 1, the count of the key arrays.
525E
If the Z FLAG is set (a tenth key array after the primary one), JUMP to 1997H, the ROM's Syntax error.
5261
RST 10H D7
RST 10H: increment Register Pair HL and load Register A with the first letter of the array's name after the sign.
5262
GOSUB to 5324H to take the array's name, find the array and enter it into the table with the flags in Register B.
5265
JUMP back to 524EH for the next key array or the end of the keys.

5267H - The Tag Arrays

Each tag array follows a comma and moves with the key arrays but is not compared. At most twenty are taken (Register C).

5267
LD C,15H 0E 15
Load Register C with 15H, the count of the tag arrays allowed: twenty.
5269
DEC HL 2B
DECrement Register Pair HL by 1, so that the RST 10H below reads the comma again.
526A
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.
526B
If the Z FLAG is set (the end of the statement), JUMP to 527AH to sort.
526D
DEC C 0D
DECrement Register C by 1, the count of the tag arrays.
526E
If the Z FLAG is set (a twenty first tag array), JUMP to 1997H, the ROM's Syntax error.
5271
RST 08H => 2CH CF 2C
RST 08H: the next character of the text at Register Pair HL must be 2CH, the comma before a tag array; Register A returns the first letter of its name.
5273
LD B,01H 06 01
Load Register B with 01H, the flags of a tag array: bit 0 in use, bit 1 clear (not a key).
5275
GOSUB to 5324H to take the array's name, find the array and enter it into the table with the flags in Register B.
5278
JUMP back to 526AH for the next tag array or the end of the statement.

527AH - The Sort

A Shell sort with gaps n/2, n/4 and so on down to 1 (n the count at 54E9H): for each gap, each element i from 0 to n-gap-1 is compared with the one a gap after it and, while they are out of order, the two are exchanged and the compare goes back by one gap (54EFH). The elements are those of the start subscript (54EBH) plus i. The compare uses the key arrays in their order: a key whose two elements are equal passes the decision to the next key; when all keys are equal nothing moves. An exchange swaps the elements of the deciding key array and of every array after it in the table, the tag arrays included.

527A
PUSH HL E5
Save Register Pair HL, the text pointer at the end of the statement, to the top of the stack.
527B
LD HL,(54E9H) 2A E9 54
Load Register Pair HL with the count from 54E9H-54EAH.
527E
SRL H CB 3C
Shift Register H right by one bit (SRL), the high byte of the count.
5280
RR L CB 1D
Rotate Register L right through the C FLAG (RR): Register Pair HL = the count divided by 2, the first gap.
5282
LD (54F1H),HL 22 F1 54
Store Register Pair HL, the gap, into 54F1H-54F2H.
5285
LD HL,(54F1H) 2A F1 54
Load Register Pair HL with the gap from 54F1H-54F2H.
5288
LD A,H 7C
Load Register A with Register H, the high byte of the gap.
5289
OR L B5
OR Register A with Register L: the Z FLAG for a gap of 0, the end of the sort.
528A
If the NZ FLAG is set (a gap), JUMP to 528EH for a pass with this gap.
528C
POP HL E1
Restore Register Pair HL, the text pointer at the end of the statement, from the top of the stack.
528D
RET C9
RETurn into the ROM's statement loop (the return address left on the stack at 5212H), with Register Pair HL at the end of the statement.
528E
LD HL,(54E9H) 2A E9 54
Load Register Pair HL with the count from 54E9H-54EAH.
5291
LD DE,(54F1H) ED 5B F1 54
Load Register Pair DE with the gap from 54F1H-54F2H.
5295
SBC HL,DE ED 52
SUBtract Register Pair DE, the gap, from Register Pair HL with the C FLAG (clear after the OR): the count less the gap.
5297
LD (54EDH),HL 22 ED 54
Store Register Pair HL, the count less the gap, into 54EDH-54EEH: the limit of Register Pair HL's index i.
529A
SBC HL,HL ED 62
SUBtract Register Pair HL with the C FLAG (clear) from itself: Register Pair HL = 0000H.
529C
LD (54F3H),HL 22 F3 54
Store Register Pair HL (0000H) into 54F3H-54F4H: the index i starts at 0.
529F
LD HL,(54F3H) 2A F3 54
Load Register Pair HL with the index i from 54F3H-54F4H.
52A2
LD (54EFH),HL 22 EF 54
Store Register Pair HL, the index i, into 54EFH-54F0H: the index j of the compare starts at i.
52A5
LD IX,54F5H DD 21 F5 54
Point Index Register IX to 54F5H, the first entry of the table of arrays: the primary key.
52A9
LD DE,(54EFH) ED 5B EF 54
Load Register Pair DE with the index j from 54EFH-54F0H.
52AD
LD HL,(54EBH) 2A EB 54
Load Register Pair HL with the start subscript from 54EBH-54ECH.
52B0
ADD HL,DE 19
ADD Register Pair DE, the index j, to Register Pair HL: the subscript of the first element.
52B1
LD DE,(54F1H) ED 5B F1 54
Load Register Pair DE with the gap from 54F1H-54F2H.
52B5
GOSUB to 53ECH for the array of Index Register IX: Register Pair HL the address of the first element, Register Pair DE that of the element a gap after it, Register B the element's length, Register C the flags; Index Register IX moves to the next entry.

52B8H - Compare and Exchange

Compares the two elements of the current key (5423H). Equal: the next key array decides (52F2H). Out of order (01H in an ascending key, FFH in a descending one): the elements of this array and of every array after it are exchanged, and the compare goes back one gap. In order: the next element i.

52B8
GOSUB to 5423H to compare the element at Register Pair HL with the one at Register Pair DE: Register A returns 00H equal, 01H when the first is greater, FFH when it is less.
52BB
OR A B7
OR Register A against itself: the Z FLAG when the two elements are equal.
52BC
If the Z FLAG is set (equal), JUMP to 52F2H: the next key array decides.
52BE
XOR C A9
XOR Register A with Register C, the flags of the key: bit 7 of the result is set for FFH in an ascending key or 01H in a descending one.
52BF
If the M FLAG is set (the two are in order), JUMP to 5309H for the next element i.
52C2
LD A,(DE) 1A
Load Register A with the byte of the second element at Register Pair DE.
52C3
LD C,(HL) 4E
Load Register C with the byte of the first element at Register Pair HL.
52C4
LD (HL),A 77
Store Register A, the second element's byte, at Register Pair HL.
52C5
LD A,C 79
Load Register A with Register C, the first element's byte.
52C6
LD (DE),A 12
Store Register A at Register Pair DE: the two bytes are exchanged.
52C7
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the first element.
52C8
INC DE 13
INCrement Register Pair DE by 1, to the next byte of the second element.
52C9
DECrement Register B and LOOP back to 52C2H for the rest of the element (2, 3, 4 or 8 bytes; a string's descriptor is exchanged, not its text).
52CB
BIT 0,(IX+00H) DD CB 00 46
Test bit 0 of the next table entry at Index Register IX+00H: the NZ FLAG when another array follows.
52CF
If the Z FLAG is set (the end of the table), JUMP to 52E2H.
52D1
LD DE,(54EFH) ED 5B EF 54
Load Register Pair DE with the index j from 54EFH-54F0H.
52D5
LD HL,(54EBH) 2A EB 54
Load Register Pair HL with the start subscript from 54EBH-54ECH.
52D8
ADD HL,DE 19
ADD Register Pair DE, the index j, to Register Pair HL: the subscript of the first element.
52D9
LD DE,(54F1H) ED 5B F1 54
Load Register Pair DE with the gap from 54F1H-54F2H.
52DD
GOSUB to 53ECH for the next array of Index Register IX: Register Pair HL and Register Pair DE the two elements, Register B their length.
52E0
JUMP back to 52C2H to exchange the two elements of that array.
52E2
LD HL,(54EFH) 2A EF 54
Load Register Pair HL with the index j from 54EFH-54F0H.
52E5
LD DE,(54F1H) ED 5B F1 54
Load Register Pair DE with the gap from 54F1H-54F2H.
52E9
SBC HL,DE ED 52
SUBtract Register Pair DE, the gap, from Register Pair HL with the C FLAG (clear after the OR above): the index one gap back; the C FLAG when j is less than the gap.
52EB
If the C FLAG is set (no element a gap back), JUMP to 5309H for the next element i.
52ED
LD (54EFH),HL 22 EF 54
Store Register Pair HL, the index one gap back, into 54EFH-54F0H as the new j.
52F0
JUMP back to 52A5H to compare again at the new index j, one gap back.
52F2
BIT 1,(IX+00H) DD CB 00 4E
Test bit 1 of the next table entry at Index Register IX+00H: the NZ FLAG when it is another key array.
52F6
If the Z FLAG is set (no more keys: the elements are equal), JUMP to 5309H for the next element i.
52F8
LD DE,(54EFH) ED 5B EF 54
Load Register Pair DE with the index j from 54EFH-54F0H.
52FC
LD HL,(54EBH) 2A EB 54
Load Register Pair HL with the start subscript from 54EBH-54ECH.
52FF
ADD HL,DE 19
ADD Register Pair DE, the index j, to Register Pair HL: the subscript of the first element.
5300
LD DE,(54F1H) ED 5B F1 54
Load Register Pair DE with the gap from 54F1H-54F2H.
5304
GOSUB to 53ECH for the next key array of Index Register IX: Register Pair HL and Register Pair DE its two elements.
5307
JUMP back to 52B8H to compare the two elements of the next key array.
5309
LD HL,(54F3H) 2A F3 54
Load Register Pair HL with the index i from 54F3H-54F4H.
530C
INC HL 23
INCrement Register Pair HL by 1, to the next element i.
530D
LD (54F3H),HL 22 F3 54
Store Register Pair HL, the index i, into 54F3H-54F4H.
5310
LD DE,(54EDH) ED 5B ED 54
Load Register Pair DE with the limit, the count less the gap, from 54EDH-54EEH.
5314
RST 18H DF
RST 18H: compare Register Pair HL, the index i, with Register Pair DE, the limit: the C FLAG while i is below it.
5315
If the C FLAG is set (more elements for this gap), JUMP to 529FH.
5317
LD HL,(54F1H) 2A F1 54
Load Register Pair HL with the gap from 54F1H-54F2H.
531A
SRL H CB 3C
Shift Register H right by one bit (SRL), the high byte of the gap.
531C
RR L CB 1D
Rotate Register L right through the C FLAG (RR): Register Pair HL = half the gap.
531E
LD (54F1H),HL 22 F1 54
Store Register Pair HL, the new gap, into 54F1H-54F2H.
5321
JUMP to 5285H for the pass with the new gap, or the end of the sort at 0.

5324H - Another Array

Takes the name of a key or tag array at Register Pair HL, finds the array (535EH) and enters it into the table with the flags in Register B (532FH). Register C, the caller's count, is kept.

5324
PUSH BC C5
Save Register Pair BC, the flags in Register B and the count in Register C, to the top of the stack.
5325
PUSH BC C5
Save Register Pair BC to the top of the stack again, for the flags.
5326
GOSUB to 535EH to take the array's name at Register Pair HL and find the array: Register Pair DE its entry, Register Pair BC its number of elements.
5329
POP AF F1
Restore Register Pair AF with the saved Register Pair BC: Register A = the flags.
532A
GOSUB to 532FH to check the range of the array and enter it into the table.
532D
POP BC C1
Restore Register Pair BC, the flags and the count, from the top of the stack.
532E
RET C9
RETurn to the caller with its count in Register C.

532FH - Enter an Array

Register A the flags, Register Pair BC the number of elements, Register Pair DE the array's entry. The count plus the start subscript must not pass the number of elements (else Illegal function call). The array is put into the first free entry of the table at 54F5H (three bytes: the flags, the entry's address). The test meant to refuse an array named twice compares both bytes of each entry's address with Register D only, so it refuses an array only when the low and high bytes of the old entry both equal the high byte of the new one; an array named twice is in practice accepted.

532F
PUSH HL E5
Save Register Pair HL, the text pointer, to the top of the stack.
5330
PUSH AF F5
Save Register Pair AF, the flags in Register A, to the top of the stack.
5331
PUSH DE D5
Save Register Pair DE, the array's entry, to the top of the stack.
5332
LD HL,(54E9H) 2A E9 54
Load Register Pair HL with the count from 54E9H-54EAH.
5335
LD DE,(54EBH) ED 5B EB 54
Load Register Pair DE with the start subscript from 54EBH-54ECH.
5339
ADD HL,DE 19
ADD Register Pair DE, the start subscript, to Register Pair HL: the count plus the start.
533A
SCF 37
Set the C FLAG, so that the SBC below also subtracts 1: start + count - 1.
533B
SBC HL,BC ED 42
SUBtract Register Pair BC, the number of elements, from Register Pair HL with the C FLAG: the NC FLAG when the last element to sort (start + count - 1) is not below the number of elements.
533D
If the NC FLAG is set (past the end of the array), JUMP to 1E4AH, the ROM's Illegal function call error.
5340
POP DE D1
Restore Register Pair DE, the array's entry, from the top of the stack.
5341
POP BC C1
Restore Register Pair BC with the saved Register Pair AF: Register B = the flags.
5342
LD HL,54F5H 21 F5 54
Point Register Pair HL to 54F5H, the table of the arrays.
5345
BIT 0,(HL) CB 46
Test bit 0 of the entry's flags at Register Pair HL: the Z FLAG for a free entry.
5347
If the Z FLAG is set (free), JUMP to 5357H to fill it.
5349
INC HL 23
INCrement Register Pair HL by 1, to the low byte of the entry's array address.
534A
LD A,(HL) 7E
Load Register A with the low byte of the address at Register Pair HL.
534B
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
534C
CP D BA
Compare Register A, the low byte, with Register D, the high byte of the new array's entry.
534D
If the NZ FLAG is set, JUMP to 5354H to the next entry.
534F
LD A,(HL) 7E
Load Register A with the high byte of the address at Register Pair HL.
5350
CP D BA
Compare Register A with Register D, the high byte of the new array's entry.
5351
If the Z FLAG is set, JUMP to 1E4AH, the ROM's Illegal function call error, meant for an array named twice.
5354
INC HL 23
INCrement Register Pair HL by 1, to the flags of the next entry.
5355
LOOP back to 5345H to test the next entry of the table.
5357
LD (HL),B 70
Store Register B, the flags, at Register Pair HL in the free entry.
5358
INC HL 23
INCrement Register Pair HL by 1, to the low byte of the address.
5359
LD (HL),E 73
Store Register E, the low byte of the array's entry, at Register Pair HL.
535A
INC HL 23
INCrement Register Pair HL by 1, to the high byte of the address.
535B
LD (HL),D 72
Store Register D, the high byte of the array's entry, at Register Pair HL.
535C
POP HL E1
Restore Register Pair HL, the text pointer, from the top of the stack.
535D
RET C9
RETurn to the caller with Register Pair HL the text pointer.

535EH - Find an Array

Takes a variable name at Register Pair HL (a letter, then letters and digits, of which the first two count) with its type: a suffix %, $, ! or #, else the type of its first letter from the ROM's DEF table at 4101H. Then the array of that name and type is looked for from ARYTAB (40FBH) to STREND (40FDH): it must exist (Illegal function call) and have one dimension. Returns Register Pair DE = the array's entry, Register Pair BC = its number of elements, Register Pair HL at the last character of the name or at its suffix.

535E
LD B,(HL) 46
Load Register B with the first letter of the name at Register Pair HL.
535F
GOSUB to 1E3DH, the ROM's test of a letter at Register Pair HL: the C FLAG when it is not one.
5362
If the C FLAG is set (not a letter), JUMP to 1997H, the ROM's Syntax error.
5365
LD C,00H 0E 00
Load Register C with 00H, the second character of a one letter name.
5367
RST 10H D7
RST 10H: increment Register Pair HL and load Register A with the next character, with the C FLAG for a digit.
5368
If the C FLAG is set (a digit), JUMP to 536FH: the second character of the name.
536A
GOSUB to 1E3DH, the ROM's test of a letter at Register Pair HL: the C FLAG when it is not one.
536D
If the C FLAG is set (the name has one letter), JUMP to 5378H with the character after it in Register A.
536F
LD C,A 4F
Load Register C with Register A, the second character of the name.
5370
RST 10H D7
RST 10H: increment Register Pair HL and load Register A with the next character, with the C FLAG for a digit.
5371
If the C FLAG is set (a digit), LOOP BACK to 5370H: the rest of the name does not count.
5373
GOSUB to 1E3DH, the ROM's test of a letter at Register Pair HL: the NC FLAG for a letter.
5376
If the NC FLAG is set (a letter), LOOP BACK to 5370H for the rest of the name.
5378
LD DE,539FH 11 9F 53
Load Register Pair DE with 539FH, where the search for the array goes on.
537B
PUSH DE D5
Save Register Pair DE (539FH) to the top of the stack, so that each RET below goes there with the type in Register D.
537C
LD D,02H 16 02
Load Register D with 02H, the type of an integer.
537E
CP 25H FE 25
Compare Register A against 25H, the suffix % of an integer array.
5380
RET Z C8
If the Z FLAG is set (%), RETurn to 539FH with Register D = 02H.
5381
INC D 14
INCrement Register D by 1, to 03H, the type of a string.
5382
CP 24H FE 24
Compare Register A against 24H, the suffix $ of a string array.
5384
RET Z C8
If the Z FLAG is set ($), RETurn to 539FH with Register D = 03H.
5385
INC D 14
INCrement Register D by 1, to 04H, the type of a single precision number.
5386
CP 21H FE 21
Compare Register A against 21H, the suffix ! of a single precision array.
5388
RET Z C8
If the Z FLAG is set (!), RETurn to 539FH with Register D = 04H.
5389
LD D,08H 16 08
Load Register D with 08H, the type of a double precision number.
538B
CP 23H FE 23
Compare Register A against 23H, the suffix # of a double precision array.
538D
RET Z C8
If the Z FLAG is set (#), RETurn to 539FH with Register D = 08H.
538E
LD A,B 78
Load Register A with Register B, the first letter of the name.
538F
SUB 41H D6 41
SUBtract 41H, the letter A, from Register A: the letter's place, 0 to 25.
5391
AND 7FH E6 7F
AND Register A with 7FH, keeping the place within the table.
5393
LD E,A 5F
Load Register E with Register A, the letter's place.
5394
LD D,00H 16 00
Load Register D with 00H: Register Pair DE = the letter's place.
5396
PUSH HL E5
Save Register Pair HL, the text pointer, to the top of the stack.
5397
LD HL,4101H 21 01 41
Point Register Pair HL to 4101H, the ROM's table of the default types of the letters A-Z (DEFINT, DEFSTR and so on).
539A
ADD HL,DE 19
ADD Register Pair DE, the letter's place, to Register Pair HL: the letter's entry.
539B
LD D,(HL) 56
Load Register D with the type at Register Pair HL.
539C
POP HL E1
Restore Register Pair HL, the text pointer, from the top of the stack.
539D
DEC HL 2B
DECrement Register Pair HL by 1, back to the last character of the name, since no suffix was there.
539E
RET C9
RETurn to 539FH with the type of the first letter in Register D.
539F
PUSH HL E5
Save Register Pair HL, the text pointer, to the top of the stack.
53A0
PUSH IX DD E5
Save Index Register IX to the top of the stack.
53A2
LD HL,54E8H 21 E8 54
Point Register Pair HL to 54E8H, where the type is kept for the search.
53A5
LD (HL),D 72
Store Register D, the type, at Register Pair HL (54E8H).
53A6
LD IX,(40FBH) DD 2A FB 40
Load Index Register IX with ARYTAB from 40FBH-40FCH, the first array.
53AA
PUSH IX DD E5
Save Index Register IX, the array's entry, to the top of the stack.
53AC
POP HL E1
Restore Register Pair HL with the array's entry: Register Pair HL = Index Register IX.
53AD
LD DE,(40FDH) ED 5B FD 40
Load Register Pair DE with STREND from 40FDH-40FEH, the end of the arrays.
53B1
RST 18H DF
RST 18H: compare Register Pair HL, the array's entry, with Register Pair DE, the end: the Z FLAG when all arrays were passed.
53B2
If the Z FLAG is set (no such array: O does not dimension one), JUMP to 1E4AH, the ROM's Illegal function call error.
53B5
LD A,(54E8H) 3A E8 54
Load Register A with the type of the array looked for from 54E8H.
53B8
CP (IX+00H) DD BE 00
Compare Register A with the array's type at Index Register IX+00H.
53BB
If the NZ FLAG is set (another type), JUMP to 53C9H to the next array.
53BD
LD A,C 79
Load Register A with Register C, the second character of the name.
53BE
CP (IX+01H) DD BE 01
Compare Register A with the array's second character at Index Register IX+01H.
53C1
If the NZ FLAG is set (another name), JUMP to 53C9H to the next array.
53C3
LD A,B 78
Load Register A with Register B, the first letter of the name.
53C4
CP (IX+02H) DD BE 02
Compare Register A with the array's first letter at Index Register IX+02H.
53C7
If the Z FLAG is set (the type and the name match), JUMP to 53D8H.
53C9
LD E,(IX+03H) DD 5E 03
Load Register E with the low byte of the array's length at Index Register IX+03H.
53CC
LD D,(IX+04H) DD 56 04
Load Register D with the high byte of the length at Index Register IX+04H.
53CF
ADD IX,DE DD 19
ADD Register Pair DE, the length, to Index Register IX.
53D1
LD DE,0005H 11 05 00
Load Register Pair DE with 0005H, the bytes before the length counts: the type, the name and the length itself.
53D4
ADD IX,DE DD 19
ADD Register Pair DE (5) to Index Register IX: the next array's entry.
53D6
LOOP BACK to 53AAH to test the next array of the array area.
53D8
LD A,(IX+05H) DD 7E 05
Load Register A with the number of dimensions at Index Register IX+05H.
53DB
DEC A 3D
DECrement Register A by 1: the Z FLAG for one dimension.
53DC
If the NZ FLAG is set (more than one dimension), JUMP to 1E4AH, the ROM's Illegal function call error.
53DF
LD C,(IX+06H) DD 4E 06
Load Register C with the low byte of the number of elements at Index Register IX+06H.
53E2
LD B,(IX+07H) DD 46 07
Load Register B with the high byte of the number of elements at Index Register IX+07H.
53E5
PUSH IX DD E5
Save Index Register IX, the array's entry, to the top of the stack.
53E7
POP DE D1
Restore Register Pair DE with the array's entry: Register Pair DE = Index Register IX.
53E8
POP IX DD E1
Restore Index Register IX, the caller's, from the top of the stack.
53EA
POP HL E1
Restore Register Pair HL, the text pointer, from the top of the stack.
53EB
RET C9
RETurn with Register Pair DE the array's entry and Register Pair BC its number of elements.

53ECH - Two Elements

For the table entry at Index Register IX: Register Pair HL a subscript, Register Pair DE the gap. Returns Register Pair HL = the address of that element, Register Pair DE = the address of the element a gap after it, Register B the length of an element and Register C the entry's flags, and Index Register IX moved to the next entry.

53EC
PUSH HL E5
Save Register Pair HL, the subscript, to the top of the stack.
53ED
GOSUB to 53FDH: Register Pair HL = the address of the element of that subscript.
53F0
EX (SP),HL E3
EXchange Register Pair HL with the top of the stack (the Stack Pointer's word): Register Pair HL = the subscript, the stack holds the first element's address.
53F1
ADD HL,DE 19
ADD Register Pair DE, the gap, to Register Pair HL: the subscript of the second element.
53F2
GOSUB to 53FDH: Register Pair HL = the address of the second element.
53F5
LD DE,0003H 11 03 00
Load Register Pair DE with 0003H, the length of a table entry.
53F8
ADD IX,DE DD 19
ADD Register Pair DE (3) to Index Register IX: the next table entry.
53FA
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair DE = the second element's address.
53FB
POP HL E1
Restore Register Pair HL, the first element's address, from the top of the stack.
53FC
RET C9
RETurn with Register Pair HL and Register Pair DE the two elements.

53FDH - The Address of an Element

Register Pair HL a subscript, Index Register IX a table entry. The element's length (the array's type: 2, 3, 4 or 8) times the subscript is added to the first element, 8 bytes after the array's entry. The multiplication by 3 uses the parity of Register A: OR A after SUB 04H gives parity even only for FFH (a string).

53FD
PUSH DE D5
Save Register Pair DE to the top of the stack.
53FE
PUSH HL E5
Save Register Pair HL, the subscript, to the top of the stack.
53FF
LD C,(IX+00H) DD 4E 00
Load Register C with the flags of the table entry at Index Register IX+00H.
5402
LD L,(IX+01H) DD 6E 01
Load Register L with the low byte of the array's entry at Index Register IX+01H.
5405
LD H,(IX+02H) DD 66 02
Load Register H with the high byte of the array's entry at Index Register IX+02H.
5408
LD B,(HL) 46
Load Register B with the array's type at Register Pair HL: the length of an element.
5409
LD DE,0008H 11 08 00
Load Register Pair DE with 0008H, the length of the entry of a one dimensional array before its first element.
540C
ADD HL,DE 19
ADD Register Pair DE (8) to Register Pair HL: the first element of the array.
540D
EX (SP),HL E3
EXchange Register Pair HL with the top of the stack (the Stack Pointer's word): Register Pair HL = the subscript, the stack holds the first element.
540E
LD A,B 78
Load Register A with Register B, the length of an element.
540F
LD D,H 54
Load Register D with Register H, the high byte of the subscript.
5410
LD E,L 5D
Load Register E with Register L: Register Pair DE = the subscript.
5411
ADD HL,HL 29
ADD Register Pair HL to itself: the subscript times 2.
5412
SUB 04H D6 04
SUBtract 04H from Register A: the C FLAG for a length of 2 or 3, the Z FLAG for 4.
5414
If the C FLAG is set (2 or 3), JUMP to 541AH.
5416
ADD HL,HL 29
ADD Register Pair HL to itself: the subscript times 4.
5417
If the Z FLAG is set (a length of 4), JUMP to 541FH.
5419
ADD HL,HL 29
ADD Register Pair HL to itself: the subscript times 8, for a length of 8.
541A
OR A B7
OR Register A against itself: the parity is even only for FFH, a length of 3 (FEH for 2 and 04H for 8 give odd parity).
541B
If the PO FLAG is set (a length of 2 or 8), JUMP to 541FH.
541E
ADD HL,DE 19
ADD Register Pair DE, the subscript, to Register Pair HL: the subscript times 3, for a string.
541F
POP DE D1
Restore Register Pair DE, the first element, from the top of the stack.
5420
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: the address of the element.
5421
POP DE D1
Restore Register Pair DE from the top of the stack.
5422
RET C9
RETurn with Register Pair HL the element's address.

5423H - Compare Two Elements

The element at Register Pair HL is compared with the one at Register Pair DE by the type in Register B: integers by the ROM's 0A39H, single precision by 0A0CH, double precision by 0A78H, strings character by character (a string that is the start of the other is the lesser). Register A returns 00H for equal, 01H when the first is greater, FFH when it is less.

5423
PUSH BC C5
Save Register Pair BC to the top of the stack.
5424
PUSH DE D5
Save Register Pair DE to the top of the stack.
5425
PUSH HL E5
Save Register Pair HL to the top of the stack.
5426
LD A,B 78
Load Register A with Register B, the type of the elements.
5427
SUB 02H D6 02
SUBtract 02H from Register A: the Z FLAG for an integer.
5429
If the Z FLAG is set (integers), JUMP to 5455H.
542B
DEC A 3D
DECrement Register A by 1: the Z FLAG for a string (type 03H).
542C
If the Z FLAG is set (strings), JUMP to 5463H.
542E
DEC A 3D
DECrement Register A by 1: the Z FLAG for single precision (type 04H).
542F
If the Z FLAG is set (single precision), JUMP to 5445H.
5431
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the second element, Register Pair DE = the first.
5432
GOSUB to 0AECH, the ROM's setting of the value type 40AFH to double precision.
5435
PUSH DE D5
Save Register Pair DE, the first element, to the top of the stack.
5436
GOSUB to 09F7H, inside the ROM's move at 09F4H: the double precision value at Register Pair HL, the second element, is copied into the accumulator at 411DH.
5439
POP HL E1
Restore Register Pair HL, the first element, from the top of the stack.
543A
LD DE,4127H 11 27 41
Point Register Pair DE to 4127H, the ROM's second operand.
543D
GOSUB to 09D2H, the ROM's move of a value of the current type from Register Pair HL to Register Pair DE: the first element into 4127H.
5440
GOSUB to 0A78H, the ROM's reversed double precision compare: Register A = 01H when the second operand (the first element) is the greater.
5443
JUMP to 548CH to return the result of the double precision compare.
5445
GOSUB to 0AEFH, the ROM's setting of the value type 40AFH to single precision.
5448
PUSH DE D5
Save Register Pair DE, the second element, to the top of the stack.
5449
GOSUB to 09B1H, the ROM's load of the accumulator from the single precision value at Register Pair HL, the first element.
544C
POP HL E1
Restore Register Pair HL, the second element, from the top of the stack.
544D
GOSUB to 09C2H, the ROM's load of Register Pairs BC and DE from the value at Register Pair HL, the second element.
5450
GOSUB to 0A0CH, the ROM's single precision compare of the accumulator with Register Pairs BC and DE: Register A = 01H when the first is the greater.
5453
JUMP to 548CH to return the result of the single precision compare.
5455
LD C,(HL) 4E
Load Register C with the low byte of the first integer at Register Pair HL.
5456
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
5457
LD B,(HL) 46
Load Register B with the high byte of the first integer at Register Pair HL: Register Pair BC = the first value.
5458
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the second element.
5459
LD E,(HL) 5E
Load Register E with the low byte of the second integer at Register Pair HL.
545A
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
545B
LD D,(HL) 56
Load Register D with the high byte of the second integer at Register Pair HL: Register Pair DE = the second value.
545C
PUSH BC C5
Save Register Pair BC, the first value, to the top of the stack.
545D
POP HL E1
Restore Register Pair HL with the first value: Register Pair HL = Register Pair BC.
545E
GOSUB to 0A39H, the ROM's signed compare of Register Pair HL with Register Pair DE: Register A = 01H when the first is the greater.
5461
JUMP to 548CH to return the result of the integer compare.
5463
LD A,(HL) 7E
Load Register A with the length of the first string from its descriptor at Register Pair HL.
5464
INC HL 23
INCrement Register Pair HL by 1, to the address of the string.
5465
LD C,(HL) 4E
Load Register C with the low byte of the first string's address at Register Pair HL.
5466
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
5467
LD B,(HL) 46
Load Register B with the high byte at Register Pair HL: Register Pair BC = the first string.
5468
EX DE,HL EB
EXchange Register Pairs DE and HL: Register Pair HL = the second descriptor.
5469
PUSH BC C5
Save Register Pair BC, the first string, to the top of the stack.
546A
LD C,(HL) 4E
Load Register C with the length of the second string at Register Pair HL.
546B
INC HL 23
INCrement Register Pair HL by 1, to the address of the string.
546C
LD E,(HL) 5E
Load Register E with the low byte of the second string's address at Register Pair HL.
546D
INC HL 23
INCrement Register Pair HL by 1, to the high byte.
546E
LD D,(HL) 56
Load Register D with the high byte at Register Pair HL: Register Pair DE = the second string.
546F
LD B,A 47
Load Register B with Register A, the length of the first string; Register C is that of the second.
5470
POP HL E1
Restore Register Pair HL, the first string, from the top of the stack.
5471
LD A,B 78
Load Register A with Register B, the characters left in the first string.
5472
OR C B1
OR Register A with Register C, those left in the second: the Z FLAG when both have ended.
5473
If the Z FLAG is set (both ended, equal), JUMP to 548CH with Register A = 00H.
5475
LD A,B 78
Load Register A with Register B, the characters left in the first string.
5476
SUB 01H D6 01
SUBtract 01H from Register A: the C FLAG (and FFH) when the first string has ended.
5478
If the C FLAG is set (the first is shorter), JUMP to 548CH with Register A = FFH.
547A
XOR A AF
Set Register A to 00H by XORing it with itself.
547B
CP C B9
Compare Register A (00H) with Register C: the NC FLAG when the second string has ended.
547C
INC A 3C
INCrement Register A by 1, to 01H (the C FLAG is kept).
547D
If the NC FLAG is set (the second is shorter), JUMP to 548CH with Register A = 01H.
547F
DEC B 05
DECrement Register B by 1, the characters left in the first string.
5480
DEC C 0D
DECrement Register C by 1, the characters left in the second string.
5481
LD A,(DE) 1A
Load Register A with the character of the second string at Register Pair DE.
5482
CP (HL) BE
Compare Register A with the character of the first string at Register Pair HL: the C FLAG when the second's character is lower.
5483
INC HL 23
INCrement Register Pair HL by 1, to the next character of the first string.
5484
INC DE 13
INCrement Register Pair DE by 1, to the next character of the second string.
5485
If the Z FLAG is set (the same character), LOOP BACK to 5471H.
5487
CCF 3F
Complement the C FLAG (CCF): the C FLAG now set when the second's character is higher.
5488
SBC A,A 9F
SUBtract Register A with the C FLAG from itself (SBC A,A): FFH when the first is less, 00H when it is greater.
5489
If the NZ FLAG is set (FFH, the first is less), JUMP to 548CH.
548B
INC A 3C
INCrement Register A by 1, to 01H: the first string is the greater.
548C
POP HL E1
Restore Register Pair HL from the top of the stack.
548D
POP DE D1
Restore Register Pair DE from the top of the stack.
548E
POP BC C1
Restore Register Pair BC from the top of the stack.
548F
RET C9
RETurn with the result of the compare in Register A.

5490H - The Heading and the Variables

Data.

5490-54B6
DEFM "SORT - BASIC Multi key/array sort - 1.7" 53 4F 52 54 20 2D 20 42 41 53 49 43 20 4D 75 6C 74 69 20 6B 65 79 2F 61 72 72 61 79 20 73 6F 72 74 20 2D 20 31 2E 37
The heading that O shows when it is run from the DOS command level (5209H).
54B7
DEFB 0AH 0A
A line feed, which starts the second line of the heading for DSPLY@.
54B8-54E6
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.
54E7
DEFB 0DH 0D
The carriage return that ends the heading for DSPLY@.
54E8
DEFS 1
The type of the array being looked for (53A5H): 02H, 03H, 04H or 08H.
54E9-54EA
DEFS 2
The count of the elements to sort, not 0 (5222H).
54EB-54EC
DEFS 2
The start subscript, the same for every array (5241H).
54ED-54EE
DEFS 2
The limit of the index i: the count less the gap (5297H).
54EF-54F0
DEFS 2
The index j of the compare, which goes back by the gap after an exchange (52A2H, 52EDH).
54F1-54F2
DEFS 2
The gap of the Shell sort: half the count, then halved after each pass (5282H, 531EH).
54F3-54F4
DEFS 2
The index i of the pass, 0 to the limit less 1 (529CH, 530DH).
54F5-554F
DEFB 00H x 91 00 x 91
The table of the arrays, 00H as loaded: thirty entries of three bytes (the flags: bit 0 in use, bit 1 a key, bit 7 descending; the address of the array's entry), the primary key first, then the other keys and the tags, and a last 00H that ends the table (52CBH, 52F2H).