INT 13H


INT 13h is shorthand for BIOS interrupt call 13hex, the 20th interrupt vector in an x86-based computer system. The BIOS typically sets up a real mode interrupt handler at this vector that provides sector-based hard disk and floppy disk read and write services using cylinder-head-sector addressing. Modern PC BIOSes also include INT 13h extension functions, originated by IBM and Microsoft in 1992, that provide those same disk access services using 64-bit LBA addressing; with minor additions, these were quasi-standardized by Phoenix Technologies and others as the EDD BIOS extensions.
INT is an x86 instruction that triggers a software interrupt, and 13hex is the interrupt number being called.
Modern computers come with both BIOS INT 13h and UEFI functionality that provides the same services and more, with the exception of UEFI Class 3 that completely removes CSM thus lacks INT 13h and other interrupts. Typically, UEFI drivers use LBA-addressing instead of CHS-addressing.

Overview

Under real mode operating systems, such as DOS, calling INT 13h would jump into the computer's ROM-BIOS code for low-level disk services, which would carry out physical sector-based disk read or write operations for the program. In DOS, it serves as the low-level interface for the built-in block device drivers for hard disks and floppy disks. This allows INT 25h and INT 26h to provide absolute disk read/write functions for logical sectors to the FAT file system driver in the DOS kernel, which handles file-related requests through DOS API functions.
Under protected mode operating systems, such as Microsoft Windows NT derivatives and Linux with dosemu, the OS intercepts the call and passes it to the operating system's native disk I/O mechanism. Windows 9x and Windows for Workgroups 3.11 also bypass BIOS routines when using 32-bit Disk Access. Besides performing low-level disk access, INT 13h calls and related BIOS data structures also provide information about the types and capacities of disks attached to the system; when a protected-mode OS boots, it may use that information from the BIOS to enumerate disk hardware so that it can load and configure appropriate disk I/O drivers.
The original BIOS real-mode INT 13h interface supports drives of sizes up to about 8 GB using what is commonly referred to as physical CHS addressing. This limit originates from the hardware interface of the IBM PC/XT disk hardware. The BIOS used the cylinder-head-sector address given in the INT 13h call, and transferred it directly to the hardware interface. A lesser limit, about 504 MB, was imposed by the combination of CHS addressing limits used by the BIOS and those used by ATA hard disks, which are dissimilar. When the CHS addressing limits of both the BIOS and ATA are combined, the number of 512-byte sectors that can be addressed represent a total of about 504 MB.
The 504 MB limit was overcome using CHS translation, a technique by which the BIOS would simulate a fictitious CHS geometry at the INT 13h interface, while communicating with the ATA drive using its native logical CHS geometry. Translation allows the BIOS, still using CHS addressing, to effectively address ATA disks with sizes up to exactly 8064 MB, the native capacity of the BIOS CHS interface alone. CHS translation is sometimes referred to as logical CHS addressing, but that is actually a misnomer since by the time of this BIOS development, ATA CHS addresses were already logical, not physical. The 8064 MB limit originates from a combination of the register value based calling convention used in the INT 13h interface and the goal of maintaining backward compatibility—dictatng that the format or size of CHS addresses passed to INT 13h could not be changed to add more bits to one of the fields, e.g. the Cylinder-number field. This limit uses 1024 cylinders, 256 heads, 63 sectors, and 512 byte blocks, allowing exactly 7.875 GiB of addressing. There were briefly a number of BIOSes that offered incompatible versions of this interface—for example, AWARD AT BIOS and AMI 386sx BIOS have been extended to handle up to 4096 cylinders by placing bits 10 and 11 of the cylinder number into bits 6 and 7 of register DH—but eventually the computer industry standardized on the interface developed in the Microid Research in 1989.
All versions of MS-DOS, have a bug which prevents booting disk drives with 256 heads, so many modern BIOSes provide CHS translation mappings with at most 255 heads, thus reducing the total addressable space to exactly 8032.5 MiB.
To support addressing of even larger disks, an interface known as INT 13h Extensions was introduced by IBM and Microsoft, then later re-published and slightly extended by Phoenix Technologies as part of BIOS Enhanced Disk Drive Services. It defines new functions within the INT 13h service, all having function numbers greater than 40h, that use 64-bit logical block addressing, which allows addressing up to 8 ZiB.. This is a "packet" interface, because it uses a pointer to a packet of information rather than the register based calling convention of the original INT 13h interface. This packet is a very simple data structure that contains an interface version, data size, and LBAs. For software backward-compatibility, the extended functions are implemented alongside the original CHS functions, and calls to functions from both sets can be intermixed, even for the same drive, with the caveat that the CHS functions cannot reach past the first 8064 MB of the disk.
Some cache drivers flush their buffers when detecting that DOS is bypassed by directly issuing INT 13h from applications. A dummy read via INT 13h can be used as one of several methods to force cache flushing for unknown caches.
AMI BIOSes from around 1990–1991 trash word unaligned buffers.
Some DOS and TSR programs clobber interrupt enabling and registers so PC DOS and MS-DOS install their own filters to prevent this.

List of services

1st floppy disk
2nd floppy disk
3rd floppy disk
1st hard disk
2nd hard disk
3rd hard disk
...-
CD/DVD, or 97th hard disk
...-
128th hard disk

Reset Disk System
Get Status of Last Drive Operation
Read Sectors From Drive
Write Sectors To Drive
Verify Sectors
Format Track
Format Track Set Bad Sector Flags
Format Drive starting at Track
Read Drive Parameters
HDInitialize Disk Controller
HDRead Long Sectors From Drive
HDWrite Long Sectors To Drive
HDMove Drive Head To Cylinder
HDReset Disk Drives
PS/2Controller Read Test
PS/2Controller Write Test
HDTest Whether Drive Is Ready
HDRecalibrate Drive
PS/2Controller RAM Test
PS/2Drive Test
HDController Diagnostic
Read Drive Type
FDDetect Media Change
FDSet Media Type For Format
FDSet Media Type For Format
Park Heads
EXTTest Whether Extensions Are Available
EXTRead Sectors From Drive
EXTWrite Sectors To Drive
EXTVerify Sectors
EXTLock/Unlock Drive
EXTEject Drive
EXTMove Drive Head To Sector
EXTRead Drive Parameters
EXTDetect Media Change

If the second column is empty then the function may be used both for floppy and hard disk.
  • FD: for floppy disk only.
  • HD: for hard disk only.
  • PS/2: for hard disk on PS/2 system only.
  • EXT: part of the Extensions which were written in the 1990s to support hard drives with more than 8 GB.

    {{mono|INT 13h AH00h}}: Reset Disk System

AH00h
DLDrive

CFSet on error
AHReturn Code

{{mono|INT 13h AH01h}}: Get Status of Last Drive Operation

AH01h
DLDrive

Bit 7=0 for floppy drive, bit 7=1 for fixed drive
AH

{{mono|INT 13h AH02h}}: Read Sectors From Drive

AH02h
ALSectors To Read Count
CHCylinder
CLSector
DHHead
DLDrive
ES:BXBuffer Address Pointer

Remarks

Register CX contains both the cylinder number
and the sector number. Cylinder and Sector bits are numbered below:
CX = ---CH--- ---CL---
cylinder : 76543210 98
sector : 543210
Examples of translation:
CX := or or sector;
cylinder := or
sector := CX and 63;
Addressing of Buffer should guarantee that the complete buffer is inside the given segment,
i.e. <= 10000h.
Otherwise the interrupt may fail with some BIOS or hardware versions.

Example

Assume you want to read 16 sectors and your buffer starts
at memory address 4FF00h. Utilizing memory segmentation, there are different ways to calculate the register values, e.g.:
ES = segment = 4F00h
BX = offset = 0F00h
sum = memory address = 4FF00h
would be a good choice because 0F00h + 2000h = 2F00h <= 10000h
ES = segment = 4000h
BX = offset = FF00h
sum = memory address = 4FF00h
would not be a good choice because FF00h + 2000h = 11F00h > 10000h
Function 02h of interrupt 13h may only read sectors of the first 16,450,560 sectors
of your hard drive, to read sectors beyond the 8 GB limit you should use function 42h
of Extensions. Another alternate may be DOS interrupt 25h which reads sectors
within a partition.

{{mono|INT 13h AH03h}}: Write Sectors To Drive

AH03h
ALSectors To Write Count
CHTrack
CLSector
DHHead
DLDrive
ES:BXBuffer Address Pointer

CFSet On Error, Clear If No Error
AHReturn Code
ALActual Sectors Written Count

{{mono|INT 13h AH04h}}: Verify Sectors From Drive

AH04h
ALSectors To Verify Count
CHTrack
CLSector
DHHead
DLDrive
ES:BXBuffer Address Pointer

CFSet On Error, Clear If No Error
AHReturn Code
ALActual Sectors Verified Count

{{mono|INT 13h AH05h}}: Format Track

AH05h
ALSectors To Format Count
CHTrack
CLSector
DHHead
DLDrive
ES:BXBuffer Address Pointer

ByteMeaningAllowable Values
1Track
2Head
3Sector
4Bytes/Sector0=128, 1-256, 2-512, 3-1024

CFSet On Error, Clear If No Error
AHReturn Code

{{mono|INT 13h AH06h}}: Format Track Set Bad Sector Flags

AH06h
ALInterleave
CHTrack
CLSector
DHHead
DLDrive

CFSet On Error, Clear If No Error
AHReturn Code

{{mono|INT 13h AH07h}}: Format Drive Starting at Track

AH07h
ALInterleave
CHTrack
CLSector
DHHead
DLDrive

CFSet On Error, Clear If No Error
AHReturn Code

{{mono|INT 13h AH08h}}: Read Drive Parameters

Remarks

  • Logical values of function 08h may/should differ from physical CHS values of function 48h.
  • Result register CX contains both cylinders and sector/track values, see remark of function 02h.

    {{mono|INT 13h AH09h}}: Init Drive Pair Characteristics

AH09h
DLDrive

CFSet On Error, Clear If No Error
AHReturn Code

AH=0Ah: Read Long Sectors From Drive

The only difference between this function and function 02h is that function 0Ah reads 516 bytes per sector
instead of only 512. The last 4 bytes contains the Error Correction Code, a checksum of sector data.

{{mono|INT 13h AH41h}}: Check Extensions Present

RegistersDescription
AH41h = function number for extensions check
DLdrive index
BX55AAh

RegistersDescription
CFSet On Not Present, Clear If Present
AHError Code or Major Version Number
BXAA55h
CXInterface support bitmask:
  • 1 – Device Access using the packet structure
  • 2 – Drive Locking and Ejecting
  • 4 – Enhanced Disk Drive Support

{{mono|INT 13h AH42h}}: Extended Read Sectors From Drive

RegistersDescription-
AH42h = function number for extended read-
DLdrive index -
DS:SIsegment:offset pointer to the DAP, see below
RegistersDescription
CFSet On Error, Clear If No Error
AHReturn Code

As already stated with int 13h AH=02h, care must be taken to ensure that the complete buffer is inside the given segment, i.e. <= 10000h

{{mono|INT 13h AH43h}}: Extended Write Sectors to Drive

RegistersDescription
AH43h = function number for extended write
AL
  • bit 0 = 0: close write check,
  • bit 0 = 1: open write check,
  • bit 1-7:reserved, set to 0
DLdrive index
DS:SIsegment:offset pointer to the DAP
RegistersDescription
CFSet On Error, Clear If No Error
AHReturn Code

{{mono|INT 13h AH48h}}: Extended Read Drive Parameters

RegistersDescription-
AH48h = function number for extended_read_drive_parameters-
DLdrive index -
DS:SIsegment:offset pointer to Result Buffer, see below
RegistersDescription
CFSet On Error, Clear If No Error
AHReturn Code

Remark

Physical CHS values of function 48h may/should differ from logical values of function 08h.
OWIKI.org. Text is available under the Creative Commons Attribution-ShareAlike License.