Prev TOP NEXT HOME
Learning about DOS
I think the best way to learn about DOS internals is to read the technical appendices in the manual. These are not as complete as we might wish, but they really aren't bad; I certainly have learned a lot from them. What you don't learn from them you might eventually learn via judicious disassembly of parts of DOS, but that shouldn't really be necessary.
From reading the technical appendices, you learn that interrupts 20H through 27H are used to communicate with DOS. Mostly, you will use interrupt 21H, the DOS function manager.
The function manager implements a great many services. You request the individual services by means of a function code in the AH register. For example, by putting a nine in the AH register and issuing interrupt 21H you tell DOS to print a message on the console screen.
Usually, but by no means always, the DX register is used to pass data for the service being requested. For example, on the print message service just mentioned, you would put the 16 bit address of the message in the DX register. The DS register is also implicitly part of this argument, in keeping with the universal segmentation rules.
In understanding DOS functions, it is useful to understand some history and also some of the philosophy of MS-DOS with regard to portability. Generally, you will find, once you read the technical information on DOS and also the IBM technical reference, you will know more than one way to do almost anything. Which is best? For example, to do asynch adapter I/O, you can use the DOS calls (pretty incomplete), you can use BIOS, or you can go directly to the hardware. The same thing is true for most of the other primitive I/O (keyboard or screen) although DOS is more likely to give you added value in these areas. When it comes to file I/O, DOS itself offers more than one interface. For example, there are four calls which read data from a file.
The way to decide rationally among these alternatives is by understanding the tradeoffs of functionality versus portability. Three kinds of portability need to be considered: machine portability, operating system portability (for example, the ability to assemble and run code under CP/M 86) and DOS version portability (the ability for a program to run under older versions of DOS>.
Most of the functions originally offered in DOS 1.0 were direct descendents
of CP/M functions; there is even a compatibility interface so that programs
which have been translated instruction for instruction from 8080 assembler to
8086 assembler might have a reasonable chance of running if they use only the
core CP/M function set. Among the most generally useful in this
original compatibility set are
09 -- print a full message on the screen
0A -- get a console input line with full DOS editing
0F -- open a file
10 -- close a file (really needed only when writing)
11 -- find first file matching a pattern
12 -- find next file matching a pattern
13 -- erase a file
16 -- create a file
17 -- rename a file
1A -- set disk transfer address
The next set provide no function above what you can get with BIOS calls or more specialized DOS calls. However, they are preferable to BIOS calls when portability is an issue.
00 -- terminate execution
01 -- read keyboard character
02 -- write screen character
03 -- read COM port character
04 -- write COM port character
05 -- print a character
06 -- read keyboard or write screen with no editing
The standard file I/O calls are inferior to the specialized DOS calls but have the advantage of making the program easier to port to CP/M style systems. Thus they are worth mentioning:
14 -- sequential read from file
15 -- sequential write to file
21 -- random read from file
22 -- random write to file
23 -- determine file size
24 -- set random record
In addition to the CP/M compatible services, DOS also offers some specialized services which have been available in all releases of DOS. These include
27 -- multi-record random read.
28 -- multi-record random write.
29 -- parse filename
2A-2D -- get and set date and time
All of the calls mentioned above which have anything to do with files makeuse of a data area called the "FILE CONTROL BLOCK" (FCB). The FCB is anywhere from 33 to 37 bytes long depending on how it is used. You are responsible for creating an FCB and filling in the first 12 bytes, which contain a drive code, a file name, and an extension.
When you open the FCB, the system fills in the next 20 bytes, which includes a logical record length. The initial lrecl is always 128 bytes, to achieve CP/M compatibility. The system also provides other useful information such as the file size.
After you have opened the FCB, you can change the logical record length. If you do this, your program is no longer CP/M compatible, but that doesn't make it a bad thing to do. DOS documentation suggests you use a logical record length of one for maximum flexibility. This is usually a good recommendation.
To perform actual I/O to a file, you eventually need to fill in byte 33 or possibly bytes 34-37 of the FCB. Here you supply information about the record you are interested in reading or writing. For the most part, this part of the interface is compatible with CP/M.
In general, you do not need to (and should not) modify other parts of the FCB.
The FCB is pretty well described in appendix E of the DOS manual.
Beginning with DOS 2.0, there is a whole new system of calls for managing files which don't require that you build an FCB at all. These calls are quite incompatible with CP/M and also mean that your program cannot run under older releases of DOS. However, these calls are very nice and easy to use. They have these characteristics
1. To open, create, delete, or rename a file, you need only a character string representing its name.
2. The open and create calls return a 16 bit value which is simply placed in the BX register on subsequent calls to refer to the file.
3. There is not a separate call required to specify the data buffer.
4. Any number of bytes can be transfered on a single call; no data area must be manipulated to do this.
The "new" DOS calls also include comprehensive functions to manipulate the new chained directory structure and to allocate and free memory.