DOSPLUS 3.5 for the Model I - SYS2/SYS Disassembled
Page Customization
Page Index
SYS2/SYS
Other Navigation
Introduction/Summary
DOSPLUS 3.5 SYS2/SYS Disassembly - OPEN@ and INIT@ (Model I)
SYS2/SYS is the low overlay that opens files: OPEN@ (request code 13H) and INIT@ (14H), with the routines they share and that other overlays request: the password code (15H, used by SYS14/SYS), the filling of a file control block from a directory entry (16H), the hash index code of a name (17H, used by SYS15/SYS), the address of the name buffer (18H, used by SYS15/SYS) and the drive of the last specification (19H). SYS0/SYS loads it at 4E00H over the low overlay before it.
The file is a load module of 5 blocks, 973 bytes, from 4E00H to 51CCH, with the transfer address 4E00H, and a 07H record. The fifth block (50FDH-5103H) is a patch over the fourth: it reorders the tests of the name character routine (50F0H) so that < and >, which are in its table, are taken in a name; before it, every character from 3AH to 40H ended the name. The page shows the patched bytes and gives the old instructions on the rows. The work area after the file, 51CDH-51EEH, is shown as DEFS rows (51CDH).
The Parts of SYS2/SYS
| Address | Contents |
|---|---|
| 4E00H-4E11H | The routine table (routines 2-9) and routine 2 (4E00H, 4E10H). |
| 4E12H-4F3FH | OPEN@: devices, the file search through the hash index table of each drive, the name compare and the password check (4E12H, 4EF2H). |
| 4F40H-4FC0H | INIT@: a free hash index entry, the new directory entry (4F40H). |
| 4FC1H-5068H | The file control block from the directory entry (4FC1H). |
| 5069H-511EH | The specification parser and the name character copier (5069H, 50F0H). |
| 511FH-519CH | The hash index code, upper case, routines 8 and 9, the free entry search, the password code (511FH, 513FH, 516EH). |
| 519DH-51CCH | Reading and writing the hash index table and reading the GAT (519DH). |
Opening a File
OPEN@ runs inside SYS0/SYS's file routine wrapper (4CDFH), which puts the file control block in Index Register IX and keeps the caller's registers. A specification that starts with @ names a device: its two character name is looked up in the DCB table (4369H), and the control block becomes 90H (open, with the FORCE flag) followed by the device's DCB address and filter table address, so character I/O on it goes to the device. For a file the name, extension, password and drive are taken apart (5069H); the name's hash index code (511FH) is looked for in the hash index table of the drive named, or of each ready drive from 0 to 7 in turn. The position of a matching byte in the table is the logical file number of the directory entry, whose name is then compared; extension entries are passed over.
The access a file is opened with depends on the password (4EF2H). Its code (516EH) is compared with CAA5H, a fixed code that opens any file with full access; then a file of protection level 7 is refused; then the code is compared with the diskette's master password code (GAT +CEH), with the entry's +10H code (the update password) and with its +12H code (the access password). The first three give access level 0, the access password gives the file's protection level, anything else error 19H. An empty password is eight spaces, whose code is 4296H.
INIT@ opens the file in the same way and, when it is not in the directory, creates it on the drive named or on the first drive that is ready and not write protected. The search for a free byte of the hash index table (513FH) starts at a place picked with the refresh register. The new entry is active with protection level 0, the logical record length, the name, and the code of the password given as both its update and its access password. The C FLAG returns set when the file was created.
The File Control Block
| Offset | Contents (from [4FC1H]) |
|---|---|
| +00H | 80H, an open file (90H for a device). |
| +01H | Bits 2-0 the access level, bit 5 set (the buffer is to be read), bit 7 set when the logical record length is not 256. |
| +02H | Bit 7 of the entry's +01H. |
| +03H-04H | The buffer. |
| +05H | The position in the buffer, 00H. |
| +06H | The drive. |
| +07H | The logical file number. |
| +08H | The end of file byte. |
| +09H | The logical record length. |
| +0AH-0BH | The next record number, 0000H. |
| +0CH-0DH | The ending record number: the sector count, less 1 when the end of file byte is not 00H. |
| +0EH-0FH | The first extent of the entry. |
| +10H-1FH | Four elements: the granules before the extent (2 bytes) and the extent (2 bytes); FFH when there are fewer extents. |
Differences from the Manual
The manual does not give the fixed password code CAA5H, which opens every file, including files of protection level 7. Its table of the directory entry does not say which of +10H and +12H is which password: +10H is the update password (full access) and +12H the access password (4F14H, 4F25H).
Variables
Memory Outside SYS2/SYS
| Address Size | Contents |
|---|---|
| 4200H-42FFH 256 bytes | System Sector Buffer The GAT (51BDH), the hash index table (519DH) and directory sectors. |
| 42CEH-42CFH 2 bytes | Master Password Code In the GAT (4E95H). |
| 4369H 66 bytes | DCB Table Device names at +09H (4E32H). |
| 43ABH 32 bytes | DCTTBL Drive names at +02H (50BBH). |
The Work Area (51CDH-51EEH)
| Address Size | Contents |
|---|---|
| 51CDH 1 byte | Drive 51CDH |
| 51CEH 1 byte | Access Level 51CEH |
| 51CFH 1 byte | Protection Level 51CFH |
| 51D0H 1 byte | Hash Index Code 51D0H |
| 51D1H 1 byte | Logical Record Length 51D1H |
| 51D2H-51D3H 2 bytes | Buffer 51D2H |
| 51D4H-51D5H 2 bytes | Master Password Code 51D4H |
| 51D6H-51DDH 8 bytes | Password 51D6H |
| 51DEH-51DFH 2 bytes | Drive or Device Name 51DEH |
| 51E0H-51EAH 11 bytes | Name and Extension 51E0H |
| 51EBH-51EEH 4 bytes | Password Codes 51EBH, 51EDH |
Tables
| Address Size | Contents |
|---|---|
| 4E00H-4E0FH 16 bytes | Routine Table 4E00H |
| 5118H-511EH 7 bytes | Name Characters 5118H |
Outside Routines
| Address | Contents |
|---|---|
| 4CDFH | SYS0/SYS: the file routine wrapper, entered after its open test (4E12H, 4F40H). |
| 4485H | SYS0/SYS: DISKIO%, functions 0 (DCHECK), 6 (SREAD) and 7 (SWRITE). |
| 448BH | SYS0/SYS: LOCDCT% (4F64H). |
| 490CH, 4915H | SYS0/SYS: read and write the directory sector of a logical file number. |
| 4943H | SYS0/SYS: 8 bit divide (514CH). |
Disassembly
4E00H - The Routine Table
Data: SYS2/SYS's table of routines 2-9, one word each, used by SYS0/SYS's overlay request handler (its 49C9H-49DCH) for the request codes 12H-19H. OPEN@ (4424H) requests 13H and INIT@ (4420H) 14H; SYS14/SYS requests 15H (its 553DH), SYS15/SYS 18H and 17H (its 56BDH, 56C0H).
4E10H - Routine 2
Nothing to do when SYS0/SYS's record locator brings SYS2/SYS back.
4E12H - OPEN@ - Open a File or a Device
Routine 3, requested by OPEN@ (4424H) with Register Pair DE pointing to a file control block that holds a file specification (as FSPEC@ leaves it), Register Pair HL to a 256 byte buffer and Register B the logical record length. A device specification (@ and a two character name) makes the control block point to the device's DCB. A file is looked for in the hash index table of the drive named, or of drives 0-7 in turn; when its name is found and a password gives access, the control block is filled from the directory entry. Register A returns 00H with the Z FLAG, or an error code with the NZ FLAG.
4EF2H - The Password Check
Sets the access level the file control block gets: 0 (everything) when the password code is CAA5H, the diskette's master password code (GAT +CEH) or the entry's +10H code; the file's protection level when it is the entry's +12H code. A file of protection level 7 opens only with CAA5H. Any other password gives error 19H.
4F40H - INIT@ - Open or Create a File
Routine 4, requested by INIT@ (4420H) with the same registers as OPEN@. The file is opened as by OPEN@; when it is not in the directory (error 18H) it is created on the drive named, or on the first of drives 0-7 that is ready and not write protected and has a free directory entry: the hash index code goes into a free byte of the hash index table, the entry gets the name, the logical record length and the password code as both passwords, and the file control block is filled. The C FLAG returns set when the file was created.
4FC1H - Fill the File Control Block
Routine 6, also the end of OPEN@ and INIT@. Index Register IX points to the file control block, Register Pair HL to the directory entry, Register B is the logical file number and Register C the drive; 51CEH holds the access level, 51D1H the logical record length and 51D2H the buffer. The block gets the open flags, the buffer, drive and logical file number, the end of file byte, the record length, the next record number 0, the ending record number and the extents of the entry: the first at +0EH-+0FH and up to four more as 4 byte elements (the granules before the extent, then the extent), with FFH in the rest.
5069H - Take the File Specification Apart
Called by OPEN@ (4E68H) with Register Pair DE pointing to the file control block that holds the specification. The name (up to 8 characters) goes to 51E0H, the extension after a slash (3) to 51E8H, the password after a period (8) to 51D6H, all padded with spaces; a drive name after a colon is looked up in DCTTBL (43ABH) and its number goes to 51CDH (FFH when no drive is given). Register A returns 00H with the Z FLAG, or 13H (no name) or 20H (no such drive) with the NZ FLAG.
50F0H - Copy Name Characters
Copies the characters at Register Pair HL that a name may hold (letters, made upper case, digits and the characters # $ % & + < >) to Register Pair DE, at most Register B of them. Register A returns the first other character, or the character after a full field, and Register Pair HL points past it. The fifth load block of the file (50FDH-5103H) is a patch: before it, 50FDH-5102H were CP 41H / RET C / CP 5BH / JR C,5111H, so the characters 3AH-40H ended the field and < and > in the table at 5118H were never taken.
511FH - The Hash Index Code
Routine 7, used by OPEN@ (4E6FH). Register A returns the code of the 11 characters of name and extension at Register Pair HL, the byte the hash index table holds for the file: each character is XORed into the code, which is then rotated left. A code of 00H, which marks a free entry, becomes 01H.
512DH - Upper Case
Makes a lower case letter in Register A upper case; any other character is returned as it is.
5136H - Routines 8 and 9
Routine 8 returns the address of the name buffer; routine 9 returns the drive found by the last specification.
513FH - Find a Free Entry of the Hash Index Table
Called by INIT@ (4F67H) with the hash index table at 4200H and Index Register IY pointing to the drive control table. The search starts at a place picked from the refresh register: one of the even entries 0, 2, 4 or 6 of a directory sector picked by the refresh register's value divided by the number of entry sectors. From there each entry of the sector is tried, then the next sector, to the last; then the search starts again at 00H. The Z FLAG returns set with Register Pair HL pointing to a free byte (00H); the NZ FLAG when there is none.
516EH - The Password Code
Routine 5, used by OPEN@ (4E78H). Register Pair HL returns the 16 bit code of the 8 characters at Register Pair DE (padded with spaces; letters are made upper case), taken from the last to the first, starting from FFFFH. Eight spaces give 4296H, the code DIR/SYS holds for a file without a password. Register Pair DE returns one byte before the first character.
519DH - Reading and Writing the Directory's First Sectors
519DH reads the hash index table (directory sector 1), 51ADH writes it, 51BDH reads the GAT (sector 0), each into or from 4200H, on drive Register C. The Z FLAG returns set when the transfer worked; otherwise Register A holds 16H, 17H or 14H with the NZ FLAG.
51CDH - The Work Area
Not in the file: the bytes after SYS2/SYS that OPEN@ and INIT@ use, up to 51EEH below the end of the low overlay area.