LDOS 5.3.1 for the Model III - DATECONV/CMD Disassembled

Page Customization

Introduction/Summary

LDOS 5.3.1 DATECONV/CMD Disassembly - Putting a Diskette's Directory into the 5.3 Date Format (Model III)

LDOS 5.3 keeps the time and a year from 1980 to 2011 in bytes +12H-+13H of each directory record, two bytes that earlier releases used for the access password of the file, and marks a diskette whose directory is kept that way with bit 3 of the configuration byte of its allocation table. DATECONV/CMD converts the directory of a diskette written by an earlier release: every file gets a time of 00:00 and the year of its date, and the diskette gets the mark. The command is DATECONV :d; the code takes nothing from the command line but the drive.

The file is a load module of 695 bytes: a record of type 1FH with the text Copyright 1991 MISOSYS, Inc., All rights reserved, three load blocks for 5200H-5473H (628 bytes) and the transfer address record for 5200H. DATECONV issues no supervisor request of its own: it calls the resident vectors of SYS0/SYS (and @CKDRV, which loads SYS2/SYS) and two ROM routines.

What DATECONV Does

StepWhat Happens
The driveAfter the spaces of the command line a colon and a digit 0-7 must follow; @CKDRV must find the drive ready. Otherwise error 20H, Illegal drive number, as a short message. A write protected diskette gives Write protected drive! (520FH, 5229H).
The allocation tableSector 0 of the directory cylinder (byte +09H of the drive code table) is read. When bit 3 of its configuration byte (offset CDH) is set the directory is already in this format, and only records whose +12H-+13H hold 4296H, the hash of a blank password, are changed below: any other value there is a time stamp (5241H).
A system disketteOn a diskette of an earlier release whose configuration byte does not have bit 7 set: when the first record of directory sector 5 (directory record 3, one of the slots of the system files) is in use, the system information sector (cylinder 0, sector 2) must start with 53H or 63H, else SYSTEM disk conversion requires a 5.3 or 6.3 disk! (524EH).
The directory sectorsThe number of sectors comes from the ending record number of DIR/SYS (the first record of directory sector 3) less 2, at most 32 (526EH). Sectors 2 onwards are read one by one; every primary record in use with a date (+02H not zero) gets 00H at +12H and the year (bits 2-0 of +02H) at +13H, and is counted. Each sector is written back with the deleted data mark and verified (5284H).
BREAKTested after every record: Date conversion aborted!, and the sector in the buffer is not written; the sectors written before stay converted and the diskette is not marked (52C1H).
The markThe allocation table is read again, bit 3 of the configuration byte set and the table written back; then n file(s) updated, conversion complete is displayed and written to the job log (52D9H).
The endThe program returns to whatever ran it with Register Pair HL = 0000H when it is done or FFFFH after an error or a message; during a JCL job an error ends at @ABORT instead (52FAH).

The Directory Record's Date

Byte +01H bits 3-0 hold the month, byte +02H bits 7-3 the day and bits 2-0 the year. DATECONV leaves them as they are. In the format of this release byte +12H holds the hour (bits 7-3) and bits 5-3 of the minutes (bits 2-0), and byte +13H bits 2-0 of the minutes (bits 7-5) and the year less 1980 (bits 4-0). DATECONV writes 00H to +12H and the year of +02H, 0-7, to +13H: the time 00:00 and a value 0-7, which bits 4-0 of +13H read as the years 1980-1987.

Reading and Writing the Directory

Every sector of the directory cylinder carries the deleted data mark. RDSECT reports such a sector with error 06H after it has read it, and DATECONV takes both 06H and success as a good read (5356H). A sector is written back with WRPROT, which writes the deleted data mark, and checked with VERSEC, which must report 06H (5344H). Any other result goes to @ERROR with bits 7 and 6 of the error number set: the short message, and back to DATECONV, which leaves with Register Pair HL = FFFFH.

About This Page

The Model III file is the Model I file of the same release with the same code at the same addresses; its 11 different bytes are the operands of six calls and loads of resident addresses: @CKDRV 4209H (5229H; Model I 44B8H), @LOGOT 428AH (52F4H, 5374H; Model I 447BH), SFLAG$ 442BH (5300H; Model I 430FH), @DIV 4451H (5315H; Model I 44C4H) and KFLAG$ 429FH (5323H; Model I 4423H). The ROM's delay at 0060H is a JP 01FBH to the same kind of loop on the Model III ROM; the keyboard routine at 002BH is the same.

Every byte of the file is shown at its address, with DEFS rows for 5474H-55FFH, the bytes DATECONV does not load; 5500H-55FFH is its sector buffer. The three message entries at 5369H, 536DH and 5371H overlap: 536DH and 5371H start one byte into the LD IX rows at 536CH and 5370H, whose comments give both readings.

Memory Map

Load Blocks in File Order

The three load blocks of the file in the order LDOS loads them, after the copyright record: 628 bytes, 5200H-5473H without a gap. The transfer address is 5200H.

AddressContents
5200H-52FFH256 bytes
5300H-53FFH256 bytes
5400H-5473H116 bytes

Sections of the Disassembly

AddressContents
5200HEntry: Save the Stack and Show the Banner
520FHThe Drive from the Command Line
5229HCheck the Drive and Read the Allocation Table
524EHThe System Diskette Test
526EHHow Many Directory Sectors
5284HThe Conversion Loop: Each Directory Sector
5289HEach Directory Record
52C1HThe Next Record and the Next Sector
52D9HMark the Diskette and Report
52FAHThe Exit
5309HWrite the Count as a Decimal Number
5322HTest for BREAK
5344HWrite a Directory Sector
5356HRead a Sector, and the Disk Errors
5369HThe Messages and the Way Out
5381HThe Texts and the Counter

Memory DATECONV/CMD Uses

AddressContents
0060HROM: the delay, Register Pair BC counted down (5332H); on the Model III ROM a JP 01FBH.
002BHROM: the keyboard routine, the next key waiting or 00H (5339H).
4030H@ABORT: the end of the program after an error during a JCL job (5306H).
4409H@ERROR: the short message of a disk error or of error 20H, then back to the program (5364H).
4467H, 428AH@DSPLY (the banner) and @LOGOT (the messages and the report, also written to the job log).
4209H@CKDRV: the check of the drive, which also reads the allocation table and stores the directory cylinder in the drive code table.
4451H@DIV: Register Pair HL divided by Register A, for the decimal count (5315H).
4700H-474FHDCT$, the drive code tables: GETDCT (478FH) points Index Register IY at the drive's table, whose +09H is the directory cylinder.
4768H, 4772H, 4777HWRPROT (write with the deleted data mark), VERSEC (verify) and RDSECT (read), the disk primitives of 5344H and 5356H.
5500H-55FFHThe buffer of the sectors DATECONV reads and writes.

Variables

The entry points of DATECONV/CMD, then the data of the file and the bytes beyond it that DATECONV uses, the operands it changes, and the cells outside the file that it uses, by address.

Entry Points

AddressContents
5200HThe start of DATECONV/CMD, the transfer address of the file.
5289HConvert one directory record.
52FAHThe exit: Register Pair HL = 0000H or FFFFH.
5309HWrite Register Pair HL as a decimal number right justified in the five bytes at Register Pair DE.
5322HTest for BREAK: the NZ FLAG when it was pressed.
5344HWrite the buffer at 5500H with the deleted data mark and verify it.
5356HRead a sector into the buffer at 5500H.
5362HA disk error (Register A) as a short message through @ERROR, then the exit.
5369HDisplay a message (5369H, 536DH, 5371H) through @LOGOT, then the exit.
537DHError 20H, Illegal drive number.

Data in the File and Beyond It

Address
Size
Contents
5381H-53AFH
47 bytes
DEFM "DATECONV - LDOS Date Conversion - Version 5.3.1"
5381H-53AFH: the first line of the banner, displayed by @DSPLY from 520BH: the name and the version of the program.
53B0H-53B0H
1 byte
DEFB 0AH
53B0H: 0AH, a line feed: the copyright goes on the next line within the same text.
53B1H-53E1H
49 bytes
DEFM "Copyright 1991 MISOSYS, Inc., All rights reserved"
53B1H-53E1H: the second line of the banner, the copyright, the same text as the copyright record of the file.
53E2H-53E3H
2 bytes
DEFB 0AH, 0DH
53E2H-53E3H: a line feed, then 0DH, the end of the banner: a blank line follows it on the screen.
53E4H-53E9H
6 bytes
DEFM " "
53E4H-53E9H: six spaces. 5309H writes the number of files converted right justified into 53E4H-53E8H; 53E9H stays a space before the words.
53EAH-540DH
36 bytes
DEFM "file(s) updated, conversion complete"
53EAH-540DH: the rest of the message displayed by @LOGOT from 52F4H when the conversion is done.
540EH-540EH
1 byte
DEFB 0DH
540EH: 0DH, the end of the message at 53E4H that reports the conversion.
540FH-5427H
25 bytes
DEFM "Date conversion aborted!" / DEFB 0DH
540FH-5427H: the message of 5371H, for BREAK pressed during the conversion (52C4H), ended by 0DH at 5427H.
5428H-545AH
51 bytes
DEFM "SYSTEM disk conversion requires a 5.3 or 6.3 disk!" / DEFB 0DH
5428H-545AH: the message of 5369H, for a system diskette whose system information sector does not start with 53H or 63H (526BH), ended by 0DH at 545AH.
545BH-5471H
23 bytes
DEFM "Write protected drive!" / DEFB 0DH
545BH-5471H: the message of 536DH, for a write protected diskette (522FH), ended by 0DH at 5471H.
5472H-5473H
2 bytes
DEFW 0000H
5472H-5473H: the number of files converted, 0000H when the program is loaded; 52BEH adds one for every record converted and 52E9H takes it for the message.
5474H-54FFH
140 bytes
DEFS 140
5474H-54FFH: not in the file and not used by DATECONV.
5500H-55FFH
256 bytes
DEFS 256
5500H-55FFH: not in the file. The buffer of every sector DATECONV reads and writes: the allocation table (523EH, 52DBH; its configuration byte at 55CDH), directory sector 5 and the system information sector (524EH-5264H), directory sector 3 (5272H, the ending record number of DIR/SYS at 5514H) and each sector of directory records (5286H).

Operands Changed While It Runs

Address
Size
Contents
526FH
1 byte
The operand of LD D,00H at 526EH: the directory cylinder of the drive, stored by 5238H from +09H of its drive code table.
52A2H
1 byte
The operand of LD A,00H at 52A1H: 00H for a diskette of an earlier release; the configuration byte of the diskette (bit 3 set) when its directory already has this release's date format (5249H). Not zero means only records whose +12H-+13H hold 4296H are changed.
52D3H
1 byte
The operand of LD A,00H at 52D2H: the last directory sector to convert, the ending record number of DIR/SYS less 1, at most 21H (5281H).
52FBH-52FCH
2 bytes
The operand of LD SP,0000H at 52FAH: the Stack Pointer at entry, stored by 5200H.
5348H
1 byte
The operand of LD C,00H at 5347H: the drive given, stored by 5222H, for the writes.
535AH
1 byte
The operand of LD C,00H at 5359H: the drive given, stored by 5225H, for the reads.

Cells Outside the File That DATECONV/CMD Uses

Address
Size
Contents
442BH
1 byte
SFLAG$, the system flags: bit 5 set while a JCL job runs (5303H).
429FH
1 byte
KFLAG$, the keyboard flags: bit 0 set by the keyboard scan when BREAK is pressed, cleared by 532DH.
IY +09HThe directory cylinder in the drive code table of the drive given (5235H).
Allocation table +CDH
1 byte
The configuration byte of the diskette (55CDH in the buffer): bit 3 set when the directory has this release's date format; DATECONV tests it (5244H) and sets it when it is done (52E1H). With bit 7 set and bit 3 clear the system diskette test is skipped (524EH).
Directory record +00H
1 byte
The attribute byte: bit 7 an extension record, bit 4 in use (528AH, 528FH).
Directory record +02H
1 byte
Bits 7-3 the day, bits 2-0 the year of the date; 00H for a record with no date (5296H).
Directory record +12H-+13H
2 bytes
In this release's date format: +12H bits 7-3 the hour, bits 2-0 bits 5-3 of the minutes; +13H bits 7-5 bits 2-0 of the minutes, bits 4-0 the year less 1980. DATECONV stores 00H and the year from +02H (52B6H-52B9H). An earlier release keeps 4296H there for a file without an access password.
Directory record +14H
1 byte
The low byte of the ending record number; for DIR/SYS (directory sector 3, the first record) the number of sectors of the directory (5275H).
System information sector +00H
1 byte
Cylinder 0, sector 2, byte 0: 53H on a system diskette of this release; DATECONV also accepts 63H (5264H).

Disassembly

5200H - Entry: Save the Stack and Show the Banner

LDOS Ready loads DATECONV/CMD at 5200H-5473H and jumps to 5200H, the transfer address, with Register Pair HL pointing at the rest of the command line after the word DATECONV and the Stack Pointer at the return address. DATECONV keeps the Stack Pointer for its exit, clears a BREAK left over from before, and shows its banner.

5200
LD (52FBH),SP ED 73 FB 52
Store the Stack Pointer, which points at the return address LDOS put on the stack when it ran the program, at 52FBH, the operand of LD SP,0000H at 52FAH: every way out of DATECONV goes through 52FAH and so finds the stack as it was at entry.
5204
PUSH HL E5
Save Register Pair HL, the pointer to the rest of the command line, to the stack while the banner is shown.
5205
GOSUB to 5322H to test bit 0 of KFLAG$ (429FH), the BREAK flag, and clear it: a BREAK pressed before DATECONV ran must not end the conversion. The flags it returns are not used here.
5208
LD HL,5381H 21 81 53
Point Register Pair HL to 5381H, the banner: the name and version of DATECONV and the copyright, two lines ended by 0DH.
520B
GOSUB to 4467H, @DSPLY, to display the text at Register Pair HL (5381H) up to its 0DH.
520E
POP HL E1
Restore Register Pair HL from the stack: the pointer to the rest of the command line.

520FH - The Drive from the Command Line

The command is DATECONV :d. After the spaces a colon must follow and then a digit 0-7; anything else gives error 20H, Illegal drive number. The drive number is put into the two disk routines and checked by @CKDRV.

520F
LD A,(HL) 7E
Fetch the next character of the command line at Register Pair HL into Register A.
5210
CP 20H FE 20
Compare Register A (the character) against 20H, a space.
5212
INC HL 23
INCrement Register Pair HL past the character just fetched. INC of a register pair does not change the flags of the compare.
5213
If the Z FLAG is set (Register A was a space), JUMP back to 520FH to take the next character: spaces before the drive are skipped.
5215
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.
5217
If the NZ FLAG is set (no colon: the drive is not given), JUMP to 537DH to give error 20H, Illegal drive number, and leave.
521A
LD A,(HL) 7E
Fetch the character after the colon at Register Pair HL into Register A: the drive digit.
521B
SUB 30H D6 30
SUBtract 30H, the character 0, from Register A: Register A = the drive number when the character was a digit.
521D
CP 08H FE 08
Compare Register A (the drive number) against 08H: the CARRY FLAG is set for drives 0-7.
521F
If the NC FLAG is set (Register A is 8 or more, or the character was below 0 and the subtraction wrapped), JUMP to 537DH to give error 20H, Illegal drive number, and leave.
5222
LD (5348H),A 32 48 53
Store Register A (the drive number, 0-7) at 5348H, the operand of LD C,00H at 5347H in the sector write routine (5344H).
5225
LD (535AH),A 32 5A 53
Store Register A (the drive number) at 535AH, the operand of LD C,00H at 5359H in the sector read routine (5356H). Every sector DATECONV reads or writes is on this drive.
5228
LD C,A 4F
Copy Register A (the drive number) into Register C, the drive for @CKDRV and GETDCT.

5229H - Check the Drive and Read the Allocation Table

@CKDRV must find the drive ready and its diskette not write protected. The directory cylinder comes from byte +09H of the drive code table, which @CKDRV has just brought into line with the diskette, and sector 0 of that cylinder, the allocation table, is read into the buffer at 5500H. Bit 3 of its configuration byte (offset CDH) says that the directory already has the date format of this release.

5229
GOSUB to 4209H, @CKDRV, to check drive Register C: the drive must be present, its diskette must turn and its allocation table must read. @CKDRV returns the Z FLAG when the drive is ready and the CARRY FLAG with it when the diskette is write protected; Register Pairs BC, DE, HL and Index Register IY are kept.
522C
If the NZ FLAG is set (@CKDRV found the drive missing or not ready), JUMP to 537DH to give error 20H, Illegal drive number, and leave. The error number @CKDRV returned in Register A is not used.
522F
If the CARRY FLAG is set (the diskette is write protected), JUMP to 536DH, an entry inside the LD IX,545BH at 536CH, to display Write protected drive! and leave.
5232
GOSUB to 478FH, GETDCT, to point Index Register IY at the drive code table of drive Register C (4700H + drive x 10).
5235
LD A,(IY+09H) FD 7E 09
Fetch byte +09H of the drive code table at Index Register IY into Register A: the directory cylinder of the diskette, which @CKDRV has just stored from the diskette.
5238
LD (526FH),A 32 6F 52
Store Register A (the directory cylinder) at 526FH, the operand of LD D,00H at 526EH, for the reads of the directory sectors after the system diskette test.
523B
LD D,A 57
Copy Register A (the directory cylinder) into Register D, the cylinder for the read below.
523C
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder: the allocation table.
523E
GOSUB to 5356H to read cylinder Register D, sector Register E (00H) of the drive into the buffer at 5500H-55FFH. A read error ends the program there.
5241
LD A,(55CDH) 3A CD 55
Fetch the byte at 55CDH into Register A: byte CDH of the allocation table, the configuration byte of the diskette.
5244
BIT 3,A CB 5F
Test bit 3 of Register A (the configuration byte): set when the directory of the diskette already has the date format of this release (the time and the year in bytes +12H-+13H of each directory record).
5246
If the Z FLAG is set (bit 3 is clear: a diskette of an earlier release), JUMP to 524EH to make the system diskette test.
5249
LD (52A2H),A 32 A2 52
Store Register A (the configuration byte, not zero since its bit 3 is set) at 52A2H, the operand of LD A,00H at 52A1H: on a diskette already in this format the loop changes only records whose bytes +12H-+13H hold 4296H, the hash of a blank password.
524C
JUMP to 526EH: a diskette already in this format is not tested for system files.

524EH - The System Diskette Test

A diskette of an earlier release that holds the system files is converted only when its system information sector (cylinder 0, sector 2) starts with 53H or 63H; else DATECONV stops with SYSTEM disk conversion requires a 5.3 or 6.3 disk!. The diskette counts as a system diskette when the first record of directory sector 5 (directory record 3, one of the slots the system files take) is in use. A configuration byte with bit 7 set skips the test.

524E
BIT 7,A CB 7F
Test bit 7 of Register A, the configuration byte of the diskette from 55CDH.
5250
If the NZ FLAG is set (bit 7 of the configuration byte is set), JUMP to 526EH: the diskette is converted without the system diskette test.
5252
LD E,05H 1E 05
Load Register E with 05H, sector 5 of the directory cylinder (Register D still holds the directory cylinder).
5254
GOSUB to 5356H to read cylinder Register D, sector Register E (05H) into the buffer at 5500H. The allocation table read before is no longer needed: it is read again at 52DBH.
5257
LD A,(5500H) 3A 00 55
Fetch the byte at 5500H into Register A: byte +00H of the first record of directory sector 5, its attribute byte. That record is directory record 3, a slot the system files of a system diskette take.
525A
AND 10H E6 10
Keep only bit 4 of Register A (AND 10H), the bit that says the record is in use.
525C
If the Z FLAG is set (the record is free: not a system diskette), JUMP to 526EH to convert it.
525E
LD DE,0002H 11 02 00
Load Register Pair DE with 0002H: Register D = cylinder 0, Register E = sector 2, the system information sector.
5261
GOSUB to 5356H to read cylinder Register D (00H), sector Register E (02H) into the buffer at 5500H. The read routine leaves Register Pair HL at 5500H, the start of the sector.
5264
LD A,(HL) 7E
Fetch the first byte of the system information sector at Register Pair HL (5500H) into Register A.
5265
CP 53H FE 53
Compare Register A (the first byte) against 53H, the character S, the mark the system information sector of this release starts with.
5267
If the Z FLAG is set (the sector starts with 53H), JUMP to 526EH to convert the diskette.
5269
CP 63H FE 63
Compare Register A (the first byte) against 63H, the character c, the other value DATECONV accepts.
526B
If the NZ FLAG is set (neither 53H nor 63H), JUMP to 5369H to display SYSTEM disk conversion requires a 5.3 or 6.3 disk! and leave.

526EH - How Many Directory Sectors

The first record of directory sector 3 is directory record 1, the record of DIR/SYS. Its ending record number (+14H) is the number of sectors of the directory cylinder that the directory takes; less the allocation table and the hash index table it is the number of sectors that hold directory records, at most 32. The last sector to convert is stored in the loop's compare.

526E
LD D,00H 16 00
Load Register D with the directory cylinder: the operand 526FH was set at 5238H from byte +09H of the drive code table (00H in the file).
5270
LD E,03H 1E 03
Load Register E with 03H, sector 3 of the directory cylinder, whose first record is directory record 1, DIR/SYS.
5272
GOSUB to 5356H to read cylinder Register D, sector Register E (03H) into the buffer at 5500H.
5275
LD A,(5514H) 3A 14 55
Fetch the byte at 5514H into Register A: byte +14H of the record of DIR/SYS, the low byte of its ending record number, the number of sectors the directory takes on its cylinder.
5278
SUB 02H D6 02
SUBtract 02H from Register A for the allocation table (sector 0) and the hash index table (sector 1): Register A = the number of sectors that hold directory records.
527A
CP 21H FE 21
Compare Register A (the number of record sectors) against 21H: the CARRY FLAG is set for 32 or fewer.
527C
If the CARRY FLAG is set (32 sectors or fewer), JUMP to 5280H to keep Register A.
527E
LD A,20H 3E 20
Load Register A with 20H: at most 32 sectors of directory records are converted (also when the subtraction wrapped).
5280
INC A 3C
INCrement Register A by 1: the record sectors are 2 to Register A, so Register A = the number of the last sector to convert.
5281
LD (52D3H),A 32 D3 52
Store Register A (the last sector) at 52D3H, the operand of LD A,00H at 52D2H, the compare at the end of each sector of the loop.

5284H - The Conversion Loop: Each Directory Sector

Register D holds the directory cylinder and Register E the sector, from 2 up to the last sector. Each sector is read into 5500H, its eight records of 32 bytes are worked through, and the sector is written back with the deleted data mark and verified.

5284
LD E,02H 1E 02
Load Register E with 02H, the first sector of directory records (Register D holds the directory cylinder).
5286
GOSUB to 5356H to read cylinder Register D, sector Register E into the buffer at 5500H, with Register Pair HL = 5500H, the first record of the sector.

5289H - Each Directory Record

A record is converted when it is a primary record (attribute bit 7 clear), in use (bit 4 set) and dated (byte +02H not zero). The year, bits 2-0 of +02H, goes into bits 4-0 of +13H, where this release keeps the year less 1980, and +12H (the hour and part of the minutes) and the rest of +13H are set to 00H. On a diskette already in this format only records whose bytes +12H-+13H hold 4296H are changed, since any other value there is a time stamp. Each change counts one file.

5289
PUSH HL E5
Save Register Pair HL, the address of the record (5500H + slot x 20H), to the stack.
528A
BIT 7,(HL) CB 7E
Test bit 7 of byte +00H, the attribute byte, of the record at Register Pair HL: set for an extension record, which holds only more extents of a file.
528C
If the NZ FLAG is set (an extension record), JUMP to 52C1H to go on to the next record.
528F
BIT 4,(HL) CB 66
Test bit 4 of the attribute byte of the record at Register Pair HL: set when the record is in use.
5291
If the Z FLAG is set (a free record), JUMP to 52C1H to go on to the next record.
5294
INC L 2C
INCrement Register L by 1: Register Pair HL = the record + 01H. The records of the buffer are all in 5500H-55FFH, so Register H does not change.
5295
INC L 2C
INCrement Register L by 1: Register Pair HL = the record + 02H, the day and the year of the date.
5296
LD A,(HL) 7E
Fetch byte +02H of the record at Register Pair HL into Register A: bits 7-3 the day, bits 2-0 the year.
5297
OR A B7
OR Register A with itself to set the flags: the Z FLAG when byte +02H is 00H.
5298
If the Z FLAG is set (no date), JUMP to 52C1H to go on to the next record.
529A
AND 07H E6 07
Keep only bits 2-0 of Register A (AND 07H): the year of the record, 0-7.
529C
LD C,A 4F
Copy Register A (the year) into Register C, to be stored at +13H.
529D
LD A,L 7D
Copy Register L (the low byte of the record + 02H) into Register A.
529E
ADD A,10H C6 10
ADD 10H to Register A: the low byte of the record + 12H.
52A0
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the record + 12H, the two bytes this release uses for the time and the year.
52A1
LD A,00H 3E 00
Load Register A with the operand 52A2H: 00H in the file, or the configuration byte of the diskette (stored at 5249H) when its directory is already in this format.
52A3
OR A B7
OR Register A with itself to set the flags: the Z FLAG for a diskette of an earlier release.
52A4
If the Z FLAG is set (a diskette of an earlier release: every dated record is converted), JUMP to 52B6H to store the time and the year.
52A6
PUSH DE D5
Save Register Pair DE (Register D the directory cylinder, Register E the sector) to the stack.
52A7
PUSH HL E5
Save Register Pair HL (the record + 12H) to the stack.
52A8
LD DE,4296H 11 96 42
Load Register Pair DE with 4296H, the hash of a blank password, the value an earlier release leaves at +12H-+13H when the file has no access password.
52AB
LD A,(HL) 7E
Fetch byte +12H of the record at Register Pair HL into Register A: the low byte of the word.
52AC
INC HL 23
INCrement Register Pair HL to the record + 13H.
52AD
LD H,(HL) 66
Fetch byte +13H of the record at Register Pair HL into Register H: the high byte of the word.
52AE
LD L,A 6F
Copy Register A (byte +12H) into Register L: Register Pair HL = the word at +12H-+13H.
52AF
OR A B7
OR Register A with itself to clear the CARRY FLAG for the subtraction below.
52B0
SBC HL,DE ED 52
SUBtract Register Pair DE (4296H) from Register Pair HL (the word at +12H-+13H): the Z FLAG when they are equal.
52B2
POP HL E1
Restore Register Pair HL from the stack: the record + 12H. POP does not change the flags.
52B3
POP DE D1
Restore Register Pair DE from the stack: Register D the directory cylinder, Register E the sector.
52B4
If the NZ FLAG is set (the word is not 4296H: a time stamp of this release), JUMP to 52C1H and leave the record alone.
52B6
LD (HL),00H 36 00
Store 00H at byte +12H of the record at Register Pair HL: hours 0 (bits 7-3) and bits 5-3 of the minutes 0 (bits 2-0).
52B8
INC HL 23
INCrement Register Pair HL to the record + 13H.
52B9
LD (HL),C 71
Store Register C (the year, 0-7) at byte +13H of the record at Register Pair HL: bits 7-5, bits 2-0 of the minutes, 0; bits 4-0 the year less 1980.
52BA
LD HL,(5472H) 2A 72 54
Fetch the word at 5472H-5473H into Register Pair HL: the number of files converted so far.
52BD
INC HL 23
INCrement Register Pair HL by 1, for the record just converted.
52BE
LD (5472H),HL 22 72 54
Store Register Pair HL (the new count) at 5472H-5473H.

52C1H - The Next Record and the Next Sector

After every record BREAK is tested: BREAK ends the program with Date conversion aborted!, and the sector in the buffer is not written. After the eighth record the sector is written back; after the last sector the loop ends.

52C1
GOSUB to 5322H to test bit 0 of KFLAG$ (429FH): the NZ FLAG when BREAK was pressed (the flag is cleared and the keyboard emptied).
52C4
If the NZ FLAG is set (BREAK), JUMP to 5371H, an entry inside the LD IX,540FH at 5370H, to display Date conversion aborted! and leave. The record address saved at 5289H stays on the stack; the exit at 52FAH sets the Stack Pointer anew.
52C7
POP HL E1
Restore Register Pair HL from the stack: the address of the record just handled (its +00H).
52C8
LD A,L 7D
Copy Register L (the low byte of the record address) into Register A.
52C9
ADD A,20H C6 20
ADD 20H to Register A, the length of a record: the low byte of the next record. After the eighth record the sum is 00H with the Z FLAG.
52CB
LD L,A 6F
Copy Register A into Register L: Register Pair HL = the next record. ADD set the flags; LD keeps them.
52CC
If the NZ FLAG is set (another record in the sector), JUMP back to 5289H to handle it.
52CF
GOSUB to 5344H to write the buffer at 5500H back to cylinder Register D, sector Register E with the deleted data mark and verify it. Every sector is written back, changed or not.
52D2
LD A,00H 3E 00
Load Register A with the last sector to convert: the operand 52D3H, set at 5281H (00H in the file).
52D4
INC E 1C
INCrement Register E by 1, to the next sector of the directory cylinder.
52D5
CP E BB
Compare Register A (the last sector) against Register E (the next sector): the NC FLAG while Register E is not past the last sector.
52D6
If the NC FLAG is set (Register E is the last sector or before it), JUMP back to 5286H to read and convert that sector.

52D9H - Mark the Diskette and Report

The allocation table is read again, bit 3 of its configuration byte is set so that the diskette counts as one in the date format of this release, and it is written back. The number of files converted is put right justified into the first five bytes of the message at 53E4H, which is displayed and written to the job log.

52D9
LD E,00H 1E 00
Load Register E with 00H, sector 0 of the directory cylinder (Register D): the allocation table.
52DB
GOSUB to 5356H to read cylinder Register D, sector Register E (00H) into the buffer at 5500H.
52DE
LD A,(55CDH) 3A CD 55
Fetch the byte at 55CDH into Register A: byte CDH of the allocation table, the configuration byte.
52E1
OR 08H F6 08
OR 08H into Register A: set bit 3, the directory has the date format of this release.
52E3
LD (55CDH),A 32 CD 55
Store Register A (the configuration byte with bit 3 set) back at 55CDH.
52E6
GOSUB to 5344H to write the allocation table at 5500H back to cylinder Register D, sector Register E (00H) with the deleted data mark and verify it.
52E9
LD HL,(5472H) 2A 72 54
Fetch the word at 5472H-5473H into Register Pair HL: the number of files converted.
52EC
LD DE,53E4H 11 E4 53
Point Register Pair DE to 53E4H, the message file(s) updated, conversion complete, whose first bytes take the number.
52EF
PUSH DE D5
Save Register Pair DE (53E4H) to the stack, for the display below.
52F0
GOSUB to 5309H to write Register Pair HL (the count) as a decimal number right justified in 53E4H-53E8H.
52F3
POP HL E1
Restore the message address 53E4H from the stack into Register Pair HL.
52F4
GOSUB to 428AH, @LOGOT, to display the message at Register Pair HL (53E4H) and write it to the job log.
52F7
LD HL,0000H 21 00 00
Load Register Pair HL with 0000H: no error, the value the program returns.

52FAH - The Exit

Every way out of DATECONV comes here with Register Pair HL = 0000H (done) or FFFFH (an error, BREAK or a refusal). The Stack Pointer is set back to its value at entry and the program returns to whatever ran it. When a JCL job runs and there was an error, the program ends at @ABORT instead, which ends the job.

52FA
LD SP,0000H 31 00 00
Load the Stack Pointer with the operand 52FBH, the value it had at entry (stored at 5200H; 0000H in the file): any bytes the program left on the stack are dropped.
52FD
LD A,H 7C
Copy Register H (the high byte of the result) into Register A.
52FE
OR L B5
OR Register L (the low byte of the result) into Register A: the Z FLAG when Register Pair HL is 0000H.
52FF
RET Z C8
If the Z FLAG is set (Register Pair HL = 0000H, no error), RETURN to whatever ran the program, with Register Pair HL = 0000H.
5300
LD A,(442BH) 3A 2B 44
Fetch the byte at 442BH, SFLAG$, the system flags, into Register A.
5303
BIT 5,A CB 6F
Test bit 5 of Register A (SFLAG$): set while a JCL job runs.
5305
RET Z C8
If the Z FLAG is set (no JCL job), RETURN to whatever ran the program, with Register Pair HL = FFFFH, an error.
5306
JUMP to 4030H, @ABORT: during a JCL job an error ends the program and the job.

5309H - Write the Count as a Decimal Number

Register Pair HL holds the number and Register Pair DE the start of a field of five bytes. The field is filled with spaces and the digits are stored from its last byte backwards, one division by 10 at a time, so the number ends up right justified. Register Pair DE comes back pointing at the byte after the field.

5309
LD B,05H 06 05
Load Register B with 05H, the length of the field.
530B
LD A,20H 3E 20
Load Register A with 20H, a space, the byte the field is filled with.
530D
LD (DE),A 12
Store Register A (a space) at the byte of the field at Register Pair DE.
530E
INC DE 13
INCrement Register Pair DE to the next byte of the field.
530F
DECrement Register B and, while it is not zero, JUMP back to 530DH: five spaces, Register Pair DE then one past the field (53E9H for the message at 53E4H).
5311
PUSH DE D5
Save Register Pair DE (one past the field) to the stack, to be returned.
5312
DEC DE 1B
DECrement Register Pair DE to the last byte of the field, where the units digit goes.
5313
LD A,0AH 3E 0A
Load Register A with 0AH, the divisor 10, for the next digit of the number.
5315
GOSUB to 4451H, @DIV, to divide Register Pair HL (the number) by Register A (10): the quotient in Register Pair HL, the remainder (the next digit, 0-9) in Register A. @DIV keeps Register Pairs BC and DE.
5318
ADD A,30H C6 30
ADD 30H, the character 0, to Register A: the digit as a character.
531A
LD (DE),A 12
Store Register A (the digit) at the byte of the field at Register Pair DE.
531B
DEC DE 1B
DECrement Register Pair DE to the byte to the left, for the next digit.
531C
LD A,H 7C
Copy Register H (the high byte of the quotient) into Register A.
531D
OR L B5
OR Register L (the low byte of the quotient) into Register A: the Z FLAG when the quotient is 0.
531E
If the NZ FLAG is set (digits remain), JUMP back to 5313H for the next digit. A count of 0 still gives one digit, 0. The count is at most 256, never more than the five bytes hold.
5320
POP DE D1
Restore Register Pair DE from the stack: one past the field.
5321
RET C9
RETURN to the caller, with Register Pair HL = 0000H, the last quotient.

5322H - Test for BREAK

Bit 0 of KFLAG$ (429FH) is set by the keyboard scan of the interrupt routine when BREAK is pressed. When it is clear the routine returns at once with the Z FLAG. When it is set the routine clears it, waits until it stays clear (BREAK released), takes every key waiting in the keyboard, and returns with the NZ FLAG. Register A and Register Pairs BC, DE and HL are kept.

5322
PUSH HL E5
Save Register Pair HL to the stack, for the caller.
5323
LD HL,429FH 21 9F 42
Point Register Pair HL to 429FH, KFLAG$, the keyboard flags.
5326
BIT 0,(HL) CB 46
Test bit 0 of KFLAG$ at Register Pair HL (429FH): set when BREAK was pressed.
5328
If the Z FLAG is set (no BREAK), JUMP to 5342H to restore Register Pair HL and return with the Z FLAG.
532A
PUSH AF F5
Save Register Pair AF to the stack: Register A of the caller and the NZ FLAG of the test just made, which the routine returns.
532B
PUSH BC C5
Save Register Pair BC to the stack: the ROM's delay at 0060H counts it down.
532C
PUSH DE D5
Save Register Pair DE to the stack, around the ROM's keyboard routine at 002BH.
532D
RES 0,(HL) CB 86
Clear bit 0 of KFLAG$ at Register Pair HL (429FH), the BREAK flag.
532F
LD BC,0B00H 01 00 0B
Load Register Pair BC with 0B00H, the count for the ROM's delay.
5332
GOSUB to 0060H, the ROM's delay (on the Model III ROM a JP 01FBH to the loop), which counts Register Pair BC (0B00H) down to zero; it changes Register A.
5335
BIT 0,(HL) CB 46
Test bit 0 of KFLAG$ at Register Pair HL (429FH) again: the keyboard scan sets it again while BREAK is held.
5337
If the NZ FLAG is set (BREAK is still held), JUMP back to 532DH to clear the flag and wait again.
5339
GOSUB to 002BH, the ROM's keyboard routine, which returns in Register A the next key waiting, or 00H when there is none.
533C
OR A B7
OR Register A with itself to set the flags: the Z FLAG when no key was waiting.
533D
If the NZ FLAG is set (a key was taken), JUMP back to 5339H to take the next one: the keyboard is emptied.
533F
POP DE D1
Restore Register Pair DE from the stack, the caller's value.
5340
POP BC C1
Restore Register Pair BC from the stack, the caller's value.
5341
POP AF F1
Restore Register Pair AF from the stack: Register A of the caller and the NZ FLAG, BREAK was pressed.
5342
POP HL E1
Restore Register Pair HL from the stack, the caller's value. POP HL does not change the flags.
5343
RET C9
RETURN to the caller: the Z FLAG for no BREAK, the NZ FLAG for BREAK.

5344H - Write a Directory Sector

Writes the buffer at 5500H to cylinder Register D, sector Register E of the drive given, with the deleted data mark every sector of the directory cylinder carries, and reads it back with a verify. The verify must report error 06H, the code for a sector with the deleted data mark: anything else, a write error included, ends the program through @ERROR.

5344
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the buffer the sector is written from.
5347
LD C,00H 0E 00
Load Register C with the drive: the operand 5348H, set at 5222H from the command line (00H in the file).
5349
GOSUB to 4768H, WRPROT, to write the 256 bytes at Register Pair HL (5500H) to cylinder Register D, sector Register E of drive Register C with the deleted data mark. It returns the Z FLAG on success, else the NZ FLAG with the error number in Register A (0FH when the drive is write protected).
534C
If the NZ FLAG is set (the write failed), JUMP to 5362H to give the error number in Register A through @ERROR and leave.
534E
GOSUB to 4772H, VERSEC, to read cylinder Register D, sector Register E of drive Register C back without storing it: Register A = 06H when it reads back with the deleted data mark.
5351
CP 06H FE 06
Compare Register A (the result of the verify) against 06H, the code for the deleted data mark.
5353
If the NZ FLAG is set (any other result: an error, or 00H for a sector with the normal data mark, which gives error 0), JUMP to 5362H to give Register A through @ERROR and leave.
5355
RET C9
RETURN to the caller with the Z FLAG: the sector is written and verified.

5356H - Read a Sector, and the Disk Errors

Reads cylinder Register D, sector Register E of the drive given into the buffer at 5500H-55FFH and returns with Register Pair HL = 5500H. A sector with the normal data mark (Z FLAG) and one with the deleted data mark (error 06H) are both taken. Any other result, and any failure of the write routine, ends the program at 5362H: the error number gets bits 7 and 6 set, so @ERROR shows its short message and comes back, and the program leaves with Register Pair HL = FFFFH.

5356
LD HL,5500H 21 00 55
Point Register Pair HL to 5500H, the buffer the sector is read into.
5359
LD C,00H 0E 00
Load Register C with the drive: the operand 535AH, set at 5225H from the command line (00H in the file).
535B
GOSUB to 4777H, RDSECT, to read cylinder Register D, sector Register E of drive Register C into the buffer at Register Pair HL (5500H). Register Pairs BC, DE and HL are kept. It returns the Z FLAG on success, else the NZ FLAG with the error number in Register A.
535E
RET Z C8
If the Z FLAG is set (the sector was read), RETURN to the caller.
535F
CP 06H FE 06
Compare Register A (the error number) against 06H, the code for a sector with the deleted data mark, the mark of the directory sectors.
5361
RET Z C8
If the Z FLAG is set (the sector carries the deleted data mark and was read), RETURN to the caller.
5362
OR C0H F6 C0
OR C0H into Register A (the error number): bit 7 tells @ERROR to return to the program, bit 6 to show the short message.
5364
GOSUB to 4409H, @ERROR, to display the message of the error number in Register A (bits 5-0) and return here.
5367
JUMP to 5377H to leave with Register Pair HL = FFFFH.

5369H - The Messages and the Way Out

Three entries display a message through @LOGOT. Each entry is a LD HL with the message address; the entries before it run over its first byte, DDH, which turns the next LD HL into a LD IX that changes nothing the program uses. So 5369H shows the system diskette message, 536DH the write protect message and 5371H the BREAK message. All three, and the errors, leave with Register Pair HL = FFFFH.

5369
LD HL,5428H 21 28 54
Point Register Pair HL to 5428H, the message SYSTEM disk conversion requires a 5.3 or 6.3 disk! (the system diskette test, 526BH).
536C
LD IX,545BH DD 21 5B 54
Load Index Register IX with 545BH: entered from 5369H, this only passes over the LD HL,545BH that starts at 536DH, and Register Pair HL keeps the message 5428H. Index Register IX is not used by DATECONV. Entered at 536DH from 522FH (write protected diskette), the bytes 21H 5BH 54H are LD HL,545BH: Register Pair HL points to Write protected drive!.
5370
LD IX,540FH DD 21 0F 54
Load Index Register IX with 540FH: entered from 5369H or 536DH, this only passes over the LD HL,540FH that starts at 5371H, and Register Pair HL keeps its message. Entered at 5371H from 52C4H (BREAK), the bytes 21H 0FH 54H are LD HL,540FH: Register Pair HL points to Date conversion aborted!.
5374
GOSUB to 428AH, @LOGOT, to display the message at Register Pair HL and write it to the job log.
5377
LD HL,FFFFH 21 FF FF
Load Register Pair HL with FFFFH, the result for an error.
537A
JUMP to 52FAH, the exit, to set the Stack Pointer back and return or end at @ABORT.
537D
LD A,20H 3E 20
Load Register A with 20H, error 32, Illegal drive number: no drive spec, a drive above 7, or a drive @CKDRV found not ready.
537F
JUMP to 5362H to give error 20H in Register A as a short message through @ERROR and leave.

5381H - The Texts and the Counter

The banner, the four messages, each ended by 0DH, and the word that counts the files converted. The message at 53E4H starts with six spaces: the first five take the count (5309H), the sixth stays a space before the words.

5381-53AF
DEFM "DATECONV - LDOS Date Conversion - Version 5.3.1" 44 41 54 45 43 4F 4E 56 20 2D 20 4C 44 4F 53 20 44 61 74 65 20 43 6F 6E 76 65 72 73 69 6F 6E 20 2D 20 56 65 72 73 69 6F 6E 20 35 2E 33 2E 31
5381H-53AFH: the first line of the banner, displayed by @DSPLY from 520BH: the name and the version of the program.
53B0
DEFB 0AH 0A
53B0H: 0AH, a line feed: the copyright goes on the next line within the same text.
53B1-53E1
DEFM "Copyright 1991 MISOSYS, Inc., All rights reserved" 43 6F 70 79 72 69 67 68 74 20 31 39 39 31 20 4D 49 53 4F 53 59 53 2C 20 49 6E 63 2E 2C 20 41 6C 6C 20 72 69 67 68 74 73 20 72 65 73 65 72 76 65 64
53B1H-53E1H: the second line of the banner, the copyright, the same text as the copyright record of the file.
53E2-53E3
DEFB 0AH, 0DH 0A 0D
53E2H-53E3H: a line feed, then 0DH, the end of the banner: a blank line follows it on the screen.
53E4-53E9
DEFM " " 20 20 20 20 20 20
53E4H-53E9H: six spaces. 5309H writes the number of files converted right justified into 53E4H-53E8H; 53E9H stays a space before the words.
53EA-540D
DEFM "file(s) updated, conversion complete" 66 69 6C 65 28 73 29 20 75 70 64 61 74 65 64 2C 20 63 6F 6E 76 65 72 73 69 6F 6E 20 63 6F 6D 70 6C 65 74 65
53EAH-540DH: the rest of the message displayed by @LOGOT from 52F4H when the conversion is done.
540E
DEFB 0DH 0D
540EH: 0DH, the end of the message at 53E4H that reports the conversion.
540F-5427
DEFM "Date conversion aborted!" / DEFB 0DH 44 61 74 65 20 63 6F 6E 76 65 72 73 69 6F 6E 20 61 62 6F 72 74 65 64 21 0D
540FH-5427H: the message of 5371H, for BREAK pressed during the conversion (52C4H), ended by 0DH at 5427H.
5428-545A
DEFM "SYSTEM disk conversion requires a 5.3 or 6.3 disk!" / DEFB 0DH 53 59 53 54 45 4D 20 64 69 73 6B 20 63 6F 6E 76 65 72 73 69 6F 6E 20 72 65 71 75 69 72 65 73 20 61 20 35 2E 33 20 6F 72 20 36 2E 33 20 64 69 73 6B 21 0D
5428H-545AH: the message of 5369H, for a system diskette whose system information sector does not start with 53H or 63H (526BH), ended by 0DH at 545AH.
545B-5471
DEFM "Write protected drive!" / DEFB 0DH 57 72 69 74 65 20 70 72 6F 74 65 63 74 65 64 20 64 72 69 76 65 21 0D
545BH-5471H: the message of 536DH, for a write protected diskette (522FH), ended by 0DH at 5471H.
5472-5473
DEFW 0000H 00 00
5472H-5473H: the number of files converted, 0000H when the program is loaded; 52BEH adds one for every record converted and 52E9H takes it for the message.
5474-54FF
DEFS 140
5474H-54FFH: not in the file and not used by DATECONV.
5500-55FF
DEFS 256
5500H-55FFH: not in the file. The buffer of every sector DATECONV reads and writes: the allocation table (523EH, 52DBH; its configuration byte at 55CDH), directory sector 5 and the system information sector (524EH-5264H), directory sector 3 (5272H, the ending record number of DIR/SYS at 5514H) and each sector of directory records (5286H).