mirror of https://github.com/AR1972/DOS3.3
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
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).
|
|
|
|
|
|
|
|
|