DOS System Architecture - Part 3


DOS was first introduced on floppy disks. Prior to the release of the original 10MB MFM-encoded hard drive with the IBM XT 5160, floppies were the only media the operating system used to boot the system and store data. There was no installation routine at this point in time. With the release of version 2.00 support for hard disk drives was added and DOS was thereafter found on two types of drive media.

Floppy disks were invented by Alan Shugart at IBM in 1967. The original disk size was eight inches. However for the purpose of DOS storage devices there are two: the 5.25" floppy and the 3.5" floppy. With the release of the IBM PC in 1981, only 5.25" floppy disks were in use for DOS. With the release of DOS version 3.30, the 3.5" floppy disk was introduced with a higher capacity and smaller footprint. Distribution media for DOS after version 3.30 was either on 5.25", 3.5", or both depending on the package.

The plastic disk inside the floppy cover is coated with ferric oxide and a binding agent to fix the material to the plastic. This substrate records electromagnetic flux from the read/write heads, which emit magnetic fields over the surface. These field impulses rearrange the oxide molecules into patterns that are permanently set until erased. Formatting the disk lays down tracks of concentric circles like a phonograph record and sectors that run perpendicular to the tracks much like cutting a round pie. The total number of sectors on the disk is determined by the number of tracks and the track layout. Since the center of the disk is smaller than the outside, the same number of sectors is formatted per track to maintain continuity.

Floppy disks come with a variety of storage capacities, which is measured by the number of sectors, sectors per track, number of tracks, and the number of recordable sides. Disks also came with two formatting options - hard sectored or soft sectored. Hard sectored disks were used early on with CP/M, meaning the media was pre-formatted and had several timing holes in it that the hardware used to determine the sector position. This as opposed to soft-sectored disks with DOS, whose media comes unformatted from the factory and the sector map is software controlled.

The actual encoding is done using MFM technology. Modified frequency modulation is a clocking algorithm. Because digital data is either 0 or 1, the encoding scheme inserts reversal fluxes on the media that designate the zero and one boundaries. Instead of using reversals after every bit to indicate a incremented sector position, it only inserts them between zeros only, since preceding 1's already indicate a reversal took place. This allows the encoding frequency to be reduced, thereby doubling the density of data storage. The disk format identifies individual sectors by number, and the encoding of data is mapped based on these indexes.

Communication with these devices is accomplished through the drivers for block devices found in the IO.SYS (or IBMBIO.COM) file or via installed software drivers supplied with the devices from the manufacturer. Each of these storage devices has a specific configuration, but all share a common unit of storage called sectors. DOS needs the sector size in bytes and the maximum number of sectors available on a given device. It can then make the geometric translation between physical and logical locations when reading and writing data using the block device drivers.

Programs that need access to these storage devices use the file system services found in the DOS Kernel (IBMDOS.COM or MSDOS.SYS). The media capacity of a given disk is based on the formula bytes per sector multiplied by sectors per track multiplied by tracks per side multiplied by the number of sides. The following floppy disk formats were supported over the product lifespan of DOS:


Single-sided,
single density
Form factor: 5.25" SS/SD
Sector Size: 512 bytes
Sectors per track: 8
Tracks per side: 40
Recordable sides: 1
Disk Capacity: 160k
(163,840)
Double-sided,
single density
Form factor: 5.25" DS/SD
Sector Size: 512 bytes
Sectors per track: 8
Tracks per side: 40
Recordable sides: 2
Disk Capacity: 320k (327,680)
Double-sided
double density
Form Factor: 5.25" DS/DD
Sector Size: 512 bytes
Sectors per track: 9
Tracks per side: 40
Recordable sides: 2
Disk Capacity: 360k (368,640)
Double-sided,
quad density
Form Factor: 5.25" DS/QD
Sector Size: 512 bytes
Sectors per track: 9
Tracks per side: 80
Recordable sides: 2
Disk Capacity: 720k (737,280 bytes)
Double-sided
high Density
Form Factor: 5.25" DS/HD
Sector Size: 512 bytes
Sectors per track: 15
Tracks per side: 80
Recordable sides: 2
Disk Capacity: 1.2Mb (1,228,800)
Double-sided
double density
Form Factor: 3.5" DS/DD
Sector Size: 512 bytes
Sectors per track: 9
Tracks per side: 80
Recordable sides: 2
Disk Capacity: 720k (737,280)
Double-sided
high density
Form Factor: 3.5" DS/HD
Sector Size: 512 bytes
Sectors per track: 18
Tracks per side: 80
Recordable sides: 2
Disk Capacity: 1.44Mb (1,474,560)

Hard Disks

IBM first invented hard disk storage in 1955, but it was not until 1980 that a product parallel to modern disk drives was developed. Once again, Alan Shugart at IBM (who left and started his own company Shugart Technology, which eventually became Seagate), released the first commercial disk drive with a 5MB capacity (the Seagate ST-506). IBM later went on to release the PC/XT with a 10MB MFM-encoded full-height drive that then led to 20 and 40MB sizes. The 3.5" half-height drives, also produced around the same time, became the standard replacing the ST-506 interface specification with IDE, which was easier to use for adding drives to the system. Drives by then were 80-120MB in size. By the time DOS 6.22 was released in 1994, disk capacities of 2GB were common.

In terms of assembly, most drives are the same with some noted variation. The drives consist of an aluminum housing with ceramic or aluminum platters stacked on a vertical spindle. These platters are coated with a ferric oxide laminate. A read/write head assembly is attached to a motor and sweeps through the disk stack to read data into a buffer on a controller board. The platters are divided into partitions using FDISK.EXE. Prior to DOS 3.30, the maximum partition size was 32MB. There are two types of partitions - primary and extended. A primary partition is an area of the disk that is bootable and priority enumerated. An extended partition is a non-bootable partition enumerated second. These are used to create logical drives. Four physical partitions and numerous logical drives from extended partitions can be created on a DOS-controlled drive.

Formatting the partitions maps the cylinders, tracks, and sectors magnetically across the platters. Data access is accomplished using the relative position pointers (binary magnetic addressing) to guide the read/write heads to the correct data location. Areas of each disk track that are physically located over or under the same point on other disks are grouped into logical cylinders. These are then divided into 512 byte sectors. The reading and writing of data was originally done with the outer sectors having a thinner bit density to keep the capacity uniform between larger-sized sectors and smaller ones near the middle. Later on came a technique called zone recording. Larger tracks on the outside of the platters are divided into groups depending on their distance from the center. Each group is a different size, and allows more efficient use of the outer track space by varying the density.

Because a cylinder is larger than a track, the read/write heads do not have to make multiple passes to use the data located in the outer sectors. This speeds up seek and access times significantly. Older drives were slower than more modern drives, and formatted the sectors with a skipping method called interleave. This defined the number of sectors to skip after the first one was read. This value was expressed by adding one for the read/write sector to the number of sectors skipped to equal the interleave factor. As drive speeds increased, interleave became less relevant and all later drives used a 1:1 sector access.

The first sector on the primary partition is called the Master Boot Record. This sector contains the information about all the partitions on the disk. It also has a small startup routine written to it that the BIOS initiates at system startup called the loader. The loader checks the partition information for a bootable operating system and hands off control to it, which then calls the software primitives in IO.SYS or IBMBIO.COM to initiate loading the kernel (refer to the Loading Sequence in the first section on Architecture).

Keyboards are the standard input device for the PC. All interrupts within DOS that handle input services assume a keyboard is the source unless a specific redirect has been issued through the console or an application. While the design has changed over the years, a typical keyboard has three groups of keys in common. Most functions are assumed to be part of the Interrupt 21H calls. Whenever a key is pressed, it triggers a scan code. Scan codes are 16-bit values that represent the characters and function keys on the keyboard. The scan code is passed along to the ROM BIOS via the keyboard interrupt 09h. There the scan code is converted into ASCII or extended ASCII. This value is then passed to the operating system via function 16h, and finally onto the application.

Monitoring the state of the input device and its values is governed by a number of functions. Editing functions in DOS use buffering. This is a small area of memory set aside to hold a string of scan codes until a carriage return is received, or until the buffer hits capacity. This is controlled using function 0Ah. When the carriage return is received, this function returns the number of characters in the buffer. These buffers are always configured for the number of bytes plus two bytes extra - one for the line feed and one for the carriage return (always last). When the buffer hits capacity, each subsequent keystroke will trigger a audible tone and the input ignored. The input buffer can be cleared on the fly using function 0Ch. This controls the data stream in the event the application needs to filter out control characters.

Programs under DOS do not multitask. When an application is running, it has full control of the processor over the operating system (which it interacts with using interrupts). In order to terminate these programs, the keyboard can send a break signal. The key combination of Ctrl-C will call Interrupt 23h, which is part of the operating system and it will attempt to immediately stop the current process. By default, DOS checks for the Break whenever input or output is made with the four standard devices (keyboard, video, printer, and serial ports).

There are two types of keyboard input - scan codes for characters that are echoed to the standard output or redirected, and special characters used for device and application control. This second group of characters do not echo to the screen. Instead, they are handled by the interrupt functions. When special characters are typed, functions 07h and 08h return the value to the AL register without echoing to the screen. The only difference between the two is how they handle the break character.

Because programs receive their input from the keyboard by default, they need some way of polling the device to see if there is data waiting to be passed along. When this check is performed, function 0Bh is called to see if there is pending input. If there is pending input, the AL register returns the value FFh. If, however, there is no input pending, the AL register returns zero. Once the sampling state is determined, the next step is to determine if the application will suspend and wait for the next character or whether it will immediately capture the character in the AL register on the fly by reading the return value from function 06h periodically.

The ability to reprogram keys is accomplished using the ANSI.SYS driver. This is the device driver DOS uses to control the keyboard. When function keys are pressed, they first send their scan code to the BIOS. The BIOS then translates the scan code into a control code, a two byte value represented by a leading zero, a semicolon, and the key's value (i.e. 0;60). These control codes identify the function keys and can be remapped.

DOS has spanned several generations of video technology. With the original IBM PC, the display was monochrome using a 8-bit display adapter. With only character positioning on the screen as its graphics ability, it was extremely limited. Soon thereafter, also in 1981 with the release of the RGB-based monitor, the color graphics adapter (CGA) was able to display 16 colors at 200x400 resolution. Because this was a pixel-based display matrix, DOS was now able to control rudimentary graphics. This was expanded on with EGA adpaters in 1984 (extended graphics adapter), which increased the color depth to 64 colors, but only able to display 16 at a time. With the introduction of the IBM PS/2, the VGA standard appeared in 1987. This format set a base resolution of 640x480 pixels using 16 colors with the ability to display 256. Finally, IBM released XGA monitors in 1990 extending the color range to 65,536 colors and resolutions up to 1024x768 pixels.

Graphic-based video display output is a combination of alphanumeric controls (text mode) and All Points Addressable controls (APA mode, or graphics mode). Text mode addressing is accomplished by outputting all 256 ASCII characters to the screen using a ROM BIOS generator. Graphics mode is based on a formula using three primary colors - red, green, and blue. Each of these colors has a range of values that are set with individual bits. By combining raw color bit values with attribute values, a maximum of 16 colors was obtained in the early display adapters. With VGA, the three-color mix was extended by using color shading. Shades were further extension of the primary colors to extend the palate to 256 colors.

Unlike programs (including the operating system) that use onboard memory, video adapters come with their own memory for display management. This is because display operations require large segments of memory, and attempting to use system memory to map out display characteristics presents capacity and speed issues. The onboard memory on a system reserves the first 128k of its upper memory stack to access the memory on the video adapter. This is done through a technique called paging. Video cards from the DOS generation may have 4mb of memory or more. The two 64k upper memory blocks DOS manages (at address range A0000h - B7FFFh) are used to copy video adapter memory segments into upper system memory. As this memory buffer is read, it immediately changes the display whenever the calling function updates the character value in the register(s). As the graphics image changes, the spent memory segment is paged out and the next section paged in.

There are two distinct categories of video output display control - monochrome (character-based) and graphic (color and image-based). In terms of monochrome character control, DOS uses several Int 21H function calls to manage their display on the screen. Backspace translation is done using function 02h. This pushes the character value in the DL register to the standard output when the function is called, overwriting the previous character that was output. Function 06h is used to output characters to the display. Unlike function 02h, this function makes no checks for character translation, sending the AL register value straight to the screen. There are also two character string controls. Function 09h and 40h are identical in that they output the string value in the DS:DX registers to the display. The only difference is function 09h cannot output the $ symbol (because it is used for termination control).

Extended screen control was introduced with DOS version 2.00. This was the incorporation of the ANSI standard for character output to a display that supports cursor control. Cursor positioning is fixed in the top left corner in positions 0,0 for the first horizontal and vertical screen coordinate. These screen controls also introduced the ability to manipulate character attributes. These display attributes are either normal white on black, reverse black on white, underlined white, blinking white, or bold intensity white for monochrome adapters. These were extended into the color graphics modes of later adapters. Another feature of screen controls was the ability to set video display modes for resolution and color depth. These were either called using Int 21H functions or by loading the ANSI.SYS driver (see the ANSI.SYS command in the command reference). The standard ROM BIOS video routines for graphics control are CGA/EGA/VGA routines accessed with functions 00h through 0Fh. These were extended over time with the introduction of the EGA adapter, when extended graphics routines were migrated to the video adapter and controlled using Int 10H - 13H function calls. VGA controls are accessed using the 1Ah - 1Ch functions (for more on functions, see the individual sections on the left menu based on the function number).

The BIOS functions DOS uses to call character management are from Int 10H. Setting the video mode is done by setting the AH register to zero, setting the AL register to the video mode value, and calling Int 10H. Inspecting the current mode is done by setting AH to 0Fh and calling Int 10H, which returns the mode value to the AL register and the number of screen columns to the AH register. Picking the active memory page is done by setting the AL register and setting the AH register to 05h, then executing Int 10H. Changing the cursor appearance (thick, thin, or block) is done by setting the AH register to 01h, setting the screen start position in CH, the screen stop position in CL, and calling Int 10H. Setting cursor position is done by loading the AH register with 02h, setting the row coordinate in DH, the column coordinate in DL, and the video page in BH, then calling Int 10H. Reading cursor position is done by setting the AH register to 03h, the video page number in BH, and calling Int 10H. This returns the row to the DH register and the column to DL. Page scrolling is accomplished by setting the AH register to 06h (up) or 07h (down), the AL register to the number of lines to scroll (0=full page), setting the screen start position in CH, the screen start column in CL, setting the DH to bottom right end row, and the DL to bottom right end column, and call Int 10h. These functions are all character-based routines that can also be used with graphics mode.

Finally, Graphics mode output is based on color palette control and read/write operations based on screen coordinates. The palette is configured by choosing the foreground and background colors. These are set using Int 10H, function 0Bh. Register BH (not to be confused with function 0Bh) is used to identify foreground vs. background value, and BL is used to identify the color selected. Set BH=0h, BL=0 for the RGB color, or BL=1 for the blended variations. Then set the AH register to 0Bh and call Int 10H to set the colors. Once the colors are set, the only remaining tasks are reading and writing the dots. To read the current pixel value using screen coordinates, set DX to the row, CX to the column, and the value 0Dh in the AH register calling Int 10H. This returns the current color in the AL register. To output colors to the screen, the high resolution graphics coordinates used with VGA map to 0,0 in the top left corner down to 479,639 in the bottom right corner (for a 640x480 resolution - the pixel mapping technique is the same for lower-resolution video modes). Output is accomplished by setting DX to the row, CX to the column, AL to the color, the AH register to the value 0Ch, and calling Int 10h.

Serial ports are the original interface for peripheral equipment on the PC. In its native configuration, it appears as a 25-pin D-sub connector (the configuration is also available in a 9-pin version). Known as "COM" ports, (a shortened variation of "communication"), serial ports are used for input and output of data between the system and external devices, such as printers and modems. For the purpose of device attachment, there are adapters that modify 25 pins to 9 pins and visa-versa.

Like other devices under DOS, serial ports use interrupts to request services, and are assigned specific interrupt request numbers (IRQ's). Generally speaking, most PCs have only two, with the default IRQ being 4 for COM1: and 3 for COM2:. These are user-changeble to avoid IRQ conflicts with other hardware installed in the system. Like other devices, when a COM port needs servicing, it sends an interrupt request over its assigned IRQ. These interrupts can be shared, but two devices on the same interrupt cannot use the same processor interrupt at the same moment.

Serial ports transmit and receive data in a linear serialized stream, one bit at a time (using a speed measurement call the baud rate). To identify the components of the data stream, serial communications insert a start bit at the beginning of the byte, a stop bit at the end, and a parity bit to match the origin value with the destination for error control. This is controlled by a special chip called a Universal Asynchronous Receiver Transmitter, or UART. Because the original PC system bus was 8 bits and transmitted data in parallel, the UART translates the data flow into a serialized stream. These chips cache the data stream in a buffer.

Finally, there are several flow control codes used to manage the buffer to prevent overflow. These are request to send (RTS), Clear To Send (CTS), Data Terminal Ready (DTR) and Data Set Ready (DSR). These commands (actually voltage states on specific pins) allow the serial device to stop and start the data, which is checked by the computer on the clear to send pin. If voltage is present on the CTS pin, the datastream is processed. If not, the datastream is stopped to prevent overflow. By toggling this pin on and off, serial communication flow is maintained in a steady fashion.

DOS assumes there is a standard source for input (the keyboard) and output (the display). By using the MODE command, these can be redirected. At the time DOS was being written, the programmers did not include functions able to call the MODE routines, instead using the ROM BIOS. Because of this, there is a limited set of functions available to maintain code portability across BIOS platforms when dealing with serial communications. There are, however, serial port function calls within DOS that can be used. Just the same, the preferred way to handle serial I/O is through Int 14h in the BIOS.

The BIOS function calls under 14h are function 00h for initializing baud, parity, and control bits, 01h to output a character, 02h to receive a character, and 03h to check the status of a port. Each of these is called by setting the DX register with the COM port, the function number in the AH register, and calling Int 14h. In contrast, the DOS function EXEC, which is called from within applications to execute DOS functions, can use the two 21H functions for character manipulation. The first is function 03h. This function uses unbuffered input by setting the character value in the AL register and calling 21H. This method is time consuming, delaying the processor as it waits for the character to be processed by the receiving application. The second is function 04h. This outputs the character to the calling program by setting the AH register to 04h, the character value in the DL register, and calling Int 21H.

Because these two DOS functions use unbuffered data control, the prevailing method is to use the UART to control the dataflow, by instructing it to use an interrupt after each character has been manipulated. This is done by addressing the serial ports directly at COM1: and COM2:. Because the nature of serial communications involves three jobs (flow control, bidirectional interaction with downstream devices, and data I/O itself) the unbuffered method is unreliable using the DOS function calls, and this is one area where the DOS source code was never well represented, with programmers opting instead to use the Int 14H calls.

Parallel ports, like serial ports, are for controlling peripheral devices. They were originally designed to work with IBM's early systems for printer data and control and consist of a 25-pin female DB connector. Unlike serial communications, which are controlled sequentially one bit at a time, parallel ports can send data using a strobe control (voltage state to indicate data) in tandem across multiple wires in 8-bit blocks, resulting in faster transmission speed. IBM included the port from the beginning in their design to anticipate the adoption of printers from Centronics® Corporation - hence the pseudonym name "centronics port". Pin voltages on the adapter indicate the control codes for busy, transmit, acknowledge, online, and out of paper. Automatic paper feed is also controlled via a pin signal.

Over the course of DOS history, 3 parallel port types have evolved. The original port was uni-directional with only one-way control. When IBM introduced the PS/2, they brought a new type to market known as the SPP or standard parallel port. This was bi-directional. In 1991 Intel and a consortium of companies introduced the EPP enhanced parallel port. This allowed for faster speeds in conjunction with the introduction of parallel port storage devices, and was not specifically a printer enhancement. Finally, ECP extended capability ports were introduced to improve printer signal control and data speed.

DOS utilizes date information for two primary functions - the creation and update information for files, whereas the ROM BIOS timekeeping routine is referenced by DOS for the system time. The attributes for file time are stored in the 22nd and 23rd byte in the directory entry. The five low-order bits 0-4 store the number of two second increments (a "compromise" that then allows the date and time information to occupy sixteen bits). Bits 5-10 contain the minute data, and bits 11-15 contain the hour data:

When functions 2Ch and 2Dh are called using interrupt 21h, a file's date and time information can be retrieved or modified. On early systems the system clock would reset everytime the system powered off, setting the byte 22 and 23 information to all zeros. This was later corrected in systems using onboard battery backup systems to hold clock data. The CX and DX registers are used for time calls, and the parameters are passed as four 8-bit fields. The CH register contains the hour data, the CL register contains the minutes, the DH register contains the seconds, and the DL register contains the 1/100 sec. value.