Instruction: int 14h BIOS Operation: Access the serial communications port Parameters: ax, dx
The IBM BIOS supports up to four different serial communications ports (the hardware supports up to eight). In general, most PCs have one or two serial ports (COM1: and COM2:) installed. Int 14h
supports four subfunctions- initialize, transmit a character, receive a character, and status. For all four services, the serial port number (a value in the range 0..3) is in the dx
register (0=COM1:, 1=COM2:, etc.). Int 14h
expects and returns other data in the al
or ax
register.
al
register using the following bit encodings:Bits Function 5..7 Select baud rate 000- 110 baud 001- 150 010- 300 011- 600 100- 1200 101- 2400 110- 4800 111- 9600 3..4 Select parity 00- No parity 01- Odd parity 10- No parity 11- Even parity 2 Stop bits 0-One stop bit 1-Two stop bits 0..1 Character Size 10- 7 bits 11- 8 bits
Although the standard PC serial port hardware supports 19,200 baud, some BIOSes may not support this speed.
Example: Initialize COM1: to 2400 baud, no parity, eight bit data, and two stop bits-
mov ah, 0 ;Initialize opcode mov al, 10100111b ;Parameter data. mov dx, 0 ;COM1: port. int 14h
After the call to the initialization code, the serial port status is returned in ax
(see Serial Port Status, ah
=3, below).
al
register through the serial port specified in the dx
register. On return, if ah
contains zero, then the character was transmitted properly. If bit 7 of ah
contains one, upon return, then some sort of error occurred. The remaining seven bits contain all the error statuses returned by the GetStatus
call except time out error (which is returned in bit seven). If an error is reported, you should use subfunction three to get the actual error values from the serial port hardware.mov dx, 0 ;Select COM1: mov al, 'a' ;Character to transmit mov ah, 1 ;Transmit opcode int 14h test ah, 80h ;Check for error jnz SerialError
This function will wait until the serial port finishes transmitting the last character (if any) and then it will store the character into the transmit register.
dx
contains the serial port number. On exit, al
contains the character read from the serial port and bit seven of ah
contains the error status. When this routine is called, it does not return to the caller until a character is received at the serial port.mov dx, 0 ;Select COM1: mov ah, 2 ;Receive opcode int 14h test ah, 80h ;Check for error jnz SerialError <Received character is now in AL>
dx
register contains the serial port number. On exit, the ax
register contains the following values:AX: Bit Meaning 15 Time out error 14 Transmitter shift register empty 13 Transmitter holding register empty 12 Break detection error 11 Framing error 10 Parity error 9 Overrun error 8 Data available 7 Receive line signal detect 6 Ring indicator 5 Data set ready (DSR) 4 Clear to send (CTS) 3 Delta receive line signal detect 2 Trailing edge ring detector 1 Delta data set ready 0 Delta clear to send
There are a couple of useful bits, not pertaining to errors, returned in this status information. If the data available bit is set (bit #8), then the serial port has received data and you should read it from the serial port. The Transmitter holding register empty bit (bit #13) tells you if the transmit operation will be delayed while waiting for the current character to be transmitted or if the next character will be immediately transmitted. By testing these two bits, you can perform other operations while waiting for the transmit register to become available or for the receive register to contain a character.
If you're interested in serial communications, you should obtain a copy of Joe Campbell's C Programmer's Guide to Serial Communications. Although written specifically for C programmers, this book contains a lot of information useful to programmers working in any programming language. See the bibliography for more details.
int 15h
provided cassette tape read and write services[1]. Almost immediately, everyone realized that cassettes were history, so IBM began using int 15h
for many other services. Today, int 15h
is used for a wide variety of function including accessing expanded memory, reading the joystick/game adapter card, and many, many other operations. Except for the joystick calls, most of these services are beyond the scope of this text. Check on the bibliography if you interested in obtaining information on this BIOS call.
Instruction: int 16h BIOS Operation: Read a key, test for a key, or get keyboard status Parameters: al
The IBM PC BIOS provides several function calls dealing with the keyboard. As with many of the PC BIOS routines, the number of functions has increased over the years. This section describes the three calls that were available on the original IBM PC.
int 16h
is called with ah
equal to zero, the BIOS will not return control to the caller until a key is available in the system type ahead buffer. On return, al
contains the ASCII code for the key read from the buffer and ah
contains the keyboard scan code. Keyboard scan codes are described in the appendices.int 16h
returns a zero in al
and the keyboard scan code in ah
. Therefore, whenever an ASCII code of zero is returned, you must check the ah
register to determine which key was pressed.int 16h
call does not echo the key pressed to the display. You have to call putc
or use int 10h
to print the character once you've read it if you want it echoed to the screen.ReadLoop: mov ah, 0 ;Read Key opcode int 16h cmp al, 0 ;Special function? jz ReadLoop ;If so, don't echo this keystroke putc cmp al, 0dh ;Carriage return (ENTER)? jne ReadLoop
int 16h
subfunction allows you to check to see if a key is available in the system type ahead buffer. Even if a key is not available, control is returned (right away!) to the caller. With this call you can occasionally poll the keyboard to see if a key is available and continue processing if a key hasn't been pressed (as opposed to freezing up the computer until a key is pressed).ax
will contain the scan and ASCII codes for that key. However, this function will not remove that keystroke from the typeahead buffer. Subfunction #0 must be used to remove characters. The following example demonstrates how to build a random number generator using the test keyboard function:; First, clear any characters out of the type ahead buffer ClrBuffer: mov ah, 1 ;Is a key available? int 16h jz BufferIsClr ;If not, Discontinue flushing mov ah, 0 ;Flush this character from the int 16h ; buffer and try again. jmp ClrBuffer BufferIsClr: mov cx, 0 ;Initialize "random" number. GenRandom: inc cx mov ah, 1 ;See if a key is available yet. int 16h jz GenRandom xor cl, ch ;Randomize even more. mov ah, 0 ;Read character from buffer int 16h ; Random number is now in CL, key pressed by user is in AX
While waiting for a key, this routine is constantly incrementing the cx
register. Since human beings cannot respond rapidly (at least in terms of microseconds) the cl
register will overflow many times, even for the fastest typist. As a result, cl
will contain a random value since the user will not be able to control (to better than about 2ms) when a key is pressed.
al
register. The values returned are as follows:Bit Meaning 7 Insert state (toggle by pressing INS key) 6 Caps lock (1=capslock on) 5 Num lock (1=numlock on) 4 Scroll lock (1=scroll lock on) 3 Alt (1=Alt key currently down) 2 Ctrl (1=Ctrl key currently down) 1 Left shift (1=left shift key down) 0 Right shift (1=right shift key down)
Due to a bug in the BIOS code, these bits only reflect the current status of these keys, they do not necessarily reflect the status of these keys when the next key to be read from the system type ahead buffer was depressed. In order to ensure that these status bits correspond to the state of these keys when a scan code is read from the type ahead buffer, you've got to flush the buffer, wait until a key is pressed, and then immediately check the keyboard status.
Instruction: int 17h BIOS Operation: Print data and test the printer status Parameters: ax, dx
Int 17h
controls the parallel printer interfaces on the IBM PC in much the same way the int 14h
controls the serial ports. Since programming a parallel port is considerably easier than controlling a serial port, using the int 17h
routine is somewhat easier than using the int 14h
routines.
Int 17h
provides three subfunctions, specified by the value in the ah
register. These subfunctions are:
0-Print the character in the AL register.
1-Initialize the printer.
2-Return the printer status.
Each of these functions is described in the following sections.
Like the serial port services, the printer port services allow you to specify which of the three printers installed in the system you wish to use (LPT1:, LPT2:, or LPT3:). The value in the dx
register (0..2) specifies which printer port is to be used.
One final note- under DOS it's possible to redirect all printer output to a serial port. This is quite useful if you're using a serial printer. The BIOS printer services only talk to parallel printer adapters. If you need to send data to a serial printer using BIOS, you'll have to use int 14h
to transmit the data through a serial port.
ah
is zero when you call int 17h
, then the BIOS will print the character in the al
register. Exactly how the character code in the al
register is treated is entirely up to the printer device you're using. Most printers, however, respect the printable ASCII character set and a few control characters as well. Many printers will also print all the symbols in the IBM/ASCII character set (including European, line drawing, and other special symbols). Most printers treat control characters (especially ESC sequences) in completely different manners. Therefore, if you intend to print something other than standard ASCII characters, be forewarned that your software may not work on printers other than the brand you're developing your software on.int 17h
subfunction zero routine, the ah
register contains the current status. The values actually returned are described in the section on subfunction number two.
ah
register contains the printer status as per function number two.
ah
register. The values returned are:AH: Bit Meaning 7 1=Printer busy, 0=printer not busy 6 1=Acknowledge from printer 5 1=Out of paper signal 4 1=Printer selected 3 1=I/O error 2 Not used 1 Not used 0 Time out error
Acknowledge from printer is, essentially, a redundant signal (since printer busy/not busy gives you the same information). As long as the printer is busy, it will not accept additional data. Therefore, calling the print character function (ah
=0) will result in a delay.
The out of paper signal is asserted whenever the printer detects that it is out of paper. This signal is not implemented on many printer adapters. On such adapters it is always programmed to a logic zero (even if the printer is out of paper). Therefore, seeing a zero in this bit position doesn't always guarantee that there is paper in the machine. Seeing a one here, however, definitely means that your printer is out of paper.
The printer selected bit contains a one as long as the printer is on-line. If the user takes the printer off-line, then this bit will be cleared.
The I/O error bit contains a one if some general I/O error has occurred.
The time out error bit contains a one if the BIOS routine waited for an extended period of time for the printer to become "not busy" yet the printer remained busy.
Note that certain peripheral devices (other than printers) also interface to the parallel port, often in addition to a parallel printer. Some of these devices use the error/status signal lines to return data to the PC. The software controlling such devices often takes over the int 17h
routine (via a technique we'll talk about later on) and always returns a "no error" status or "time out error" status if an error occurs on the printing device. Therefore, you should take care not to depend too heavily on these signals changing when you make the int 17h
BIOS calls.
Instruction: int 18h BIOS Operation: Activate ROM BASIC Parameters: None
Executing int 18h
activates the ROM BASIC interpreter in an IBM PC. However, you shouldn't use this mechanism to run BASIC since many PC compatibles do not have BASIC in ROM and the result of executing int 18h
is undefined.
Instruction: int 19h BIOS Operation: Restart the system Parameters: None
Executing this interrupt has the same effect as pressing control-alt-del on the keyboard. For obvious reasons, this interrupt service should be handled carefully!
Instruction: int 1ah BIOS Operation: Real time clock services Parameters: ax, cx, dx
There are two services provided by this BIOS routine- read the clock and set the clock. The PC's real time clock maintains a counter that counts the number of 1/18ths of a second that have transpired since midnight. When you read the clock, you get the number of "ticks" which have occurred since then. When you set the clock, you specify the number of "ticks" which have occurred since midnight. As usual, the particular service is selected via the value in the ah
register.
ah
= 0, then int 1ah
returns a 33-bit value in al:cx:dx
as follows:Reg Value Returned dx L.O. word of clock count cx H.O. word of clock count al Zero if timer has not run for more than 24 hours Non-zero otherwise.
The 32-bit value in cx:dx
represents the number of 55 millisecond periods which have elapsed since midnight.
cx:dx
contains the current count (in 55ms increments) since last midnight. Cx
contains the H.O. word, dx
contains the L.O. word.