DOS 3.30 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

7051 lines
242 KiB

MICROSOFT(R)
MS(tm)-DOS
Adaptation Guide
Last Updated on JULY 24, 1987
in conjunction with the MS-DOS 3.30 FINAL RELEASE
Microsoft Corporation
Information in this document is subject to change without
notice and does not represent a commitment on the part of
Microsoft Corporation. The software described in this
document is furnished under a license agreement or
non-disclosure agreement. The software may be used or
copied only in accordance with the terms of that agreement.
It is against the law to copy the MS-DOS Disk Operating
System on magnetic tape, disk, or any other medium for any
purpose other than the purchaser's personal use.
Copyright (C) Microsoft Corporation, 1982, 1983, 1984, 1985, 1986
INTEL is a registered trademark of Intel Corporation.
IBM is a registered trademark of International Business
Machines Corporation.
Microsoft, the Microsoft logo, and MS-DOS are registered
trademarks of Microsoft Corporation.
XENIX is a trademark of Microsoft Corporation.
TABLE OF CONTENTS
CHAPTER 1 MS-DOS INSTALLATION KIT
1.1 README.DOC File 1-1
CHAPTER 2 MS-DOS DEVELOPMENT TOOLS
CHAPTER 3 INSTALLING MS-DOS
CHAPTER 4 DISK STRUCTURE AND BOOTSTRAP LOADING
CHAPTER 5 RESIDENT DEVICE DRIVERS
CHAPTER 6 SYSINIT AND MS-DOS INITIALIZATION
CHAPTER 7 WRITING THE FORMAT MODULE
CHAPTER 8 TROUBLE SHOOTING
APPENDIX A CUSTOMIZATION OF MS-DOS AND
INTERNATIONALIZATION
A.1 Customizing MS-DOS A-1
A.2 ECS Considerations -- MS-DOS 2.25 A-2
A.3 Input A-3
A.4 Output A-3
APPENDIX B HOW TO UPGRADE A 2.X BIOS TO 3.X
APPENDIX C HOW TO UPGRADE A 3.1 BIOS TO 3.2
APPENDIX D DEVICE DRIVERS - CHAPTER 2 MS-DOS 3.20 PROGRAMMER'S REFERENCE
APPENDIX E MS-DOS 2.25 DEVICE DRIVER EXTENSIONS
APPENDIX F MS-DOS 2.25 APPLICATION LEVEL INTERFACE EXTENSION
APPENDIX G SPECIAL DOC
APPENDIX H PROGRAMMING RECOMMENDATIONS - CHAPTER 7 MS-DOS 3.20
PROGRAMMER'S REFERENCE
GLOSSARY OF MS-DOS TERMS
CONTENTS
CHAPTER 1 MS-DOS INSTALLATION KIT
1.1 README.DOC File 1-1
1.2 Contents 1-1
1.3 Common Questions and Answers 1-2
1.4 MS-DOS Hardware Requirements 1-3
1.5 MS-DOS Overview 1-5
CHAPTER 1
MS-DOS INSTALLATION KIT
1.1 README.DOC FILE
Check the README.DOC file on DISTRIBUTION DISKETTES for
version specific information and any addenda to this document.
1.2 CONTENTS
The MS-DOS 3.21 Installation Kit is provided on 5-1/4" high capacity
1.2 Megabyte disks. It consists of the MS-DOS DISTRIBUTION
DISKETTES that include files formerly found
version.
Included with the kit is a Sample MS-DOS 2.XX/3.XX Implementation.
The sample implementation runs on all members of the IBM PC family and
is intended to be functionally equivalent to the IBM implementation.
The purpose of this sample is to assist Microsoft OEMs with their
MS-DOS installations, but can also be used directly as part of the OEMs
product. IO.SYS, the BIOS, has been intended to be self documenting and
Microsoft will support services for it as it run on IBM PCs.
Included in the kit is a copy of the current Microsoft(R) Macro Assembler
featuring SYMDEB, the symbolic debugger. The full MASM retail package is
no longer provided.
The installation kit also includes four manuals:
MS-DOS User's Guide. This is an introduction to ______ ______ _____
MS-DOS, including how to start the system and use
applications.
MS-DOS User's Reference Manual. This manual ______ ______ _________ ______
explains hierarchical directories, the MS-DOS file
structure, and MS-DOS commands and utilities. This
manual is new in 3.XX.
MS-DOS Programmer's Reference Manual. This manual ______ ____________ _________ ______
includes a summary of all published system calls
and MS-DOS structures.
MS-DOS Adaptation Guide. This manual describes how ______ __________ _____
to implement MS-DOS on OEM machines. This guide is
available on diskette only and is the text you are
now reading.
MS-DOS INSTALLATION KIT Page 1-2
1.3 COMMON QUESTIONS AND ANSWERS
Q. What kind of development machine do you recommend?
A. Microsoft recommends that an MS-DOS machine be used as a
development tool in preparing software for your target
machine. Using an MS-DOS machine avoids problems with
incompatible assemblers and object module formats. You
may want to read standard MS-DOS disk formats. Using
the development machine to build a system disk for the
target machine simplifies the implementation process.
Q. Are sources available?
A. Sources for MS-DOS are not available (except for the sample
BIOS implementation).
Q. What language is MS-DOS written in?
A. The source code for MS-DOS and most utilities is written
in 8086 assembler code. It is compatible with the macro
facility found in Microsoft Macro Assembler for the
MS-DOS operating system. The format of the object
modules provided is a subset of the INTEL(R) format, and
may not be compatible with non-Microsoft linkers.
Q. What does an MS-DOS implementor need to know?
A. To install MS-DOS, you will need to be familiar with
systems programming in 8086 assembler language. This
means you should have experience in writing device
drivers for disk drives, keyboards, printers, and other
peripherals.
Q. How long does it take to install MS-DOS?
A. This depends on whether the low-level I/O routines are
already written. The record time for getting MS-DOS up
and running on a new machine is one weekend. In this
case, all of the low-level routines were in ROM.
Typically, a complete customer-ready MS-DOS
implementation takes two or more months.
MS-DOS INSTALLATION KIT Page 1-3
Q. Are there any consultants who do MS-DOS implementations?
A. Microsoft can supply a list of consultants who have done
MS-DOS implementations. Microsoft cannot make any
recommendations regarding the competence of these
consultants.
Q. Do you recommend that we have an In Circuit Emulator
(ICE) for our machine?
A. Yes. Since there are no MS-DOS debugging tools that can
be used to debug the boot sequence, an ICE is very
helpful.
1.4 MS-DOS HARDWARE REQUIREMENTS
To be compatible with the MS-DOS operating system, a machine
must conform to certain hardware characteristics. These
characteristics are as follows:
o The processor must be INTEL 8086 compatible.
o The Interrupt vector locations 20H through 3FH must
be reserved for MS-DOS.
o Four character device drivers and one block device
driver are required. They must recognize the
MS-DOS device driver call format.
o An ANSI terminal driver must be implemented.
(MS-DOS sends an ANSI escape sequence to clear the
console.)
o A logical disk, as described in this document, must
be available to MS-DOS. A disk format table, as
described in this document, should be present in
the first logical sector of each disk. Logical
sectors must be a multiple of 64 bytes in size.
o Random Access Memory (RAM) should be contiguous
from the point where MS-DOS is located through top
of memory.
o MS-DOS requires a minimum of 128K of RAM (depending
on IO.SYS size). Microsoft recommends a minimum
configuration of 128K non-video RAM and 192K for
future products.
The sample BIOS that is provided has been designed to only run on
a machine with the exact architecture of IBM PC family.
If MS-DOS can run on the OEMs hardware using the sample BIOS, then
the hardware is compatible with the IBM PC family architecture.
MS-DOS INSTALLATION KIT Page 1-4
In addition to these minimum requirements, the following
hardware features are recommended for optimum performance as
well as compatibility with new Microsoft products. Features
recommended for performance on 2.0 and higher systems are
starred.
o *An interrupt-driven keyboard with a type-ahead
buffer (Interrupt-driven I/O for all devices).
o *Direct memory access.
o *Non-interlaced disks.
o *Disk door locks or a detection mechanism to check
if disks have been changed.
o Support of standard MS-DOS disk formats.
o User-addressable bit-mapped video display with
minimum resolution of 640 by 200 pixels.
o Programmable interval timer.
o Mouse support.
o RS-232 and printer interfaces.
o Minimum 192K RAM memory.
o A Scroll Lock/Break key that puts a Control-S and
Control-C at the beginning of the keyboard
type-ahead buffer when pressed.
MS-DOS INSTALLATION KIT Page 1-5
1.5 MS-DOS OVERVIEW
An MS-DOS implementation requires seven components:
1. The resident device drivers (the IO.SYS file), a
collection of hardware-specific device drivers that
must be written by the OEM. The resident device
drivers are called by MS-DOS to handle I/O
requests. These device drivers may be partly ROM
resident or may be completely RAM resident.
2. The SYSINIT Module(s), (SYSINIT1.OBJ and SYSINIT2.OBJ
in 3.xx and only SYSINIT.OBJ in 2.xx) and SYSIMES.OBJ,
Microsoft-supplied modules which are linked to the
resident device drivers and initialize the system.
The file that contains these device drivers is
named IO.SYS (on the IBM(R) PC, this file is named
IBMBIO.COM).
3. MSDOS.SYS, the hardware-independent disk operating
system supplied by Microsoft. (On the IBM PC, this
file is named IBMDOS.COM.)
4. COMMAND.COM, the command interpreter program that
reads and interprets keyboard input, executes
"built-in" commands like DIR, and initiates
external programs.
5. Bootstrap loader, the OEM-supplied module that
loads the IO.SYS and MSDOS.SYS files into memory.
MSDOS.SYS may optionally be loaded by IO.SYS.
A sample bootstrap loader has been provided with
the OEM kit. This sample bootstrap loader is
compatible with the IBM PC family.
6. A system ROM which may optionally perform
diagnostics on power-up or reset. The system ROM
loads the boot sector into RAM and transfers
control to it.
7. MS-DOS utilities, including FORMAT, for which
Microsoft modules are provided and a
hardware-specific section must be written by the
OEM. NOTE: Refer to the MS-DOS 3.3 specific portions
for use of the hardware independent FORMAT utility.
MS-DOS INSTALLATION KIT
CONTENTS
CHAPTER 2 MS-DOS DEVELOPMENT TOOLS
EDLIN Text Editor 2-1
Microsoft Macro Assembler 2-1
Microsoft Linker (MS-LINK) 2-2
MS-DEBUG 2-2
EXE2BIN 2-2
FORMAT 2-2
CHAPTER 2
MS-DOS DEVELOPMENT TOOLS
An assembler, text editor, linker, and other utilities are
required for completing an MS-DOS implementation. We assume
that your development machine has the following standard
utilities:
EDLIN Text Editor
The EDLIN text editor provided with MS-DOS for your
development machine may be used to prepare assembler
source files. The version of EDLIN on MS-DOS 2.x and
3.x release disks is for versions 2.x and 3.x only, and
will not run under MS-DOS 1.x. A third party full screen
text editor (not a word processor) may be more efficient
for manipulating source files.
Microsoft Macro Assembler
A complimentary copy of the current Microsoft Macro Assembler
is provided with the MS-DOS installation kit.
The assembler is not actually a part of MS-DOS; it must be
licensed separately if you wish to ship it to your
customers. The Cross-Reference Utility (MS-CREF),
included with Microsoft Macro Assembler, can be used to
make cross-reference listings of assembler programs.
The Microsoft Macro Assembler package will only run
under MS-DOS 2.XX and later operating systems. The
output of the assembler is a relocatable object module
(.OBJ file type) which conforms to a subset of the
INTEL MCS 86 object module format description. Refer
to the MS-DOS Programmer's Reference Manual for ______ ____________ _________ ______
information on the INTEL MCS 86 object module format
description.
MS-DOS DEVELOPMENT TOOLS Page 2-2
Microsoft Linker (MS-LINK)
Your MS-DOS development machine should include a linker
named LINK.EXE. Use LINK.EXE for linking object
modules (.OBJ files) produced by the Microsoft Macro
Assembler. The output of the Linker is a file with an
.EXE format. This is an executable program requiring a
special loader that is part of MS-DOS. Refer to the
MS-DOS Programmer's Reference Manual for details on ______ ____________ _________ ______
.EXE formats.
SYMDEB
SYMDEB.EXE is the MS-DOS symbolic debugger. The debugger
can do absolute disk reads and writes. You may use this
facility to write your bootstrap loader program into
the boot sector. Note that since MS-DOS is not
reentrant, this debugger may not be used to set break
points within the DOS or device drivers.
EXE2BIN
The EXE2BIN.EXE utility supplied with your MS-DOS
development machine must be used for converting output
from the Linker (.EXE files) to a pure binary (core
image) format not requiring a special loader. Note
that only .COM files may execute out of ROM.
FORMAT
The FORMAT program (FORMAT.EXE) supplied with your
MS-DOS development machine may be used to format a boot
disk for the target machine, assuming both machines
have compatible media.
EXEFIX
EXEFIX is a special purpose utility used for building
SORT. It sets the maximum memory allocation.
MS-DOS DEVELOPMENT TOOLS
CONTENTS
CHAPTER 3 INSTALLING MS-DOS
CHAPTER 3
INSTALLING MS-DOS
If you are using an MS-DOS machine for development and your
target machine will read MS-DOS standard disk formats,
follow these steps to implement MS-DOS.
NOTE: The steps involved in developing IO.SYS are not necessary
if the sample BIOS provided with the OEM kit is used.
This sample can also be used for technical reference.
1. Using a text editor on your development machine,
write the 8086 assembler source code for the
resident device drivers. The resident device
drivers are the hardware-specific routines that
will be accessed by MS-DOS to perform I/O. There
must be a minimum of five device drivers: four ____
character drivers and one block device driver (the
disk drive on most systems). In addition to the
device drivers, you may want to include some code
for hardware initialization. The source file
should be named IO.ASM and must not contain a STACK
segment.
For more information, see:
MS-DOS Programmer's Reference Manual ______ ____________ _________ ______
IO.ASM on the distribution disk
The resident device driver section of this manual
2. Use MASM.EXE, the macro assembler provided with
your MS-DOS installation kit to assemble your
device driver code. MASM will create a file called
IO.OBJ, which is in a special object module format
(a subset of INTEL's object module format).
For more information, see:
Microsoft Macro Assembler Manual (Macro Assembler _________ _____ _________ ______
section)
3. Use LINK.EXE, the Microsoft Linker, to link your
IO.OBJ module to appropriate SYSINIT.OBJ module(s)and the
appropriate SYSIMES.OBJ module. The
modules must be linked in this order:
2.xx IO.OBJ+SYSINIT.OBJ+SYSIMES.OBJ
3.XX IO.OBJ+SYSINIT1.OBJ+SYSINIT2.OBJ+SYSIMES.OBJ
The output file should be named IO.EXE. You
INSTALLING MS-DOS Page 3-2
may get the message "Warning, no STACK segment" while
linking the module. This is a warning message and
is normal with some versions of the linker.
For more information, see:
Microsoft Macro Assembler Manual (Chapter 3 LINK: _________ _____ _________ ______
A Linker)
4. The file created in step 3 is an .EXE file which is
in a special format recognized by the .EXE loader.
Since the .EXE loader is not available at boot
time, the IO.EXE file must be converted to a pure
binary core image file. This is done with the
EXE2BIN utility provided with the MS-DOS release on
your development machine. The EXE2BIN utility must
know exactly where the code will reside in memory
to resolve any FAR references. You will be
prompted for the base address, the absolute segment
address where the code will begin. The resultant
file must be named IO.SYS. EXE2BIN will change the
name when you type the following command line:
EXE2BIN IO.EXE IO.SYS
------------------------------------------------------------
| |
| Note |
| |
| It is the responsibility of the bootstrap loader to |
| locate IO.SYS at the location you specified as the base |
| address. The location itself is arbitrary, since one |
| of the parameters that the resident device driver code |
| passes to SYSINIT is the location of the first device |
| driver. |
| |
|__________________________________________________________|
For more information, see:
MS-DOS User's Reference Manual (Chapter 3) ______ ______ _________ ______
5. Customize the function key table in DOSMES.ASM.
6. Use MSDOSBLD.BAT on the distribution disk to assemble
appropriate object modules and link them with those
already provided to form MSDOS.SYS.
7. Write a bootstrap loader program using the text
editor. This step is not necessary if the sample
bootstrap loader included in the OEM kit is used.
The sample bootstrap loader can also be used for
technical reference.
Name this file BOOT.ASM. We assume that you have
a system ROM which will load the first sector of
the system disk into memory when you turn
on or reset the compter. Ideally, the bootstrap
loader fits into the first sector of the boot disk.
In addition to the loader, information relating to
the BIOS Parameter Block (BPB) should be kept in the
boot sector of the disk. The format of the boot
INSTALLING MS-DOS Page 3-3
sector is described in Chapter 4.
The bootstrap loader loads IO.SYS and MSDOS.SYS into
memory. MS-DOS can be located any place in memory
above IO.SYS. (IO.SYS can alternately be used to
load MSDOS.SYS.) Loading IO.SYS and MSDOS.SYS is
simple because these two files must always be the
first files on the disk. This means that a
bootstrap loader could simply load a series of
consecutive sectors into memory. Your bootstrap
loader may also read in the first sector of the
directory before it loads IO.SYS to verify that
these files are the first files on the disk.
For more information, see:
MS-DOS Programmer's Reference Manual ______ ____________ _________ ______
(Chapter 2)
MS-DOS Adaptation Guide (Chapter 4) ______ __________ _____
8. Assemble, link, and convert to binary (using
EXE2BIN) the BOOT.ASM file to produce BOOT.BIN.
9. Format a non-system disk using your MS-DOS
development machine.
10. Using the MS-DOS Copy command, copy IO.SYS,
MSDOS.SYS, and appropriate version of
COMMAND.COM to the formatted disk.
11. Using DEBUG.COM on the development machine, load
BOOT.BIN and write it to the first sector of the
formatted disk. This can be done as follows:
DEBUG
-N BOOT.BIN
-L (loads BOOT.BIN)
-W 100 0 0 1 (writes BOOT.BIN to drive 0
sector 0)
-Q
Note: More operations may be required depending on
how your boot program is organized.
For more information, see:
Microsoft Macro Assembler Manual (Chapter 4 SYMDEB: _________ _____ _________ ______
A Symbolic Debug Utility
The formatted disk should now be bootable by your
system.
INSTALLING MS-DOS Page 3-4
12. Write the source code for the hardware-specific part
of the FORMAT program. The MS-DOS 3.3 version of the
FORMAT utility has been structured so that the hardware
specific portions have been placed solely in IO.SYS.
Minimal work should be required for the OEM use of the
MS-DOS 3.2 FORMAT utility.
Assemble and link this to the FORMAT.OBJ and FORMES.OBJ
files supplied by Microsoft. The modules must be linked
in the following order:
2.XX: FORMAT.OBJ+FORMES.OBJ+OEMFOR.OBJ
where OEMFOR.OBJ is your hardware-specific module.
Use EXE2BIN to convert the OEMFOR.EXE file produced
to FORMAT.COM.
3.XX: FORMAT.OBJ+FORPROC.OBJ+FORMES.OBJ+OEMFOR.OBJ+PRINTF.OBJ
where OEMFOR is your hardware-specific module.
Although the PRINTF.OBJ module is the last module
specified, it does not follow the OEM module in the
memory image.
For more information, see:
MS-DOS Adaptation Guide (Chapter 7) ______ __________ _____
OEMFOR.ASM Disk file of sample OEM FORMAT module
MS-DOS User's Reference Manual (Format Command, ______ ______ _________ ______
Chapter 3)
MS-DOS Programmer's Reference Manual (Chapter 3) ______ ____________ _________ ______
13. Install the MS-DOS OEM serial number.
For information on how this is done, refer to the README.DOC
on the distribution diskette.
14. Modify SORTMES.ASM as appropriate.
15. Build SORT executable with SORTBLD.BAT.
16. Modify PRINT source modules as appropriate
17. Build PRINT executable with PRINTBLD.BAT
INSTALLING MS-DOS
CONTENTS
CHAPTER 4 DISK STRUCTURE AND BOOTSTRAP LOADING
4.1 Reserved Area 4-1
4.2 File Allocation Table 4-2
4.3 MS-DOS File System Limits 4-4
4.3.1 Disk Format Identification 4-6
4.4 The role of the Boot Sector 4-7
CHAPTER 4
DISK STRUCTURE AND BOOTSTRAP LOADING
MS-DOS disks are divided into four logical data areas.
1. Reserved sectors (boot sector)
2. File Allocation Tables
3. Root directory
4. Data area which may include subdirectories
as well as program and data files
When creating non-standard disks or non-removable media
(such as hard disks), the logical disk which your device _______
driver presents to MS-DOS must conform to the above
standard. The physical layout may be completely different. ________
For example, you may want to implement a partitioning scheme
on the hard disk so that it can be shared by multiple
operating systems. In this case, either the device driver
or firmware maps the physical structure into an MS-DOS
logical layout. The MS-DOS file system can even be
logically implemented within another operating system's file
structure.
4.1 RESERVED AREA
The reserved area is the first part of the disk and is
typically used for boot purposes. Some machines not
specifically designed for MS-DOS may use track 0 for special
purposes (it may even have a different sector size than the
rest of the disk). In this case, the entire track should be
marked as reserved so that the device driver will map
MS-DOS's logical sector 0 to the beginning of track 1
instead of track 0.
It may be difficult to fit the required boot information
into a single sector. Note that disk formats using 128- or
256-byte sectors and without any firmware support may
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-2
require several sectors.
4.2 FILE ALLOCATION TABLE
The File Allocation Table (FAT) is the most important data
structure on the disk. Two copies are usually kept at the
OEM's option. (Two copies need not be kept for a virtual
RAM disk because, in this case, the media cannot be damaged.)
MS-DOS files are allocated in "allocation units" or "clusters".
Each cluster is some number of sectors. The number of sectors
per allocation unit must be a power of 2 which fits in a byte.
Thus, the complete list of possible values is:
1, 2, 4, 8, 16, 32, 64, 128.
The FAT is a physical map of the allocation units in the
data area of the disk. There is one FAT entry for each
allocation unit on the disk plus two reserved entries at the
beginning of the FAT. The entries serve as a linked list of
pointers. For a complete discussion of FAT structure, refer
to Chapter 3 of the MS-DOS Programmer's Reference Manual. ______ ____________ _________ ______
FAT size can be determined by the following formula:
FAT = Q * ( T - R - D + 2)
--------------------
Q * N + ( A * S )
FAT is the number of sectors needed for one FAT and will
usually not be an integer. It must be rounded up to
the next integer value.
Q is the number 1.5 for 12-bit FAT entries and 2.0
for 16-bit FAT entries.
T is the total number of sectors on the disk.
R is the number of reserved sectors.
D is the number of root directory sectors (there must
be 32 bytes for each directory entry).
A is the number of sectors per cluster or allocation
unit.
N is the number of file allocation tables on the disk.
S is the number of bytes per sector.
MS-DOS 3.x can use 16-bit FAT pointers whenever the total
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-3
number of clusters on the disk exceeds 4085 (=4096-10; two
are reserved at the beginning, and eight are reserved at the
end). Although the FAT entries are 16 bits, the present
software only works with 15 bits (up to 32766 clusters).
____________________________________________________________
| |
| Important |
| |
| Be careful when reducing cluster size as it can cause |
| significant performance degradation. Reducing cluster |
| size results in increased fragmentation, a larger FAT |
| to buffer (increasing the number of disk accesses); and |
| increasing the FAT entries from 12 to 16-bit expands |
| the FAT size by 33%. |
| |
|__________________________________________________________|
The FORMAT program will create a proper FAT. The FAT has an
entry for each allocation unit in the data area of the disk.
It also contains two extra entries at the beginning. These
represent reserved clusters. The first cluster of the data
region of the disk is cluster 2.
The first (0th cluster) of these two reserved entries can be
used to indicate the format of the disk. Only the low 8
bits are used, and this byte is often referred to as the
FATID byte. The high 4 bits (high byte if a 16-bit FAT) of
this first cluster are all set (=1).
The FATID byte is restricted to be in the range 0F8H to
0FFH, inclusive (8 possible values). The FATID byte is also
an end-of-file (EOF) mark. If a FAT chain contains a zero
entry (which should never happen), it will point to this EOF
marker. The second (1st cluster) of these two reserved
entries is always 0FFFH (0FFFFH for a 16-bit FAT), which is
an end-of-file mark.
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-4
Figure 4.1 illustrates the first two clusters of a 12-bit
File Allocation Table.
FAT BYTE 00 01 02 03
XXH XXH XXH XXH----->Byte 3
|| || ||
Middle 4 bits | || High and middle 4 bits of
of cluster 0 | || cluster 1 (always F)
| | High 4 bits of
Low 4 bits of | cluster 0 (always F)
cluster 0 |
| | Low 4 bits of cluster
|------------------| 1 (always F)
|
FATID BYTE
Figure 4.1. First Two Entries of the FAT (12-bit)
4.3 MS-DOS FILE SYSTEM LIMITS
The following figure shows the file storage limitations
within MS-DOS.
| MS-DOS 2.x | Both | MS-DOS 3.x
_______________|______________|_____________|_______________
|FAT entry size |12 bits | |12 or 16 bits |
|Sector size | |64b-32Kb | |
|No. of Sectors | |Max of 64K | |
|Cluster size | |1-128 sectors| |
|Max. disk size |4085 clusters |64K sectors |32766 clusters|
|Max. file size | |Disk size | |
________________|______________|_____________|______________|
All ranges in the table are inclusive. As well as the above
limitations, there are also various limits as noted below:
1. FAT entry size.
This is the only file storage limit difference
between MS-DOS 2.XX and 3.XX; it significantly
increases the maximum number of clusters and hence
the maximum disk size allowed. MS-DOS 3.x
determines whether a 12- or 16-bit FAT is in use by
calculating the number of disk clusters from the
BPB. If the number of clusters is less than or
equal to 4085, a 12-bit FAT is in use; otherwise,
a 16-bit FAT is assumed. A 16-bit FAT cannot be
used if the total number of clusters is less than
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-5
or equal to 4085.
Some existing MS-DOS applications (such as copy
protection schemes and disk maintenance utilities)
bypass MS-DOS and manipulate the FAT directly.
These existing applications will cause problems
with 16-bit FATs until the applications are updated
to recognize the 16-bit FATs.
2. Sector Size.
Must be a multiple of 64 bytes.
3. No. of Sectors.
The number of sectors is limited to 64K because
16-bit sector numbers are passed to the device
drivers.
4. Cluster Size.
The cluster size (bytes/cluster = sectors/cluster *
bytes/sector) must be less than 64K because MS-DOS
uses 16-bit arithmetic.
Sectors/Cluster must be a power of 2 in the range
1-128.
Excessively small cluster sizes can seriously
degrade performance. Refer to the MS-DOS ______
Programmer's Reference Manual for sample disk ____________ _________ ______
formats.
5. Max. Disk Size.
MS-DOS 2.XX: Lesser of 4085 clusters or 64K sectors
(For example, 64K*512 byte sectors = 32Mb disk).
MS-DOS 3.XX: Lesser of 32766 clusters or 64K
sectors.
The total number of sectors is limited to 64K due
to the use of 16-bit arithmetic.
The maximum number of possible clusters is
calculated by the following:
FAT entry size
(2 -10 Reserved)
Reserved: 8 FAT ID/EOF (F8-FF)
2 RESERVED (0,1)
------------------------------------------------------------
| |
| Note |
| |
| However, some MS-DOS utilities (such as Chkdsk and |
| Recover) restrict the total FAT size to 32K entries, |
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-6
| hence the MS-DOS 3.x limit of 32,766 clusters and not |
| 65,525 (216-11). |
| |
|__________________________________________________________|
There are 10 MS-DOS reserved FAT entries; two at
the front of the FAT, and eight at the end:
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-7
4086 = 4K -10
32766 = 32K -2
The 8 reserved clusters
are in the range 65528-65536.
6. Max. File Size.
Files cannot be split across disks; therefore, the
maximum file size is normally the maximum disk
size. The file size is also restricted by a 32-bit
file pointer. This means that the maximum possible
file size is 4 gigabytes:
32
4 million K, 2 -1
4.3.1 Disk Format Identification
Beginning with MS-DOS 2.0, Microsoft is promoting the use of
a media descriptor table in the boot sector. This table
contains both a physical description (number of sectors,
sides, tracks, etc.) and a logical description (number of
FATs, directory entries, etc.) of the disk layout. The
media description table allows MS-DOS to accommodate future
floppy disk formats, or formats defined by other
manufacturers but not generated by your FORMAT utility.
Your device driver should assume that the media description
table exists if the first byte of the boot sector is the
first byte of a 3-byte (near) jump or a 2-byte jump.
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-8
4.4 THE ROLE OF THE BOOT SECTOR
Typically, the system ROM will load the reserved (boot)
sector or sectors into memory at power-up or restart. We
recommend that the boot sector do the following:
1. It should read the first sector of the directory
and verify that the first two files on the disk are
IO.SYS and MSDOS.SYS, in that order.
You may choose to have your FORMAT utility generate
different boot sectors for each disk format. Or,
you may create a universal boot sector to read the
media description table and determine where to find
the first directory sector both logically and
physically.
2. If the boot code does not find the MS-DOS files in
the directory, then the boot sector should prompt
the operator that an attempt has been made to boot
from a non-bootable disk. You determine how the
user should continue ("Strike any key" or "Turn
power off").
3. The boot sector must read in the IO.SYS and
MSDOS.SYS files. Alternatively, the boot sector may
read in only IO.SYS, and IO.SYS may then read in
MSDOS.SYS. Only IO.SYS needs to be contiguous on the
disk.
The boot sector must know or calculate where those
files physically begin on the disk (right after the
last directory sector) and how long they are
(contained in directory entries). You must code
(or calculate) the location at which they should be
loaded into memory in the boot sector.
4. The boot sector must transfer control to your entry
point in IO.SYS.
The boot sector does not load COMMAND.COM, as it
will be loaded by SYSINIT.
The SYS command allows users to transfer the operating
system onto a formatted disk that contains no files or
contains an old version of the operating system of equal or
greater size. For the MS-DOS 2.XX version on the IBM PC, the
SYS command was modified to transfer MS-DOS 2.XX system files
onto old 1.XX disks. The new MSDOS.SYS can be placed on the
disk in a non-contiguous format. (IO.SYS is still
contiguous because the new IO.SYS is smaller than the
DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-9
combined sizes of the old IO.SYS and MSDOS.SYS.) The boot
sector is only responsible for loading IO.SYS, although it
must check that MSDOS.SYS is the second file on the disk.
Therefore, IO.SYS may load a non-contiguous MSDOS.SYS.
The logic to facilitate checking through the FAT entries
must be added to IO.SYS because the logic normally resides
in the not-yet-loaded MSDOS.SYS. The logic resides in the
installation part of IO.SYS so that it will be overwritten
when MSDOS.SYS is loaded. This technique should only be
used to use the SYS command to transfer a new, bigger MS-DOS
onto an old disk. It is not useful if you do not have old
disks to support in the field. Note that the various FAT
entries for a non-contiguous MSDOS.SYS may reside in
different FAT sectors making it necessary to read more than
just the first FAT sector into memory.
There is an example of a boot sector on the OEM Sample MS-DOS
Implementation Diskette.
DISK STRUCTURE AND BOOTSTRAP LOADING
CONTENTS
CHAPTER 5 RESIDENT DEVICE DRIVERS
5.1 Introduction 5-1
5.2 Bit 4 5-3
5.3 Installation of Device Drivers 5-5
5.4 The CLOCK Device 5-5
5.5 INIT (Command Code 0) 5-6
5.6 Media Check 5-7
5.7 DMA Boundary Violation 5-9
CHAPTER 5
RESIDENT DEVICE DRIVERS
------------------------------------------------------------
| |
| Note |
| |
| Chapter 2, "Device Drivers," in the MS-DOS Programmer's |
| Reference Manual contains a description of MS-DOS |
| device drivers. Additional information applicable to |
| OEM is included here. |
| |
------------------------------------------------------------
5.1 INTRODUCTION
The IO.SYS file is composed of the "resident" device
drivers. This forms the MS-DOS Basic Input Output System
(BIOS), and these drivers are called upon by MS-DOS to
handle I/O requests initiated by application programs.
One of the most powerful features of MS-DOS is the ability
to add new devices such as printers, plotters, or mouse
input devices without rewriting the BIOS. The MS-DOS BIOS
is "configurable;" that is, new drivers can be added and
existing drivers can be pre-empted. Non-resident device
drivers may be easily added by a user at boot time via the
"DEVICE =" entry in the CONFIG.SYS file. In this section,
these non-resident drivers are called "installable" device
drivers to distinguish them from drivers in the IO.SYS file,
which are considered the resident drivers.
At boot time, a minimum of five resident device drivers (four
character devices and one block device) must be present.
These drivers are in a linked list: the header
of each one contains a DWORD pointer to the next. The last
driver in the chain has an end-of-list marker of -1, -1 (all
bits on).
Each driver in the chain has two entry points: the strategy
entry point and the interrupt entry point. MS-DOS 2.XX/3.XX
does not take advantage of the two entry points: it calls
RESIDENT DEVICE DRIVERS Page 5-2
the strategy routine, then immediately calls the interrupt
routine.
The dual entry points facilitate future multitasking
versions of MS-DOS. In multitasking environments, I/O must
be asynchronous; to accomplish this, the strategy routine
will be called to (internally) queue a request and return
quickly. It is then the responsibility of the interrupt
routine to perform the I/O at interrupt time by getting
requests from the internal queue and processing them. When
a request is completed, it is flagged as "done" by the
interrupt routine. MS-DOS periodically scans the list of
requests looking for those that are flagged as done, and
"wakes up" the process waiting for the completion of the
request.
When requests are queued in this manner, it is no longer
sufficient to pass I/O information in registers, since many
requests may be pending at any time. Therefore, the MS-DOS
2.x/3.x device interface uses "packets" to pass request
information. These request packets are of variable size and
format, and are composed of two parts:
1. The static request header, which has the same
format for all requests.
2. A section that has information specific to the type
of request.
A driver is called with a pointer to a packet. In
multitasking versions, this packet will be linked into a
global chain of all pending I/O requests maintained by
MS-DOS.
The 2.XX and 3.XX versions of MS-DOS do not implement a
global or local queue. Only one request is pending at any
one time. The strategy routine must store the address of
the packet at a fixed location, and the interrupt routine
(which is called immediately after the strategy routine)
should process the packet by completing the request and
returning. It is assumed that the request is completed when
the interrupt routine returns.
To make a device driver that SYSINIT can install, a .BIN
(core image) or .EXE format file must be created with the
device driver header at the beginning of the file. The link
field should be initialized to -1 (SYSINIT fills it in).
Device drivers that are part of the BIOS should have their
headers point to the next device in the list and the last
header should be initialized to -1,-1. The BIOS must be a
BIN (core image) format file produced by using the utility
EXE2BIN.
.EXE format installable device drivers may be used in
RESIDENT DEVICE DRIVERS Page 5-3
non-IBM versions of MS-DOS before 3.0. The reason for this
restriction is that on the IBM PC, the .EXE loader is located
in COMMAND.COM, which is not present at the time that installable
devices are being loaded.
The attribute field and entry points must be set correctly.
If the device is a character device, the name field must be
filled in. (This name can be any 8-character legal
filename). If it is a block device, SYSINIT will fill in the
correct unit count. SYSINIT always installs character
devices at the start of the device list, so if you want to
install a new CON device, simply name it CON. The new one
will be placed ahead of the old one in the list and will
pre-empt the old one because the search for devices stops on
the first match.
Be sure to set the standard input (sti) and standard output
(sto) bits on a new CON device.
------------------------------------------------------------
| |
| Note |
| |
| Since SYSINIT may install the driver anywhere, be |
| careful when coding FAR memory references. You |
| should NOT expect that your installable driver will be |
| located in the same place every time. This does not |
| apply for the resident device drivers. |
| |
|__________________________________________________________|
5.2 BIT 4
In the MS-DOS Programmer's Reference Manual, bit 4 of the ______ ____________ _________ ______
device driver header format is defined as reserved. It
actually has special meaning.
Bit 4, the special bit, applies to CON drivers. The new
interface supports many new features, but it is slower than
MS-DOS 1.x if old style "single-byte" system calls are made.
To make most efficient use of the interface, all
applications should block their I/O as much as possible.
For example, you should make one XENIX-style system call to
output x number of bytes rather than x system calls to
output one byte each.
RESIDENT DEVICE DRIVERS Page 5-4
Putting a device channel in raw mode provides an even faster
way to output characters. (See the Glossary for an
explanation of "raw" mode.) Bit 4, has been implemented to
alleviate the CON output speed problem for older programs
that use system calls 01H to 0BH to output large amounts of
data. If this bit is 1, the device is CON and an Interrupt
29H has been implemented, where the 29H handler is defined
as follows:
CONSOLE OUTPUT via INT 29H handler
Input: Character in AL
Function: Output the character in AL
to the screen at the current
cursor location.
Output: None
Registers: All registers except BX must be
preserved. No registers except
AL have a known or consistent
value.
If a character device implements the special bit, the driver
must install an address at the correct location in the
interrupt table for Interrupt 29H. Only one device driver
can have the special bit set in the system. There is no
check to ensure this state.
____________________________________________________________
| |
| Warning |
| |
| This feature may not be supported in future versions of |
| MS-DOS. Any application (not device driver) that uses |
| Interrupt 29H directly will not work on future versions.|
| In addition, the console device driver must be tested |
| with bit 4 not set to ensure that it will work with such |
| future versions of MS-DOS. |
| |
____________________________________________________________
The headers of resident drivers should point to the next
device in the list and the last header should be initialized
to -1,-1. IO.SYS must be a .COM format file.
RESIDENT DEVICE DRIVERS Page 5-5
5.3 INSTALLATION OF DEVICE DRIVERS
MS-DOS 2.XX/3.XX allows new device drivers to be installed
dynamically at boot time. This is accomplished by the
SYSINIT module(s) supplied by Microsoft, which read(s) and
processes the CONFIG.SYS file. The resident driver source
file (IO.ASM) is assembled and linked to the appropriate SYSINIT
module(s) and SYSIMES.OBJ. The resultant .EXE file must
be converted via EXE2BIN to create the file IO.SYS. This
should be the first file that appears on the system disk.
When block drivers are installed, the logical drive letters
are assigned in list order; thus, the driver that will have
logical A must be the first unit of the first block device
in the list. The order of character devices is also
important. There must be at least four character devices
defined at boot time. The first four character devices must
be as follows:
1. Standard input, standard output, and standard error
output (CON)
2. Standard auxiliary input and output (AUX)
3. Standard list output (PRN)
4. Date/time (CLOCK)
The linked list of device drivers must look like this:
->CON->AUX->PRN->CLOCK->any other block or
character devices
5.4 THE CLOCK DEVICE
The CLOCK device is used by MS-DOS 2.XX/3.XX for marking file
control blocks and directory entries with date and time as
well as providing date/time services to application
programs. It is unique in that MS-DOS will read or write a
6-byte sequence which encodes the date and time. A write to
this device will set the date and time and a read will get
the date and time.
Figure 5.1 illustrates the binary date and time format used
by the CLOCK device.
RESIDENT DEVICE DRIVERS Page 5-6
byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
+--------+--------+---------+--------+--------+---------+
| | | | | | |
|days since 1-1-80| minutes | hours | sec/100| seconds |
|low byte|hi byte | | | | |
+--------+--------+---------+--------+--------+---------+
Figure 5.1. CLOCK Device Format
5.5 INIT (COMMAND CODE 0)
One of the functions defined for each device is INIT. This
routine is called only when the device is installed. It is
used for initializing character and block devices.
Figure 5.2 illustrates the format of INIT.
+------------------------------------+
| 13-BYTE Request Header |
+------------------------------------+
| BYTE # of units |
+------------------------------------+
| DWORD Break Address |
+------------------------------------+
| DWORD Pointer to BPB array |
| (not set by character devices) |
+------------------------------------+
Figure 5.2. INIT Format
For resident character devices:___ ________ _________ _______
No parameters are passed, and none are returned.
For resident block drivers:___ ________ _____ _______
Unlike character device drivers, block device drivers must
return a number of parameters. The following data are
returned:
1. The number of units defined by this block device
driver. This is used to determine logical device
names. If the current maximum logical device
letter is F at the time of installation, and the
INIT routine returns 4 as the number of units, then
those units will have the logical names G, H, I and
J. This mapping is determined by the position of
RESIDENT DEVICE DRIVERS Page 5-7
the driver in the device list and the number of
units defined by the device (stored in the first
byte of the device name field). You must return
this number at offset 13D in the INIT call, even
though the number of units is stored in the device
header.
2. A DWORD pointer to an array of WORD offsets to BPBs
(BIOS Parameter Blocks). There must be one entry
for each unit defined by the device driver. If the
device driver defines two units, then the DWORD
pointer points to the first of two one-word offsets
which, in turn, point to BPBs. If both BPBs are
the same, this will allow you to save space by
entering two offsets to the same location.
The BPB is used by MS-DOS to create an internal DOS
structure. The BPBs that are returned by the resident
device drivers are scanned to determine the largest sector
size. This number is used to set the cache buffer size.
Installable block devices cannot have larger sector sizes
than those defined by the resident drivers. For this
reason, you may want to use dummy BPBs to reserve space.
Use an invalid media byte so that when you later report the
correct BPB for the unit. MS-DOS will build the correct
internal DOS structure for the particular drive unit.
5.6 MEDIA CHECK
The MEDIA CHECK function is called when there is a pending
drive access call other than a file read or write (i.e access
to the "FILENAME space" - Open, Close, Get_disk_size, INT 25H,
INT 26H, etc.). Its purpose is to determine whether the media
in the drive has been changed. Note that the previous media ID
byte is passed to the device driver. Although the old media ID
byte is the same as the new one, the disk may have been changed
and a new disk may be in the drive; therefore, the FAT, and
directory and data sectors for the unit are invalid.
MS-DOS 3.XX imposes stricter conditions than MS-DOS 2.XX on
when media changes are allowed. This can lead to MEDIA
CHECK routines that seemed to work correctly under MS-DOS
2.XX causing problems under MS-DOS 3.XX.
MS-DOS performance is greatly improved if MEDIA CHECK uses a
doorlock or some other detection method so that it can
guarantee that no disk change has occurred; then MS-DOS
does not have to reread the FAT before each directory
access.
MEDIA CHECK can directly use the door-lock mechanism to
return "Disk not changed." However, the door-lock mechanism
RESIDENT DEVICE DRIVERS Page 5-8
indicating that the door has been opened does not
necessarily mean that the disk has been changed, since the
user could have reinserted the same disk. MEDIA CHECK
routines that return "Disk has been changed" just because
the door has been opened will cause problems under MS-DOS
3.x, but not under MS-DOS 2.XX.
The recommended behavior for MEDIA CHECK is to return as
follows:
Disk has not been changed - whenever the door lock
indicates that the door
has not been opened
Don't know - under all other
circumstances
It is possible for MEDIA CHECK to try to determine whether a
disk has really been changed by checking the Volume ID;
however, many disks have no Volume ID. Therefore, it is
safer and quicker for MEDIA CHECK to simply return "Don't
know." The action that MS-DOS takes depends on the state of
its internal file storage buffers. In general, if "Don't
know" is returned when MS-DOS has data in its internal
buffers (data that needs to be written out), MS-DOS will
assume no disk change has occurred. Otherwise, with empty
buffers or all buffers "clean", MS-DOS assumes the disk has
been changed.
The possible problems caused by an incorrect MEDIA CHECK
routine can be checked as follows:
1. Load MS-DOS 3.XX
2. Ensure the disk is write-protected
3. COPY FILE1 FILE2
4. Write Protect Error from MS-DOS
5. Remove the write protection from the disk
6. Reinsert the disk in the drive
7. Press "R" to cause MS-DOS to retry
8. Copy success message
If an incorrect MEDIA CHECK routine is in use, the Dir
command will show FILE2 with a size of zero bytes, and
Chkdsk will report "lost clusters." Note that the copy
process always returns the success message even with an
incorrect MEDIA CHECK routine.
The above test should also be repeated with a "Drive Not
Ready" error condition instead of the Write Protect error.
The same symptoms will be displayed.
For more information on MEDIA CHECK, refer to the MS-DOS ______
Programmer's Reference Manual.____________ _________ _______
RESIDENT DEVICE DRIVERS Page 5-9
5.7 DMA BOUNDARY VIOLATIONS
Some OEMs check for any DMA boundary violations on disk
operations. If a DMA boundary violation error is detected
then action is taken to prevent this error from being
reported to the DOS. The sample IO.SYS handles the problem in
the following way. The operation is tried and if a DMA boundary
violation is reported, then a flag (in this case bl) is set
to indicate that we need to do a memory swap to avoid the
boundary problem. The sector of data that causes the DMA
boundary violation is transfered into an internal buffer
that belongs to IO.SYS and then is copied into the buffer
specified in the original request.
In other words, the request is broken into several pieces
consisting of a request for the data up to the DMA boundary
violation, then the one sector of data that causes the DMA boundary
violation (in the sample IO.SYS SwapMemory routine is responsible
for doing this), and then the rest of the request as specified
by the original disk operation.
Applications do not depend on this feature in any direct way.
However, if you do not implement the DMA boundary checking then
it would be possible for an application to get an INT24 error because
of the DMA boundary problem and thus behave differently
depending on how the BIOS was implemented.
CHAPTER 6 SYSINIT AND MS-DOS INITIALIZATION
6.1 Introduction 6-1
6.2 The Role of SYSINIT 6-3
6.3 COMMAND.COM 6-5
CHAPTER 6
SYSINIT AND MS-DOS INITIALIZATION
6.1 INTRODUCTION
In addition to implementing the resident drivers and
performing any hardware initialization, the IO.ASM code must
initialize certain external variables. These variables are
declared public in the SYSINIT module(s) to which the IO.OBJ
module is linked. The public variables and their functions
are described below.
CURRENT_DOS_LOCATION WORD
This is the paragraph location where the bootstrap loader
(or, optionally, IO.SYS) has loaded MSDOS.SYS into memory.
Typically, MSDOS.SYS is located immediately after IO.SYS.
FINAL_DOS_LOCATION WORD
Since SYSINIT immediately relocates itself to high memory,
there will be a hole right after the resident drivers. By
telling SYSINIT the paragraph where you want it to relocate
MSDOS.SYS, you can fill up this hole plus overlay any code
that IO.SYS used for hardware initialization at boot time.
SYSINIT will move MSDOS.SYS down to this location,
conserving space. This location also defines where memory
starts for MS-DOS.
DEVICE_LIST DWORD
IO.SYS must tell SYSINIT where the linked list of device
drivers begins. This is the location of the CON device
driver header; the information is passed to MS-DOS so that
the drivers can be accessed.
SYSINIT AND MS-DOS INITIALIZATION Page 6-2
MEMORY_SIZE WORD
This word is the paragraph number of the highest location in
RAM. If you do not initialize MEMORY_SIZE, SYSINIT will do
a memory scan to determine the amount of memory. It does
this by reading every 16 bytes starting at 32K, writing an
arbitrary pattern, reading it back for a match, and
returning the original value. It stops when it gets a
mismatch. If your system has parity memory, you must
declare this value, since writing to nonexistent memory will
cause a parity error.
MS-DOS should be implemented in systems with contiguous
memory.
DEFAULT_DRIVE BYTE
If you can boot MS-DOS from several drives, you must tell
SYSINIT which drive you booted from so it can find
CONFIG.SYS and COMMAND.COM. This variable should be set as
follows: drive A = 1, drive B = 2, etc. If DEFAULT_DRIVE
is not set, the default drive (drive A) is assumed.
BUFFERS BYTE
This is the default number of sector buffers for the system.
The BUFFERS value may be overridden by the user in the
CONFIG.SYS file. On versions of MS-DOS up to 3.1, the default
number of buffers is 2. On versions of MS-DOS after 3.1,
3 buffers will be allocated if there is a floppy drive in the
hardware configuration with a capacity greater than 360KB.
Beginning with 3.3, if memory size is greater than 128K, then
5 buffers will be allocated, and if memory is greater than
256K 10 will be allocated; if memory is greater than 512K, 15
buffers will be allocated.
The value specified for the number of buffers must be greater
than or equal to 1.
FILES BYTE
This is the default number of open files that system calls
2FH-62H can access. This value may be overridden by the
user in the CONFIG.SYS file. Its default setting in SYSINIT
is 8. Values of less than 5 are ignored.
The entry point in SYSINIT should be defined as a FAR label
in IO.SYS as follows:
EXTRN SYSINIT:FAR
After IO.SYS code has performed any hardware initialization
and has set the above external variables, it should do a FAR
jump to this label.
SYSINIT AND MS-DOS INITIALIZATION Page 6-3
You must provide a FAR procedure in the IO.ASM code which is
not subject to being overlayed when SYSINIT relocates
MS-DOS. This procedure is called RE_INIT. It should be
declared as follows:
RE_INIT: PROC FAR
........
........
RET
RE_INIT ENDP
The RE_INIT procedure is called by SYSINIT after MS-DOS is
installed. On entry, DS:0 points to a 100H-byte program
segment prefix which represents the Program Segment Prefix
of SYSINIT and IO.SYS taken together. This is not a normal
program because no memory is allocated to it; therefore, if
you allocate and load or Exec, you may overlay this block.
SYSINIT is located in the top 10K of memory. Do not write __ ___ _____
there. The space above the 100H byte header at DS:100 is_____
available for temporary use during RE_INIT.
The RE_INIT routine can be used to perform functions such as
to print headers and read files, and it is handy for IO.SYS
debugging. If you don't need to use this procedure, simply
do a return (RET). Note that starting with MS-DOS 3.XX,
RE_INIT may not use FCB system calls.
------------------------------------------------------------
| |
| Warning |
| |
| RE_INIT must not change any registers or flags. |
| |
|__________________________________________________________|
Beginning with MS-DOS 3.2, another FAR procedure must be provided in
IO.ASM. The name of this procedure is STACKINIT.
The purpose of this procedure is to initialize a hardware stack
switching algorithm. If some of the hardware interrupt handlers in the
ROM BIOS of the OEM hardware system are stack intensive, then
this initialization routine would be used to direct the processing
of the hardware interrupt handlers to another portion of code in
IO.ASM. This code will save the current stack setup and switch stacks to
an internal space on occurrence of a hardware interrupt.
When the stack has been switched the original interrupt handler
is called. The rest of the interrupt handling will use the internal
stack and not the stack that was in use when the interrupt occurred.
When the interrupt handler returns the stack is set to its original
state.
The advantage of this feature is that there is greater system reliability
since a dedicated stack space is being used for interrupt handling.
The OEM should determine which hardware interrupt handlers are stack
intensive and redirect only those interrupts to the stack switching code
in IO.ASM.
This procedure is similar to the FAR procedure RE_INIT in that the code
is not subject to being overlayed when SYSINIT relocates MS-DOS.
The procedure STACKINIT should be declared in the same fashion as RE_INIT.
After MS-DOS is installed, SYSINIT calls the procedure STACKINIT. If this
procedure is not going to be used, then simply do a return or the OEM
can assemble SYSINIT with the conditional STACKSW set to FALSE. On entry
to this routine, there are three data variables that are available.
These pieces of data reside in the SYSINIT segment. The following
declarations should be made in IO.ASM to access these variables.
SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
EXTRN STACK_ADDR:DWORD
EXTRN STACK_SIZE:WORD
EXTRN STACK_COUNT:WORD
SYSINITSEG ENDS
These variables are set by SYSINIT and can be changed by using the
STACKS option in CONFIG.SYS. The full syntax of the STACKS option is:
STACKS=STACK_COUNT,STACK_SIZE
where
STACK_COUNT is the number of stacks
(range 8 to 64, default 9)
STACK_SIZE is the stack size
(range 32 to 512 bytes, default 128)
The variable STACK_ADDR is the FAR address of the space that SYSINIT
has allocated for the internal stacks.
Beginning with MS DOS 3.3, there is a special case for STACKS=0,0.
This will result in no dynamic stacks being provided. DOS will not
intercept any interrupts and will only use it own standard stack.
____________________________________________________________
| |
| Warning |
| |
| STACKINIT must not change any registers or flags. |
| |
------------------------------------------------------------
6.2 THE ROLE OF SYSINIT
The following steps illustrate the role of SYSINIT in MS-DOS
initialization:
1. When SYSINIT gains control from the IO.SYS
initialization code, it determines the size of
memory (performing a scan if requested, based on
value of MEMORY-SIZE) and, based on the highest
paragraph and the size of SYSINIT, it relocates
itself to high memory.
SYSINIT AND MS-DOS INITIALIZATION Page 6-4
2. Running in high memory, SYSINIT moves MSDOS.SYS
from the CURRENT_DOS_LOCATION to the
FINAL_DOS_LOCATION as specified by IO.SYS (see the
memory maps in Section 6.3, "COMMAND.COM").
3. SYSINIT does a FAR call to MS-DOS. MS-DOS has
initialization code which steps through the linked
list of device drivers and performs the INIT call
to each. The copyright message is then printed out
on the screen.
4. After initializing the resident devices, building
drive parameter blocks for the resident block
devices, and installing a sector buffer, MS-DOS
does a FAR return to SYSINIT.
During MS-DOS initialization, MS-DOS examines the
BIOS Parameter Blocks (BPBs) returned by the INIT
call to the block devices. It uses the largest
sector size it finds as the default buffer size for
all buffers. For this reason, the initial BPBs may
be used to reserve space for an installable device
with a larger sector size rather than reflecting
the format of the installed disk. In this case,
these dummy BPBs must have media bytes that do not
have the same value as those used in real BPBs.
5. SYSINIT calls RE_INIT in IO.ASM to allow the OEM to
print headers or handle any other initialization.
------------------------------------------------------------
| |
| Warning |
| |
| Do not attempt to modify memory. |
| |
|__________________________________________________________|
6. After IO.SYS returns control to SYSINIT, SYSINIT
attempts to open the CONFIG.SYS file. If found,
this file is loaded in memory and all characters
are turned to uppercase. It is then parsed looking
for keywords such as DEVICE, BUFFERS, and SHELL.
Any new devices are loaded, added to the linked
list, and installed via the INIT call. Character
devices are added to the front of the list, and new
block devices are added to the end. Thus, a new
CON device can supplant an existing resident CON
device. This provides the facility to reconfigure
IO.SYS except for the Resident Disk Block device
driver.
SYSINIT AND MS-DOS INITIALIZATION Page 6-5
7. SYSINIT allocates all of the memory it needs to
protect the buffers, installed device driver code,
and IO.SYS. It sets the "owner" of the memory to a
special value to ensure that this block of memory
is never deallocated.
8. SYSINIT closes all file handles, and then reopens
CON, AUX, and PRN. This enables a new CON, AUX or
PRN device to replace the resident devices.
9. SYSINIT allocates memory for the buffers.
10. SYSINIT allocates memory for hardware stacks and
calls STACKINIT to initialize the hardware stack
switching algorithm (only in versions of DOS 3.2
and later).
11. SYSINIT executes COMMAND.COM.
12. COMMAND.COM allocates memory for its transient portion
and moves it.
MS-DOS is now up and running.
6.3 COMMAND.COM
During its initialization, COMMAND.COM allocates memory for
its transient part and reloads it. The transient part of
COMMAND, which contains the internal commands (Copy, Dir,
Date, Time, etc.), resides in unprotected memory when a
user's program is loaded into the Transient Program Area
(TPA). It will be overlaid by programs needing the space.
When a user program terminates to the COMMAND resident, the
transient is checked to see if reloading is necessary.
SYSINIT AND MS-DOS INITIALIZATION Page 6-6
Each of the following memory maps represents a step in the
MS-DOS initialization process.
+-----------------------------+
| | High memory
| |
| |
| |
+-----------------------------+ Loaded at arbitrary
| Bootstrap loader | location by system ROM
+-----------------------------+ XX:00
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+-----------------------------+ Segment 40H
| Interrupt Vector Table |
+-----------------------------+ -0:00
Memory organization in an MS-DOS
system after the system ROM
has loaded the boot sector.
SYSINIT AND MS-DOS INITIALIZATION Page 6-7
+-----------------------------+
| | High memory
| |
| |
+- - - - - - - - - - - - - - -+
| Spent bootstrap loader |
+- - - - - - - - - - - - - - -+
| |
| |
| |
+-----------------------------+
| | MS-DOS disk operating
| MSDOS.SYS | system in temporary
| | location
| |
+-----------------------------+ Microsoft-supplied
| SYSINIT | system initialization
+- - - - - - - - - - - - - - -+ module (part of IO.SYS)
| |
| IO.SYS | IO.SYS (may begin at
+-----------------------------+ any location)
| Interrupt Vector Table |
+-----------------------------+
Memory after bootstrap loader
loads IO.SYS and MSDOS.SYS.
SYSINIT AND MS-DOS INITIALIZATION Page 6-8
+-----------------------------+
| SYSINIT | High memory
| relocates itself to highmem |
+-----------------------------+
| |
| |
| |
| |
| |
+-----------------------------+
| |
| MS-DOS structures, buffers, | SYSINIT loads installable
| hardware stack space, | drivers and buffers here
| and installable drivers |
+-----------------------------+
| |
| MSDOS.SYS relocated by | SYSINIT moves MS-DOS
| SYSINIT to fill hole in | down to OEM-designated
| memory. | FINAL_DOS_LOCATION
| |
+-----------------------------+
| IO.SYS |
+-----------------------------+
| Interrupt Vector Table |
+-----------------------------+
Memory during system initialization
performed by SYSINIT module.
SYSINIT AND MS-DOS INITIALIZATION Page 6-9
+-----------------------------+
| COMMAND.COM | High memory
| (transient) |
+-----------------------------+
| | Start of TPA will vary
| Transient Program Area | with # of drivers,
| (TPA) | buffers, etc.
+-----------------------------+
| COMMAND.COM (resident) | COMMAND.COM loads its
+-----------------------------+ transient part into top
| | of largest available
| MS-DOS structures, buffers | memory
| hardware stack space, |
| and installable drivers |
+-----------------------------+
| |
| |
| MSDOS.SYS |
| |
| |
+-----------------------------+
| |
| IO.SYS |
| resident device drivers |
+-----------------------------+
| Interrupt Vector Table |
+-----------------------------+
Memory after SYSINIT installs command interpreter.
This represents the normal configuration
during MS-DOS operation.
SYSINIT AND MS-DOS INITIALIZATION
CONTENTS
CHAPTER 7A WRITING THE FORMAT MODULE FOR MS-DOS 3.20/3.21
7.1 Introduction 7-1
7.2 Format Modules and the ES Register 7-9
7.3 Changing the Logical Format of Disks 7-9
CHAPTER 7B
WRITING THE FORMAT MODULE
MS-DOS 3.20/3.21
HIGHLIGHTS OF CHANGES IN 3.2X OVER PREVIOUS 2.XX FORMAT VERSION:
o FORMAT is now designed to be an .EXE file.
o The FBIGFAT variable has been introduced for 16-bit
FAT support.
o ALLOCATEFAT routine allows space for the FAT to be
dynamically allocated.
o Hardware specific functionality assumed to be provided
by device drivers.
HIGHLIGHTS OF CHANGES IN 3.20 OVER PREVIOUS FORMAT VERSIONS:
The intention of the MS-DOS 3.2 FORMAT utility is to
reduce the amount of OEM work and also move any machine
dependencies to the device drivers (software BIOS).
The following are the new features of the MS-DOS 3.2
FORMAT utility:
o FORMAT is now designed to be hardware independent.
The FORMAT utility no longer makes calls directly to
the ROM BIOS to perform the format operation. The direct
calls to the ROM BIOS have been replaced with MS-DOS
system calls (Generic IOCTL's) that perform the necessary
format functions. The responsibility for interacting
with the ROM BIOS to deal with the formating functions is now
placed in the OEM's device drivers.
o The current head and cylinder being formated is displayed in the
layout:
Head: %d Cylinder: %d
o Two new switches have been added to FORMAT. The new switches
are:
/N:xx - Specifies the number of sectors/cylinder
on the media.
/T:yy - Specifies the number of tracks on the media.
These two options will only be useful if the ROM BIOS has support
to deal with changing of the disk drive parameters.
o FORMAT will no longer format the default drive if no drive was
specified on the command line.
7.1 INTRODUCTION
The MS-DOS Format command formats a new disk, clears the FAT
and directory, and optionally copies system files and
COMMAND.COM to the new disk. The 3.2X Format utility no
longer requires the hardware specific code supplied by the
OEM in previous versions. Instead, Format relies on the
drive device driver to provide the functionality required
to format a track on that drive. The Format utility uses a
GENERIC_IOCTL function request to access the drive device
driver to format a track on the drive. If the device driver
does not support a format track function the Format utility
will not be able to format the drive.
FORMAT is shipped in two hardware-independent object
modules. These must be linked to a system configuration
dependant module written by the OEM. The following section
describes the routines required in this module. A sample
OEM format module is included on the MS-DOS release disks
to assist in writing these routines.
The syntax for the Format command is:
Format drive: [/switch1][/switch2]...[/switch16]
"drive:" is a legal drive specification. As many as 16
legal switches can be included in the command line.
7.2 CODE AND DATA FROM THE OEM
As the OEM may need to tailor the FORMAT module for a particular
system configuration the OEM must supply the routines and data
items which are specific to that configuration. The OEM should
produce a module, eg. OEMFOR.ASM, which contains the following
(NEAR) data items;
SWITCHLIST
DOSFILE
BIOSFILE
and the following (NEAR) routines;
OEMDONE
WRITEBOOTSECTOR
CHECKSWITCHES
LASTCHANCETOSAVEIT
The detailed description of the data items required to be declared
public in the OEM's module is as follows;
SWITCHLIST
A string of bytes. The first byte is count
n, followed by n characters that are the
switches to be accepted by the command line
scanner. Alphabetic characters must be in
uppercase (the numeric characters 0-9 are
allowed). The last six switches, normally
"/N","/T","/C","/O", "/V" and "/S", have
predefined meanings.
The "/S" switch is the switch that causes the
system files IO.SYS, MSDOS.SYS, and
COMMAND.COM to be transferred to the disk
after it is formatted, thus making a system
disk. The switch can be some letter other
than "S", but the last switch in the list is
assumed to have the meaning "transfer
system," regardless of what the particular
letter is.
The second to the last switch, "/V", causes
FORMAT to prompt the user for a volume label
after the disk is formatted. As with "/S",
the particular letter is not important but
rather the position in the list.
The third to the last switch, "/O", causes
FORMAT to produce an IBM Personal Computer
DOS version 1.x-compatible disk. Normally
FORMAT causes a 0 byte to be placed in the
first byte of each directory entry instead of
the 0E5H free entry designator. This
markedly increases the performance of a
directory search due to an optimization in
the DOS. Disks made with this switch cause
trouble on IBM PC DOS 1.x versions which did
not have this optimization. The 0 byte fools
IBM 1.x versions into thinking these entries
are allocated instead of free. Note that IBM
Personal Computer DOS version 2.10 and MS-DOS
version 1.25 have no trouble with these
disks, since they have the same optimization.
The "/O" switch causes FORMAT to redo the
directory with a 0E5H byte at the start of
each entry so that the disk may be used with
1.x versions of IBM PC DOS, as well as with
MS-DOS 1.25/2.XX and IBM PC DOS 2.00/2.10.
This switch should only be given when needed
because it takes a fair amount of time for
FORMAT to perform the conversion, and it
noticeably decreases 1.25 and 2.x performance
on disks with few directory entries.
A "/C" switch is specified for "Clear". This
switch should cause the formatting operation
to be bypassed (within DISKFORMAT or
BADSECTOR). This is provided as a
time-saving convenience to the user, who may
wish to "start fresh" on a previously
formatted and used disk.
The "/T:<xx>" option is used to specify the
number of tracks that Format will place on
a floppy disk.
The "/N:<xx>" option is used to specify the
number of sectors per track that Format will
use to format a floppy disk.
BIOSFILE & DOSFILE
The BIOSFILE and DOSFILE data strings are used to
specify the filenames for the hidden BIOS and DOS
system files written to the formatted disk when
the /s option is selected.
The filename strings should be null terminated root
directory specifications commencing with a dummy
non-zero drive letter byte which will be modified
by the FORMAT module at run-time.
eg.
BIOSFILE db "x:\IO.SYS",0
DOSFILE db "x:\MSDOS.SYS",0
The following data is declared PUBLIC in Microsoft's
FORMAT module and may be used by the OEM's module
as required.
SWITCHMAP
A WORD value with a bit vector indicating
which switches are included in the command
line. The correspondence of the bits to the
switches is determined by SWITCHLIST. The
extreme right (highest-addressed) switch in
SWITCHLIST (which must be the system transfer
switch, normally "/S") corresponds to bit 0,
the second from the right, normally "/V" to
bit 1, etc. For example, if SWITCHLIST is
the string "7,'AGI2OVS'", and the user
specifies "/G/S" on the command line, then
bit 6 will be 0 (/A not specified), bit 5
will be 1 (/G specified), bits 4,3,2 and 1
will be 0 (neither I,2,O or V specified), and
bit 0 will be 1 (/S specified).
FBIGFAT
BYTE which takes on one of two possible
values, 0 or 0FFH. WARNING: Any value other
than 0 or 0FFH will cause FORMAT to do very
odd things. The value 0 indicates that the
disk being formatted will have a 12-bit FAT.
The value 0FFH means that the disk being
formatted will have a 16-bit FAT.
DRIVE
A byte value containing the drive specified
in the command line. 0=A, 1=B, etc.
DRIVELETTER
A byte value containing the ASCII value of
the drive letter specified in the command
line.
DEVICEPARAMETES
A structue containing the device parameters of
the drive to be formatted. The format of the
DEVICEPARAMETERS data structure is as follows;
DP_SpecialFunctions : BYTE
DP_DeviceType : BYTE
DP_DeviceAttributes : WORD
DP_Cylinders : WORD
DP_MediaType : BYTE
DP_BPB : BPB
DP_TrackTableEntries : WORD
DP_sectorTable : BYTE TABLE
INBUFF
A string buffer used to return a character
string entered from the keyboard in the
user_string routine in the FORMAT module.
CURRENTHEAD
A word value containing the drive head
which was being formatted when an error
occurred.
CURRENTCYLINDER
A word value containing the drive cylinder
which was being formatted when an error
occured.
FLASTCHANCE
A byte value used to flag whether a format
message is to printed at the start of
a format attempt.
NUMSECTORS
A word value containing the number of
sectors specified in the command line
with the /n switch.
TRACKCNT
A word value containing the number of
sectors specified in the command line
with the /t switch.
The detailed description of the routines required to be declared
public in the OEM's module is as follows;
OEMDONE
This routine is called after the formatting has
been completed, the disk directory has been
initialized and the system has been transferred
if specified. It is called once for each disk to
be formatted. This gives the chance for any
finishing up operations, if needed. If the OEM
desires extra files to be put on the formatted
disk by default, or according to a switch, this
could be done in OEMDONE.
The OEMDONE routine should also check for the /b
switch and, if present, should notify the FORMAT
module of a non-standard system size by calling
the ADDTOSYSTEMSIZE routine in the FORMAT module.
The following data items form the inputs to the
OEMDONE routine;
SwitchMap : A WORD vaule indicating which
switches were selected. The
format of the SwitchMap is
as described previously.
The OEMDONE outputs should be;
Carry Flag : Set on error, else clear.
If an error status is returned
by OEMDONE, the error message
"Format failure" and a prompt
for another disk will be
displayed.
WRITEBOOTSECTOR
This routine is called once for each disk formatted
after the format has occured but prior to installing
a system on the disk.
The routine writes the OEM specific boot sector(s)
to the disk. The first boot sector must be written
to the disk with an initialized BPB. The boot code
may be contained within the OEMFOR module and copied
to the boot sectors by this routine or may be
written to the boot sectors after the format using a
separate OEM utility as long as the BPB is written
in this routine.
The functionality of the code and data required in
the boot sector(s) is discussed in detail in
section 4.4 .
If an error occurs while writing the boot sector(s)
the routine should display an error message and
return with the carry flag set.
CHECKSWITCHES
This routine is called once before any disks have
been formatted. It is used to verify that the
switches selected are a legal combination for the
drive type to be formatted and to modify the drive
device parameters according to the selected switches
if they are valid. For example the valid swith
combinations for supported drive types could be;
Disk Type Valid switches
160/180KB /l /4 /8 /b /n /t /v /s
320/360KB /l /4 /8 /b /n /t /v /s
720KB /n /t /v /s
1.2MB /n /t /v /s
Hard disk /v /s
The CHECKSWITCH routine is included in the OEMFOR
module so that the OEM may decide what action to
take for an OEM specific drive type with the switch
combination selected.
The following data items form the inputs to the
CHECKSWITCHES routine;
deviceParameters : A data structure containing
the drive parameters for the
drive to be formatted. The
fields of this structure are
as descibed previously.
SwitchMap : A WORD vaule indicating which
switches were selected. The
format of the SwitchMap is
as described previously.
NumSectors : A WORD value containing the
number of sectors specified
with the /n switch if it was
present in the command line.
NumTracks : A WORD value containing the
number of tracks specified
with the /t option if it was
present in the command line.
The CHECKSWITCHES outputs should be;
Carry Flag : Set on error, else clear.
deviceParameters : Device parameters to use in
the format operation. Should
have been modified by
CHECKSWITCES if a legal switch
combination specifies parameter
modification.
NumSectors : If the /n switch was not present
in the command line then the
CHECKSWITCHES routine should
initialize the NumSectors WORD
from the deviceParamaters
structure.
Trackcnt : If the /t switch was not present
in the command line then the
CHECKSWITCHES routine should
initialize the Trackcnt WORD
from the deviceParamaters
structure.
LASTCHANCETOSAVEIT
This routine is called when an error, other
than a write protect or not ready error,
occurs during the disk format. It gives the
OEM a chance to modify the disk parameters
to be used in the format operation. The
format will then be tried with these parameters.
An example of when this could be used is if
the format fails on the second head (track
zero), the OEM may want to try formatting
the disk single sided.
The LASTCHANCETOSAVEIT inputs are:
deviceParameters : A data structure containing
the drive parameters for the
drive being formatted when
the error occurred. The fields
of this structure are as
described previously.
currentCylinder : A WORD value indicating the
drive cylinder on which the
error occurred.
currentHead : A WORD value indicating the
drive head on which the error
occurred.
The LASTCHANCETOSAVEIT outputs should are:
Carry Flag : Set if the error was fatal and
no attempt is to be made to
re-format the drive, else clear.
deviceParameters : Modified to contain the new
parameters for the re-format,
if a re-format attempt required.
fLastChance : A BYTE value set to TRUE if an
attempt to re-format the drive
is required. This prevents
multiple format messages for
a single drive format.
The following routines are declared PUBLIC in Microsoft's
FORMAT module and may be used by the OEMFOR module
as required.
ADDTOSYSTEMSIZE
Adds to the number of sectors reserved for the system.
INPUTS : ax = size of system file in bytes.
OUTPUTS : None.
PRINTSTRING
Displays a character string.
INPUTS : dx = near pointer to null terminated string.
OUTPUTS : None.
STD_PRINTF
Displays a character string.
INPUTS : dx = near pointer to a near pointer to a
null terminated string.
OUTPUTS : None.
CRLF
Outputs a carriage return and linefeed to the console.
INPUTS : None.
OUTPUTS : None.
USER_STRING
Get a string from the keyboard.
INPUTS : None.
OUTPUTS : Zero flag set if <CR> only was enterred.
String length in BYTE at offset INBUFF + 1.
Console input in INBUFF commencing at offset
INBUFF +2.
Once the OEM-supplied module has been prepared, it must be
linked with Microsoft's FORMAT.OBJ module, and the
FORMES.OBJ module. In 3.XX, there are additional format
modules that must be linked in. If the OEM-supplied module
is called OEMFOR.OBJ, then use the following linker command;
link format forproc formes oemfor printf;
This command produces an executable file called FORMAT.EXE.
NOTE: The OEM's module CAN NOT make the assumption, as it
could in the previous versions, that it is at the "end" of
the memory image. It must use function 48h (allocate
memory) if required.
7.3 FORMAT MODULES AND THE ES REGISTER
If an OEM-written FORMAT module, such as OEMDONE, makes use of
the ES register, the value of ES should be established by the
OEM's code. The contents of the ES register cannot be assumed.
CONTENTS
CHAPTER 7B WRITING THE FORMAT MODULE FOR MS-DOS 2.25/3.10
7.1 Introduction 7-1
7.2 Format Modules and the ES Register 7-9
7.3 Changing the Logical Format of Disks 7-9
CHAPTER 7B
WRITING THE FORMAT MODULE
MS-DOS 2.25/3.10
HIGHLIGHTS OF CHANGES IN 3.XX OVER PREVIOUS 2.XX FORMAT VERSION:
o FORMAT is now designed to be an .EXE file.
o The FBIGFAT variable has been introduced for 16-bit
FAT support.
o ALLOCATEFAT routine allows space for the FAT to be
dynamically allocated.
7.1 INTRODUCTION
The MS-DOS Format command formats a new disk, clears the FAT
and directory, and optionally copies system files and
COMMAND.COM to the new disk. Since the Format command must
perform functions that have no equivalent in MS-DOS function
calls, FORMAT is shipped in two hardware-independent object
modules. These must be linked to a hardware-specific module
written by the OEM. The following section describes the
routines required in this module. A sample OEM format
module is included on the MS-DOS release disks to assist in
writing these routines.
The syntax for the Format command is:
Format [drive:][/switch1][/switch2]...[/switch16]
"drive:" is a legal drive specification. If it is
omitted, the default drive will be used. As many as 16
legal switches can be included in the command line.
WRITING THE FORMAT MODULE Page 7-2
In 3.XX the OEM must supply six (NEAR) routines to the program along
with seven data items. In 2.XX the OEM must supply five (NEAR) routines
to the program along with six data items. The names of the routines are:
ALLOCATEFAT
INIT
DISKFORMAT
BADSECTOR
WRTFAT
DONE
ALLOCATEFAT is used only in 3.XX.
Their flow of control (by the Microsoft module) is like
this:
|
+-------------+
| ALLOCATEFAT |
+-------------+
|
+---------+
| INIT |
+---------+
|
|<------------------------------+
+------------+ |
| DISKFORMAT | |
+------------+ |
|<-------+ |
+-----------+ |-This loop is done |- This loop is
| BADSECTOR | | for each group of | done once for
+-----------+ | bad sectors | each disk to be
|----->--+ | formatted. If
| | variable HARDFLAG
+----------+ | is set then the
| | | loop is only
| WRTFAT | | performed once.
+----------+ |
| |
+------+ |
| DONE | |
+------+ |
+---->--------------------------+
The ALLOCATEFAT, INIT, DISKFORMAT, and BADSECTOR routines
are free to use any MS-DOS system calls, except for calls
that cause disk accesses on the disk being formatted. DONE
may use any calls, since by the time it is called the new ___
disk has been formatted.
WRITING THE FORMAT MODULE Page 7-3
The following data must be declared PUBLIC in a module
provided by the OEM:
SWITCHLIST
A string of bytes. The first byte is count
n, followed by n characters that are the
switches to be accepted by the command line
scanner. Alphabetic characters must be in
uppercase (the numeric characters 0-9 are
allowed). The last three switches, normally
"/O", "/V" and "/S", have pre-defined
meanings.
The "/S" switch is the switch that causes the
system files IO.SYS, MSDOS.SYS, and
COMMAND.COM to be transferred to the disk
after it is formatted, thus making a system
disk. The switch can be some letter other
than "S", but the last switch in the list is
assumed to have the meaning "transfer
system," regardless of what the particular
letter is.
The second to the last switch, "/V", causes
FORMAT to prompt the user for a volume label
after the disk is formatted. As with "/S",
the particular letter is not important but
rather the position in the list.
The third to the last switch, "/O", causes
FORMAT to produce an IBM Personal Computer
DOS version 1.x-compatible disk. Normally
FORMAT causes a 0 byte to be placed in the
first byte of each directory entry instead of
the 0E5H free entry designator. This
markedly increases the performance of a
directory search due to an optimization in
the DOS. Disks made with this switch cause
trouble on IBM PC DOS 1.x versions which did
not have this optimization. The 0 byte fools
IBM 1.x versions into thinking these entries
are allocated instead of free. Note that IBM
Personal Computer DOS version 2.10 and MS-DOS
version 1.25 have no trouble with these
disks, since they have the same optimization.
The "/O" switch causes FORMAT to redo the
directory with a 0E5H byte at the start of
each entry so that the disk may be used with
1.x versions of IBM PC DOS, as well as with
MS-DOS 1.25/2.XX and IBM PC DOS 2.00/2.10.
This switch should only be given when needed
because it takes a fair amount of time for
WRITING THE FORMAT MODULE Page 7-4
FORMAT to perform the conversion, and it
noticeably decreases 1.25 and 2.x performance
on disks with few directory entries.
Up to 16 switches are permitted. Normally a
"/C" switch is specified for "Clear". This
switch should cause the formatting operation
to be bypassed (within DISKFORMAT or
BADSECTOR). This is provided as a
time-saving convenience to the user, who may
wish to "start fresh" on a previously
formatted and used disk.
HARDFLAG
BYTE location which specifies whether the OEM
routine is formatting a fixed disk or a drive
with removable media. A zero means removable
media; any other value indicates a fixed
disk. The status of this byte only affects
the messages printed by the main FORMAT
module. This value should be set or reset by
the OEM-supplied INIT routine.
FATID
BYTE location containing the value to be used
in the first byte of the FAT. Must be in the
range F8H to FFH.
STARTSECTOR
WORD location containing the sector number of
the first sector of the data area.
FATSPACE
WORD location containing the address of the
start of the FAT area. A FAT built in this
area will be written to disk using the
OEM-supplied WRTFAT subroutine. 6K is
sufficient to store any 12-bit FAT. This
area must not overlap the FREESPACE area.
FREESPACE
WORD location that contains the address of
the start of free memory space. This is
where the system will be loaded by the
Microsoft module for transferring to the
newly formatted disk. Memory should be
available from this address to the end of
memory, so it is typically the address of the
end of the OEM module.
WRITING THE FORMAT MODULE Page 7-5
FBIGFAT
BYTE which takes on one of two possible
values, 0 or 0FFH. WARNING: Any value other
than 0 or 0FFH will cause FORMAT to do very
odd things. The value 0 indicates that the
disk being formatted will have a 12-bit FAT.
The value 0FFH means that the disk being
formatted will have a 16-bit FAT. See
ALLOCATEFAT call, below, for details.
FBIGFAT is used only in 3.XX.
The following routines must be declared PUBLIC in the
OEM-supplied module:
ALLOCATEFAT
ALLOCATEFAT is used only in 3.XX. It is
an initialization routine. This routine is
called once at the start of the FORMAT run
after the switches have been processed. This
routine must set the correct values of
FBIGFAT, FATSPACE, and FREESPACE.
With only 12-bit FATs it was convenient to
allocate a FAT area of 6K (maximum size of a
12-bit FAT) as part of the memory image of
FORMAT. With the advent of 16-bit FATs in
DOS 3.XX this is no longer convenient; the
maximum size of of a FAT is 32K.
ALLOCATEFAT is a dynamic space allocator that
allocates enough memory to hold the FAT by setting
the values of FATSPACE and FREESPACE.
ALLOCATEFAT must also set FBIGFAT so that
FORMAT knows whether the disk has a 12 or a
16-bit FAT.
FBIGFAT must be set consistently with the
following FAT rule (see below).
The 16-bit FAT rule:
- Any disk with less than 4086 clusters has a ____ ____
12-bit FAT.
- Any disk with greater than or equal to 4086 _______ ____ __ _____ __
clusters has a 16-bit FAT.
The OEM FORMAT module cannot force a 16-bit
FAT if the total number of clusters is less
than 4086. Similarly, you cannot have a
12-bit FAT on a disk with more than 4085
clusters. If the OEM module does not set
FBIGFAT consistently with the 16-bit FAT
rule, the disk will not be formatted
correctly, and MS-DOS will not access the
disk in the proper manner.
WRITING THE FORMAT MODULE Page 7-6
Currently, there is no error return from
ALLOCATEFAT. It should exit with CARRY
CLEAR, however, so that it is consistent with
the other routines.
The Microsoft 3.XX FORMAT.OBJ is responsible for
checking that the memory needed for the FAT is
actually available to the system. It will
produce a "Insufficient memory for system transfer"
error when memory is inadequate. This error
is produced when memory is inadequate for both
"/S" and non "/S" procedures.
INIT
An initialization routine. This routine is
called once at the start of the FORMAT run
after the switches have been processed. This
routine should perform any functions that
need to be done once per FORMAT run. An
example of what this routine might do is read
the boot sector into a buffer so that it can
be transferred to the new disks by
DISKFORMAT. If this routine returns with the
CARRY flag set, it indicates an error, and
FORMAT will print "Format failure" and quit.
This feature detects conflicting switches
(like specifying both single and double
density) and causes the FORMAT routine to
abort.
DISKFORMAT
Formats the disk according to the options
indicated by the switches and the value of
FATID must be defined when it returns
(although INIT may have already done it).
This routine is called once for each disk to
be formatted. If necessary, it must transfer
the bootstrap loader. If any error
conditions are detected, the carry flag is
set. FORMAT will report a "Format failure"
and prompt for another disk. (If you only
require a clear directory and FAT, all that
DISKFORMAT must do is set the appropriate
FATID, if this has not already been done by
INIT.
BADSECTOR
Reports the sector number of any bad sectors
that may have been found during the
formatting of the disk. This routine is
called at least once for each disk to be
formatted, and is called repeatedly until the
AX register is zero or the carry flag is set.
The carry flag is used just as in DISKFORMAT
to indicate an error, and FORMAT handles it
in the same way. The first sector in the
data area must be in STARTSECTOR for the
returns from this routine to be interpreted
correctly. If there are bad sectors,
BADSECTOR must return a sector number in
WRITING THE FORMAT MODULE Page 7-7
register BX, the number of consecutive bad
sectors in register AX, and clear the carry
flag. FORMAT will then process the bad
sectors and call BADSECTOR again. When
BADSECTOR returns with AX = 0, there are no
more bad sectors; FORMAT clears the
directory and goes on to DONE. For this last
return, BX need not contain anything
meaningful.
FORMAT processes bad sectors by determining
their corresponding allocation unit and
marking that unit with an FF7H in the File
Allocation Table. CHKDSK understands the
FF7H mark as a flag for bad sectors and
accordingly reports the number of bytes
marked in this way.
Actual formatting of the disk can be done in
BADSECTOR instead of DISKFORMAT on a "report
as you go" basis. Formatting continues until
a group of bad sectors is encountered;
BADSECTOR then reports them by returning with
AX and BX set. FORMAT will then call
BADSECTOR again and formatting can continue.
WRTFAT
This routine is called after the disk is
formatted and bad sectors have been reported.
It writes all copies of the FAT from the area
of memory referenced by FATSPACE to the drive
just formatted. It may be possible to use
INT 26H to perform the write, or a direct
BIOS call. Whether this is possible depends
on whether the FAT ID byte is used by the
BIOS to determine the media in the drive. If
it is, these methods will probably fail
because there is no FATID byte on the disk
yet (in this case WRTFAT's primary job is to
get the FATID byte out on the disk).
DONE
This routine is called after the formatting
has been completed, the disk directory has
been initialized, and the system has been
transferred if specified. It is called once
for each disk to be formatted. This gives
the chance for any finishing-up operations,
if needed. If the OEM desires extra files to
be put on the disk by default, or according
to a switch, this could be done in DONE.
WRITING THE FORMAT MODULE Page 7-8
Again, as in BADSECTOR and DISKFORMAT, carry
flag set on return means an error has
occurred; "Format failure" will be printed
and FORMAT will prompt for another disk.
The following data is declared PUBLIC in Microsoft's
FORMAT module:
SWITCHMAP
A WORD value with a bit vector indicating
which switches are included in the command
line. The correspondence of the bits to the
switches is determined by SWITCHLIST. The
extreme right (highest-addressed) switch in
SWITCHLIST (which must be the system transfer
switch, normally "/S") corresponds to bit 0,
the second from the right, normally "/V" to
bit 1, etc. For example, if SWITCHLIST is
the string "7,'AGI2OVS'", and the user
specifies "/G/S" on the command line, then
bit 6 will be 0 (/A not specified), bit 5
will be 1 (/G specified), bits 4,3,2 and 1
will be 0 (neither I,2,O or V specified), and
bit 0 will be 1 (/S specified).
Bits 0,1 and 2 are the only switches used in
Microsoft's FORMAT module. These switches
are used 1) after INIT has been called to
determine if it must load the system; 2)
after the last BADSECTOR call to determine if
the system should be written, E5 directory
conversion should be done, and/or a volume
label should be asked for. INIT may force
these bits set or reset if desired (for
example, some drives may never be used as
system disk, such as hard disks). After
INIT, the "/S" bit may be turned off (but not
on, since the system was never read) if
something happens that means the system
should not be transferred.
After INIT, a second copy of SWITCHMAP is
made internally.It is used to restore
SWITCHMAP for each disk to be formatted.
FORMAT will turn off the system bit if bad
sectors are reported in the system area;
DISKFORMAT and BADSECTOR are also allowed to
change the map. However, these changes
affect only the current disk being formatted,
since SWITCHMAP is restored after each disk.
(Changes made to SWITCHMAP by INIT affect all
disks.)
WRITING THE FORMAT MODULE Page 7-9
DRIVE
A byte value containing the drive specified
in the command line. 0=A, 1=B, etc.
Once the OEM-supplied module has been prepared, it must
linked with Microsoft's FORMAT.OBJ module, and the
FORMES.OBJ module. In 3.XX, there are additional format
that must be linked in. If the OEM-supplied module is called
OEMFOR.OBJ, then use the appropriate linker command.
2.XX LINK FORMAT.OBJ+FORMES.OBJ+OEMFOR.OBJ
3.XX LINK FORMAT.OBJ+FORPROC.OBJ+FORMES.OBJ+OEMFOR.OBJ.PRINTF.OBJ
For 3.XX, the command produces an executable file called
FORMAT.EXE. Note that although the PRINTF.OBJ module
is the last module specified, it does not follow the
OEMFOR module in the memory image. The OEMFOR module
can still make the assumption, as it has in the past,
that it is at the "end" of the memory image.
For 2.XX, the command produces a FORMAT.EXE file which
must be changed to a simple binary. This should be done
with the following command.
EXE2BIN FORMAT.EXE FORMAT.COM
This produces the 2.XX file, FORMAT.COM.
7.2 FORMAT MODULES AND THE ES REGISTER
If an OEM-written FORMAT module makes use of the ES
register, such as DISKFORMAT, the value of ES should be
established by the OEM's code. The contents of the ES
register cannot be assumed.
WRITING THE FORMAT MODULE PAGE 7-10
7.3 CHANGING THE LOGICAL FORMAT OF DISKS
MS-DOS has an internal table which it builds from
information returned by the BIOS BUILDBPB routine.
There is a table maintained for each drive within the
system and it is updated to reflect the media type
whenever a new disk is loaded. Before any access to
the disk directory, MS-DOS calls the BIOS MEDIACHECK
routine. If a disk change is reported, MS-DOS calls
the BIOS BUILDBPB routine to get the new media
information and updates its internal table. It is
important to realize that MS-DOS operates with its own
table and not with any table within the BIOS.
FORMAT can be used to physically reformat the disk from
single to double-sided use. Therefore, the WRTFAT
routine should ensure that the next call to the BIOS
MEDIA CHECK/BUILD BPB routines made by the DOS will set
the media type to the type just formatted. This is
because when the format operation is started, the DPB
(Drive Parameter Block) reflects the media that existed
before the format. This may need to be changed because
the disk media may have been changed due to the format
process. Since this is basically a communication
between the OEM part of the FORMAT utility and the OEM
BIOS, it is up to the OEM to determine the most
efficient and appropriate way to determine the correct
media type. As an example, the FORMAT utility can call
the BIOS and cause the BIOS to return "media changed"
on the next MEDIA CHECK call made by the DOS. The DOS
will then call the BUILDBPB BIOS routine; it must
return the correct BPB for the disk just formatted.
Trying to determine media change externally with the
FORMAT utility calling the DOS will not work. You
must:
o Have the correct BPB in the BIOS, and your
FORMAT utility must communicate that
information down to your BIOS, or
o Your BIOS must detect that the disk has been
changed when the FORMAT utility is used.
Then, the BIOS can look on the disk for the
BPB and tell the DOS what the new BPB is.
The OEM may decide how this can be structured. The
BIOS can be in control and inform FORMAT what was done,
or FORMAT can be in control and inform the BIOS that
the media has changed.
There is an example of an OEM written FORMAT module on the
Sample MS-DOS Implementation Diskette.
CONTENTS
CHAPTER 8 TROUBLE-SHOOTING
CHAPTER 8
TROUBLE-SHOOTING
The following section addresses typical problems that you
may encounter when installing MS-DOS.
Problem:
When I type "r" for Retry when a disk error occurs, the
system crashes.
Typical Cause:
When an error occurs during I/O, your device driver
must report the number of sectors or characters
correctly transferred. If you just set the error bit,
MS-DOS will assume that it was able to read all of the
sectors since the sector count will be the same as that
set by MS-DOS.
Recommendation:
Report the actual number of sectors/bytes transferred
in addition to reporting the error.
Problem:
I am booting up MS-DOS. I see the MS-DOS copyright
message on the screen, but then I get the message "Bad
or missing command interpreter."
Typical Cause:
SYSINIT is executing COMMAND.COM. This is the
conclusion of MS-DOS initialization and is the first
time that the disk must be read successfully. (Failure
to find CONFIG.SYS is not an error.) Either COMMAND.COM
is not on the disk or an invalid Bios Parameter Block
(BPB) has been returned to MS-DOS so it does not
correctly understand the format of the disk.
TROUBLE-SHOOTING Page 8-2
Recommendation:
Check that the correct BPB is being returned and that
COMMAND.COM is on disk. Install debugging code in the
device driver to make sure requests to the device
driver make sense.
Problem:
I am booting up MS-DOS. I get the MS-DOS copyright
message on the screen, but then I get the message "Bad
or missing /DEV/CON."
Typical Cause:
SYSINIT has closed all file handles and is now
reopening them. The first file it opens is /DEV/CON,
which is your console device. The system file table is
examined for this device. /DEV/CON should be present.
If it is not found, some of your IO.SYS code has
destroyed the system file table or MS-DOS itself. This
may happen if you have blown the MS-DOS stack, causing
MS-DOS to write over the file table.
Recommendation:
Use a local stack in your device drivers.
Problem:
MS-DOS is trying to read some sectors starting at an
extremely large or invalid sector number.
Typical Cause:
The BPB that you returned for the drive is bad.
Recommendation:
The INIT and BUILD BPB device driver routines should be
checked.
Problem:
After I jump to SYSINIT, control never comes back.
Typical Cause 1:
You may not have loaded MS-DOS correctly with your
bootstrap loader. SYSINIT must know exactly where
MS-DOS is. MS-DOS must be on a paragraph boundary and
CURRENT_DOS_LOCATION and FINAL_DOS_LOCATION must be
set up accordingly.
TROUBLE-SHOOTING Page 8-3
Recommendation:
Check the location of MSDOS.SYS after bootstrap
loading.
Typical Cause 2:
You are incorrectly reporting the amount of memory in
the system or the memory scan is failing because of a
discontinuity.
Recommendation:
Don't move MS-DOS after bootstrap loading. Don't
request a memory scan. Make sure memory is contiguous.
Typical Cause 3:
MS-DOS can't find the beginning of the device list.
Recommendation:
Check the value passed to SYSINIT to make sure that it
is the correct value for the beginning of the list.
Typical Cause 4:
The driver attributes are wrong. MS-DOS will not look
for the end of list mark if the attributes are wrong.
Recommendation:
Check the device driver attribute words.
Typical Cause 5:
You do not have a driver in the linked list of device
drivers with the CLOCK attribute bit set. This is
necessary before SYSINIT will start looking for FFFF,
FFFF in the last device driver.
Recommendation:
Be sure you have a CLOCK device in your linked list
with its attribute word set properly.
Problem:
Everything was working great, but when I tried to
install a new device, the system wouldn't boot.
Typical Cause:
You are failing to set the BREAK ADDRESS during the
TROUBLE-SHOOTING Page 8-4
device INIT routine. This points to the first byte of
free memory after the device code and data.
Recommendation:
Set the break address.
Problem:
Everything works OK until I define a new drive in
IO.SYS. Then the system won't come up.
Typical Cause:
You are returning invalid data from the INIT call to
the block device driver.
Recommendation:
Examine the INIT call. This is probably not being
handled correctly. You should return a DWORD pointer
to an array of WORD POINTERS to BPBs. The array must be
below the 'break address' returned by INIT. There should
be one array element for each drive defined. The number
of subunits is also returned by the INIT call.
Problem:
My device driver defines two drives, but when I try to
use drive B, I get an "Invalid drive specification"
message.
Typical Cause:
You are not handling the INIT call to the device driver
properly.
Recommendation:
The INIT call should return the value "2" at offset 13
from the beginning of the static request header.
Problem:
When I have a single-sided disk in drive B and remove
it and install a double-sided disk, MS-DOS treats the
double-sided disk like a single-sided disk. I am
returning the correct BPB for the double-sided disk.
Typical Cause:
The media bytes in the BPBs are not unique.
Recommendation:
TROUBLE-SHOOTING Page 8-5
Each BPB has a unique media byte. MS-DOS will not
rebuild its internal DPB structure if the media byte
doesn't change.
Problem:
I have a one-drive system. When I type B:<Return>, I
get an "Invalid drive specification" message, but on
some single-drive machines, MS-DOS prompts me for the
"disk for drive B:."
Typical Cause:
The INIT call is only defining one disk drive and
support for swapping has not been implemented in
IO.SYS.
Recommendation:
Support for disk swapping is implemented at the IO.SYS
file level rather than at the MS-DOS level. The driver
reports two drives and when it sees a request for unit
1 (the second drive), it prints the swap message
directly on the screen.
Problem:
Everything is running fine, but when I run Chkdsk I
find that I only have 60K bytes free, but I have a 128K
machine. I know that DOS and IO.SYS only take up 24K.
What is happening to the missing bytes?
Typical Cause:
The Block Device Driver INIT call is returning a bad
BPB pointer which reports an absurdly large sector
size. This sector size is used to make all of the
sector buffers, and consequently wastes thousands of
bytes. You could have incorrectly set FINAL_DOS_LOCATION
or installed a device driver that returned an 'absurdly
large' break address.
Recommendation:
Fix the block device driver INIT call.
Problem:
Every time I try to do an Allocate Memory call
(Function 48H) or an EXEC call, I get a return code of
8, "Not enough memory."
Typical Cause:
There is no free memory.
TROUBLE-SHOOTING Page 8-6
Recommendation:
Do a Set Block (Function 4AH) call to shrink the size
of the currently allocated block, freeing some memory.
See the section on arenas in the Glossary.
Problem:
When running a program that opens a number of files via
Function Request 3DH, the file open fails even though
the file is present on the disk.
Typical Cause:
You have run out of entries in the system file table.
Recommendation:
Increase the "FILES = " entry in CONFIG.SYS and reboot.
Problem:
Control-S, Control-P, and the other control characters
seem to be ignored by MS-DOS.
Typical Cause:
The non-destructive console read routine is not
implemented properly.
Recommendation:
Check the non-destructive read routine in the console
or other character driver where this problem is
occurring.
Problem:
Sometimes when I am typing a long file to the screen
and press Control-S, the Control-S is ignored and
doesn't stop the scrolling of the file. I have the
same problem with Control-C.
Typical Cause:
Another character has been typed into the type-ahead
buffer first, and the nondestructive read keyboard
status check never sees the Control-S or the Control-C.
Recommendation:
Implement Scroll Lock and Break keys which flush the
TROUBLE-SHOOTING Page 8-7
input queue and put the Control-S/Control-C at the
beginning of the type-ahead buffer.
Problem:
I am trying to use EXE2BIN to convert IO.EXE to IO.SYS.
I get the message "File cannot be converted."
Typical Cause:
You have a "SEGMENT AT NNNN" statement and there is
code or initialized data in that segment. You may also
have a stack segment, which is not permitted.
Recommendation:
Remove the "SEGMENT AT" statement or remove code or
initialized data from the segment.
It is possible, if your code contains FAR references, that
EXE2BIN may request a 'Fixup' address. If your IO.SYS will
always be loaded at the same place in memory, this may be
OK. Check your FAR references in any case.
APPENDIX A
CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION
A.1 CUSTOMIZING MS-DOS
Many manufacturers find it necessary to customize MS-DOS (as
distinct from IO.SYS) to some degree. The function key
table and OEM serial number are often modified. The
function key table is found in the DOSMES.ASM file. Extensive
modification to this table may require modifying the line
input routines in STRIN.ASM, which is available to source
licensees only.
OEM Serial Numbers:
Each OEM is eligible for a unique OEM Serial Number. The Series
is 0 to FF (255). IBM is 00 and we are currently at about 50H
on list.
These numbers are assigned sequentially by MS-DOS Product Marketing
as requested through the OEM's Account Manager.
Once the OEM has this number they can modify the default FF
value in the file DOSMES.ASM that is part of the adaptation
kit. If this is done, when MSDOS.SYS file is built
it will the right value.
It can be patched after they MSDOS.SYS is built by following
the instructions in the README.DOC on the MS-DOS DISTRIBUTION
DISKETTES.
Function Request 30H - Get MS-DOS Version Number will
return the version of the DOS that is being run, the OEM
Serial number and the OEM user number.
To implement OEM user number concept properly each individual
disk shipped should have to have a separate user number patched
in according to the directions in the README.DOC on the
MS-DOS DISTRIBUTION DISKETTES.
The OEM serial number can, however, be used without using the
OEM User Number.
With these numbers properly installed, an application program
could tell which version of MS-DOS was being run, which
OEM had sold it and which customer had bought it.
Internationalization may also require customizing MS-DOS.
The file named DOSMES.ASM contains a case conversion routine
and a table used to translate foreign characters into their
uppercase equivalents. This routine defaults to no case
conversion, and a sample for the IBM PC character set is
included. Note that this table is country-dependent. You
should not translate a lowercase character available on the
keyboard into a uppercase equivalent that is not on the ___
keyboard. For example, in France, translate lowercase c
cedilla into uppercase C (not C cedilla); in Germany,
translate lowercase "a umlaut" into uppercase A umlaut.
DOSMES.ASM also contains country-dependent tables used by
the international system call (Function 38H). MS-DOS
utilities and COMMAND.COM make two system calls to determine
time and date formats and the location of the case
conversion routine. You may supply as many tables as you
wish; however, it is not necessary to supply tables for all
countries in all translations. You should include tables
for all countries into which a language translation is
distributed. For example, French might include tables for
France, Belgium, and Switzerland. All versions should
include a U.S. table as well. There is a pointer in
DOSMES.ASM to the table to which MS-DOS should default if
the user specifies no "COUNTRY =" parameter in CONFIG.SYS.
Country numbers follow the information telephone codes where
two-digit numbers are employed.
CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page A-2
A non-ASCII character text is represented by variables
equated at the beginning of the file. These default to the
IBM PC character set. If your character set is different,
redefine the equates and reassemble, linking the message
file with the code files.
The SORTMES.ASM file contains a table for collating
sequences. This defaults to no mapping; all uppercase
ASCII is sorted before all lowercase ASCII. A sample table
for the IBM PC character set is included. Note that there
is no capability for equating a single character to a
multiple character string or vice versa. Therefore, German
implementations cannot equate an umlaut to "ae", but may
choose to equate it to "a" or have it fall between "a" and
"b".
A.2 EXTENDED CHARACTER SET (ECS) CONSIDERATIONS - MS-DOS 2.25
All ECS characters are two-byte quantities which also display as two
physical character positions (double-written) on the screen and
printer. This imposes some constraints on the IO.SYS keyboard and
screen drivers. MS-DOS ensures that 16-bit ECS characters are treated
as a single logical character from the user's standpoint, rather
than being confused for two characters.
CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page A-3
A.3 INPUT
On input, it is the responsibility of IO.SYS to pass ECS
characters to MS-DOS. IO.SYS must handle all
Kata-kana-to-ECS conversion or any other method used to
enter ECS. IO.SYS always places both bytes of the ECS
character into its buffer at once; however, they are passed
to MS-DOS as if they are two separate single-byte
characters. Therefore, even non-interrupt-driven keyboards
should always have the second byte of the ECS character
waiting by the time the first byte is accepted by MS-DOS.
IO.SYS should never pass an invalid ECS sequence to
MS-DOS.
A.4 OUTPUT
On output, IO.SYS must identify the first byte of an ECS
character, set a flag, and wait for the second byte. Once
the entire ECS character has been received, IO.SYS indexes
into the font table. The font table may be in memory, on
disk, or in a combined memory-disk caching scheme. IO.SYS
may call MS-DOS to read font files stored on the disk in
MS-DOS format. These files should be opened in IO.SYS when
control is passed back to RE_INIT, after MS-DOS has been
initialized.
IO.SYS performs error recovery in case the font files are on
a disk that has been removed. Door lock detection is most
helpful here. Files should be reopened whenever the
potential for a changed disk occurs. MS-DOS screen and
keyboard routines are not reentrant, and cannot be called
from within IO.SYS to facilitate recovery from this error.
A solution to the problem of missing font files is to
display all ECS characters for which no font is in memory
as double-width reverse video blanks.
IO.SYS also must perform error handling in the data stream
where an invalid ECS sequence is sent. Although invalid
characters should never be input from the keyboard, they can
be output by several occurrences:
1. The user can display a garbage file, such as a
binary executable file.
2. A program may have executed a file with bad ECS
data.
3. The manipulation of fixed length fields may have
split a ECS character between its two bytes.
CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page A-4
If any of these occur, the recommended procedure is to
display a double-width reverse video blank character
followed by the single-byte ASCII value for the character
outside of the valid second-byte range. This will help to
resynchronize the data stream as soon as possible.
MS-DOS recognizes double-byte values, such as blank space,
over ECS in its line editing procedures. It also will
accept and display (if appropriate) the second byte where a
single-byte response is anticipated ("Strike any key").
IO.SYS should ensure that a ECS character is never split
across the last column of one physical line and the first
column of the next line. The entire ECS character must
start on the next line. IO.SYS must keep a flag for each
line to determine whether one or two logical backspace
operations should be performed. The "Backspace-Space-
Backspace" destructive operation issued by MS-DOS will work
properly.
For example, starting with column 1, assume that text runs
up to and includes column 79. MS-DOS requests that a
double-byte ECS character be displayed. IO.SYS:
1. Blanks column 80.
2. Sets a flag for that physical line.
3. Moves to the beginning of the next line.
4. Displays both bytes.
MS-DOS requests two backspaces over this ECS character.
If a third backspace is issued, IO.SYS must clear the flag
and perform an extra backspace, returning to column 79
instead of 80. If a space is issued, column 79 will be
blanked. Remember that column 80 was originally blank, so
there is no need to reset it.
If the ANSI screen driver is also implemented, the driver
should never allow only one-half of a ECS character to be
block transferred without blanking it in scrolling regions.
This rule also applies to both the region being moved and
the area into which it is being moved.
APPENDIX B
HOW TO UPGRADE A 2.XX BIOS TO 3.XX
MS-DOS 3.XX provides very few new services that impact device
drivers. The basic BIOS mechanisms are identical to those
in MS-DOS 2.XX. The only changes are that a few new device
driver calls have been added. These calls are not required. ___
There are new device attribute bits that indicate the
presence of these new functions. Old device drivers do not
have these bits set, and thus indicate that the functions
are not present.
There are several new CONFIG.SYS commands. The code for
these is contained in the SYSINIT modules, and there are no
new PUBLICs in SYSINIT, or expected EXTERNs in the BIOS.
First, to quickly bring up MS-DOS 3.XX with a 2.XX set of
device drivers, all that you need to do is build a new BIOS
with the new 3.XX SYSINIT and SYSIMES modules in the same way
that the 2.XX BIOS was built. This will produce a perfectly
functional BIOS, but none of the devices will have any of
the new 3.XX functions implemented.
Since you have not modified your BIOS, you cannot support
the following features:
1. The IOCTL is Changeable (Function 4408H) call.
This is useful for FORMAT and other programs that
want to prompt for a change of media.
2. The character device OPEN and CLOSE device driver
calls. These are useful for flushing
interrupt-driven I/O.
3. The background print utility spooling to a network
printer.
4. Output-until-busy device driver call for
PRINT/PSPRINT spool devices.
HOW TO UPGRADE A 2.XX BIOS TO 3.XX Page B-2
1. IOCTL Is Changeable Call
The IOCTL Is Changeable (Function 4408H) call is
fairly easy to implement. Set the appropriate bit
in the device-attribute word for your block device
drivers, and add the necessary code to return the
particular value for your floppies and hard disks.
2. OPEN and CLOSE calls
OPEN and CLOSE device driver calls are needed only ____
if you have interrupt-driven I/O. If you omitted
this feature, then you have nothing to do. If you
support interrupt-driven I/O, set the appropriate
bit in the attribute word for your character device
driver and add the necessary code to wait until
your buffers are empty.
____________________________________________________________
| |
| Note |
| |
| The same bit in the attribute word is used to indicate |
| that Is-Removable and OPEN/CLOSE is present. This |
| means that you must put in NO-OP stubs for those |
| functions you will not use (simply return with no error |
| for OPEN/CLOSE). MS-DOS assumes that all three of |
| these new functions exist if this attribute bit is set. |
| |
|__________________________________________________________|
3. Background Print Utility
The third feature (background print spooling to a
network printer) is difficult to implement. You
MAY need to add code to the output loop of the
character device driver that tells the network
portion of MS-DOS that you sent a character to a
particular device. You will also need to modify
the code in NETPS (part of the Redirector) to
receive this input. The skeleton code in NETPS is
for INT 17H (output-to-printer) on the IBM PC. So
there is NO SPECIAL CODE in the IBM PC printer
device drivers as everything is handled by INT 17H.
Your architecture may require a different mechanism.
You may wish to use the INT 2FH mechanism to achieve
this.
If your architecture doesn't provide for Redirection
at the ROM BIOS entry level (INT 17H on the IBM PC),
your added code in the device driver will signal
the network piece that you have a character
destined for a particular device. The network
piece will decide whether or not that output should
be routed across the network. If so, it will
handle the character and return an indication that
the character was handled. Otherwise, it will
indicate that the device driver should take care of
HOW TO UPGRADE A 2.XX BIOS TO 3.XX Page B-3
it. After this call in the device driver, the code
should examine the return to see if the device
driver should process the character or return. The
code required to do this is quite small, typically
less than 100 bytes.
There is more information about how this is done
in the Redirector Adaptation Guide that is available
on the MS-NET distribution diskette.
4. Output-Until-Busy Call
The fourth feature is a new device call that helps
the performance of the PRINT and PSPRINT
(networking print) utilities. Most printers have
RAM buffers which typically hold a line of
characters or some fixed amount of characters.
These buffers fill up without the printer going
busy. This yields a "burst" type of behavior. A
line of characters can be very quickly output to
the printer, then the printer goes busy for a long
time while the characters are being printed. This
new device call allows the background spooling
programs PRINT and PSPRINT to use this burst
behavior efficiently. Rather than take the
overhead of a device driver call for each
character, or risk getting "stuck" in the device
driver outputting a block of characters, this call
allows a burst of characters to be output without
getting stuck in the device driver waiting for the
device to come ready.
APPENDIX C
HOW TO UPGRADE A 3.10 BIOS TO 3.20
The major change in the MS-DOS 3.2 BIOS is in the device drivers.
The device drivers provide the support for the new Generic IOCTL
requests. If some of the new MS-DOS 3.2 features are going to be
used, then the Generic IOCTL functions have to implemented in the
device drivers. For example, the new MS-DOS 3.2 FORMAT utility
has been designed to be hardware independent and uses Generic IOCTL's
extensively. If the Generic IOCTL's are implemented in the device
drivers, then the OEM will not have to modify the FORMAT utility.
Refer to the MS-DOS 3.2 Device Drivers Guide and the MS-DOS 3.2
Technical Guide for a complete listing of the use of Generic IOCTL's.
NOTE: Old device drivers will still work under MS-DOS 3.2 without
the Generic IOCTL's, but will not get the benefit of this feature.
The MS-DOS 3.2 BIOS makes use of a new data structure called
the Block Data Structure (BDS). The BDS is listed in the file
MSBDS.ASM in the sample BIOS disk. This data structure describes
the characteristics of a physical block device. The BDS is filled
in at BIOS initialization time. The physical characteristics
within the BDS can be changed after initialization time by using the
DRVPARM option in the CONFIG.SYS file. Any block device drivers that
have the special MS-DOS 3.2 version bit set in the attribute word
must contain a BDS. The BDS in the device driver will be linked with
the other BDS's of the system at initialization time.
The BDS structure must be used if the Generic Device Driver (DRIVER.SYS)
is to used in the OEM's system.
The MS-DOS 3.2 BIOS has extended the concept of logical drives.
There can now be more than one logical drive associated with each physical
drive. This logical drive mapping is achieved by using the Generic Device
Driver, DRIVER.SYS.
The extension of logical drives has prompted the idea of "Present Physical
Drive Owner". The Present Physical Drive Owner is the last logical drive
to have accessed a physical drive. This is an important concept because
when a reference is made to a logical drive that is NOT the Present
Physical Drive Owner, the BIOS displays the following message:
Insert diskette for drive d: and strike
any key when ready
where d: is the logical drive that was referenced. The Present Physical
Drive Owner is stored in the BDS for the particular physical drive.
Two new IOCTL calls have been introduced in connection with logical
drives. The new calls are GET/SET LOGICAL DRIVE MAP. These two IOCTL's
are important for applications that want to control the printing of the
message to swap disks. The message to swap disks will only be displayed
if the Present Physical Drive Owner is not the same as the logical drive
being referenced. Applications that want to control the printing of this
message (for example, full screen applications that want to display
the swap disk message in a dialogue box) would use these calls to get and
set the Present Physical Drive Owner.
APPENDIX D
This material was taken from the MS-DOS 3.20 Programmer's Reference
Manual. It is intended be used with the MS-DOS 2.XX/3.XX Adaptation
Guide.
CHAPTER 2
MS-DOS DEVICE DRIVERS
2.1 INTRODUCTION
The IO.SYS file is composed of the "resident" device
drivers, and forms the MS-DOS BIOS. MS-DOS calls upon these
resident drivers to handle I/O requests initiated by
application programs.
One of the most powerful features of MS-DOS is that it lets
you add new devices such as printers, plotters, or mouse
input devices without rewriting the BIOS. The MS-DOS BIOS
is "configurable;" that is, you can add and preempt new
drivers and existing drivers. You can also add non-resident
device drivers at boot time by using the "DEVICE =" entry in
the CONFIG.SYS file. In this section, these non-resident
drivers are referred to as "installable" to distinguish them
from drivers which, in the IO.SYS file, are considered as
the resident drivers.
At boot time, a minimum of five resident device drivers must
be present. These drivers are in a linked list. The
"header" of each driver contains a DWORD pointer to the
next. The last driver in the chain has an end-of-list
marker of -1, -1 (all bits on).
Each driver in the chain has two entry points--the strategy
entry point and the interrupt entry point. MS-DOS does not
take advantage of the two entry points. Instead, it first
calls the strategy routine, then immediately calls the
interrupt routine.
The dual entry points are provided for future multitasking
versions of MS-DOS. In multitasking environments, I/O must
be asynchronous; to accomplish this, the strategy routine
will be called to (internally) queue a request and return
quickly. It is then the responsibility of the interrupt
routine to perform the I/O at interrupt time by getting
requests from the internal queue and processing them. When
a request is completed, the interrupt routine flags it as
"done." MS-DOS periodically scans the list of requests,
looking for those requests with done flags, and "wakes up"
MS-DOS DEVICE DRIVERS Page 2-2
the process that is waiting for the completion of the
request.
When requests are queued in this manner, it is no longer
sufficient to pass I/O information in registers, since many
requests may be pending at any one time. Therefore, the
MS-DOS device interface uses "packets" to pass request
information. These request packets vary in size and format
and are composed of two parts:
1. The static request header section, which has the
same format for all requests.
2. A section that has information specific to the type
of request.
A driver is called with a pointer to a packet. In
multitasking versions, this packet will be linked into a
global chain of all pending I/O requests maintained by
MS-DOS.
MS-DOS does not implement a global or local queue. Only one
request is pending at any one time. The strategy routine
must store the address of the packet at a fixed location,
and the interrupt routine, which is called immediately after
the strategy routine, should process the packet by
completing the request and returning. MS-DOS assumes that
the request is complete when the interrupt routine returns.
To make a device driver that SYSINIT can install, you must
create a .BIN (core image) or .EXE format file that contains
the device driver header at the beginning of the file. The
link field should be initialized to -1 (SYSINIT fills it
in). Device drivers that are part of the BIOS should have
their headers point to the next device in the list and the
last header should be initialized to -1,-1. The BIOS must
be a .BIN (core image) format file.
If you have a non-IBM compatible version of MS-DOS 2.x, you
can use installable device drivers that are in .EXE format.
On the IBM PC (or compatible) DOS 2.x versions, the .EXE
loader is located in COMMAND.COM, which is not present at
the time that MS-DOS is loading the installable devices.
2.2 FORMAT OF A DEVICE DRIVER
A device driver is a program segment responsible for
communication between DOS and the system hardware. It has a
special header at the beginning identifying it as a device
driver, defining its entry points, and describing its
various attributes.
MS-DOS DEVICE DRIVERS Page 2-3
------------------------------------------------------------
| |
| Note |
| |
| For device drivers, the file must not use the ORG 100H |
| (like .COM files). Because it does not use the Program |
| Segment Prefix, the device driver is simply loaded; |
| therefore, the file must have an origin of zero (ORG 0 |
| or no ORG statement). |
| |
|__________________________________________________________|
There are two kinds of device drivers:
1. Character device drivers
2. Block device drivers
Character devices perform serial character I/O. Examples
are the console, communications port, and printer. These
devices have specific names (i.e., CON, AUX, CLOCK, etc.),
and programs may open channels (handles or FCBs) to send I/O
to them.
Block devices are the "disk drives" on the system. They can
perform random I/O in structured pieces called blocks
(usually the physical sector size). These devices are not
named as the character devices are, and therefore cannot be
opened directly. Instead they have unit numbers and are
identified by drive letters such as A, B, and C.
A single block device driver may be responsible for one or
more logically contiguous disk drives. For example, the
block device driver ALPHA may be responsible for drives A,
B, C, and D. This means that it has four units defined
(0-3). The position of the driver in the list of all
drivers determines which units correspond to which drive
letters. For example, if driver ALPHA is the first block
driver in the device list, and it defines 4 units (0-3),
then they will be A, B, C, and D. If BETA is the second
block driver and defines three units (0-2), then they will
be E, F, and G, and so on. The theoretical limit is 63, but
the device installation code does not allow the installation
of a device if it would result in a drive letter >`Z' (5AH).
All block device drivers present in the standard resident
BIOS are placed ahead of installable block-device drivers in
the list.
MS-DOS DEVICE DRIVERS Page 2-4
------------------------------------------------------------
| |
| Note |
| |
| Character devices cannot define multiple units |
| because they have only one name. |
| |
|__________________________________________________________|
2.3 HOW TO CREATE A DEVICE DRIVER
To create a device driver that MS-DOS can install, you must
create a binary file (.COM or .EXE format) with a device
header at its beginning. Device driver code should not
originate at 100H, but at 0. The device header contains a
link field (pointer to next device header) which should be
-1, unless there is more than one device driver in the file.
You must also correctly set the attribute field and entry
points. The name field for a character device should
contain the name of that device. This name can be any legal
8-character filename. But if it is less than eight
characters, you should pad it out to eight by typing spaces
(20H). Note that device names do not include colons (:).
The fact that "CON" is the same as "CON:" is a property of
the default MS-DOS command interpreter (COMMAND.COM) and not
of the device driver or MS-DOS interface. All character
device names are handled in this way.
MS-DOS always processes installable device drivers before
handling the default devices, so to install a new CON
device, simply name the device "CON". Remember to set the
standard input and standard output device bits in the
attribute word on a new CON device. The scan of the device
list stops on the first match, so the installable device
driver takes precedence.
It is not possible to replace the "resident" disk block
device driver with an installable device driver as you would
replace other device drivers in the BIOS. Block drivers can
be used only for devices not supported directly by the
default disk drivers in IO.SYS.
------------------------------------------------------------
| |
| Note |
| |
| Because MS-DOS can install the driver anywhere in |
| memory, you must be careful when making far memory |
| references. You should not expect that your driver |
| will always be loaded in the same place every time. |
| |
|__________________________________________________________|
MS-DOS DEVICE DRIVERS Page 2-5
2.3.1 Device Strategy Routine
This routine, which MS-DOS calls for each device driver
service request, is primarily responsible for queuing these
requests in the order in which they are to be processed by
the Device Interrupt Routine. Such queuing can be an
important performance feature in a multitasking environment,
or where asynchronous I/O is supported. Since MS-DOS does
not currently support these facilities, only one request
(usually a short one) can be serviced at a time. In the
coding examples in Section 2.12, each request is simply
stored in a single pointer area.
2.3.2 Device Interrupt Routine
This routine contains the code necessary for processing the
service request. It may interface to the hardware, or it
may use ROM BIOS calls. It usually consists of a series of
procedures, which handle the specific command codes to be
supported, as well as some exit and error-handling routines.
See the coding examples in Section 2.12.
2.4 INSTALLATION OF DEVICE DRIVERS
MS-DOS allows new device drivers to be installed dynamically
at boot time. This is accomplished by IO.SYS initialization
code which reads and processes the CONFIG.SYS file.
MS-DOS calls upon the device drivers to perform their
functions in the following manner:
1. MS-DOS makes a far call to strategy entry.
2. MS-DOS passes device driver information in a
request header to the strategy routine.
3. MS-DOS then makes a far call to the interrupt
entry.
This structure can be easily upgraded to support any future
multitasking environment.
MS-DOS DEVICE DRIVERS Page 2-6
2.5 DEVICE HEADERS
A device header, which is required at the beginning of every
device driver, looks like this:
+--------------------------------------+
| DWORD Pointer to next device |
| (Usually set to -1 if this driver |
| is the last or only driver in the |
| file) |
+--------------------------------------+
| WORD Attributes |
+--------------------------------------+
| WORD Pointer to device strategy |
| entry point |
+--------------------------------------+
| WORD Pointer to device interrupt |
| entry point |
+--------------------------------------+
| 8-BYTE Character device name field |
| Character devices set a device name. |
| For block devices the first byte is |
| the number of units. |
+--------------------------------------+
Figure 2.1. Sample Device Header
Note that the device entry points are words. They must be
offsets from the same segment number used to point to this
table. For example, if XXX:YYY points to the start of this
table, then XXX:strategy and XXX:interrupt are the entry
points.
The device header fields are described in the following
section.
2.5.1 Pointer to Next Device Field
This pointer is a double word field (offset followed by
segment). MS-DOS sets this field so that it points to the
next driver in the system list at the time the device driver
is loaded. Unless there is more than one device driver in
the file, it is important that you set this field to -1
prior to loading (when it is on the disk as a file). If
there is more than one driver in the file, the first word of
the double word pointer should be the offset of the next
driver's device header.
MS-DOS DEVICE DRIVERS Page 2-7
------------------------------------------------------------
| |
| Note |
| |
| If there is more than one device driver in the |
| file, the last driver in the file must have the pointer |
| to the next device header field set to -1. |
| |
|__________________________________________________________|
2.5.2 Attribute Field
The attribute field identifies the type of device this
driver is responsible for. In addition to distinguishing
between block and character devices, these bits give
selected character devices special treatment. (Note that if
a bit in the attribute word is defined only for one type of
device, a driver for the other type of device must set that
bit to 0.)
For character devices:
Bit Value Meaning
15 1 Character device
14 1 Device supports
IOCTL control strings
13 1 Device supports
Output Until Busy (OUB)
12 RESERVED
11 1 Device understands
OPEN/CLOSE
10-7 RESERVED
6 1 Device supports 3.2 functions
5-4 RESERVED
3 1 Device is CLOCK device
2 1 Device is NUL device
1 1 Device is console output (STO)
0 1 Device is console input (STI)
For Block Devices:
Bit Value Meaning
15 0 Block device
14 1 Device supports IOCTL control
strings
13 1 Device determines the media by
examining the FATID byte.
12 RESERVED
11 1 Device understands
OPEN/CLOSE/Removable Media.
MS-DOS DEVICE DRIVERS Page 2-8
10-7 RESERVED
6 1 Device supports 3.2 functions
5-0 RESERVED
For example, assume that you have a new device driver that
you want to use as the standard input and output. In
addition to installing the driver, you must tell MS-DOS that
you want this new driver to override the current standard
input and standard output (the CON device). You do this by
setting bits 0 and 1 to 1 (note that they are separate!).
Similarly, you could install a new CLOCK device by setting
the appropriate attribute. (Refer to Section 2.10, "The
CLOCK Device," in this chapter for more information.)
Although there is a NUL device attribute, you cannot
reassign the NUL device. This attribute exists so that
MS-DOS can determine whether the NUL device is being used.
The IOCTL bit, bit 14, allows IOCTL functions to send and
receive data to character and block devices for their own
use. This allows them to set baud rate, stop bits, form
length, etc., instead of passing data over the device
channel as a normal read or write does. The interpretation
of the passed information is up to the device, but the
device must not treat this information as normal I/O. This
bit tells MS-DOS whether the device can handle control
strings via the IOCTL system call, Function 44H.
If a driver cannot process control strings, it should set
this bit initially to 0. This tells MS-DOS to return an
error if an attempt is made (via Function 44H) to send or
receive control strings to this device. A device which can
process control strings should initialize the IOCTL bit to
1. For drivers of this type, MS-DOS makes calls to the
IOCTL INPUT and OUTPUT device functions to send and receive
IOCTL strings.
For block devices, bit 13 affects the operation of the BUILD
BPB (BIOS Parameter Block) device call. If set, it requires
the first sector of the FAT to reside ALWAYS in the same
place. Bit 13 has a different meaning on character devices,
indicating that the device implements the OUTPUT UNTIL BUSY
device call.
The OPEN/CLOSE/RM bit, bit 11, signals to MS-DOS 3.x, and
later versions, whether this driver supports additional
MS-DOS 3.0 functionality. But to support these old drivers,
it is necessary to detect them. Bit 11 was reserved in
MS-DOS 2.x, and is 0. All new devices, however, should
support the OPEN, CLOSE, and REMOVABLE MEDIA calls and set
this bit to 1. Since MS-DOS 2.x never makes these calls,
the driver will be backwardly compatible.
The MS-DOS 3.2 bit, bit 6, signals whether the device
supports logical drive mapping via Function 440EH (Get
Logical Drive Map) and Function 440FH (Set Logical Drive
MS-DOS DEVICE DRIVERS Page 2-9
Map). This bit also supports generic IOCTL functions via
Function 440C (Generic IOCTL for Handles) and Function 440D
(Generic IOCTL for Block Devices).
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
____________________________________________________________
| C | I | O | | O | | | | | 3 | | | C | N | S | S |
| H | O | Y | | P | | | | | . | | | L | U | T | T |
| R | C | B | | N | | | | | 2 | | | K | L | O | I |
|___|___|___|___|___|___|__|__|__|___|__|__|___|___|___|___|
Figure 2.? Attribute Word for character devices
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
____________________________________________________________
| | I | F | | O | | | | | 3 | | | | | | |
| | O | A | | P | | | | | . | | | | | | |
| | C | T | | N | | | | | 2 | | | | | | |
|___|___|___|___|___|___|__|__|__|___|__|__|___|___|___|___|
Figure 2.? Attribute Word for block devices
2.5.3 Strategy And Interrupt Routines
These two fields are the pointers to the entry points of the
strategy and interrupt routines. They are word values, so
they must be in the same segment as the device header.
2.5.4 Name Field
This is an 8-byte field that contains the name of a
character device or the number of units of a block device.
If it is a block device, the number of units can be put in
the first byte. This is optional, because MS-DOS fills in
this location with the value returned by the driver's INIT
code. Refer to Section 2.4, "Installation of Device
Drivers," for more information.
2.6 REQUEST HEADER
When MS-DOS calls a device driver to perform a function, it
passes a request header in ES:BX to the strategy entry
point. This is a fixed length header, followed by data
pertinent to the function being performed. Note that it is
the device driver's responsibility to preserve the machine
state (for example, save all registers including flags on
entry and restore them on exit). There is enough room on
the stack to do about 20 pushes, when MS-DOS calls either
the strategy or the interrupt routines. If more stack is
MS-DOS DEVICE DRIVERS Page 2-10
needed, the driver should set up its own stack.
The following figure illustrates a request header.
REQUEST HEADER ->
+-----------------------------+
| BYTE Length of record |
| Length in bytes of this |
| request header |
+-----------------------------+
| BYTE Unit code |
| The subunit the operation |
| is for (minor device) |
| (no meaning on character |
| devices) |
+-----------------------------+
| BYTE Command code |
+-----------------------------+
| WORD Status |
+-----------------------------+
| 8 BYTES Reserved |
| |
|-----------------------------|
Figure 2.2. Request Header
The request header fields are described below.
2.6.1 Length of Record
This field contains the length (in bytes) of the request
header.
2.6.2 Unit Code Field
The unit code field identifies which unit in your device
driver the request is for. For example, if your device
driver has 3 units defined, the possible values of the unit
code field would be 0, 1, and 2.
2.6.3 Command Code Field
The command code field in the request header can have the
following values:
Command Function
Code
0 INIT
MS-DOS DEVICE DRIVERS Page 2-11
1 MEDIA CHECK (Block devices only)
2 BUILD BPB (Block devices only)
3 IOCTL INPUT (Only called if device has IOCTL)
4 INPUT (read)
5 NON-DESTRUCTIVE INPUT NO WAIT (Char devs only)
6 INPUT STATUS (Char devs only)
7 INPUT FLUSH (Char devs only)
8 OUTPUT (write)
9 OUTPUT (Write) with verify
10 OUTPUT STATUS (Char devs only)
11 OUTPUT FLUSH (Char devs only)
12 IOCTL OUTPUT (Only called if device has IOCTL)
13 DEVICE OPEN (Only called if OPEN/CLOSE/RM bit set)
14 DEVICE CLOSE (Only called if OPEN/CLOSE/RM bit set)
15 REMOVABLE MEDIA (Only called if OPEN/CLOSE/RM bit
set and device is block)
16 OUTPUT UNTIL BUSY (Only called if bit 13 is set on
character devices)
19 Generic IOCTL Request (Only called if bit 0 is set
for block devices)
23 Get Drive Map (Only called if bit 6 is set on
block devices)
24 Set Drive Map (Only called if bit 6 is set on
block devices)
Unused command codes are reserved.
2.6.4 Status Field
The following figure illustrates the status field in the
request header.
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+
| E | | B | D | |
| R | RESERVED | U | O | ERROR CODE (bit 15 on)|
| R | | S | N | |
| | | Y | E | |
+---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+
The status word is zero on entry and is set by the driver
interrupt routine on return.
Bit 8 is the done bit. When set, it means the operation has
completed. The driver sets it to 1 when it exits.
Bit 15 is the error bit. If it is set, the low 8 bits
indicate the error. The errors are:
0 Write protect violation
1 Unknown unit
2 Drive not ready
MS-DOS DEVICE DRIVERS Page 2-12
3 Unknown command
4 CRC error
5 Bad drive request structure length
6 Seek error
7 Unknown media
8 Sector not found
9 Printer out of paper
A Write fault
B Read fault
C General failure
D Reserved
E Reserved
F Invalid disk change
Bit 9 is the busy bit, which is set only by status calls and
the removable media call.
2.7 DEVICE DRIVER FUNCTIONS
Device drivers may perform all or some of these nine general
functions. In some cases, these functions break down into
several command codes. Each is described in this section.
1. INIT
2. MEDIA CHECK
3. BUILD BPB
4. READ or WRITE or WRITE TIL BUSY or Write with
Verify or Read IOCTL or Write IOCTL
5. NON DESTRUCTIVE READ NO WAIT
6. OPEN or CLOSE (3.x)
7. REMOVABLE MEDIA (3.x)
8. STATUS
9. FLUSH
10. Generic IOCTL
11. Get Logical Device
12. Set Logical Device
All strategy routines are called with ES:BX pointing to the
Request Header. The interrupt routines get the pointers to
the Request Header from the queue in which the strategy
MS-DOS DEVICE DRIVERS Page 2-13
routines store them. The command code in the request header
tells the driver which function to perform and what data
follows the request header.
------------------------------------------------------------
| |
| Note |
| |
| All DWORD pointers are stored offset first, segment |
| second. |
| |
|__________________________________________________________|
2.7.1 INIT
Command code = 0
INIT - ES:BX ->
+------------------------------------+
| 13-BYTE Request header |
+------------------------------------+
| BYTE Number of units |
+------------------------------------+
| DWORD End Address |
+------------------------------------+
| DWORD Pointer to BPB array |
| (Not set by character devices) |
+------------------------------------+
| BYTE Block device number |
+------------------------------------+
One of the functions defined for each device driver is INIT.
This routine is called only once when the device is
installed. The INIT routine must return the END ADDRESS,
which is a DWORD pointer to the end of the resident portion
of the device driver. To save space you can use this
pointer method to delete init code that is needed only once.
The driver sets the number of units, end address, and BPB
pointer. For installable block device drivers, the DWORD
pointer to BPB array now points to the first character after
the equal sign (=) on the line in CONFIG.SYS (the line that
caused this device to be loaded). This line is terminated
by a RETURN or a linefeed. This data is read-only and lets
the device driver scan the CONFIG.SYS line for arguments.
device=\dev\vt52.sys /l
^
|_____BPB address points here
Also, the block device driver defines the first unit and
assigns it to the drive number in the block device number
MS-DOS DEVICE DRIVERS Page 2-14
field (for example, A=0). This field is also read-only.
Installable character devices must return only the end
address parameter. This parameter is a pointer to the first
available byte of memory above the location of the driver
and which the driver may use to throw away initialization
code.
Block devices must return the following information:
1. The number of units. MS-DOS uses this number to
determine logical device names. At the time of the
install call, if the current maximum logical device
letter is F, and the INIT routine returns 4 as the
number of units, these units will have logical
names G, H, I and J. This mapping is determined by
the position of the driver in the device list and
by the number of units on the device (stored in the
first byte of the device name field).
2. A DWORD pointer to an array of one-word offsets
(pointers) to BPBs (BIOS Parameter Blocks). MS-DOS
creates an internal structure by using the BPBs
passed by the device driver. There must be one
entry in this array for each unit defined by the
device driver. In this way, if all units are the
same, all the pointers can point to the same BPB,
saving space. If the device driver defines two
units, the DWORD pointer points to the first of two
one-word offsets. In turn these offsets point to
BPBs. The format of the BPB is described later in
this chapter in Section 2.7.3, "BUILD BPB."
Note that this array of one-word offsets must not
be above the free pointer set by the return,
because the device driver builds an internal DOS
structure, starting at the byte pointed to by the
free pointer. The defined sector size must be less
than or equal to the maximum sector size defined by
the resident device drivers (BIOS) during
initialization. If it isn't, the installation will
fail.
3. The media descriptor byte. This byte, which is the
last byte returned by INIT, means nothing to
MS-DOS, but is passed to devices so that they know
which parameters MS-DOS is currently using for a
particular drive unit.
Block devices may be either dumb or smart. A dumb device ____ _____
defines a unit (and therefore an internal DOS structure) for
MS-DOS DEVICE DRIVERS Page 2-15
each possible media-drive combination. For example, unit 0
= drive 0, single sided; unit 1 = drive 0, double sided.
For the "dumb device" approach, media descriptor bytes do
not mean anything. A smart device allows multiple media per
unit. In the case of a smart device, the BPB table returned
upon INIT must define sufficient space to accommodate the
largest possible media. Smart drivers use the media
descriptor byte to pass information about what media is
currently in a unit.
For more information on the media descriptor byte, see
Section 2.8, "Media Descriptor Byte."
------------------------------------------------------------
| |
| Note |
| |
| If a file contains multiple device drivers, MS-DOS uses |
| the ending address returned by the last INIT called. |
| All the device drivers in a single file should return |
| the same ending address. The code to remain resident |
| for all the devices in a file should be grouped |
| together in low memory with the initialization code for |
| all devices following it. |
| |
|__________________________________________________________|
2.7.2 MEDIA CHECK
Command Code = 1
MEDIA CHECK - ES:BX ->
+------------------------------------+
| 13-BYTE Request header |
+------------------------------------+
| BYTE Media descriptor from BPB |
+------------------------------------+
| BYTE Returned |
+------------------------------------+
| Returned DWORD pointer to previous |
| Volume ID if bit 11 set and |
| Media Changed is returned |
+------------------------------------+
The MEDIA CHECK function is used with block devices only.
It is called when there is a pending drive access call other
than a file read or write, such as open, close, delete, or
rename. Its purpose is to determine whether the media in
the drive has been changed. If the driver can ensure that
MS-DOS DEVICE DRIVERS Page 2-16
the media has not been changed (through a door-lock or other
interlock mechanism), MS-DOS does not need to reread the FAT
and invalidate in-memory buffers for each directory access.
When such a disk access call to the DOS occurs (other than a
file read or write), the following sequence of events takes
place:
1. The DOS converts the drive letter into the unit
number of a particular block device.
2. The device driver is then called to request a media
check on that subunit to see if the disk might have
been changed. MS-DOS passes the old media
descriptor byte. The driver returns:
Media not changed...... (1)
Don't know if changed...(0)
Media changed...........(-1)
Error
If the media has not been changed, MS-DOS proceeds
with the disk access.
If the value returned is "Don't know," and if there
are any disk sectors that have been modified and
not yet written back to the disk for this unit,
MS-DOS assumes that the disk has not been changed
and proceeds. MS-DOS invalidates any other buffers
for the unit and does a BUILD BPB device call (see
step 3, below).
If the media has been changed, MS-DOS invalidates
all buffers associated with this unit including
buffers with modified data that are waiting to be
written, and requests a new BIOS Parameter Block
via the BUILD BPB call (see step 3, below).
3. Once the BPB has returned, MS-DOS corrects its
internal structure for the drive from the new BPB
and, after reading the directory and the FAT,
proceeds with the access.
Note that the previous media ID byte is passed to the device
driver. If the old media ID byte is the same as the new
one, the disk might have been changed and a new disk may be
in the drive. Therefore, all FAT, directory, and data
sectors that are buffered in memory for the unit are
considered invalid.
If the driver has bit 11 of the device attribute word set to
1, and the driver returns -1, "Media Changed," it must set
MS-DOS DEVICE DRIVERS Page 2-17
the DWORD pointer to the previous Volume ID field. If the
DOS determines that "Media Changed" is an error based on the
state of the DOS buffer cache, it generates a 0FH error on
behalf of the device. If the driver does not implement
Volume ID support, but has bit 11 set, it should set a
static pointer to the string, "NO NAME",0.
It is not possible for a user to change a disk in less than
2 seconds. So when MEDIA CHECK occurs within 2 seconds of a
disk access, the driver reports "1," "Media not changed."
This action increases performance tremendously.
------------------------------------------------------------
| |
| Note |
| |
| For MS-DOS versions before 3.2 if the media ID byte in |
| the returned BPB is the same as the previous media ID |
| byte, MS-DOS assumes that the format of the disk is the |
| same (even though the disk may have been changed) and |
| skips the step of updating its internal structure. All |
| BPBs, therefore, must have unique media bytes regardless|
| of FAT ID bytes. |
| |
|__________________________________________________________|
2.7.3 BUILD BPB (BIOS Parameter Block)
Command code = 2
BUILD BPB - ES:BX ->
+------------------------------------+
| 13-BYTE Request header |
+------------------------------------+
| BYTE Media descriptor from BPB |
+------------------------------------+
| DWORD Transfer address |
| (Points to one sector worth of |
| scratch space or first sector |
| of FAT depending on the value |
| of Bit 13 in the device attribute |
| word.) |
+------------------------------------+
| DWORD Pointer to BPB |
+------------------------------------+
The Build BPB function is used with block devices only. As
described in the MEDIA CHECK function, the BUILD BPB
function is called any time that a preceding MEDIA CHECK
call indicates that the disk has been, or might have been,
MS-DOS DEVICE DRIVERS Page 2-18
changed. The device driver must return a pointer to a BPB.
This is different from the INIT call where the device driver
returns a pointer to an array of word offsets to BPBs.
The BUILD BPB call gets a DWORD pointer to a one-sector
buffer. The contents of this buffer are determined by the
NON FAT ID bit (bit 13) in the attribute field. If the bit
is zero, the buffer contains the first sector of the first
FAT. The FAT ID byte is the first byte of this buffer, so
in this case, the driver must not alter the buffer. Note
that the location of the FAT must be the same as for all
possible media because the DOS must read this FAT sector
before the driver returns the BPB that the DOS called. If
the NON FAT ID bit is set, the pointer points to one sector
of scratch space (space which may be used for anything).
Refer to Section 2.8, "Media Descriptor Byte,"" and Section
2.9, "Format of a Media Descriptor Table," for information
on how to construct the BPB.
MS-DOS 3.x includes additional support for devices that have
door-locks or some other means of telling when a disk has
been changed. Error 15, a new error that the device driver
can return, means "the disk has been changed when it
shouldn't have been." The user is prompted for the correct
disk using a Volume ID. The driver may generate this error
for READ or WRITE. The DOS may generate the error for MEDIA
CHECK if the driver reports media changed, and there are
buffers in the DOS buffer cache that need to be flushed to
the previous disk.
For drivers that support this error, the BUILD BPB function
is a trigger that causes the driver to read a new Volume ID
from the disk. This action indicates that the disk has been
legally changed. The FORMAT or LABEL utility places a
Volume ID on the disk. This ID is simply an entry in the
root directory of the disk that has the Volume ID attribute.
The driver stores the Volume ID as an ASCIZ string.
The requirement that the driver return a Volume ID does not
exclude some other Volume identifier scheme as long as the
scheme uses ASCIZ strings. A NUL (nonexistent or
unsupported) Volume ID is by convention the string:
DB "NO NAME ",0
MS-DOS DEVICE DRIVERS Page 2-19
2.7.4 READ or WRITE
Command codes = 3,4,8,9, 12, and 16
READ OR WRITE (Including IOCTL) or
OUTPUT UNTIL BUSY - ES:BX ->
+------------------------------------+
| 13-BYTE Request header |
+------------------------------------+
| BYTE Media descriptor from BPB |
+------------------------------------+
| DWORD Transfer address |
+------------------------------------+
| WORD Byte/sector count |
+------------------------------------+
| WORD Starting sector number |
| (Ignored on character devices) |
+------------------------------------+
| Returned DWORD pointer to requested|
| Volume ID if error 0FH |
+------------------------------------+
COMMAND CODE REQUEST
3 IOCTL READ
4 READ (block or character)
8 WRITE (block or character)
9 WRITE WITH VERIFY
12 IOCTL WRITE
16 OUTPUT TIL BUSY (char devs only)
The driver must perform the READ or WRITE call depending on
which command code is set. Block devices read or write
sectors; character devices read or write bytes.
When I/O completes, the device driver must set the status
word and report the number of sectors or bytes successfully
transferred, even if an error prevented the transfer from
being completed. Setting the error bit and error code alone _______ ___ _____ ___ ___ _____ ____ _____
is not sufficient.__ ___ __________
In addition to setting the status word, the driver must set
the sector count to the actual number of sectors (or bytes)
transferred. No error check is performed on an IOCTL I/O
call.
If the verify switch is on, the device driver is called with
command code 9 (WRITE WITH VERIFY). Your device driver is
then responsible for verifying the write.
If the driver returns error code 0FH (Invalid disk change),
it must return a DWORD pointer to an ASCIZ string (which is
the correct Volume ID). The return of this error code
triggers the DOS to prompt the user to re-insert the disk.
The device driver should have read the Volume ID as a result
of the BUILD BPB function.
Drivers may maintain a reference count of open files on the
disk by monitoring the OPEN and CLOSE functions. This
allows the driver to determine when to return error 0FH. If
there are no open files (reference count = 0), and the disk
MS-DOS DEVICE DRIVERS Page 2-20
has been changed, the I/O is okay. If there are open files,
however, an 0FH error may exist.
The OUTPUT UNTIL BUSY call is a speed optimization on
character devices only for print spoolers. The device
driver is expected to output all the characters possible
until the device returns busy. Under no circumstances
should the device driver block during this function. Note
that it is not an error if the device driver returns a
smaller number of bytes output than bytes requested.
The OUTPUT UNTIL BUSY call allows spooler programs to take
advantage of the burst behavior of most printers. Many
printers have on-board RAM buffers which typically hold a
line or a fixed amount of characters. These buffers fill up
without making the printer "busy" between characters for a
relatively short time (or at least not for more than ten
instructions). The device driver can quickly output a line
of characters to the printer, which is then busy for a
comparatively longer time while it prints. This new device
call allows background spooling programs to use this burst
behavior efficiently. Rather than take the overhead of a
device driver call for each character, or risk getting stuck
in the device driver outputting a block of characters, this
call allows a burst of characters to be output without the
device driver having to wait until the device is ready.
If the MS-DOS 3.2 bit is set, then MS-DOS can configure the
number of retries (allowed by the device driver) that the
printer can make before returning "busy."
THE FOLLOWING APPLIES TO BLOCK DEVICE DRIVERS:___ _________ _______ __ _____ ______ _______
Under certain circumstances, the device driver may request
that the BIOS perform a write operation of 64K bytes, which
seems to be a "wrap around" of the transfer address in the
BIOS I/O packet. This request arises due to an optimization
added to the write code in MS-DOS. It will only manifest
itself on user writes within a sector size of 64K bytes to
files "growing" past the current EOF. The BIOS may ignore ___ ____ ___ ______
the balance of the write that "wraps around," if it so___ _______ __ ___ _____ ____ ______ ________ __ __ __
chooses. For example, a write of 10000H bytes worth of________
sectors with a transfer address of XXX:1 could ignore the
last two bytes. A user program can never request an I/O of
more than FFFFH bytes and cannot wrap around (even to 0) in
the transfer segment. Therefore, in this case the BIOS
ignores the last two bytes.
MS-DOS maintains two FATs. If the DOS has problems reading
the first, it automatically tries the second before
reporting the error. The BIOS is responsible for all
retries.
Although the COMMAND.COM handler does no automatic retries,
there are applications that have their own Interrupt 24H
MS-DOS DEVICE DRIVERS Page 2-21
handlers. These handles do automatic retries on certain
types of Interrupt 24H errors before reporting them.
2.7.5 NON DESTRUCTIVE READ NO WAIT
Command code = 5
NON DESTRUCTIVE READ NO WAIT - ES:BX ->
+------------------------------------+
| 13-BYTE Request header |
+------------------------------------+
| BYTE read from device |
+------------------------------------+
This call lets MS-DOS look ahead one input character. The
device sets the done bit in the status word.
If the character device returns busy bit = 0, characters are
in the buffer and the next character that would be read is
returned. This character is not removed from the input ___
buffer (hence the term "Non Destructive Read"). If the
character device returns busy bit = 1, there are no
characters in the buffer.
2.7.6 OPEN or CLOSE
Command codes = 13 and 14
OPEN or CLOSE - ES:BX ->
+------------------------------------+
| 13-BYTE Static request header |
+------------------------------------+
These functions are called by MS-DOS 3.x only if the device
driver sets the OPEN/CLOSE/RM attribute bit in the device
header. They are designed to inform the device about its
current file activity. On block devices, these functions
can manage local buffering, and the device can keep a
reference count.
Every OPEN causes the device to increment the count, every
CLOSE to decrement. When the count goes to zero no open
files are on the device. Also, the device should flush any
buffers that it may have used in case the media has been
changed.
Block devices can have problems with this mechanism because
programs that use FCB calls can open files without closing
MS-DOS DEVICE DRIVERS Page 2-22
them. Therefore, when the media has been changed and the
BUILD BPB call has been made to the device, you should reset
the count to zero without flushing the buffers.
These calls are more useful on character devices. For
example, the device could use the OPEN call to send a device
initialization string. For example, this string might set a
printer's default characteristics for font and page size.
Using IOCTL to set these pre- and post-strings provides a
flexible mechanism of serial I/O device stream control. A
driver could also use the reference count mechanism to
detect a simultaneous access error. You may not want to
allow more than one OPEN on a device at any given time,
since, in this case, a second OPEN would result in an error.
Note that since all processes have access to stdin, stdout,
stderr, stdaux, and stdprn (handles 0,1,2,3,4), the CON,
AUX, and PRN devices are always open. ______
2.7.7 REMOVABLE MEDIA
Command code = 15
REMOVABLE MEDIA - ES:BX ->
+------------------------------------+
| 13-BYTE Static request header |
+------------------------------------+
This function is called by MS-DOS 3.x only if the device
driver sets the OPEN/CLOSE/RM attribute bit in the device
header. Only a subfunction of the IOCTL system call can
issue this call to block devices. Sometimes it is necessary
for a utility to know whether it is using a non-removable
media drive (a hard disk), or a removable media drive (a
floppy). For example, the FORMAT utility prints different
prompts depending on the media.
The information returns in the busy bit of the status word.
If the busy bit is 1, the media is non-removable, and if the
busy bit is 0, the media is removable. Note that the device
driver does not check the error bit; it just assumes that
this call always succeeds.
MS-DOS DEVICE DRIVERS Page 2-23
2.7.8 STATUS
Command codes = 6 and 10
STATUS Calls ES:BX ->
+------------------------------------+
| 13-BYTE request header |
+------------------------------------+
This call returns information to the DOS to let it know if
data is waiting for input or output. All the driver must do
is set the status word and the busy bit as follows:
For output on character devices: If the driver ___ ______ __ _________ _______
sets bit 9 to 1 on return, it informs the DOS that
a write request (if made) would wait for completion
of a current request. If bit 9 is 0, there is no
current request and a write request (if made) would
start immediately.
For input on character devices with a buffer: If ___ _____ __ _________ _______ ____ _ ______
bit 9 equals 1 this implies that the buffer is
empty and that a read request (if made) would go to
the physical device. If bit 9 is 0 on return,
characters are in the device buffer and a read
request would start immediately. A return of 0
implies that you have typed something. MS-DOS
assumes that all character devices have an input
type-ahead buffer; devices that do not should
always return busy = 0 so that the DOS does not
wait for you to put something into a non-existent
buffer.
2.7.9 FLUSH
Command codes = 7 and 11
FLUSH Calls - ES:BX ->
+------------------------------------+
| 13-BYTE request header |
+------------------------------------+
The FLUSH call tells the driver to flush (terminate) all
pending requests. This call is used to flush the input
queue on character devices. The device driver performs the
flush function, sets the status word, and returns.
MS-DOS DEVICE DRIVERS Page 2-24
2.7.10 Generic IOCTL Request
Command code = 19
ES:BX --> +----------------------------------+
| 13-BYTE Static Request Header |
+----------------------------------+
| BYTE Category (Major) Code |
+----------------------------------+
| BYTE Function (Minor) Code |
+----------------------------------+
| WORD (SI) contents |
+----------------------------------+
| WORD (DI) contents |
+----------------------------------+
| DWORD pointer to data buffer |
+----------------------------------+
This function provides a generic, expandable IOCTL facility
that replaces and makes the Read IOCTL and Write IOCTL
device driver functions obsolete. The MS-DOS 2.0 IOCTL
functions remain to support existing uses of the IOCTL
system call (subfunctions 2, 3, 4 and 5), but new device
drivers should use this generic MS-DOS IOCTL facility.
The generic IOCTL function contains both a category and
function code. The DOS examines the category field in order
to intercept and obey device commands that are actually
serviced by the DOS code; all other command categories are
forwarded to the device driver for servicing.
For more information on these category and function codes,
refer to Functions 440CH (Generic IOCTL for handles) and
Function 440DH (Generic IOCTL for block devices) in Chapter
1, "System Calls."
2.7.11 Get/Set Logical Drive Map
Command code = 23 (Get) or 24 (Set)
+-------------------------------------------+
| 13-byte Static Request Header |
+-------------------------------------------+
| BYTE Input (unit code) |
+-------------------------------------------+
| BYTE Output (last device referenced) |
+-------------------------------------------+
| BYTE Command code |
+-------------------------------------------+
| WORD Status |
+-------------------------------------------+
| DWORD Reserved |
+-------------------------------------------+
This function is only called by MS-DOS if the device driver
sets the DOS 3.2 attribute bit in the device header. The
call is only issued to block devices by a subfunction of the
IOCTL system call. The logical drive is passed in the UNIT
field of the header to the device driver, which returns the
MS-DOS DEVICE DRIVERS Page 2-25
current logical drive that is mapped on the physical drive
in the UNIT field of the header.
2.8 MEDIA DESCRIPTOR BYTE
In MS-DOS, the media descriptor byte informs the DOS that a
different type of media is present. The media descriptor
byte can be any value between 0 and FFH. It does not have
to be the same as the FAT ID byte. The FAT ID byte, which
is the first byte of the FAT, was used in MS-DOS 1.00 to
distinguish between different types of disk media. This
byte may also be used under 2.x and 3.x disk device drivers.
However, FAT ID bytes have significance only for block
device drivers where the NON FAT ID bit is not set (0).
Values of the media descriptor byte or the FAT ID byte have
no significance to MS-DOS. They are passed directly to the
device driver so that programs can determine the media type.
2.9 FORMAT OF A MEDIA DESCRIPTOR TABLE
The MS-DOS file system uses a linked list of pointers (one
for each cluster or allocation unit) called the File
Allocation Table (FAT). Unused clusters are represented by
zero and end-of-file by FFF (or FFFF on units with 16-bit
FAT entries). No valid entry should ever point to a zero
entry, but if one does, the first FAT entry (which would be
pointed to by a zero entry) should be reserved and set to
end-of-chain. Eventually, several end-of-chain values can
be defined ([F]FF8-[F]FFF), and used to distinguish
different media types.
A preferrable technique is to write a complete media
descriptor table in the boot sector and use it for media
identification. To ensure backward compatibility for
systems whose drivers do not set the NON FAT ID bit
(including the IBM PC implementation), it is necessary to
write the FAT ID bytes during the FORMAT process.
In the future to allow more flexibile support for many
different disk formats, you should keep the information
relating to the BPB for a particular media in the boot
sector. Figure 2.3 shows the format of such a boot sector.
MS-DOS DEVICE DRIVERS Page 2-26
+------------------------------------+
| 3 BYTE Near JUMP to boot code |
+------------------------------------+
| 8 BYTES OEM name and version |
---+------------------------------------+---
B | WORD Bytes per sector |
P +------------------------------------+
B | BYTE Sectors per allocation unit |
+------------------------------------+
| | WORD Reserved sectors |
V +------------------------------------+
| BYTE Number of FATs |
+------------------------------------+
| WORD Number of root dir entries |
+------------------------------------+
| WORD Number of sectors in logical |
^ | image |
| +------------------------------------+
B | BYTE Media descriptor |
P +------------------------------------+
B | WORD Number of sectors per FAT |
---+------------------------------------+---
| WORD Sectors per track |
+------------------------------------+
| WORD Number of heads |
+------------------------------------+
| WORD Number of hidden sectors |
+------------------------------------+
| WORD High order number of hidden |
| sectors |
+------------------------------------+
| DWORD Number of logical sectors |
+------------------------------------+
Figure 2.3. Format of Boot Sector
Although MS-DOS does not use the five fields that follow the
BPB, they may be used by a device driver to help it
understand the media.
The "Sectors per track" and "Number of heads" fields are
useful for supporting different media which may have the
same logical layout, but a different physical layout (e.g.,
40 track double-sided versus 80 track single-sided).
"Sectors per track" tells the device driver how the logical
disk format is laid out on the physical disk.
The "Number of hidden sectors" and the "High order number of
hidden sectors" fields may be used to suport
drive-partitioning schemes.
The "Number of logical sectors" field is not currently used
but will tell the device driver how many sectors to reserve
if the "Number of sectors in logical image" field is zero.
MS-DOS DEVICE DRIVERS Page 2-27
(This is intended for supporting drives that access more
than 32 megabytes.)
NON FAT ID format drivers should use the following procedure
to determine media type:
1. Read the boot sector of the drive into the 1-sector
scratch space pointed to by the DWORD Transfer
address.
2. Determine whether the first byte of the boot sector
is either E9H (the first byte of a 3-byte NEAR or
2-byte short jump) or EBH (the first byte of a
2-byte jump followed by a NOP). If it is, return a
pointer to a BPB beginning at offset 3.
3. If the boot sector does not have a BPB table, it is
probably a disk formatted under a 1.x version of
MS-DOS. Therefore, it probably uses a FAT ID byte
for determining media.
As an option, the driver may attempt to read the
first sector of the FAT into the 1-sector scratch
space and then read the first byte to determine the
media type. Return a pointer to a hard-coded BPB.
2.10 THE CLOCK DEVICE
MS-DOS assumes that some sort of clock is available in the
system. This clock may be either a CMOS real-time clock or
an interval timer which the user initializes at boot time.
The CLOCK device defines and performs functions like any
other character device except that the DOS identifies it by
a bit in the attribute word. Consequently this device may
take any name. The IBM version uses "$CLOCK" to avoid
conflict with existing files named "CLOCK."
The CLOCK device is unique because MS-DOS reads or writes a
6-byte sequence that encodes the date and time. A write to
this device sets the date and time, and a read gets the date
and time.
Figure 2.4 illustrates the binary time format which the
CLOCK device uses:
MS-DOS DEVICE DRIVERS Page 2-28
byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
+--------+--------+---------+--------+--------+---------+
| | | | | | |
|days since 1-1-80| minutes | hours | sec/100| seconds |
|low byte|hi byte | | | | |
+--------+--------+---------+--------+--------+---------+
Figure 2.4. CLOCK Device Format
2.11 ANATOMY OF A DEVICE CALL
The following steps illustrate what happens when MS-DOS
calls on a block device driver to perform a WRITE request:
1. MS-DOS writes a request packet in a reserved area
of memory.
2. It then calls the block device driver strategy
entry point.
3. The device driver saves the ES and BX registers
(ES:BX points to the request packet) and does a FAR
return.
4. MS-DOS calls the interrupt entry point.
5. The device driver retrieves the pointer to the
request packet and reads the command code (offset
2) to determine that this is a write request. The
device driver converts the command code for an
index into a dispatch table and passes control to
the disk write routine.
6. The device driver reads the unit code (offset 1) to
determine which disk drive it should write to.
7. Since the command is a disk write, the device
driver must get the transfer address (offset 14),
the sector count (offset 18), and the start sector
(offset 20) in the request packet.
8. The device driver translates the first logical
sector number into a track, head, and sector
number.
MS-DOS DEVICE DRIVERS Page 2-29
9. The device driver writes the specified number of
sectors, starting at the beginning sector on the
drive defined by the unit code (the subunit defined
by this device driver), and transfers data from the
address indicated in the request packet. Note that
this may involve multiple write commands to the
disk controller.
10. After the transfer is complete, the device driver
must report the status of the request to MS-DOS by
setting the done bit in the status word (offset 3
in the request packet). It reports the number of
sectors actually transferred in the sector count
area of the request packet.
11. If an error occurs, the driver sets the done bit
and the error bit in the status word and fills in
the error code in the lower half of the status
word. The number of sectors actually transferred
must be written in the request header. It is not
sufficient just to set the error bit of the status
word.
12. Finally, the device driver does a FAR return to
MS-DOS.
The device drivers should preserve the state of MS-DOS,
including all registers (and flags). In particular, the
direction flag and interrupt enable bits are critical. When
the interrupt entry point in the device driver is called,
MS-DOS has room for about 40 to 50 bytes on its internal
stack. Your device driver should switch to a local stack if
it uses extensive stack operations.
APPENDIX E
MSDOS 2.25 Device Driver Interface Extension.
MSDOS 2.25 is designed so as to be able to run with
CONSOLE DEVICE DRIVERS FROM PREVIOUS VERSIONS. If this is
the case then no interim character processing can be done,
and all character composition must be handled directly by
the console device driver.
The MSDOS 2.25 BIOS interface (IO.SYS) has the
following differences from the standard MSDOS 2.11 BIOS.
These changes are extensions to the CON (Console) Device
driver for hardware which will be utilizing Interim
Character support. Consult the MSDOS Adapatation Guide
for overall description of device driver design and
funtionality
1) On the INPUT and NON-DESTRUCTIVE INPUT calls to the
device driver (DD) the DD must check bit 0 of the byte at
offset 14 in the request packet. If the bit is 0 then it
should return only final characters, if the bit is 1 then
the device driver should return interim as well as final
characters to the dos.
Also on INPUT, if the request is for more than ONE byte
then the DD should return ONLY final characters, no matter
what the state of bit 0 in the byte at offset 14.
2) On return from INPUT, NON-DESTRUCTIVE INPUT and
INPUT STATUS calls, the device driver should return to the
dos with bit 10 of the status word SET if the character
read, or the character available is an interim character, or
the bit RESET if the character is a final character. (Pre
2.25 DD's always return with this bit reset). If more than
one character is read on an INPUT call then bit 10 should be
RESET as all the characters returned should be final
characters (see above).
3) On Console WRITE function the device driver should
check bit 0 of the byte at offset 14 in the request packet.
If the bit is reset then the character should be output as a
regular character by printing the character and advancing
the cursor to the next position. If the bit is SET then the
character is an interim character and should be treated by
the device driver display routine accordingly. In most cases
the character should be displayed without advancing the
cursor to the next character position. When using interim 16
bit characters that are output a byte at a time, then the
routine should handle this correctly, displaying the 16 bit
interim and not advancing the cursor to the next character
position.
Special considerations / requirements.
If a console device driver is going to return interim
characters then the device driver MUST be able to handle the
extension made to character WRITE (described above in 3).
Device drivers should be able to support requests for
final / interim characters in any order. Application
programs may at any time change the way they want
characters, and device drivers should be capable of changing
without any other indication than the DD request itself.
Device drivers should be capable of handling
composition somehow for those applications that do not do it
themselves.
The keyboard typeahead buffer should be kept at the key
level, without further interpretation. All processing of
interims in case of an input request for a final character
is issued (and there are interims in the buffer that have to
be composed to obtain a final character), should be done at
the time the request is done to the device driver.
Sample Device Driver for DOS 2.25 Interim Character Support
WARNING!! Not Assembleable. This code must be modified for
the OEM's own hardware and firmware.
PAGE
CODE SEGMENT BYTE
ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
;----------------------------------------------------------------
;
; C O N - CONSOLE DEVICE DRIVER
;
DW -1,-1
DW 1000000000010011B ; CON IN AND CON OUT + Special bit
DW STRATEGY
DW ENTRY
DB 'CON '
InterH db 0 ; Interim character flag
ALTAH DB 0 ; Special key handling
;----------------------------------------------------------------
;
; COMMAND JUMP TABLES
CONTBL:
DW CON$INIT
DW EXIT
DW EXIT
DW CMDERR
DW CON$READ
DW CON$RDND
DW EXIT
DW CON$FLSH
DW CON$WRIT
DW CON$WRIT
DW EXIT
DW EXIT
PAGE
;----------------------------------------------------------------
;
; Device entry point
;
CMDLEN = 0 ;LENGTH OF THIS COMMAND
UNIT = 1 ;SUB UNIT SPECIFIER
CMD = 2 ;COMMAND CODE
STATUS = 3 ;STATUS
MEDIA = 13 ;MEDIA DESCRIPTOR
TRANS = 14 ;TRANSFER ADDRESS
COUNT = 18 ;COUNT OF BLOCKS OR CHARACTERS
START = 20 ;FIRST BLOCK TO TRANSFER
BRKADR = Oem_Brk ; Break Vector Address
CHROUT = 29H ; fast con int
PAGE
;----------------------------------------------------------------
;
; Entry Procedures
;
PTRSAV DD 0
STRATP PROC FAR
STRATEGY:
MOV WORD PTR CS:[PTRSAV],BX
MOV WORD PTR CS:[PTRSAV+2],ES
RET
STRATP ENDP
ENTRY:
PUSH SI
PUSH AX
PUSH CX
PUSH DX
PUSH DI
PUSH BP
PUSH DS
PUSH ES
PUSH BX
LDS BX,CS:[PTRSAV] ; DS:BX points to IO packet
mov cx,word ptr ds:[bx].count ; CX = count
mov dl,byte ptr ds:[bx].media ; DL = input type flag
mov al,byte ptr ds:[bx].cmd ; AL = command code
cbw
MOV SI,OFFSET CONTBL ; command table
ADD SI,AX
ADD SI,AX
CMP AL,11
JA CMDERR ; command code out of range
LES DI,DWORD PTR DS:[BX].TRANS ; transfer address
PUSH CS
POP DS
ASSUME DS:CODE
JMP WORD PTR [SI] ; GO DO COMMAND
PAGE
;----------------------------------------------------------------
;
; EXIT - ALL ROUTINES RETURN THROUGH THIS PATH
;
CMDERR:
MOV AL,3 ; Unknown Command Error
ERR$EXIT:
mov ah,10000001b ; Mark Error Return
jmp short err1
BUS$EXIT:
mov ah,00000011b ; Device Busy Exit
jmp short err1
HanExit:
mov [InterH],0 ; reset interim flag
mov ah,00000101b ; Bit 10 Set for interim chars
jmp short err1
EXITP PROC FAR
EXIT: MOV AH,00000001B
ERR1: LDS BX,CS:[PTRSAV]
MOV WORD PTR [BX].STATUS,AX ; Mark Operation Complete
POP BX
POP ES
POP DS
POP BP
POP DI
POP DX
POP CX
POP AX
POP SI
RET ; RESTORE REGS AND RETURN
EXITP ENDP
PAGE
;----------------------------------------------------------------
;
; BREAK KEY HANDLING
;
BREAK:
MOV CS:ALTAH,3 ; INDICATE BREAK KEY SET
IRET
;----------------------------------------------------------------
;
; CHROUT - WRITE OUT CHAR IN AL USING CURRENT ATTRIBUTE
;
; CALLED VIA INT 29H
;
OUTCHR:
INT OEM_Char_Output
RET
PAGE
;----------------------------------------------------------------
;
; INPUT SINGLE CHAR INTO AL
;
ChrIn:
xor ax,ax
xchg al,ALTAH ; Get Character & Zero ALTAH
or al,al
jnz sj3
mov ah,Request_Interim ; assume interim char input
or dl,dl ; Interim chars wanted?
jnz sj0
mov ah,Request_Char ; regular whole char input
sj0:
int OEM_Kybd_Input ; Get character
or ax,ax ; Check for non-key after BREAK
jz ChrIn
or al,al ; Special Case?
jnz ChkInter
mov ALTAH,ah ; Save Special Key
sj3:
mov [InterH],0 ; reset interim flag
ret
ChkInter:
cmp ah,Hangeul_Interim ; a Hangeul interim?
jne sj3
mov [InterH],1 ; yes flag it
ret
PAGE
;----------------------------------------------------------------
;
; CONSOLE READ ROUTINE
;
; Input:
; CX = transfer count
; DL = input type flag (0 = whole chars, 1 = interim allowed)
; ES:DI = transfer addess
;
CON$READ:
JCXZ CON$EXIT
CON$LOOP:
CALL CHRIN ; GET CHAR IN AL
STOSB ; STORE CHAR AT ES:DI
LOOP CON$LOOP
CON$EXIT:
cmp [InterH],1 ; An Intermidiate Char?
jne ExVec ; no, regulear exit
JMP HanExit ; yes, reset flag and exit new way
PAGE
;----------------------------------------------------------------
;
; KEYBOARD FLUSH ROUTINE
;
CON$FLSH:
MOV [ALTAH],0 ; Clear out holding buffer
mov [InterH],0
mov ah,Flush_Buffer
int OEM_Kybd_Input
JMP EXIT
PAGE
;----------------------------------------------------------------
;
; KEYBOARD NON DESTRUCTIVE READ, NO WAIT
; Input:
; DL = input type flag (0 = whole chars, 1 = interim allowed)
;
EXVEC: JMP EXIT
CONBUS: JMP BUS$EXIT
CON$RDND:
MOV AL,[ALTAH]
OR AL,AL
JNZ sj6
MOV AH,Request_Interim_Status ;Assume interim allowed
or dl,dl ; check interim flag
jnz sj4
mov ah,Requst_Std_Status ; regular status wanted
sj4:
INT OEM_Kybd_Input ; Get status
JZ CONBUS
OR AX,AX
JNZ sj6 ; CHECK FOR NULL AFTER BREAK
MOV AH,Request_Char
INT OEM_Kybd_Input ; READ THE NULL
JMP short CON$RDND ; AND GET A REAL STATUS
sj6:
MOV [InterH],0 ; not interim
sj7:
LDS BX,[PTRSAV]
MOV [BX].MEDIA,AL ; return the char to dos
cmp [InterH],0
je EXVEC
jmp HanExit
sj8:
cmp ah,Interim_Char ; a Hangeul interim?
jne sj6
mov [InterH],1
jmp short sj7
PAGE
;----------------------------------------------------------------
;
; CONSOLE WRITE ROUTINE
;
CON$WRIT:
JCXZ EXVEC
cmp dl,01h ; write and not ad cursor?
je CON$LP2
CON$LP: MOV AL,ES:[DI] ; GET CHAR
INC DI
MOV AH,Output_Char
INT CHROUT ; OUTPUT CHAR
LOOP CON$LP ; REPEAT UNTIL ALL THROUGH
JMP EXIT
CON$LP2: ; write but do not advance cursor
MOV AL,ES:[DI] ; GET CHAR
INC DI
MOV AH,Output_No_Advance
INT CHROUT
LOOP CON$LP2 ; REPEAT UNTIL ALL THROUGH
JMP EXIT
PAGE
;----------------------------------------------------------------
;
; Initialization Code
;
CON$INIT:
XOR BX,BX
MOV DS,BX
MOV BX,BRKADR
MOV WORD PTR [BX],OFFSET BREAK
MOV WORD PTR [BX+2],CS
MOV BX,CHROUT*4
MOV WORD PTR [BX],OFFSET OUTCHR
MOV WORD PTR [BX+2],CS
LDS BX,CS:[PTRSAV]
MOV WORD PTR [BX].TRANS,OFFSET CON$INIT ; SET BREAK ADDRESS
MOV [BX].TRANS+2,CS
JMP EXIT
CODE ENDS
END
APPENDIX F
MSDOS 2.25 Application Level Interface Extension
1) System call 63H, get_lead_tbl.
This call takes an argument in register AL. This
argument determines what function will this call execute.
Valid values for the function code are 0, 1 and 2.
If AL = 0, then the call returns in DS:SI a pointer to
a table containing the lead byte ranges for the 16 bit
alphabet in question. The table consists of byte pairs that
are the boundaries for the lead bytes (both values
inclusive). The end of the table is marked by two zero byte
entries.
Example, for japanese kanji the table would look like
db 81H,9FH
db 0E0h,0FCh
db 0,0
Note that the values should be read as byte values not
as word values since otherwise the ranges would be
transposed due to the byte ordering in the 8086/88.
This table is empty in the regular version of the dos
(as there are no 16 bit characters). The table if obtained
would point to a pair of zero bytes.
If AL = 1 then the call will set (or reset) the interim
console flag in the dos depending on the value in DL. If DL
= 1, then the interim flag will be SET, and certain console
system calls will return interim characters if these are
available. If DL = 0 then the interim flag is RESET and only
final characters will be returned. The default value of the
flag is RESET. All application programs start with the flag
RESET. The flag is allways restored to the parents setting
when an application terminates.
If AL = 2 then the dos will return in DL the current
value of the console interim flag (0 if RESET, 1 if SET).
If an invalid code is used the call will reurn with
carry set and error code 0 (error_invalid_function).
IMPORTANT NOTE: This system call unlike all other
system calls make NO GUARANTEE to preserve ANY registers
other than SS:SP upon return. So care should be taken to
save all relevant registers before issuing the call. It is
advisable that an application either copy the table to its
private data area or save the pointer to the table at
initialization time. This should save considerable execution
time as there is no need to reissue the call everytime a
check for 16 bit characters is necessary, and consequently
there is no need to save any registers before issuing the
call.
2) Console i/o system calls.
Some console i/o system calls are capable of returning
interim character information to application programs. Only
those applications that have enabled the feature through the
63H call (function 1) will receive interim characters on
these system calls, otherwise the dos will never return
interim characters and the system calls will work as in
previous versions of 2.00.
* Call 01H, Read & Echo.
This call never returns interim characters no matter
what mode the console is on. Composition if any will take
place at the cursor. It will return when the first byte of
the final character is obtained.
* Call 06H, Direct Console i/o.
Always returns final characters, never interims. Only
returns character available when a final character is
available, not when interims are available. Composition if
any is handled as in call 01H.
* Call 07H, Direct Console Input.
Returns interim characters if one is available and the
console mode has been set to interim through the 63H call.
Interim characters are returned with the zero flag SET,
final characters have the flag RESET. In non interim support
(the default) the zero flag value is undefined.
* Call 08H, Read Keyboard.
Same as system call 07H.
* Call 0AH, Buffered Keyboard input.
Always returns a string of final characters,
composition if any, is handled by the dos.
* Call 0BH, Check Keyboard Status.
This call supports interim characters if the console
has been placed in interim mode through the ioctl call. If a
character is available (AL = 0FFH) then the zero flag will
be SET if the character is an interim, or RESET if the
character is a final character. The zero flag is undefined
if either there is no character available, or the console is
not in interim mode.
* Call 0CH, Flush Buffer, Read Keyboard.
This call will flush the type-ahead buffer and execute
the specified console i/o call. The con i/o call will work
as described above for each specific case.
* Call 3FH, Xenix Read.
This call always returns final characters, no matter
what the state of the dos. This call when directed to the
console it ends up in the buffered console input code, and
so it will act as that call (0AH) when used to read from the
console.
APPENDIX G
This file is part of what was formerly supplied with MS-DOS 2.11
as SPECIAL.DOC. It has information about undocumented COMMAND.COM
switches and the version dependent system call (GET_DPB) which
OEM's may use when writing format.
The remaining portions of this file have been incorporated into
printed MS-DOS documentation.
COMMAND invocation
COMMAND [[<drive>:]<path>] [<cttydev>] [/D] [/P] [/C <string>] [/E:nnnn]
/P If present COMMAND will be permanent, otherwise
this is a transient command.
/D If present COMMAND will not prompt for DATE and
TIME when it comes up.
d: Specifies device where command will look for
COMMAND.COM current default drive if absent.
<Path> Specifies a directory on device d: root
directory if absent.
<cttydev> Name of the CTTY device. \DEV\CON if absent
and command is permanent. The \DEV\ may be left
off if AVAILDEV is TRUE (see sysinit doc).
/C <string> If present /C must be the last switch.
This causes COMMAND to try to execute the string
as if the user had typed it at the standard input.
COMMAND executes this single command string and
then exits. If the /P switch is present it is
ignored (can't have a single command, permanent
COMMAND). NOTE: ALL of the text on the command
line after the /C is just passed on. It is not
processed for more arguments, this is why /C must
be last.
/E:nnnn Set the environment size to nnnn (specified in
decimal bytes). The environment size can be between
128 bytes and 32768 bytes. NOTE: This feature is only
available in versions of MS-DOS starting with 3.20.
GET_DPB UNDOCUMENTED SYSTEM CALL. THIS CALL MAY BE USED
TO GET A POINTER TO THE PHYSICAL LOCATION OF THE DISK DEVICE
DRIVER. CONSULT THE DBP STRUCTURE DOCUMENTED IN DOSSYM.ASM
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| C A V E A T P R O G R A M M E R |
| |
Name: * GET_DPB - get pointer to drive parameter
block
Assembler usage:
MOV AH,GET_DPB
INT 21h
; DS:BX has address of drive parameter block
Description:
Return pointer to default drive parameter block.
Error returns:
None.
Assembler usage:
MOV DL,DrvNUM
MOV AH,32H
INT 21h
; DS:BX has address of drive parameter block
Description:
Return pointer to drive parameter block for drive
designated in DL (0=Default, A=1, B=2 ...)
Error returns:
AL = FF
The drive given in DL is invalid.
| |
| C A V E A T P R O G R A M M E R |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
APPENDIX H
This material was taken from the MS-DOS 3.10 Programmer's Reference
Manual. It is intended be used with the MS-DOS 2.XX/3.XX Adaptation
Guide.
7.1 INTRODUCTION
This chapter describes recommended MS-DOS 3.1 programming
procedures. By using these programming hints, you can
ensure compatibility with future versions of MS-DOS.
The hints are organized into the following categories:
Interrupts
System Calls
Device Management
Memory Management
Process Management
File and Directory Management
Miscellaneous
7.2 INTERRUPTS
Never explicitly issue Interrupt 22H (Terminate Process Exit
Address).
This should only be done by the DOS. To change the
terminate address, use Function 35H (Get Interrupt
Vector) to get the current address and save it, then
use Function 25H (Set Interrupt Vector) to change
the Interrupt 22H entry in the vector table to point
to the new terminate address.
PROGRAMMING HINTS Page 7-2
Use Interrupt 24H (Critical Error Handler Address) with
care.
The Interrupt 24H handler must preserve the ES
register.
Only system calls 01H-0CH can be made by an
Interrupt 24H handler. Making any other calls will
destroy the MS-DOS stack and prevent successful use
of the Retry or Ignore options.
The registers SS, SP, DS, BX, CX, and DX must be
preserved when using the Retry or Ignore options.
When an Interrupt 24H (Critical Error Handler Address) is
received, always IRET back to MS-DOS with one of the
standard responses.
Programs that do not IRET from Interrupt 24H leave
the system in an unpredictable state until a
function call other than 01H-0CH is made. The
Ignore option may leave data in internal system
buffers that is incorrect or invalid.
Avoid trapping Interrupt 23H (Control-C Handler Address) and
Interrupt 24H (Critical Error Handler Address). Don't rely
on trapping errors via Interrupt 24H as part of a copy
protection scheme.
These might not be included in future releases of
the operating system.
Interrupt 23H (Control-C Handler Address) must never be
issued by a user program.
Interrupt 23H must be issued only by MS-DOS.
Save any registers your program uses before issuing
Interrupt 25H (Absolute Disk Read) or Interrupt 26H
(Absolute Disk Write).
These interrupts destroy all registers except for
the segment registers.
Avoid writing or reading an interrupt vector
directly to or from memory.
Use Functions 25H and 35H (Set Interrupt Vector and Get
Interrupt Vector) to set and get values in the interrupt
table.
PROGRAMMING HINTS Page 7-3
7.3 SYSTEM CALLS
Use new system calls.
Avoid using system calls that have been superseded
by new calls unless a program must maintain backward ____
compatibility with pre-2.0 versions of MS-DOS. See
Section 1.8, "Old System Calls," of this manual for
a list of these new calls.
Avoid using system calls 01H-0CH and 26H (Create New PSP).
Use the new "tools" approach for reading and writing
on standard input and output. Use Function 4B00H
(Load and Execute Program) instead of 26H to execute
a child process.
Use file-sharing calls if more than one process is in
effect.
See "File Sharing," in Section 1.5.2, "File-Related
Function Requests" in Chapter 1 for more
information.
Use networking calls where appropriate.
Some forms of IOCTL can only be used with Microsoft
Networks. See Section 1.6, "Microsoft Networks," in
this manual for a list of these calls.
When selecting a disk with Function 0EH (Select Disk), treat
the value returned in AL with care.
The value in AL specifies the maximum number of
logical drives; it does not specify which drives
are valid.
7.4 DEVICE MANAGEMENT
Use installable device drivers.
MS-DOS provides a modular device driver structure
for the BIOS, allowing you to configure and install
device drivers at boot time. Block device drivers
transmit a block of data at a time, while character
device drivers transmit a byte of data at a time.
Examples of both types of device drivers are given
in Chapter 2, "MS-DOS Device Drivers."
PROGRAMMING HINTS Page 7-4
Use buffered I/O.
The device drivers can handle streams of data up to
64K. When sending a large amount of output to the
screen, you can send it with one system call. This
will increase performance.
Programs that use direct console I/O via Function 06H and
07H (Direct Console I/O and Direct Console Input) and that
want to read Control-C as data should ensure that Control-C
checking is off.
The program should ensure that Control-C checking is
off by using Function 33H (Control-C Check).
Be compatible with international support.
To provide support for international character sets,
MS-DOS recognizes all possible byte values as
significant characters in filenames and data
streams. Pre-2.x versions ignored the high bit in
the MS-DOS filename.
7.5 MEMORY MANAGEMENT
Use memory management.
MS-DOS keeps track of allocated memory by writing a
memory control block at the beginning of each area
of memory. Programs should use Functions 48H
(Allocate Memory), 49H (Free Allocated Memory), and
4AH (Set Block) to release unneeded memory.
This will allow for future compatibility.
See Section 1.3, "Memory Management," for more
information.
Only use allocated memory.
Don't directly access memory that was not provided
as a result of a system call. Do not use fixed
addressing, use only relative references.
A program that uses memory that has not been
allocated to it may destroy other memory control
blocks or cause other applications to fail.
PROGRAMMING HINTS Page 7-5
7.6 PROCESS MANAGEMENT
Use the EXEC Function Call to load and execute programs.
The EXEC Function (4B00H) is the preferred way to
load programs and program overlays. Using the EXEC
call instead of hard-coding information about how to
load an .EXE file (or always assuming that your file
is a .COM file) will isolate your program from
changes in future releases of MS-DOS and .EXE file
formats.
Use Function 31H (Keep Process), instead of Interrupt 27H
(Terminate But Stay Resident). Function 31H allows programs
to terminate and stay resident that are greater than 64K.
Programs should terminate using End Process (4CH).
Programs that terminate by
- a long jump to offset 0 in the PSP,
- issuing an Interrupt 20H with CS:0 pointing at the PSP,
- issuing an Interrupt 21H with AH=0, CS:0 pointing at the
PSP, or
- a long call to location 50H in the PSP with AH=0
must ensure that the CS register contains the segment
address of the PSP.
7.7 FILE AND DIRECTORY MANAGEMENT
Use the MS-DOS file management system.
Using the MS-DOS file system will ensure program
compatibility with future MS-DOS versions through
compatible disk formats and consistent internal
storage. This will ensure compatibility with future
MS-DOS versions.
Use file handles instead of FCBs.
A handle is a 16-bit number that is returned by
MS-DOS when a file is opened or created using
Functions 3CH, 3DH, 5AH, or 5BH (Create Handle, Open
Handle, Create Temporary File, or Create New File).
The MS-DOS file-related function requests that use
handles are listed in Table 1.5 in Chapter 1,
"System Calls."
These calls should be used instead of the old
file-related functions that use FCBs (file control
blocks). This is because a file operation can
simply pass its handle rather than having to
PROGRAMMING HINTS Page 7-6
maintain FCB information. If FCBs must be used, be
sure the program closes them and does not move them
around in memory.
Close all files that have changed in length before issuing
an Interrupt 20H (Program Terminate), Function 00H
(Terminate Program), Function 4CH (End Process), or Function
0DH (Reset Disk).
If a changed file is not closed, its length will not
be recorded correctly in the directory.
Close all files when they are no longer needed.
Closing unneeded files will optimize performance in
a networking environment.
Only change disks if all files on the disk are closed.
Information in internal system buffers may be
written incorrectly to a changed disk.
7.7.1 Locking Files
Programs should not rely on being denied access to a locked
region.
Determine the status of the region by attempting to
lock it, and examine the error code.
Programs should not close a file with a locked region or
terminate with an open file that contains a locked region.
The result is undefined. Programs that might be
terminated by an Interrupt 23H or Interrupt 24H
(Control-C Handler Address or Critical Error Handler
Address) should trap these interrupts and unlock any
locked regions before exiting.
7.8 MISCELLANEOUS
Avoid timing dependencies.
Various machines use CPUs of different speeds.
Also, programs that rely upon the speed of the clock
for timing will not be dependable in a networking
environment.
PROGRAMMING HINTS Page 7-7
Use the documented interface to the operating system. If
either the hardware or media change, the operating system
will be able to use the features without modification.
Don't use the OEM (Original Equipment Manufacturer)
-provided ROM support.
Don't directly address the video memory.
Don't use undocumented function calls, interrupts,
or features. These items may change or not continue
to exist in future versions of MS-DOS. Use of these
features would make your program highly
non-portable.
Use the .EXE format rather than the .COM format.
.EXE files are relocatable and .COM files are direct
memory images that load at a specific place and have
no room for additional control information to be
placed in them. .EXE files have headers that can be
expanded for compatibility with future versions of
MS-DOS.
Use the environment to pass information to applications.
The environment allows a parent process to pass
information to a child process. COMMAND.COM is
usually the parent process to every application, so
default drive and path information can easily be
passed to the application.
GLOSSARY OF MS-DOS TERMS
Allocation Unit
(See Cluster)
Arena
MS-DOS uses a software memory management scheme.
Blocks in memory are either owned by processes or
are free. An owned block has an ID number, which
is the initial paragraph of the Program Segment
GLOSSARY OF MS-DOS TERMS
Prefix of a process in memory (your program). Each
block has a size as well. When your process is in
memory, there is a 16-byte arena block which
identifies it and specifies how much memory is
allocated.
ASCIZ
Any null (zero byte) terminated ASCII string.
Cluster
The storage unit that MS-DOS uses to allocate space
for files on a disk. All files are allocated in
multiples of clusters. A cluster must be a power
of two sectors (i.e., 1, 2, 4, 8 ... ). This term
is synonymous with allocation unit.
Block device drivers perform I/O in
sectors, not clusters.
Cooked/Raw Mode
Character devices have two modes that have
significance when performing I/O via the Read
Handle and Write Handle calls (Functions 3FH and
40H). These are "raw" and "cooked" mode. A device
driver can be set to raw mode via the IOCTL
Function Request 44H.
Cooked mode input is buffered input with echoing to
the screen (if console) and Control-C checking.
Cooked mode input of a certain number of characters
will return when the specified number of characters
is returned or a carriage return is typed. Cooked
mode output performs Control-C checking between
characters.
Raw mode I/O is very fast. When raw mode I/O of
"n" characters is requested, MS-DOS passes the
request directly to the indicated device driver.
The device driver does not return to MS-DOS until
the I/O has completed. Characters are written or
read directly from the process buffer. No checking
of any kind is performed. No characters have any
significance, including Control-C.
GLOSSARY OF MS-DOS TERMS
For example, if the requesting program puts a
device in raw mode and requests a write of 50,000
characters to the AUX device, the device driver
will get a request from MS-DOS to write 50,000
characters from the buffer located at the DWORD
transfer address. The driver will not return until
the request has completed.
In cooked mode, MS-DOS performs a Control-C check
at the console after each single character write.
This is an overhead of 50,000 Control-C checks.
Environment
The environment is a maximum of 32K data area which
consists of ASCIZ strings of the form:
AAAA=BBBBBBB. The end of the environment is marked
by two consecutive nulls. The word at 2CH in the
Program Segment Prefix points to the segment
containing the start of a program's environment.
New variables can be added to the environment by
using the MS-DOS Set command. Since nulls have
significance, the environment cannot be used for
storing binary data.
When a parent process (such as COMMAND.COM)
executes a child process (any other program), the
child is given a copy of the parent's environment.
Parameters such as Prompt, which specifies the
style of prompt used by COMMAND.COM, are stored in
the environment. Application programs can use the
environment to find overlays or special files which
may not be located in the current directory.
COMMAND.COM uses this technique to examine the
elements of the Path looking for binaries and batch
files. Of course the application program must be
specifically coded to find the environment and
parse it for variables.
FATID Byte
The FATID byte is the first byte of the File
Allocation Table that starts at the sector
immediately after the reserved sectors of the disk.
The FATID byte was used by OEMs in MS-DOS 1.x for
identification of disk media. This byte should be
between F8H and FFH. To read MS-DOS 1.x disks, one
must read this byte, determine which of the four
predefined FATID bytes is present and return a
pointer to the appropriate BPB. This method of
GLOSSARY OF MS-DOS TERMS
determining media is less general and less
desirable than the BPB table method (see MEDIA ID
Byte).
File Handle
In versions of MS-DOS that are 2.0 and higher,
there is a system file table set up at boot time.
By the time COMMAND.COM gets control, all of the
character devices have been entered into the system
file table. The first five handles are initialized
as follows.
HANDLE XENIX NAME DEFAULT SETTING
0 Standard Input CON
1 Standard Output CON
2 Standard Error CON
3 Standard AUX AUX
4 Standard PRN PRN
As new files are opened via XENIX-compatible calls,
they are assigned the first available numbers.
When COMMAND.COM executes a program, the child
process inherits all of the handles that
COMMAND.COM has open. Typing
prog < infyle > outfyle
on the command line means that you want PROG to
read its input from INFYLE and write its output to
OUTFYLE instead of to console out. COMMAND.COM
will close handle 0 and open INFYLE; it will DUP
handle 0. It will then close handle 1, standard
out, and open OUTFYLE (which is assigned to
standard out). COMMAND will exec PROG, which
inherits this environment. When PROG reads from
standard in, or writes to standard out, it reads
from and writes to INFYLE and OUTFYLE,
respectively.
If a child is executed, it inherits the files of
its parent. The converse is not true. When a
child process which opens AUX as standard in and
PRN as standard out returns, the parent does not ___
inherit the files of its child.
GLOSSARY OF MS-DOS TERMS
MEDIA ID Byte
The MEDIA ID byte is the byte in the Bios Parameter
Block (BPB) located at offset 0AH. The MEDIA ID
byte may have any value between 0 and 0FFH. It may
or may not have the same value as the FATID byte.
The major significance of the MEDIA ID byte is that
there be a one-to-one relationship between unique
MEDIA ID bytes and disk formats. For disk
compatibility with other OEMs as well as with
future releases of MS-DOS, Microsoft recommends
that the BPB table be located at offset 0BH in the
first reserved (boot) sector. OEMs may register
their media byte/format combinations with OEM
Customer Support. The BPB technique of determining
disk format is much more general than the limited
FATID byte method and is the preferred method.
The significance of the media byte and FATID byte
depends on whether you have decided to make your
block device driver IBM format-compatible. You
must indicate this by setting bit 13 in the device
driver header. This will alter the way MS-DOS
performs the GET BPB device call. With the NON
FATID bit set, you can support various media,
including IBM format media. If the device driver
is IBM-format compatible, use FATID bytes to
determine the media in the drive. The
correspondence between FATID bytes and various
media is defined in the MS-DOS Programmer's ______ ____________
Reference Manual. _________ ______
If your system is not IBM Format-compatible, you
are given a pointer to a one-sector scratch buffer
when your block device gets called by MS-DOS to do
a BUILD BPB. Follow these steps:
1. Read the boot sector of the disk into that
buffer and check the first byte. If it is an
E9H, it is the first byte of a 3-byte JMP and
there is a BIOS Parameter Block table in the
boot sector.
Alternately, EBH may be the first byte. This
is also a 3-byte JMP (actually, a 2-byte JMP
followed by a NOP).
GLOSSARY OF MS-DOS TERMS
2. Return a pointer to the BPB. Set the status
word and return. If the first byte of the boot
sector is not an E9H, then there is not a BPB
table in the boot sector. You can assume that
the disk is an IBM format disk and the FAT
begins with the second sector of the disk.
Read the FAT into the scratch buffer and check
the first byte. Determine which one of the
four defined FATID bytes it is, and return a
pointer to the appropriate BPB.
Refer to the MS-DOS Programmer's Reference ______ ____________ _________
Manual for a list of valid FATID bytes. Any ______
other media should be defined in the boot
sector and should use a FATID byte of FFH.
Paragraph
Any location in the memory of the 8086 which has an
address that is a multiple of 16 (i.e., 0, 16, 32).