@Interrupt Services DOSoBIOSoEMSoMouse
:int table:interrupt table:exceptions:IRQ
^Intel Defined CPU Exception Table (see notes)
% Interrupt Function
0 Divide by zero
1 Single step
2 Non-maskable (NMI)
3 Breakpoint
4 Overflow trap
5 BOUND range exceeded (186,286,386)
6 Invalid opcode (186,286,386)
7 Coprocessor not available (286,386)
8 Double fault exception (286,386)
9 Coprocessor segment overrun (286,386)
A Invalid task state segment (286,386)
B Segment not present (286,386)
C Stack exception (286,386)
D General protection exception (286,386)
E Page fault (286,386)
F Reserved
10 Coprocessor error (286,386)
^IBM PC Hardware Interrupt Table (in order of priority)
% IRQ# Interrupt Function
IRQ0 8 ~timer~ (55ms intervals, 18.2 per second)
IRQ1 9 keyboard service required
IRQ2 A slave ~8259~ or EGA/VGA vertical retrace
IRQ8 70 real time clock (AT,XT286,PS50+)
IRQ9 71 software redirected to IRQ2 (AT,XT286,PS50+)
IRQ10 72 reserved (AT,XT286,PS50+)
IRQ11 73 reserved (AT,XT286,PS50+)
IRQ12 74 mouse interrupt (PS50+)
IRQ13 75 numeric coprocessor error (AT,XT286,PS50+)
IRQ14 76 fixed disk controller (AT,XT286,PS50+)
IRQ15 77 reserved (AT,XT286,PS50+)
IRQ3 B COM2 or COM4 service required, (COM3-COM8 on MCA PS/2)
IRQ4 C COM1 or COM3 service required
IRQ5 D fixed disk or data request from LPT2
IRQ6 E floppy disk service required
IRQ7 F data request from LPT1 (unreliable on IBM mono)
^Interrupt Table as Implemented by System BIOS/DOS
% INT # Locus Function
0 CPU divide by zero
1 CPU single step
2 CPU non-maskable
3 CPU breakpoint
4 CPU overflow trap
5 BIOS print screen
6 CPU Invalid opcode (186,286,386)
7 CPU coprocessor not available (286,386)
8 IRQ0 ~timer~ (55ms intervals, 18.21590 per second)
9 IRQ1 keyboard service required (see ~INT 9~)
A IRQ2 slave ~8259~ or EGA/VGA vertical retrace
B IRQ3 COM2 service required (PS/2 MCA COM3-COM8)
C IRQ4 COM1 service required
D IRQ5 fixed disk or data request from LPT2
E IRQ6 floppy disk service required
F IRQ7 data request from LPT1 (unreliable on IBM mono)
10 BIOS video (see ~INT 10~)
11 BIOS Equipment determination (see ~INT 11~)
12 BIOS memory size (see ~INT 12~)
13 BIOS disk I/O service (see ~INT 13~)
14 BIOS serial communications (see ~INT 14~)
15 BIOS system services, cassette (see ~INT 15~)
16 BIOS keyboard services (see ~INT 16~)
17 BIOS parallel printer (see ~INT 17~)
18 BIOS ROM BASIC loader
19 BIOS bootstrap loader (unreliable, see ~INT 19~)
1A BIOS time of day (see ~INT 1A~)
1B BIOS user defined ctrl-break handler (see ~INT 1B~)
1C BIOS user defined clock tick handler (see ~INT 1C~)
1D BIOS ~6845~ video parameter pointer
1E BIOS diskette parameter pointer (base table)
1F BIOS graphics character table
20 DOS general program termination
21 DOS function request services (see ~INT 21~)
22 DOS terminate address (see ~INT 22~)
23 DOS control break termination address (see ~INT 23~)
24 DOS critical error handler (see ~INT 24~)
25 DOS absolute disk read (see ~INT 25~)
26 DOS absolute disk write (see ~INT 26~)
27 DOS terminate and stay resident (see ~INT 27~)
28 DOS idle loop, issued by DOS when idle (see ~INT 28~)
29 DOS fast TTY console I/O (see ~INT 29~)
2A DOS critical section and NETBIOS (see ~INT 2A~)
2B DOS internal, simple ~IRET~ in DOS 2.0-5.0
2C DOS internal, simple IRET in DOS 2.0-5.0
2D DOS internal, simple IRET in DOS 2.0-5.0
2E DOS exec command from base level command
interpreter (see ~INT 2E~)
2F DOS multiplexer (see ~INT 2F~)
30-31 CPM far jump vector for CPM (not an interrupt)
31 DPMI DOS Protected Mode Interface (for DOS extenders)
32 reserved
33 mouse support (see ~INT 33~)
34-3E Microsoft/Borland floating point emulation
3F overlay manager
40 BIOS hard disk
41 BIOS fixed disk 0 parameters pointer (see ~INT 13,9~)
42 BIOS relocated video handler (EGA/VGA/PS)
43 BIOS user font table (EGA/VGA/PS)
44 BIOS first 128 graphics characters (also Netware)
45 BIOS reserved for BIOS
46 BIOS fixed disk 1 parameters ptr (see ~INT 13,9~/INT 41)
47 BIOS reserved for BIOS
48 BIOS PCjr cordless keyboard translation
49 BIOS PCjr non-keyboard scancode translation table
4A BIOS user alarm (AT,CONV,PS/2) (see ~INT 4A~)
4B-4F BIOS reserved
50 BIOS periodic alarm from timer (PS/2)
51-58 BIOS reserved
59 BIOS GSS Computer Graphics Interface
5A BIOS cluster adapter BIOS entry point
5B BIOS cluster adapter boot
5C NETBIOS NETBIOS interface, TOPS interface
5D-5F BIOS reserved for BIOS
60-67 reserved for user software interrupts
67 EMS LIM/EMS specification (see ~INT 67~)
68 APPC
69-6B reserved by IBM
6C DOS DOS 3.2 real time clock update
BIOS system resume vector
6D-6F reserved
70 IRQ8 real time clock (AT,XT286,PS50+, see ~INT 15~)
71 IRQ9 software redirected to IRQ2 (AT,XT286,PS50+)
72 IRQ10 reserved (AT,XT286,PS50+)
73 IRQ11 reserved (AT,XT286,PS50+)
74 IRQ12 mouse interrupt (PS50+)
75 IRQ13 numeric coprocessor NMI error (AT,XT286,PS50+)
76 IRQ14 fixed disk controller (AT,XT286,PS50+)
77 IRQ15 reserved (AT,XT286,PS50+)
78-79 unused
80-85 ROM BASIC
86-F0 DOS reserved for BASIC interpreter use
86 NETBIOS NETBIOS relocated INT 18
E0 CPM CP/M 86 function calls
F1-FF reserved by IBM
FE-FF may be destroyed by return from protected
mode using VDISK on 286 machines (Apr 86, DDJ)
- Intel defined 0 through 20h for use for internal CPU; IBM
redefined interrupts 0 through 1Fh for its own use, hence
the duplicate definitions in the tables
- all interrupts except the internal CPU exceptions push the
flags and the CS:IP of the next instruction onto the stack.
CPU exception interrupts are similar but push the CS:IP of the
causal instruction. 8086/88 divide exceptions are different,
they return to the instruction following the division
- interrupts are disabled upon entry into any interrupt routine and
should be enabled by the user or by an ~IRET~
- in DOS 3.2+ hardware IRQ interrupts are re-vectored through DOS
to provide standard stack frames
:int 5
^INT 5 - Print Screen
no input data
% related memory:
50:00 = 00 Print screen has not been called, or upon return
from a call there were no errors
= 01 Print screen is already in progress
= FF Error encountered during printing
- invoked from ~INT 9~
:int 8:BIOS timer interrupt
^INT 8 - System timer
no input data
% related memory:
40:6C = Daily timer counter (4 bytes)
40:70 = 24 hr overflow flag (1 byte)
40:67 = Day counter on all products after AT
40:40 = Motor shutoff counter - decremented until 0 then
shuts off diskette motor
- ~INT 1C~ is invoked as a user interrupt
- the byte at 40:70 is a flag that certain DOS functions use
and adjust the date if necessary. Since this is a flag and
not a counter it results in DOS (not the ~RTC~) losing days
when several midnights pass before a DOS call
- generated 18.2 times per second by the ~8253~ Programmable Interval
Timer (PIT)
- normal INT 8 execution takes approximately 100 microseconds
- see ~8253~
:int 9:keyboard interrupt
^INT 9 - Keyboard Interrupt (Hardware Handler)
no input data
% related memory:
40:17 = updates keyboard flag byte 0
40:18 = updates keyboard flag byte 1
40:1A = queue head ptr is set to buffer start if Ctrl-Break is hit
40:1C = updates buffer tail pointer for each keystroke; sets
queue tail ptr is set to queue start if Ctrl-Break is hit
40:1E = updates keyboard buffer (32 bytes)
40:71 = updates bit 7 of the BIOS break flag if Ctrl-Break is hit
40:72 = updates reset flag with 1234H if Ctrl-Alt-Del pressed
40:96 = indicates keyboard type (AT,PS/2)
40:97 = updates keyboard LED flags (AT,PS/2)
FFFF:0 = reboot code called if Ctrl-Alt-Del pressed
% related interrupts:
~INT 5~ invoked if print screen key pressed
~INT 1B~ invoked if Ctrl-Break key sequence pressed
~INT 15,85~ invoked on AT if system request key is pressed
~INT 15,4F~ invoked on machines after PC/AT with AL = scan code
- records key press and key release via IRQ1/8259 and
stores scan codes in the BIOS buffer located at 40:1C
- keyboard controllers also buffer data when interrupts are
disabled at the ~8259~ interrupt controller
- keyboard controller is capable of storing 16 keystrokes
even when interrupts are disabled at the 8259
- normal INT 9 execution takes approximately 500 microseconds;
at least one standard XT BIOS is known to take up to 1.3
milliseconds to execute
- see ~MAKE CODES~ ~KB FLAGS~
:int 10:BIOS video services:video interrupt
^INT 10 - Video BIOS Services
% For more information, see the following topics:
~INT 10,0~ - Set video mode
~INT 10,1~ - Set cursor type
~INT 10,2~ - Set cursor position
~INT 10,3~ - Read cursor position
~INT 10,4~ - Read light pen
~INT 10,5~ - Select active display page
~INT 10,6~ - Scroll active page up
~INT 10,7~ - Scroll active page down
~INT 10,8~ - Read character and attribute at cursor
~INT 10,9~ - Write character and attribute at cursor
~INT 10,A~ - Write character at current cursor
~INT 10,B~ - Set color palette
~INT 10,C~ - Write graphics pixel at coordinate
~INT 10,D~ - Read graphics pixel at coordinate
~INT 10,E~ - Write text in teletype mode
~INT 10,F~ - Get current video state
~INT 10,10~ - Set/get palette registers (EGA/VGA)
~INT 10,11~ - Character generator routine (EGA/VGA)
~INT 10,12~ - Video subsystem configuration (EGA/VGA)
~INT 10,13~ - Write string (BIOS after 1/10/86)
~INT 10,14~ - Load LCD char font (convertible)
~INT 10,15~ - Return physical display parms (convertible)
~INT 10,1A~ - Video Display Combination (VGA)
~INT 10,1B~ - Video BIOS Functionality/State Information (MCGA/VGA)
~INT 10,1C~ - Save/Restore Video State (VGA only)
~INT 10,FE~ - Get DESQView/TopView Virtual Screen Regen Buffer
~INT 10,FF~ - Update DESQView/TopView Virtual Screen Regen Buffer
Warning: Some BIOS implementations have a bug that causes register
BP to be destroyed. It is advisable to save BP before a call to
Video BIOS routines on these systems.
- registers CS, DS, ES, SS, BX, CX, DX are preserved unless
explicitly changed
- see ~INT 1F~ ~INT 1D~ ~INT 29~ ~INT 21,2~ ~INT 21,6~ ~INT 21,9~
:int 10,0:video modes
^INT 10,0 - Set Video Mode
AH = 00
AL = 00 40x25 B/W text (CGA,EGA,MCGA,VGA)
= 01 40x25 16 color text (CGA,EGA,MCGA,VGA)
= 02 80x25 16 shades of gray text (CGA,EGA,MCGA,VGA)
= 03 80x25 16 color text (CGA,EGA,MCGA,VGA)
= 04 320x200 4 color graphics (CGA,EGA,MCGA,VGA)
= 05 320x200 4 color graphics (CGA,EGA,MCGA,VGA)
= 06 640x200 B/W graphics (CGA,EGA,MCGA,VGA)
= 07 80x25 Monochrome text (MDA,HERC,EGA,VGA)
= 08 160x200 16 color graphics (PCjr)
= 09 320x200 16 color graphics (PCjr)
= 0A 640x200 4 color graphics (PCjr)
= 0B Reserved (EGA BIOS function 11)
= 0C Reserved (EGA BIOS function 11)
= 0D 320x200 16 color graphics (EGA,VGA)
= 0E 640x200 16 color graphics (EGA,VGA)
= 0F 640x350 Monochrome graphics (EGA,VGA)
= 10 640x350 16 color graphics (EGA or VGA with 128K)
640x350 4 color graphics (64K EGA)
= 11 640x480 B/W graphics (MCGA,VGA)
= 12 640x480 16 color graphics (VGA)
= 13 320x200 256 color graphics (MCGA,VGA)
= 8x EGA, MCGA or VGA ignore bit 7, see below
= 9x EGA, MCGA or VGA ignore bit 7, see below
- if AL bit 7=1, prevents EGA,MCGA & VGA from clearing display
- function updates byte at 40:49; bit 7 of byte 40:87
(EGA/VGA Display Data Area) is set to the value of AL bit 7
:int 10,1
^INT 10,1 - Set Cursor Type
AH = 01
CH = cursor starting scan line (cursor top) (low order 5 bits)
CL = cursor ending scan line (cursor bottom) (low order 5 bits)
returns nothing
- cursor scan lines are zero based
- cursor size can also be set via the ~6845~ CRT controller
- cursor size can be determined using the CRTC, ~INT 10,3~ or the
~BIOS Data Area~ bytes 40:60 (ending scan line) and 40:61 (starting
scan line)
- the following is a list of the cursor scan lines associated with
most common adapters; screen sizes over 40 lines may differ
depending on adapters.
% Line Starting Ending Character
% Video Count Scan Line Scan Line Point Size
CGA 25 06 07 08
MDA 25 0B 0C 0E
EGA 25 06 07 0E
EGA 43 04/06 07 08
VGA 25 0D 0E 10
VGA 40 08 09 0A
VGA 50 06 07 08
- use CX = 2000h to disable cursor
:int 10,2
^INT 10,2 - Set Cursor Position
AH = 02
BH = page number (0 for graphics modes)
DH = row
DL = column
returns nothing
- positions relative to 0,0 origin
- 80x25 uses coordinates 0,0 to 24,79; 40x25 uses 0,0 to 24,39
- the ~6845~ can also be used to perform this function
- setting the data in the BIOS Data Area at location 40:50 does not
take immediate effect and is not recommended
- see ~VIDEO PAGES~ ~6845~ ~BDA~
:int 10,3
^INT 10,3 - Read Cursor Position and Size
AH = 03
BH = video page
on return:
CH = cursor starting scan line (low order 5 bits)
CL = cursor ending scan line (low order 5 bits)
DH = row
DL = column
- returns data from ~BIOS DATA AREA~ locations 40:50, 40:60 and 40:61
- the ~6845~ can also be used to read the cursor position
- the return data can be circumvented by direct port I/O to the 6845
CRT Controller since this function returns the data found in the
BIOS Data Area without actually checking the controller
:int 10,4
^INT 10,4 - Read Light Pen Position
AH = 04
on return:
AH = 0 light pen switch not triggered
= 1 light pen triggered
BX = pixel column (0-319 or 0-639, mode dependent)
CH = raster line (0-199) (CGA and EGA modes 4, 5 and 6)
CX = raster line (EGA modes except 4, 5 and 6)
DH = row (0-24)
DL = column (0-79 or 0-79 mode dependent)
- data returned as a byte coordinate, leaving horizontal
accuracy to within 2 pixels (320) or 4 pixels (640)
- vertical accuracy within 2 lines
- PS/2's don't support the light pen interface
:int 10,5
^INT 10,5 - Select Active Display Page
AH = 05
AL = new page number, see ~VIDEO PAGES~
for PCjr only:
AL = 80h to read CRT/CPU page registers
81h to set CPU page register
BL = CPU page register
82h to set CRT page register
BH = CRT page register
83h to set CPU and page registers
BH = CRT page register
BL = CPU page register
on return: (PCjr only)
BH = CRT page register
BL = CPU page register
:int 10,6
^INT 10,6 - Scroll Window Up
AH = 06
AL = number of lines to scroll, previous lines are
blanked, if 0 or AL > screen size, window is blanked
BH = attribute to be used on blank line
CH = row of upper left corner of scroll window
CL = column of upper left corner of scroll window
DH = row of lower right corner of scroll window
DL = column of lower right corner of scroll window
returns nothing
- in video mode 4 (300x200 4 color) on the EGA, MCGA and VGA
this function scrolls page 0 regardless of the current page
- can be used to scroll graphics screens, using character coords
- on CGA's this function disables video adapter, causing flitter
:int 10,7
^INT 10,7 - Scroll Window Down
AH = 07
AL = number of lines to scroll, previous lines are
blanked, if 0 or AL > screen size, window is blanked
BH = attribute to be used on blank line
CH = row of upper left corner of scroll window
CL = column of upper left corner of scroll window
DH = row of lower right corner of scroll window
DL = column of lower right corner of scroll window
returns nothing
- in video mode 4 (300x200 4 color) on the EGA, MCGA and VGA
this function scrolls page 0 regardless of the current page
- can be used to scroll graphics screens, using character coords
- on CGA's this function disables video adapter, causing flitter
:int 10,8
^INT 10,8 - Read Character and Attribute at Cursor Position
AH = 08
BH = display page
on return:
AH = attribute of character (alpha modes only)
AL = character at cursor position
- in video mode 4 (300x200 4 color) on the EGA, MCGA and VGA
this function works only on page zero
:int 10,9
^INT 10,9 - Write Character and Attribute at Cursor Position
AH = 09
AL = ASCII character to write
BH = display page (or mode 13h, background pixel value)
BL = character attribute (text) foreground color (graphics)
CX = count of characters to write (CX >= 1)
returns nothing
- does not move the cursor
- in graphics mode (except mode 13h), if BL bit 7=1 then
value of BL is XOR'ed with the background color
:int 10,a
^INT 10,A - Write Character Only at Current Cursor Position
AH = 0A
AL = ASCII character to write
BH = display page (or mode 13h, background pixel value)
BL = foreground color (graphics mode only)
CX = count of characters to write (CX >= 1)
return nothing
- similar to ~INT 10,9~ except color ignored in text modes
:int 10,b
^INT 10,B - Set Color Palette
AH = 0B
BH = palette color ID
= 0 to set background and border color
= 1 to select 4 color palette
BL = color value (when BH = 0)
= palette value (when BH = 1)
Palette Pixel Color
0 0 current background color
1 green (2)
2 red (4)
3 brown (6)
1 0 current background color
1 cyan (3)
2 magenta (5)
3 white (7)
- does not work for all EGA and VGA video modes
- sets border color in text mode (BH = 0)
:int 10,c
^INT 10,C - Write Graphics Pixel at Coordinate
AH = 0C
AL = color value (XOR'ED with current pixel if bit 7=1)
BH = page number, see ~VIDEO PAGES~
CX = column number (zero based)
DX = row number (zero based)
returns nothing
- if bit 7 is 1, color specified is XOR'ed with current pixel
- page number in BH ignored for 320x200 4 color graphics mode
- this function is known to destroy AX and possibly SI and DI on
on some PS/2 VGA systems
:int 10,d
^INT 10,D - Read Graphics Pixel at Coordinate
AH = 0D
BH = page number, see ~VIDEO PAGES~
CX = column number (zero based)
DX = row number (zero based)
on return:
AL = color of pixel read
- 64K IBM EGAs with BIOS dated 9/13/84 in 350 line video
modes, return invalid data in AL
- page number in BH ignored for 320x200 4 color graphics mode
:int 10,e
^INT 10,E - Write Text in Teletype Mode
AH = 0E
AL = ASCII character to write
BH = page number (text modes)
BL = foreground pixel color (graphics modes)
returns nothing
- cursor advances after write
- characters BEL (7), BS (8), LF (A), and CR (D) are
treated as control codes
- for some older BIOS (10/19/81), the BH register must point
to the currently displayed page
- on CGA adapters this function can disable the video signal while
performing the output which causes flitter.
:int 10,f
^INT 10,F - Get Video State
AH = 0F
on return:
AH = number of screen columns
AL = mode currently set (see ~VIDEO MODES~)
BH = current display page
- video modes greater than 13h on EGA, MCGA and VGA indicate
~INT 10,0~ was called with the high bit of the mode (AL) set
to 1, meaning the display does not need cleared
- function returns byte value at 40:49; On EGA, MCGA and
VGA bit 7 of register AL is determined by bit 7 of BIOS Data
Area byte 40:87. This bit is usually set by INT 10,0
with bit 7 of the requested mode (in AL) set to 1
:int 10,10
^INT 10,10 - Set/Get Palette Registers (EGA/VGA)
AH = 10h
% AL = 00 set individual palette register
BH = color value
BL = palette register
% AL = 01 set border color (overscan register)
BH = color value
% AL = 02 set all palette registers and border
ES:DX = pointer to 17 byte table representing 16 palette
registers and border color register
% AL = 03 toggle intensity/blinking (EGA)
BL = 0 enable intensity
1 enable blinking
% AL = 07 read palette register (PS/2)
BL = palette register to read (0-15)
on return:
BH = value of palette register
% AL = 08 read border color (overscan register, PS/2)
on return:
BH = value of border color (overscan register)
% AL = 09 read palette registers and border (PS/2)
ES:DX = pointer to 17 byte table representing 16 palette
registers and border color register
on return:
ES:DX = pointer to table provided as input
% AL = 10 set DAC color register
BX = color register to set
CH = green value
CL = blue value
DH = red value
% AL = 12 set block of DAC color registers
BX = first color register to set
CX = number of color registers to set
ES:DX = pointer to table of color values to set
% AL = 13 set attribute controller color select state
BL = 0 set Mode Control register bit 7
BH = value for bit 7
BL = 1 set color select register
BH = value for color select register
% AL = 15 read DAC color register (PS/2)
BX = color register to read
on return:
CH = green value
CL = blue value
DH = red value
% AL = 17 read block of DAC color registers
BX = first color register to read
CX = number of color registers to read
ES:DX = pointer to buffer for color registers
on return:
ES:DX = pointer to color table provided as input
% AL = 18 update video DAC mask register
BL = new mask
% AL = 19 read video DAC mask register
on return:
BL = value read from video DAC mask register
% AL = 1A read color page state
BL = bit 7 of Mode Control Register
BH = bits 2 thru 3 of Color select register if BL = 0
= bits 0 thru 3 of Color select register if BL = 1
on return:
BL = current paging mode
CX = current page
% AL = 1B sum color values to shades of gray
BX = first color register to sum
CX = number of color registers to sum
- controls the pixel color mapping bit values
- BIOS extension to EGA/VGA systems
:int 10,11
^INT 10,11 - Character Generator Routine (EGA/VGA)
AH = 11h
% AL = 00 user character load
BH = number of bytes per character
BL = table in character generator RAM
CX = count of characters in table
DX = ASCII code of first character defined
ES:BP = pointer to user table
% AL = 01 ROM BIOS 8x14 monochrome set
BL = table in character generator RAM
% AL = 02 ROM BIOS 8x8 double dot
BL = table in character generator RAM
% AL = 03 set displayed definition table
BL = value for character Map Select register (EGA,VGA)
= character generator RAM table numbers (MCGA)
% AL = 04 ROM BIOS 8x16 character set
BL = table in character generator RAM
% AL = 10 user specified character definition table
BH = bytes per character (points)
BL = table in character generator RAM
CX = number of characters defined in table
DX = ASCII code of first character defined
ES:BP = pointer to user table
% AL = 11 ROM BIOS 8x14 monochrome character set
BL = table in character generator RAM
% AL = 12 ROM 8x8 double dot character definitions
BL = table in character generator RAM
% AL = 14 ROM 8x16 double dot character definitions
BL = table in character generator RAM
% AL = 20 pointer to graphics character table for ~INT 1F~ (8x8)
ES:BP = pointer to user table
% AL = 21 user graphics character pointer at INT 43
BL = row specifier
= 0 - user specified (DL = rows)
= 1 is 14 rows
= 2 is 25 rows
= 3 is 43 rows
CX = bytes per character (points)
DL = rows (when BL = 0)
ES:BP = pointer to user table
% AL = 22 ROM 8x14 character set
BL = number of rows (see AL=21)
DL = rows (when BL = 0)
% AL = 23 ROM 8x8 double dot character set
BL = row specifier (see AL=21)
DL = rows (when BL = 0)
% AL = 24 ROM 8x16 character set
BL = row specifier (see AL=21)
DL = rows (when BL = 0)
% AL = 30 get current character generator information
BH = information desired:
= 0 ~INT 1F~ pointer
= 1 INT 44h pointer
= 2 ROM 8x14 pointer
= 3 ROM 8x8 double dot pointer (base)
= 4 ROM 8x8 double dot pointer (top)
= 5 ROM 9x14 alpha alternate pointer
= 6 ROM 8x16 character table pointer
= 7 ROM 9x16 alternate character table pointer
on return:
CX = bytes per character (points)
DL = rows (less 1)
ES:BP = pointer to table
:int 10,12
^INT 10,12 - Video Subsystem Configuration (EGA/VGA)
AH = 12h
% BL = 10 return video configuration information
on return:
BH = 0 if color mode in effect
= 1 if mono mode in effect
BL = 0 if 64k EGA memory
= 1 if 128k EGA memory
= 2 if 192k EGA memory
= 3 if 256k EGA memory
CH = feature bits
CL = switch settings
% BL = 20 select alternate print screen routine
% BL = 30 select scan lines for alphanumeric modes
AL = 0 200 scan lines
= 1 350 scan lines
= 2 400 scan lines
on return:
AL = 12
% BL = 31 select default palette loading
AL = 0 enable default palette loading
= 1 disable default palette loading
on return:
AL = 12
% BL = 32 CPU access to video RAM
AL = 0 enable CPU access to video RAM and I/O ports
= 1 disable CPU access to video RAM and I/O ports
on return:
AL = 12
% BL = 33 Gray scale summing
AL = 0 enable gray scale summing
= 2 disable gray scale summing
on return:
AL = 12
% BL = 34 cursor emulation
AL = 0 enable cursor emulation
= 1 disable cursor emulation
on return:
AL = 12
% BL = 35 PS/2 video display switching
AL = 0 initial adapter video off
= 1 initial planar video on
= 2 switch active video off
= 3 switch inactive video on
ES:DX pointer to 128 byte save area (when AL = 0, 2 or 3)
on return:
AL = 12
% BL = 36 video refresh control
AL = 0 enable refresh
= 1 disable refresh
on return:
AL = 12
:int 10,13
^INT 10,13 - Write String (BIOS versions from 1/10/86)
AH = 13h
AL = write mode (see bit settings below)
= 0 string is chars only, attribute in BL, cursor not moved
= 1 string is chard only, attribute in BL, cursor moved
= 2 string contains chars and attributes, cursor not moved
= 3 string contains chars and attributes, cursor moved
BH = video page number
BL = attribute if mode 0 or 1 (AL bit 1=0)
CX = length of string (ignoring attributes)
DH = row coordinate
DL = column coordinate
ES:BP = pointer to string
Bit settings for write mode (register AL):
|7|6|5|4|3|2|1|0| AL
| | | | | | | ----- 0=don't move cursor, 1=move cursor
| | | | | | ------ 0=BL has attributes, 1=string has attributes
----------------- unused
returns nothing
- BEL, BS, CR, LF are treated as ASCII control codes
- wraps data and scrolls if unable to fit data on one line
:int 10,14
^INT 10,14 - Load LCD Character Font (convertible only)
AH = 14h
% AL = 0 - load user specified font
ES:DI = pointer to character font
CX = number of characters to store
DX = char offset into ram font area
BH = number of bytes per character
BL = 0 load main font (block 0)
= 1 load alternate font (block 1)
% AL = 1 - load system ROM default font
BL = 0 load main font (block 0)
= 1 load alternate font (block 1)
% AL = 2 - set mapping of LCD high intensity attribute
BL = 0 ignore high intensity attribute
= 1 map high intensity to underscore
= 2 map high intensity to reverse video
= 3 map high intensity to select alternate font
:int 10,15
^INT 10,15 - Return Physical Display Parms (convertible)
AH = 15h
on return:
AX = alternate display adapter type
ES:DI = pointer to parameter table:
% Offset Size Description
01 word monitor model number
02 word vertical pels per meter
03 word horizontal pels per meter
04 word total number of vertical pels
05 word total number of horizontal pels
06 word horizontal pel separation in micrometers
07 word vertical pel separation in micrometers
:int 10,1a
^INT 10,1A - Video Display Combination (VGA)
AH = 1A
AL = 00 get video display combination
= 01 set video display combination
BL = active display (see table below)
BH = inactive display
on return:
AL = 1A, if a valid function was requested in AH
BL = active display (AL=00, see table below)
BH = inactive display (AL=00)
% Valid display codes:
FF Unrecognized video system
00 No display
01 MDA with monochrome display
02 CGA with color display
03 Reserved
04 EGA with color display
05 EGA with monochrome display
06 Professional graphics controller
07 VGA with analog monochrome display
08 VGA with analog color display
09 Reserved
0A MCGA with digital color display
0B MCGA with analog monochrome display
0C MCGA with analog color display
- returns value at byte 40:8A indicating display combination status
- used to detect video display capabilities
:int 10,1b
^INT 10,1B - Video BIOS Functionality and
^State Information (MCGA/VGA)
AH = 1B
BX = implementation type (must be zero)
ES:DI = pointer to 64 byte buffer
on return:
AL = 1B
ES:DI = pointer to updated buffer (see below)
- returns static and dynamic information about the current
state and capabilities of the current video system
- bytes 0-3 of the dynamic data table at ES:DI contain a far
pointer to the video static information table
^Video BIOS Dynamic Functionality State Table (MCGA/VGA)
% Dynamic Video State Table
00 dword address of static functionality table
04 byte video mode
05 word number of columns
07 word length of displayed video buffer (# bytes)
09 word start address of upper left corner of video buffer
0B 16bytes cursor position table for 8 pages (col,row)
1B byte cursor end line
1C byte cursor start line
1D byte active video page
1E word I/O port for CRTC address register
20 byte current value of CRTC 3x8 register
21 byte current value of CRTC 3x9 register
22 byte number of displayed character rows
23 word height of character matrix (points)
25 byte active display combination code
26 byte inactive display combination code
27 word number of displayed colors (mono = 0)
29 byte number of supported video pages
2A byte raster scan lines 0=200, 1=350, 2=400, 3=480
2B byte text character table used
2C byte text character table used
2D byte other state information:
|7|6|5|4|3|2|1|0| State Information byte at offset 2D
| | | | | | | ---- 1 = all modes active (MCGA always 0)
| | | | | | ----- 1 = gray scale summing enabled
| | | | | ------ 1 = monochrome display attached
| | | | ------- 1 = default palette loading disabled
| | | -------- 1 = cursor emulation enabled
| | --------- 1 = blinking attribute enabled
------------ 1 = reserved
2E 3bytes reserved
31 byte video RAM available 0=64K, 1=128K, 2=192K, 3=256K
32 byte save area status
|7|6|5|4|3|2|1|0| Save Area Status
| | | | | | | ---- 1 = two text char sets are active
| | | | | | ----- 1 = dynamic save area is active
| | | | | ------ 1 = text char set override is active
| | | | ------- 1 = graphics char set is override active
| | | -------- 1 = palette override is active
| | --------- 1 = display combination code ext. active
------------ 1 = reserved
33 dword reserved
^Video BIOS Static Functionality Table (EGA/VGA)
|7|6|5|4|3|2|1|0| Video modes supported, byte at offset 00
| | | | | | | ---- 1 = mode 0
| | | | | | ----- 1 = mode 1
| | | | | ------ 1 = mode 2
| | | | ------- 1 = mode 3
| | | -------- 1 = mode 4
| | --------- 1 = mode 5
| ---------- 1 = mode 6
----------- 1 = mode 7
|7|6|5|4|3|2|1|0| Video modes supported, byte at offset 01
| | | | | | | ---- 1 = mode 8
| | | | | | ----- 1 = mode 9
| | | | | ------ 1 = mode A
| | | | ------- 1 = mode B
| | | -------- 1 = mode C
| | --------- 1 = mode D
| ---------- 1 = mode E
----------- 1 = mode F
|7|6|5|4|3|2|1|0| Video modes supported, byte at offset 02
| | | | | | | ---- 1 = mode 10
| | | | | | ----- 1 = mode 11
| | | | | ------ 1 = mode 12
| | | | ------- 1 = mode 13
-------------- reserved
03 dword reserved
07 byte scan lines supported in text modes
|7|6|5|4|3|2|1|0| Scan lines supported, byte at offset 07
| | | | | | | ---- 1 = 200 lines
| | | | | | ----- 1 = 350 lines
---------------- 1 = 400 lines
08 byte max number of displayable text character sets
09 byte # of text definition tables in char generator RAM
0A byte other capability flags
|7|6|5|4|3|2|1|0| Other flags, byte at offset 0A
| | | | | | | ---- 1 = all modes (0 on MCGA)
| | | | | | ----- 1 = gray scale summing
| | | | | ------ 1 = character set loading
| | | | ------- 1 = default palette loading
| | | -------- 1 = cursor emulation
| | --------- 1 = 64 color palette
| ---------- 1 = video DAC loading
----------- 1 = DAC controlled by ACCS
0B byte other capability flags
|7|6|5|4|3|2|1|0| Other flags, byte at offset 0B
| | | | | | | ---- 1 = light pen support
| | | | | | ----- 1 = save/restore video state
| | | | | ------ 1 = blinking/background intensity
| | | | ------- 1 = display combination code
-------------- reserved
0C word reserved
0E byte save area capabilities
|7|6|5|4|3|2|1|0| save area capabilities at offset 0E
| | | | | | | ----- 1 = multiple text character sets
| | | | | | ------ 1 = dynamic save area
| | | | | ------- 1 = text character set override
| | | | -------- 1 = graphics character set override
| | | --------- 1 = palette override
| | ---------- 1 = display combination code extension
------------- reserved
0F byte reserved
:int 10,1c
^INT 10,1C - Save/Restore Video State (VGA only)
AH = 1C
% AL = 0 get save buffer size
CX = requested states
bit 0: video hardware state
bit 1: video BIOS data areas
bit 2: video DAC state
on return:
AL = 1C
BX = buffer size in 64 byte blocks
% AL = 1 save requested state
CX = requested states (see AL = 0)
ES:BX = pointer to buffer
returns nothing
% AL = 2 restore requested states
CX = requested states (see AL = 0)
ES:BX = pointer to buffer
returns nothing
:int 10,fe
^INT 10,FE - Get DESQView/TopView Virtual Screen Regen Buffer
AH = FE
ES:DI = set to sentinel value (test for INT 10,FE supported)
returns:
ES:DI = address of DESQView/TopView video buffer, DI will always
be zero
- on return ES:DI should be tested against the original value;
the value will change if this function is supported (DESQView
or TopView loaded), otherwise it will remain unchanged
- if ES:DI changes this address can be used as the video screen
regen buffer
:int 10,ff
^INT 10,FF - Update DESQView/TopView Virtual Screen Regen Buffer
AH = FF
CX = number of characters changed
ES:DI = pointer to first character in buffer to change, ES is
set to segment returned by ~INT 10,FE~
returns nothing
- the physical screen does not get updated until INT 10,FF is
called in TopView
- it is not necessary to make this call under DESQView since it
handles updates automatically
- calling this function under DESQView will cancel the automatic
update mode
:int 11:equipment flags
^INT 11 - BIOS Equipment Determination / BIOS Equipment Flags
no input data
on return:
AX contains the following bit flags:
|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0| AX
| | | | | | | | | | | | | | | ----- IPL diskette installed
| | | | | | | | | | | | | | ------ math coprocessor
| | | | | | | | | | | | --------- old PC system board RAM < 256K
| | | | | | | | | | | | | ------ pointing device installed (PS/2)
| | | | | | | | | | | | ------- not used on PS/2
| | | | | | | | | | ---------- initial video mode
| | | | | | | | ------------- # of diskette drives, less 1
| | | | | | | -------------- 0 if DMA installed
| | | | ------------------- number of serial ports
| | | -------------------- game adapter installed
| | --------------------- unused, internal modem (PS/2)
------------------------ number of printer ports
- bits 3 & 2, system board RAM if less than 256K motherboard
00 - 16K 01 - 32K
10 - 16K 11 - 64K (normal)
- bits 5 & 4, initial video mode
00 - unused 01 - 40x25 color
10 - 80x25 color 11 - 80x25 monochrome
- bits 7 & 6, number of disk drives attached, when bit 0=1
00 - 1 drive 01 - 2 drives
10 - 3 drive 11 - 4 drives
- returns data stored at ~BIOS Data Area~ location 40:10
- some flags are not guaranteed to be correct on all machines
- bit 13 is used on the PCjr to indicate serial printer
:int 12
^INT 12 - Memory Size Determination
no input data
on return:
AX = the number of contiguous 1k memory blocks found at startup
- contiguous memory does not include video memory or extended RAM
:int 13:BIOS disk services
^INT 13 - Diskette BIOS Services
^For more information see the following topics:
~INT 13,0~ Reset disk system
~INT 13,1~ Get disk status
~INT 13,2~ Read disk sectors
~INT 13,3~ Write disk sectors
~INT 13,4~ Verify disk sectors
~INT 13,5~ Format disk track
~INT 13,6~ Format track and set bad sector flag (XT & portable)
~INT 13,7~ Format the drive starting at track (XT & portable)
~INT 13,8~ Get current drive parameters (XT & newer, see note +)
~INT 13,9~ Initialize 2 fixed disk base tables (XT & newer, see note +)
~INT 13,A~ Read long sector (XT & newer, see note +)
~INT 13,B~ Write long sector (XT & newer, see note +)
~INT 13,C~ Seek to cylinder (XT & newer, see note +)
~INT 13,D~ Alternate disk reset (XT & newer, see note +)
~INT 13,E~ Read sector buffer (XT & portable only)
~INT 13,F~ Write sector buffer (XT & portable only)
~INT 13,10~ Test for drive ready (XT & newer, see note +)
~INT 13,11~ Recalibrate drive (XT & newer, see note +)
~INT 13,12~ Controller ram diagnostic (XT & portable only)
~INT 13,13~ Drive diagnostic (XT & portable only)
~INT 13,14~ Controller internal diagnostic (XT & newer, see note +)
~INT 13,15~ Read disk type/DASD type (XT BIOS from 1/10/86 & newer)
~INT 13,16~ Disk change line status (XT BIOS from 1/10/86 & newer)
~INT 13,17~ Set dasd type for format (XT BIOS from 1/10/86 & newer)
~INT 13,18~ Set media type for format (BIOS date specific)
~INT 13,19~ Park fixed disk heads (AT & newer)
~INT 13,1A~ Format ESDI drive unit (PS/2 50+)
+ The 1983 version of the "IBM XT BIOS Technical Reference"
shows these functions are available for the XT but many other
programming references say they aren't available until the AT.
This is probably due to misunderstanding the design of the disk
BIOS. Upon bootup the hard disk BIOS replaces the default
INT 13h diskette handler with the hard disk INT 13h handler.
% Most disk BIOS calls use the following parameter scheme:
AH = function request number
AL = number of sectors (1-128 dec.)
CH = cylinder number (0-1023 dec.)
CL = sector number (1-17 dec.)
DH = head number (0-15 dec.)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
DL = drive number (0=A:, 1=2nd floppy, 80h=C:, 81h=D:)
Note that some programming references use (0-3) as the
drive number which represents diskettes only.
ES:BX = address of user buffer
% and return with:
CF = 0 if successful
= 1 if error
AH = status of operation (see INT 13,STATUS)
- INT 13 diskette read functions should be retried at least 3
times to assure the disk motor has time to spin up to speed
- physical sector numbers can be converted to and from DOS sector
numbers with the following formulas:
dos_sector = (sector - 1) + (head * sectors_per_track) +
(track * sectors_per_track * num_heads)
physical_sector = 1 + (dos_sector MOD sectors_per_track)
physical_head = (dos_sector / sectors_per_track) MOD num_heads
physical_track = dos_sector / (sectors_per_track * num_heads)
- registers DS, BX, CX and DX are preserved
- see ~INT 13,STATUS~
:int 13,0
^INT 13,0 - Reset Disk System
AH = 00
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
AH = disk operation status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- clears reset flag in controller and pulls heads to track 0
- setting the controller reset flag causes the disk to recalibrate
on the next disk operation
- if bit 7 is set, the diskette drive indicated by the lower 7 bits
will reset then the hard disk will follow; return code in AH is
for the drive requested
:int 13,1:int 13,status
^INT 13,1 - Disk Status
AH = 01
on return:
AL = status:
% Status in AL
00 no error
01 bad command passed to driver
02 address mark not found or bad sector
03 diskette write protect error
04 sector not found
05 fixed disk reset failed
06 diskette changed or removed
07 bad fixed disk parameter table
08 DMA overrun
09 DMA access across 64k boundary
0A bad fixed disk sector flag
0B bad fixed disk cylinder
0C unsupported track/invalid media
0D invalid number of sectors on fixed disk format
0E fixed disk controlled data address mark detected
0F fixed disk DMA arbitration level out of range
10 ECC/CRC error on disk read
11 recoverable fixed disk data error, data fixed by ECC
20 controller error (NEC for floppies)
40 seek failure
80 time out, drive not ready
AA fixed disk drive not ready
BB fixed disk undefined error
CC fixed disk write fault on selected drive
E0 fixed disk status error/Error reg = 0
FF sense operation failed
- codes represent controller status after last disk operation
- returns the status byte located at 40:41 in the ~BIOS Data Area~
:int 13,2
^INT 13,2 - Read Disk Sectors
AH = 02
AL = number of sectors to read (1-128 dec.)
CH = track/cylinder number (0-1023 dec., see below)
CL = sector number (1-17 dec.)
DH = head number (0-15 dec.)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
ES:BX = pointer to buffer
on return:
AH = status (see ~INT 13,STATUS~)
AL = number of sectors read
CF = 0 if successful
= 1 if error
- BIOS disk reads should be retried at least three times and the
controller should be reset upon error detection
- be sure ES:BX does not cross a 64K segment boundary or a
DMA boundary error will occur
- many programming references list only floppy disk register values
- only the disk number is checked for validity
- the parameters in CX change depending on the number of cylinders;
the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5-0| CX
| | | | | | | | | | ------ sector number
| | | | | | | | ---------- high order 2 bits of track/cylinder
------------------------- low order 8 bits of track/cyl number
- see ~INT 13,A~
:int 13,3
^INT 13,3 - Write Disk Sectors
AH = 03
AL = number of sectors to write (1-128 dec.)
CH = track/cylinder number (0-1023 dec.)
CL = sector number (1-17 dec., see below)
DH = head number (0-15 dec.)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
ES:BX = pointer to buffer
on return:
AH = 0 if CF=0; otherwise disk status (see ~INT 13,STATUS~)
AL = number of sectors written
CF = 0 if successful
= 1 if error
- BIOS disk write attempts should reset the controller on error
- be sure ES:BX does not cross a 64K segment boundary or a
DMA boundary error will occur
- IBM PC XT 286 does not require a value in AL, though it is
recommended that one be supplied for portability
- many programming references list only floppy disk register values
- only the disk number is checked for validity
- the parameters in CX change depending on the number of cylinders;
the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5-0| CX
| | | | | | | | | | ------ sector number
| | | | | | | | ---------- high order 2 bits of track/cylinder
------------------------- low order 8 bits of track/cyl number
- see ~INT 13,B~
:int 13,4
^INT 13,4 - Verify Disk Sectors
AH = 04
AL = number of sectors to verify (1-128 dec.)
CH = track/cylinder number (0-1023 dec., see below)
CL = sector number (1-17 dec.)
DH = head number (0-15 dec.)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
ES:BX = pointer to buffer
on return:
AH = status (see ~INT 13,STATUS~)
AL = number of sectors verified
CF = 0 if successful
= 1 if error
- BIOS disk reads should be retried at least three times and the
controller should be reset upon error detection
- causes controller to calculate the CRC of the disk data and
compare it against the CRC stored in the sector header
- BIOS before 11/15/85 required ES:BX point to a valid buffer
that doesn't cross DMA boundaries. More recent BIOS versions
actually ignore the buffer and the DMA boundary requirement
- use this function to check for valid formatted diskette in a
the specified drive and for drive ready for read
- only the disk number is checked for validity
- the parameters in CX change depending on the number of cylinders;
the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5-0| CX
| | | | | | | | | | ------ sector number
| | | | | | | | ---------- high order 2 bits of track/cylinder
------------------------- low order 8 bits of track/cyl number
- see ~DETECTING~
:int 13,5
^INT 13,5 - Format Disk Track
AH = 05
AL = interleave value (XT only)
CX = track/cylinder number (see below for format)
DH = head number (0-15 dec.)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
ES:BX = pointer to block of "track address fields" containing
four byte fields for each sector to be formatted of the form:
1 byte track number
1 byte head number Size #
1 byte sector number Codes Bytes
1 byte sector size code 0 128
1 256
2 512
3 1024
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- BIOS disk write attempts should reset the controller on error
- ~INT 13,17~ should be called to set the DASD type
- this function is capable of doing great damage if the parameters
are incorrectly specified; only the drive number is checked
- initializes disk address fields and data sectors
- interleave is specified by ordering of track address fields
- after INT 13 disk format, if the disk is to be used with DOS the
DOS data structure must be written
- only the disk number is checked for validity
- the parameters in CX change depending on the number of cylinders;
the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5-0| CX (cylinder value 0-1023 dec.)
| | | | | | | | | | ------ unused
| | | | | | | | ---------- high order 2 bits of track/cylinder
------------------------- low order 8 bits of track/cyl number
:int 13,6
^INT 13,6 - Format Track and Set Bad Sector Flags (XT & portable)
AH = 06
AL = Interleave value (XT only)
BX = format buffer, size = 512 bytes; the first
2*(sectors/track) bytes contain F,N for each sector
F = 00h for good sector,
F = 80h for bad sector
N = sector number
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- BIOS disk write attempts should reset the controller on error
- only the disk number is checked for validity
:int 13,7
^INT 13,7 - Format Drive Starting at Specified Track (XT & portable)
AH = 07
AL = interleave value (XT only)
BX = format buffer, size = 512 bytes; the first 2*(sectors/track)
bytes contain F, N for each sector where:
F = 00h for good sector
F = 80h for bad sector
N = sector number
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- BIOS disk write attempts should reset the controller on error
- only the disk number is checked for validity
:int 13,8
^INT 13,8 - Get Current Drive Parameters (XT & newer)
AH = 08
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
AH = status (see ~INT 13,STATUS~)
BL = CMOS drive type
01 - 5q 360K 03 - 3h 720K
02 - 5q 1.2Mb 04 - 3h 1.44Mb
CH = cylinders (0-1023 dec. see below)
CL = sectors per track (see below)
DH = number of sides (0 based)
DL = number of drives attached
ES:DI = pointer to 11 byte ~Disk Base Table~ (DBT)
CF = 0 if successful
= 1 if error
% Cylinder and Sectors Per Track Format
|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0| CX
| | | | | | | | | | ------------- sectors per track
| | | | | | | | ------------- high order 2 bits of cylinder count
------------------------- low order 8 bits of cylinder count
- the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track)
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
- only the disk number is checked for validity
:int 13,9
^INT 13,9 - Initialize Fixed Disk Table (XT & newer)
AH = 09
DL = fixed disk number (80h=drive 0, 81h=drive 1)
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- sets specified fixed disk table to the default values from ROM
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
- INT 41h vector is pointer to table for drive 0
- INT 46h vector is pointer to table for drive 1
^Table definitions located by interrupt vectors 41H & 46H
% Offset Size Description
00 word maximum number of cylinders
02 byte maximum number of heads
03 word starting reduced write current cylinder
05 word starting write pre-comp cylinder
07 byte maximum ECC data burst length
08 byte control byte:
|7|6|5|4|3|2|1|0| Control byte
| | | | | --------- drive option
| | -------------- always zero
| --------------- disable ECC retries
---------------- disable access retires
:int 13,a
^INT 13,A - Read Long Sector (XT & newer)
AH = 0A
AL = number of sectors (1-121 dec.)
CH = track number (0-1023 dec., see below)
CL = sector number (1-17 dec., see below)
DH = head number (0-15 dec.)
DL = fixed drive number (80h=drive 0, 81h=drive 1)
ES:BX = address of buffer
on return:
AH = status (see ~INT 13,STATUS~)
AL = number of sectors actually transferred
CF = 0 if successful
= 1 if error
- BIOS disk reads should be retried at least three times and the
controller should be reset upon error detection
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
- reads regular data sectors (128-1024 bytes) with an additional
4 byte ECC code included
- a DMA boundary error will occur if the buffer at ES:BX crosses
a 64K segment boundary
- only the disk number is checked for validity
- the parameters in CX change depending on the number of cylinders;
the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0| CX
| | | | | | | | | | --------------- sector number
| | | | | | | | --------------- high order 2 bits of track number
--------------------------- low order 8 bits of track number
- see ~INT 13,2~
:int 13,b
^INT 13,B - Write Long Sectors (XT & newer)
AH = 0B
AL = number of sectors (1-121 dec.)
CH = track number (0-1023 dec., see below)
CL = sector number (1-17 dec., see below)
DH = head number (0-15 dec.)
DL = fixed drive number (80h=drive 0, 81h=drive 1)
ES:BX = address of buffer
on return:
AL = number of sectors actually transferred
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- BIOS disk write attempts should reset the controller on error
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
- writes regular sectors (128-1024 bytes) with additional 4 byte
ECC code included in data
- a DMA boundary error will occur if the buffer at ES:BX crosses
a 64K segment boundary
- only the disk number is checked for validity
- the parameters in CX change depending on the number of cylinders;
the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0| CX
| | | | | | | | | | --------------- sector number
| | | | | | | | --------------- high order 2 bits of track number
--------------------------- low order 8 bits of track number
- see ~INT 13,3~
:int 13,c
^INT 13,C - Seek to Cylinder (XT & newer)
AH = 0C
CH = low order byte of cylinder number (see below)
CL = high order byte of cylinder number (see below)
DH = head number (0-15)
DL = fixed drive number (80h=drive 0, 81h=drive 1)
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
- notice that CX is in reverse byte format similar to the way data
is stored in memory and reverse of normal register storage
- only the disk number is checked for validity
- the parameters in CX change depending on the number of cylinders;
the track/cylinder number is a 10 bit value taken from the 2 high
order bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5-0| CX
| | | | | | | | | | ------ unused
| | | | | | | | ---------- high order 2 bits of track number
------------------------- low order 8 bits of track number
:int 13,d
^INT 13,D - Alternate Disk Reset (XT & newer)
AH = 0D
DL = fixed drive number (80h=drive 0, 81h=drive 1)
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
- used to force drive recalibration similar to ~INT 13,0~
- drive heads are positioned at track zero
:int 13,e
^INT 13,E - Read Sector Buffer (XT & portable only)
AH = 0E
on return:
AL = number of sectors actually transferred
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
:int 13,f
^INT 13,F - Write Sector Buffer (XT & portable only)
AH = 0F
on return:
AL = number of sectors actually transferred
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
:int 13,10
^INT 13,10 - Test for Drive Ready (XT & newer)
AH = 10h
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
:int 13,11
^INT 13,11 - Recalibrate Drive (XT & newer)
AH = 11h
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
:int 13,12
^INT 13,12 - Controller RAM Diagnostic (XT & portable only)
AH = 12h
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
:int 13,13
^INT 13,13 - Drive Diagnostic (XT & portable only)
AH = 13h
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
:int 13,14
^INT 13,14 - Controller Internal Diagnostic (XT & newer)
AH = 14h
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- many good programming references indicate this function is only
available on the AT, PS/2 and later systems, but all hard disk
systems since the XT have this function available
- not valid on PS/2 model 30
:int 13,15
^INT 13,15 - Read DASD Type (XT BIOS from 1/10/86 & newer)
AH = 15h
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
AH = 00 drive not present
= 01 diskette, no change detection present
= 02 diskette, change detection present
= 03 fixed disk present
CX:DX = number of fixed disk sectors; if 3 is returned in AH
CF = 0 if successful
= 1 if error
- XT's must have a BIOS date 1/10/86 or newer
- used to determine if ~INT 13,16~ can detect disk change
- see ~INT 13,STATUS~
:int 13,16
^INT 13,16 - Change of Disk Status (XT BIOS from 1/10/86 & newer)
AH = 16h
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
AH = 00 no disk change
= 01 disk changed
CF = set if disk has been removed or an error occurred
- used to detect if a disk change has occurred
- see ~INT 13,STATUS~ ~INT 13,15~
:int 13,17
^INT 13,17 - Set DASD Type for Format (XT BIOS from 1/10/86 & newer)
AH = 17h
AL = 00 no disk
= 01 320k/360k diskette in 320k/360k drive
= 02 320k/360k diskette in 1.2Mb drive
= 03 1.2Mb diskette in 1.2Mb drive
= 04 720k diskette in 720k drive (BIOS 6/10/85 & newer)
720K diskette in 1.44Mb drive (PS/2)
1.44Mb diskette in 1.44Mb drive (PS/2)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
returns nothing
- only the disk number is checked for validity
- tells BIOS format routine about the disk type
:int 13,18
^INT 13,18 - Set Media Type for Format (BIOS date specific)
AH = 18h
CH = lower 8 bits of number of tracks (0-1023 dec., see below)
CL = sectors per track (1-17 dec., see below)
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
ES:DI = pointer to 11-byte ~Disk Base Table~ (DBT)
AH = 00h if requested combination supported
= 01h if function not available
= 0Ch if not supported or drive type unknown
= 80h if there is no media in the drive
CF = 0 if successful
= 1 if error
- valid only for XT BIOS dated after 1/10/86, AT after 11/15/86,
XT 286 and the PS/2 line
- only disk number is checked for validity
- track number is a 10 bit value taken from the 2 high order
bits of CL and the 8 bits in CH (low order 8 bits of track):
|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0| CX
| | | | | | | | | | --------------- sectors per track count
| | | | | | | | --------------- high order 2 bits track/cyl count
--------------------------- low order 8 bits of track/cyl count
- see ~INT 13,STATUS~
:int 13,19
^INT 13,19 - Park Fixed Disk Heads (AT & newer)
AH = 19h
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
on return:
AH = status (see ~INT 13,STATUS~)
CF = 0 if successful
= 1 if error
- available only on AT, XT 283 and PS/2 machines
:int 13,1a
^INT 13,1A - Format Unit (PS/2 model 50+)
AH = 1Ah
AL = defect table count
DL = drive number (0=A:, 1=2nd floppy, 80h=drive 0, 81h=drive 1)
ES:BX = far pointer to defect table
CL = modifier bits
|7|6|5|4|3|2|1|0| Format Unit Modifier Bits
| | | | | | | ----- 1=ignore primary defect map, 0=use map
| | | | | | ------ 1=ignore secondary defect map, 0=use map
| | | | | ------- 1=update secondary defect map, 0=don't
| | | | -------- 1=do extended surface analysis, 0=don't
| | | --------- 1=periodic interrupt status on, 0=off
-------------- reserved
returns nothing
- only the disk number is checked for validity
- see ~INT 13,STATUS~
:int 14:BIOS serial services:BIOS communications:int 14,status
^INT 14 - BIOS Asynchronous Communications Services
% For more information, see the following topics:
~INT 14,0~ Initialize serial port parameters
~INT 14,1~ Send character in AL
~INT 14,2~ Receive character in AL
~INT 14,3~ Get Serial port status
~INT 14,4~ Extended initialize (PS/2)
~INT 14,5~ Extended communication port control (PS/2)
- all functions have:
AH = function number
AL = character to send or receive
DX = zero based RS232 card number
- all registers are preserved except AX
- these functions use hardware flow control
- used by DOS MODE to redirect LPTx output to a serial device
- see individual functions for more data
^BIOS Asynchronous Communications Services (Status)
|7|6|5|4|3|2|1|0| AL modem status
| | | | | | | ----- clear to send status changed
| | | | | | ------ data set ready status changed
| | | | | ------- trailing edge ring indicator
| | | | -------- receive line signal changed
| | | --------- clear to send
| | ---------- data set ready
| ----------- ring indicator
------------ receive line signal detected
|7|6|5|4|3|2|1|0| AH port status
| | | | | | | ----- data ready
| | | | | | ------ overrun error
| | | | | ------- parity error
| | | | -------- framing error
| | | --------- break detect
| | ---------- transmit holding register empty
| ----------- transmit shift register empty
------------ time out (N/A for functions 1 and 2)
:int 14,0
^INT 14,0 - Initialize Communications Port Parameters
AH = 00
AL = parms for initialization (see tables below)
DX = zero based serial port number (0-1) (0-3 for AT)
|7|6|5|4|3|2|1|0| AL Parity (bits 4 & 3)
| | | | | | ------- word length bits 00 = none
| | | | | -------- stop bits flag 01 = odd
| | | ----------- parity bits 10 = none
---------------- baud rate bits 11 = even
% Word length (bits 1 & 0) Stop bit count (bit 2)
10 = 7 bits 0 = 1 stop bit
11 = 8 bits 1 = 2 stop bits
% Baud rate (bits 7, 6 & 5)
000 = 110 baud 100 = 1200 baud
001 = 150 baud 101 = 2400 baud
010 = 300 baud 110 = 4800 baud
011 = 600 baud 111 = 9600 baud (4800 on PCjr)
on return:
AH = port status
AL = modem status
- for status bits see ~INT 14,STATUS~
:int 14,1
^INT 14,1 - Send Character to Communications Port
AH = 01
AL = character to send
DX = zero based serial port number (0-1) (0-3 for AT)
on return:
AH = port status (see ~INT 14,STATUS~)
bit 7=0 indicates success
bit 7=1 indicates error, bits 0-6 indicate cause
- ~INT 14,3~ should be used to determine the actual cause
of the error since the time-out bit of the status register
is always set during an error on this call
- uses hardware flow control
:int 14,2
^INT 14,2 - Receive Character from Communications Port
AH = 02
DX = zero based serial port number (0-1) (0-3 for AT)
on return:
AH = port status (see ~INT 14,STATUS~)
bit 7 = 0 if successful
bit 7 = 1 if call failed
AL = character received if call was success
- ~INT 14,3~ should be used to determine the actual cause of
the error since the time-out bit of the status register is
always set during an error on this call
- uses hardware flow control
:int 14,3
^INT 14,3 - Get Serial Port Status
AH = 03
DX = zero based serial port number (0-1) (0-3 for AT)
on return:
AH = port status
AL = modem status
- for status bits see ~INT 14,STATUS~
- the status check performs a poll of the port and does not
perform character I/O
:int 14,4
^INT 14,4 - Serial Port Extended Initialization (PS/2 & later systems)
AH = 04
AL = break setting
BH = parity setting
BL = stop bit setting
CH = word length setting
CL = baud rate setting
DX = zero based serial port number (0-3)
% --- Break Setting ---
1 = break
0 = no break
% ----- Parity Setting ----- --- Stop Bit Setting ---
0 = no parity 0 = one stop bit
1 = odd parity 1 = 2 stop bits
2 = even parity 1h if register CH=0
3 = stick parity odd (5 bit word length)
4 = stick parity even
% -- Word Length Setting -- ---- Baud rate Setting ----
0 = 5 bits 0 = 110 5 = 2400
1 = 6 bits 1 = 150 6 = 4800
2 = 7 bits 2 = 300 7 = 9600
3 = 8 bits 3 = 600 8 = 19200
4 = 1200
on return:
AH = port status
AL = modem status
- for status bits see ~INT 14,STATUS~
:int 14,5
^INT 14,5 - Extended Communication Port Control (PS/2 & later systems)
AH = 05
AL = read or write modem control register
= 00 read modem control register
= 01 read modem control register
DX = zero based serial port number (0-1) (0-3 for AT)
BL = modem control register
|7|6|5|4|3|2|1|0| BL
| | | | | | | ----- 1 = activate data terminal ready
| | | | | | ------ 1 = activate request to send
| | | | | ------- OUT1
| | | | -------- OUT2
| | | --------- 0 = normal, 1 = loopback test
-------------- reserved, forced to zero
on return:
AH = port status
AL = modem status
BL = ~UART~ modem control register
- for status bits see ~INT 14,STATUS~
:int 15:BIOS system services:system interrupts
^INT 15 - System BIOS Services
^For more information see the following topics:
~INT 15,0~ Turn cassette motor on (PC,PCjr only)
~INT 15,1~ Turn cassette motor off (PC,PCjr only)
~INT 15,2~ Read blocks from cassette (PC,PCjr only)
~INT 15,3~ Write blocks to cassette (PC,PCjr only)
~INT 15,F~ PS/2 format periodic interrupt (PS/2 only)
~INT 15,20~ PRINT.COM Critical region flag (undocumented DOS 3.x+)
~INT 15,21~ PS/2 power on self test (PS/2 except 30)
~INT 15,40~ Read / modify profiles (convertible only)
~INT 15,41~ Wait on external event (convertible only)
~INT 15,42~ Request system power off (convertible only)
~INT 15,43~ Read system status (convertible only)
~INT 15,44~ (De)activate internal modem power (convertible)
~INT 15,4F~ Keyboard intercept (BIOS date specific)
~INT 15,80~ Device open
~INT 15,81~ Device close
~INT 15,82~ Program termination
~INT 15,83~ Event wait
~INT 15,84~ Joy-Stick support
~INT 15,85~ System request key pressed
~INT 15,86~ Elapsed time wait (AT and after)
~INT 15,87~ Move block to/from extended memory
~INT 15,88~ Extended memory size determination
~INT 15,89~ Switch processor to protected mode
~INT 15,90~ Device busy
~INT 15,91~ Interrupt complete
~INT 15,C0~ Return system configuration parameters (PS/2 only)
~INT 15,C1~ Return extended BIOS data address (PS/2 only)
~INT 15,C2~ Pointing device BIOS interface (PS/2 only)
~INT 15,C3~ Enable/Disable watchdog timer
~INT 15,C4~ Programmable option select
- CF is set and AX is left unchanged if a function requested in AH
isn't supported
- some Tandy BIOS's fail to restore interrupts on return from INT 15
:int 15,0
^INT 15,0 - Turn Cassette Motor On (PC,PCjr only)
AH = 00
- all programs using the cassette must actually turn on
the device before use
- there is a noticeable delay between turn-on and device ready
- a noticeable clicking noise can be heard by switching the
cassette on and off
- see ~INT 15,1~
:int 15,1
^INT 15,1 - Turn Cassette Motor Off (PC,PCjr only)
AH = 01
- all programs using the cassette should turn off
the device after use
- a noticeable clicking noise can be heard by switching the
cassette on and off
- see ~INT 15,0~
:int 15,2
^INT 15,2 - Read Blocks from Cassette (PC,PCjr only)
AH = 02
CX = count of bytes to read
ES:BX = pointer to data buffer
on return:
AH = error code if CF=1
= 1 if CRC error
= 2 data transition lost, (bit signal scrambled)
= 3 no data found on tape
DX = count of bytes actually read
ES:BX = pointer to byte following last byte read
- data is transferred in 256 byte blocks, though only the
number of bytes requested are actually stored
:int 15,3
^INT 15,3 - Write Blocks to Cassette (PC,PCjr only)
AH = 03
CX = count of bytes to write
ES:BX = pointer to data buffer
on return:
CX = zero
ES:BX = pointer to byte following last byte written
- data is actually written in 256 byte blocks
- if CX is less than 256, then the block is padded
- no error detection/correction is available for writing
:int 15,f
^INT 15,F - Format Periodic Interrupt (PS/2 only)
AH = 0F
AL = phase code
= 00 reserved
= 01 surface analysis
= 02 formatting
on return:
CF = 0 continue formatting/scanning
= 1 end of format/scanning
- after formatting/scanning each cylinder the formatting
routine calls this interrupt
- may be used by a program to gain control after formatting
a cylinder
- if invoked from a non-PS/2 CF=1 and AH contains the following
AH = 80h for PC and PCjr
= 86h on most other machines
:int 15,20
^INT 15,20 - PRINT.COM Critical Region Flag (undocumented DOS 3.x+)
AH = 20h
AL = 00 disable user critical region flag
= 01 enable user critical region flag
ES:BX = pointer to user critical region flag byte (AH = 1)
returns nothing
- provides PRINT.COM with the address of a byte to increment on
entry to DOS functions
- see ~bibliography~ reference for "Undocumented DOS"
:int 15,21
^INT 15,21 - Power On Self Test (POST) Error Log (PS/2 except 30)
AH = 21h
AL = 00 read POST error log
= 01 write error code to POST error log
BH = Device code (if write)
BL = Device error (if write)
on return
CF = 0 if successful
= 1 if in error (AH contains code)
% if reading POST error log:
AH = 00h if successful
= 80h (PCjr and PC) = 86h for all other machines
BX = number of POST error codes stored
ES:DI pointer to POST error log
% if writing POST error log:
AH = 00h if successful = 01 POST error log full
= 80h (PCjr and PC) = 86h for all other machines
:int 15,40
^INT 15,40 - Read / Modify Profiles (convertible only)
AH = 40h
AL = 00 - return system profile in CX,BX
01 - modify system profile
CX,BX = profile info
AL = 02 - return internal modem profile in BX
AL = 03 - modify internal modem profile
BX = profile info
:int 15,41
^INT 15,41 - Wait on External Event (convertible only)
AH = 41h
AL = condition type:
|7|6|5|4|3|2|1|0| AL
| | | | | --------- conditions (codes) to wait for
| | | | ---------- reserved
| | | ----------- 1=port address/0=user byte
---------------- reserved
% Condition codes:
0 = any external event
1 = compare and return if equal
2 = compare and return if not equal
3 = test and return if not zero
4 = test and return if zero
BH = condition compare or mask value
BL = time-out value times 55 ms, 0 if no time limit
DX = I/O port address (if AL bit 4 = 1)
ES:DI = pointer to user byte (if AL bit 4 = 0)
:int 15,42
^INT 15,42 - Request System Power Off (convertible only)
AH = 42h
AL = 00 to use system profile
= 01 to force suspend regardless of profile
:int 15,43
^INT 15,43 - Read System Status (convertible only)
AH = 43h
on return
AL = STATUS:
|7|6|5|4|3|2|1|0| AL
| | | | | | | ----- LCD detached
| | | | | | ------ reserved
| | | | | ------- RS232/parallel powered on
| | | | -------- internal modem powered on
| | | --------- power activated by alarm
| | ---------- standby power lost
| ----------- external power in use
------------ battery low
:int 15,44
^INT 15,44 - (De)activate Internal Modem Power (convertible)
AH = 44h
AL = 00 to power off
= 01 to power on
:int 15,4f
^INT 15,4F - Keyboard Intercept (BIOS date specific)
AH = 4F
AL = scan code
CF = set to 1 (via STC instruction)
on return
AH = 80h, CF set (PC, PCjr)
= 86h, CF set (XT BIOS 11/8/82, AT BIOS 1/10/84)
AL = CF set, new scan code
= CF clear, original scancode
- available with XT BIOS after 11/8/82, AT BIOS after 1/10/84
- called by ~INT 9~, makes allowance for keyboard translation
- normally returns the scan code in AL, with CF set
- if function returns with CF clear, INT 9 ignores keystroke
- do not rely on this function being called for each INT 9 since
any user INT 9 handler can exit prematurely and circumvent
this function
:int 15,80
^INT 15,80 - Device Open
AH = 80h
BX = device id
CX = process id
on return:
CF = 0 if successful
= 1 if error
AH = 80h for PC & PCjr
= 86h for XT (BIOS after 11/8/82)
- available on the AT, XT 286, PS/2 and XT with BIOS after 11/8/82
- designed for use in simple multitasking
:int 15,81
^INT 15,81 - Device Close
AH = 81h
BX = device id
CX = process id
on return:
CF = 0 if successful
= 1 if error
AH = 80h for PC & PCjr
= 86h for XT (BIOS after 11/8/82)
- available on the AT, XT 286, PS/2 and XT with BIOS after 11/8/82
- designed for use in simple multitasking
:int 15,82
^INT 15,82 - Program Termination
AH = 82h
BX = device id
on return:
CF = 0 if successful
= 1 if error
AH = 80h for PC & PCjr
= 86h for XT (BIOS after 11/8/82)
- available on the AT, XT 286, PS/2 and XT with BIOS after 11/8/82
- designed for use in simple multitasking
:int 15,83
^INT 15,83 - Event Wait
AH = 83h
AL = 0 set interval
= 1 cancel interval (PS/2)
CX,DX = number of microseconds to wait (976 ms resolution)
ES:BX = pointer to memory flag (bit 7 is set
when interval expires)
(granularity is 976 microseconds)
on return:
CF = 1 if function already busy
AH = 80h for PC
= 86h for XT & AT
- available on the AT (BIOS after 1/10/84) and PS/2's except 30
- designed for use in simple multitasking
:int 15,84
^INT 15,84 - Joy-Stick Support
AH = 84h
DX = 0 to read the current switch settings
= 1 to read the ~joystick~ position (resistive inputs)
on return (DX=0, read switch setting):
CF = 0 if successful
= 1 if error
AH = 80h error code if CF set on PC
= 86h error code if CF set on XT before 11/8/82
AL = switch settings in bits 7-4 (if read switch function)
on return (DX=1, read joystick position):
AX = A(X)
BX = A(Y)
CX = B(X)
DX = B(Y)
:int 15,85
^INT 15,85 - System Request Key Pressed
AH = 85h
AL = 00 key pressed
= 01 key released
on return:
CF = 0 if successful
= 1 if error
AH = 80h for PC or PCjr
= 86h for XT (BIOS after 11/8/82)
- called by BIOS when the System Request key is pressed/released
- available on machines with newer BIOS and keyboards
:int 15,86
^INT 15,86 - Elapsed Time Wait (AT and PS/2)
AH = 86h
CX,DX = number of microseconds to wait (976 ms resolution)
on return:
CF = set if error (PC,PCjr,XT)
= set if wait in progress
= clear if successful wait
AH = 80h for PC and PCjr
= 86h for XT
- AT and PS/2 only for system timing
- not designed for user application usage
:int 15,87
^INT 15,87 - Move Block to/from Extended Memory
AH = 87h
CX = word count of block to be moved
ES:SI = pointer to Global Descriptor Table (~GDT~)
on return:
CF = 0 if successful (AH contains return code)
= 1 if error detected
AH = 0 operation successful (ZF also set)
= 1 RAM parity error (if CF set)
= 2 other exception (if CF set)
= 3 gate address on line 20h failed (if CF set)
= 80h on PC and PCjr (if CF set)
= 86h on XT and newer 808x machines (if CF set)
- transfers data blocks to and from extended memory on 80286
and 80386 machines by switching from real to protected mode
for the duration of the transfer
- all real mode interrupts are disabled
- processor shuts down during the switch from protected mode
to real mode on 286 processors
:int 15,88
^INT 15,88 - Extended Memory Size Determination
AH = 88h
on return:
CF = 80h for PC, PCjr
= 86h for XT and Model 30
= other machines, set for error, clear for success
AX = number of contiguous 1k blocks of memory starting
at address 1024k (100000h)
- works only on 80286 and 80386 machines
- retrieves bytes 30 and 31 from the ~CMOS~ RAM (this data is set
by the boot memory scan
:int 15,89
^INT 15,89 - Switch Processor to Protected Mode
AH = 89h
BH = IRQ8 interrupt vector offset
BL = IRQ0 interrupt vector offset
CX = offset into protected mode CS to jump
ES:SI = pointer to Global Descriptor Table (~GDT~)
on return:
CF = 0 if successful
= 1 if error
- switches 286 and 386 machines into protected mode to take
advantage of advanced feature and extended memory
- Global descriptor table must be setup before interrupt
- normal BIOS functions are not available after the switch
:int 15,90
^INT 15,90 - Device Busy
AH = 90h
AL = type code:
= 00 disk
= 01 diskette
= 02 keyboard
= 03 pointing device
= 80 network (ES:BX = NCB)
= FC fixed disk reset (PS/2)
= FD diskette motor start
= FE printer
ES:BX = pointer to network control block if waiting for network
on return:
CF = 0 if wait not satisfied
= 1 if wait time satisfied
AH = when CF set, 80h for PC & PCjr, 86h for XT (BIOS 11/8/82)
- tells the OS a a program is about to wait for a device
- used for multitasking OS development
:int 15,91
^INT 15,91 - Interrupt Complete
AH = 91h
on return:
CF = 0 if successful
= 1 if error
AH = when CF set, 80h for PC & PCjr, 86h for XT (BIOS 11/8/82)
AL = type code:
= 00 disk
= 01 diskette
= 02 keyboard
= 03 pointing device
= 80 network (ES:BX = NCB)
= FC fixed disk reset (PS/2)
= FD diskette motor start
= FE printer
- should not be used by applications software
- used by the BIOS to indicate device interrupt is complete
- used for multitasking OS development
:int 15,c0
^INT 15,C0 - Return System Configuration Parameters (PS/2 only)
AH = C0
on return:
CF = 0 if successful
= 1 if error
AH = when CF set, 80h for PC & PCjr, 86h for XT
(BIOS after 11/8/82) and AT (BIOS after 1/10/84)
ES:BX = pointer to system descriptor table in ROM of the format:
% Offset Size Description
00 word length of descriptor (8 minimum)
02 byte model byte (same as F000:FFFE, not reliable)
03 byte secondary model byte
04 byte BIOS revision level (zero based)
05 byte feature information, see below
06 dword reserved
% Feature Information
|7|6|5|4|3|2|1|0| Feature Byte
| | | | | | | ----- reserved
| | | | | | ------ 0=PC bus, 1=Micro Channel
| | | | | ------- Extended BIOS Data Area (~EBDA~)allocated
| | | | -------- wait for external event supported
| | | --------- ~INT 15,4F~ used (kbd intercept)
| | ---------- ~RTC~ present
| ----------- 2nd ~8259~ present
------------ DMA channel 3 used by fixed disk BIOS
- see ~MACHINE ID~
:int 15,c1
^INT 15,C1 - Return Extended BIOS Data Area Segment (PS/2 only)
AH = C1
on return:
CF = 0 if successful
= 1 if error
AH = when CF set, 80h for PC & PCjr, 86h for XT (BIOS 11/8/82)
ES = ~EBDA~ segment address if PS/2
- the EBDA is used internally by the PS/2 BIOS routines
- the EBDA is allocated at the top of user memory by the ~POST~
routine
:int 15,c2
^INT 15,C2 - Pointing Device BIOS Interface (PS/2 only)
AH = C2
AL = 0 enable/disable pointing device (BH contains flag)
= 1 reset pointing device
= 2 set sample rate
= 3 set resolution
= 4 read device type
= 5 pointing device initialization
= 6 extended commands
= 7 pointing device far call initialization
BH = 0 indicates enable for AL = 0
= 1 indicates disable for AL = 0
on return:
CF = 0 if successful
= 1 if error
AH = when CF set, 80h for PC & PCjr, 86h for XT, AT
= 01 invalid function call
= 02 invalid input
= 03 interface error
= 04 resend
= 05 no far call installed
:int 15,c3
^INT 15,C3 - Enable/Disable Watchdog Timer (PS/2)
AH = C3
AL = 0 disable watchdog time-out
= 1 enable watchdog time-out
BX = watchdog timer count (1-255)
on return:
CF = 0 if successful
= 1 if error
AH = when CF set, 80h for PC & PCjr, 86h for XT, AT & Model 30
- the watchdog timer is available only on PS/2 with 80286 and
80386 processors.
- the ~timer~ uses channel timer channel 3 and IRQ0. Activated
when IRQ0 is active for more than one channel 0 timer cycle,
which causes the timer to be decremented. When the watch-
dog timer reaches 0, and NMI is generated.
:int 15,c4
^INT 15,C4 - Programmable Option Select (PS/2)
AH = C4
AL = 0 get Programmable Option Select adapter register address
= 1 enable slot for setup
= 2 adapter enable
on return:
CF = 0 if successful
= 1 if error
AH = when CF set, 80h for PC & PCjr, 86h for XT, AT & 30
BL = slot number (function AL=1)
DL = POS adapter register address (function AL=0)
- allows access to PS/2 Programmable Option Select registers
- available on 80286 and 80386 PS/2's
:int 16:BIOS keyboard services
^INT 16 - Keyboard BIOS Services
^For more information, see the following topics:
~INT 16,0~ Wait for keystroke and read
~INT 16,1~ Get keystroke status
~INT 16,2~ Get shift status
~INT 16,3~ Set keyboard typematic rate (AT+)
~INT 16,4~ Keyboard click adjustment (AT+)
~INT 16,5~ Keyboard buffer write (AT,PS/2 enhanced keyboards)
~INT 16,10~ Wait for keystroke and read (AT,PS/2 enhanced keyboards)
~INT 16,11~ Get keystroke status (AT,PS/2 enhanced keyboards)
~INT 16,12~ Get shift status (AT,PS/2 enhanced keyboards)
- with IBM BIOS's, INT 16 functions do not restore the flags to
the pre-interrupt state to allow returning of information via
the flags register
- functions 3 through 12h are not available on all AT machines
unless the extended keyboard BIOS is present
- all registers are preserved except AX and FLAGS
- see ~SCAN CODES~
:int 16,0
^INT 16,0 - Wait for Keypress and Read Character
AH = 00
on return:
AH = keyboard scan code
AL = ASCII character or zero if special function key
- halts program until key with a scancode is pressed
- see ~SCAN CODES~
:int 16,1
^INT 16,1 - Get Keyboard Status
AH = 01
on return:
ZF = 0 if a key pressed (even Ctrl-Break)
AX = 0 if no scan code is available
AH = ~scan code~
AL = ASCII character or zero if special function key
- data code is not removed from buffer
- ~Ctrl-Break~ places a zero word in the keyboard buffer but does
register a keypress.
:int 16,2
^INT 16,2 - Read Keyboard Flags
AH = 02
on return:
AL = BIOS keyboard flags (located in ~BIOS Data Area~ 40:17)
|7|6|5|4|3|2|1|0| AL or BIOS Data Area 40:17
| | | | | | | ----- right shift key depressed
| | | | | | ------ left shift key depressed
| | | | | ------- CTRL key depressed
| | | | -------- ALT key depressed
| | | --------- scroll-lock is active
| | ---------- num-lock is active
| ----------- caps-lock is active
------------ insert is active
:int 16,3
^INT 16,3 - Set Keyboard Typematic Rate (AT+)
AH = 03
AL = 00 set typematic rate to default
01 increase initial delay
02 slow typematic rate by 1/2
04 turn off typematic chars
05 set typematic rate/delay
BH = repeat delay (AL=5)
0 = 250ms 2 = 750ms
1 = 500ms 3 = 1000ms
BL = typematic rate, one of the following (AL=5)
00 - 30.0 01 - 26.7 02 - 24.0 03 - 21.8
04 - 20.0 05 - 18.5 06 - 17.1 07 - 16.0
08 - 15.0 09 - 13.3 0A - 12.0 0B - 10.9
0C - 10.0 0D - 9.2 0E - 8.6 0F - 8.0
10 - 7.5 11 - 6.7 12 - 6.0 13 - 5.5
14 - 5.0 15 - 4.6 16 - 4.3 17 - 4.0
18 - 3.7 19 - 3.3 1A - 3.0 1B - 2.7
1C - 2.5 1D - 2.3 1E - 2.1 1F - 2.0
returns nothing
- if the typematic rate is not within range,no action is taken
- available on AT and PS/2 machines with extended keyboard support
- see ~KEYBOARD COMMANDS~
:int 16,4
^INT 16,4 - Keyboard Click Adjustment (AT+)
AH = 04
AL = 1 for click on
= 0 for click off
- available only on AT and later machines that support the extended
keyboard BIOS
:int 16,5
^INT 16,5 - Keyboard Buffer Write (AT+)
AH = 05
CH = ~scan code~
CL = ASCII character
on return:
AL = 00 if success
01 if buffer full
- available on AT and PS/2 machines with extended keyboard support
- stores normal keystroke into keyboard buffer
- will not store attribute keys like Shift, Alt, Ctrl, etc...
:int 16,10
^INT 16,10 - Extended Wait for Keypress and Read Character (AT+)
AH = 10h
on return:
AH = ~scan code~
AL = ASCII character or zero if special function key
- available on AT and PS/2 machines with extended keyboard support
- similar to ~INT 16,0~
:int 16,11
^INT 16,11 - Extended Get Keyboard Status (AT+)
AH = 11h
on return:
ZF = 0 if key pressed (data waiting)
AX = 0 if no scan code is available
AH = ~scan code~
AL = ASCII character or zero if special function key
- available on AT and PS/2 machines with extended keyboard support
- data is not removed from buffer
- similar to ~INT 16,1~
:int 16,12
^INT 16,12 - Extended Get Keyboard Status (AT+)
AH = 12h
on return:
AH = BIOS keyboard flags (~BIOS Data Area~ location 40:18)
|7|6|5|4|3|2|1|0| AH
| | | | | | | ----- left CTRL key depressed
| | | | | | ------ left ALT key depressed
| | | | | ------- right CTRL key pressed
| | | | -------- right ALT key depressed
| | | --------- scroll-lock depressed
| | ---------- num-lock key depressed
| ----------- caps-lock key depressed
------------ system request key depressed
AL = BIOS keyboard flags (BIOS Data Area location 40:17)
|7|6|5|4|3|2|1|0| AL
| | | | | | | ----- right shift key depressed
| | | | | | ------ left shift key depressed
| | | | | ------- CTRL key depressed
| | | | -------- ALT key depressed
| | | --------- scroll-lock is active
| | ---------- num-lock is active
| ----------- caps-lock is active
------------ insert is active
- available on AT and PS/2 machines with extended keyboard support
- similar to ~INT 16,2~
- see ~KB FLAGS~
:int 17:BIOS printer services:int 17,status:printer status
^INT 17 - Printer BIOS Services
% For more information, see the following topics:
~INT 17,0~ Print character
~INT 17,1~ Initialize printer port
~INT 17,2~ Read printer port status
Status flags returned in register AH
|7|6|5|4|3|2|1|0| AH (status)
| | | | | | | ----- time-out
| | | | | -------- unused
| | | | --------- 1 = I/O error (~parallel~ pin 15)
| | | ---------- 1 = printer selected/on-line (parallel pin 13)
| | ----------- 1 = out of paper (parallel pin 12)
| ------------ 1 = printer acknowledgment (parallel pin 10)
------------- 1 = printer not busy (parallel pin 11)
- on the AT, XT 286, and PS/2 when the BIOS determines the printer
is busy, ~INT 15,90~ is executed
- all printers do not return reliable status information; bit 3 and
bit 7 are usually reliable.
- all registers are preserved except AH
:int 17,0
^INT 17,0 - Print Character
AH = 00
AL = character to print
DX = printer to be used (0-2)
on return:
AH = printer status, see ~INT 17,STATUS~
- writes character and returns status
:int 17,1
^INT 17,1 - Initialize Printer Port
AH = 01
DX = printer port to initialize (0-2)
on return:
AH = status, see ~INT 17,STATUS~
- initializes printer port and returns status
- outputs characters 0x08 and 0x0C to printer port which
reset ~Epson~ and IBM printers, but may produce undesirable
effects on other printers
:int 17,2
^INT 17,2 - Read Printer Port Status
AH = 02
DX = printer port to be used (0-2)
on return:
AH = status:
|7|6|5|4|3|2|1|0| Printer status bits
| | | | | | | ----- time out
| | | | | -------- unused
| | | | --------- I/O error
| | | ---------- selected
| | ----------- out of paper
| ------------ acknowledge
------------- not busy
- returns status of specified printer port
:int 19
^INT 19 - Bootstrap Loader
DL = physical drive where boot sector is located
no output
- track 0, sector 1 is loaded into address 0:7C00
and control is transferred there
- not a preferred method for rebooting by applications. A
better method is to set the word at location 40:72 to 1234h
and jump to location FFFF:0 in ROM
- memory is not cleared when rebooted through this interrupt
- see ~WARM BOOT~
:int 1a:BIOS clock services
^INT 1A - System and Real Time Clock BIOS Services
% For more informations, see the following topics:
~INT 1A,0~ Read system clock counter
~INT 1A,1~ Set system clock counter
~INT 1A,2~ Read real time clock time (AT,PS/2)
~INT 1A,3~ Set real time clock time (AT,PS/2)
~INT 1A,4~ Read real time clock date (AT,PS/2)
~INT 1A,5~ Set real time clock date (AT,PS/2)
~INT 1A,6~ Set real time clock alarm (AT,PS/2)
~INT 1A,7~ Reset real time clock alarm (PS/2)
~INT 1A,8~ Set RTC activated power on mode (convertible,PS/2)
~INT 1A,9~ Read RTC alarm time and status (convertible,PS/2)
~INT 1A,A~ Read system day counter (PS/2)
~INT 1A,B~ Set system day counter (PS/2)
~INT 1A,80~ Set up sound multiplexer (PCjr only)
- function is specified in register AH
- see ~RTC~
:int 1a,0
^INT 1A,0 - Read System Clock Counter
AH = 00
on return:
AL = midnight flag, 1 if 24 hours passed since reset
CX = high order word of tick count
DX = low order word of tick count
- incremented approximately 18.206 times per second
- at midnight CX:DX is zero
- this function can be called in a program to assure the date is
updated after midnight; this will avoid the passing two midnights
date problem
:int 1a,1
^INT 1A,1 - Set System Clock Counter
AH = 01
CX = high order word of tick count
DX = low order word of tick count
returns nothing
- CX:DX should be set to the number of seconds past
midnight multiplied by approximately 18.206
:int 1a,2
^INT 1A,2 - Read Time From Real Time Clock (XT 286,AT,PS/2)
AH = 02
on return:
CF = 0 if successful
= 1 if error, ~RTC~ not operating
CH = hours in BCD
CL = minutes in BCD
DH = seconds in BCD
DL = 1 if daylight savings time option
- on AT with BIOS before 6/10/85, DL is not returned
:int 1a,3
^INT 1A,3 - Set Time on Real Time Clock (XT 286,AT,PS/2)
AH = 03
CH = hours in BCD
CL = minutes in BCD
DH = seconds in BCD
DL = 1 if daylight savings time option
= 0 if standard time
returns nothing
- clock values must be in BCD
- see ~RTC~
:int 1a,4
^INT 1A,4 - Read Real Time Clock Date (XT 286,AT,PS/2)
AH = 04
on return:
CH = century in BCD (decimal 19 or 20)
CL = year in BCD
DH = month in BCD
DL = day in BCD
CF = 0 if successful
= 1 if error or clock not operating
- calling this interrupt will update the DOS maintained date and
reset the ~BIOS Data Area~ date rollover flag at 40:70
- see ~RTC~
:int 1a,5
^INT 1A,5 - Set Real Time Clock Date (XT 286,AT,PS/2)
AH = 05
CH = century in BCD (decimal 19 or 20)
CL = year in BCD
DH = month in BCD
DL = day in BCD
returns nothing
- all values must be in BCD
- see ~RTC~
:int 1a,6
^INT 1A,6 - Set Real Time Clock Alarm (XT 286,AT,PS/2)
AH = 06
CH = hours in BCD
CL = minutes in BCD
DH = seconds in BCD
on return:
CF = 1 if alarm already set or clock inoperable
- alarm setting is not relative like some sources claim, but the
actually clock time the interrupt should occur
- settings values must be in BCD
- when the alarm time is reached ~INT 4A~ is executed
- INT 4A vector should be replaced with address of the alarm
handling interrupt routine before setting the alarm
- ~INT 1A,7~ should be called to disable the ~RTC~ alarm
:int 1a,7
^INT 1A,7 - Disable Real Time Clock Alarm (XT,AT,PS/2)
AH = 07
returns nothing
- should be called previous to setting or resetting the
~RTC~ alarm with ~INT 1A,6~
:int 1a,8
^INT 1A,8 - Set RTC Activated Power On Mode (convertible)
AH = 08
CH = hours in BCD
CL = minutes in BCD
DH = seconds in BCD
- see ~RTC~
:int 1a,9
^INT 1A,9 - Read RTC Alarm Time and Status (convertible,PS/2)
AH = 09
on return:
CH = hours in BCD
CL = minutes in BCD
DH = seconds in BCD
DL = alarm status:
= 00 if alarm not enabled (AIE=0)
= 01 if alarm enabled but will not power up system (AIE=1)
= 02 if alarm will power up system (AIE=1)
- see ~RTC~
:int 1a,a
^INT 1A,A - Read System Day Counter (PS/2)
AH = 0Ah
on return:
CX = count of days since 1-1-1980
:int 1a,b
^INT 1A,B - Set System Day Counter (PS/2)
AH = 0Bh
CX = count of days since 1-1-1980
:int 1a,80
^INT 1A,80 - Setup Sound Multiplexer (PCjr only)
AL = 00 - source is ~8253~ channel 2
= 01 - source is cassette input
= 02 - source is I/O channel "AUDIO IN"
= 03 - source is sound generator chip
:int 1b:Ctrl-Break:BIOS break interrupt
^INT 1B - BIOS Ctrl-Break Handler Address
- holds address of the BIOS Ctrl-Break interrupt handler
- called by ~INT 9~ after Ctrl-Break key is pressed; INT 9 sets the
BIOS keyboard head and tail pointers to the buffer start and
places a zero word in the buffer
- the BIOS initially sets this value to point to a simple ~IRET~ but
DOS re-vectors this to its own code, usually 2 lines of code that
sets an internal flag (to 3) and then returns via IRET.
- DOS checks this flag on entry to many of its subfunctions. If the
flag is set, it invokes ~INT 23~.
- pointing this address to a null function with and IRET disables
Ctrl-Break aborts
- if the INT 1B code chooses to retain control of the system, it
must issue an EOI for any interrupt pending on the ~8259~ and reset
all I/O devices
- should be terminated via an IRET
- should not be called directly by user application
:int 1c:user timer routine
^INT 1C - System Timer Tick (User Routine)
- called by ~INT 8~, approximately 18.206 times per second
(unless the program modifies the ~8253~ PIT
- this is a user routine which the BIOS defaults to a simple ~IRET~
- this interrupt vector can be used for TSR popup utilities,
animated graphics updates and event polling
- since many TSR's don't maintain the integrity of the interrupt
call chain, relying on this for TSR popup isn't recommended
:int 1d
^INT 1D - Video Initialization Parameter Table Vector
- not a true interrupt, but a far pointer to a video
initialization parameter table for video controllers
:int 1e
^INT 1E - Disk Initialization Parameter Table Vector
- not an interrupt, but a far pointer to the diskette base table
- this table contains initialization parameters for the disk
controller used during formatting, reading, and writing to a disk
% Disk Initialization Parameter Table Vector Definition:
% Offset Description
00 |7|6|5|4|3|2|1|0| Disk Controller Mode byte 1
| | | | ----------- head step rate in milliseconds (0-F)
------------------ head unload time in milliseconds (0-F)
01 |7|6|5|4|3|2|1|0| Disk Controller Mode byte 2
| | | | | | | ----- DMA flag (0 = use DMA)
------------------ (head load time/2)-1 in milliseconds
02 clock ticks until motor off
03 FM or MFM Mode: Log2 (Bytes per Sector/128)
FM=Frequency Modulation used on single-density disks
MFM=Modified Frequency Modulation used on double-sided disks
04 last sector on track
05 gap length in bytes:
Bytes Per Sectors Write Format
MFM Sector Per Track Gap Gap
1 256 18 0Ah 0Ch
1 256 16 20h 32h
2 512 8 2Ah 50h
2 512 9 1Bh 6Ch
3 1024 4 80h F0h
4 2048 2 C8h FFh
5 4096 1 C8h FFh
06 disk data length
80h for 128 bytes/sector
FFh otherwise
07 gap length when formatting
08 data pattern used during formatting
09 floppy head bounce delay (in milliseconds)
0A floppy motor start delay (in 0.125 second intervals)
0B floppy motor stop delay (in 0.25 second intervals)
- see ~INT 13,18~
:int 1f
^INT 1F - Graphics Display Character Bit Map Table
- not a true interrupt, but a far pointer to a table of
character bit maps for the graphics mode representation of
ASCII characters 128 through 255
- can be used to change character fonts in CGA graphics mode
:DOS interrupts
^DOS Interrupt Summary
% See the following topics for more information:
~INT 20~ Program terminate
~INT 21~ DOS Function Dispatcher
~INT 22~ Program Terminate
~INT 23~ Ctl-break exit address
~INT 24~ Critical error handler address
~INT 25~ Absolute disk read
~INT 26~ Absolute disk write
~INT 27~ Terminate but stay resident
~INT 28~ DOS idle loop/scheduler (undocumented)
~INT 29~ Fast character output (undocumented)
~INT 2E~ Execute command using base level COMMAND.COM (undoc.)
~INT 2F~ Multiplex interrupt (DOS 3.x+)
:int 20
^INT 20 - Program Terminate
CS = address of ~PSP~
returns nothing
- INT 20 restores the terminate, ~Ctrl-Break~, and critical error
exit addresses from values in the PSP, flushes all buffers, frees
memory and returns to DOS via the termination handler address
- does not close ~FCB~s
- this function is no longer recommended, but can be used by
version of DOS before 2.0, see ~INT 21,4C~ and ~INT 21,0~
:int 21:DOS services:DOS functions
^INT 21 - DOS Function Dispatcher
^For more information, see the following topics:
~INT 21,0~ Program terminate
~INT 21,1~ Keyboard input with echo
~INT 21,2~ Display output
~INT 21,3~ Wait for auxiliary device input
~INT 21,4~ Auxiliary output
~INT 21,5~ Printer output
~INT 21,6~ Direct console I/O
~INT 21,7~ Wait for direct console input without echo
~INT 21,8~ Wait for console input without echo
~INT 21,9~ Print string
~INT 21,A~ Buffered keyboard input
~INT 21,B~ Check standard input status
~INT 21,C~ Clear keyboard buffer, invoke keyboard function
~INT 21,D~ Disk reset
~INT 21,E~ Select disk
~INT 21,F~ Open file using ~FCB~
~INT 21,10~ Close file using FCB
~INT 21,11~ Search for first entry using FCB
~INT 21,12~ Search for next entry using FCB
~INT 21,13~ Delete file using FCB
~INT 21,14~ Sequential read using FCB
~INT 21,15~ Sequential write using FCB
~INT 21,16~ Create a file using FCB
~INT 21,17~ Rename file using FCB
~INT 21,18~ DOS dummy function (CP/M) (not used/listed)
~INT 21,19~ Get current default drive
~INT 21,1A~ Set disk transfer address
~INT 21,1B~ Get allocation table information
~INT 21,1C~ Get allocation table info for specific device
~INT 21,1D~ DOS dummy function (CP/M) (not used/listed)
~INT 21,1E~ DOS dummy function (CP/M) (not used/listed)
~INT 21,1F~ Get pointer to default drive parameter table (undocumented)
~INT 21,20~ DOS dummy function (CP/M) (not used/listed)
~INT 21,21~ Random read using ~FCB~
~INT 21,22~ Random write using FCB
~INT 21,23~ Get file size using FCB
~INT 21,24~ Set relative record field for FCB
~INT 21,25~ Set interrupt vector
~INT 21,26~ Create new program segment
~INT 21,27~ Random block read using FCB
~INT 21,28~ Random block write using FCB
~INT 21,29~ Parse filename for FCB
~INT 21,2A~ Get date
~INT 21,2B~ Set date
~INT 21,2C~ Get time
~INT 21,2D~ Set time
~INT 21,2E~ Set/reset verify switch
~INT 21,2F~ Get disk transfer address
~INT 21,30~ Get DOS version number
~INT 21,31~ Terminate process and remain resident
~INT 21,32~ Get pointer to drive parameter table (undocumented)
~INT 21,33~ Get/set ~Ctrl-Break~ check state & get boot drive
~INT 21,34~ Get address to DOS critical flag (undocumented)
~INT 21,35~ Get vector
~INT 21,36~ Get disk free space
~INT 21,37~ Get/set switch character (undocumented)
~INT 21,38~ Get/set country dependent information
~INT 21,39~ Create subdirectory (mkdir)
~INT 21,3A~ Remove subdirectory (rmdir)
~INT 21,3B~ Change current subdirectory (chdir)
~INT 21,3C~ Create file using handle
~INT 21,3D~ Open file using handle
~INT 21,3E~ Close file using handle
~INT 21,3F~ Read file or device using handle
~INT 21,40~ Write file or device using handle
~INT 21,41~ Delete file
~INT 21,42~ Move file pointer using handle
~INT 21,43~ Change file mode
~INT 21,44~ I/O control for devices (~IOCTL~)
~INT 21,45~ Duplicate file handle
~INT 21,46~ Force duplicate file handle
~INT 21,47~ Get current directory
~INT 21,48~ Allocate memory blocks
~INT 21,49~ Free allocated memory blocks
~INT 21,4A~ Modify allocated memory blocks
~INT 21,4B~ EXEC load and execute program (func 1 undocumented)
~INT 21,4C~ Terminate process with return code
~INT 21,4D~ Get return code of a sub-process
~INT 21,4E~ Find first matching file
~INT 21,4F~ Find next matching file
~INT 21,50~ Set current process id (undocumented)
~INT 21,51~ Get current process id (undocumented)
~INT 21,52~ Get pointer to DOS "INVARS" (undocumented)
~INT 21,53~ Generate drive parameter table (undocumented)
~INT 21,54~ Get verify setting
~INT 21,55~ Create ~PSP~ (undocumented)
~INT 21,56~ Rename file
~INT 21,57~ Get/set file date and time using handle
~INT 21,58~ Get/set memory allocation strategy (3.x+, undocumented)
~INT 21,59~ Get extended error information (3.x+)
~INT 21,5A~ Create temporary file (3.x+)
~INT 21,5B~ Create new file (3.x+)
~INT 21,5C~ Lock/unlock file access (3.x+)
~INT 21,5D~ Critical error information (undocumented 3.x+)
~INT 21,5E~ Network services (3.1+)
~INT 21,5F~ Network redirection (3.1+)
~INT 21,60~ Get fully qualified file name (undocumented 3.x+)
~INT 21,62~ Get address of program segment prefix (3.x+)
~INT 21,63~ Get system lead byte table (MSDOS 2.25 only)
~INT 21,64~ Set device driver look ahead (undocumented 3.3+)
~INT 21,65~ Get extended country information (3.3+)
~INT 21,66~ Get/set global code page (3.3+)
~INT 21,67~ Set handle count (3.3+)
~INT 21,68~ Flush buffer (3.3+)
~INT 21,69~ Get/set disk serial number (undocumented DOS 4.0+)
~INT 21,6A~ DOS reserved (DOS 4.0+)
~INT 21,6B~ DOS reserved
~INT 21,6C~ Extended open/create (4.x+)
~INT 21,F8~ Set OEM INT 21 handler (functions F9-FF) (undocumented)
- int 21 functions are called with the function number in AH
- register AX may be altered, its contents are not guaranteed
- if an error occurs, CF is set to 1 and AX contains a simple
error code; ~INT 21,59~ can be used to determine cause.
- most INT 21 functions do not restore the flags to pre-interrupt
state to allow returning of information via the flags register
:int 21,0
^INT 21,0 - Program Terminate
AH = 00
CS = ~PSP~ segment address
returns nothing
- restores the terminate, ~Ctrl-Break~, and critical error
exit addresses, flushes all buffers, frees memory
and returns to DOS via the termination handler address
- does not close ~FCB~s
- this function is no longer recommended, but can be used by
version of DOS before 2.0, see ~INT 21,4C~ and ~INT 20~
:int 21,1
^INT 21,1 - Keyboard Input with Echo
AH = 01
on return:
AL = character from standard input device
- waits for keyboard input from STDIN and echoes to STDOUT
- returns 0 for extended keystroke, then function must be
called again to return scan code
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed
:int 21,2
^INT 21,2 - Display Output
AH = 02
DL = character to output
returns nothing
- outputs character to STDOUT
- backspace is treated as non-destructive cursor left
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed
:int 21,3
^INT 21,3 - Wait for Auxiliary Device Input
AH = 03
on return:
AL = character from the auxiliary device
- does not supply error returns
- waits for character and reads from STDAUX
- default DOS AUX parameters are 2400,N,8,1
:int 21,4
^INT 21,4 - Auxiliary Output
AH = 04
DL = character to output
returns nothing
- sends character in DL to STDAUX
- does not supply error returns
- waits until STDAUX is available
- default DOS AUX parameters are 2400,N,8,1
:int 21,5
^INT 21,5 - Printer Output
AH = 05
DL = character to output
returns nothing
- sends character in DL to STDPRN
- waits until STDPRN device is ready before output
:int 21,6
^INT 21,6 - Direct Console I/O
AH = 06
DL = (0-FE) character to output
= FF if console input request
on return:
AL = input character if console input request (DL=FF)
ZF = 0 if console request character available (in AL)
= 1 if no character is ready, and function request
was console input
- reads from or writes to the console device depending on
the value of DL
- cannot output character FF (DL=FF indicates read function)
- for console read, no echo is produced
- returns 0 for extended keystroke, then function must be
called again to return scan code
- ignores Ctrl-Break and Ctrl-PrtSc
:int 21,7
^INT 21,7 - Direct Console Input Without Echo
AH = 07
on return:
AL = character from STDIN
- waits for keyboard input until keystroke is ready
- character is not echoed to STDOUT
- returns 0 for extended keystroke, then function must be
called again to return scan code
- ignores Ctrl-Break and Ctrl-PrtSc
- see ~INT 21,1~
:int 21,8
^INT 21,8 - Console Input Without Echo
AH = 08
on return:
AL = character from STDIN
- returns 0 for extended keystroke, then function must be
called again to return scan code
- waits for character from STDIN and returns data in AL
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed
:int 21,9
^INT 21,9 - Print String
AH = 09
DS:DX = pointer to string ending in "$"
returns nothing
- outputs character string to STDOUT up to "$"
- backspace is treated as non-destructive
- if ~Ctrl-Break~ is detected, ~INT 23~ is executed
:int 21,a
^INT 21,A - Buffered Keyboard Input
AH = 0A
DS:DX = pointer to input buffer of the format:
| max | count | BUFFER (N bytes)
| | ------- input buffer
| ------------- number of characters returned (byte)
--------------- maximum number of characters to read (byte)
returns nothing
- since strings can be pre-loaded, it is recommended that the
default string be terminated with a CR
- N bytes of data are read from STDIN into buffer+2
- max buffer size is 255, minimum buffer size is 1 byte
- chars up to and including a CR are placed into the buffer
beginning at byte 2; Byte 1 returns the number of chars
placed into the buffer (extended codes take 2 characters)
- DOS editing keys are active during this call
- ~INT 23~ is called if Ctrl-Break or Ctrl-C detected
:int 21,b
^INT 21,B - Check Standard Input Status
AH = 0B
on return:
AL = 00 if no character available
= FF if character available
- checks STDIN for available characters
- character is not returned
- if Ctrl-Break is detected ~INT 23~ is executed
:int 21,c
^INT 21,C - Clear Keyboard Buffer and Invoke Keyboard Function
AH = 0C
AL = 01, 06, 07, 08 or 0A (INT 21 input functions)
on return:
see return values from INT 21,AL where AL is 1, 6, 7, 8 or A
- main function is to clear the input buffer and call INT 21h with
the specified function (in AL)
- see ~INT 21,1~, ~INT 21,6~, ~INT 21,7~, ~INT 21,8~ & ~INT 21,A~
:int 21,d
^INT 21,D - Disk Reset
AH = 0D
returns nothing
- all file buffers are flushed to disk
- does NOT update directory entry
:int 21,e
^INT 21,E - Select Disk
AH = 0E
DL = zero based, drive number (0-25, A: - Z:)
on return:
AL = one based, total number of logical drives including
hardfiles (1-26)
- for DOS 3.x+, this function returns the number of logical
drives or the value of LASTDRIVE (default of 5) in the
CONFIG.SYS file
:int 21,f
^INT 21,F - Open a File Using FCB
AH = 0F
DS:DX = pointer to unopened ~FCB~
on return:
AL = 00 if file opened
= FF if unable to open
- opens an existing file using a previously setup FCB
- the FCB fields drive identifier, filename and extension
must be filled in before call
- sets default FCB fields; current block number is set to 0;
record size is set to 80h; file size, date and time are set
to the values from the directory
- does not create file, see ~INT 21,16~
- DOS 2.x allows opening of subdirectories, DOS 3.x does not
:int 21,10
^INT 21,10 - Close a File Using FCB
AH = 10h
DS:DX = pointer to opened ~FCB~
on return:
AL = 00 if file closed
= FF if file not closed
- closes a previously opened file opened with an FCB
- FCB must be setup with drive id, filename, and extension
before call
:int 21,11
^INT 21,11 - Search for First Entry Using FCB
AH = 11h
DS:DX = pointer to unopened ~FCB~
on return:
AL = 00 if matching file found
= FF if file not found
- searches for first occurrence of filename specified in FCB
- FCB must have drive id, filename, and extension before call
- extended FCB can be used to specify a search criteria based
on attributes; hidden, system, label, and directory attributes
can be used to narrow the search (see ~FILE ATTRIBUTES~)
- after successful call DTA holds an unopened ~FCB~/~XFCB~ for
the requested file. Using any of the other FCB functions
destroys this ~DTA~ copy of the FCB/XFCB
- searching can be continued with the FCB find-next function
- "?" wildcard supported after DOS 2.1, "*" supported in DOS 3.x
- DOS 2.x can't find . and .. entries, DOS 3.x can (unless in root)
- see ~INT 21,12~
:int 21,12
^INT 21,12 - Search for Next Entry Using FCB
AH = 12h
DS:DX = pointer to unopened ~FCB~ returned from
~INT 21,11~ or ~INT 21,12~
on return:
AL = 00 if file found
= FF if file not found
- finds next matching file after calls to ~INT 21,11~ and
~INT 21,12~
- FCB should be the same across calls to INT 21,11 and 12
- after successful call ~DTA~ holds an unopened ~FCB~/~XFCB~ for
the requested file. Using any of the other FCB functions
destroys this DTA copy of the FCB/XFCB
:int 21,13
^INT 21,13 - Delete File Using FCB
AH = 13h
DS:DX = pointer to an unopened ~FCB~
on return:
AL = 00 if file deleted
= FF if file not found
- deletes unopened file with normal attributes
- FCB must contain drive id, filename, and extension before call
- "?" wildcard supported after DOS 2.1, "*" supported by DOS 3.x+
- DOS 2.x allowed deletion of a subdirectory if ~XFCB~ was provided,
even if files existed, causing lost clusters. DOS 3.x does not
:int 21,14
^INT 21,14 - Sequential Read Using FCB
AH = 14h
DS:DX = pointer to an opened ~FCB~
on return:
AL = 00 if successful read
= 01 if end of file (no data read)
= 02 if ~DTA~ is too small
= 03 if end of file or partial record read
- reads a record from file pointed to by FCB at the location
specified in current block and current record number
- data record is read into the DTA
- FCB record number is updated
:int 21,15
^INT 21,15 - Sequential Write Using FCB
AH = 15h
DS:DX = pointer to an opened ~FCB~
on return:
AL = 00 if write was successful
= 01 if diskette is full or read only
= 02 if ~DTA~ is too small
- writes a record from the DTA to the current record position
in file specified by the opened FCB
- record size and output location are maintained in the FCB
:int 21,16
^INT 21,16 - Create a File Using FCB
AH = 16h
DS:DX = pointer to an unopened ~FCB~
on return:
AL = 00 if file created
= FF if file creation failed
- creates file using FCB and leaves open for later output
- FCB must be setup with drive id, filename, and extension
before call
- an extended FCB can be used to also set ~file attributes~
:int 21,17
^INT 21,17 - Rename a File Using FCB
AH = 17h
DS:DX = pointer to a modified ~FCB~ of the format:
Offset Description
00 drive designator
01 original file name
09 original file extension
11 new file name
19 new extension
on return:
AL = 00 if file renamed
= FF if file not renamed
- allows renaming of files with normal attributes
- "?" wildcard supported after DOS 2.1, "*" supported by
DOS 3.x+
:int 21,19
^INT 21,19 - Get Current Default Drive
AH = 19h
on return:
AL = current default drive (0=A,1=B,etc)
- determines the current default drive
:int 21,1a
^INT 21,1A - Set Disk Transfer Address (DTA)
AH = 1A
DS:DX = pointer to disk transfer address (~DTA~)
returns nothing
- specifies the disk transfer address to DOS
- DTA cannot overlap 64K segment boundary
- offset 80h in the ~PSP~ is a 128 byte default DTA supplied
by DOS upon program load
- use of the DTA provided by DOS will result in the loss
of the program command tail which also occupies the 128
bytes starting at offset 80h of the PSP
- see ~INT 21,2F~
:int 21,1b
^INT 21,1B - Get Allocation Table Information
AH = 1B
on return:
AL = sectors per cluster
CX = bytes per sector
DX = clusters on disk
DS:BX = pointer to ~Media Descriptor Byte~ found in ~FAT~
- retrieves information on capacity and format of default drive
- DS:BX can be used to determine if drive is RAMDISK or removable
- see ~INT 21,1C~
:int 21,1c
^INT 21,1C - Get Allocation Table Info for Specified Drive
AH = 1C
DL = drive number (0 for default, 1 = A:, Z: = 26)
on return:
AL = sectors per cluster
CX = bytes per sector
DX = clusters on disk
DS:BX = pointer to ~Media Descriptor Byte~ found in ~FAT~
- retrieves information on capacity and format of specified drive
- DS:BX can be used to determine if drive is RAMDISK or removable
- see ~INT 21,1B~
:int 21,1f
^INT 21,1F - Get Pointer to Current Drive Parameter Table
^(Undocumented)
AH = 1F
DL = drive number (0=default, 1=A, ...)
on return:
AL = 00 DS:BX is pointer to drive parameter table (~DPT~)
FF drive does not exist
DS:BX = pointer to drive parameter table (DPT) if AL=0
- the format of the DPT varies between DOS versions
- calls ~INT 21,32~ with DL=00 for DOS version 2.x+
:int 21,21
^INT 21,21 - Random Read Using FCB
AH = 21h
DS:DX = pointer to an opened ~FCB~
on return:
AL = 00 if read successful
= 01 if EOF (no data read)
= 02 if ~DTA~ is too small
= 03 if EOF (partial record read)
- reads random records from a file opened with an FCB
to the DTA
- FCB must be setup with drive id, filename, extension,
record position and record length before call
- current record position field in FCB is not updated
:int 21,22
^INT 21,22 - Random Write Using FCB
AH = 22h
DS:DX = far pointer to an opened ~FCB~
on return:
AL = 00 if write successful
= 01 if diskette full or read only
= 02 if ~DTA~ is too small
- write records to random location in file opened with FCB
- FCB must be setup with drive id, filename, extension,
record position and record length before call
- current record position field in FCB is not updated
:int 21,23
^INT 21,23 - Get File Size Using FCB
AH = 23h
DS:DX = pointer to an unopened ~FCB~
on return:
AL = 00 if successful
= FF if file not found
- determines the number of records in a file
- FCB must be setup with drive id, complete filename and
extension plus record length before call
- updates random record position in FCB located at DS:DX
with file record count
:int 21,24
^INT 21,24 - Set Relative Record Field in FCB
AH = 24h
DS:DX = pointer to an opened ~FCB~
returns nothing
- modifies opened FCB for random operation
- sets FCB random record field to current sequential block
and record fields
:int 21,25
^INT 21,25 - Set Interrupt Vector
AH = 25h
AL = interrupt number
DS:DX = pointer to interrupt handler
returns nothing
- provides a safe method for changing interrupt vectors
- see ~INT 21,35~
:int 21,26
^INT 21,26 - Create New Program Segment Prefix
AH = 26h
DX = segment address of new ~PSP~
returns nothing
- allocates memory for a PSP and copies current PSP there
- used before DOS 2.x to spawn a child process
- the application is responsible for allocating any memory
necessary for the child process
- ~INT 21,4B~ (EXEC) is now the recommended method for starting
a child process, so this function should be avoided
- see also ~INT 21,55~
:int 21,27
^INT 21,27 - Random Block Read Using FCB
AH = 27h
CX = number of records to read
DS:DX = pointer to an opened ~FCB~
on return:
AL = 00 if read was successful
= 01 if EOF (no data read)
= 02 if ~DTA~ is too small
= 03 if EOF (partial record read)
CX = actual number of records read
- allows random access and sequential reading of a group
of records from a file opened with an FCB into the DTA
- FCB must be setup with drive id, filename, extension
record length and random record number before call
:int 21,28
^INT 21,28 - Random Block Write Using FCB
AH = 28h
CX = number of records to write
DS:DX = pointer to an opened ~FCB~
on return:
AL = 00 if write successful
= 01 if diskette full or read only
= 02 if ~DTA~ is too small
CX = number of records written
- allows random access and sequential writing of a group
of records from a file opened with an FCB into the DTA
- FCB must be setup with random record number and record size
- updates random record number, current block and current
record fields
:int 21,29
^INT 21,29 - Parse a Filename for FCB
AH = 29h
AL = bit pattern to control parsing (see bit meanings below)
DS:SI = pointer to a filespec to parse
ES:DI = pointer to a buffer for unopened ~FCB~
Bit patterns for parsing control found in AL:
|7|6|5|4|3|2|1|0| AL
| | | | | | | ----- 1 = ignore leading separators
| | | | | | | 0 = don't ignore leading separators
| | | | | | ------ 1 = modify drive ID if specified
| | | | | | 0 = modify drive ID regardless
| | | | | ------- 1 = modify filename if specified
| | | | | 0 = modify filename regardless
| | | | -------- 1 = modify extension if specified
| | | | 0 = modify extension regardless
--------------- unused
on return:
AL = 00 if no wildcard characters present
= 01 if wildcards present in string
= FF if drive specifier is invalid
DS:SI = pointer to the first character after parsed filename
ES:DI = pointer to the updated unopened FCB
- retrieves filename from the command line string and places
the filename components into an unopened FCB for later use
- if no filename is found a pointer is returned in ES:DI that
has a blank at ES:DI+1
- this function can be used to detect the existence of logical DOS
drives by creating a dummy filespec with a drive letter and colon
prepended. If the drive is invalid, this function will return FF
in AL
:int 21,2a
^INT 21,2A - Get Date
AH = 2A
on return:
AL = day of the week (0=Sunday)
CX = year (1980-2099)
DH = month (1-12)
DL = day (1-31)
- retrieves system date based on the DOS maintained clock
- updates ~BIOS Data Area~ current date and date rollover flag
at location 40:70
:int 21,2b
^INT 21,2B - Set Date
AH = 2B
CX = year (1980-2099)
DH = month (1-12)
DL = day (1-31)
on return:
AL = 00 if date change successful
= FF if invalid date
- sets DOS maintained clock
- DOS versions 3.3+ also update the ~CMOS~ date where applicable
:int 21,2c
^INT 21,2C - Get Time
AH = 2C
on return:
CH = hour (0-23)
CL = minutes (0-59)
DH = seconds (0-59)
DL = hundredths (0-99)
- retrieves DOS maintained clock time
:int 21,2d
^INT 21,2D - Set Time
AH = 2D
CH = hour (0-23)
CL = minutes (0-59)
DH = seconds (0-59)
DL = hundredths (0-99)
on return:
AL = 00 if time change successful
= FF if time invalid
- changes DOS maintained clock
- DOS version 3.3+ also update CMOS clock where applicable
:int 21,2e
^INT 21,2E - Set/Reset Verify Switch
AH = 2E
AL = 00 to set off
= 01 to set verify on
DH = 00 for DOS versions before 3.0
returns nothing
- with the verify setting on, disk I/O is more secure but
takes longer to complete
- see ~INT 21,54~
:int 21,2f
^INT 21,2F - Get Disk Transfer Address (DTA)
AH = 2F
on return:
ES:BX = pointer to current ~DTA~
- returns the DTA address
- the default DTA is a 128 byte block at address 80h in the
Program Segment Prefix (~PSP~). This area also contains the
command tail at program startup it must be saved or the DTA
must be relocated before use to preserve the command tail
- see ~INT 21,1A~
:int 21,30
^INT 21,30 - Get DOS Version Number
AH = 30h
on return:
AL = major version number (2-5)
AH = minor version number (in hundredths decimal)
BH = FF indicates MS-DOS, only if OEM vendor chooses to identify
= 00 indicates PC-DOS
BL:CX = 24 bit OEM serial number if BH is FF
- for an example DOS version 2.1 returns AL=2 and AH=10
- DOS versions prior to DOS 2.0 return zero in AH and AL
- DOS version 4.0 and 4.1 usually return the same value of 4.00
- the OEM serial number is a rarity, though some older OEM DOS
versions implemented this feature
- the OS/2 compatibility box returns 10.10 for OS/2 1.1, 10.20
for OS/2 1.2, etc...
- when testing for version, a specific test can often cause your
code to not work in following versions of DOS. It is often better
to test for a version number greater or equal to the minimum rather
than a specific version number where possible
- see ~DOS Versions~
:int 21,31
^INT 21,31 - Terminate Process and Remain Resident
AH = 31h
AL = exit code (returned to batch files)
DX = memory size in paragraphs to reserve
returns nothing
- preferred method for Terminate and Stay Resident programs
- terminates process without releasing allocated memory and
without closing open files
- attempts allocation of memory specified in DX from memory
allocated by DOS at startup. ~INT 21,48~ memory allocation
is not affected
- see ~INT 27~
:int 21,32
^INT 21,32 - Get Pointer to Drive Parameter Table (Undocumented)
AH = 32h
DL = drive (0=default, 1=A:, 2=B:, 3=C:, ...)
on return:
AL = FF if the drive number in DL was invalid
DS:BX = address of drive parameter table (~DPT~)
- available since DOS 2.0
- used by DOS commands CHKDSK and RECOVER
- forces a media check, which clears byte DS:[BX+17h] or DS:[BX+18h]
in the Drive Parameter Table
- actually accesses the disk, causing a critical error if a disk
error occurs
- can be used to determine if a drive is SUBST'ed by comparing
DS:[BX+1] and DS:[BX] for a match. If not equal, then the
drive is possibly SUBST'ed (though not guaranteed, this may also
indicate a Bernoulli box)
- can be used to determine if a drive is a RAM disk; if the disk is
NOT removable and (DS:[BX+1] == 0), then the disk is a RAM disk
(see ~IOCTL,0~ bit number 0Bh to determine if the disk is removable)
:int 21,33
^INT 21,33 - Get/Set System Values (Ctl-Break/Boot Drive)
AH = 33h
AL = 00 to get Ctrl-Break checking flag
= 01 to set Ctrl-Break checking flag
= 02 to set extended Ctrl-Break checking
= 05 get boot drive (DOS 4.x)
DL = 00 to set Ctrl-Break checking off
= 01 to set Ctrl-Break checking on
= boot drive for subfunction 5; (1=A:, 2=B:, ...)
on return:
DL = 00 Ctrl-Break checking OFF (AL=0 or AL=2)
= 01 Ctrl-Break checking ON (AL=0 or AL=2)
= boot drive number (1-26, A: - Z:) (function 05)
- retrieves DOS Ctrl-Break or extended Ctrl-Break setting which
determines if DOS will check for Ctrl-Break during INT 21 calls
:int 21,34:INDOS
^INT 21,34 - Get Address to DOS Critical Flag
^INDOS (Undocumented DOS 2.0+)
AH = 34h
on return:
ES:BX = address of a byte indicating whether a DOS call is
in progress. No DOS calls should be made if set.
- AKA the INDOS flag, this critical section flag may be checked from
within an interrupt handler before requesting a DOS service. It is
a semaphore that is non-zero when DOS is busy, and zero otherwise.
- though this flag indicates whether a DOS interrupt is active, it
should not be used alone to determine DOS is safe for re-entry;
Here's the standard rule for safe DOS entry: if ~INT 28~ is active
or this flag and the critical error flag are clear then it is safe
to call DOS
- this interrupt should be used only during TSR initialization;
the returned pointer should be used thereafter
- this flag is cleared after a critical error (~INT 24~)
- ES:BX-1 points to the critical error flag for DOS 3.x+
ES:BX+1 points to the critical error flag for DOS 2.x
ES:BX-1AA points to the critical error flag for COMPAQ DOS 3.0
~INT 21,5D~ in DOS 3.x+ can be used to locate the critical
error flag
:int 21,35
^INT 21,35 - Get Interrupt Vector
AH = 35h
AL = interrupt vector number
on return:
ES:BX = pointer to interrupt handler
- standard method for retrieving interrupt vectors
- see ~INT 21,25~
:int 21,36
^INT 21,36 - Get Disk Free Space
AH = 36h
DL = drive number (0=default, 1=A:)
on return:
AX = sectors per cluster
= FFFF if drive is invalid
BX = number of available clusters
CX = number of bytes per sector
DX = number of clusters per drive
- used to determine available space on specified disk
- see ~INT 21,1B~ ~INT 21,1C~
:int 21,37
^INT 21,37 - Get/Set Switch Character (Undocumented, DOS 2.0+)
AH = 37h
AL = 0 get switch character into DL; some systems return "-"
= 1 set switch character to value in DL
= 2 read device prefix flag into DL; returns DL = 0 indicating
devices must be accessed using /DEV/device. A non-zero value
indicates devices may be accessed without prefix
= 3 set device prefix flag, device names must begin with \DEV\.
DL = new switch character (AL=1)
= 00 \DEV\ must preceed device names (AL=3)
= 01 \DEV\ is not neccesary in device names (AL=3)
on return:
AL = FF illegal subfunction code specified
DL = current switch character (AL=0)
= device availability (AL=2, always FF with DOS 4.x+)
- subfunctions 0 and 1 were formerly available as a CONFIG.SYS
command in DOS versions before 3.x; also supportedin the OS/2
compatibility box
- subfunctions 2 and 3 were available in DOS 2.x only; they have
no effect in DOS 4.x+
- /DEV/ prefix is valid in DOS 2.x by default, setting the flag makes
it mandatory. DOS internal commands like DIR, TYPE and DEL do not
recognize filenames the are identical to device names regardless of
the setting of the AVAILDEV flag.
:int 21,38
^INT 21,38 - Get/Set Country Dependent Information
AH = 38h
AL = 00 to get current country information
= 00-FE country codes (DOS 3.x+)
= FF for country codes >= FF, country codes are in BX
BX = country code if AL = FF (country code > 255)
DX = FFFF to set country information
DS:DX = pointer to buffer to contain country data (if get data)
on return:
AX = error code if CF set
= 02 invalid country
BX = country code (DOS 3.x+)
DS:DX = pointer to returned country data (see ~COUNTRY CODES~)
- returns a pointer to country specific data, for DOS 3.x+ this
function can be used to also set this information
:int 21,39
^INT 21,39 - Create Subdirectory (mkdir)
AH = 39h
DS:DX = pointer to ASCIIZ path name
on return:
CF = 0 if successful
= 1 if error
AX = error code (see ~DOS ERROR CODES~)
- creates specified subdirectory
- returns error if directory already exists, element of the path
is not found, directory full or write protected disk
:int 21,3a
^INT 21,3A - Remove Subdirectory (rmdir)
AH = 3A
DS:DX = pointer to ASCIIZ path name
on return:
CF = 0 if successful
= 1 if error
AX = error code (see ~DOS ERROR CODES~)
- allows deletion of a subdirectory as long as it exists, is empty
and not the current directory
:int 21,3b
^INT 21,3B - Change Current Directory (chdir)
AH = 3B
DS:DX = pointer to ASCIIZ path name
on return:
CF = 0 if successful
= 1 if error
AX = error code if CF set (see ~DOS ERROR CODES~)
- changes the current directory to the directory specified
by pointer DS:DX
:int 21,3c
^INT 21,3C - Create File Using Handle
AH = 3C
CX = file attribute (see ~FILE ATTRIBUTES~)
DS:DX = pointer to ASCIIZ path name
on return:
CF = 0 if successful
= 1 if error
AX = files handle if successful
= error code if failure (see ~DOS ERROR CODES~)
- if file already exists, it is truncated to zero bytes on opening
:int 21,3d
^INT 21,3D - Open File Using Handle
AH = 3D
AL = open access mode
00 read only
01 write only
02 read/write
DS:DX = pointer to an ASCIIZ file name
on return:
AX = file handle if CF not set
= error code if CF set (see ~DOS ERROR CODES~)
% Access modes in AL:
|7|6|5|4|3|2|1|0| AL
| | | | | --------- read/write/update access mode
| | | | ---------- reserved, always 0
| --------------- sharing mode (see below) (DOS 3.1+)
---------------- 1 = private, 0 = inheritable (DOS 3.1+)
% Sharing mode bits (DOS 3.1+): Access mode bits:
% 654 210
000 compatibility mode (exclusive) 000 read access
001 deny others read/write access 001 write access
010 deny others write access 010 read/write access
011 deny others read access
100 full access permitted to all
- will open normal, hidden and system files
- file pointer is placed at beginning of file
:int 21,3e
^INT 21,3E - Close File Using Handle
AH = 3E
BX = file handle to close
on return:
AX = error code if CF set (see ~DOS ERROR CODES~)
- if file is opened for update, file time and date stamp
as well as fil