Tim Mann, author of XTRS and the OG Catweasel Utilties was kind enough to document how to go about determining the drive geometry of a hard drive based on the CONFIG/SYS file found on LS-DOS v6.

First, export the CONFIG/SYS file to your computer. You can do this with XTRS’s “EXPORT” utility or with Matthew Reed’s TRSTOOLS. If you are doing this inside an emulator, LS-DOS will likely not boot without the hard drive attached, so you need to press the virtual CLEAR key at just the right time during the LS-DOS boot process.

You then need to find the DCT in the CONFIG/SYS file. It gets loaded at 4300H instead of 0470H where the DCT$ is supposed to be, probably so as not to overwrite the DCT that’s actually in use based on boot disk.

Next you need to parse the CONFIG/SYS. Tim used the “cmddump” utility that comes with xtrs to parse it. It’s in /CMD (load module) format. Tim ran cmddump config.sys once with no flags, to see what the highest memory address used was — it was 0x434f. In Windows you can use George Phillips’ utility trld with a command line of trld -d config.sys.

Tim then used “cmddump config.sys config.mem 0 0x4350” to get a raw memory image of the part of memory that config/sys loads into (actually he used 0x434F, but that was a mistake since it cut off the last byte). For those using Windows, that will give you the hex dump. For those on Linux you need to use Linux’s “hd” to get a hex dump of that memory to work from.

Using a disk I gave Tim as an example, he found the DCT to read as follows (color added):

00004300   c3 f4 0f 0c 90 00 98 bf   bf 4c c3 f4 0f 0c 38 00   |.........L....8.|
00004310   98 7f 7f 4c c3 f4 0f 0c   38 99 99 7f 7f 4d c3 f4   |...L....8....M..|
00004320   0f 0c 10 99 98 bf bf 4c   c3 3d 0e 54 61 04 27 11   |.......L.=.Ta.'.|
00004330   45 14 c3 3d 0e 44 42 00   27 11 45 14 c3 3d 0e 44   |E..=.DB.'.E..=.D|
00004340   64 14 27 11 45 14 c3 3d   0e 44 68 28 4f 11 45      |d.'.E..=.Dh(O.E|

Decoding the first set (meaning Drive 0) by hand:

C3 : DCT+0: C3=Drive enabled / C9 = Drive disabled.

F4 0F : DCT+1,2: This is the address of the hard disk driver.

0C: DCT+3: 0C is 00001100 in decimal so:

Bits 0-1: 00 = Drive 0

Bit 2: 1 = Not removable

Bit 3: 1 = Hard Drive

Bit 4: 0 = Side Select 0

Bit 5: 0 = 5.25″ Drive

Bit 6: 0 = Single Density

Bit 7: 0 = Not Write Protected.

90: DCT+4: 90 is 10010000 in binary so:

Bits 0-3: 0000 = Starting Head # 0

Bit 4: 1 = “Controller does not return index pulses in its status register”

Bit 5: 0 = DBLBIT = 0, so one logical cylinder = one physical cylinder

Bit 6: 0 = “Controller is NOT capable of double density operation”

Bit 7: 1 = “No @CKDRV will be performed by @OPEN when accessing that drive”.

00: DCT+5: DCT+5 is not regularly used for Hard Drives.

98: DCT+6: 98H is 152 in decimal. Since Since DBLBIT=0, this means that the highest numbered logical cylinder on the drive is 152 in decimal (for total of 153 tracks).

BF: DCT+7. BFH is 10111111 in binary.

Bits 4-0: Highest numbered sector on a track numbered relative from zero. Bits 4-0 are 11111 (Decimal: 31) for 32 sectors per track.

Bits 7-5: Number of heads assigned to the logical partition. Bits 7-5 are 101 (Decimal: 5), so there are 6 heads for this logical partition.

BF: DCT+8. BFH is 10111111 in binary.

Bits 4-0: Sectors per granule. Bits 4-0 are 11111 (Decimal: 31) for 32 sectors per granule.

Bits 7-5: Granules per track. Bits 7-5 are 101 (Decimal: 5), so since DBLBIT=0, there are 6 granules per track.

4C: DCT+9. 4CH is 76 in decimal. Since DBLBIT=0, this means that the directory is on logical cylinder 76.

Decoding the entire DCT then gives us:

Drive :0
Hard drive, not removable, DBLBIT = 0, starting head number 0, drive unit address 0, starting logical cylinder 0, 153 logical cylinders, 6 heads, 32 sectors per track, 6 granules per physical cylinder, 32 sectors per granule, directory on logical cylinder 76.
Drive :1
Hard drive, not removable, DBLBIT = 1, starting head number 0, drive unit address 1, starting logical cylinder 0, 153 logical cylinders, 4 heads, 32 sectors per track, 4 granules per physical cylinder, 32 sectors per granule, directory on logical cylinder 76.
Drive :2
Hard drive, not removable, DBLBIT = 1, starting head number 0, drive unit address 1, starting logical cylinder 153, 154 logical cylinders, 4 heads, 32 sectors per track, 4 granules per physical cylinder, 32 sectors per granule, directory on logical cylinder 77.
Drive :3
Hard drive, not removable, DBLBIT = 0, starting head number 0, drive unit address 0, starting logical cylinder 153, 153 logical cylinders, 6 heads, 32 sectors per track, 6 granules per physical cylinder, 32 sectors per granule, directory on logical cylinder 76.
Drive :4
Floppy, 5″, physical address 1
Drive :5
Floppy, 5″, physical address 2
Drive :6
Floppy, 5″, physical address 4
Drive :7
Floppy, 5″, physical address 8
Note: DBLBIT = 1 means there are two physical cylinders per logical cylinder; DBLBIT = 0 means one physical per logical.


The below is more detailed information about the Drive Control Table record assigned to a hard drive partition taken from RSHARD – Hard Disk Driver Package and “The Programmer’s Guide to TRSDOS Version 6”.

DCT+3
This field contains a series of sub-field parameters associated with the disk drive specifications. The field is encoded as follows:
Bits 1-0
This subfield is used for different purposes depending on whether the drive associated with the DCT is a floppy drive or a hard drive.
  • Floppy: The field contains the step rate specification code (0-3) for the floppy disk controller. With a Western Digital 179X FDC or equivalent, the codes correspond to a step rate of 6, 12, 20, and 30ms at an FDC clock speed of 1 MHz and 3, 6, 10, and 15ms at an FDC clock speed of 2 MHz.
  • Hard Drive: This field is usually associated with the drive select code of the hard disk drive (binary value 0-3).
Bit 2
This subfield is used for different purposes depending on whether the drive associated with the DCT is a floppy drive or a hard drive.
  • Floppy: This bit is set by the system to indicate the minimum time delay required after selecting a floppy disk drive whose motors are not currently running. It must be used by floppy disk drivers to adjust their time delay between selection of the floppy drive and the first poll of the status register. A “1” value indicates the minimum delay to be 0.5 seconds while a “0” value indicates the delay to be 1.0 seconds. The time delay can be introduced via a request of the @PAUSE SuperVisor Call with an appropriate count..
  • Hard Drive: This bit is RESET if the drive is a REMOVABLE cartridge.
Bit 3
Is the logical drive a hard drive? If this bit is set to a “1”, it indicates that the DCT position is associated with a hard drive (Winchester). A “0” in this bit position indicates a floppy disk drive is associated with the DCT position. The bit is used by the system in informative messages by such things as DEVICE displays, DIRectory displays, and FREE displays. In addition, the system’s @CKDRV routine uses this bit to inhibit its automatic logging of a hard drive while it restricts its checking to write protect status only.
Bit 4
This bit is used to store the side selection number for a current access of a diskette. It is a storage area usable by the disk driver to place the side number calculated from the relative sector passed in the disk primitive request. The system passes a relative sector number based upon the number of sectors per cylinder. On a two-headed floppy disk drive, by dividing the relative sector number by the number of sectors per track, the result will be indicative of the side selection number, 0 or 1. The routine performing the calculation can then place the result in this bit of the DCT for the use of the drive selection routine. The bit value will match the side indicator bit in the sector header as written by the FDC. Hard disk drivers will use storage space internal to the driver to hold such a result.
Bit 5
If this bit is set to a “1”, the drive associated with the DCT position is an 8″ drive. This bit will be a “0” if the drive associated with the DCT position is a 5-1/4″ drive. This bit is initially set by whatever installs the disk driver (see the FLOPPY/DCT utility). In the installation of a hard disk driver, this bit should be set according to the size of the hard drive – 5″ or 8″. In the case of floppy drives, the system formatter will use this bit to adjust its formatting data to 5″ or 8″. It is also used to adjust informative messages as mentioned under bit-6.
Bit 6
This subfield is used for different purposes depending on whether the drive associated with the DCT is a floppy drive or a hard drive.
  • Floppy: If set to a “1”, it indicates that the floppy diskette currently being accessed is formatted in double density. If set to a “0” it indicates that the diskette is single density. The disk driver is responsible for maintaining this bit by recognizing the density of the disk it is accessing. The bit is used both by the driver in the drive selection process and by the system in informative messages by such things as DEVICE displays, DIRectory displays, and FREE displays.
  • Hard Drive: This bit is not referenced by the system.
Bit 7
Set to 1 will indicate the disk device is “software” write protected. It is the responsibility of the disk driver to check this bit on any disk primitive that references a WRITE operation (i.e. write sector, write system sector, format track, or format device) and return a “Write protected disk” error code (error 15) if set.
DCT+4
This byte contains additional drive specifications and parameters. The field is encoded as follows:
Bits 3-0
This subfield is used for different purposes depending on whether the drive associated with the DCT is a floppy drive or a hard drive.
  • Floppy: The field contains the physical drive address (1, 2, 4, or 8) corresponding to the drive select line (DS0, DS1, DS2, or DS3). Thus, only one of the four bits will ever be set.
  • Hard Drive: Hard drive installations that partition a drive by head, may use this field to indicate the relative starting head number of the logical drive partition. This provides support for a drive of up to 16 heads although 4 heads is typical. Bit 3 contains the drive address. Bits 2-0 contains the starting head number, counting from zero. Bits 1-0 contains the number of the starting cylinder for the logical partition, noting that if DBLBIT is set, this number represents half the actual value.
Bit 4
Short Version: This bit is set to indicate that the controller does not supply an index pulse indication to the disk driver on each rotation of the drive surface. Longer Version: This bit is used to indicate the controller associated with the DCT position is an “alien” controller. The term, “alien”, refers to a controller that does not return index pulses in its status register. The system uses index pulse transitions in a finite time period (usually 0.5 seconds) to detect the presence of a rotating diskette. If a disk drive does not contain a diskette, or does but the drive door is open, the status obtained on continuous selection of the drive will not indicate the presence of any index pulse transitions. By examining the state of the index pulse over a period of time corresponding to 2.5 possible rotations of a disk, the lack of an OFF-ON-OFF transition state will indicate that the drive is not available. If a controller does not return the state of an index pulse in the controller status byte, then the system will never be able to detect the availability of the drive if it maintains the state transition examination in the logging process. This bit should be set when such controllers are used to inhibit the @CKDRV routine from performing such an examination and proceed to the configuration logging.
Bit 5
This bit is used for different purposes depending on whether the drive associated with the DCT is a floppy drive or a hard drive.
  • Floppy: A “1” indicates that the diskette currently mounted in the drive is a two sided diskette while a “0” indicates that the diskette is a single-sided diskette. This bit is updated whenever the disk is logged by the system or whenever a program invokes the @CKDRV SuperVisor Call. Note that if a dual sided diskette is placed into a two-headed disk drive that previously accessed a single-sided diskette, the system will not recognize the second side of the new diskette until the logging process.
  • Hard Drive: Also known as the “DBLBIT” bit, this bit may be used to indicate that a logical cylinder represents two physical cylinders thereby providing support for twice as many cylinders as limited by the Granule Allocation Table (the GAT limits the number of logical cylinders to 203 – thus by using this bit, hard drives to 406 cylinders can be supported as a single logical drive). This bit will be SET if you requested more than 203 cylinders for a single logical drive.
Bit 6
This bit is used as a flag to the formatter. If set to a “1”, it indicates that the controller is capable of double density operation. In this case, the formatter defaults to double density formatting unless the user overrides the default. If set to a “0”, the formatter will default to single density formatting. For controllers capable of double density operation, this bit is usually set.
Bit 7
Effective with 6.2, this bit is used to inhibit @CKDRV . If set to a “1”, no @CKDRV will be performed by @OPEN when accessing that drive.
DCT+5
Also known as “CURCYL”, this field is used for different purposes depending on whether the drive associated with the DCT is a floppy drive or a hard drive. For floppies, the field is used by the disk driver to store the current cylinder position of the disk drive assigned to the DCT position. Since a Floppy Disk controller is used to access up to four different drives, when it accesses a drive, its track register must be loaded with correct information as to the current track position of the head. The current cylinder position is maintained by the disk driver in this storage field. The driver can then be use this field to reload the FDC track register prior to a seek operation and update the field to the cylinder requested in the seek. Hard disk controllers generally contain their own internal track register that is not accessible to a software driver. This means that hard disk drivers do not need to maintain the current cylinder position in this field. The field is thus available for the storage of other data items as required by the hard disk driver. Other data items may include the total quantity of heads on the physical drive (as needed by XEBEC controllers), the complex drive select code (as used by Lobo Drives UniVersal Controller), or data associated with drive partitioning by cylinder rather than by head.
  • Floppy: The field is used by the disk driver to store the current cylinder position of the disk drive assigned to the DCT position. Since a Floppy Disk controller is used to access up to four different drives, when it accesses a drive, its track register must be loaded with correct information as to the current track position of the head. The current cylinder position is maintained by the disk driver in this storage field. The driver can then be use this field to reload the FDC track register prior to a seek operation and update the field to the cylinder requested in the seek.
  • Hard Drive: Hard disk controllers generally contain their own internal track register that is not accessible to a software driver. This means that hard disk drivers do not need to maintain the current cylinder position in this field. The field is thus available for the storage of other data items as required by the hard disk driver. Other data items may include the total quantity of heads on the physical drive (as needed by XEBEC controllers), the complex drive select code (as used by Lobo Drives UniVersal Controller), or data associated with drive partitioning by cylinder rather than by head.
DCT+6
Also known as “MAXCYL,” this field contains the highest numbered logical cylinder on the drive referenced from a starting cylinder numbered “0”. Thus, a 35-cylinder drive would be entered as X’22’, a 40-cylinder drive as X’27’, and an 80-cylinder drive as X’4F’. A typical 153-cylinder ST506 compatible winchester drive would have an entry of X’98’. If a hard drive has more than 203 cylinders but less than 407 cylinders and is to be maintained as a single drive (or one partitioned by heads), then the system must access it as if each two physical cylinders were a single cylinder with twice as much capacity (although the system will still limit the logical cylinder to not exceed 256 sectors). In that case, the MAXCYL entry will be half of the actual quantity and bit-5 of the FLAG-2 field will be set. For example, an SA-1000 drive (8″ winchester) has 256 cylinders, four surfaces, and 32 sectors per track. If this drive is treated as a single volume (no partitioning), the MAXCYL entry is X’7F’ indicating the highest numbered cylinder is 127 (128 cylinders). The DBLBIT bit is set indicating a logical cylinder is composed of two physical cylinders. Another description is that this field contains the highest numbered logical cylinder on the partition. This number is relative – it references the actual number of cylinders assigned to the partition and is counted from zero. If the DBLBIT is set, the number of physical cylinders assigned is twice this number.
DCT+7
This is the first of a two-byte field containing information concerning the physical space parameters of the disk drive and how space is allocated per cylinder.
Bits 4-0
This subfield contains the highest numbered sector on a track numbered relative from zero. A ten-sector-per-track drive would show an X’09’ entry. A 32-sector-per-track hard drive would show an X’1F’.
Bits 7-5
This subfield contains the number of heads (surfaces) assigned to the logical partition of a hard disk drive. In the case of floppy disk drives, this entry should be a B’000′. For example, a four-head hard drive with a two-head partition would have a B’001′ in this subfield. The entry is zero relative, thus a one-head partition is B’000′, a two-head partition would be B’001′, and an eight-head partition would be B’111′.
DCT+8
This is the second of a two-byte field containing information concerning the physical space parameters of the disk drive and how space is allocated per cylinder.
Bits 4-0
This field contains the number of sectors per granule that is used in the configuration of the disk. In the case of floppy disk drives, this figure is standardized for 5-1/4″ and 8″ media. Hard disk drive granule sizes are assigned by the implementor of the hard disk drive system. The initialization program will always attempt to minimize this value. For example, 32 sectors per cylinder (SPC) drives use 4-sector granules (1K), 64 SPC drives use 2K granules, 96 SPC use 3K, 128 SPC use 4K, 256 SPC use 8K granules.
Bits 7-5
This subfield contains the number of granules per track allocated to the disk drive according to the number of sectors per granule. Since the field is 3-bits in length, the entry is offset from zero. Thus, one granule per track is entered as B’000′, two as B’001′, etc. In the case of floppy disk drives, this figure is standardized for 5-1/4″ and 8″ media. If the DCT is associated with a hard drive, then the figure entered here refers to the number of granules in a physical cylinder according to the number of surfaces. If the DBLBIT bit is set, this entry then represents half of the granules on a logical cylinder. The total granules per logical cylinder is computed by the doubling the value contained in this field if bit-5 of DCT FLAG-2 is set. Let’s illustrate this again using the SA-1000 drive. If we configure the drive as a single volume with 16 sectors per granule, a physical track has two granules per track. Since the drive has four surfaces, a physical cylinder has eight granules. However, since the DBLBIT bit must be set to indicate double the 128 cylinders shown in the MAXCYL field, the system would have to double the granules per cylinder computing 16 GPC. This is clearly in violation of the system’s upper limit of eight granules per cylinder maximum. Therefore, our example SA-1000 drive would be configured with 32 sectors per granule, one granule per track, four granules per physical cylinder. The DBLBIT bit would provide eight logical granules per logical cylinder. Therefore, this subfield would have an entry to indicate four granules. The initialization program will attempt to allocate all eight granules per logical drive. It does this by dividing the total number of sectors per logical cylinder by eight with the resulting value used as the number of sectors per granule.
DCT+9
Also known as “DIRCYL,” this field contains the logical cylinder number where the directory is located. If the DBLBIT is set, then this number is actually half the physical number. For any directory access, the system will use the contents of this field as a pointer to the cylinder containing the disk’s directory. The system attempts to maintain the integrity of this field by using the status returned when the driver reads a system sector in contrast to a non-system sector. If the system expects to be reading a directory sector but does not get the error code 6 (“Attempted to read system data sector”), it will read the BOOT sector and obtain the directory cylinder storage byte located therein for a second attempt to read the directory sector. After an unsuccessful second attempt (including whatever retries are performed per attempt by the driver), the system posts a read or write error depending on the original request. This error will eventually be classified as a GAT , HIT or DIRECTORY error if the attempt was an I/O request for the GAT, HIT or a directory entry sector respectively. Realizing that most hard disk controllers do NOT support a data address mark convention, the hard disk driver must simulate the READ SYSTEM SECTOR error code when an @RDSEC or @VRSEC request is made to the directory cylinder. Since the only indication of where the directory is located is contained in this field, it is paramount to the functioning of the hard disk environment that this field be correctly maintained. The system’s LOG command will always reload this field with the BOOT sector’s directory cylinder pointer. Thus, it may be necessary to highlight the function of LOG in any written information pertinent to the hard disk system user.
----------------------------------------------------------------------
| C3/C9 | VECTOR  | FLAG | FLAG | CUR | MAX | H  M  S  | G  S  | DIR |
|       | ADDRESS |   1  |  2   | CYL | CYL | D  A  E  | P  P  | CYL |
|       |         |      |      |     |     | S  X  C  | T  G  |     |
----------------------------------------------------------------------

Notice that most of the size or max numbers are “highest value”, so for example 5 in the “heads” field means there are 6 heads numbered 0-5.

Other information I have no idea what to do with …

ARCHIVE FILE SET HEADER RECORD
Each file segment of an archived file has a header record written as the first sector of the file segment. The information contained in the header is used to support fail-safe reconstruction of the original file. This section covers the information contained in the fields of the header record. Each like-named file in the file set will have a header record where the first forty bytes are identical. The numbers contained within angle brackets are sector offset values in hexadecimal.
DIRECTORY [00 – 15]
This 22 byte field contains the first twenty two bytes of the original file’s primary directory entry record. Any technical manual on the operation of the DOS will detail these bytes.
DATE [16 – 1D]
This field contains the date that the file set was created. The date is in standard ASCII string notation: MM/DD/YY.
TIME [1E – 25]
This field contains the time that the file set was created. The time is in standard ASCII string notation: HH:MM:SS.
RANDOM [26 – 27]
This field contains a 15 bit random number.
DISKNUM [28 – 29]
This field contains the 16-bit number of the d isk set for a given file segment. Each file that is archived begins its header with a disk number of zero. The value is stored in standard low-high order.
RECBGN [2A – 2B]
This field stores the relative sector number (relative to zero) of the first record contained in this file segment.
RECEND [2C – 2D]
This field stores the relative sector number (relative to zero) of the last record contained in this file segment.
SPARE [2E – 3F]
This 18-byte region is currently unused. It is always filled with zeroes.
LOCKED [40 – 7F]
This field is composed of 2-byte subfields. Each subfield contains a file segment record number that was detected as bad on the destination disk during the archival process and was thus locked from use. A value of zero indicates no record lock (the zeroth record is the header). These numbers are used during restoral to indicate if any source sectors should be skipped.
BADREC [80-FF]
This field is composed of 2-byte subfields. Each subfield contains a record number of the SOURCE file that was detected as unreadable during the archive process and that was written to this file segment as all spaces. This number may be useful to you if you neglected to write it down during the archival process.