Make your own free website on Tripod.com

Prev TOP HOME


Learning about BIOS and the hardware

You can't do everything with DOS calls. You may need to learn something about the BIOS and about the hardware itself. In this, the Technical Reference is a very good thing to look at.

The first thing you look at in the Technical Reference, unless you are really determined to master the whole ball of wax, is the BIOS listings presented in Appendix A. Glory be: here is the whole 8K of ROM which deals with low level hardware support layed out with comments and everything.

In fact, if you are just interested in learning what BIOS can do for you, you just need to read the header comments at the beginning of each section of the listing.

BIOS services are invoked by means of the INT instruction; the BIOS occupies interrupts 10H through 1FH and also interrupt 5H; actually, of these seventeen interrupts, five are used for user exit points or data pointers, leaving twelve actual services.

In most cases, a service deals with a particular hardware interface; for example, BIOS interrupt 10H deals with the screen. As with DOS function calls, many BIOS services can be passed a function code in the AH register and possible other arguments.

I am not going to summarize the most useful BIOS features here; you will see some examples in the next sample program we will look at.

The other thing you might want to get into with the Tech reference is the description of some hardware options, particularly the asynch adapter, which are not well supported in the BIOS. The writeup on the asynch adapter is pretty complete.

Actually, the Tech reference itself is pretty complete and very nice as far as it goes. One thing which is missing from the Tech reference is information on the programmable peripheral chips on the system board. These include

the 8259 interrupt controller
the 8253 timer
the 8237 DMA controller and
the 8255 peripheral interface

To make your library absolutely complete, you should order the INTEL data sheets for these beasts.

I should say, though, that the only I ever found I needed to know about was the interrupt controller. If you happen to have the 8086 Family User's Manual, the big book put out by INTEL, which is one of the things people sometimes buy to learn about 8086 architecture, there is an appendix there which gives an adequate description of the 8259.

A final example

I leave you with a more substantial example of code which illustrates some good elementary techniques; I won't claim its style is perfect, but I think it is adequate. I think this is a much more useful example than what you will get with the assembler:

PAGE 61,132
TITLE SETSCRN -- Establish correct monitor use at boot time
;
; This program is a variation on many which toggle the equipment flags
; to support the use of either video option (monochrome or color).
; The thing about this one is it prompts the user in such a way that he
; can select the use of the monitor he is currently looking at (or which
; is currently connected or turned on) without really having to know
; which is which. SETSCRN is a good program to put first in an
; AUTOEXEC.BAT file.
;
; This program is highly dependent on the hardware and BIOS of the IBMPC
; and is hardly portable, except to very exact clones. For this reason,
; BIOS calls are used in lieu of DOS function calls where both provide
; equal function.
;


OK. That's the first page of the program. Notice the PAGE statement, which you can use to tell the assembler how to format the listing. You give it lines per page and characters per line. I have mine setup to print on the host lineprinter; I routinely upload my listings at 9600 baud and print them on the host; it is faster than using the PC printer.

There is also a TITLE statement. This simply provides a nice title for each page of your listing. Now for the second page:

SUBTTL -- Provide .COM type environment and Data
PAGE
;
; First, describe the one BIOS byte we are interested in
;
BIOSDATA SEGMENT AT 40H ;Describe where BIOS keeps his data
ORG 10H ;Skip parts we are not interested in
EQUIP DB ? ;Equipment flag location
MONO EQU 00110000B ;These bits on if monochrome
COLOR EQU 11101111B ;Mask to make BIOS think of the color board
BIOSDATA ENDS ;End of interesting part
;
; Next, describe some values for interrupts and functions
;
DOS EQU 21H ;DOS Function Handler INT code
PRTMSG EQU 09H ;Function code to print a message
KBD EQU 16H ;BIOS keyboard services INT code
GETKEY EQU 00H ;Function code to read a character
SCREEN EQU 10H ;BIOS Screen services INT code
MONOINIT EQU 02H ;Value to initialize monochrome screen


IBM PC Assembly Language Tutorial 25

;COLORINIT EQU 03H ;Value to initialize color screen (80x25)
COLORINIT EQU 01H ;Value to initialize color screen (40X25)
;
; Now, describe our own segment
;
SETSCRN SEGMENT ;Set operating segment for CODE and DATA
;
ASSUME CS:SETSCRN,DS:SETSCRN,ES:SETSCRN,SS:SETSCRN ;All segments
;
ORG 100H ;Begin assembly at standard .COM offset
;
MAIN PROC NEAR ;COM files use NEAR linkage
JMP BEGIN ;And, it is helpful to put the data first, but
; ;then you must branch around it.
;
; Data used in SETSCRN
;
CHANGELOC DD EQUIP ;Location of the EQUIP, recorded as far pointer
MONOPROMPT DB 'Please press the plus ( + ) key.$' ;User sees on mono
COLORPROMPT DB 'Please press the minus ( - ) key.$' ;User sees on color


Several things are illustrated on this page. First, in addition to titles, the assembler supports subtitles: hence the SUBTTL pseudo-op. Second, the PAGE pseudo-op can be used to go to a new page in the listing. You see an example here of the DSECT-style segment in the "SEGMENT AT 40H". Here, our our interest is in correctly describing the location of some data in the
BIOS work area which really is located at segment 40H.

You will also see illustrated the EQU instruction, which just gives a symbolic name to a number. I don't make a fetish of giving a name to every single number in a program. I do feel strongly, though, that interrupts and function codes, where the number is arbitrary and the function being performed is the thing of interest, should always be given symbolic names.

One last new element in this section is the define doubleword (DD) instruction. A doubleword constant can refer, as in this case, to a location in another segment. The assembler will be happy to use information at its disposal to properly assemble it. In this case, the assembler knows that EQUIP is offset 10 in the segment BIOSDATA which is at 40H.

SUBTTL -- Perform function
PAGE
BEGIN: CALL MONOON ;Turn on mono display
MOV DX,OFFSET MONOPROMPT ;GET MONO PROMPT
MOV AH,PRTMSG ;ISSUE
INT DOS ;IT
CALL COLORON ;Turn on color display
MOV DX,OFFSET COLORPROMPT ;GET COLOR PROMPT
MOV AH,PRTMSG ;ISSUE
INT DOS ;IT
MOV AH,GETKEY ;Obtain user response
INT KBD
CMP AL,'+' ;Does he want MONO?
JNZ NOMONO
CALL MONOON ;yes. give it to him
NOMONO: RET
MAIN ENDP


The main code section makes use of subroutines to keep the basic flow simple. About all that's new to you in this section is the use of the BIOS interrupt KBD to read a character from the keyboard.

Now for the subroutines, MONOON and COLORON:

SUBTTL -- Routines to turn monitors on
PAGE
MONOON PROC NEAR ;Turn mono on
LES DI,CHANGELOC ;Get location to change
ASSUME ES:BIOSDATA ;TELL ASSEMBLER ABOUT CHANGE TO ES
OR EQUIP,MONO
MOV AX,MONOINIT ;Get screen initialization value
INT SCREEN ;Initialize screen
RET
MONOON ENDP
COLORON PROC NEAR ;Turn color on
LES DI,CHANGELOC ;Get location to change
ASSUME ES:BIOSDATA ;TELL ASSEMBLER ABOUT CHANGE TO ES
AND EQUIP,COLOR
MOV AX,COLORINIT ;Get screen initialization value
INT SCREEN ;Initialize screen
RET
COLORON ENDP
SETSCRN ENDS ;End of segment
END MAIN ;End of assembly; execution at MAIN


The instructions LES and LDS are useful ones for dealing with doubleword addresses. The offset is loaded into the operand register and the segment into ES (for LES) or DS (for LDS). By telling the assembler, with an ASSUME, that ES now addresses the BIOSDATA segment, it is able to correctly assemble the OR and AND instructions which refer to the EQUIP byte. An ES
segment prefix is added.

To understand the action here, you simply need to know that flags in that particular byte control how the BIOS screen service initializes the adapters. BIOS will only work with one adapter at a time; by setting the equipment flags to show one or the other as installed and calling BIOS screen initialization, we achieve the desired effect.

The rest is up to you.