55
BIOS and DOS Interrupts Dr. Tim McGuire CS 272 Sam Houston State University These notes roughly correspond to text chapter 10, although the approach is considerably different Overview Previously, we used the INT (interrupt) instruction to call system routines In this module, we discuss different kinds of interrupts and take a closer look at the operation of the INT instruction o We will discuss the services provided by various BIOS (basic input/output system) and DOS interrupt routines To demonstrate the use of interrupts, we will write a program that displays the current time on the screen Hardware Interrupt Whenever a key is pressed, the CPU must be notified to read a key code into the keyboard buffer The general hardware interrupt goes like this: a device that needs service sends an interrupt request signal to the processor o the CPU suspends the current task and transfers control to an interrupt routine o the interrupt routine services the hardware device by performing some I/O operation o control is transferred back to the original executing task at the point where it was suspended Questions to be Answered How does the CPU find out a device is signaling? How does it know which interrupt routine to execute? How does it resume the previous task? Acknowledging an Interrupt

BIOS and DOS Interrupts

Embed Size (px)

Citation preview

Page 1: BIOS and DOS Interrupts

BIOS and DOS Interrupts Dr. Tim McGuire CS 272 Sam Houston State University

These notes roughly correspond to text chapter 10, although the approach is considerably different

Overview Previously, we used the INT (interrupt) instruction to call system routines In this module, we discuss different kinds of interrupts and take a closer look at the

operation of the INT instruction o We will discuss the services provided by various BIOS (basic input/output

system) and DOS interrupt routines To demonstrate the use of interrupts, we will write a program that displays the

current time on the screen

Hardware Interrupt Whenever a key is pressed, the CPU must be notified to read a key code into the

keyboard buffer The general hardware interrupt goes like this: a device that needs service sends an interrupt request signal to the processor

o the CPU suspends the current task and transfers control to an interrupt routine

o the interrupt routine services the hardware device by performing some I/O operation

o control is transferred back to the original executing task at the point where it was suspended

Questions to be Answered How does the CPU find out a device is signaling? How does it know which interrupt routine to execute? How does it resume the previous task?

Acknowledging an Interrupt Because an interrupt signal may come at any time, the CPU checks for the signal

after executing each instruction On detecting the interrupt signal, the CPU acknowledges it by sending an interrupt

acknowledge signal The interrupting device responds by sending an eight-bit number on the data bus,

called an interrupt number Each device uses a different interrupt number to identify its own service routine This process is called hand-shaking

Transferring to an Interrupt Routine The process is similar to a procedure call

Page 2: BIOS and DOS Interrupts

Before transferring control to the interrupt routine, the CPU first saves the address of the next instruction on the stack; this is the return address

The CPU also saves the FLAGS register on the stack; this ensures that the status of the suspended task will be restored

It is the responsibility of the interrupt routine to restore any registers it uses

Software Interrupt Software interrupts are used by programs to request system services A software interrupt occurs when a program calls an interrupt routine using the

INT instruction The format of the INT instruction is

INT interrupt_number The 8086 treats this interrupt number in the same way as the interrupt number

generated by a hardware device We have already seen a number of examples of this using INT 21h and INT 10h

Processor Exception There is a third kind of interrupt, called a processor exception A processor exception occurs when a condition arises inside the processor, such as

divide overflow, that requires special handling Each condition corresponds to a unique interrupt type For example, divide overflow is type 0, so when overflow occurs in a divide

instruction the CPU automatically executes interrupt 0 to handle the overflow condition

Interrupt Numbers The interrupt numbers for the 8086 are unsigned byte values -- therefore 256 types

of interrupts are possible Not all interrupt numbers are used BIOS interrupt service routines are stored in ROM DOS interrupt routines (int 21h) are loaded into memory when the machine is

started Some additional interrupt numbers are reserved by the manufacturer for further use;

the remaining numbers are available for the user

Interrupt Types Interrupt Types    Description

     0h-1Fh         BIOS Interrupts     20h-3Fh         DOS Interrupts     40h-7Fh         reserved     80h-F0h         ROM BASIC     F1h-FFh         not used

Interrupt Vector

Page 3: BIOS and DOS Interrupts

The CPU does not generate the interrupt routine's address directly from the interrupt number

o Doing so would mean that a particular interrupt routine must be placed in exactly the same location in every computer

o Instead, the CPU uses the interrupt number to calculate the address of a memory location that contains the actual address of the interrupt routine

This means that the routine may appear anywhere, so long as its address, called an interrupt vector, is stored in a predefined memory location

Interrupt Vector Table All interrupt vectors are placed in an interrupt vector table, which occupies the first

1KB of memory Each interrupt vector is given as segment:offset and occupies four bytes

o The first four bytes of memory contain interrupt vector 0

Accessing the Vector To find the vector for an interrupt routine, multiply the interrupt number by 4

o This gives the memory location containing the offset of the routine o The segment number of the routine is in the next word

Example The keyboard interrupt routine is interrupt 9 The offset address is stored in location 9x4 = 36 = 00024h The segment address is found in location 24h + 2 = 00026h BIOS initializes its interrupt vectors when the computer is turned on, and the DOS

interrupt vectors are initialized when DOS is loaded

Interrupt Routines When the CPU executes an INT instruction, it first saves the flags by pushing the

contents of the FLAGS register onto the stack Then it clears the control flags IF (interrupt flag) and TF (trap flag)

o The reason for this action is explained later Finally, it uses the interrupt number to get the interrupt vector from memory and

transfers control to the interrupt routine by loading CS:IP with the interrupt vector o The 8086 transfers to a hardware interrupt routine or processor exception in

a similar fashion On completion, an interrupt routine executes an IRET (interrupt return) instruction

that restores the IP, CS, and FLAGS registers

The Control Flag TF When TF is set, the 8086 generates a processor exception (interrupt 1)

o This interrupt is used by debuggers to "single step" through a program o To trace an instruction, the debugger first sets TF, and then transfers control

to the instruction to be traced After the instruction is executed, the processors generates an interrupt type 1

because TF is set

Page 4: BIOS and DOS Interrupts

o The debugger uses its own interrupt 1 routine to gain control of the processor

The Control Flag IF IF is used to control hardware interrupts

o When IF is set, hardware devices may interrupt the CPU o External interrupts may be disabled (masked out) by clearing IF o Actually, there is a hardware interrupt, called NMI (nonmaskable interrupt)

that cannot be masked out Both TF and IF are cleared by the processor before transferring to an interrupt

routine so that the routine will not be interrupted. o Of course, an interrupt routine can change the flags to enable interrupts

during its execution

BIOS Interrupts Interrupt types 0 - 1Fh are BIOS interrupts whose service routines reside in ROM

segment F000h Interrupt 0 -- Divide Overflow: generated when a DIV or IDIV operation produces

an overflow o The interrupt 0 routine displays the message "DIVIDE OVERFLOW" and

returns control to DOS Interrupt 1 -- Single Step: generated when the TF is set Interrupt 2 -- Nonmaskable Interrupt: cannot be masked out by clearing the IF

o The IBM PC uses this interrupt to signal memory and I/O parity errors that indicate bad chips

Interrupt 3 -- Breakpoint: used by debuggers to set up breakpoints Interrupt 4 -- Overflow: generated by the instruction INTO (interrupt if overflow)

when OF is set o Programmers may write their own interrupt routine to handle unexpected

overflows Interrupt 5 -- Print Screen: The BIOS interrupt 5 routine sends the video screen

information to the printer o An INT 5 instruction is generated by the keyboard interrupt routine (INT 9)

when the PrtScr key is pressed Interrupts 6&7 are reserved by Intel

Interrupt 8 -- Timer: A timer circuit generates an interrupt once every 54.92 milliseconds

o The BIOS interrupt 8 routine services the timer circuit It users the timer signals to keep track of the time of day

Interrupt 9 -- Keyboard: generated by the keyboard whenever a key is pressed or released

o The service routine reads a scan code and stores it in the keyboard buffer Interrupt E -- Diskette Error: The BIOS interrupt routine Eh handles diskette errors

Page 5: BIOS and DOS Interrupts

Interrupt Types 10h - 1Fh The interrupt routines 10h - 1Fh are software interrupts which can be called by

application programs to perform various I/O operations and status checking Interrupt 10h -- Video: The BIOS interrupt 10h routine is the video driver

o Details have been covered in a other units Interrupt 11h -- Equipment Check: returns the equipment configuration of the

particular PC o The return code is placed in AX o The table on the next slide shows how to interpret AX

Equipment Check

15-14     Number of printers installed 13 = 1    if internal modem installed 12 = 1    if game adapter installed 11-9      Number of serial ports installed 8         not used 7-6       Number of floppy drives (if bit 0=1)                 00=1, 01=2KB, 10=3, 11=4 5-4       Initial video mode                 00=not used, 01=40x25 color,                 10=80x25 color, 11=80x25 monochrome 3-2       System board RAM size (original PC)                 00=16KB, 01=32KB, 10=48KB, 11=64KB

1 = 1     if math coprocessor installed 0 = 1     if floppy drive installed

Interrupt Types 10h - 1Fh Interrupt 12h -- Memory Size: returns in AX the amount of conventional memory

o Conventional memory refers to memory circuits with address below 640K -- the unit for the return value is in kilobytes

o Example: Suppose a computer has 512KB of conventional memory. What will

be returned in AX if the instruction INT 12h is executed? 512 = 200h, hence AX = 200h

Interrupt 13h -- Disk I/O: The BIOS interrupt 13h routine is the disk driver; it allows application programs to do disk I/O

o Most file operations are done through DOS INT 21h, functions 39h - 42h, however; these utilize the BIOS INT 13h routine

Interrupt 14h -- Communications: The communications driver that interacts with the serial ports

Interrupt 15h -- Cassette: Used by the original PC for the cassette interface

Page 6: BIOS and DOS Interrupts

Interrupt 16h -- Keyboard: the keyboard driver, discussed in a previous unit Interrupt 17h -- Printer I/O: the printer driver

o supports 3 functions, given by AH=0,1, or 2 Function 0: writes character to the printer Function 1: initializes a printer port Function 2: gets printer status

Interrupt 18h -- BASIC: transfers control to ROM BASIC Interrupt 19h -- Bootstrap: reboots the system Interrupt 1Ah -- Time of Day: allows a program to get and set the timer tick count Interrupt 1Bh -- Ctrl-Break: called by the INT 9 routine when Ctrl-Break is pressed

o The BIOS routine is a stub; it contains only an IRET instruction o Users may write their own routines to handle the Ctrl-Break key

Interrupt 1Ch -- Timer Tick: called by INT 8 each time the timer circuit interrupts -- as in INT 1Bh, the routine is a stub

Interrupts 1Dh-1Fh: These interrupt vectors point to data instead of instructions (video parameters, diskette parameters, and video graphics characters, respectively)

DOS Interrupts The interrupt types 20h-3Fh are serviced by DOS routines that provide high-level

service to hardware as well as system resources such as files and directories The most useful is INT 21h, which provides many functions for doing keyboard,

video, and file operations

DOS Interrupts 20h-27h Interrupt 20h -- Program Terminate: Terminates program, but it is better to use INT

21h, function 4Ch Interrupt 21h -- Function Request: Functions 0h-5Fh

o These functions may be classified as character I/O, file access, memory management, disk access, networking, etc.

Interrupt 22h-26h: These handle critical errors and direct disk access Interrupt 27h -- Terminate and Stay Resident: allows programs to stay in memory

after termination

A Time Display Program As an example of using interrupt routines, we now write a program that displays the

current time o We will write three versions, each more complex

The first version simply displays the current time in hours, minutes, and seconds The second version will show the time updated every second The third version will be a memory resident program that can display the time while

other programs are running

Clock at Power-up When the computer is powered up, the current time is usually supplied by a real-

time clock circuit that is battery powered

Page 7: BIOS and DOS Interrupts

o If there is no real-time clock, DOS prompts the user to enter a time This time value is kept in memory and updated by a timer circuit using interrupt 8 A program can call DOS interrupt 21h, function 2Ch, to access the time

INT 21h, Function 2Ch Time Of Day Input:

o AH = 2Ch Output:

o CH = hours (0 - 23) o CL = minutes (0 - 59) o DH = seconds (0 - 59) o DL = 1/100 seconds (0 - 99)

Returns the time: hours, minutes, seconds, and hundredths of seconds

How the Program Works Three steps

o obtains the current time (procedure GET_TIME) o converts the hours, minutes, and seconds into ASCII digits (ignore the

fractions of seconds) (procedure CONVERT) o display the ASCII digits

A time buffer, TIME_BUF, is initialized with the message of 00:00:00 The main procedure calls GET_TIME to store the current time in the time buffer

The main procedure then calls INT 21h, function 9 to print out the string in the time buffer

GET_TIME calls INT 21h, function 2Ch to get the time, then calls CONVERT to convert the time to ASCII characters

CONVERT divides the input number in AL by 10; this will put the ten's digit in AL and the one's digit in AH

The second step is to convert the digits into ASCII The program displays the time and terminates

Program Listing (timedsp1.asm) %TITLE "TIME_DISPLAY_VER_1" ;program that displays the current time     IDEAL     MODEL small     STACK 100h     DATASEG TIME_BUF DB '00:00:00$'   ;time buffer hr:min:sec     CODESEG Start:     mov AX,@data     mov DS,AX             ;initialize DS

Page 8: BIOS and DOS Interrupts

;get and display time     lea BX,[TIME_BUF]     ;BX points to TIME_BUF     call GET_TIME         ;put current time in TIME_BUF     lea DX,[TIME_BUF]     ;DX points to TIME_BUF     mov AH,09h            ;display time     int 21h ;exit     mov AH,4Ch            ;return     int 21h               ;to DOS

Procedure GET_TIME PROC GET_TIME NEAR ;get time of day and store ASCII digits in time buffer ;input: BX = address of time buffer     mov AH,2Ch            ;gettime     int 21h               ;CH = hr, CL = min, DH = sec ;convert hours into ASCII and store     mov AL,CH             ;hour     call CONVERT          ;convert to ASCII     mov [BX],AX           ;store ;convert minutes into ASCII and store     mov AL,CL             ;minute     call CONVERT          ;convert to ASCII     mov [BX+3],AX         ;store ;convert seconds into ASCII and store     mov AL,DH             ;second     call CONVERT          ;convert to ASCII     mov [BX+6],AX         ;store     ret

ENDP GET_TIME

Procedure CONVERT PROC CONVERT ;converts byte number (0-59) into ASCII digits ;input: AL = number ;output: AX = ASCII digits, AL = high digit, AH = low digit     mov AH,0             ;clear AH     mov DL,10            ;divide AX by 10

Page 9: BIOS and DOS Interrupts

    div DL               ;AH has remainder, AL has quotient     or AX,3030h          ;convert to ASCII, AH has low digit     ret                  ;AL has high digit ENDP CONVERT ;

END Start

User Interrupt Procedures To make the time display program more interesting, let's write a second version that

displays the time and updates it every second o One way to continuously update the time is to execute a loop that keeps

obtaining the time via INT 21h, function 2Ch and displaying it o The problem here is to find a way to terminate the program o Instead of pursing this approach, we will write a routine for interrupt 1Ch

INT 8 and INT 1Ch Interrupt 1Ch is generated by the INT 8 routine which is activated by a timer circuit

about 18.2 times per second We will write a new interrupt 1Ch routine so that when it is called, it will get the

time and display it Our program will have a main procedure that sets up the interrupt routine and when

a key is pressed, it will deactivate the interrupt routine and terminate

Set Interrupt Vector To set up an interrupt routine, we need to

o save the current interrupt vector o place the vector of the user procedure in the interrupt vector table, and o restore the previous vector before terminating the program

We use INT 21h, function 35h to get the old vector and function 25h to set up the new interrupt vector

INT 21h, Function 25h Set Interrupt Vector

Store interrupt vector into vector table o Input:

AH = 25h AL = Interrupt number DS:DX = interrupt vector

o Output: none

INT 21h, Function 35h

Page 10: BIOS and DOS Interrupts

Get Interrupt VectorObtain interrupt vector from vector table

o Input: AH = 35h AL = Interrupt number

o Output: ES:BX = interrupt vector

Procedure SETUP_INT The procedure SETUP_INT in program listing setupint.asm saves an old interrupt

vector and sets up a new vector It gets the interrupt number in AL, a buffer to save the old vector at DS:DI, and a

buffer containing the new interrupt vector at DS:SI By reversing the two buffers, SETUP_INT can also be used to restore the old vector

Cursor Control Each display of the current time by INT 21h, function 9, will advance the cursor

o If a new time is displayed, it appears at a different screen position o So, to view the time updated at the same screen position we must restore the

cursor to its original position before we display the time o This is achieved by first determining the current cursor position; then, after

each print string operation, we move the cursor back We use INT 10h, functions 2 and 3, to save the original cursor position and to move

the cursor to its original position after each print string operation

INT 10h, Function 2 Described in I/O module, repeated here for convenience

Move Cursor Input:

o AH = 2 o DH = new cursor row (0-24) o DL = new cursor column (0-79 for 80x25 mode) o BH = page number

Output: none

INT 10h, Function 3 Described in I/O module, repeated here for convenience

Get Cursor Position and Size Input:

o AH = 3 o BH = page number

Output: o DH = cursor row o DL = cursor column o CH = cursor starting scan line o CL = cursor ending scan line

Page 11: BIOS and DOS Interrupts

Interrupt Procedure When an interrupt procedure is activated, it cannot assume that the DS register

contains the program's data segment address Thus, if it uses any variables it must first reset the DS register The DS register should be restored before ending the interrupt routine with IRET

DISPTIME2.ASM Program listing dsptime2.asm contains a main procedure and the interrupt

procedure TIME_INT the steps in the main procedure are

o save the current cursor position o set up the interrupt vector for TIME_INT o wait for a key input, and o restore the old interrupt vector and terminate

Setting and Restoring the Interrupt Vector To set up the interrupt vector, we use the pseudo-ops OFFSET and SEG to obtain

the offset and segment of the TIME_INT routine o The vector is then stored in the buffer NEW_VEC

SETUP_INT is called to set up the vector for interrupt type 1Ch (timer tick) INT 16h, fcn 0 is used for key input SETUP_INT is again used for to restore the old interrupt vector

o this time SI points to the old vector and DI points to the vector for TIME_INT

The TIME_INT Routine The steps in TIME_INT are

o set DS o get new time o display time o restore cursor position, and o restore DS

Outline of the Program The program operates like this:

o After setting up the cursor and interrupt vectors, the main procedure just waits for a keystroke

o In the meantime, the interrupt routine (TIME_INT) keeps updating the time whenever the timer circuit ticks

o After a key is hit, the old interrupt vector is restored and the program terminates

Assembling and Linking The modules must be separately assembled and then linked with:

tlink timedsp2 setupint gettime

Page 12: BIOS and DOS Interrupts

Memory Resident Program We will write the third version of DISPLAY_TIME as a TSR (terminate and stay

resident) program Normally, when a program terminates, the memory occupied by the program is used

by DOS to load other programs However, when a TSR program terminates, the memory occupied is not released Thus, a TSR program is also called a memory resident program

Terminating a TSR To return to DOS, a TSR program is terminated by using either INT 27h or INT

21h, function 31h o Our program uses INT 27h

We write our program as a .COM program because to use interrupt 27h, we need to determine how many bytes are to remain memory resident

The structure of a .COM program makes this easy, because there is only one program segment

.COM programs also are smaller, so they save space for TSRs

INT 27h Terminate and Stay Resident Input:

o DS:DX = address of byte beyond the part that is to remain resident Output:

o none

Once terminated, a TSR program is not active o It must be activated by some external activity, such as a certain key

combination or by the timer The advantage of a TRS program is that it may be activated while some other

program is running o Our program will become active when the Ctrl and right shift keys are

pressed To keep the program small, it will not update the time

The program has two parts: o an initialization part that sets up the interrupt vector, and o the interrupt routine itself

The procedure INITIALIZE initializes the interrupt vector 9 (keyboard interrupt) with the address of the interrupt procedure MAIN and then calls INT 27h to terminate

The address is passed to INT 27h is the beginning address of the INITIALIZE procedure

o this is possible because the instructions are no longer needed The procedure INITIALIZE is shown in the program listing INITLZE.ASM

Page 13: BIOS and DOS Interrupts

There are a number of ways for the interrupt routine to detect a particular key combination

o The simplest way is to detect the control and shift keys by checking the keyboard flags

o When activated by a keystroke, the interrupt routine calls the old keyboard interrupt routine to handle the key input

o To detect the control and shift keys, a program can examine the keyboard flags at the BIOS data area 0000:0417h or use INT 16h, function 2

INT 16h, Function 2 Get Keyboard Flags Input:

o AH = 2 Output:

o AL = key flags

bit       meaning

7=1     Insert on 6=1     Caps Lock on 5=1     Num Lock on 4=1     Scroll Lock on 3=1     Alt key down 2=1     Ctrl key down 1=1     Left shift key down 0=1     Right shift key down    

We will use the Ctrl and right shift key combination to activate and deactivate the clock display

o When activated, the current time will be displayed on the upper right-hand corner

o We must first save the screen data so that when the clock display is deactivated the screen can be restored

The procedure SET_CURSOR sets the cursor at row 0 and the column given in DL The procedure SAVE_SCREEN copies the screen data into a buffer called

SS_BUF, and the procedure RESTORE_SCREEN moves the data back to the screen buffer

All three procedures are contained in SAVESCRN.ASM

We are now ready to write the interrupt routine To determine whether to activate or deactivae the time display, we use the variable

ON_FLAG, which is set to 1 when the time is being displayed Procedure MAIN is the interrupt routine

Page 14: BIOS and DOS Interrupts

The steps in procedure MAIN are: o save all registers used and set up the DS and ES registers o call the old keyboard interrupt routine to handle the key input o check to see if both Ctrl and right shift keys are down (if not, then exit) o test ON_FLAG to determine status, and if ON_FLAG is 1 then restore

screen and exit o save current cursor position and also the display screen info, and o get time, display time, then exit

In step 1, to set up the registers DS and ES, we use CS o segment values cannot be used in a .COM program

In step 2, we need to push the FLAGS register so that the procedure call simulates an interrupt call

In step 6, we use the BIOS interrupt 10h instead of DOS interrupt 21h, function 9 to display the time because (from experience) INT 21h, function 9 tends to be unreliable in a TSR program

Because the program has been written as a .COM program, we need to rewrite the file containing the GET_TIME procedure with full segment directives. The file GETTIME2.ASM contains GET_TIME, CONVERT, and SETUP_INT

The TLINK command should be

tlink /t timedsp3 savescrn gettime2 initlze Notice that initlze.obj is linked last so that the procedure INITIALIZE is

placed at the end of the program Writing TSR programs is tricky -- if there are other TSR programs on your system,

your program may not function properly

Page 15: BIOS and DOS Interrupts

IBM PC/XT/AT & M24 BIOS SOFTWARE INTERRUPTS    Alarm Interrupt Vector - INT 4Ah Cassette I/O - INT 15h Diskette I/O - INT 13h Fixed Disk I/O - INT 13h Equipment Determination - INT 11h IBM AT BIOS extensions - INT 15h Keyboard I/P - INT 16h Memory Size Determination - INT 12h Parallel Printer O/P - INT 17h RS232 Serial I/O - INT 14h Time of Day - INT 1Ah Timer Tick Interrupt Vector - INT 1Ch Video Interrupt Service Routine - INT 10h    INT 10h - Video Interrupt Service Routine (Technical References: IBM AT - VIDEO 5-127 @ VIDEO_IO IBM PC - A-43 @ F065h IBM XT - System BIOS A-46 @ F065h Olivetti M24 - D-148 & F065h) AH = 00h - Set Mode & Clear Screen 01h - Set Cursor Value 02h - Set Cursor Position 03h - Read Cursor Position 04h - Read Light Pen Position 05h - Select Active Display Page 06h - Scroll Active Page Up 07h - Scroll Active Page Down 08h - Read Attribute & Character at Current Cursor 09h - Write Attribute & Character at Current Cursor 0Ah - Write Character at Current Cursor 0Bh - Set Overscan, Back & Foreground Colours 0Ch - Write Dot 0Dh - Read Dot 0Eh - Terminal Emulator for Active Page 0Fh - Read Current Video Status 10h-12h - Reserved 13h - Write String (IBM AT)

Page 16: BIOS and DOS Interrupts

  AH = 00h - Set Mode & Clear Screen  Input: AL = mode = 00h - text 40x 25 monochrome = 01h - text 40x 25 colour = 02h - text 80x 25 monochrome = 03h - text 80x 25 colour = 04h - graphics 320x200 colour = 05h - graphics 320x200 monochrome = 06h - graphics 640x200 monochrome = 07h - text 80x 25 monochrome card = 40h - graphics 640x400 monochrome (M24 only) = 48h - graphics 640x400 monochrome tinytext (M24 only)  Output: AH = 00h AL = palette colour  AH = 01h - Set Cursor Value  Input: CH bit#s 0-4 = starting line for cursor CL bit#s 0-4 = ending line for cursor  Output: AH = 0Ah AL = CL  Hardware will always cause blink. Setting bit#s 5-7 can cause errors.  AH = 02h - Set Cursor Position  Input: BH = page number (0-7 for text, 0 for graphics) (DH,DL) = required (row,col) of cursor, ref (0,0) is upper left  Output: None  AH = 03h - Read Cursor Position  Input: BH = page number (0-7 for text, 0 for graphics) Output: (DH,DL) = (row,col) of cursor, ref (0,0) at upper left (CH,CL) = current cursor mode setting  AH = 04h - Read Light Pen Position  Output: AH = 0 - light pen not down/not triggered AH = 1 - valid light pen values in the registers (DH,DL) = (row,col) of character position CH = rastor line (0-199/399)

Page 17: BIOS and DOS Interrupts

BX = pixel column (0-319/639)  AH = 05h - Select Active Display Page  Input: AL = new page number (0-7 for modes 0-1, 0-3 for modes 2-3)  Output: None  AH = 06h - Scroll Active Page Up  Input: IF AL = 0, THEN clear entire window with attribute in BH ELSE, AL = number of rows to 'scroll' up = number of rows to clear at bottom of window BH = attribute to be used on blank rows (CH,CL) = (row,col) of upper left corner of window (DH,DL) = (row,col) of lower right corner of window  Output: None  AH = 07h - Scroll Active Page Down  Input: IF AL = 0, THEN clear entire window with attribute in BH ELSE, AL = number of rows to 'scroll' down = number of rows to clear at top of window BH = attribute to be used on blank rows (CH,CL) = (row,col) of upper left corner of window (DH,DL) = (row,col) of lower right corner of window  Output: None  AH = 08h - Read Attribute & Character at Current Cursor  Input: BH = display page  Output: AL = character read AH = attribute of character  AH = 09h - Write Attribute & Character at Current Cursor  Input: AL = character to write BH = display page BL = attribute of character to write CX = number of characters to write  Output: None  AH = 0Ah - Write Character at Current Cursor

Page 18: BIOS and DOS Interrupts

  Input: AL = character to write BH = display page CX = number of characters to write  Output: None  AH = 0Bh - Set Overscan, Back & Foreground Colours  Input: BH = palette colour ID to set (0-127) BL = colour value to be used with that colour ID  Output: None  AH = 0Ch - Write Dot  Input: AL = colour value (if bit# 7 = 1, AL is XORed with current value) CX = column number DX = row number  Output: None  AH = 0Dh - Read Dot  Input: None  Output: AL = colour value CX = column number DX = row number  AH = 0Eh - Terminal Emulator for Active Page  Input: AL = character to write BL = foreground colour (graphics mode) BH = display page (alpha mode) (IBM PC)  Output: None  AH = 0Fh - Read Current Video Status  Input: None  Output: AH = number of character columns on screen AL = display mode currently set BH = current active display page  AH = 13h - Write String (IBM AT only

Page 19: BIOS and DOS Interrupts

  Input: AL = action byte 0 - use attribute in BL, cursor not moved 1 - use attribute in BL, cursor is moved 2 - string includes attribute, cursor not moved 3 - string includes attribute, cursor is moved  BH = page number CX = length of character string to be written DX = (DH,DL) = (row,col) of starting cursor position ES:BP = pointer to string to be written: either [char,char, ... ,char] or [char,attrib,char,attrib, ... ,char,attrib]  Output: None  Note: IRET for IBM PX, XT and M24  INT 11h - Equipment Determination (Technical References: IBM AT - BIOS 5-143 @ EQUIPMENT IBM PC - A-67 @ F84Dh IBM XT - System BIOS A-71 @ F84Dh Olivetti M24 - D-174 & F84Dh, D-88, & 2-106) Input: None  Output: AX = equipment descriptor bit#s 15,14 (C000h) = number of parallel ports attached bit# 13 (2000h) not used bit# 12 (1000h) = game i/o attached (IBM AT not used) bit#s 11-9 (0E00h) = number of serial ports attached bit# 8 (0100h) not used bit#s 7,6 (00C0h) = # of diskette drives - 1 if bit# 0 = 1 bit#s 5,4 (0030h) = initial video mode 0 - unused 1 - 40x25 B&W using colour card 2 - 80x25 B&W using colour card 3 - 80x25 B&W using B&W card bit#s 3,2 (000Ch) = Motherboard RAM size (IBM AT not used) (0h=16k,4h=32k,8h=48k,Ch=64k) bit# 1 (0002h) = math coprocessor (IBM AT only) bit# 0 (0001h) = 1 indicates diskettes attached  

Page 20: BIOS and DOS Interrupts

INT 12h - Memory Size Determination (Technical References: IBM AT - BIOS 5-143 @ MEMORY_SIZE_DETERMINE IBM PC - A-67 @ F841h IBM XT - System BIOS A-71 @ F841h Olivetti M24 - D-174 & F841h) Input: None  Output: AX = number of contiguous 1k blocks of memory (-640)  INT 13h - Diskette I/O (Technical References: IBM AT - Diskette 5-89 @ DISKETTE_IO IBM PC - A-32 @ EC59h IBM XT - System BIOS A-34 @ EC59h Olivetti M24 - D-132 & EC59h)  AH = 00h - Reset Diskette System 01h - Read Status of Last Operation to AL 02h - Read Sectors to Memory 03h - Write Sectors from Memory 04h - Verify the Desired Sectors 05h - Format the Specified Track 15h - Read DASD Type (AT only) 16h - Disk Change Line Status (AT only) 17h - Set DASD Type for Format (AT only)  Note: drive numbers are 0 & 1 for IBM AT & Olivetti M24, else 0-3.  AH = 00h - Reset Diskette System  Input: None (DL must be 0/1 on Olivetti M24)  Output: None  AH = 01h - Read Status of Last Operation to AL  Input: None (DL must be 0/1 on Olivetti M24)  Output: AL = status 80h - timeout 40h - bad seek 20h - disk controller failure

Page 21: BIOS and DOS Interrupts

10h - bad CRC on diskette read 09h - attempt to DMA across 64k page boundary 08h - DMA overrun on i/o operation 06h - media removed (on dual attach card - AT) 04h - requested sector not found 03h - attempt to write on write protected disk 02h - address mark not found 01h - bad command 00h - operation successful AH = 02h - Read Sectors to Memory  Input: AL = number of sectors to read (1-8/9,1-15) CL = starting sector number (1-8/9,1-15) CH = track number (0-39,0-79) DL = drive number (0-1/3) DH = head number (0/1) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 03h - Write Sectors from Memory  Input: AL = number of sectors to write (1-8/9,1-15) CL = starting sector number (1-8/9,1-15) CH = track number (0-39,0-79) DL = drive number (0-1/3) DH = head number (0/1) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 04h - Verify the Desired Sectors  Input: AL = number of sectors to verify (1-8/9,1-15) CL = starting sector number (1-8/9,1-15) CH = track number (0-39,0-79) DL = drive number (0-1/3) DH = head number (0/1) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 05h - Format the Specified Track

Page 22: BIOS and DOS Interrupts

  Input: AL = number of sectors to format (1-8/9,1-15) CH = track number (0-39,0-79) DL = drive number (0-1/3) DH = head number (0/1) ES:BX = address of buffer (C,H,R,N,c,h,r,n...)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) Note: In the IBM AT, function call 17 must be made to set the type  AH = 15h - Read DASD Type (AT only)  Input: DL = drive number (0-1)  Output: CF = 0/1 - operation successful/failure AH = 00 - drive not present 01 - diskette, no change line available 02 - diskette, change line available 03 - fixed disk  AH = 16h - Disk Change Line Status (AT only)  Input: DL = drive number (0-1)  Output: CF = 0 & AH = 0 - disk change line not active CF = 1 & AH = 6 - disk change line active  AH = 17h - Set DASD Type for Format (AT only)  Input: AL = 00 - not used 01 - diskette 320/360k in 320/360k drive 02 - diskette 320/360k in 1.2M drive 03 - diskette 1.2M in 1.2M drive DL = drive number (0-1)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h)  INT 13h - Fixed Disk I/O (Technical References: IBM AT - Disk 5-103 @ DISK_IO IBM XT - Fixed Disk BIOS A-84 @ 0256h Olivetti M24 - D-30 & D1A8h)

Page 23: BIOS and DOS Interrupts

  AH = 00h - Reset Disk 01h - Read Status of Last Operation to AL 02h - Read Sectors to Memory 03h - Write Sectors from Memory 04h - Verify the Desired Sectors 05h - Format the Specified Track 06h - Format the Specified Track and set Bad Sector Flags 07h - Format the Drive 08h - Return the Current Drive Parameters 09h - Initialize Drive Pair Characteristics 0Ah - Read Long 0Bh - Write Long 0Ch - Seek 0Dh - Alternate Disk Reset 0Eh - Read Sector Buffer 0Fh - Write Sector Buffer 10h - Test Drive Ready 11h - Recalibrate 12h - Controller RAM Diagnostic 13h - Drive Diagnostic 14h - Controller Internal Diagnostic 15h - Read DASD Type (AT only) 16h - Disk Change Line Status (AT only) 17h - Set DASD Type for Format (AT only)  Note: drive numbers are 80h-87h  AH = 00h - Reset Disk  Input: DL = drive number  Output: CF = 0/1 - operation successful/failure AH = status  AH = 01h - Read Status of Last Operation to AL  Input: DL = drive number  Output: AL = status FFh - sense fail BBh - undefined error (XT) 80h - timeout 40h - bad seek 20h - disk controller failure 11h - data corrected by ECC (AL has burst length) 10h - bad ECC on diskette read

Page 24: BIOS and DOS Interrupts

0Bh - bad track (M24) 09h - attempt to DMA across 64k page boundary 07h - drive parameter activity failed 05h - bad reset 04h - requested sector not found 02h - address mark not found 01h - bad command 00h - operation successful AH = 02h - Read Sectors to Memory  Input: AL = number of sectors to read (1-80h) CL = starting sector number (1-17) CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 03h - Write Sectors from Memory  Input: AL = number of sectors to write (1-80h) CL = starting sector number (1-17) CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 04h - Verify the Desired Sectors  Input: AL = number of sectors to verify (1-80h) CL = starting sector number (1-17) CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 05h - Format the Specified Track 

Page 25: BIOS and DOS Interrupts

Input: AL = sector interleave (1-16) CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) Note: The record buffer should be written before formatting  AH = 06h - Format the Specified Track, Setting Bad Sector Flags  Input: AL = sector interleave (1-16) CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 07h - Format the Drive  Input: AL = sector interleave (1-16) CH = starting track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 08h - Return the Current Drive Parameters  Input: DL = drive number (80-87h)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) CL = Maximum value for sector number CH = Maximum value for track number (hi bits in bit# 7 & 6 of CL) DL = Number of drives attached (0-2) DH = Maximum value for head number  AH = 09h - Initialize Drive Pair Characteristics  Input: DL = valid drive number  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h)

Page 26: BIOS and DOS Interrupts

Drive parameters at table pointed to by INT 41h  AH = 0Ah - Read Long Sectors to Memory  Input: AL = number of sectors to read (1-79h) CL = starting sector number (1-17) CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) Note: Read and Write long sectors are 512 bytes od data + 4 bytes ECC  AH = 0Bh - Write Long Sectors from Memory  Input: AL = number of sectors to write (1-79h) CL = starting sector number (1-17) CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7) ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 0Ch - Seek  Input: CH = track number (0-1023, hi bits in bit# 7 & 6 of CL) DL = drive number (80-87h) DH = head number (0-7)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 0Dh - Alternate Disk Reset (without diskette reset)  Input: DL = drive number  Output: CF = 0/1 - operation successful/failure AH = status  AH = 0Eh - Read Sector Buffer  Input: ES:BX = address of buffer

Page 27: BIOS and DOS Interrupts

  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 0Fh - Write Sector Buffer  Input: ES:BX = address of buffer  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 10h - Test Drive Ready  Input: DL = drive number  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 11h - Recalibrate  Input: DL = drive number  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 12h - Controller RAM Diagnostic  Input: None  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 13h - Drive Diagnostic  Input: DL = drive number  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 14h - Controller Internal Diagnostic  Input: None  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h) AH = 15h - Read DASD Type (AT only)

Page 28: BIOS and DOS Interrupts

  Input: DL = drive number (0-1)  Output: CF = 0/1 - operation successful/failure AH = 00 - drive not present 01 - diskette, no change line available 02 - diskette, change line available 03 - fixed disk  AH = 16h - Disk Change Line Status (AT only)  Input: DL = drive number (0-1)  Output: CF = 0 & AH = 0 - disk change line not active CF = 1 & AH = 6 - disk change line active  AH = 17h - Set DASD Type for Format (AT only)  Input: AL = 00 - not used 01 - diskette 320/360k in 320/360k drive 02 - diskette 320/360k in 1.2M drive 03 - diskette 1.2M in 1.2M drive DL = drive number (0-1)  Output: CF = 0/1 - operation successful/failure AH = status (see status call, AH=01h)  INT 14h - RS232 Serial I/O (Technical References: IBM AT - RS232 5-125 @ RS232_IO IBM PC - A-20 @ E739h IBM XT - System BIOS A-21 @ E739h Olivetti M24 - D-111 & E739h)  AH = 00h - Initialize the Communications Port 01h - Send the Byte in AL 02h - Receive a Byte from the Communications Port 03h - Return the Communcications Port status  AH = 00h - Initialize the Communications Port  Input: AL - parameters for initialization  --- baud rate ---- parity ---stops- word length - bit# 7 6 5 4 3 2 1 0

Page 29: BIOS and DOS Interrupts

  000 - 110 X0 - NONE 0 - 1 10 - 7 bits 001 - 150 01 - ODD 1 - 2 11 - 8 bits 010 - 300 11 - EVEN 011 - 600 100 - 1200 101 - 2400 110 - 4800 111 - 9600  DX = RS232 port to access (0,1)  Output: AX - full port status (as for AH = 3)  Note: IBM allow 2 serial ports, Olivetti, 4  AH = 01h - Send the Byte in AL  Input: AL = byte to send DX = port# (0,1)  Output: AH = line control status with bit# 7 set if unable to transmit  AH = 02h - Receive a Byte from the Communications Port  Input: DX = port# (0,1)  Output: AL = byte received AH = current line status masked by 9Eh. i.e. error if <>0 bit# 7 = 1 - DSR not set  AH = 03h - Return the Communcications Port status  Input: DX = port# (0,1)  Output: AH = line control status bit# 7 = time out (no DSR on Rx) bit# 6 = Tx shift register empty bit# 5 = Tx holding register empty bit# 4 = bread detect bit# 3 = framing error bit# 2 = parity error bit# 1 = overrun error bit# 0 = data ready AL = modem status bit# 7 = receive line signal detect (DCD - pin 8) bit# 6 = ring indicator (RI - pin 22)

Page 30: BIOS and DOS Interrupts

bit# 5 = data set ready (DSR - pin 6) bit# 4 = clear to send (CTS - pin 5) bit# 3 = delta receive line signal detect bit# 2 = trailing edge ring detector bit# 1 = delta data set ready bit# 0 = delta clear to send  INT 15h - Cassette i/o (Technical References: IBM AT - BIOS 1 5-147 @ CASSETTE_IO IBM PC - A-68 @ F859h IBM XT - System BIOS A-72 @ F859h Olivetti M24 - D-175 & F859h) AH = 00h - Turn Cassette Motor On (IBM PC only, not XT,AT or M24) 01h - Turn Cassette Motor Off (IBM PC only) 02h - Read 256 Byte Block(s) from Cassette (IBM PC only) 03h - Write 256 Byte Block(s) to Cassette (IBM PC only)  AH = 00h - Turn Cassette Motor On (IBM PC only)  Input: None  Output: CF = 0, AH = 0  Note: IBM XT, AT & M24: CF = 1, AH = 86h - bad command  AH = 01h - Turn Cassette Motor Off (IBM PC only)  Input: None  Output: CF = 0, AH = 0  Note: IBM XT, AT & M24: CF = 1, AH = 86h - bad command  AH = 02h - Read 256 Byte Block(s) from Cassette (IBM PC only)  Input: CX = number of bytes to read ES:BX = pointer to data buffer  Output: DX = number of bytes read ES:BX = pointer to last byte read + 1 CF = 0 & AH = 0 if no error occurred CF = 1 & AH = 01h - CRC error was detected AH = 02h - data transitions lost

Page 31: BIOS and DOS Interrupts

AH = 03h - no data found  Note: IBM XT, AT & M24: CF = 1, AH = 86h - bad command  AH = 03h - Write 256 Byte Block(s) to Cassette (IBM PC only)  Input: CX = number of bytes to write ES:BX = pointer to data buffer  Output: CX = 0 ES:BX = pointer to last byte written + 1 CF = 0 & AH = 0  Note: IBM XT, AT & M24: CF = 1, AH = 86h - bad command  INT 15h - IBM AT BIOS Extensions (Technical References : IBM AT - BIOS 1 5-147 @ CASSETTE_IO) AH = 80h - Device Open 81h - Device Close 82h - Program Termination 83h - Event Wait 84h - Joystick Support 85h - System Request Key Pressed 86h - Wait 87h - Move Block To And From Extended Memory 88h - Extended Memory Size Determine 89h - Processor to Virtual Mode 90h - Device Busy Loop 91h - Interrupt Complete Flag Set  AH = 80h - Device Open  Input: BX = device ID CX = process ID  Output: CF = 0 & AH = 0 - successful  Note: IBM AT: MOV AH,0 ! CLC ! RET 2 (BIOS 01/10/84) IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 81h - Device Close 

Page 32: BIOS and DOS Interrupts

Input: BX = device ID CX = process ID  Output: CF = 0 & AH = 0 - successful  Note: IBM AT: MOV AH,0 ! CLC ! RET 2 (BIOS 01/10/84) IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 82h - Program Termination  Input: BX = device ID  Output: CF = 0 & AH = 0 - successful  Note: IBM AT: MOV AH,0 ! CLC ! RET 2 (BIOS 01/10/84) IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 83h - Event Wait  Input: AL = 0 - set interval (CX,DX) = number of microseconds to delay (CX = MSW) (ES:BX) = pointer to byte that will have bit# 7 set when time interval has expired AL = 1 - cancel (BIOS 01/10/84 code assumes AL = 0!)  Output: CF = 0 - interval timer set CF = 1 - interval timer already in use  Note: IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 84h - Joystick Support  Input: DX = 0 - read the current switch settings 1 - read the resistive inputs  Output: CF = 0 - operation complete AL has switch settings in bit#s 7-4 or AX = A(x) value BX = A(y) value CX = B(x) value DX = B(y) value CF = 1 - no adaptor card or invalid call  Note: IBM PC: CF = 1 & AH = 80h - undefined operation

Page 33: BIOS and DOS Interrupts

IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 85h - System Request Key Pressed  Input: AL = 0 - make of key 1 - break of key Output: CF = 0 & AH = 0 - successful  Note: IBM AT: MOV AH,0 ! CLC ! RET 2 (BIOS 01/10/84) IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 86h - Wait  Input: (CX,DX) = number of microseconds to delay (CX = MSW)  Output: CF = 0 - have done delay CF = 1 - interval timer already in use  Note: IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 87h - Move Block To And From Extended Memory  Input: CX = number of words to move (max count = 8000h, 32k words) ES:SI = location of Global Descriptor Table DESCRIPT STRUC SEG_LIMIT DW ? ; segment limit (1-64k bytes) BASE_LO DW ? ; 24 bit absolute address of BASE_HI DB ? ; segment ACCESS DB ? ; access rights byte DW ? ; reserved DESCRIPT ENDS GDT STRUC DUMMY DQ ? ; dummy descript initialized to zero CGDT_LOC DQ ? ; location of calling routine (all 0's) SOURCE DQ ? ; source descriptor (set by user) TARGET DQ ? ; target descriptor (set by user) BIOS_CS DQ ? ; BIOS code descriptor (all 0's) TEMP_SS DQ ? ; stack descriptor (all 0's) GDT ENDS  Output: CF = 0 & ZF = 1 & AH = 0 - successful CF = 1 & ZF = 0 & AH = 1 - RAM parity error CF = 1 & ZF = 0 & AH = 2 - exception interrupt error CF = 1 & ZF = 0 & AH = 3 - gate address line 20 failed

Page 34: BIOS and DOS Interrupts

  Note: IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 88h - Extended Memory Size Determine  Input: None  Output: AX = number of contiguous 1k blocks starting at 1024k  Note: IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 89h - Processor to Virtual Mode  Input: ES:SI = location of Global Descriptor Table DESCRIPT STRUC SEG_LIMIT DW ? ; segment limit (1-64k bytes) BASE_LO DW ? ; 24 bit absolute address of BASE_HI DB ? ; segment ACCESS DB ? ; access rights byte DW ? ; reserved DESCRIPT ENDS GDT STRUC DUMMY DQ ? ; dummy descript initialized to zero GDTPTR DQ ? ; location of calling routine IDTPTR DQ ? ; IDT descriptor USER_DS DQ ? ; data segment descriptor USER_ES DQ ? ; extra segment descriptor USER_SS DQ ? ; stack segment descriptor USER_CS DQ ? ; code segment descriptor BIOS_CS DQ ? ; BIOS code descriptor (all 0's) GDT ENDS  Output: AH = 0 - successful CF = 1 & ZF = 0 & AH = FFh - gate address line 20 failed  Note: IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  AH = 90h - Device Busy Loop  Input: AL = type code 00-7Fh = serially reusable devices; operating system must serialize access 80-BFh = reentrant devices; ES:BX is used to distinguish calls (multiple i/o calls are allowed simultaneously)

Page 35: BIOS and DOS Interrupts

C0-FFh = wait only calls; these are timeout dependent. times are function number dependent e.g. 00h = disk (timeout) 01h = diskette (timeout) 02h = keyboard (no timeout) 80h = network (no timeout) ES:BX --> NCB FDh = diskette motor start (timeout) FEh = printer (timeout)  Output: CF = 0 & AH = 0 - successful  Note: IBM AT: MOV AX,0 ! CLC ! RET 2 (BIOS 01/10/84) IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command AH = 91h - Interrupt Complete Flag Set  Input: AL = type code as described for AH = 90h above  Output: Flags restored, AX = 0  Note: IBM AT: MOV AX,0 ! IRET (BIOS 01/10/84) IBM PC: CF = 1 & AH = 80h - undefined operation IBM XT & M24: CF = 1 & AH = 86h - bad command  INT 16h - Keyboard I/P (Technical References: IBM AT - KEYBOARD 5-115 @ KEYBOARD_IO IBM PC - A-23 @ E82Eh IBM XT - System BIOS A-24 @ E82Eh Olivetti M24 - D-114 & E82Eh) AH = 00h - Read the next key struck from the keyboard 01h - Return 'key struck' status of keyboard 02h - Return current shift status of keyboard  AH = 00 - Read the next key struck into AX  Input: None Output: AH = scan code AL = character code  AH = 01h - Return 'key struck' status of keyboard 

Page 36: BIOS and DOS Interrupts

Input: None  Output: ZF = 1 - no code available ZF = 0 - code is available and is returned in AX AX = scan code & character code as above. The keyboard buffer is not altered  AH = 02h - Return current shift status of keyboard  Input: None  Output: AL = shift status bit# 7 - insert state active bit# 6 - Caps Lock toggled bit# 5 - Num Lock toggled bit# 4 - Scroll Lock toggled bit# 3 - Alt shift key depressed bit# 2 - Ctrl shift key depressed bit# 1 - left Shift key depressed bit# 0 - right Shift key depressed  INT 17h - Parallel Printer O/P (Technical References: IBM AT - PRINTER 5-123 @ PRINTER_IO IBM PC - A-42 @ EFD2h IBM XT - System BIOS A-44 @ EFD2h Olivetti M24 - D-144 & EFD2h) AH = 00h - Print the character in AL 01h - Initialize the printer port 02h - Read the printer status into AH  AH = 00 - Print the character in AL  Input: AL = character to send DX = printer to use (0-2) Output: AH = 1 if character could not be printed AH <> 1 = current status  Note: The IBM allow 3 printer ports, Olivetti, 4  AH = 01h - Initialize the printer port  Input: DX = printer # (0-2)

Page 37: BIOS and DOS Interrupts

  Output: AH = printer status  AH = 02h - Read the printer status into AH  Input: DX = printer # (0-2)  Output: AH = printer status byte bit# 0 - time out bit#s 1 & 2 - unused bit# 3 - i/o error (NOT pin 15) bit# 4 - selected (pin 13) bit# 5 - out of paper (pin 12) bit# 6 - acknowledge (NOT pin 10) bit# 7 - not busy (NOT pin 11)  Note: 'Good' statuses are 90h & 10h if a printer is connected, 30h if printer is disconnected.  INT 1Ah - Time of Day (Technical References: IBM AT - BIOS 2 5-159 @ TIME_OF_DAY IBM PC - A-77 @ FE6Eh IBM XT - System BIOS A-79 @ FE6Eh Olivetti M24 - D-188 & FE6Eh) AH = 00h - Read the Current Clock Setting 01h - Set the Current Clock 02h - Read the Real Time Clock (IBM AT only) 03h - Set the Real Time Clock (IBM AT only) 04h - Read the Date (IBM AT only) 05h - Set the Date (IBM AT only) 06h - Set the Alarm (IBM AT only) 07h - Reset the Alarm (IBM AT only) FEh - Read Clock Calendar Device (M24 only) FFh - Write Clock Calendar Device (M24 only)  AH = 00 - Read the Current Clock Setting  Input: None  Output: AL <> 0 if timer has passed 24 hours since last read CX = high portion of count DX = low portion of count Note: Counts occur at 1193180/65536 counts/sec (18.2 per sec)

Page 38: BIOS and DOS Interrupts

INT 1Ch is accessed at each count AH = 01h - Set the Current Clock  Input: CX = high portion of count DX = low portion of count  Output: None  AH = 02h - Read the Real Time Clock (IBM AT only)  Input: None  Output: CF = 0, CH = hours in BCD CL = minutes in BCD DH = seconds in BCD CF = 1 - clock not operating  Note: NOP for IBM PC, XT & M24  AH = 03h - Set the Real Time Clock (IBM AT only)  Input: CH = hours in BCD CL = minutes in BCD DH = seconds in BCD DL = 1 if daylight savings time option, else 0  Output: None  Note: NOP for IBM PC, XT & M24  AH = 04h - Read the Date (IBM AT only)  Input: None  Output: CF = 0, CH = 19 or 20, century in BCD CL = year in BCD DH = month in BCD DL = day in BCD CF = 1 - clock not operating  Note: NOP for IBM PC, XT & M24  AH = 05h - Set the Date (IBM AT only)  Input: CH = century in BCD (19 or 20) CL = year in BCD

Page 39: BIOS and DOS Interrupts

DH = month in BCD DL = day in BCD  Output: None  Note: NOP for IBM PC, XT & M24  AH = 06h - Set the Alarm (IBM AT only)  Input: CH = hours in BCD CL = minutes in BCD DH = seconds in BCD Set alarm vector in INT 4Ah  Output: CF = 0 - alarm set CF = 1 - clock not operating or alarm already set  Note: NOP for IBM PC, XT & M24  AH = 07h - Reset the Alarm (IBM AT only)  Input: None  Output: None  Note: NOP for IBM PC, XT & M24  AH = FEh - Read Clock Calendar Device (M24 only)  Input: None  Output: BX = day from 1-1 of leap year up to 12-31 of leap year+7 CH = hour CL = minutes DH = seconds DL = hundredths of seconds  Note: Resets Alarm in IBM AT NOP for IBM PC, XT  AH = FFh - Write Clock Calendar Device (M24 only)  Input: BX = day from 1-1 of leap year up to 12-31 of leap year+7 CH = hour (0-23) CL = minutes (0-59)  Output: AH = -1 - date time error

Page 40: BIOS and DOS Interrupts

= 0 - date time OK  Note: Resets Alarm in IBM AT NOP for IBM PC, XT  INT 1Ch - Timer Tick Interrupt (Technical References: IBM AT - BIOS 2 5-162 IBM PC - A-78 @ FEE9h IBM XT - System BIOS A-79 @ FEE3h Olivetti M24 - D-190 & FEE2h) This interrupt is called every time the time of day clock 'ticks' (approximately 18.2 Hz). The 8259 PIC is not sent an End of Interrupt until the IRET from this routine. Care should be taken to save the current INT 1Ch vector and chain to it after the service routine is finished.  INT 4Ah - Alarm Interrupt (IBM AT) (Technical References: IBM AT - BIOS 2 5-159) This interrupt is called when the Real Time Clock alarm is set off. The alarm should be reset before the IRET. 

Page 41: BIOS and DOS Interrupts