LDOS 5.3.1 for the Model III - LOG/CMD Disassembled

Page Customization

Introduction/Summary

LDOS 5.3.1 LOG/CMD Disassembly - Log In One Drive's Diskette (Model III)

LOG/CMD logs in the diskette of one drive: it puts the directory cylinder of the diskette and its number of sides into the drive's code table, as the DEVICE command does for every drive. The command is LOG :d; for drive 0, given or by default, the program first asks for the diskette to be exchanged, so that a system diskette with another directory cylinder or a double sided diskette can go into drive 0. The manual (M-40-060) gives that use: LOG :0 must be used when switching between double and single sided diskettes in drive 0.

The file is a load module of 194 bytes: a record of type 1FH with the text Copyright 1991 MISOSYS, Inc., All rights reserved, one load block for 5200H-5286H (135 bytes) and the transfer address record for 5200H. LOG issues no supervisor request of its own: it calls the resident vectors and disk primitives of SYS0/SYS (and @CKDRV, which loads SYS2/SYS) and two ROM routines.

What LOG Does

StepWhat Happens
The driveSpaces are passed over; a colon and the character after it give the drive (bits 2-0 of the character, not checked). Without a colon the drive is 0 (5200H).
Drive 0Exchange disks and hit <ENTER> is shown with the cursor on and the ROM waits for any key; @CKDRV is not called (5210H).
Drives 1-7@CKDRV must find the drive ready, else error 20H, Illegal drive number, as a short message, and the program ends at @ABORT (5224H).
The directory cylinderCylinder 0, sector 0, the copy of the boot sector, is read into 5287H; its byte 02H goes to +09H of the drive code table (522CH).
The sidesSector 0 of that cylinder, the allocation table, must read with the deleted data mark; bit 5 of its configuration byte (CDH) is copied into bit 5 of +04H of the drive code table. Then @EXIT (5246H).

About This Page

The Model I diskette of LDOS 5.3.1 has no LOG/CMD, so this page is written from the bytes of the Model III file alone. Every byte of the file is shown at its address, with a DEFS row for 5287H-5386H, the buffer beyond the file. Found in the code: the character after the colon is not checked, so LOG :X works on drive 0 (58H AND 07H); a diskette whose allocation table carries the normal data mark ends with the short message of error 0 (40H, 5250H); for drive 0 nothing tests that the drive is ready before the read, which then gives the error of RDSECT.

Memory Map

Load Blocks in File Order

The one load block of the file, after the copyright record: 135 bytes, 5200H-5286H. The transfer address is 5200H.

AddressContents
5200H-5286H135 bytes

Sections of the Disassembly

AddressContents
5200HThe Drive from the Command Line
5210HDrive 0: Exchange the Diskettes
522CHRead the Boot Sector: the Directory Cylinder
5246HRead the Allocation Table: the Number of Sides
5267HThe Prompt and the Buffer

Memory LOG/CMD Uses

AddressContents
0033HROM: display the character in Register A (5221H).
0049HROM: wait for a key, returned in Register A (521AH).
402DH@EXIT: the end of the program (5264H).
4409H@ERROR: the short message of an error, then @ABORT (5229H, 5237H, 5250H).
4467H@DSPLY: the prompt for drive 0 (5217H).
4209H@CKDRV: the check of drives 1-7 (5224H).
4700H-474FHDCT$, the drive code tables: GETDCT (478FH) points Index Register IY at the drive's table; LOG sets its +09H and bit 5 of +04H.
4777HRDSECT: the reads of the boot sector copy and the allocation table (5232H, 5249H).
5287H-5386HThe buffer of both reads.

Variables

The entry point of LOG/CMD, then the data of the file and the buffer beyond it, and the cells outside the file that it uses, by address. LOG changes no operand of its own code.

Entry Points

AddressContents
5200HThe start of LOG/CMD, the transfer address of the file.

Data in the File and Beyond It

Address
Size
Contents
5267H-5284H
30 bytes
DEFM "Exchange disks and hit <ENTER>"
The prompt for drive 0, displayed by @DSPLY from 5217H.
5285H-5286H
2 bytes
DEFB 0EH, 03H
Cursor on, then the end of the text.
5287H-5386H
256 bytes
DEFS 256
Not in the file: the buffer of the boot sector copy (its directory cylinder at 5289H) and of the allocation table (its configuration byte at 5354H).

Cells Outside the File That LOG/CMD Uses

Address
Size
Contents
IY +09H
1 byte
The directory cylinder in the drive code table of the drive given, stored by 5240H from byte 02H of the boot sector.
IY +04H
1 byte
The drive's flags: bit 5, two sides, set or cleared by 5261H from the allocation table.
Boot sector +02H
1 byte
Cylinder 0, sector 0, byte 02H: the directory cylinder (5289H in the buffer).
Allocation table +CDH
1 byte
The configuration byte of the diskette (5354H in the buffer): bit 5 set for a double sided diskette.

Disassembly

5200H - The Drive from the Command Line

LDOS Ready loads LOG/CMD at 5200H-5286H and jumps to 5200H, the transfer address, with Register Pair HL at the rest of the command line after the word LOG. The command is LOG :d. Spaces are passed over; when a colon follows, the character after it gives the drive in its bits 2-0. Without a colon the drive is 0. Nothing else on the line is read.

5200
LD C,00H 0E 00
Load Register C with 00H, drive 0: the drive LOG works on when the command line names no drive after a colon.
5202
LD A,(HL) 7E
Fetch the next character of the command line at Register Pair HL into Register A.
5203
INC HL 23
INCrement Register Pair HL past the character just fetched; INC of a register pair leaves the flags alone.
5204
CP 20H FE 20
Compare Register A (the character) against 20H, a space: the Z FLAG for a space.
5206
If the Z FLAG is set (Register A was a space), JUMP back to 5202H to take the next character of the command line.
5208
CP 3AH FE 3A
Compare Register A (the first character that is not a space) against 3AH, a colon. Register Pair HL already points at the character after it.
520A
If the NZ FLAG is set (no colon: no drive given), JUMP to 5210H with Register C still 00H, drive 0.
520C
LD A,(HL) 7E
Fetch the character after the colon at Register Pair HL into Register A: the drive digit, 0-7.
520D
AND 07H E6 07
Keep only bits 2-0 of Register A (AND 07H): the drive number. The character is not checked: any character after the colon gives a drive 0-7.
520F
LD C,A 4F
Copy Register A (the drive number, 0-7) into Register C, the drive for @CKDRV, RDSECT and GETDCT below.

5210H - Drive 0: Exchange the Diskettes

For drive 0, given or by default, LOG lets the diskette be changed: it shows Exchange disks and hit <ENTER> with the cursor on and waits for a key through the ROM; @CKDRV is not called, since a diskette just put in may not be in the drive code table yet. For any other drive @CKDRV must find the drive ready, or LOG ends with error 20H.

5210
LD A,C 79
Copy Register C (the drive number) into Register A, to test it for drive 0.
5211
AND A A7
AND Register A with itself to set the flags: the Z FLAG when Register A, the drive, is 0.
5212
If the NZ FLAG is set (drive 1-7), JUMP to 5224H to check the drive with @CKDRV.
5214
LD HL,5267H 21 67 52
Point Register Pair HL to 5267H, the text Exchange disks and hit <ENTER>, ended by 0EH (cursor on) and 03H.
5217
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (5267H) up to its 03H, which is not displayed; the 0EH before it turns the cursor on.
521A
GOSUB to 0049H, the ROM's keyboard wait, which returns in Register A the first key pressed. Any key goes on; ENTER is not checked.
521D
LD A,0DH 3E 0D
Load Register A with 0DH, the carriage return, to end the line of the prompt on the screen.
521F
GOSUB to 0033H, the ROM's display of the character in Register A (0DH): the cursor goes to the start of the next line.
5222
JUMP to 522CH to read the boot sector of drive 0 (Register C is still 00H) without calling @CKDRV.
5224
GOSUB to 4209H, @CKDRV, to check drive Register C: the Z FLAG when it is present and ready with a diskette that turns, the NZ FLAG when it is not.
5227
LD A,60H 3E 60
Load Register A with 60H: error 20H, Illegal drive number, with bit 6 set for the short message. LD does not change the flags of @CKDRV.
5229
If the NZ FLAG is set (@CKDRV found the drive not ready), JUMP to 4409H, @ERROR, with Register A = 60H: bit 7 is clear, so after the message LOG ends at @ABORT (4030H).

522CH - Read the Boot Sector: the Directory Cylinder

Cylinder 0, sector 0 holds a copy of the boot sector, whose byte 02H is the directory cylinder of the diskette. LOG reads it into the buffer at 5287H, beyond the file, and stores that byte at +09H of the drive's code table.

522C
LD HL,5287H 21 87 52
Point Register Pair HL to 5287H, the buffer of 256 bytes after the file (5287H-5386H) for the sectors LOG reads.
522F
LD DE,0000H 11 00 00
Load Register Pair DE with 0000H: Register D = cylinder 0, Register E = sector 0, the copy of the boot sector.
5232
GOSUB to 4777H, RDSECT, to read cylinder Register D (00H), sector Register E (00H) of drive Register C into the buffer at Register Pair HL (5287H). It returns the Z FLAG on success, else the NZ FLAG and the error number in Register A.
5235
SET 6,A CB F7
Set bit 6 of Register A (the error number) for the short message of @ERROR. SET does not change the flags of RDSECT.
5237
If the NZ FLAG is set (the read failed), JUMP to 4409H, @ERROR, to show the short message of Register A and end at @ABORT (bit 7 clear).
523A
GOSUB to 478FH, GETDCT, to point Index Register IY at the drive code table of drive Register C (4700H + the drive x 10). Register Pair HL is kept: 5287H.
523D
INC HL 23
INCrement Register Pair HL to 5288H, byte 01H of the boot sector in the buffer.
523E
INC HL 23
INCrement Register Pair HL to 5289H, byte 02H of the boot sector: the directory cylinder of the diskette.
523F
LD A,(HL) 7E
Fetch the directory cylinder from the boot sector at Register Pair HL (5289H) into Register A.
5240
LD (IY+09H),A FD 77 09
Store Register A (the directory cylinder) at +09H of the drive code table at Index Register IY, the byte every directory access of the drive takes its cylinder from.
5243
LD D,A 57
Copy Register A (the directory cylinder) into Register D, the cylinder for the next read.
5244
LD E,00H 1E 00
Load Register E with 00H: sector 0 of the directory cylinder, the allocation table.

5246H - Read the Allocation Table: the Number of Sides

The allocation table is read into the buffer; it must come back with the deleted data mark every sector of the directory cylinder carries (RDSECT's error 06H). Bit 5 of its byte CDH, the configuration byte, says that the diskette is double sided; it is copied into bit 5 of +04H of the drive code table, and LOG ends at @EXIT.

5246
LD HL,5287H 21 87 52
Point Register Pair HL to 5287H again, the buffer for the allocation table.
5249
GOSUB to 4777H, RDSECT, to read cylinder Register D (the directory cylinder), sector Register E (00H) of drive Register C into the buffer at Register Pair HL (5287H).
524C
CP 06H FE 06
Compare Register A against 06H, the code RDSECT returns for a sector read with the deleted data mark: the Z FLAG for the allocation table read as it should be.
524E
SET 6,A CB F7
Set bit 6 of Register A for the short message of @ERROR. SET does not change the flags of the compare.
5250
If the NZ FLAG is set (an error, or the sector read with the normal data mark: Register A = 40H, the short message of error 0), JUMP to 4409H, @ERROR, and end at @ABORT.
5253
LD DE,00CDH 11 CD 00
Load Register Pair DE with 00CDH, the offset of the configuration byte in the allocation table.
5256
ADD HL,DE 19
ADD Register Pair DE (00CDH) to Register Pair HL (5287H, kept by RDSECT): Register Pair HL = 5354H, byte CDH of the allocation table.
5257
LD A,(HL) 7E
Fetch the configuration byte of the allocation table at Register Pair HL (5354H) into Register A.
5258
AND 20H E6 20
Keep only bit 5 of Register A (AND 20H): 20H when the diskette is double sided, 00H when it is single sided.
525A
LD B,A 47
Copy Register A (20H or 00H) into Register B, to be put into the drive code table.
525B
LD A,(IY+04H) FD 7E 04
Fetch byte +04H of the drive code table at Index Register IY into Register A: the drive's flags.
525E
AND DFH E6 DF
Clear bit 5 of Register A (AND DFH), the two sided flag of the drive code table.
5260
OR B B0
OR Register B (bit 5 from the allocation table) into Register A: bit 5 set for a double sided diskette.
5261
LD (IY+04H),A FD 77 04
Store Register A at +04H of the drive code table at Index Register IY: the drive now uses one side or two as the diskette says.
5264
JUMP to 402DH, @EXIT, to end the program and go back to LDOS Ready (or the JCL job) without an error.

5267H - The Prompt and the Buffer

The text displayed for drive 0, then the buffer beyond the file that both sectors are read into.

5267-5284
DEFM "Exchange disks and hit <ENTER>" 45 78 63 68 61 6E 67 65 20 64 69 73 6B 73 20 61 6E 64 20 68 69 74 20 3C 45 4E 54 45 52 3E
5267H-5284H: the prompt displayed by @DSPLY from 5217H when LOG works on drive 0.
5285-5286
DEFB 0EH, 03H 0E 03
5285H-5286H: 0EH, the code that turns the cursor on, then 03H, the end of the text for @DSPLY (not displayed).
5287-5386
DEFS 256
5287H-5386H: not in the file. The buffer of RDSECT: the copy of the boot sector (522CH; its directory cylinder at 5289H), then the allocation table (5246H; its configuration byte at 5354H).