[Front] [Prev Chapter] [Next Chapter]

Chapter 7 The DR-DOS BIOS

Structure of the BIOS

Building the BIOS

Use of ROM BIOS in the DR-DOS Sample BIOS


This chapter describes sample BIOS files and utilities that are supplied only with a Caldera DR-DOS OEM System Builder Kit or developer kit. However, the information may also be useful to programmers, and is included here for completeness.

The BIOS contains the resident device drivers which interface DR-DOS with the hardware of the computer.There are two logical components of the DR-DOS BIOS file. These are the BIOSINIT and the resident drivers. The physical files are assembled and linked to form the file IBMBIO.COM.

7.1 Structure of the BIOS

Undisplayed Graphic

Figure 7-1
Structure of the IBMBIO.COM File

The sample BIOS supplied with the DR-DOS System Builder Kit is for the IBM PS2/AT/XT/PC or compatible machine. This chapter will refer to this BIOS to give examples but the comments will be relevant to other hardware. The actions required to build the BIOS depend on the type of hardware to be used. The following subsections describe the actions required in the three possible cases.

Using theSample BIOS for an IBM PS2/AT/XT/PC or Compatible Computer

For an IBM PS2/AT/XT/PC or compatible computer the sample BIOS will work without modification. You may wish, however, to add features to this BIOS by modifying the resident device drivers. The sample BIOS uses the ROM BIOS interrupts supplied on the machine and described in its technical handbook. It will therefore operate on as many machines in the range as possible. A list of the ROM BIOS functions currently used by the sample BIOS is given in Table 7.1, in Section 7.3, Use of ROM BIOS in the DR-DOS Sample BIOS.

Using the Sample BIOS to Run Common PC Applications on a Non-compatible Computer

For a computer that is not a compatible, but on which some PC applications are to run, it is best to write hardware dependent routines that emulate the ROM BIOS functions. You should ensure that you implement all the functions used by the sample BIOS and by the DOS applications that will be used on the computer. A list of these functions is given in Table 7.1 in section 7.3, Use of ROM BIOS in the DR-DOS Sample BIOS.

The replacement ROM BIOS may be linked with the BIOS or be part of the power-on ROM. It should be initialized first after power on or reset and will then set up the software interrupt vectors used by the sample BIOS.

Using the Sample BIOS for a Non-compatible Computer that is not to Run Common PC Applications

If there is no requirement to run PC applications it may be easier to write resident device drivers to the device driver interface specification using the sample BIOS as a guide. These device drivers may then be linked to the BIOSINIT object file in place of the sample drivers, to make the IBMBIO.COM file.

The sample BIOS provides drivers for the hard disk, floppy disk, console, printer, clock and serial port of the IBM PS2/AT/XT/PC and compatible range of computers. These are supplied in source form. A small amount of code is also required to set some initial global values before passing control to the BIOSINIT module.

7.2 Building the BIOS

The sample BIOS consists of a number of assembler sources and object files. To create the file the sources are assembled and all objects are linked to form a.EXE type file. This file is further processed using the EXE2BIN utility to form a binary image file named IBMBIO.COM. The INIT module must be linked first and the BIOSEND module must be the last of the resident driver code. The generic BIOSINIT modules are also linked in but assembler statements are used to ensure that the BIOSINIT code and data are correctly positioned last. A batch file is provided to demonstrate building the BIOS and to illustrate the correct link sequence.

Sections 7.2.1 to 7.2.6 describe in detail the modules supplied for the sample BIOS for the IBM PS2/AT/XT/PC and compatible computers.

7.2.1 INI module (INIT.ASM)

The INIT module is the first code in the BIOS to be executed after the bootstrap procedure has loaded the IBMBIO.COM file into memory. The number of the disk drive used for booting is passed to the INIT module in register DL. It is used to indicate the drive from which to load the rest of DR-DOS. The value held in register DL is passed on to the BIOSINIT module. For a floppy disk drive the number is 00H, 01H, and so on, and for a hard disk the top bit is set so the drives are numbered 80H, 81H, and so on.

The INIT code sets various global BIOS values depending on the physical hardware. These values are described in section 7.4, BIOSINIT Module.

The current ROMBIOS diskette drive parameters are copied to the ROM BIOS data area and the number of sectors is set to 18 (max number required for 1.44 Mbyte media). The INIT module relocates the device driver headers by setting the segment values to the BIOS segment. The global entry point cleanup is provided in the INIT module and is called by the BIOSINIT code after all the drivers and the BDOS are initialized. In the sample BIOS, this entry is not used and is just a return far instruction. Control is now passed to the generic BIOSINIT module via a near jump to BIOSINIT.

If a ROM system is required INIT must be modified to set current_DOS to the location in ROM of the IBMBIO.COM file. The init_flags byte should be set to indicate a ROM-based system.

7.2.2 CONSOLE module (CONSOLE.ASM)

The console driver initialization routine installs the fast console output entry point at Interrupt 29H and the control break interrupt 1BH. If a control break interrupt occurs a CTRL-C character is placed in the one byte local buffer.

The INPUT function repeatedly calls a read character routine until the request is satisfied, that is, the requested number of characters has been returned. The read character routine tests the local buffer. If a character is present it is returned and the buffer cleared, otherwise the ROM BIOS is called to read a character.

If the character is CTRL-Print screen a CTRL-P is returned. If the character is an extended (2 byte) character the second byte (scan code) is placed in the local buffer and the first byte returned.

The TEST STATUS and INPUT NON-DESTRUCTIVE routines test the status of the local buffer and if necessary call the ROM BIOS. In the case of TEST STATUS a true/false value is returned. For the INPUT NON- DESTRUCTIVE function a character will be returned but the character is not removed from the buffer or ROM BIOS.

The INPUT FLUSH reads characters until no more are available. The OUTPUT routine sends all characters in the buffer to the ROM BIOS using the “normal” attribute.

The FAST CONSOLE routine called from Interrupt 29H outputs the character to the ROM BIOS in the same way but preserves registers. OUTPUT STATUS, FLUSH, OPEN, CLOSE and GENIOCTL are no-operations and return good status.

7.2.3 CLOCK module (CLOCK.ASM)

The INITIALIZATION routine attempts to read the real time clock via the ROM BIOS interrupt. If the machine does not support a real time clock then a default date is used. The day, month and year format is then converted to the standard binary value for the date used in DR-DOS.

The INPUT function is used by the BDOS to read the current time and date. The 32-bit tick count is read from hardware using a ROM BIOS interrupt. This is then converted to the appropriate number of hundredths, seconds, minutes, hours and days. The 6-byte packet containing this information is then transferred to the input buffer. The day is in the form of a word giving the number of days since the first of January 1980.

The OUTPUT function reads the same 6 bytes of data from the output buffer. This information is then converted to Binary Coded Decimal values and the ROM BIOS interrupt used to set the date and time on machines that have a real time clock. The 32-bit number of ticks is also computed and this is used to set the system timer using another ROM BIOS interrupt.

7.2.4 SERPAR module (SERPAR.ASM)

The serial and parallel port drivers are combined in one device driver module. This has device headers for all the devices but uses common code for all the supported functions. The interrupt entry for each device just sets a device number into a variable before jumping to a common routine to process the function. Each function is common until the point at which the ROM BIOS is called when the device number is used to invoke the appropriate routine.

Initialization consists of a single ROM BIOS interrupt for all devices. The port number is 0, 1 or 2 for the printer and 3 to n for the COM ports. The serial ports are set to 2400 baud, No parity, 8 data bits and one stop bit. The PRN and AUX device are mapped to LPT1 and COM1 so these ports are initialized twice.

The input routines are only appropriate for the serial ports and are the same as those described for the console except that there are no special cases for any returned characters. The output routines branch to ROM BIOS interrupts either to the parallel or the serial port. Status testing for output tests the ready bit in the case of the printer. For the serial ports the transmit, buffer empty and data set ready flags are tested. As with the console module OUTPUT FLUSH, OPEN, CLOSE and GENERIC IOCTL are no-operations and return good status.

7.2.5 DISK module (DISK.ASM)

The DISK module contains the code to support both hard disks and diskettes. It supports the following diskette drive types available on the PS2/AT/XT/PC or compatible machines:

The interface to the hardware is via the ROM BIOS software interrupt (13H). The ROM BIOS is used for all disk functions and allowance is made for the new functions available on later releases of computers.

The strategy entry is used to store the address of the request packet. The interrupt entry tests the function is in the correct range and then branches via a table to the appropriate routine.

The driver supports both hard disks and diskettes, and a table is used to translate the logical drive A:, B: , and so on, into the correct physical drive number.

The INIT function is only required once during the BIOS initialization and is called from the BIOSINIT module. The code for this function is placed in the INIT group so that the space occupied can be recovered. Diskette drives are initialized first followed by the hard disks. If only one diskette drive is available then a “virtual drive” is created that uses the same physical drive. The BIOS prompts with messages to ensure that the correct disk is inserted in the drive. The functions GET/SET logical drive translate the logical unit number to the physical drive so that applications can work with the virtual drives.

The diskette initialization uses the ROM BIOS interrupt 11H to determine the number of drives. For each diskette drive a data structure is built containing all the variables associated with each drive (UDSC). This minimises the code and data overhead of the disk driver. The drive type is determined using the available ROM BIOS functions and will be one of the four types previously mentioned. The default and current BIOS Parameter Block (BPB) structures for this drive type are copied into the UDSC structure.

The hard disk initialization requires that the partition table of each hard disk be read into memory and decoded. Each partition of each disk is then allocated to a different logical drive starting from drive C:. If the partition type is not one of the types currently supported then the partition is skipped. They may be DOS extended partitions and may also have sector sizes other than the standard 512 bytes. The BPB is normally read from the partition. If for some reason it is found to be invalid then it is constructed using the partition size information following the same rules that the FDISK programme uses to initialize a partition. A UDSC structure is constructed for each partition as for each diskette.

The MEDIA CHECK function tests whether the drive is permanent. If the drive is not permanent, the media check uses the ROM BIOS function to determine whether the disk has been changed. If the disk has changed the function returns with this information. If the disk is unchanged, the boot sector is read to identify the media type. If there is no BPB in the sector 1, or if a disk error occurs or the media type is different, the function returns a value indicating that the disk may have changed. Otherwise the function returns a value indicating that the media has not changed.

For systems with no change line a simple 2 second timeout count is maintained after each drive I/O function. If the timer has reached zero the disk media may have changed, otherwise the function returns a value indicating that the media has not changed.

The BUILD BPB function for hard disks returns the BPB determined when the disk was logged. For diskettes, sector 0 is read into a local buffer. If the disk has a valid BPB on sector zero then this is copied to the UDSC structure and the function returns. For older disks that did not have the BPB on sector zero the function reads sector 2. If it is a FAT sector then the FATID byte is compared with the table of supported BPBs. If a match is found then this BPB is returned, otherwise a default BPB for that drive type is used.

The INPUT/OUTPUT and OUTPUT WITH VERIFY routines share common code for both diskette and hard disk. In both cases the ROM BIOS is called with parameters derived from the request packet and the disk offset information in the UDSC. If the transfer crosses a 64k boundary this sector is deblocked through a local buffer. This overcomes a restriction of the DMA controller on the series of machines. Up to 5 retries are attempted with a restore to cylinder 0 in between to improve track positioning. The verify function is called following a successful write if requested.

The device OPEN and CLOSE functions increment and decrement the UDSC open count. This count is zeroed whenever the disk is logged in. The removable media function returns the state of the UDSC hard disk flag for the appropriate logical drive.

The GENERIC IOCTL function supports get/set device parameters, read/write, format and verify. For get device parameters the values in the units UDSC are returned. If required, the media is relogged before the BPB is returned. In set device parameters the BPB may be set in the UDSC from the request packet. The layout table is initialized ready for a format using the data passed in the request packet. IOCTL read/write use the passed values to perform a read/write directly on the unit. The format function sets the data rate and drive parameters before using the ROM BIOS format function to format a track. After the format the VERIFY function is used to test for errors. On hard disks only the verify is performed. On diskettes, the layout table is updated for the correct cylinder and head. The sector and size data is not modified.

GET/SET LOGICAL DEVICE is for the virtual diskette drive. The request header passes a logical drive number. The GET LOGICAL DEVICE function returns the current physical drive number. The SET LOGICAL DRIVE function will modify the current physical drive value to the requested logical drive passed in the request packet. On read/write functions, if the physical drive does not match the requested logical drive the user is prompted to install the correct disk in the drive.


This module contains the directives necessary to group and position the segments of the DR-DOS BIOS correctly. The module must be linked as the first module before the hardware-dependent modules.

7.3 Use of ROM BIOS in the DR-DOS Sample BIOS

The following ROM BIOS interrupts are used by the sample BIOS. The table indicates the interrupt number, the module it is used in and the sub functions used. Note that some of the utilities such as FDISK, CHKDSK, GRAPHICS, GRAFTBL and MODE also use ROM BIOS interrupts as do many common applications. Also the utility KEYB is hardware dependent using the keyboard interrupt. No ROM BIOS interrupts are used by the part of the BIOS (BIOSINIT, BDOSLDR, CONFIG) which is designed to be hardware independent.

Table 7 1
ROM BIOS Interrupts




Subfunctions used



console, disk











0, 2, 3, 4, 5, 8, 16, 17, 18




0, 1, 2, 3



console, disk

0, 1




0, 1, 2




0, 1, 3, 4, 5






init, disk

In addition the ROM BIOS data area starting at 0:400 is also used in the BIOS modules. The two areas used are the dual_drive byte at location 0:500 - used for the virtual diskette drive and the diskette drive parameters at location 0:522.

7.4 BIOSINIT module

This module is hardware independent, and is supplied in object format. It is linked with the resident drivers to form the IBMBIO.COM file and consists of BIOSINIT, CONFIG, BDOSLDR and INITMSGS object files.

The BIOSINIT performs the following sequence of functions.

1. Relocates the BIOSINIT code and data to the top of the available memory and continues execution from there. The top of memory is defined by the mem_size variable initialized before the jump to BIOSINIT.

2. Makes a far call to each resident device driver entry point in turn to initialize it. The device drivers are linked in a chain and the first driver is located by the device_root double word initialized before the jump to BIOSINIT. After the last driver has been initialized the request packet contains the next available location in memory following the resident drivers.

3. Loads the IBMDOS.COM file depending on the values of two global words final_dos and current_dos that are set before BIOSINIT is started. If current_dos is zero then IBMDOS.COM is read from the root of the init_drv otherwise it is copied from the location defined by current_dos. When current_dos is non-zero it indicates that the file has been already loaded before BIOSINIT was entered or that the system is ROM-based. If final_dos is equal to current_dos then no move is performed.

4. Initializes the IBMDOS.COM file by a far call to offset 0 of the final_dos location.

5. Reads the CONFIG.SYS file from the root of the boot drive and interprets the command lines in it. This will load and initialize loadable device drivers and set system values. Data structures for all devices are now initialized in memory and buffers are allocated.

6. Calls the resident portion via the global cleanup to allow it to perform any final initialization.

7. Load the COMMAND processor file (default COMMAND.COM) from disk to the first available location in memory following the operating system and execute it.

The BIOSINIT and resident drivers are linked using PUBLIC and EXTERNAL declarations which are defined below.

Table 7 2
Declarations in BIOSINIT and Resident Drivers



Defined in





This is the entry point for the BIOSINIT module.




This word if zero indicates that the BMDOS.COM file should be read from disk, if it is not zero the BMDOS.COM has already been loaded or is ROM-based and exists at that segment location.




This word is the segment address at which the IBMDOS.COM file should be located. A value of zero forces the operating system kernel to be loaded immediately after the BIOS.




This word is set to the number of available paragraphs of memory from location 0:0.




This byte is set to the physical disk drive from which the BIOS was loaded. (A: = 0; B: = 1....). Default is A:. IBMDOS.COM, CONFIG.SYS and AUTOEXEC.BAT will use this drive.




This byte is set to the default number of disk buffers to be allocated.




This double word must be set to the offset and segment of the first resident driver of the linked list. The drivers are initializedin the order of the list.




This entry point is called after the BDOS is loaded to allow the resident driver to performany final initialization that requires BDOS function calls.




This is a character string containing the name of the BDOS file. The default value is “IBMDOS.COM”. The name is held in FCB format, for example “IO SYS” is valid, but “IO.SYS” is invalid.




This word is used to control the initialization code in BIOSINIT. The default value is 0.
Bit 0 = 0 RAM-resident BDOS. Move the code and data to final_dos.
= 1 ROM-resident BDOS code. Code is not relocated, data is relocated to final_dos.
Bit 1 = 0 comspec_drv is invalid - load the command processor from the root of init_drv.
= 1comspec_drv is valid - load the command processor from this drive. CONFIG.SYS and AUTOEXEC.BAT are still loaded from init_drv.




This specifies the drive from whichCOMMAND.COM can be loaded, ifdifferent from init_drive. This feature allows you to boot a system where COMMAND.COM is loaded from ROM disk, but AUTOEXEC.BAT and CONFIG.SYS are loaded from init_drive.

All global values defined above must be set before BIOSINIT is called.

[Front] [Prev Chapter] [Next Chapter]

Copyright © 1993, 1997 Caldera, Inc All rights reserved.