DOSPLUS 3.5 for the Model I - BACKUP/CMD Disassembled

Page Customization

Introduction/Summary

DOSPLUS 3.5 BACKUP/CMD Disassembly - The Mirror Image Floppy Backup (Model I)

BACKUP/CMD is DOSPLUS's backup utility, run from the DOS command level as BACKUP [FROM] :sd [TO] :dd (DATE="string",USE="string"); its heading reads BACKUP - DOSPLUS Floppy backup - 3.51. It is a load module of 16 blocks, 2730 bytes, at 5200H-5CB3H with the transfer address 5200H, after the two comment records (the name BACKUP and the copyright notice) and a 07H record. The last four blocks are patches that load over bytes already loaded: three blocks put new code at 53B3H-53CBH (5396H), and one changes 59F7H from 30H to 31H, so that the heading shows 3.51 instead of 3.50 (59D3H). The page shows the bytes as they are after the patches. The Model I and Model III files have the same length and differ in 47 bytes: the addresses in SYS0/SYS (DATE$, LOW$, HMEM$, SFLAG1$, DCTTBL, DISKIO%, LOCDCT%, the multiply and divide and the routine that saves the registers) and the three prompts Insert ... disk, which end (ENTER) on the Model I and [ENTER] on the Model III; this page is the Model I one.

BACKUP copies a floppy diskette as a mirror image: every granule that the source's GAT shows as allocated, and not locked out, is copied to the same cylinder, granule and sector of the destination. It refuses a rigid drive (Drive NOT SUPPORTED!, 567AH) and a copy between an 8 inch and a 5 inch drive (Drives INCOMPATABLE!, as the file spells it, 56F6H). With the same drive as source and destination it prompts for each diskette in turn (540DH).

The Parts of BACKUP/CMD

AddressContents
5200H-528CHThe heading, the buffer, EVAL@, the source and destination drives (5200H).
528DH-52DAHThe date (528DH).
52DBH-531FHThe source and the destination diskettes (52DBH, 5306H).
5320H-5395HThe copy loop: runs of cylinders read, written and verified (5320H).
5396H-540CHThe directory cylinder, with the 3.51 patch, and the end (5396H).
540DH-54DAHThe prompt for a disk, the read, write and verify passes, sectors and granules (540DH, 5415H, 544CH, 5483H, 54C3H, 54D0H).
54DBH-55CBHFormatting: the sector order and the track image (54DBH, 54F8H, 55C2H).
55CCH-5635HThe errors and the end (55CCH, 5612H).
5636H-56A3HReading a GAT and finding the format and the density (5636H, 567AH).
56A4H-57FFHThe destination: use it or format it, flaws, the new GAT (56A4H, 5743H, 57B7H).
5800H-5877HThe cylinders to copy and the geometry (5800H, 580EH, 581CH, 5847H).
5878H-5986HPrompts, texts, digits, bits and drive names (5878H, 5891H, 58B5H, 58DAH, 5918H, 592AH, 595AH).
5987H-5CB3HThe formats, the texts, the evaluation block and the variables (5987H, 59D3H, 5C96H).

How BACKUP Works

The buffer of sectors starts at 6100H, or at the page above LOW$ (4047H) when that is higher, and needs 3BFEH bytes below HMEM$ (4049H) for the image of a track (else No available memory!, 5200H). EVAL@ takes the drives and the two parameters from the command line (5237H); a drive not given is asked for with Source drivespec ? or Destination drivespec ?, whose reply is the drive's one or two character name in DCTTBL, without a colon (595AH). The date comes from DATE=, else from the system date as MM/DD/YY, else from the prompt Backup date ? (528DH).

BACKUP checks the source drive and notes whether its diskette is write protected, finds its density from sector 2 of cylinder 0 and reads its GAT (5636H). From then on both drives are given the source's geometry (581CH). A double density diskette whose cylinder 0 is in single density, as a Model I system diskette must be for the ROM to boot it, is noted (5CB5H): cylinder 0 is then read, written and formatted as one single density granule of 10 sectors (5993H).

The destination (56A4H) is formatted when it cannot be read; otherwise Diskette contains data, use or not ? is answered by USE= or at the prompt: N ends BACKUP, F formats all of it, Y or U use its format. A diskette that is used but has fewer cylinders, another density or another count of sides is formatted all the same; else only cylinder 0 (when its density differs) and the old directory cylinder (when the directory moves) are formatted, and the destination keeps its own lock outs and, when it has more cylinders than the source, its own count. Formatting (5743H, 54F8H) writes each track with an interleave of 2 in single density and 3 in double density, starting each track twice the interleave further on, with 256 bytes of 6CH in every sector; then every granule is read back from the last cylinder down, and one that cannot be read is locked out (GRAN FLAWED! Locked out!); a flawed boot granule ends BACKUP. The new GAT (57B7H) holds the granules to copy and the destination's lock outs; a granule to copy that is locked out on the destination ends BACKUP with BACKUP rejected! Too many FLAWS!. Its bytes +C0H-+FFH (the name, the master password, the AUTO command) are the source's, with the date of the backup, the version 35H and the count of cylinders.

The copy loop (5320H) reads the granules to copy, cylinder after cylinder, as long as another whole cylinder fits below HMEM$, writes that run to the destination with each sector's data address mark (DWRITA for a sector that was read with the directory's mark, 54D0H) and verifies it, then goes on with the next run. Last (5396H) the directory cylinder is read from the source, the modified flag of every directory entry is cleared, the cylinder is written back to the source unless it is write protected, and written to the destination with the new GAT in place of the source's. Both drives are then marked to be logged again, and Insert SYSTEM disk (ENTER) is flashed when drive 0 was one of them (5612H).

The 3.51 Patch

The 3.50 code at 53B3H-53CBH was LD HL,(5CBBH) / INC H / INC H / INC L / LD A,(IY+0EH) / SUB 02H / LD B,A, then RES 6,(HL) / LD A,20H / ADD A,L / LD L,A / JR NC / INC H / DJNZ, between two EXX: it cleared bit 6 of byte +01H in every 32 byte entry of the directory sectors. In an extended entry (FXDE, bit 7 of byte +00H set) byte +01H is not a flag byte but the link back to the file's first entry, so the old code could change that link. The patched code tests bit 7 of each entry's first byte and leaves the FXDEs alone (53BDH); it no longer keeps the registers by EXX, which the code after it does not need.

Findings

BACKUP does not test EVAL@'s return code (523BH): an unknown parameter or a value of the wrong type is passed over without a message. The entries USE and DATE take only a string in quotation marks (type 80H, 5C96H); EVAL@ stores the address of the string's text over the operands of two LD HL instructions, and BACKUP copies up to 8 characters from there (5891H). The verify pass reads every sector back but does not compare it with what was written (5483H). A read error in the verify pass, or while the source's directory cylinder is read, shows Destination disk WRITE ERROR! (53B0H); the messages I/O ERROR! routine aborted! and Destination disk READ ERROR! are never shown (55CCH). A read whose code is 06H or more counts as a good read: 06H is the record type of the directory's data address mark, and the code less 05H is kept as the sector's mark (54C3H). The flashing prompts wait for any key, not only ENTER, and are not shown while a DO file runs (58DAH). An answer of N at Diskette contains data ends BACKUP with EXIT@, not with an error.

Differences from the Manual

The manual (Utilities, BACKUP, pages 3-1 to 3-5, and the first backup in the getting started section) gives the parameters with USE=Y or U=Y; the bytes take only USE="Y" (any string, its first character the answer), and with USE=Y EVAL@ refuses the value and BACKUP prompts all the same. The manual lists Y, U, F and BREAK at Diskette contains data, and N in the getting started text; the bytes take N, F, U and Y, in either case. In a backup with one drive the manual says BACKUP may need the system disk from time to time; the bytes prompt for it only at the end, and only when drive 0 was the source or the destination. The manual's statements that only allocated granules are copied, that the destination may keep its format, that formatting is done as little as needed, that a granule locked out on the destination aborts the backup, and that the modified flags of both directories are cleared, agree with the bytes; that BACKUP does not de-allocate the extra cylinders of a destination that has more agrees too (5708H).

Variables

BACKUP/CMD Variables

Address
Size
Contents
528EH-528FH
2 bytes
DATE string
The operand of LD HL at 528DH: the address of the DATE string, 0000H when none (5230H).
56C2H-56C3H
2 bytes
USE string
The operand of LD HL at 56C1H: the address of the USE string (5233H).
5917H
1 byte
Flash state
1EH while a prompt is shown, 00H while the line is clear (5917H).
599DH-59A6H
10 bytes
Geometry
The source's DCT+0BH-DCT+14H; 59A4H the directory cylinder, 59A5H the count of cylinders (599DH).
5C96H-5CB1H
28 bytes
Evaluation block
The block of EVAL@ and its parameters USE and DATE (5C96H).
5CB2H-5CB3H
2 bytes
Drives
The source and the destination drive (5CB2H).
5CB4H-5CBAH
7 bytes
Flags
The format code, the density flag of cylinder 0, the run of cylinders, the empty cylinder byte, write protect, one drive (5CB4H).
5CBBH-5CBCH
2 bytes
Buffer
The start of the buffer of sectors (5CBBH).
5CBDH-5CC4H
8 bytes
Date
The date of the backup (5CBDH).
5CC6H-5CCEH
9 bytes
Reply
The reply to a prompt and the copies of 5891H (5CC6H).
5CD0H-5D11H
66 bytes
Fields
The source and destination field blocks of EVAL@ (5CD0H).
5D12H-5D31H
32 bytes
Sector order
The sector order of a track being formatted (5D12H).
5D32H-5EFFH
462 bytes
Sector marks
One byte a sector in the buffer (5D32H).
5F00H-5FFFH
256 bytes
Source GAT
The source's GAT (5F00H).
6000H-60FFH
256 bytes
New GAT
The destination's new GAT (6000H).

Memory Outside BACKUP/CMD

Address
Size
Contents
4044H-4046H
3 bytes
DATE$
The system date: year, day, month (5294H).
4047H-4048H
2 bytes
LOW$
The lowest address free for programs (5207H).
4049H-404AH
2 bytes
HMEM$
The highest address free for programs (5224H, 5348H).
4302H
1 byte
SFLAG1$
Bit 5, a DO file runs (58DAH).
43ABH
32 bytes
DCTTBL
The drive names (595AH).
6100H on
to HMEM$
Buffer
The sectors of a run of cylinders, or the image of a track (5219H).

Outside Routines

AddressContents
4479HSYS0/SYS: EVAL@ (523BH).
4485HSYS0/SYS: DISKIO% (52E3H and others).
448BHSYS0/SYS: LOCDCT% (567AH, 581FH, 5616H).
4934HSYS0/SYS: 8 bit multiply (54BDH, 550EH).
4943HSYS0/SYS: 8 bit divide (5516H).
4525HSYS0/SYS: run a routine with the registers saved (58E0H).
402DHSYS0/SYS: EXIT@ (540AH).
4030HSYS0/SYS: ABORT@ (560FH).
0033HROM: display a character (58BBH, 587FH, 5905H).
0040HROM: line input (5888H).
002BHROM: scan the keyboard (58F8H).

Disassembly

5200H - BACKUP

BACKUP/CMD's transfer address, entered from the DOS command level with Register Pair HL at the command line after the word BACKUP: BACKUP [FROM] :sd [TO] :dd (DATE="string",USE="string"). BACKUP shows its heading, sets its buffer above 6100H, takes the drives from the command line or from the prompts, takes the date, checks both drives, reads the source's GAT, prepares the destination (56A4H: format it, or use its format), then copies every allocated granule cylinder by cylinder, as many as fit in memory at a time (read, write, verify), and last copies the directory cylinder with the modified flags cleared. It ends with the prompt for the system disk and EXIT@, or with an error message and ABORT@.

5200
PUSH HL E5
Save Register Pair HL, the command line pointer after BACKUP, to the top of the stack for EVAL@ below.
5201
LD HL,59D3H 21 D3 59
Point Register Pair HL to 59D3H, BACKUP's heading (BACKUP - DOSPLUS Floppy backup - 3.51) and copyright line.
5204
GOSUB to 58B5H to show the text at Register Pair HL up to its ending 03H.
5207
LD HL,(4047H) 2A 47 40
Load Register Pair HL with LOW$ from 4047H-4048H, the lowest address free for programs.
520A
LD BC,6100H 01 00 61
Load Register Pair BC with 6100H, the lowest address BACKUP ever uses for its buffer of sectors.
520D
OR A B7
OR Register A against itself, to clear the C FLAG for the SBC below.
520E
SBC HL,BC ED 42
SUBtract Register Pair BC (6100H) from Register Pair HL (LOW$) with the C FLAG: the C FLAG when LOW$ is below 6100H.
5210
If the C FLAG is set (LOW$ below 6100H), JUMP to 5219H with Register Pair BC = 6100H as the buffer.
5212
LD BC,(4047H) ED 4B 47 40
Load Register Pair BC with LOW$ from 4047H-4048H again, for a buffer above a program in low memory.
5216
LD C,00H 0E 00
Load Register C with 00H, the start of the page that holds LOW$.
5218
INC B 04
INCrement Register B by 1: Register Pair BC is the start of the page above LOW$.
5219
LD (5CBBH),BC ED 43 BB 5C
Store Register Pair BC, the start of the buffer, into 5CBBH-5CBCH, where every pass takes it.
521D
LD HL,3BFEH 21 FE 3B
Load Register Pair HL with 3BFEH, the room the buffer needs at least (a whole track image for formatting).
5220
ADD HL,BC 09
ADD Register Pair BC (the buffer) to Register Pair HL: the end of that room, with the C FLAG past FFFFH.
5221
If the C FLAG is set (past the top of memory), JUMP to 55EAH for the message No available memory!.
5224
LD BC,(4049H) ED 4B 49 40
Load Register Pair BC with HMEM$ from 4049H-404AH, the highest address free for programs.
5228
SBC HL,BC ED 42
SUBtract Register Pair BC (HMEM$) from Register Pair HL (the end of the room) with the C FLAG, which is clear here.
522A
If the NC FLAG is set (the room reaches HMEM$), JUMP to 55EAH for the message No available memory!.
522D
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H, to clear the two string addresses of the parameters DATE and USE.
5230
LD (528EH),HL 22 8E 52
Store Register Pair HL (0000H) into 528EH-528FH, the operand of LD HL at 528DH: no DATE string yet.
5233
LD (56C2H),HL 22 C2 56
Store Register Pair HL (0000H) into 56C2H-56C3H, the operand of LD HL at 56C1H: no USE string yet.
5236
POP HL E1
Restore Register Pair HL, the command line pointer, from the top of the stack.
5237
LD IX,5C96H DD 21 96 5C
Point Index Register IX to 5C96H, BACKUP's evaluation block for EVAL@ (source, destination and parameters).
523B
GOSUB to 4479H, EVAL@, to take the drives and the parameters of the command line; its return code is not tested.
523E
BIT 0,(IX+00H) DD CB 00 46
Test bit 0 of the flags at Index Register IX+00H, set by EVAL@ when a source field was given.
5242
If the Z FLAG is set (no source on the command line), JUMP to 524FH to prompt for it.
5244
LD A,(5CD0H) 3A D0 5C
Load Register A with the flag byte of the source field from 5CD0H: bit 7 a device or drive, bit 3 a drive.
5247
LD C,A 4F
Copy Register A, the field's flags, into Register C to keep them.
5248
AND C8H E6 C8
AND Register A with C8H to keep bit 7 (a device or drive), bit 6 (a name) and bit 3 (a drive).
524A
CP 88H FE 88
Compare Register A against 88H: the Z FLAG for a drive alone (bits 7 and 3, no name).
524C
LD A,C 79
Load Register A with Register C, the field's flags, whose bits 0-2 are the drive number.
524D
If the Z FLAG is set (the source is a drive), JUMP to 525FH to keep its number.
524F
LD B,02H 06 02
Load Register B with 02H, the most characters the reply to the prompt may have.
5251
LD HL,5A2BH 21 2B 5A
Point Register Pair HL to 5A2BH, the prompt Source drivespec ?, followed by its count of spaces.
5254
GOSUB to 5878H to show the prompt at Register Pair HL and take the reply into 5CC6H.
5257
GOSUB to 5891H to pad the reply at Register Pair HL (5CC6H) with spaces to 8 characters.
525A
GOSUB to 595AH to look up the reply at Register Pair HL among the drive names of DCTTBL: Register A the drive.
525D
If the NZ FLAG is set (no drive of that name), JUMP to 524FH to ask again.
525F
AND 07H E6 07
AND Register A with 07H, to keep the drive number 0-7.
5261
LD (5CB2H),A 32 B2 5C
Store Register A, the source drive, into 5CB2H.
5264
LD (5CB3H),A 32 B3 5C
Store Register A into 5CB3H as well: the destination is the same drive until another is given.
5267
BIT 1,(IX+00H) DD CB 00 4E
Test bit 1 of the flags at Index Register IX+00H, set by EVAL@ when a destination field was given.
526B
If the Z FLAG is set (no destination on the command line), JUMP to 5278H to prompt for it.
526D
LD A,(5CF1H) 3A F1 5C
Load Register A with the flag byte of the destination field from 5CF1H.
5270
LD C,A 4F
Copy Register A, the field's flags, into Register C to keep them.
5271
AND C8H E6 C8
AND Register A with C8H to keep bit 7 (a device or drive), bit 6 (a name) and bit 3 (a drive).
5273
CP 88H FE 88
Compare Register A against 88H: the Z FLAG for a drive alone (bits 7 and 3, no name).
5275
LD A,C 79
Load Register A with Register C, the field's flags, whose bits 0-2 are the drive number.
5276
If the Z FLAG is set (the destination is a drive), JUMP to 5288H to keep its number.
5278
LD B,02H 06 02
Load Register B with 02H, the most characters the reply to the prompt may have.
527A
LD HL,5A3FH 21 3F 5A
Point Register Pair HL to 5A3FH, the prompt Destination drivespec ?, followed by its count of spaces.
527D
GOSUB to 5878H to show the prompt at Register Pair HL and take the reply into 5CC6H.
5280
GOSUB to 5891H to pad the reply at Register Pair HL (5CC6H) with spaces to 8 characters.
5283
GOSUB to 595AH to look up the reply at Register Pair HL among the drive names of DCTTBL: Register A the drive.
5286
If the NZ FLAG is set (no drive of that name), JUMP to 5278H to ask again.
5288
AND 07H E6 07
AND Register A with 07H, to keep the drive number 0-7.
528A
LD (5CB3H),A 32 B3 5C
Store Register A, the destination drive, into 5CB3H.

528DH - The Date

The date written into the destination's GAT: the DATE string of the command line (its address stored over the operand at 528EH by EVAL@), else the system date DATE$ as MM/DD/YY, else the reply to the prompt Backup date ?. A month of 0 means that no date is set; ENTER alone at the prompt then gives 00/00/00.

528D
LD HL,0000H 21 00 00
Load Register Pair HL with the address of the DATE string: 0000H unless EVAL@ stored the address here (528EH).
5290
LD A,H 7C
Load Register A with Register H, the high byte of the DATE string's address.
5291
OR L B5
OR Register A with Register L: the Z FLAG when no DATE string was given.
5292
If the NZ FLAG is set (a DATE string), JUMP to 52C5H to take up to 8 characters of it.
5294
LD A,(4046H) 3A 46 40
Load Register A with the month of DATE$ from 4046H.
5297
OR A B7
OR Register A against itself: the Z FLAG for month 0, no system date.
5298
If the Z FLAG is set (no system date), JUMP to 52B9H for the prompt Backup date ?.
529A
LD HL,5CC6H 21 C6 5C
Point Register Pair HL to 5CC6H, the work area where the date is made as MM/DD/YY.
529D
PUSH HL E5
Save Register Pair HL, the start of the date, to the top of the stack.
529E
LD A,(4046H) 3A 46 40
Load Register A with the month of DATE$ from 4046H.
52A1
GOSUB to 5918H to store Register A as two decimal digits at Register Pair HL.
52A4
LD (HL),2FH 36 2F
Store 2FH, a slash, at Register Pair HL, after the month.
52A6
INC HL 23
INCrement Register Pair HL by 1, to the place of the day.
52A7
LD A,(4045H) 3A 45 40
Load Register A with the day of DATE$ from 4045H.
52AA
GOSUB to 5918H to store Register A as two decimal digits at Register Pair HL.
52AD
LD (HL),2FH 36 2F
Store 2FH, a slash, at Register Pair HL, after the day.
52AF
INC HL 23
INCrement Register Pair HL by 1, to the place of the year.
52B0
LD A,(4044H) 3A 44 40
Load Register A with the year (mod 100) of DATE$ from 4044H.
52B3
GOSUB to 5918H to store Register A as two decimal digits at Register Pair HL.
52B6
POP HL E1
Restore Register Pair HL, the start of the date at 5CC6H, from the top of the stack.
52B7
JUMP to 52C5H to pad the date to 8 characters and keep it.
52B9
LD B,08H 06 08
Load Register B with 08H, the most characters the reply to the date prompt may have.
52BB
LD HL,5A58H 21 58 5A
Point Register Pair HL to 5A58H, the prompt Backup date ?, followed by its count of spaces.
52BE
GOSUB to 5878H to show the prompt at Register Pair HL and take the reply into 5CC6H; Register A its first character.
52C1
CP 0DH FE 0D
Compare Register A against 0DH: the Z FLAG when the reply is ENTER alone.
52C3
If the Z FLAG is set (no date given), JUMP to 529AH to make the date from DATE$, which is 00/00/00.
52C5
GOSUB to 5891H to copy up to 8 characters from Register Pair HL to 5CC6H, padded with spaces; Register Pair HL = 5CC6H.
52C8
LD DE,5CBDH 11 BD 5C
Point Register Pair DE to 5CBDH, where the 8 character date is kept for the destination's GAT.
52CB
LD BC,0008H 01 08 00
Load Register Pair BC with 0008H, the length of the date.
52CE
LDIR ED B0
Copy the 8 characters of the date from Register Pair HL to Register Pair DE (LDIR, Register Pair BC the count).
52D0
LD A,(5CB2H) 3A B2 5C
Load Register A with the source drive from 5CB2H.
52D3
LD C,A 4F
Copy Register A, the source drive, into Register C.
52D4
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
52D7
SUB C 91
SUBtract Register C (the source drive) from Register A (the destination drive): 00H when they are the same.
52D8
LD (5CBAH),A 32 BA 5C
Store Register A into 5CBAH: 00H for a backup with one drive, which prompts for each disk.

52DBH - The Source Diskette

Checks the source drive (DCHECK), notes whether its diskette is write protected (5CB9H), reads its GAT into 5F00H and keeps its format (5636H): the format code in 5CB4H, the density flag of cylinder 0 in 5CB5H, and its ten drive control table bytes from DCT+0BH in 599DH-59A6H, the geometry used for both drives from now on.

52DB
LD HL,5ACEH 21 CE 5A
Point Register Pair HL to 5ACEH, the prompt Insert SOURCE disk (ENTER).
52DE
GOSUB to 540DH to show the prompt at Register Pair HL and wait for a key, only for a backup with one drive.
52E1
LD A,00H 3E 00
Load Register A with 00H, the function DCHECK of DISKIO%: is the drive Register C ready.
52E3
GOSUB to 4485H, DISKIO%, to check the source drive Register C: the C FLAG for write protect.
52E6
If the NZ FLAG is set (the drive is not ready), JUMP to 55D1H for the message Source drive NOT READY!.
52E9
LD HL,5CB9H 21 B9 5C
Point Register Pair HL to 5CB9H, the write protect flag of the source diskette.
52EC
LD (HL),00H 36 00
Store 00H at Register Pair HL: the source diskette is not write protected.
52EE
If the NC FLAG is set (not write protected), JUMP to 52F1H.
52F0
DEC (HL) 35
DECrement the byte at Register Pair HL to FFH: the source is write protected, so its directory is not rewritten.
52F1
LD HL,5F00H 21 00 5F
Point Register Pair HL to 5F00H, the buffer of the source's GAT.
52F4
GOSUB to 5636H to find the density of drive Register C and read its GAT to Register Pair HL; Register Pair BC returns its format.
52F7
If the NZ FLAG is set (the GAT could not be read), JUMP to 55F4H for the message Source disk READ ERROR!.
52FA
LD (5CB4H),BC ED 43 B4 5C
Store Register Pair BC into 5CB4H-5CB5H: Register C the format code, Register B the density flag of cylinder 0.
52FE
LD DE,599DH 11 9D 59
Point Register Pair DE to 599DH, where the source's drive control table bytes are kept.
5301
LD BC,000AH 01 0A 00
Load Register Pair BC with 000AH, the ten bytes DCT+0BH to DCT+14H that 5636H points Register Pair HL to.
5304
LDIR ED B0
Copy the ten bytes from Register Pair HL to Register Pair DE (LDIR, Register Pair BC the count): the source's geometry.

5306H - The Destination Diskette

Checks the destination drive (DCHECK: not ready or write protected ends BACKUP), then prepares the destination diskette (56A4H): it is formatted, or its format is used, and its new GAT is made at 6000H.

5306
LD HL,5AE9H 21 E9 5A
Point Register Pair HL to 5AE9H, the prompt Insert DESTINATION disk (ENTER).
5309
GOSUB to 540DH to show the prompt at Register Pair HL and wait for a key, only for a backup with one drive.
530C
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
530F
LD C,A 4F
Copy Register A, the destination drive, into Register C for DISKIO%.
5310
LD A,00H 3E 00
Load Register A with 00H, the function DCHECK of DISKIO%: is the drive Register C ready.
5312
GOSUB to 4485H, DISKIO%, to check the destination drive Register C: the C FLAG for write protect.
5315
If the NZ FLAG is set (the drive is not ready), JUMP to 55D6H for the message Destination drive NOT READY!.
5318
If the C FLAG is set (the diskette is write protected), JUMP to 55E5H for the message Destination disk WRITE PROTECTED!.
531B
GOSUB to 56A4H to prepare the destination diskette (format it or use its format) and make its GAT at 6000H.
531E
LD D,00H 16 00
Load Register D with 00H, the first cylinder to copy.

5320H - The Copy Loop

One round copies a run of cylinders: from the next cylinder that has a granule to copy (5CB7H), the allocated granules are read into the buffer from (5CBBH) until no other cylinder would fit below HMEM$ (5CB6H is then the cylinder after the run), then written to the destination and verified there. A granule to copy is one allocated in the source's GAT and not locked out (580EH). When no cylinder is left, the directory cylinder is done at 5396H.

5320
GOSUB to 5801H to find the next cylinder from Register D on that has a granule to copy: the NZ FLAG when none is left.
5323
If the NZ FLAG is set (every cylinder is copied), JUMP to 5396H for the directory cylinder.
5325
LD HL,5ACEH 21 CE 5A
Point Register Pair HL to 5ACEH, the prompt Insert SOURCE disk (ENTER).
5328
GOSUB to 540DH to show the prompt at Register Pair HL and wait for a key, only for a backup with one drive.
532B
LD A,(5CB2H) 3A B2 5C
Load Register A with the source drive from 5CB2H.
532E
LD C,A 4F
Copy Register A, the source drive, into Register C for DISKIO%.
532F
LD A,D 7A
Load Register A with Register D, the first cylinder of this run.
5330
LD (5CB7H),A 32 B7 5C
Store Register A into 5CB7H, the first cylinder of the run, for the write and verify passes.
5333
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH.
5336
LD IX,5D32H DD 21 32 5D
Point Index Register IX to 5D32H, the table of the sector marks, one byte for each sector read.
533A
GOSUB to 5801H to find the next cylinder from Register D on that has a granule to copy: the NZ FLAG when none is left.
533D
If the NZ FLAG is set (no cylinder left), JUMP to 5351H to end the run here.
533F
GOSUB to 5415H to read the granules to copy of cylinder Register D into the buffer at Register Pair HL.
5342
If the NZ FLAG is set (a read error), JUMP to 55F4H for the message Source disk READ ERROR!.
5345
GOSUB to 5800H to step Register D to the next cylinder (and find the next one to copy; the flags are not used here).
5348
LD A,(404AH) 3A 4A 40
Load Register A with the high byte of HMEM$ from 404AH.
534B
SUB (IY+11H) FD 96 11
SUBtract the sectors per cylinder at Index Register IY+11H from Register A: the last page where a whole cylinder still fits.
534E
CP H BC
Compare Register A against Register H, the page of the buffer where the next sector would go.
534F
If the NC FLAG is set (another cylinder fits), JUMP to 533AH to read the next cylinder.
5351
LD A,D 7A
Load Register A with Register D, the cylinder after the last one read.
5352
LD (5CB6H),A 32 B6 5C
Store Register A into 5CB6H, the end of the run.
5355
LD HL,5AE9H 21 E9 5A
Point Register Pair HL to 5AE9H, the prompt Insert DESTINATION disk (ENTER).
5358
GOSUB to 540DH to show the prompt at Register Pair HL and wait for a key, only for a backup with one drive.
535B
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
535E
LD C,A 4F
Copy Register A, the destination drive, into Register C for DISKIO%.
535F
LD A,(5CB7H) 3A B7 5C
Load Register A with the first cylinder of the run from 5CB7H.
5362
LD D,A 57
Copy Register A into Register D, the cylinder to write.
5363
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH.
5366
LD IX,5D32H DD 21 32 5D
Point Index Register IX to 5D32H, the table of the sector marks, from its start.
536A
GOSUB to 5801H to find the next cylinder from Register D on that has a granule to copy (the same cylinders as the read).
536D
GOSUB to 544CH to write the granules to copy of cylinder Register D from the buffer at Register Pair HL.
5370
If the NZ FLAG is set (a write error), JUMP to 55F9H for the message Destination disk WRITE ERROR!.
5373
GOSUB to 5800H to step Register D to the next cylinder and find the next one to copy.
5376
LD A,(5CB6H) 3A B6 5C
Load Register A with the end of the run from 5CB6H.
5379
DEC A 3D
DECrement Register A by 1, to the last cylinder of the run.
537A
CP D BA
Compare Register A against Register D: the NC FLAG while Register D is not past the run.
537B
If the NC FLAG is set (more of the run to write), JUMP to 536AH.
537D
LD A,(5CB7H) 3A B7 5C
Load Register A with the first cylinder of the run from 5CB7H.
5380
LD D,A 57
Copy Register A into Register D, the cylinder to verify.
5381
GOSUB to 5801H to find the next cylinder from Register D on that has a granule to copy.
5384
GOSUB to 5483H to verify (read back) the granules to copy of cylinder Register D on the destination.
5387
If the NZ FLAG is set (a read error on the destination), JUMP to 55F9H for the message Destination disk WRITE ERROR!.
538A
GOSUB to 5800H to step Register D to the next cylinder and find the next one to copy.
538D
LD A,(5CB6H) 3A B6 5C
Load Register A with the end of the run from 5CB6H.
5390
DEC A 3D
DECrement Register A by 1, to the last cylinder of the run.
5391
CP D BA
Compare Register A against Register D: the NC FLAG while Register D is not past the run.
5392
If the NC FLAG is set (more of the run to verify), JUMP to 5381H.
5394
JUMP to 5320H for the next run of cylinders to read, write and verify.

5396H - The Directory Cylinder

Reads the source's directory cylinder (its allocated granules) into the buffer, clears the modified flag of every directory entry there (the 3.51 patch, 53B3H-53CBH), writes it back to the source unless the source is write protected, puts the destination's new GAT (6000H) in place of the source's, and writes the cylinder to the destination. The patch blocks of the file load new code over 53B3H-53CBH: the 3.50 code (D9 2A BB 5C 24 24 2C FD 7E 0E D6 02 47 CB B6 3E 20 85 6F 30 F8 24 10 F5 D9) cleared bit 6 of byte +01H of every entry with the registers kept by EXX, also in an extended entry (FXDE), where byte +01H is the link back to the first entry; the new code skips the FXDEs.

5396
LD HL,5ACEH 21 CE 5A
Point Register Pair HL to 5ACEH, the prompt Insert SOURCE disk (ENTER).
5399
GOSUB to 540DH to show the prompt at Register Pair HL and wait for a key, only for a backup with one drive.
539C
LD A,(5CB2H) 3A B2 5C
Load Register A with the source drive from 5CB2H.
539F
LD C,A 4F
Copy Register A, the source drive, into Register C.
53A0
GOSUB to 581CH to give drive Register C the source's geometry; Index Register IY returns its drive control table.
53A3
LD D,(IY+12H) FD 56 12
Load Register D with the directory cylinder from Index Register IY+12H.
53A6
LD IX,5D32H DD 21 32 5D
Point Index Register IX to 5D32H, the table of the sector marks, from its start.
53AA
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH.
53AD
GOSUB to 5415H to read the allocated granules of the directory cylinder Register D into the buffer at Register Pair HL.
53B0
If the NZ FLAG is set (a read error), JUMP to 55F9H for the message Destination disk WRITE ERROR! (not Source disk READ ERROR!).
53B3
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH: directory sector 0, the GAT (patch code from here to 53CBH).
53B6
LD B,(IY+0EH) FD 46 0E
Load Register B with the directory length from Index Register IY+0EH, in sectors.
53B9
DEC B 05
DECrement Register B by 1, for the GAT, directory sector 0.
53BA
DEC B 05
DECrement Register B by 1, for the HIT: Register B is the count of sectors of directory entries.
53BB
INC H 24
INCrement Register H by 1, past the GAT; with the INC H below Register Pair HL is the first entry sector.
53BC
INC H 24
INCrement Register H by 1, to the next sector of the directory in the buffer.
53BD
BIT 7,(HL) CB 7E
Test bit 7 of the flag byte (+00H) of the entry at Register Pair HL, set in an extended entry (FXDE).
53BF
INC HL 23
INCrement Register Pair HL by 1, to byte +01H of the entry.
53C0
If the NZ FLAG is set (an FXDE, whose byte +01H is the link back), JUMP to 53C4H to leave it.
53C2
RES 6,(HL) CB B6
Reset bit 6 of byte +01H at Register Pair HL, the modified flag of the file.
53C4
LD A,1FH 3E 1F
Load Register A with 1FH, the distance from byte +01H to the next entry.
53C6
ADD A,L 85
ADD Register L to Register A: the low byte of the next entry, with the C FLAG past the end of the sector.
53C7
LD L,A 6F
Copy Register A into Register L: Register Pair HL is the next entry.
53C8
If the NC FLAG is set (more entries in this sector), JUMP to 53BDH.
53CA
DECrement Register B and, while it is not zero, JUMP to 53BCH for the next sector of entries (DJNZ).
53CC
LD A,(5CB9H) 3A B9 5C
Load Register A with the write protect flag of the source from 5CB9H.
53CF
OR A B7
OR Register A against itself: the NZ FLAG when the source diskette is write protected.
53D0
If the NZ FLAG is set (write protected), JUMP to 53DFH: the source's directory is not rewritten.
53D2
LD IX,5D32H DD 21 32 5D
Point Index Register IX to 5D32H, the table of the sector marks of the directory cylinder.
53D6
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH.
53D9
GOSUB to 544CH to write the directory cylinder Register D back to the source drive Register C, with the flags cleared.
53DC
If the NZ FLAG is set (a write error), JUMP to 55F9H for the message Destination disk WRITE ERROR!.
53DF
LD HL,5AE9H 21 E9 5A
Point Register Pair HL to 5AE9H, the prompt Insert DESTINATION disk (ENTER).
53E2
GOSUB to 540DH to show the prompt at Register Pair HL and wait for a key, only for a backup with one drive.
53E5
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set (EXX), to keep the drive and cylinder.
53E6
LD HL,6000H 21 00 60
Point Register Pair HL to 6000H, the destination's new GAT.
53E9
LD DE,(5CBBH) ED 5B BB 5C
Load Register Pair DE with the start of the buffer from 5CBBH-5CBCH, where the source's GAT was read.
53ED
LD BC,0100H 01 00 01
Load Register Pair BC with 0100H, the 256 bytes of a GAT.
53F0
LDIR ED B0
Copy the destination's GAT from Register Pair HL to Register Pair DE (LDIR, Register Pair BC the count) over the source's.
53F2
EXX D9
Exchange Register Pairs BC, DE and HL with the alternate set (EXX): the drive and cylinder are back.
53F3
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
53F6
LD C,A 4F
Copy Register A, the destination drive, into Register C.
53F7
LD IX,5D32H DD 21 32 5D
Point Index Register IX to 5D32H, the table of the sector marks of the directory cylinder.
53FB
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH.
53FE
GOSUB to 544CH to write the directory cylinder Register D to the destination drive Register C.
5401
If the NZ FLAG is set (a write error), JUMP to 55F9H for the message Destination disk WRITE ERROR!.
5404
LD HL,5B09H 21 09 5B
Point Register Pair HL to 5B09H, the prompt Insert SYSTEM disk (ENTER), for the end of BACKUP.
5407
GOSUB to 5612H to have both drives logged again and prompt for the system disk when drive 0 was used.
540A
JUMP to 402DH, EXIT@, back to the DOS: the backup is done.

540DH - The Prompt for a Disk

Only for a backup with one drive (5CBAH = 00H): shows the flashing prompt at Register Pair HL (58DAH) and waits for a key. With two drives it does nothing.

540D
LD A,(5CBAH) 3A BA 5C
Load Register A with the one drive flag from 5CBAH: 00H when the source and destination are the same drive.
5410
OR A B7
OR Register A against itself: the Z FLAG for a backup with one drive.
5411
If the Z FLAG is set (one drive), GOSUB to 58DAH to flash the prompt at Register Pair HL until a key is pressed.
5414
RET C9
RETurn to the caller with Register Pair HL past the prompt or as it was.

5415H - The Read Pass

Reads the granules to copy of cylinder Register D of drive Register C into the buffer at Register Pair HL, one page a sector, and stores a mark for each sector at Index Register IX (00H, or 01H for a sector with the directory's data address mark, from DISKIO%'s code 06H less 05H). It shows READING and the cylinder first. Returns the Z FLAG, or the NZ FLAG with Register A = the DISKIO% error.

5415
PUSH HL E5
Save Register Pair HL, the place in the buffer, to the top of the stack.
5416
LD HL,5A8DH 21 8D 5A
Point Register Pair HL to 5A8DH, the text READING that starts the line of the pass.
5419
GOSUB to 58C1H to show the text at Register Pair HL and then Cylinder with the cylinder Register D.
541C
GOSUB to 581CH to give drive Register C the source's geometry; Index Register IY returns its drive control table.
541F
POP HL E1
Restore Register Pair HL, the place in the buffer, from the top of the stack.
5420
LD E,00H 1E 00
Load Register E with 00H, the first granule of the cylinder.
5422
GOSUB to 580EH to load Register A with the granules to copy of cylinder Register D, a bit for each.
5425
GOSUB to 594AH to test bit Register E of Register A: the NZ FLAG when granule Register E is to be copied.
5428
If the NZ FLAG is set (a granule to copy), GOSUB to 5434H to read it into the buffer at Register Pair HL.
542B
RET NZ C0
If the NZ FLAG is set (a read error, Register A the code), RETurn to the caller.
542C
LD A,(IY+10H) FD 7E 10
Load Register A with the granules per cylinder from Index Register IY+10H.
542F
INC E 1C
INCrement Register E by 1, to the next granule.
5430
CP E BB
Compare Register A against Register E: the Z FLAG after the last granule of the cylinder.
5431
If the NZ FLAG is set (more granules), JUMP to 5422H.
5433
RET C9
RETurn to the caller with the Z FLAG: the cylinder is read.

5434H - Read a Granule

Reads the sectors of granule Register E of cylinder Register D into the buffer from Register Pair HL on (Register H stepped once a sector), storing each sector's mark at Index Register IX. Register Pair DE is kept.

5434
PUSH DE D5
Save Register Pair DE, the cylinder and the granule, to the top of the stack.
5435
GOSUB to 54B9H to load Register E with the first sector of granule Register E.
5438
LD B,(IY+0FH) FD 46 0F
Load Register B with the sectors per granule from Index Register IY+0FH, the count of sectors to read.
543B
GOSUB to 54C3H to read sector Register E of cylinder Register D to Register Pair HL: Register A the mark or the error.
543E
If the NZ FLAG is set (a read error), JUMP to 544AH with Register A the error code.
5440
LD (IX+00H),A DD 77 00
Store Register A, the sector's mark (00H or 01H), at Index Register IX+00H for the write pass.
5443
INC H 24
INCrement Register H by 1, to the next page of the buffer.
5444
INC E 1C
INCrement Register E by 1, to the next sector.
5445
INC IX DD 23
INCrement Index Register IX by 1, to the mark of the next sector.
5447
DECrement Register B and, while it is not zero, JUMP to 543BH for the next sector (DJNZ).
5449
XOR A AF
Load Register A with 00H by XORing it with itself, and set the Z FLAG: the granule is read.
544A
POP DE D1
Restore Register Pair DE, the cylinder and the granule, from the top of the stack.
544B
RET C9
RETurn to the caller with the Z FLAG, or the NZ FLAG and Register A the error code.

544CH - The Write Pass

Writes the granules to copy of cylinder Register D to drive Register C from the buffer at Register Pair HL, each sector with the mark kept at Index Register IX in the read pass (54D0H: DWRITE, or DWRITA for the directory's data address mark). It shows WRITING and the cylinder first.

544C
PUSH HL E5
Save Register Pair HL, the place in the buffer, to the top of the stack.
544D
LD HL,5A9AH 21 9A 5A
Point Register Pair HL to 5A9AH, the text WRITING that starts the line of the pass.
5450
GOSUB to 58C1H to show the text at Register Pair HL and then Cylinder with the cylinder Register D.
5453
GOSUB to 581CH to give drive Register C the source's geometry; Index Register IY returns its drive control table.
5456
POP HL E1
Restore Register Pair HL, the place in the buffer, from the top of the stack.
5457
LD E,00H 1E 00
Load Register E with 00H, the first granule of the cylinder.
5459
GOSUB to 580EH to load Register A with the granules to copy of cylinder Register D, a bit for each.
545C
GOSUB to 594AH to test bit Register E of Register A: the NZ FLAG when granule Register E is to be copied.
545F
If the NZ FLAG is set (a granule to copy), GOSUB to 546BH to write it from the buffer at Register Pair HL.
5462
RET NZ C0
If the NZ FLAG is set (a write error, Register A the code), RETurn to the caller.
5463
LD A,(IY+10H) FD 7E 10
Load Register A with the granules per cylinder from Index Register IY+10H.
5466
INC E 1C
INCrement Register E by 1, to the next granule.
5467
CP E BB
Compare Register A against Register E: the Z FLAG after the last granule of the cylinder.
5468
If the NZ FLAG is set (more granules), JUMP to 5459H.
546A
RET C9
RETurn to the caller with the Z FLAG: the cylinder is written.

546BH - Write a Granule

Writes the sectors of granule Register E of cylinder Register D from the buffer at Register Pair HL, each with the mark at Index Register IX. Register Pair DE is kept.

546B
PUSH DE D5
Save Register Pair DE, the cylinder and the granule, to the top of the stack.
546C
GOSUB to 54B9H to load Register E with the first sector of granule Register E.
546F
LD B,(IY+0FH) FD 46 0F
Load Register B with the sectors per granule from Index Register IY+0FH, the count of sectors to write.
5472
LD A,(IX+00H) DD 7E 00
Load Register A with the mark of the sector from Index Register IX+00H (00H or 01H).
5475
GOSUB to 54D0H to write sector Register E of cylinder Register D from Register Pair HL with the mark in Register A.
5478
If the NZ FLAG is set (a write error), JUMP to 5481H with Register A the error code.
547A
INC H 24
INCrement Register H by 1, to the next page of the buffer.
547B
INC E 1C
INCrement Register E by 1, to the next sector.
547C
INC IX DD 23
INCrement Index Register IX by 1, to the mark of the next sector.
547E
DECrement Register B and, while it is not zero, JUMP to 5472H for the next sector (DJNZ).
5480
XOR A AF
Load Register A with 00H by XORing it with itself, and set the Z FLAG: the granule is written.
5481
POP DE D1
Restore Register Pair DE, the cylinder and the granule, from the top of the stack.
5482
RET C9
RETurn to the caller with the Z FLAG, or the NZ FLAG and Register A the error code.

5483H - The Verify Pass

Reads back the granules to copy of cylinder Register D of drive Register C (54A2H), each sector into the first page of the buffer: it checks that every sector can be read, but does not compare the data with what was written. It shows VERIFYING and the cylinder first.

5483
PUSH HL E5
Save Register Pair HL, the place in the buffer, to the top of the stack.
5484
LD HL,5AA7H 21 A7 5A
Point Register Pair HL to 5AA7H, the text VERIFYING that starts the line of the pass.
5487
GOSUB to 58C1H to show the text at Register Pair HL and then Cylinder with the cylinder Register D.
548A
GOSUB to 581CH to give drive Register C the source's geometry; Index Register IY returns its drive control table.
548D
POP HL E1
Restore Register Pair HL, the place in the buffer, from the top of the stack.
548E
LD E,00H 1E 00
Load Register E with 00H, the first granule of the cylinder.
5490
GOSUB to 580EH to load Register A with the granules to copy of cylinder Register D, a bit for each.
5493
GOSUB to 594AH to test bit Register E of Register A: the NZ FLAG when granule Register E is to be copied.
5496
If the NZ FLAG is set (a granule to copy), GOSUB to 54A2H to read it back.
5499
RET NZ C0
If the NZ FLAG is set (a read error, Register A the code), RETurn to the caller.
549A
LD A,(IY+10H) FD 7E 10
Load Register A with the granules per cylinder from Index Register IY+10H.
549D
INC E 1C
INCrement Register E by 1, to the next granule.
549E
CP E BB
Compare Register A against Register E: the Z FLAG after the last granule of the cylinder.
549F
If the NZ FLAG is set (more granules), JUMP to 5490H.
54A1
RET C9
RETurn to the caller with the Z FLAG: the cylinder is verified.

54A2H - Verify a Granule

Reads every sector of granule Register E of cylinder Register D into the page at (5CBBH), the start of the buffer. Also used after formatting (5785H) to find the flawed granules. Register Pairs DE and HL are kept.

54A2
PUSH DE D5
Save Register Pair DE, the cylinder and the granule, to the top of the stack.
54A3
PUSH HL E5
Save Register Pair HL to the top of the stack.
54A4
GOSUB to 54B9H to load Register E with the first sector of granule Register E.
54A7
LD B,(IY+0FH) FD 46 0F
Load Register B with the sectors per granule from Index Register IY+0FH, the count of sectors to read.
54AA
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH: every sector is read into the same page.
54AD
GOSUB to 54C3H to read sector Register E of cylinder Register D to Register Pair HL.
54B0
If the NZ FLAG is set (a read error), JUMP to 54B6H with Register A the error code.
54B2
INC E 1C
INCrement Register E by 1, to the next sector.
54B3
DECrement Register B and, while it is not zero, JUMP to 54AAH for the next sector (DJNZ).
54B5
XOR A AF
Load Register A with 00H by XORing it with itself, and set the Z FLAG: the granule reads back.
54B6
POP HL E1
Restore Register Pair HL from the top of the stack.
54B7
POP DE D1
Restore Register Pair DE, the cylinder and the granule, from the top of the stack.
54B8
RET C9
RETurn to the caller with the Z FLAG, or the NZ FLAG and Register A the error code.

54B9H - The First Sector of a Granule

Register E = granule Register E times the sectors per granule (DCT+0FH); Register D is kept.

54B9
LD A,(IY+0FH) FD 7E 0F
Load Register A with the sectors per granule from Index Register IY+0FH.
54BC
PUSH DE D5
Save Register Pair DE, the cylinder in Register D, to the top of the stack.
54BD
GOSUB to 4934H, SYS0/SYS's 8 bit multiply: Register A = Register A times Register E, the first sector.
54C0
POP DE D1
Restore Register Pair DE, the cylinder and the granule, from the top of the stack.
54C1
LD E,A 5F
Copy Register A, the first sector of the granule, into Register E.
54C2
RET C9
RETurn to the caller with Register E the first sector of the granule.

54C3H - Read a Sector

DREAD (function 03H) of sector Register E, cylinder Register D, drive Register C to Register Pair HL. Codes 01H-05H are errors (the NZ FLAG); 00H returns Register A = 00H with the Z FLAG; a code of 06H or more (06H: the record type of the directory's data address mark) returns the Z FLAG with Register A = the code less 05H, the sector's mark.

54C3
LD A,03H 3E 03
Load Register A with 03H, the function DREAD of DISKIO%: read a sector.
54C5
GOSUB to 4485H, DISKIO%, to read sector Register E of cylinder Register D of drive Register C to Register Pair HL.
54C8
RET Z C8
If the Z FLAG is set (read with no error, Register A = 00H), RETurn to the caller.
54C9
CP 06H FE 06
Compare Register A against 06H, the first code that is not an error here.
54CB
RET C D8
If the C FLAG is set (a code 01H-05H, a read error), RETurn to the caller with the NZ FLAG.
54CC
SUB 05H D6 05
SUBtract 05H from Register A: 01H for the code 06H, the directory's data address mark.
54CE
CP A BF
Compare Register A against itself, to set the Z FLAG: the sector is read and Register A is its mark.
54CF
RET C9
RETurn to the caller with the Z FLAG and Register A the mark of the sector.

54D0H - Write a Sector

Writes sector Register E of cylinder Register D of drive Register C from Register Pair HL: DWRITE (function 05H) for the mark 00H in Register A, DWRITA (08H, with the directory's data address mark) for any other mark.

54D0
OR A B7
OR Register A against itself: the Z FLAG for the mark 00H, an ordinary sector.
54D1
LD A,05H 3E 05
Load Register A with 05H, the function DWRITE of DISKIO%, without changing the flags.
54D3
If the Z FLAG is set (an ordinary sector), JUMP to 54D7H.
54D5
LD A,08H 3E 08
Load Register A with 08H, the function DWRITA of DISKIO%: write with the directory's data address mark.
54D7
GOSUB to 4485H, DISKIO%, to write sector Register E of cylinder Register D of drive Register C from Register Pair HL.
54DA
RET C9
RETurn to the caller with the Z FLAG, or the NZ FLAG and Register A the error code.

54DBH - Format a Cylinder

Formats cylinder Register D of drive Register C with the source's geometry: side 0, then side 1 for a diskette with two sides (Register E = the sectors per track, the first sector of side 1). It shows FORMATTING and the cylinder first.

54DB
LD HL,5AB4H 21 B4 5A
Point Register Pair HL to 5AB4H, the text FORMATTING that starts the line of the pass.
54DE
GOSUB to 58C1H to show the text at Register Pair HL and then Cylinder with the cylinder Register D.
54E1
GOSUB to 581CH to give drive Register C the source's geometry; Index Register IY returns its drive control table.
54E4
PUSH BC C5
Save Register Pair BC, the drive in Register C, to the top of the stack.
54E5
LD E,00H 1E 00
Load Register E with 00H, side 0 (the first sector of side 0).
54E7
GOSUB to 54F8H to format side 0 of cylinder Register D.
54EA
If the NZ FLAG is set (a format error), JUMP to 54F6H.
54EC
LD A,(IY+0CH) FD 7E 0C
Load Register A with the count of surfaces from Index Register IY+0CH.
54EF
DEC A 3D
DECrement Register A by 1: the NZ FLAG for a diskette with two sides.
54F0
LD E,(IY+0DH) FD 5E 0D
Load Register E with the sectors per track from Index Register IY+0DH, the first sector number of side 1.
54F3
If the NZ FLAG is set (two sides), GOSUB to 54F8H to format side 1 of cylinder Register D.
54F6
POP BC C1
Restore Register Pair BC, the drive in Register C, from the top of the stack.
54F7
RET C9
RETurn to the caller with the Z FLAG, or the NZ FLAG and Register A the error code.

54F8H - Make and Write a Track

Builds the image of one track in the buffer at (5CBBH) and writes it with DFORMT (function 09H). The sector order: the interleave Register A from 5847H (2 in single density, 3 in double) is laid out from a starting place that moves by twice the interleave on each track (the skew), into the table at 5D12H (place -> sector number). The image is made from the format description at Register Pair DE: pairs of a count and a byte (55C2H), with the ID fields (FEH, cylinder, side, sector, length code 01H, F7H for the CRC) and 256 data bytes of 6CH after FBH in each sector.

54F8
PUSH BC C5
Save Register Pair BC, the drive in Register C, to the top of the stack.
54F9
PUSH DE D5
Save Register Pair DE, the cylinder and the side's first sector, to the top of the stack.
54FA
LD B,D 42
Load Register B with Register D, the cylinder: the track number for one side.
54FB
LD A,(IY+0CH) FD 7E 0C
Load Register A with the count of surfaces from Index Register IY+0CH.
54FE
DEC A 3D
DECrement Register A by 1: the Z FLAG for a diskette with one side.
54FF
If the Z FLAG is set (one side), JUMP to 5508H with Register B the cylinder.
5501
SLA B CB 20
Shift Register B left by one bit (SLA): twice the cylinder, the track number of side 0.
5503
INC E 1C
INCrement Register E by 1, to test it for zero below without changing it.
5504
DEC E 1D
DECrement Register E by 1: the Z FLAG for side 0 (Register E = 00H).
5505
If the Z FLAG is set (side 0), JUMP to 5508H.
5507
INC B 04
INCrement Register B by 1: the track number of side 1.
5508
GOSUB to 5847H for the format of the track: Register A the interleave, Register Pair DE the format description.
550B
LD E,B 58
Copy Register B, the track number, into Register E for the multiply.
550C
LD B,A 47
Copy Register A, the interleave, into Register B.
550D
ADD A,A 87
ADD Register A to itself: twice the interleave.
550E
GOSUB to 4934H, SYS0/SYS's 8 bit multiply: Register A = Register A times Register E, twice the interleave times the track.
5511
LD E,A 5F
Copy Register A into Register E for the divide.
5512
LD C,(IY+0DH) FD 4E 0D
Load Register C with the sectors per track from Index Register IY+0DH.
5515
LD A,C 79
Copy Register C, the sectors per track, into Register A, the divisor.
5516
GOSUB to 4943H, SYS0/SYS's 8 bit divide: Register E = Register E divided by Register A, the remainder: the skew.
5519
LD A,E 7B
Load Register A with Register E, the starting place of the first sector on this track.
551A
LD D,B 50
Load Register D with Register B, the interleave, the step between sectors.
551B
LD HL,5D12H 21 12 5D
Point Register Pair HL to 5D12H, the table of the sector order (one byte a place).
551E
LD B,C 41
Load Register B with Register C, the sectors per track, the count of places to clear.
551F
LD (HL),FFH 36 FF
Store FFH at Register Pair HL: the place is free.
5521
INC HL 23
INCrement Register Pair HL by 1, to the next place.
5522
DECrement Register B and, while it is not zero, JUMP to 551FH (DJNZ).
5524
LD E,00H 1E 00
Load Register E with 00H, the first sector number to place.
5526
LD B,C 41
Load Register B with Register C, the count of sectors to place.
5527
CP C B9
Compare Register A, the place, against Register C, the sectors per track: the C FLAG when it is on the track.
5528
If the C FLAG is set (on the track), JUMP to 552BH.
552A
SUB C 91
SUBtract Register C (the sectors per track) from Register A, to wrap the place round.
552B
PUSH DE D5
Save Register Pair DE, the sector number and the interleave, to the top of the stack.
552C
LD HL,5D12H 21 12 5D
Point Register Pair HL to 5D12H, the table of the sector order.
552F
LD E,A 5F
Copy Register A, the place on the track, into Register E for the offset.
5530
LD D,00H 16 00
Load Register D with 00H: Register Pair DE is the place.
5532
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: the byte of the place in the table.
5533
POP DE D1
Restore Register Pair DE, the sector number and the interleave, from the top of the stack.
5534
BIT 7,(HL) CB 7E
Test bit 7 of the place at Register Pair HL: set while the place is free (FFH).
5536
If the NZ FLAG is set (the place is free), JUMP to 553BH.
5538
INC A 3C
INCrement Register A by 1, to try the next place.
5539
JUMP to 5527H to wrap and test the next place.
553B
LD (HL),E 73
Store Register E, the sector number, at the place at Register Pair HL.
553C
INC E 1C
INCrement Register E by 1, to the next sector number.
553D
ADD A,D 82
ADD Register D (the interleave) to Register A: the place of the next sector.
553E
DECrement Register B and, while it is not zero, JUMP to 5527H for the next sector (DJNZ).
5540
POP DE D1
Restore Register Pair DE, the cylinder and the side's first sector, from the top of the stack.
5541
POP BC C1
Restore Register Pair BC, the drive in Register C, from the top of the stack.
5542
PUSH BC C5
Save Register Pair BC, the drive, to the top of the stack again.
5543
PUSH DE D5
Save Register Pair DE, the cylinder and the side, to the top of the stack again.
5544
LD A,E 7B
Load Register A with Register E, the side's first sector: 00H for side 0.
5545
OR A B7
OR Register A against itself: the Z FLAG for side 0.
5546
If the Z FLAG is set (side 0), JUMP to 554AH with Register A = 00H.
5548
LD A,01H 3E 01
Load Register A with 01H, side 1, for the ID fields.
554A
LD (5583H),A 32 83 55
Store Register A, the side, into 5583H, the operand of LD (HL) at 5582H: the side byte of every ID field.
554D
LD A,D 7A
Load Register A with Register D, the cylinder.
554E
LD (5580H),A 32 80 55
Store Register A, the cylinder, into 5580H, the operand of LD (HL) at 557FH: the cylinder byte of every ID field.
5551
GOSUB to 5847H for the format description in Register Pair DE and Register Pair HL = 8001H.
5554
LD A,L 7D
Load Register A with Register L, 01H, the length code of a 256 byte sector.
5555
LD (558CH),A 32 8C 55
Store Register A into 558CH, the operand of LD (HL) at 558BH: the length byte of every ID field.
5558
LD A,H 7C
Load Register A with Register H, 80H, half the bytes of a sector.
5559
LD (559BH),A 32 9B 55
Store Register A into 559BH, the operand of LD B at 559AH: the count of the data loop (two bytes a pass).
555C
LD C,(IY+0DH) FD 4E 0D
Load Register C with the sectors per track from Index Register IY+0DH, the count of sectors to make.
555F
LD HL,5D12H 21 12 5D
Point Register Pair HL to 5D12H, the table of the sector order.
5562
PUSH HL E5
Save Register Pair HL, the place in the sector order, to the top of the stack.
5563
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH, where the track image is made.
5566
GOSUB to 55C2H to store the first group of the description at Register Pair DE into the image at Register Pair HL.
5569
GOSUB to 55C2H to store the next group (the index address mark FCH).
556C
GOSUB to 55C2H to store the next group, the gap after the index address mark.
556F
LD (5574H),DE ED 53 74 55
Store Register Pair DE, the description of a sector, into 5574H-5575H, the operand of LD DE at 5573H.
5573
LD DE,0000H 11 00 00
Point Register Pair DE to the description of a sector (the operand at 5574H, set at 556FH; 0000H as loaded).
5576
GOSUB to 55C2H to store the first group of the gap before the ID field.
5579
GOSUB to 55C2H to store the second group of the gap before the ID field.
557C
LD (HL),FEH 36 FE
Store FEH at Register Pair HL, the ID address mark.
557E
INC HL 23
INCrement Register Pair HL by 1, to the cylinder byte.
557F
LD (HL),00H 36 00
Store the cylinder at Register Pair HL (00H as loaded; the operand 5580H is set at 554EH).
5581
INC HL 23
INCrement Register Pair HL by 1, to the side byte.
5582
LD (HL),00H 36 00
Store the side at Register Pair HL (00H as loaded; the operand 5583H is set at 554AH).
5584
INC HL 23
INCrement Register Pair HL by 1, to the sector byte.
5585
EX (SP),HL E3
Exchange Register Pair HL with the top of the stack (the Stack Pointer's word): Register Pair HL the place in the sector order.
5586
LD A,(HL) 7E
Load Register A with the sector number at Register Pair HL, the next one in the sector order.
5587
INC HL 23
INCrement Register Pair HL by 1, to the next place in the sector order.
5588
EX (SP),HL E3
Exchange Register Pair HL with the top of the stack (the Stack Pointer's word): Register Pair HL the image again.
5589
LD (HL),A 77
Store Register A, the sector number, at Register Pair HL.
558A
INC HL 23
INCrement Register Pair HL by 1, to the length byte.
558B
LD (HL),00H 36 00
Store the length code at Register Pair HL (00H as loaded; the operand 558CH is set to 01H at 5555H).
558D
INC HL 23
INCrement Register Pair HL by 1, past the length byte.
558E
LD (HL),F7H 36 F7
Store F7H at Register Pair HL, the controller's code to write the two CRC bytes of the ID field.
5590
INC HL 23
INCrement Register Pair HL by 1, past the CRC code.
5591
GOSUB to 55C2H to store the first group of the gap after the ID field.
5594
GOSUB to 55C2H to store the second group of the gap after the ID field.
5597
GOSUB to 55C2H to store the third group of the gap after the ID field.
559A
LD B,00H 06 00
Load Register B with the count of the data loop (00H as loaded; the operand 559BH is set to 80H at 5559H).
559C
LD (HL),FBH 36 FB
Store FBH at Register Pair HL, the data address mark.
559E
INC HL 23
INCrement Register Pair HL by 1, to the data of the sector.
559F
LD (HL),6CH 36 6C
Store 6CH at Register Pair HL, the byte a new sector is filled with.
55A1
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the data.
55A2
LD (HL),6CH 36 6C
Store 6CH at Register Pair HL, the second byte of the pass.
55A4
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the data.
55A5
DECrement Register B and, while it is not zero, JUMP to 559FH: 128 passes of two bytes (DJNZ).
55A7
LD (HL),F7H 36 F7
Store F7H at Register Pair HL, the controller's code to write the two CRC bytes of the data field.
55A9
INC HL 23
INCrement Register Pair HL by 1, past the CRC code.
55AA
GOSUB to 55C2H to store the gap after the data field.
55AD
DEC C 0D
DECrement Register C by 1, the count of sectors still to make.
55AE
If the NZ FLAG is set (more sectors), JUMP to 5573H for the next sector.
55B0
GOSUB to 55C2H to store the first group of the gap at the end of the track.
55B3
GOSUB to 55C2H to store the second group of the gap at the end of the track.
55B6
POP DE D1
Restore Register Pair DE from the top of the stack, to drop the place in the sector order.
55B7
POP DE D1
Restore Register Pair DE, the cylinder and the side's first sector, from the top of the stack.
55B8
POP BC C1
Restore Register Pair BC, the drive in Register C, from the top of the stack.
55B9
LD HL,(5CBBH) 2A BB 5C
Load Register Pair HL with the start of the buffer from 5CBBH-5CBCH, the track image.
55BC
LD A,09H 3E 09
Load Register A with 09H, the function DFORMT of DISKIO%: write a track.
55BE
GOSUB to 4485H, DISKIO%, to write the track image at Register Pair HL to cylinder Register D, side Register E, drive Register C.
55C1
RET C9
RETurn to the caller with the Z FLAG, or the NZ FLAG and Register A the error code.

55C2H - Store a Group

Takes a count and a byte from Register Pair DE (a count of 00H is 256) and stores the byte that many times at Register Pair HL; both pointers are left after them.

55C2
LD A,(DE) 1A
Load Register A with the count of the group at Register Pair DE.
55C3
INC DE 13
INCrement Register Pair DE by 1, to the byte of the group.
55C4
LD B,A 47
Copy Register A, the count of the group, into Register B for the DJNZ.
55C5
LD A,(DE) 1A
Load Register A with the byte of the group at Register Pair DE.
55C6
INC DE 13
INCrement Register Pair DE by 1, to the next group.
55C7
LD (HL),A 77
Store Register A, the byte, at Register Pair HL in the track image.
55C8
INC HL 23
INCrement Register Pair HL by 1, to the next byte of the image.
55C9
DECrement Register B and, while it is not zero, JUMP to 55C7H (DJNZ).
55CB
RET C9
RETurn to the caller with Register Pairs DE and HL after the group.

55CCH - The Errors

Each entry points Register Pair HL to its message and goes to 5606H, which shows it, logs both drives again (with the prompt for the system disk when drive 0 was used) and leaves by ABORT@. 55E0H (I/O ERROR! routine aborted!) and 55FEH (Destination disk READ ERROR!) are reached by nothing: a read error in the verify pass and in the source's directory cylinder shows Destination disk WRITE ERROR!.

55CC
LD HL,5B3AH 21 3A 5B
Point Register Pair HL to 5B3AH, the message Drives INCOMPATABLE!.
55CF
JUMP to 5606H to show the message, log the drives again and abort.
55D1
LD HL,5B50H 21 50 5B
Point Register Pair HL to 5B50H, the message Source drive NOT READY!.
55D4
JUMP to 5606H to show the message, log the drives again and abort.
55D6
LD HL,5B69H 21 69 5B
Point Register Pair HL to 5B69H, the message Destination drive NOT READY!.
55D9
JUMP to 5606H to show the message, log the drives again and abort.
55DB
LD HL,5BAAH 21 AA 5B
Point Register Pair HL to 5BAAH, the message Drive NOT SUPPORTED!, for a rigid drive.
55DE
JUMP to 5606H to show the message, log the drives again and abort.
55E0
LD HL,5BDCH 21 DC 5B
Point Register Pair HL to 5BDCH, the message I/O ERROR! routine aborted! (no instruction jumps here).
55E3
JUMP to 5606H to show the message, log the drives again and abort.
55E5
LD HL,5B87H 21 87 5B
Point Register Pair HL to 5B87H, the message Destination disk WRITE PROTECTED!.
55E8
JUMP to 5606H to show the message, log the drives again and abort.
55EA
LD HL,5B24H 21 24 5B
Point Register Pair HL to 5B24H, the message No available memory!.
55ED
JUMP to 5606H to show the message, log the drives again and abort.
55EF
LD HL,5BFAH 21 FA 5B
Point Register Pair HL to 5BFAH, the message BOOT FLAWED! routine aborted!.
55F2
JUMP to 5606H to show the message, log the drives again and abort.
55F4
LD HL,5C1AH 21 1A 5C
Point Register Pair HL to 5C1AH, the message Source disk READ ERROR!.
55F7
JUMP to 5606H to show the message, log the drives again and abort.
55F9
LD HL,5C34H 21 34 5C
Point Register Pair HL to 5C34H, the message Destination disk WRITE ERROR!.
55FC
JUMP to 5606H to show the message, log the drives again and abort.
55FE
LD HL,5C54H 21 54 5C
Point Register Pair HL to 5C54H, the message Destination disk READ ERROR! (no instruction jumps here).
5601
JUMP to 5606H to show the message, log the drives again and abort.
5603
LD HL,5C73H 21 73 5C
Point Register Pair HL to 5C73H, the message BACKUP rejected! Too many FLAWS!.
5606
GOSUB to 58B5H to show the message at Register Pair HL up to its ending 03H.
5609
LD HL,5B09H 21 09 5B
Point Register Pair HL to 5B09H, the prompt Insert SYSTEM disk (ENTER).
560C
GOSUB to 5612H to log both drives again and prompt for the system disk when drive 0 was used.
560F
JUMP to 4030H, ABORT@, back to the DOS with the abort.

5612H - The End

Sets the log flag (bit 0 of DCT+03H) of the source and destination drives, so that the DOS reads their real geometry again on the next access, then flashes the prompt at Register Pair HL (Insert SYSTEM disk) and waits for a key when either drive was drive 0; else it only clears the line.

5612
LD A,(5CB2H) 3A B2 5C
Load Register A with the source drive from 5CB2H.
5615
LD C,A 4F
Copy Register A, the source drive, into Register C.
5616
GOSUB to 448BH, LOCDCT%: Index Register IY = the drive control table of drive Register C.
5619
SET 0,(IY+03H) FD CB 03 C6
Set bit 0 of DCT+03H at Index Register IY+03H, the log flag: the source is logged again.
561D
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
5620
LD C,A 4F
Copy Register A, the destination drive, into Register C.
5621
GOSUB to 448BH, LOCDCT%: Index Register IY = the drive control table of drive Register C.
5624
SET 0,(IY+03H) FD CB 03 C6
Set bit 0 of DCT+03H at Index Register IY+03H, the log flag: the destination is logged again.
5628
INC C 0C
INCrement Register C by 1, to test it for zero below without changing it.
5629
DEC C 0D
DECrement Register C by 1: the Z FLAG when the destination is drive 0.
562A
If the Z FLAG is set (the destination is drive 0), JUMP to 5630H.
562C
LD A,(5CB2H) 3A B2 5C
Load Register A with the source drive from 5CB2H.
562F
OR A B7
OR Register A against itself: the Z FLAG when the source is drive 0.
5630
If the Z FLAG is set (drive 0 was used), JUMP to 58DAH to flash the prompt at Register Pair HL until a key.
5633
JUMP to 5905H to clear the line: drive 0 was not used.

5636H - Read a GAT and Find the Format

Finds the density of drive Register C (567AH), then reads its GAT (SREAD of directory sector 0, which logs the diskette) into Register Pair HL. 563AH, entered after 567AH, is the same without the density test. Sets DCT+13H from the GAT's cylinder count (+CCH plus 35) and returns the Z FLAG with Register C = the format code (bit 0 double density, bit 1 8 inch, bit 2 two sides), Register B = 80H when SREAD had to change the density (cylinder 0 is in another density than the directory, as on a double density Model I system diskette) else 00H, and Register Pair HL = DCT+0BH; or the NZ FLAG and the error code in Register A.

5636
GOSUB to 567AH to find the density of drive Register C from cylinder 0 (a rigid drive ends BACKUP there).
5639
RET NZ C0
If the NZ FLAG is set (sector 2 of cylinder 0 could not be read), RETurn to the caller.
563A
LD B,(IY+0BH) FD 46 0B
Load Register B with the density byte DCT+0BH from Index Register IY+0BH, as found on cylinder 0.
563D
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder, the GAT.
563F
LD A,06H 3E 06
Load Register A with 06H, the function SREAD of DISKIO%: read a sector of the directory cylinder.
5641
GOSUB to 4485H, DISKIO%, to read the GAT of drive Register C to Register Pair HL (the diskette is logged first).
5644
RET NZ C0
If the NZ FLAG is set (the GAT could not be read), RETurn to the caller with the error code in Register A.
5645
LD DE,00CCH 11 CC 00
Load Register Pair DE with 00CCH, the offset of the GAT's cylinder count.
5648
ADD HL,DE 19
ADD Register Pair DE to Register Pair HL: +CCH of the GAT, the formatted cylinder count less 35.
5649
LD A,(HL) 7E
Load Register A with the byte at Register Pair HL, the GAT's +CCH.
564A
ADD A,23H C6 23
ADD 23H (35) to Register A: the count of cylinders of the diskette.
564C
LD (IY+13H),A FD 77 13
Store Register A, the count of cylinders, into DCT+13H at Index Register IY+13H.
564F
LD A,(IY+0BH) FD 7E 0B
Load Register A with the density byte DCT+0BH from Index Register IY+0BH, as SREAD left it.
5652
AND 80H E6 80
AND Register A with 80H to keep bit 7, double density.
5654
LD C,A 4F
Copy Register A, the density bit (80H or 00H), into Register C.
5655
RLC C CB 01
Rotate Register C left (RLC): bit 0 of the format code, double density.
5657
XOR B A8
XOR Register A with Register B, the density found on cylinder 0.
5658
AND 80H E6 80
AND Register A with 80H: 80H when SREAD changed the density.
565A
LD B,A 47
Copy Register A into Register B, the density flag of cylinder 0.
565B
LD A,(IY+03H) FD 7E 03
Load Register A with the flags DCT+03H from Index Register IY+03H.
565E
AND 80H E6 80
AND Register A with 80H to keep bit 7, an 8 inch drive.
5660
RLCA 07
Rotate Register A left (RLCA): the 8 inch bit to bit 0.
5661
RLCA 07
Rotate Register A left (RLCA) again: the 8 inch bit to bit 1.
5662
OR C B1
OR Register A with Register C, the double density bit.
5663
LD C,A 4F
Copy Register A into Register C, the format code so far.
5664
LD A,(IY+0CH) FD 7E 0C
Load Register A with the count of surfaces from Index Register IY+0CH.
5667
DEC A 3D
DECrement Register A by 1: 01H for two sides.
5668
RLCA 07
Rotate Register A left (RLCA): the sides bit to bit 1.
5669
RLCA 07
Rotate Register A left (RLCA) again: the sides bit to bit 2.
566A
OR C B1
OR Register A with Register C, the format code so far.
566B
LD C,A 4F
Copy Register A into Register C, the whole format code.
566C
PUSH IY FD E5
Save Index Register IY, the drive control table, to the top of the stack.
566E
LD DE,000BH 11 0B 00
Load Register Pair DE with 000BH, the offset of the drive control table's perishable bytes.
5671
ADD IY,DE FD 19
ADD Register Pair DE to Index Register IY: DCT+0BH.
5673
PUSH IY FD E5
Save Index Register IY (DCT+0BH) to the top of the stack.
5675
POP HL E1
Restore Register Pair HL from the top of the stack: Register Pair HL = DCT+0BH.
5676
POP IY FD E1
Restore Index Register IY, the drive control table, from the top of the stack.
5678
XOR A AF
Load Register A with 00H by XORing it with itself, and set the Z FLAG: the GAT is read.
5679
RET C9
RETurn to the caller with the Z FLAG, Register C the format code and Register B the density flag.

567AH - Find the Density

LOCDCT% for drive Register C; a rigid drive (bit 5 of DCT+03H) ends BACKUP with Drive NOT SUPPORTED!. Sets the log flag, then verifies sector 2 of cylinder 0 (DVERF) in single density, and if that fails in double density: the density bit 7 of DCT+0BH is left as the one that worked. Returns the Z FLAG when one of them worked.

567A
GOSUB to 448BH, LOCDCT%: Index Register IY = the drive control table of drive Register C.
567D
BIT 5,(IY+03H) FD CB 03 6E
Test bit 5 of DCT+03H at Index Register IY+03H, set for a rigid drive.
5681
If the NZ FLAG is set (a rigid drive), JUMP to 55DBH for the message Drive NOT SUPPORTED!.
5684
SET 0,(IY+03H) FD CB 03 C6
Set bit 0 of DCT+03H at Index Register IY+03H, the log flag: SREAD will log the diskette.
5688
RES 7,(IY+0BH) FD CB 0B BE
Reset bit 7 of DCT+0BH at Index Register IY+0BH: try single density first.
568C
LD DE,0002H 11 02 00
Load Register Pair DE with 0002H: Register D cylinder 0, Register E sector 2.
568F
LD A,01H 3E 01
Load Register A with 01H, the function DHOME of DISKIO%: restore the head to cylinder 0.
5691
GOSUB to 4485H, DISKIO%, to restore the head of drive Register C.
5694
LD A,04H 3E 04
Load Register A with 04H, the function DVERF of DISKIO%: verify a sector.
5696
GOSUB to 4485H, DISKIO%, to verify sector Register E of cylinder Register D of drive Register C.
5699
RET Z C8
If the Z FLAG is set (it reads in single density), RETurn to the caller.
569A
SET 7,(IY+0BH) FD CB 0B FE
Set bit 7 of DCT+0BH at Index Register IY+0BH: try double density.
569E
LD A,04H 3E 04
Load Register A with 04H, the function DVERF of DISKIO%: verify a sector.
56A0
GOSUB to 4485H, DISKIO%, to verify sector Register E of cylinder Register D of drive Register C again.
56A3
RET C9
RETurn to the caller with the Z FLAG, or the NZ FLAG when neither density reads.

56A4H - Prepare the Destination

Makes 5CB8H, the GAT byte of an empty cylinder (a bit set for each granule a cylinder does not have). Then a destination that cannot be read in either density is formatted (5743H). Otherwise the answer to Diskette contains data, use or not ? is taken from USE= (its first character) or from the prompt: N ends BACKUP, F formats, Y or U uses the diskette (56EAH). A destination whose GAT cannot be read, or with fewer cylinders, another density or another count of sides is formatted; one of another drive size (8 inch or not) ends BACKUP with Drives INCOMPATABLE!. Else only cylinder 0 is formatted when its density flag differs, and the old directory cylinder when the directory is elsewhere; the destination's own lock outs are kept. The new GAT is made at 6000H (57B7H).

56A4
LD E,(IY+10H) FD 5E 10
Load Register E with the granules per cylinder from Index Register IY+10H, the source's.
56A7
LD A,FFH 3E FF
Load Register A with FFH, every granule bit set.
56A9
DEC E 1D
DECrement Register E by 1, to the last granule of a cylinder.
56AA
GOSUB to 593AH to reset bit Register E of Register A: a granule the cylinder has.
56AD
DEC E 1D
DECrement Register E by 1, to the granule before it.
56AE
If the P FLAG is set (Register E not below 0), JUMP to 56AAH.
56B1
LD (5CB8H),A 32 B8 5C
Store Register A into 5CB8H, the GAT byte of an empty cylinder (FCH for two granules a cylinder).
56B4
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
56B7
LD C,A 4F
Copy Register A, the destination drive, into Register C.
56B8
LD HL,6000H 21 00 60
Point Register Pair HL to 6000H, the buffer of the destination's GAT.
56BB
GOSUB to 567AH to find the density of drive Register C from cylinder 0.
56BE
If the NZ FLAG is set (the destination cannot be read: blank), JUMP to 5743H to format all of it.
56C1
LD HL,0000H 21 00 00
Load Register Pair HL with the address of the USE string: 0000H unless EVAL@ stored the address here (56C2H).
56C4
LD A,H 7C
Load Register A with Register H, the high byte of the USE string's address.
56C5
OR L B5
OR Register A with Register L: the Z FLAG when no USE string was given.
56C6
If the Z FLAG is set (no USE string), JUMP to 56CEH for the prompt.
56C8
GOSUB to 5891H to copy the USE string from Register Pair HL to 5CC6H; Register Pair HL = 5CC6H.
56CB
LD A,(HL) 7E
Load Register A with the first character of the USE string at Register Pair HL.
56CC
JUMP to 56D6H to take the first character of the USE string as the answer.
56CE
LD B,03H 06 03
Load Register B with 03H, the most characters the reply to the prompt may have.
56D0
LD HL,5A67H 21 67 5A
Point Register Pair HL to 5A67H, the prompt Diskette contains data, use or not ?, followed by its count of spaces.
56D3
GOSUB to 5878H to show the prompt at Register Pair HL and take the reply; Register A its first character.
56D6
GOSUB to 58D1H to make the letter in Register A upper case.
56D9
CP 4EH FE 4E
Compare Register A against 4EH, an N: do not use the diskette.
56DB
If the Z FLAG is set (N), JUMP to 5404H to end BACKUP without copying.
56DE
CP 46H FE 46
Compare Register A against 46H, an F: format the diskette.
56E0
If the Z FLAG is set (F), JUMP to 5743H to format all of it.
56E2
CP 55H FE 55
Compare Register A against 55H, a U: use the diskette.
56E4
If the Z FLAG is set (U), JUMP to 56EAH to use the diskette as it is.
56E6
CP 59H FE 59
Compare Register A against 59H, a Y: use the diskette.
56E8
If the NZ FLAG is set (any other answer), JUMP to 56CEH to ask again.
56EA
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
56ED
LD C,A 4F
Copy Register A, the destination drive, into Register C.
56EE
LD HL,6000H 21 00 60
Point Register Pair HL to 6000H, the buffer of the destination's GAT.
56F1
GOSUB to 563AH to read the destination's GAT to Register Pair HL: Register C its format code, Register B its density flag.
56F4
If the NZ FLAG is set (its GAT cannot be read), JUMP to 5743H to format all of it.
56F6
LD A,(5CB4H) 3A B4 5C
Load Register A with the source's format code from 5CB4H.
56F9
XOR C A9
XOR Register A with Register C, the destination's format code: the bits that differ.
56FA
AND 02H E6 02
AND Register A with 02H to keep bit 1, the 8 inch bit.
56FC
If the NZ FLAG is set (one drive is 8 inch and the other not), JUMP to 55CCH for the message Drives INCOMPATABLE!.
56FF
LD HL,59A5H 21 A5 59
Point Register Pair HL to 59A5H, the source's count of cylinders (DCT+13H as kept).
5702
LD A,(IY+13H) FD 7E 13
Load Register A with the destination's count of cylinders from Index Register IY+13H.
5705
CP (HL) BE
Compare Register A against the source's count at Register Pair HL: the C FLAG when the destination has fewer.
5706
If the C FLAG is set (fewer cylinders), JUMP to 5743H to format all of it.
5708
LD (HL),A 77
Store Register A, the destination's count, at Register Pair HL (59A5H): its GAT keeps all its cylinders.
5709
LD A,(5CB4H) 3A B4 5C
Load Register A with the source's format code from 5CB4H.
570C
XOR C A9
XOR Register A with Register C, the destination's format code: the bits that differ.
570D
AND 01H E6 01
AND Register A with 01H to keep bit 0, the density.
570F
If the NZ FLAG is set (another density), JUMP to 5743H to format all of it.
5711
LD A,(5CB4H) 3A B4 5C
Load Register A with the source's format code from 5CB4H.
5714
XOR C A9
XOR Register A with Register C, the destination's format code: the bits that differ.
5715
AND 04H E6 04
AND Register A with 04H to keep bit 2, two sides.
5717
If the NZ FLAG is set (another count of sides), JUMP to 5743H to format all of it.
5719
LD A,(5CB5H) 3A B5 5C
Load Register A with the source's density flag of cylinder 0 from 5CB5H.
571C
CP B B8
Compare Register A against Register B, the destination's: the Z FLAG when they are the same.
571D
LD B,(IY+12H) FD 46 12
Load Register B with the destination's directory cylinder from Index Register IY+12H.
5720
If the Z FLAG is set (cylinder 0 has the same density), JUMP to 572EH.
5722
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
5725
LD C,A 4F
Copy Register A, the destination drive, into Register C.
5726
LD D,00H 16 00
Load Register D with 00H, cylinder 0, the one cylinder to format here.
5728
GOSUB to 54DBH to format cylinder Register D of drive Register C as the source has it.
572B
If the NZ FLAG is set (a format error), JUMP to 55F9H for the message Destination disk WRITE ERROR!.
572E
LD A,(59A4H) 3A A4 59
Load Register A with the source's directory cylinder from 59A4H (DCT+12H as kept).
5731
CP B B8
Compare Register A against Register B, the destination's directory cylinder.
5732
If the Z FLAG is set (the directory is on the same cylinder), JUMP to 57B7H to make the new GAT.
5735
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
5738
LD C,A 4F
Copy Register A, the destination drive, into Register C.
5739
LD D,B 50
Load Register D with Register B, the destination's old directory cylinder.
573A
GOSUB to 54DBH to format cylinder Register D of drive Register C, wiping the old directory.
573D
If the NZ FLAG is set (a format error), JUMP to 55F9H for the message Destination disk WRITE ERROR!.
5740
JUMP to 57B7H to make the new GAT of the destination at 6000H.

5743H - Format the Destination

Makes an empty GAT at 6000H (FFH, with the empty cylinder byte 5CB8H for each cylinder in the allocation and lock out tables), formats every cylinder with the source's geometry, then verifies each granule from the last cylinder down (54A2H): a granule that cannot be read is shown as GRAN FLAWED! Locked out! and set in both tables. A flawed granule 0 of cylinder 0 (the boot) ends BACKUP.

5743
LD HL,6000H 21 00 60
Point Register Pair HL to 6000H, the buffer of the destination's new GAT.
5746
LD (HL),FFH 36 FF
Store FFH at Register Pair HL: every byte of the new GAT starts as FFH.
5748
INC L 2C
INCrement Register L by 1, to the next byte of the GAT.
5749
If the NZ FLAG is set (not past the end of the page), JUMP to 5746H.
574B
LD A,(5CB8H) 3A B8 5C
Load Register A with the GAT byte of an empty cylinder from 5CB8H.
574E
LD E,A 5F
Copy Register A, the GAT byte of an empty cylinder, into Register E.
574F
LD A,(59A5H) 3A A5 59
Load Register A with the count of cylinders from 59A5H.
5752
LD B,A 47
Copy Register A, the count of cylinders, into Register B.
5753
LD (HL),E 73
Store Register E, the empty cylinder byte, at Register Pair HL in the allocation table.
5754
INC L 2C
INCrement Register L by 1, to the next cylinder.
5755
DECrement Register B and, while it is not zero, JUMP to 5753H (DJNZ).
5757
LD HL,6060H 21 60 60
Point Register Pair HL to 6060H, the lock out table of the new GAT (+60H).
575A
LD B,A 47
Load Register B with Register A, the count of cylinders.
575B
LD (HL),E 73
Store Register E, the empty cylinder byte, at Register Pair HL in the lock out table.
575C
INC L 2C
INCrement Register L by 1, to the next cylinder.
575D
DECrement Register B and, while it is not zero, JUMP to 575BH (DJNZ).
575F
LD A,(5CB3H) 3A B3 5C
Load Register A with the destination drive from 5CB3H.
5762
LD C,A 4F
Copy Register A, the destination drive, into Register C.
5763
LD D,00H 16 00
Load Register D with 00H, the first cylinder to format.
5765
GOSUB to 54DBH to format cylinder Register D of drive Register C.
5768
If the NZ FLAG is set (a format error), JUMP to 55F9H for the message Destination disk WRITE ERROR!.
576B
LD A,(59A5H) 3A A5 59
Load Register A with the count of cylinders from 59A5H.
576E
DEC A 3D
DECrement Register A by 1, to the last cylinder.
576F
INC D 14
INCrement Register D by 1, to the next cylinder.
5770
CP D BA
Compare Register A against Register D: the NC FLAG while Register D is not past the last.
5771
If the NC FLAG is set (more cylinders), JUMP to 5765H.
5773
LD D,A 57
Load Register D with Register A, the last cylinder: the verify goes from there down.
5774
LD L,A 6F
Load Register L with Register A, the last cylinder.
5775
LD H,60H 26 60
Load Register H with 60H: Register Pair HL is the GAT byte of the last cylinder.
5777
PUSH HL E5
Save Register Pair HL to the top of the stack.
5778
POP IX DD E1
Restore Index Register IX from the top of the stack: Index Register IX = the GAT byte of the cylinder.
577A
LD HL,5AA7H 21 A7 5A
Point Register Pair HL to 5AA7H, the text VERIFYING that starts the line of the pass.
577D
GOSUB to 58C1H to show the text at Register Pair HL and then Cylinder with the cylinder Register D.
5780
GOSUB to 581CH to give drive Register C the source's geometry; Index Register IY returns its drive control table.
5783
LD E,00H 1E 00
Load Register E with 00H, the first granule of the cylinder.
5785
GOSUB to 54A2H to read every sector of granule Register E of cylinder Register D.
5788
If the Z FLAG is set (the granule reads), JUMP to 57A2H.
578A
LD HL,5BC0H 21 C0 5B
Point Register Pair HL to 5BC0H, the message GRAN FLAWED! Locked out!.
578D
GOSUB to 58B5H to show the message at Register Pair HL.
5790
LD HL,5AA7H 21 A7 5A
Point Register Pair HL to 5AA7H, the text VERIFYING, to start the line again.
5793
GOSUB to 58C1H to show the text at Register Pair HL and then Cylinder with the cylinder Register D.
5796
LD A,(IX+00H) DD 7E 00
Load Register A with the GAT byte of the cylinder from Index Register IX+00H.
5799
GOSUB to 592AH to set bit Register E of Register A: granule Register E is in use.
579C
LD (IX+00H),A DD 77 00
Store Register A into the allocation table at Index Register IX+00H.
579F
LD (IX+60H),A DD 77 60
Store Register A into the lock out table at Index Register IX+60H: the granule is locked out.
57A2
LD A,(IY+10H) FD 7E 10
Load Register A with the granules per cylinder from Index Register IY+10H.
57A5
INC E 1C
INCrement Register E by 1, to the next granule.
57A6
CP E BB
Compare Register A against Register E: the Z FLAG after the last granule of the cylinder.
57A7
If the NZ FLAG is set (more granules), JUMP to 5785H.
57A9
DEC D 15
DECrement Register D by 1, to the cylinder below.
57AA
DEC IX DD 2B
DECrement Index Register IX by 1, to that cylinder's GAT byte.
57AC
If the P FLAG is set (Register D not below 0), JUMP to 577AH for the next cylinder.
57AF
LD A,(6060H) 3A 60 60
Load Register A with the lock out byte of cylinder 0 from 6060H.
57B2
AND 01H E6 01
AND Register A with 01H to keep bit 0, granule 0 of cylinder 0, which holds BOOT/SYS.
57B4
If the NZ FLAG is set (the boot granule is flawed), JUMP to 55EFH for the message BOOT FLAWED! routine aborted!.

57B7H - Make the New GAT

For every cylinder, the granules to copy (the source's allocation XOR its lock out table) must not be locked out on the destination (else BACKUP rejected! Too many FLAWS!); the destination's allocation byte becomes those granules together with its own lock outs. The bytes +C0H-+FFH come from the source's GAT (the diskette name, date and AUTO command among them), then the date is put in +D8H-+DFH, the version 35H in +CBH and the count of cylinders less 35 in +CCH.

57B7
LD A,(59A5H) 3A A5 59
Load Register A with the count of cylinders from 59A5H.
57BA
LD B,A 47
Copy Register A, the count of cylinders, into Register B.
57BB
LD IY,6000H FD 21 00 60
Point Index Register IY to 6000H, the destination's GAT.
57BF
LD IX,5F00H DD 21 00 5F
Point Index Register IX to 5F00H, the source's GAT.
57C3
LD A,(IX+00H) DD 7E 00
Load Register A with the source's allocation byte from Index Register IX+00H.
57C6
XOR (IX+60H) DD AE 60
XOR Register A with the source's lock out byte at Index Register IX+60H: the granules to copy.
57C9
PUSH AF F5
Save Register Pair AF, the granules to copy, to the top of the stack.
57CA
AND (IY+60H) FD A6 60
AND Register A with the destination's lock out byte at Index Register IY+60H: the NZ FLAG for a clash.
57CD
If the NZ FLAG is set (a granule to copy is locked out), JUMP to 5603H for the message BACKUP rejected! Too many FLAWS!.
57D0
POP AF F1
Restore Register Pair AF, the granules to copy, from the top of the stack.
57D1
OR (IY+60H) FD B6 60
OR Register A with the destination's lock out byte at Index Register IY+60H.
57D4
LD (IY+00H),A FD 77 00
Store Register A into the destination's allocation byte at Index Register IY+00H.
57D7
INC IX DD 23
INCrement Index Register IX by 1, to the source's next cylinder.
57D9
INC IY FD 23
INCrement Index Register IY by 1, to the destination's next cylinder.
57DB
DECrement Register B and, while it is not zero, JUMP to 57C3H (DJNZ).
57DD
LD HL,5FC0H 21 C0 5F
Point Register Pair HL to 5FC0H, +C0H of the source's GAT.
57E0
LD DE,60C0H 11 C0 60
Point Register Pair DE to 60C0H, +C0H of the destination's GAT.
57E3
LD BC,0040H 01 40 00
Load Register Pair BC with 0040H, the 64 bytes +C0H-+FFH.
57E6
LDIR ED B0
Copy the 64 bytes from Register Pair HL to Register Pair DE (LDIR, Register Pair BC the count).
57E8
LD HL,5CBDH 21 BD 5C
Point Register Pair HL to 5CBDH, the date of the backup.
57EB
LD DE,60D8H 11 D8 60
Point Register Pair DE to 60D8H, +D8H of the destination's GAT, the diskette date.
57EE
LD C,08H 0E 08
Load Register C with 08H: Register Pair BC = 0008H, the length of the date (Register B is 00H after the LDIR).
57F0
LDIR ED B0
Copy the date from Register Pair HL to Register Pair DE (LDIR, Register Pair BC the count).
57F2
LD A,35H 3E 35
Load Register A with 35H, the version of DOSPLUS that formatted the diskette (3.5).
57F4
LD (60CBH),A 32 CB 60
Store Register A into 60CBH, +CBH of the destination's GAT, the version byte.
57F7
LD A,(59A5H) 3A A5 59
Load Register A with the count of cylinders from 59A5H.
57FA
SUB 23H D6 23
SUBtract 23H (35) from Register A: the cylinder count less 35.
57FC
LD (60CCH),A 32 CC 60
Store Register A into 60CCH, +CCH of the destination's GAT.
57FF
RET C9
RETurn to the caller: the destination is ready and its GAT is at 6000H.

5800H - The Next Cylinder to Copy

5800H steps Register D on first. From cylinder Register D on, finds the first cylinder with a granule to copy (580EH): returns the Z FLAG with Register D that cylinder, or the NZ FLAG (and the C FLAG) when Register D is past the last cylinder.

5800
INC D 14
INCrement Register D by 1, to the next cylinder.
5801
LD A,(59A5H) 3A A5 59
Load Register A with the count of cylinders from 59A5H.
5804
DEC A 3D
DECrement Register A by 1, to the last cylinder.
5805
CP D BA
Compare Register A against Register D: the C FLAG (and the NZ FLAG) when Register D is past the last.
5806
RET C D8
If the C FLAG is set (no cylinder left), RETurn to the caller with the NZ FLAG.
5807
GOSUB to 580EH to load Register A with the granules to copy of cylinder Register D.
580A
If the Z FLAG is set (none in this cylinder), JUMP to 5800H for the next.
580C
CP A BF
Compare Register A against itself, to set the Z FLAG: cylinder Register D has a granule to copy.
580D
RET C9
RETurn to the caller with the Z FLAG and Register D the cylinder.

580EH - The Granules to Copy

Register A = the source's allocation byte of cylinder Register D (5F00H on) XOR its lock out byte (5F60H on): a bit set for each granule allocated and not locked out; the Z FLAG when there is none.

580E
PUSH HL E5
Save Register Pair HL to the top of the stack.
580F
LD H,5FH 26 5F
Load Register H with 5FH, the page of the source's GAT.
5811
LD L,D 6A
Load Register L with Register D, the cylinder: Register Pair HL its allocation byte.
5812
LD A,(HL) 7E
Load Register A with the allocation byte at Register Pair HL.
5813
PUSH AF F5
Save Register Pair AF, the allocation byte, to the top of the stack.
5814
LD A,60H 3E 60
Load Register A with 60H, the offset of the lock out table.
5816
ADD A,L 85
ADD Register L to Register A: the cylinder's lock out byte.
5817
LD L,A 6F
Copy Register A into Register L: Register Pair HL is the lock out byte.
5818
POP AF F1
Restore Register Pair AF, the allocation byte, from the top of the stack.
5819
XOR (HL) AE
XOR Register A with the lock out byte at Register Pair HL: the granules to copy, with the flags.
581A
POP HL E1
Restore Register Pair HL from the top of the stack.
581B
RET C9
RETurn to the caller with Register A the granules to copy.

581CH - Give a Drive the Source's Geometry

LOCDCT% for drive Register C, then copies the source's nine bytes DCT+0BH-DCT+13H (599DH) into the drive's DCT+0BH on, or for cylinder 0 of a diskette whose cylinder 0 is in the other density the single density values at 5993H. Every register but Index Register IY is kept.

581C
PUSH BC C5
Save Register Pair BC, the drive in Register C, to the top of the stack.
581D
PUSH DE D5
Save Register Pair DE, the cylinder in Register D, to the top of the stack.
581E
PUSH HL E5
Save Register Pair HL to the top of the stack.
581F
GOSUB to 448BH, LOCDCT%: Index Register IY = the drive control table of drive Register C.
5822
LD HL,599DH 21 9D 59
Point Register Pair HL to 599DH, the source's drive control table bytes.
5825
LD A,(5CB5H) 3A B5 5C
Load Register A with the density flag of cylinder 0 from 5CB5H.
5828
OR A B7
OR Register A against itself: the Z FLAG when cylinder 0 has the directory's density.
5829
If the Z FLAG is set (one density), JUMP to 5832H.
582B
INC D 14
INCrement Register D by 1, to test it for zero below without changing it.
582C
DEC D 15
DECrement Register D by 1: the Z FLAG for cylinder 0.
582D
If the NZ FLAG is set (not cylinder 0), JUMP to 5832H.
582F
LD HL,5993H 21 93 59
Point Register Pair HL to 5993H, the values for a single density cylinder 0.
5832
PUSH IY FD E5
Save Index Register IY, the drive control table, to the top of the stack.
5834
LD DE,000BH 11 0B 00
Load Register Pair DE with 000BH, the offset of the drive control table's perishable bytes.
5837
ADD IY,DE FD 19
ADD Register Pair DE to Index Register IY: DCT+0BH.
5839
PUSH IY FD E5
Save Index Register IY (DCT+0BH) to the top of the stack.
583B
POP DE D1
Restore Register Pair DE from the top of the stack: Register Pair DE = DCT+0BH.
583C
LD BC,0009H 01 09 00
Load Register Pair BC with 0009H, the nine bytes DCT+0BH-DCT+13H.
583F
LDIR ED B0
Copy the nine bytes from Register Pair HL to Register Pair DE (LDIR, Register Pair BC the count).
5841
POP IY FD E1
Restore Index Register IY, the drive control table, from the top of the stack.
5843
POP HL E1
Restore Register Pair HL from the top of the stack.
5844
POP DE D1
Restore Register Pair DE, the cylinder, from the top of the stack.
5845
POP BC C1
Restore Register Pair BC, the drive, from the top of the stack.
5846
RET C9
RETurn to the caller with Index Register IY the drive control table.

5847H - The Format of a Track

Returns Register A = the interleave, Register Pair DE = the format description and Register Pair HL = 8001H (01H the sector length code, 80H the count of the data loop): for cylinder 0 of a diskette whose cylinder 0 is in the other density, 02H and the single density description 59A7H; else the entry of the format code's bits 0-1 in the table at 5987H. Index Register IX is changed.

5847
LD A,(5CB5H) 3A B5 5C
Load Register A with the density flag of cylinder 0 from 5CB5H.
584A
OR A B7
OR Register A against itself: the Z FLAG when cylinder 0 has the directory's density.
584B
If the Z FLAG is set (one density), JUMP to 585AH.
584D
INC D 14
INCrement Register D by 1, to test it for zero below without changing it.
584E
DEC D 15
DECrement Register D by 1: the Z FLAG for cylinder 0.
584F
If the NZ FLAG is set (not cylinder 0), JUMP to 585AH.
5851
LD DE,59A7H 11 A7 59
Point Register Pair DE to 59A7H, the format description of a single density track.
5854
LD HL,8001H 21 01 80
Load Register Pair HL with 8001H, the length code 01H and the data loop count 80H.
5857
LD A,02H 3E 02
Load Register A with 02H, the interleave of a single density track.
5859
RET C9
RETurn to the caller with Register A, Register Pair DE and Register Pair HL set.
585A
LD A,(5CB4H) 3A B4 5C
Load Register A with the source's format code from 5CB4H.
585D
AND 03H E6 03
AND Register A with 03H to keep bit 0 (double density) and bit 1 (8 inch): the entry 0-3.
585F
LD E,A 5F
Copy Register A, the entry 0-3 of the table, into Register E.
5860
ADD A,A 87
ADD Register A to itself: twice the entry, on the way to three times.
5861
ADD A,E 83
ADD Register E to Register A: three times the entry, the offset in the table.
5862
LD E,A 5F
Copy Register A, the offset, into Register E.
5863
LD D,00H 16 00
Load Register D with 00H: Register Pair DE is the offset.
5865
LD IX,5987H DD 21 87 59
Point Index Register IX to 5987H, the table of the formats, 3 bytes an entry.
5869
ADD IX,DE DD 19
ADD Register Pair DE to Index Register IX: the entry of the format.
586B
LD A,(IX+00H) DD 7E 00
Load Register A with the interleave from Index Register IX+00H.
586E
LD E,(IX+01H) DD 5E 01
Load Register E with the low byte of the description's address from Index Register IX+01H.
5871
LD D,(IX+02H) DD 56 02
Load Register D with the high byte of the description's address from Index Register IX+02H.
5874
LD HL,8001H 21 01 80
Load Register Pair HL with 8001H, the length code 01H and the data loop count 80H.
5877
RET C9
RETurn to the caller with Register A, Register Pair DE and Register Pair HL set.

5878H - A Prompt and Its Reply

Shows the text at Register Pair HL up to its 03H, then as many spaces as the byte after the 03H gives, and takes a reply of up to Register B characters into 5CC6H with the ROM's line input (0040H). BREAK ends BACKUP at 5404H. Returns Register Pair HL = 5CC6H and Register A = the first character of the reply.

5878
PUSH DE D5
Save Register Pair DE to the top of the stack.
5879
GOSUB to 58B5H to show the prompt at Register Pair HL; Register Pair HL returns past its 03H.
587C
LD C,(HL) 4E
Load Register C with the count of spaces at Register Pair HL, the byte after the 03H.
587D
LD A,20H 3E 20
Load Register A with 20H, a space, to show before the reply.
587F
GOSUB to 0033H, the ROM's display of the character in Register A.
5882
DEC C 0D
DECrement Register C by 1, the count of spaces still to show.
5883
If the NZ FLAG is set (more spaces), JUMP to 587DH.
5885
LD HL,5CC6H 21 C6 5C
Point Register Pair HL to 5CC6H, the buffer for the reply.
5888
GOSUB to 0040H, the ROM's line input of up to Register B characters to Register Pair HL; the C FLAG for BREAK.
588B
POP DE D1
Restore Register Pair DE from the top of the stack.
588C
If the C FLAG is set (BREAK), JUMP to 5404H to end BACKUP with the prompt for the system disk.
588F
LD A,(HL) 7E
Load Register A with the first character of the reply at Register Pair HL.
5890
RET C9
RETurn to the caller with Register A the first character and Register Pair HL = 5CC6H.

5891H - Copy Up to 8 Characters

Copies the text at Register Pair HL to 5CC6H, at most 8 characters, ending at a control character or at a double or single quotation mark (the end of a string given to DATE or USE), and fills the rest of the 8 with spaces. Returns Register Pair HL = 5CC6H.

5891
LD DE,5CC6H 11 C6 5C
Point Register Pair DE to 5CC6H, the place of the copy.
5894
PUSH DE D5
Save Register Pair DE, the start of the copy, to the top of the stack.
5895
LD C,08H 0E 08
Load Register C with 08H, the most characters to copy.
5897
LD A,(HL) 7E
Load Register A with the next character at Register Pair HL.
5898
LD (DE),A 12
Store Register A at Register Pair DE in the copy.
5899
CP 20H FE 20
Compare Register A against 20H, a space: the C FLAG for a control character.
589B
If the C FLAG is set (a control character), JUMP to 58ACH to fill the rest with spaces.
589D
CP 22H FE 22
Compare Register A against 22H, a double quotation mark.
589F
If the Z FLAG is set (the end of a string), JUMP to 58ACH to fill the rest with spaces.
58A1
CP 27H FE 27
Compare Register A against 27H, a single quotation mark.
58A3
If the Z FLAG is set (the end of a string), JUMP to 58ACH to fill the rest with spaces.
58A5
INC HL 23
INCrement Register Pair HL by 1, to the next character of the text.
58A6
INC DE 13
INCrement Register Pair DE by 1, to the next place of the copy.
58A7
DEC C 0D
DECrement Register C by 1, the count of characters still allowed.
58A8
If the NZ FLAG is set (fewer than 8 copied), JUMP to 5897H.
58AA
POP HL E1
Restore Register Pair HL, the start of the copy (5CC6H), from the top of the stack.
58AB
RET C9
RETurn to the caller with Register Pair HL = 5CC6H.
58AC
LD A,20H 3E 20
Load Register A with 20H, a space, to fill the rest of the copy.
58AE
LD (DE),A 12
Store Register A, the space, at Register Pair DE.
58AF
INC DE 13
INCrement Register Pair DE by 1, to the next place of the copy.
58B0
DEC C 0D
DECrement Register C by 1, the count of places still to fill.
58B1
If the NZ FLAG is set (more places), JUMP to 58AEH.
58B3
POP HL E1
Restore Register Pair HL, the start of the copy (5CC6H), from the top of the stack.
58B4
RET C9
RETurn to the caller with Register Pair HL = 5CC6H.

58B5H - Show a Text

Shows the characters at Register Pair HL with the ROM's 0033H until the 03H that ends the text. Returns Register Pair HL past the 03H; Register Pair DE is kept.

58B5
LD A,(HL) 7E
Load Register A with the next character at Register Pair HL.
58B6
INC HL 23
INCrement Register Pair HL by 1, past the character.
58B7
CP 03H FE 03
Compare Register A against 03H, the end of the text.
58B9
RET Z C8
If the Z FLAG is set (the end), RETurn to the caller.
58BA
PUSH DE D5
Save Register Pair DE to the top of the stack.
58BB
GOSUB to 0033H, the ROM's display of the character in Register A.
58BE
POP DE D1
Restore Register Pair DE from the top of the stack.
58BF
JUMP to 58B5H for the next character of the text at Register Pair HL.

58C1H - Show a Pass and the Cylinder

Shows the text of the pass at Register Pair HL (a carriage return and a cursor up start it, so the line is written over), then Cylinder and the cylinder Register D in two decimal digits (stored over the 00 at 5ACBH).

58C1
GOSUB to 58B5H to show the text of the pass at Register Pair HL.
58C4
LD A,D 7A
Load Register A with Register D, the cylinder.
58C5
LD HL,5ACBH 21 CB 5A
Point Register Pair HL to 5ACBH, the two digits of the cylinder in the text Cylinder 00.
58C8
GOSUB to 5918H to store Register A as two decimal digits at Register Pair HL.
58CB
LD HL,5AC1H 21 C1 5A
Point Register Pair HL to 5AC1H, the text Cylinder with the cylinder's digits.
58CE
JUMP to 58B5H to show the text at Register Pair HL and return.

58D1H - Upper Case

Makes a lower case letter in Register A upper case; any other character is left as it is.

58D1
CP 61H FE 61
Compare Register A against 61H, a lower case a: the C FLAG below it.
58D3
RET C D8
If the C FLAG is set (not a lower case letter), RETurn to the caller.
58D4
CP 7BH FE 7B
Compare Register A against 7BH, the character after a lower case z.
58D6
RET NC D0
If the NC FLAG is set (above z), RETurn to the caller.
58D7
AND 5FH E6 5F
AND Register A with 5FH, to make the letter upper case.
58D9
RET C9
RETurn to the caller with Register A the upper case letter.

58DAH - Flash a Prompt

Flashes the text at Register Pair HL (Insert SOURCE disk and the like) until a key is pressed: 500 scans of the keyboard with the text shown, 500 with the line cleared, and so on. The line is cleared at the end. Nothing is done while a DO file runs (bit 5 of SFLAG1$), so a DO file can run BACKUP. The registers are kept (4525H).

58DA
LD A,(4302H) 3A 02 43
Load Register A with SFLAG1$ from 4302H, the system flags.
58DD
AND 20H E6 20
AND Register A with 20H to keep bit 5, a DO file is running.
58DF
RET NZ C0
If the NZ FLAG is set (a DO file runs), RETurn to the caller without waiting.
58E0
GOSUB to 4525H, SYS0/SYS's routine that runs the rest of this routine with the registers saved.
58E3
LD BC,01F4H 01 F4 01
Load Register Pair BC with 01F4H, the 500 scans of the keyboard of each half of the flash.
58E6
PUSH HL E5
Save Register Pair HL, the prompt, to the top of the stack.
58E7
LD A,(5917H) 3A 17 59
Load Register A with the flash state from 5917H: 1EH while the prompt is shown.
58EA
XOR 1EH EE 1E
XOR Register A with 1EH: 00H with the Z FLAG when the prompt is shown, else 1EH.
58EC
PUSH AF F5
Save Register Pair AF, the new state, to the top of the stack.
58ED
If the Z FLAG is set (the prompt is shown), GOSUB to 5905H to clear the line.
58F0
POP AF F1
Restore Register Pair AF, the new state, from the top of the stack.
58F1
LD (5917H),A 32 17 59
Store Register A, the new flash state (00H or 1EH), into 5917H.
58F4
If the NZ FLAG is set (the line was clear), GOSUB to 58B5H to show the prompt at Register Pair HL.
58F7
POP HL E1
Restore Register Pair HL, the prompt, from the top of the stack.
58F8
GOSUB to 002BH, the ROM's scan of the keyboard: Register A the key, or 00H.
58FB
OR A B7
OR Register A against itself: the NZ FLAG when a key is pressed.
58FC
If the NZ FLAG is set (a key), JUMP to 5905H to clear the line and return.
58FE
DEC BC 0B
DECrement Register Pair BC by 1, the count of scans.
58FF
LD A,B 78
Load Register A with Register B, the high byte of the count.
5900
OR C B1
OR Register A with Register C: the Z FLAG when the count is out.
5901
If the NZ FLAG is set (more scans), JUMP to 58F8H.
5903
JUMP to 58E3H for the next half of the flash.

5905H - Clear the Line

Shows a carriage return, a cursor up (1BH) and an erase to the end of the line (1EH): the line of the cursor is cleared and the cursor is at its start. Sets the flash state 5917H to 1EH.

5905
LD A,0DH 3E 0D
Load Register A with 0DH, a carriage return, to the start of a new line.
5907
GOSUB to 0033H, the ROM's display of the character in Register A.
590A
LD A,1BH 3E 1B
Load Register A with 1BH, the cursor up a line, back to the line of the prompt.
590C
GOSUB to 0033H, the ROM's display of the character in Register A.
590F
LD A,1EH 3E 1E
Load Register A with 1EH, the erase to the end of the line.
5911
LD (5917H),A 32 17 59
Store Register A (1EH) into 5917H, the flash state, as if the prompt were shown.
5914
JUMP to 0033H, the ROM's display of the character in Register A, which returns to the caller.
5917
DEFB 1EH 1E
The flash state of 58DAH: 1EH while the prompt is shown (and as loaded), 00H while the line is clear.

5918H - Two Decimal Digits

Stores Register A (0-99) at Register Pair HL as two ASCII digits, the tens first; Register Pair HL is left after them and Register Pair DE is kept.

5918
PUSH DE D5
Save Register Pair DE to the top of the stack.
5919
LD E,30H 1E 30
Load Register E with 30H, the ASCII digit 0, the tens.
591B
SUB 0AH D6 0A
SUBtract 0AH (10) from Register A, one ten at a time.
591D
If the C FLAG is set (below 0), JUMP to 5922H.
591F
INC E 1C
INCrement Register E by 1, the next tens digit.
5920
JUMP to 591BH to take off the next ten from Register A.
5922
ADD A,3AH C6 3A
ADD 3AH to Register A: the units as an ASCII digit (10 too many were taken off).
5924
LD (HL),E 73
Store Register E, the tens digit, at Register Pair HL.
5925
INC HL 23
INCrement Register Pair HL by 1, to the place of the units.
5926
LD (HL),A 77
Store Register A, the units digit, at Register Pair HL.
5927
INC HL 23
INCrement Register Pair HL by 1, past the two digits.
5928
POP DE D1
Restore Register Pair DE from the top of the stack.
5929
RET C9
RETurn to the caller with Register Pair HL after the digits.

592AH - Set, Reset or Test Bit E

592AH sets bit Register E (0-7) of Register A, 593AH resets it, and 594AH tests it (the Z FLAG when it is clear): each stores the bit number into the second byte of its SET, RES or BIT instruction (5938H, 5948H, 5958H) and then runs it.

592A
PUSH AF F5
Save Register Pair AF, the byte, to the top of the stack.
592B
LD A,E 7B
Load Register A with Register E, the bit number.
592C
AND 07H E6 07
AND Register A with 07H, to keep the bit number 0-7.
592E
RLCA 07
Rotate Register A left (RLCA): the bit number towards bits 3-5.
592F
RLCA 07
Rotate Register A left (RLCA) again: the bit number one place higher.
5930
RLCA 07
Rotate Register A left (RLCA) again: the bit number in bits 3-5.
5931
OR C7H F6 C7
OR Register A with C7H: the second byte of SET n,A.
5933
LD (5938H),A 32 38 59
Store Register A into 5938H, the second byte of the SET instruction at 5937H.
5936
POP AF F1
Restore Register Pair AF, the byte, from the top of the stack.
5937
SET 0,A CB C7
Set the bit of Register A that 5933H stored (SET 0,A as loaded): bit Register E.
5939
RET C9
RETurn to the caller with Register A the byte with the bit set.
593A
PUSH AF F5
Save Register Pair AF, the byte, to the top of the stack.
593B
LD A,E 7B
Load Register A with Register E, the bit number.
593C
AND 07H E6 07
AND Register A with 07H, to keep the bit number 0-7.
593E
RLCA 07
Rotate Register A left (RLCA): the bit number towards bits 3-5.
593F
RLCA 07
Rotate Register A left (RLCA) again: the bit number one place higher.
5940
RLCA 07
Rotate Register A left (RLCA) again: the bit number in bits 3-5.
5941
OR 87H F6 87
OR Register A with 87H: the second byte of RES n,A.
5943
LD (5948H),A 32 48 59
Store Register A into 5948H, the second byte of the RES instruction at 5947H.
5946
POP AF F1
Restore Register Pair AF, the byte, from the top of the stack.
5947
RES 0,A CB 87
Reset the bit of Register A that 5943H stored (RES 0,A as loaded): bit Register E.
5949
RET C9
RETurn to the caller with Register A the byte with the bit reset.
594A
PUSH AF F5
Save Register Pair AF, the byte, to the top of the stack.
594B
LD A,E 7B
Load Register A with Register E, the bit number.
594C
AND 07H E6 07
AND Register A with 07H, to keep the bit number 0-7.
594E
RLCA 07
Rotate Register A left (RLCA): the bit number towards bits 3-5.
594F
RLCA 07
Rotate Register A left (RLCA) again: the bit number one place higher.
5950
RLCA 07
Rotate Register A left (RLCA) again: the bit number in bits 3-5.
5951
OR 47H F6 47
OR Register A with 47H: the second byte of BIT n,A.
5953
LD (5958H),A 32 58 59
Store Register A into 5958H, the second byte of the BIT instruction at 5957H.
5956
POP AF F1
Restore Register Pair AF, the byte, from the top of the stack.
5957
BIT 0,A CB 47
Test the bit of Register A that 5953H stored (BIT 0,A as loaded): the NZ FLAG when bit Register E is set.
5959
RET C9
RETurn to the caller with the Z FLAG or the NZ FLAG for the bit.

595AH - A Drive Name

Looks up the two characters at Register Pair HL (made upper case) among the names of the eight entries of DCTTBL (43ABH: a DCT address and a two character name): returns the Z FLAG and Register A = the drive number, or the NZ FLAG when no name matches. A reply of one character matches a name whose second character is a space, since the reply is padded with spaces.

595A
PUSH IX DD E5
Save Index Register IX to the top of the stack.
595C
LD IX,43ABH DD 21 AB 43
Point Index Register IX to 43ABH, DCTTBL, the table of the drives.
5960
LD DE,0004H 11 04 00
Load Register Pair DE with 0004H, the length of an entry of DCTTBL.
5963
LD B,08H 06 08
Load Register B with 08H, the count of entries.
5965
LD A,(HL) 7E
Load Register A with the first character at Register Pair HL.
5966
GOSUB to 58D1H to make the character in Register A upper case.
5969
CP (IX+02H) DD BE 02
Compare Register A against the first character of the name at Index Register IX+02H.
596C
If the NZ FLAG is set (no match), JUMP to 5979H for the next entry.
596E
INC HL 23
INCrement Register Pair HL by 1, to the second character.
596F
LD A,(HL) 7E
Load Register A with the second character at Register Pair HL.
5970
GOSUB to 58D1H to make the character in Register A upper case.
5973
DEC HL 2B
DECrement Register Pair HL by 1, back to the first character.
5974
CP (IX+03H) DD BE 03
Compare Register A against the second character of the name at Index Register IX+03H.
5977
If the Z FLAG is set (the name matches), JUMP to 5980H.
5979
ADD IX,DE DD 19
ADD Register Pair DE (0004H) to Index Register IX, to the next entry.
597B
DECrement Register B and, while it is not zero, JUMP to 5965H for the next entry (DJNZ).
597D
POP IX DD E1
Restore Index Register IX from the top of the stack.
597F
RET C9
RETurn to the caller with the NZ FLAG: no drive has that name.
5980
POP IX DD E1
Restore Index Register IX from the top of the stack.
5982
LD A,08H 3E 08
Load Register A with 08H, the count of entries.
5984
SUB B 90
SUBtract Register B (the entries left) from Register A: the drive number.
5985
CP A BF
Compare Register A against itself, to set the Z FLAG.
5986
RET C9
RETurn to the caller with the Z FLAG and Register A the drive number.

5987H - The Formats

Data: the table of 5847H, one entry for each value of the format code's bits 0-1 (an interleave, then the address of a format description); the single density values of cylinder 0 for 581CH; the work area of the source's drive control table bytes; and the two format descriptions, pairs of a count and a byte for 55C2H (a count of 00H is 256).

5987
DEFB 02H 02
Entry 0, single density 5 inch: the interleave 2.
5988-5989
DEFW 59A7H A7 59
Entry 0: the single density format description at 59A7H.
598A
DEFB 03H 03
Entry 1, double density 5 inch: the interleave 3.
598B-598C
DEFW 59BDH BD 59
Entry 1: the double density format description at 59BDH.
598D
DEFB 03H 03
Entry 2, single density 8 inch: the interleave 3.
598E-598F
DEFW 59A7H A7 59
Entry 2: the single density format description at 59A7H.
5990
DEFB 03H 03
Entry 3, double density 8 inch: the interleave 3.
5991-5992
DEFW 59BDH BD 59
Entry 3: the double density format description at 59BDH.
5993
DEFB 40H 40
DCT+0BH for a single density cylinder 0 (582FH): bit 7 clear, single density, with bit 6 set.
5994
DEFB 01H 01
DCT+0CH for cylinder 0: one surface, the count of sides.
5995
DEFB 0AH 0A
DCT+0DH for cylinder 0: 10 sectors a track (single density).
5996
DEFB FFH FF
DCT+0EH for cylinder 0, the directory length: not used on cylinder 0.
5997
DEFB 0AH 0A
DCT+0FH for cylinder 0: 10 sectors a granule.
5998
DEFB 01H 01
DCT+10H for cylinder 0: one granule a cylinder.
5999
DEFB 0AH 0A
DCT+11H for cylinder 0: 10 sectors a cylinder.
599A-599C
DEFB FFH,FFH,FFH FF FF FF
DCT+12H and DCT+13H for cylinder 0 (not used there), and a tenth byte that 581CH does not copy.
599D-59A6
DEFS 10
The source's drive control table bytes DCT+0BH-DCT+14H (5304H): 59A4H the directory cylinder, 59A5H the count of cylinders (the destination's when it has more, 5708H); not loaded.
59A7-59A8
DEFB 0BH,FFH 0B FF
Single density: 11 bytes of FFH at the start of the track.
59A9-59AA
DEFB 01H,FCH 01 FC
Single density: one byte FCH, the controller writes it as the index address mark.
59AB-59AC
DEFB 14H,FFH 14 FF
Single density: 20 bytes of FFH after the index address mark.
59AD-59AE
DEFB 03H,00H 03 00
Single density, each sector (5574H): 3 bytes of 00H before the ID field.
59AF-59B0
DEFB 03H,00H 03 00
Single density: 3 more bytes of 00H before the ID field.
59B1-59B2
DEFB 0BH,FFH 0B FF
Single density: 11 bytes of FFH after the ID field.
59B3-59B4
DEFB 03H,00H 03 00
Single density: 3 bytes of 00H before the data field.
59B5-59B6
DEFB 03H,00H 03 00
Single density: 3 more bytes of 00H before the data field.
59B7-59B8
DEFB 0BH,FFH 0B FF
Single density: 11 bytes of FFH after the data field.
59B9-59BA
DEFB 00H,FFH 00 FF
Single density: 256 bytes of FFH at the end of the track.
59BB-59BC
DEFB 00H,FFH 00 FF
Single density: 256 more bytes of FFH at the end of the track.
59BD-59BE
DEFB 16H,4EH 16 4E
Double density: 22 bytes of 4EH at the start of the track.
59BF-59C0
DEFB 01H,FCH 01 FC
Double density: one byte FCH, the controller writes it as the index address mark.
59C1-59C2
DEFB 28H,4EH 28 4E
Double density: 40 bytes of 4EH after the index address mark.
59C3-59C4
DEFB 08H,00H 08 00
Double density, each sector (5574H): 8 bytes of 00H before the ID field.
59C5-59C6
DEFB 03H,F5H 03 F5
Double density: 3 bytes of F5H, the controller's code for the A1H sync bytes.
59C7-59C8
DEFB 16H,4EH 16 4E
Double density: 22 bytes of 4EH after the ID field.
59C9-59CA
DEFB 0CH,00H 0C 00
Double density: 12 bytes of 00H before the data field.
59CB-59CC
DEFB 03H,F5H 03 F5
Double density: 3 bytes of F5H, the A1H sync bytes of the data field.
59CD-59CE
DEFB 18H,4EH 18 4E
Double density: 24 bytes of 4EH after the data field.
59CF-59D0
DEFB 00H,4EH 00 4E
Double density: 256 bytes of 4EH at the end of the track.
59D1-59D2
DEFB 00H,4EH 00 4E
Double density: 256 more bytes of 4EH at the end of the track.

59D3H - The Texts

Data: the heading, the prompts (each followed by its 03H and the count of spaces 5878H shows after it), the texts of the passes and the messages, each ended by 03H for 58B5H. The heading's last digit 59F7H is the patch byte that makes the version 3.51 (31H; 3.50 as first loaded).

59D3-59F7
DEFM "BACKUP - DOSPLUS Floppy backup - 3.51" 42 41 43 4B 55 50 20 2D 20 44 4F 53 50 4C 55 53 20 46 6C 6F 70 70 79 20 62 61 63 6B 75 70 20 2D 20 33 2E 35 31
The heading shown at the start (5201H); the 1 at 59F7H is loaded by the last patch block.
59F8
DEFB 0DH 0D
The carriage return that ends the heading's first line.
59F9-5A27
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 shown at the start.
5A28-5A2A
DEFB 0DH,0DH,03H 0D 0D 03
Two carriage returns (an empty line after the heading) and the 03H that ends it.
5A2B-5A3C
DEFM "Source drivespec ?" 53 6F 75 72 63 65 20 64 72 69 76 65 73 70 65 63 20 3F
The prompt for the source drive (5251H), when the command line has none.
5A3D-5A3E
DEFB 03H,07H 03 07
The 03H that ends the prompt, and 7 spaces before the reply.
5A3F-5A55
DEFM "Destination drivespec ?" 44 65 73 74 69 6E 61 74 69 6F 6E 20 64 72 69 76 65 73 70 65 63 20 3F
The prompt for the destination drive (527AH).
5A56-5A57
DEFB 03H,02H 03 02
The 03H that ends the prompt, and 2 spaces before the reply.
5A58-5A64
DEFM "Backup date ?" 42 61 63 6B 75 70 20 64 61 74 65 20 3F
The prompt for the date when no system date is set (52BBH).
5A65-5A66
DEFB 03H,0CH 03 0C
The 03H that ends the prompt, and 12 spaces before the reply.
5A67-5A8A
DEFM "Diskette contains data, use or not ?" 44 69 73 6B 65 74 74 65 20 63 6F 6E 74 61 69 6E 73 20 64 61 74 61 2C 20 75 73 65 20 6F 72 20 6E 6F 74 20 3F
The prompt for a destination that can be read (56D0H).
5A8B-5A8C
DEFB 03H,01H 03 01
The 03H that ends the prompt, and 1 space before the reply.
5A8D-5A8E
DEFB 0DH,1BH 0D 1B
A carriage return and a cursor up: the line of the pass is written over.
5A8F-5A98
DEFM "READING " 52 45 41 44 49 4E 47 20 20 20
The text of the read pass (5416H), padded with spaces to 10 characters.
5A99
DEFB 03H 03
The 03H that ends the text READING for 58B5H.
5A9A-5A9B
DEFB 0DH,1BH 0D 1B
A carriage return and a cursor up: the line of the pass is written over.
5A9C-5AA5
DEFM "WRITING " 57 52 49 54 49 4E 47 20 20 20
The text of the write pass (544DH), padded with spaces to 10 characters.
5AA6
DEFB 03H 03
The 03H that ends the text WRITING for 58B5H.
5AA7-5AA8
DEFB 0DH,1BH 0D 1B
A carriage return and a cursor up: the line of the pass is written over.
5AA9-5AB2
DEFM "VERIFYING " 56 45 52 49 46 59 49 4E 47 20
The text of the verify passes (5484H, 577AH).
5AB3
DEFB 03H 03
The 03H that ends the text VERIFYING for 58B5H.
5AB4-5AB5
DEFB 0DH,1BH 0D 1B
A carriage return and a cursor up: the line of the pass is written over.
5AB6-5ABF
DEFM "FORMATTING" 46 4F 52 4D 41 54 54 49 4E 47
The text of the format pass (54DBH), 10 characters like the others.
5AC0
DEFB 03H 03
The 03H that ends the text FORMATTING for 58B5H.
5AC1-5ACC
DEFM " Cylinder 00" 20 43 79 6C 69 6E 64 65 72 20 30 30
The cylinder after the text of a pass (58CBH); its two digits 5ACBH-5ACCH are set by 58C8H.
5ACD
DEFB 03H 03
The 03H that ends the text Cylinder and its two digits.
5ACE-5AE7
DEFM "Insert SOURCE disk (ENTER)" 49 6E 73 65 72 74 20 53 4F 55 52 43 45 20 64 69 73 6B 20 28 45 4E 54 45 52 29
The prompt for the source disk in a backup with one drive (52DBH, 5325H, 5396H).
5AE8
DEFB 03H 03
The 03H that ends the prompt for the source disk.
5AE9-5B07
DEFM "Insert DESTINATION disk (ENTER)" 49 6E 73 65 72 74 20 44 45 53 54 49 4E 41 54 49 4F 4E 20 64 69 73 6B 20 28 45 4E 54 45 52 29
The prompt for the destination disk in a backup with one drive (5306H, 5355H, 53DFH).
5B08
DEFB 03H 03
The 03H that ends the prompt for the destination disk.
5B09-5B22
DEFM "Insert SYSTEM disk (ENTER)" 49 6E 73 65 72 74 20 53 59 53 54 45 4D 20 64 69 73 6B 20 28 45 4E 54 45 52 29
The prompt for the system disk at the end when drive 0 was used (5404H, 5609H).
5B23
DEFB 03H 03
The 03H that ends the prompt for the system disk.
5B24-5B37
DEFM "No available memory!" 4E 6F 20 61 76 61 69 6C 61 62 6C 65 20 6D 65 6D 6F 72 79 21
The message of a buffer that does not fit below HMEM$ (55EAH).
5B38-5B39
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5B3A-5B4D
DEFM "Drives INCOMPATABLE!" 44 72 69 76 65 73 20 49 4E 43 4F 4D 50 41 54 41 42 4C 45 21
The message of an 8 inch drive with a 5 inch one (55CCH), spelt INCOMPATABLE in the file.
5B4E-5B4F
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5B50-5B66
DEFM "Source drive NOT READY!" 53 6F 75 72 63 65 20 64 72 69 76 65 20 4E 4F 54 20 52 45 41 44 59 21
The message of a source drive that DCHECK finds not ready (55D1H).
5B67-5B68
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5B69-5B84
DEFM "Destination drive NOT READY!" 44 65 73 74 69 6E 61 74 69 6F 6E 20 64 72 69 76 65 20 4E 4F 54 20 52 45 41 44 59 21
The message of a destination drive that DCHECK finds not ready (55D6H).
5B85-5B86
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5B87-5BA7
DEFM "Destination disk WRITE PROTECTED!" 44 65 73 74 69 6E 61 74 69 6F 6E 20 64 69 73 6B 20 57 52 49 54 45 20 50 52 4F 54 45 43 54 45 44 21
The message of a write protected destination (55E5H).
5BA8-5BA9
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5BAA-5BBD
DEFM "Drive NOT SUPPORTED!" 44 72 69 76 65 20 4E 4F 54 20 53 55 50 50 4F 52 54 45 44 21
The message of a rigid drive as the source or the destination (55DBH).
5BBE-5BBF
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5BC0-5BD9
DEFM " GRAN FLAWED! Locked out!" 20 20 47 52 41 4E 20 46 4C 41 57 45 44 21 20 4C 6F 63 6B 65 64 20 6F 75 74 21
The message after VERIFYING for a granule that cannot be read after formatting (578AH).
5BDA-5BDB
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5BDC
DEFB 0DH 0D
The carriage return that starts the message I/O ERROR!.
5BDD-5BF7
DEFM "I/O ERROR! routine aborted!" 49 2F 4F 20 45 52 52 4F 52 21 20 72 6F 75 74 69 6E 65 20 61 62 6F 72 74 65 64 21
A message no instruction shows: only 55E0H points to it, and nothing reaches 55E0H.
5BF8-5BF9
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5BFA
DEFB 0DH 0D
The carriage return that starts the message BOOT FLAWED!.
5BFB-5C17
DEFM "BOOT FLAWED! routine aborted!" 42 4F 4F 54 20 46 4C 41 57 45 44 21 20 72 6F 75 74 69 6E 65 20 61 62 6F 72 74 65 64 21
The message of a flawed granule 0 of cylinder 0 on a formatted destination (55EFH).
5C18-5C19
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5C1A
DEFB 0DH 0D
The carriage return that starts the message Source disk READ ERROR!.
5C1B-5C31
DEFM "Source disk READ ERROR!" 53 6F 75 72 63 65 20 64 69 73 6B 20 52 45 41 44 20 45 52 52 4F 52 21
The message of a read error on the source in the copy loop or in its GAT (55F4H).
5C32-5C33
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5C34
DEFB 0DH 0D
The carriage return that starts the message Destination disk WRITE ERROR!.
5C35-5C51
DEFM "Destination disk WRITE ERROR!" 44 65 73 74 69 6E 61 74 69 6F 6E 20 64 69 73 6B 20 57 52 49 54 45 20 45 52 52 4F 52 21
The message of every error of the write, verify and format passes and of the directory cylinder (55F9H).
5C52-5C53
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5C54
DEFB 0DH 0D
The carriage return that starts the message Destination disk READ ERROR!.
5C55-5C70
DEFM "Destination disk READ ERROR!" 44 65 73 74 69 6E 61 74 69 6F 6E 20 64 69 73 6B 20 52 45 41 44 20 45 52 52 4F 52 21
A message no instruction shows: only 55FEH points to it, and nothing reaches 55FEH.
5C71-5C72
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.
5C73
DEFB 0DH 0D
The carriage return that starts the message BACKUP rejected!.
5C74-5C93
DEFM "BACKUP rejected! Too many FLAWS!" 42 41 43 4B 55 50 20 72 65 6A 65 63 74 65 64 21 20 54 6F 6F 20 6D 61 6E 79 20 46 4C 41 57 53 21
The message of a granule to copy that is locked out on the destination (5603H).
5C94-5C95
DEFB 0DH,03H 0D 03
A carriage return and the 03H that ends the message.

5C96H - The Evaluation Block and the Variables

Data: the evaluation block of EVAL@ (5237H) and its parameter block (9 byte entries: a six character name, the address for the value, the type byte 80H for a string; the address stored is that of the string's text, here the operands of two LD HL instructions), then the drives. 5CB4H on is not loaded.

5C96
DEFB 00H 00
The flags of the evaluation block, set by EVAL@: bit 0 a source field, bit 1 a destination field.
5C97-5C98
DEFW 5CD0H D0 5C
The address of the source field's block, 5CD0H.
5C99-5C9A
DEFW 5CF1H F1 5C
The address of the destination field's block, 5CF1H.
5C9B-5C9C
DEFW 5CD0H D0 5C
The address of the wildmask field's block, the source's block again (BACKUP takes no wildmask).
5C9D-5C9E
DEFW 5C9FH 9F 5C
The address of the parameter block, 5C9FH, the entries USE and DATE.
5C9F-5CA4
DEFM "USE " 55 53 45 20 20 20
The name of the parameter USE (or U): the answer to Diskette contains data, use or not ?.
5CA5-5CA6
DEFW 56C2H C2 56
The address for USE's value: the operand of LD HL at 56C1H takes the address of its string.
5CA7
DEFB 80H 80
The type byte of USE: a string only (bit 7), so USE=Y without quotation marks is not taken.
5CA8-5CAD
DEFM "DATE " 44 41 54 45 20 20
The name of the parameter DATE (or D): the date of the backup, up to 8 characters.
5CAE-5CAF
DEFW 528EH 8E 52
The address for DATE's value: the operand of LD HL at 528DH takes the address of its string.
5CB0
DEFB 80H 80
The type byte of DATE: a string only (bit 7).
5CB1
DEFB 00H 00
The 00H that ends the parameter block after its two entries.
5CB2
DEFB 00H 00
The source drive (5261H), 0-7, from the command line or the prompt.
5CB3
DEFB 00H 00
The destination drive (5264H, 528AH), 0-7, the source drive until another is given.
5CB4
DEFS 1
The source's format code (52FAH): bit 0 double density, bit 1 8 inch, bit 2 two sides.
5CB5
DEFS 1
The density flag of the source's cylinder 0 (52FAH): 80H when cylinder 0 is in the other density.
5CB6
DEFS 1
The cylinder after the last one of a run in the buffer (5352H).
5CB7
DEFS 1
The first cylinder of a run in the buffer (5330H).
5CB8
DEFS 1
The GAT byte of an empty cylinder (56B1H), FCH for two granules a cylinder.
5CB9
DEFS 1
FFH when the source diskette is write protected, else 00H (52ECH).
5CBA
DEFS 1
00H for a backup with one drive (52D8H), else the difference of the drives.
5CBB-5CBC
DEFS 2
The start of the buffer of sectors, 6100H or the page above LOW$ (5219H).
5CBD-5CC4
DEFS 8
The date of the backup for the destination's GAT (52CEH).
5CC6-5CCE
DEFS 9
The reply to a prompt (up to 8 characters and its ending carriage return), the date being made, and the copies of 5891H.
5CD0-5CF0
DEFS 33
The source field's block for EVAL@: a flag byte (bit 7 a device or drive, bit 3 a drive, bits 0-2 its number) and the text.
5CF1-5D11
DEFS 33
The destination field's block for EVAL@, in the same form.
5D12-5D31
DEFS 32
The sector order of a track being formatted, one byte a place (551BH).
5D32-5EFF
DEFS 462
The marks of the sectors in the buffer, one byte a sector: 00H, or 01H for the directory's data address mark (5440H).
5F00-5FFF
DEFS 256
The source's GAT (52F1H): the allocation table, the lock out table at 5F60H, the bytes +C0H-+FFH.
6000-60FF
DEFS 256
The destination's new GAT (56B8H, 5743H, 57B7H), written to its directory at the end (53E6H).