BIOS Fixed-Disk Parameter Tables: INT 41h, INT 46h, and Legacy Geometry
Read legacy fixed-disk parameter vectors safely, distinguish XT and AT table layouts, and avoid confusing BIOS geometry with partitions or modern drives.
Classic PC BIOSes expose fixed-disk configuration through parameter tables referenced by interrupt vectors 41h and, on many AT-class systems, 46h. These vectors are data pointers used by firmware routines; they are not disk-read interrupts and they are not the partition table. The table format and even the meaning of a vector depend on the IBM machine generation and BIOS implementation. Modern DOS software should rarely need to parse them, but understanding the distinction helps when auditing a boot path or diagnosing software that assumes an old drive-type table.
This deep dive follows IBM’s PC/XT/AT and PS/2 BIOS interface reference. It does not claim that every compatible BIOS implements the same structure, and it does not recommend editing firmware tables while DOS or a disk driver is running.
The vectors have model-specific roles
On IBM PC/XT fixed-disk configurations documented by IBM, INT 41h points to the beginning of a table whose entries correspond to adapter switch settings. The switch selection is used as an index to pick a drive configuration. On AT, PC XT Model 286, and specified PS/2 products, INT 41h points to the single parameter table for drive 0 and INT 46h points to the single table for drive 1. IBM also documents an ESDI adapter case in which the BIOS gets drive configuration from the device and the table initialization function does no work.
That distinction makes generic “drive C is INT 41h” descriptions misleading. INT 41h is a low-memory vector address (the IVT entry lives at 0000:0104), and the pointer it contains leads to firmware data. It is not an API that takes a drive number in registers. A tool that wants to inspect a table must decode the vector and then parse bytes according to a matching machine family and BIOS revision.
Table shape is not universal
IBM’s PS/2 reference describes a table for certain PS/2 systems containing a length field, an ASCII drive-type string, a binary type number, maximum cylinder and head values, reserved fields, write-precompensation data, a control byte, landing zone, and sectors-per-track information. Older XT tables have a different structure with fields such as maximum cylinders, maximum heads, reduced write-current cylinder, precompensation cylinder, ECC burst length, control byte, and timeout values.
The table is not one invariant structure that can be decoded using an arbitrary C struct. The size and field meanings vary. Reserved bytes must remain reserved. Some values are expressed as zero-based maxima or encode flags, and a table’s declared length may bound later fields. A robust forensic reader uses a family-specific layout, checks the table length before accessing optional bytes, and reports unsupported formats instead of guessing.
These tables also predate modern disk discovery. A legacy BIOS geometry is an interface abstraction used by firmware, not necessarily the physical disk’s actual geometry. IDE translation, controller firmware, drive firmware, boot managers, and later BIOS extensions can alter the logical presentation. Do not derive an LBA or partition boundary from an old table without following the exact BIOS and partition specification.
Keep three different structures separate
The fixed-disk parameter table, the INT 13h register interface, and the MBR partition table serve different roles. The parameter table supplies BIOS drive characteristics. INT 13h services perform operations such as reading sectors or returning drive parameters. The partition table is on-disk metadata describing logical partitions. Editing a table pointer does not rewrite partition metadata, and changing an MBR partition entry does not update the BIOS drive-type table.
DOS drive letters add another layer. A DOS volume letter is assigned through DOS’s mounted-volume and device-driver environment. It is not a stable alias for a BIOS drive number, an INT 41h vector, or a partition entry. A diagnostic should label which layer produced each value and avoid conflating C: with a hard-coded BIOS ID.
Safe inspection and bounds
A read-only utility should begin by recording the IVT bytes for vectors 41h and 46h, the BIOS identity, and the machine or emulator. It should validate the pointer range, copy only the documented table size, and parse using the chosen family. If the environment cannot read low memory through its supported API, report the pointer as inaccessible rather than using an invalid segment pointer.
Pseudocode for a parser:
for vector in [0x41, 0x46]:
far_pointer = read_IVT_vector(vector)
if pointer_is_not_readable(far_pointer):
report vector, far_pointer, "unreadable"
continue
header = bounded_copy(far_pointer, family_header_size)
layout = identify_documented_layout(header, BIOS_family)
if layout is unknown or declared_length exceeds safe bound:
report raw bytes and "unknown layout"
continue
report decoded fields and their source vector
Do not call a table’s bytes a “BIOS answer” if your tool inferred the layout from a different adapter. Keep the original byte sequence in the report so another reviewer can verify the decoding independently. If the pointer appears to reference RAM, do not assume it is safe to modify; a writable address is still shared firmware state.
Why table patching can break storage
An old BIOS setup utility or drive controller may expect the table to match the configured drive type. Changing maximum cylinders, heads, or sectors can change how INT 13h translates requests. A mismatch can make valid sectors unreachable or cause an operating system to interpret the same disk through inconsistent geometries. It can also interfere with a disk overlay, option ROM, or boot manager that has installed its own translation layer.
If the goal is to recover files, editing a table is not a first-line repair. Work from a sector image and identify the actual partition/volume layout, BIOS translation, and any overlay in use. Do not run FORMAT, FDISK, CHKDSK, or a write-mode repair while testing an uncertain geometry. A seemingly successful read in the first cylinder says little about whether later partitions are being addressed correctly.
For a driver or firmware engineer, controlled modification should occur only through the documented setup or vendor API. Capture the old values, use a disposable image, change one setting, verify the full accessible sector range, and restore the previous configuration if any mismatch appears. A clean reboot may be required to reset cached BIOS state, but even rebooting does not make an unsupported change safe.
Diagnostic interpretation
If INT 41h and INT 46h appear identical, that may be a machine-specific implementation or a pointer to shared data; it is not sufficient proof of two identical drives. If one vector points into ROM and another into RAM, record that observation without assuming the RAM table is an editable override. If the BIOS’s INT 13h drive parameters disagree with the table, possible explanations include a translation layer, a different machine-specific structure, or a BIOS that does not use the table in the way expected.
Use the BIOS drive-parameter function and disk-image inspection as separate observations. Compare cylinder/head/sector limits, drive ID, partition metadata, and actual readable sectors in a read-only workflow. A cloned virtual machine can be used to reproduce a suspected mismatch, but it cannot prove every physical controller’s behavior.
Acceptance checks
Test the parser with a known IBM-compatible ROM image or emulator and synthetic malformed data: null vector, pointer near a segment boundary, shorter declared table, unsupported format, and reserved bytes containing nonzero values. Confirm the tool never writes to the vector target and never issues disk writes. Verify that a raw capture and its decoded output can be reproduced from the same bytes.
For a real recovery, image the disk before analysis, record BIOS and option-ROM versions, and compare the reported table against the exact machine reference. State explicitly whether a number came from the BIOS table, an INT 13h call, DOS, or an on-disk partition record. That labeling prevents historical drive geometry from being mistaken for a physical property or a filesystem fact.
The practical value of INT 41h and INT 46h is historical compatibility and forensic context. They are pointers into a BIOS-specific storage configuration model. Parse them only with a matching layout, keep them separate from INT 13h and partition data, and prefer read-only evidence over a speculative table edit.
Related:
- FreeDOS and BIOS INT 13h: CHS, LBA Extensions, and Safe Disk Access
- Recovering a FreeDOS Boot Disk with a Damaged MBR
Sources: