MICROSOFT(R) MS(tm)-DOS Adaptation Guide 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(tm)-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 INTEL is a registered trademark of Intel Corporation. IBM is a registered trademark of International Business Machines Corporation. Microsoft and the Microsoft logo are registered trademarks and MS is a trademark of Microsoft Corporation. XENIX is a trademark of Microsoft Corporation. Document No. 8412-200-00 Part No. 036-014-008 WCONTENTS WCHAPTER 1 MS-DOS 2.0 INSTALLATION KIT 1.1 Readme File 1-1 1.2 Contents 1-1 1.3 Common Questions and Answers about MS-DOS Installation 1-2 1.4 MS-DOS 2.0 Hardware Requirements 1-3 1.5 Compatibility 1-4 1.6 MS-DOS Overview 1-5 WCHAPTER 2 MS-DOS DEVELOPMENT TOOLS WCHAPTER 3 INSTALLING MS-DOS WCHAPTER 4 DISK STRUCTURE AND BOOTSTRAP LOADING 4.1 Reserved Area 4-1 4.2 File Allocation Table 4-2 4.3 The Role of the Boot Sector 4-4 WCHAPTER 5 RESIDENT DEVICE DRIVERS 5.1 Introduction 5-1 5.2 Format of a Device Driver 5-2 5.3 Installation of Device Drivers 5-7 5.4 The CLOCK Device 5-8 5.5 The Device Driver Strategy Routine 5-9 5.6 The Device Driver Interrupt Routine 5-9 5.7 Status Word 5-10 5.8 Device Driver Functions 5-11 5.9 Anatomy of a Device Call 5-23 WCHAPTER 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 WCHAPTER 7 WRITING THE FORMAT MODULE 7.1 Skeletal Format Module 7-9 WCHAPTER 8 TROUBLE SHOOTING WAPPENDIX A FILES ON MS-DOS RELEASE DISKS WAPPENDIX B CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION B.1 Customizing MS-DOS B-1 B.2 Kanji Considerations B-2 B.3 Input B-3 B.4 Output B-3 WAPPENDIX C USE OF THE MS-DOS EXEC CALL WINDEX W CONTENTS WCHAPTER 1 MS-DOS 2.0 INSTALLATION KIT 1.1 Readme File 1-1 1.2 Contents 1-1 1.3 Common Questions and Answers about MS-DOS Installation 1-2 1.4 MS-DOS 2.0 Hardware Requirements 1-3 1.5 Compatibility 1-4 1.6 MS-DOS Overview 1-5 W CHAPTER 1 W MS-DOS 2.0 INSTALLATION KIT W1.1 README FILE Check the README file on the release disks for any addenda and errata for this document. W1.2 CONTENTS The MS-DOS installation kit is available on 5-1/4" or 8" MS-DOS disks. It consists of MS-DOS release software and an evaluation copy of Microsoft(r) Macro Assembler. The installation kit also includes four manuals: MS-DOS 2.0 User's Guide. This is a user's ______ ___ ______ _____ introduction to MS-DOS commands and utilities. MS-DOS 2.0 Programmer's Reference Manual. This ______ ___ ____________ _________ ______ manual includes a summary of all published system calls and MS-DOS structures. MS-DOS Macro Assembler Manual. This contains ______ _____ _________ ______ documentation for Microsoft Macro Assembler, Cross-Reference Utility (MS-CREF), Linker (MS-LINK), Librarian (MS-LIB) and MS-DOS debugger (MS-DEBUG). The MS-DOS Macro Assembler Manual is ______ _____ _________ ______ included with the Macro Assembler evaluation package. MS-DOS 2.0 Adaptation Guide. This manual describes ______ ___ __________ _____ how to implement MS-DOS on OEM machines. MS-DOS 2.0 INSTALLATION KIT Page 1-2 W1.3 COMMON QUESTIONS AND ANSWERS ABOUT MS-DOS INSTALLATION 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 most of MS-DOS are available to licensees of the product for an additional source fee. These sources are used by Microsoft on a mainframe computer for assembling MS-DOS using an internally developed Cross-Assembler. We cannot guarantee that the source files can be assembled on other systems. NOTE Sources for the Linker and some other utilities are not included in MS-DOS source package. 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 2.0 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. W1.4 MS-DOS 2.0 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 should be INTEL(R) 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 Implementation of an ANSI terminal driver. (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 64K of RAM (depending on BIOS size). Microsoft recommends a minimum configuration of 128K nonvideo RAM and 192K for future products. 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 systems are starred. MS-DOS 2.0 INSTALLATION KIT Page 1-4 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 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. W1.5 COMPATIBILITY Some well known programs written for popular MS-DOS machines perform console I/O directly to the hardware of those machines or use machine-specific interrupts rather than using MS-DOS console system calls. This is usually done to facilitate using bit-mapped graphics or to improve performance for programs where extreme speed is an issue. These programs will not run on any MS-DOS system unless it duplicates the same hardware environment. Programs which use MS-DOS system calls for I/O will run on all MS-DOS systems of the appropriate version. MS-DOS 2.0 is compatible with all "well behaved" MS-DOS 1.1 programs. Pre-2.0 programs, which exploited undocumented characteristics of MS-DOS 1.0 or characteristics of a particular machine, may not be compatible with MS-DOS 2.0. See the SPECIAL file on the MS-DOS release disks for more information. MS-DOS 2.0 INSTALLATION KIT Page 1-5 W1.6 MS-DOS OVERVIEW An MS-DOS implementation requires seven components: 1. The resident device drivers, often called the BIOS (Basic Input Output System), 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. SYSINIT, Microsoft-supplied modules which are linked to the BIOS and initialize the system. The file that contains BIOS and SYSINIT is named IO.SYS. 3. MSDOS.SYS, the hardware-independent disk operating system supplied by Microsoft. 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 which loads the IO.SYS and MSDOS.SYS files into memory. MSDOS.SYS may optionally be loaded by IO.SYS. 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. MS-DOS 2.0 INSTALLATION KIT Page 1-6 During the system initialization process, there is a series of memory arrangements as the bootstrap loader gets loaded into memory, as the IO.SYS and MSDOS.SYS files are loaded, and finally, as the SYSINIT module installs MS-DOS, the installable drivers, and COMMAND.COM. Refer to Chapter 6, "SYSINIT and MS-DOS Initialization," for figures that illustrate memory organization during MS-DOS initialization. W CONTENTS WCHAPTER 2 MS-DOS DEVELOPMENT TOOLS EDLIN Text Editor 2-1 Microsoft Macro Assembler 2-1 Microsoft Linker (MS-LINK) 2-1 MS-DEBUG 2-2 EXE2BIN 2-2 FORMAT 2-2 W CHAPTER 2 W 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: WEDLIN 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 release disks is for version 2.x only, and will not run under MS-DOS 1.x. WMicrosoft Macro Assembler An evaluation copy of 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.x 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. WMicrosoft Linker (MS-LINK) Your MS-DOS development machine should include a linker at the proper MS-DOS release level. The Linker on MS-DOS 2.x release disks will not run under MS-DOS 1.x. Use LINK.EXE for linking object modules (OBJ files) produced by 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 Chapter 5 in the MS-DOS 2.0 Programmer's Reference Manual ______ ___ ____________ _________ ______ for details on EXE formats. MS-DOS DEVELOPMENT TOOLS Page 2-2 WMS-DEBUG DEBUG.COM is the MS-DOS debugger. The version supplied with MS-DOS 2.x will not run under MS-DOS 1.x. The debugger can do absolute disk reads and writes. You may use this facility to write your bootstrap loader program into the boot sector. WEXE2BIN 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. The EXE2BIN version on the release disks will run only under MS-DOS 2.x. WFORMAT The FORMAT program (FORMAT.COM) supplied with your MS-DOS development machine may be used to format a boot disk for the target machine. W CONTENTS WCHAPTER 3 INSTALLING MS-DOS W CHAPTER 3 W 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. 1. Using a text editor on your development machine, write the 8086 assembler source code for the resident device drivers. The resident device drivers (sometimes referred to as the BIOS) 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 2.0 Programmer's Reference Manual ______ ___ ____________ _________ ______ SKELIO.ASM disk file (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 SYSINIT.OBJ and SYSIMES.OBJ. The modules must be linked in this order: IO.OBJ+SYSINIT.OBJ+SYSIMES.OBJ. The output file should be named IO.EXE. You will get the message INSTALLING MS-DOS Page 3-2 "Warning, no STACK segment" while linking the module. This is a warning message and is normal. For more information, see: Microsoft Macro Assembler Manual (MS-LINK) _________ _____ _________ ______ 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 Guide (Chapter 5) ______ ______ _____ 5. Write a bootstrap loader program using the text editor. 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 upon power-up or reset. Ideally, the bootstrap loader fits into the first sector of the boot disk. In addition to the loader, the first sector of the disk must contain a table describing the disk format and should contain some OEM information. (See section 5.8.5 for the format of this table). 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 INSTALLING MS-DOS Page 3-3 always be the first files on the disk. This means that a bootstrap loader could simply load a series of consecutive sectors into memory. For more information, see: MS-DOS 2.0 Programmer's Reference Manual ______ ___ ____________ _________ ______ (Chapter 2) MS-DOS 2.0 Adaptation Guide (Chapter 4) ______ ___ __________ _____ 6. Assemble, link, and EXE2BIN the BOOT.ASM file that produces BOOT.BIN. 7. Format a nonsystem disk using your MS-DOS development machine. 8. Using the MS-DOS COPY command, copy IO.SYS, MSDOS.SYS, and the 2.0 version of COMMAND.COM to the formatted disk. 9. 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 For more information, see: Microsoft Macro Assembler Manual (DEBUG section) _________ _____ _________ ______ The formatted disk should now be bootable by your system. 10. Write the source code for the hardware-specific part of the FORMAT program. Assemble and link this to the FORMAT.OBJ and FORMES.OBJ files supplied by Microsoft. The modules must be linked in the following order: FORMAT+FORMES+OEMFOR where OEMFOR.OBJ is your hardware specific module. Use EXE2BIN to convert the OEMFOR.EXE file produced to FORMAT.COM. INSTALLING MS-DOS Page 3-4 For more information, see: MS-DOS 2.0 Adaptation Guide (Chapter 7) ______ ___ __________ _____ GENFOR.ASM Disk file of sample OEM format module MS-DOS 2.0 User's Guide (Chapter 5, Format Command) ______ ___ ______ _____ MS-DOS 2.0 Programmer's Reference Manual (Chapter ______ ___ ____________ _________ ______ 3) 11. Customize the function key table in DOSMES.ASM, and install the MS-DOS serial number. For more information, see: MS-DOS 2.0 Adaptation Guide ______ ___ __________ _____ (Appendix B, "Customizing MS-DOS") SPECIAL file on MS-DOS release disks W CONTENTS WCHAPTER 4 DISK STRUCTURE AND BOOTSTRAP LOADING 4.1 Reserved Area 4-1 4.2 File Allocation Table 4-2 4.2.1. Disk Format Identification 4-3 4.3 The Role of the Boot Sector 4-4 W CHAPTER 4 W 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 nonstandard disks or nonremovable 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, a ________ number of manufacturers have implemented 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. A few manufacturers have even implemented the MS-DOS file system logically within another operating system's file structure. W4.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. In this case, the entire track should be marked as reserved or the device driver may 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 require several sectors. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-2 W4.2 FILE ALLOCATION TABLE Because the File Allocation Table (FAT) is the most important data structure on the disk, two copies are usually kept at the OEMs option. (Two copies are not 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" which are a power of 2 sectors ( 1, 2, 4, 8, 16, etc.). The FAT is a physical map of the allocation units in the data area of the disk. There is one 12-bit entry in the FAT 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 = 1.5 * ( T - R - D + 2*A) ------------------------- 1.5 * 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. 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 The format program will create a proper FAT. The FAT has a 1-1/2 byte 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 1-1/2-byte entries is used by some OEMs to indicate the format of the disk. Only the low 8 bits (first byte of the FAT) are used, and this byte is often referred to as the FAT ID byte. The high 4 bits of this first 12-bit cluster are all set. The second (1st cluster) of these two reserved 1-1/2-byte entries is reserved. It is always 0FFFH, which is an end-of-file mark (EOF). In this way, if the FAT becomes damaged and a cluster chain accidentally points to cluster 1, MS-DOS interprets it as EOF. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-3 Figure 1 illustrates the first two clusters of a File Allocation Table. FAT BYTE 00 01 02 03 XXh XXh XXh XXh || || || 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) | FAT ID BYTE Figure 1. First Two Clusters of the FAT. W4.2.1 Disk Format Identification Beginning with MS-DOS 2.00, Microsoft is promoting the use of a media description 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. See Chapter 5, Figure 10, for the format of this table. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-4 W4.3 THE ROLE OF THE BOOT SECTOR Typically, the system ROM will load the reserved (boot) sector or sectors into memory at powerup or restart. The boot sector has the following responsibilities: 1. It must read in 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 MS-DOS files are not found in the directory by the boot code, then the boot sector should prompt the operator that an attempt has been made to boot from a nonbootable 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, which are contiguous on the disk. Alternatively, the boot sector may read in only IO.SYS, and IO.SYS may then read in MSDOS.SYS. The boot sector must know or calculate where those files physically begin on the disk (right after the last directory sector). You must code the (combined) length of these files into the boot sector. You must also code 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 utility allows users to transfer the operating system onto a formatted disk which contains no files or contains a version of the operating system to be updated. For the MS-DOS 2.0 version on the IBM PC, the SYS command was modified to transfer MS-DOS 2.0 system files onto old 1.x disks. The new MSDOS.SYS can be placed on the disk in a noncontiguous format. (IO.SYS is still contiguous because DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-5 the new IO.SYS is smaller than the 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 noncontiguous 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 if you need to be able to SYS 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. W CONTENTS WCHAPTER 5 RESIDENT DEVICE DRIVERS 5.1 Introduction 5-1 5.2 Format of a Device Driver 5-2 5.3 Installation of Device Drivers 5-7 5.4 The CLOCK Device 5-8 5.5 The Device Driver Strategy Routine 5-9 5.6 The Device Driver Interrupt Routine 5-9 5.7 Status Word 5-10 5.8 Device Driver Functions 5-11 5.8.1 INIT (Command Code O) 5-12 5.8.2 MEDIA CHECK (Command Code 1) 5-14 5.8.3 BUILD BPB (Command Code 2) 5-17 5.8.4 READ OR WRITE Including IOCTL 5.8.5 NON DESTRUCTIVE READ NO WAIT (Command Code 5) 5-21 5.8.6 STATUS Calls (Command Code 6, 10) 5-22 5.8.7 FLUSH Calls (Command Codes 7, 11) 5-22 5.9 Anatomy of a Device Call 5-23 W CHAPTER 5 W RESIDENT DEVICE DRIVERS W5.1 INTRODUCTION The IO.SYS file is composed of the "resident" device drivers. This forms the MS-DOS 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 an end user at boot time via the "DEVICE =" entry in the CONFIG.SYS file. In this section, these non-resident drivers are termed "installable" 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 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.0 does not take advantage of the two entry points: it calls 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 RESIDENT DEVICE DRIVERS Page 5-2 "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.0 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 section, which has the same format for all requests. 2. A section which 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.0 version of 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. It is assumed that the request is completed when the interrupt routine returns. W5.2 FORMAT OF A DEVICE DRIVER A device driver is a relocatable memory image which contains all of the code to implement the device. As previously mentioned, it has a special header at the front to identify it as a device, define the strategy and interrupt entry points, and define various attributes. RESIDENT DEVICE DRIVERS Page 5-3 There are two types of devices: 1. Character devices 2. Block devices Character devices are designed to do character I/O in a serial manner. The required character devices are: CON Keyboard input and screen output. AUX Auxiliary tty device (often an RS232 port). PRN Printer device driver. CLOCK The CLOCK device. Users may open channels (file handles) to do I/O to them and treat them just like files. Block devices are the "disk drives" on the system. They can perform random I/O in pieces called blocks, usually the physical sector size. These devices are not "named" as character devices are, and therefore cannot be opened directly. Instead, they are mapped via drive letters (A,B,C, etc.,). Block devices have units. A single driver may be responsible for one or more disk drives. For instance, the first block device driver may be responsible for drives A,B,C, and D; this means that it has four units (0-3) defined, and therefore uses four drive letters. Which units correspond to which drive letters is determined by the position of the driver in the chain of all drivers. For example, if the first block driver in the device chain defines four units (0-3), they will be A,B,C, and D. If the second block driver defines three units (0-2), then they will be E,F, and G. MS-DOS 2.0 is not limited to 16 block device units. The theoretical limit is 63 (26 - 1), but after 26, the drive designations are unconventional (like "]" and "^"). Character devices cannot define multiple units because they have only one name. RESIDENT DEVICE DRIVERS Page 5-4 Figure 2 illustrates the device driver header format. +-------------------------------------+ | DWORD pointer to next driver | | (Set to -1,-1 on installable | | devices or on last resident driver | +-------------------------------------+ | WORD attributes | | Bit 15 = 1 if char device or 0 | | if block device | | if bit 15 is 1: | | Bit 0 = 1 if Current sti device | | Bit 1 = 1 if Current sto device | | Bit 2 = 1 if Current NUL device | | Bit 3 = 1 if Current CLOCK | | Bit 4 = 1 if Special device | | Bit 14 is the IOCTL bit | | Bit 13 is NON IBM FORMAT bit | +-------------------------------------+ | WORD pointer to device strategy | | entry point | +-------------------------------------+ | WORD pointer to device interrupt | | entry point | +-------------------------------------+ | 8 BYTE Character device name field | | Left-justified space filled | | Uppercase characters | | | | For block devices, first byte is | | number of units defined | +-------------------------------------+ Figure 2. Device Driver Header Format 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 the table, then XXX:STRATEGY and XXX:INTERRUPT are the entry points. In the attribute field, bit 15 is used to tell the system whether this is a block or character device. Most other bits are used to give selected character devices special treatment. Except for bit 13, these bits have no meaning on a block device. Assume that a user wants to use a new device driver as the standard input and output. Besides installing the driver, the user needs to tell SYSINIT that the new driver should override the current sti (standard input) and sto (standard output, i.e., the CON device). This is accomplished by setting the attributes to the desired characteristics: bits 0 and 1 would be set to 1 (note that they are separate). Similarly, a new CLOCK device could be installed by setting RESIDENT DEVICE DRIVERS Page 5-5 bit 3 to 1. NOTE Although there is a NUL device attribute, the NUL device cannot be reassigned. This attribute exists so MS-DOS can determine if the NUL device is being used. Bit 13, the NON IBM FORMAT bit, applies only to block devices and affects the operation of the Get BPB device call. Bit 14, the IOCTL bit, has meaning on character or block devices. It tells MS-DOS whether this device can handle control strings via the IOCTL system call, Function 44H. The IOCTL functions allow data to be sent and received by the device for its own use (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 it must ____ not be treated as normal I/O. ___ If a device driver cannot process control strings, it should initially set bit 14 to 0. This tells MS-DOS to return an error if an attempt is made (via the IOCTL system call) to send or receive control strings to this device. A device that can process control strings should initialize the IOCTL bit to 1. For this type of driver, MS-DOS can make calls to the IOCTL INPUT and OUTPUT device functions to send and receive IOCTL strings. Bit 4, the special bit, applies to CON drivers. The new 2.0 interface supports many new features, but it is slower than 1.25 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-6 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, the special bit, has been implemented to help 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. 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 will not be supported in future versions of the operating system. Any application (not device driver) which uses Interrupt 29H directly will not work on future versions. 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 which 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. EXE format installable device drivers may be used in non IBM versions of MS-DOS. On the IBM PC, the EXE loader is RESIDENT DEVICE DRIVERS Page 5-7 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 sti and 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. W5.3 INSTALLATION OF DEVICE DRIVERS MS-DOS 2.0 allows new device drivers to be installed dynamically at boot time. This is accomplished by the SYSINIT module supplied by Microsoft which reads and processes the CONFIG.SYS file. The resident driver source file (IO.ASM) is assembled and linked to SYSINIT.OBJ 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. RESIDENT DEVICE DRIVERS Page 5-8 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> W5.4 THE CLOCK DEVICE The CLOCK device is used by MS-DOS 2.0 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 3 illustrates the binary date and time format used by the CLOCK device. 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 3. CLOCK Device Format RESIDENT DEVICE DRIVERS Page 5-9 W5.5 THE DEVICE DRIVER STRATEGY ROUTINE The first entry point in the device driver is the strategy routine. The purpose of the strategy routine is to allow MS-DOS to pass to the device driver a pointer to the request packet built by MS-DOS. On entry, ES:BX points to the packet and should be stored by the driver. The strategy routine should then do a FAR return. MS-DOS 2.0 immediately calls the interrupt entry point. W5.6 THE DEVICE DRIVER INTERRUPT ROUTINE The device driver interrupt routine is called with no parameters. Its primary function is to perform the operation based on the data in the request packet in memory and then return to MS-DOS. The interrupt routine must be able to perform the following calls: 0 INIT 1 MEDIA CHECK (Block only, NOP for character) 2 BUILD BPB " " " " " 3 IOCTL INPUT (Only called if device has IOCTL) 4 INPUT (Read) 5 NON-DESTRUCTIVE INPUT NO WAIT (Char devs only) 6 INPUT STATUS " " " 7 INPUT FLUSH " " " 8 OUTPUT (Write) 9 OUTPUT (Write) with verify 10 OUTPUT STATUS " " " 11 OUTPUT FLUSH " " " 12 IOCTL OUTPUT (Only called if device has IOCTL) The interrupt routine performs the request described by the packet and returns to MS-DOS when it is done. The device driver must recognize the format of the request packet. which consists of a fixed-length header followed by various parameters, depending upon which of the 13 calls are being made. RESIDENT DEVICE DRIVERS Page 5-10 Figure 4 illustrates the format of the request packet header. 13-BYTE REQUEST PACKET HEADER -> +-----------------------------+ | BYTE total length of packet | +-----------------------------+ | BYTE unit code | | The subunit (drive) the | | operation is for | | No meaning on character | | devices | +-----------------------------+ | BYTE command code | +-----------------------------+ | WORD status | +-----------------------------+ | 8 bytes reserved here for | | two DWORD links. One will | | be a link for MS-DOS queue, | | the other for the device | | queue | +-----------------------------+ Figure 4. Request Packet Header Format W5.7 STATUS WORD Figure 5 illustrates the format of the status word. 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 | | +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--++ Figure 5. Status Word Format The status word is zero on entry and is always set by the driver interrupt routine on return. Bit 8 is the done bit. It means the operation is complete. Currently the driver sets it to 1 when it exits. Bit 9 is the busy bit which is set only by status calls (see Section 5.8.8, "Status Calls.") RESIDENT DEVICE DRIVERS Page 5-11 Bit 15 is the error bit. If it is set, then the low 8 bits indicate one of the following errors: 0 Write protect violation 1 Unknown unit 2 Not ready 3 Unknown command 4 CRC error 5 Bad request packet 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 W5.8 DEVICE DRIVER FUNCTIONS The following device driver functions are described in this section: 1. INIT and the Bios Parameter Block 2. Build BPB and determining disk formats 3. Read or Write Calls 4. Non Destructive Read No Wait 5. Status Calls 6. Flush Calls RESIDENT DEVICE DRIVERS Page 5-12 W5.8.1 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 6 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 6. INIT Format For resident character devices: ___ ________ _________ _______ No parameters are passed, and none are returned. For installable character devices: ___ ___________ _________ _______ If the INIT call is being made for an installable driver, the request packet location "DWORD pointer to BPB array" will contain a pointer to the equal sign in the "DEVICE =" statement in the CONFIG.SYS file (located in memory). This allows the CONFIG.SYS file to pass parameters to a device driver. The break address parameter must be returned. This is a pointer to the first available byte of memory above the driver and may be used to throw away initialization code. 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 the Install call, 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 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 RESIDENT DEVICE DRIVERS Page 5-13 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. NOTE For installable block device drivers, the Break Address (which is a pointer to the first free byte of memory) must be returned as in the character device driver. The BPBs and the array of word offsets must be below this location. Like the character driver, the pointer to the "=" in the "DEVICE =" entry is present for passing parameters to the device driver. The BPB is used by MS-DOS to create an internal structure called the Drive Parameter Block (DPB). 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 DPB for the particular drive unit. RESIDENT DEVICE DRIVERS Page 5-14 Figure 7 illustrates the format of the BPB. +------------------------------------+ | WORD Sector size in bytes | | Must be a multiple of 64 | +------------------------------------+ | BYTE Sectors/allocation unit | | Must be a power of 1, 2, 4 etc. | +------------------------------------+ | WORD Number of reserved (boot) | | sectors. May be zero | +------------------------------------+ | BYTE Number of FATs | +------------------------------------+ | WORD Number of directory entries | | in the root directory | +------------------------------------+ | WORD Total number of sectors | | Includes reserved sectors | +------------------------------------+ | BYTE Media descriptor | | Must be unique for each BPB | +------------------------------------+ | WORD Number of sectors occupied by | | a single FAT | +------------------------------------+ Figure 7. BPB Format W5.8.2 MEDIA CHECK (Command Code 1) Figure 8 illustrates the format of the MEDIA CHECK function. +------------------------------------+ | 13-BYTE Request Header | +------------------------------------+ | BYTE Old media descriptor from DPB | +------------------------------------+ | BYTE returned | +------------------------------------+ Figure 8. MEDIA CHECK Format The MEDIA CHECK function is called when there is a pending drive access call other than a file read or write. 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. The RESIDENT DEVICE DRIVERS Page 5-15 MEDIA CHECK routine sets the status word and returns a byte with the following values: -1 Disk has been changed 0 Don't know if disk has been changed 1 Disk has not been changed If the driver returns -1 or 1 (with a doorlock or some other detection mechanism), MS-DOS performance will be greatly enhanced, since MS-DOS will not have to reread the FAT and directory for each directory access. Some OEMs have creatively surmounted the problem of no doorlocks. One OEM determined that it was impossible for the operator to change a disk in less than 2 seconds; therefore, when MEDIA CHECK occurred within 2 seconds of a disk access, the driver reported "1," media not changed. This made a tremendous improvement in performance. When a disk access call (other than a file read or write) occurs, the following sequence of events takes place: 1. The drive letter is turned into a DPB pointer by looking through the list of DPBs until the correct driver unit number is found. 2. The pointer to the driver is retreived from the DPB and the device driver is then called to request a media check on that subunit. 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 RESIDENT DEVICE DRIVERS Page 5-16 If the media has not been changed, MS-DOS proceeds with the disk access. If the media has been changed, MS-DOS invalidates all buffers associated with this unit and requests a new BIOS Parameter Block via the BUILD BPB call (see step 3, below). If the value returned is "don't know," then if there are any dirty buffers (disk sectors which have been modified and not written back out to the disk yet) for this unit, MS-DOS assumes that the disk has not been changed and proceeds. If there are no dirty buffers for the unit, MS-DOS invalidates any buffers for the unit and does a BUILD BPB device call (see step 3, below). 3. If the media has been changed or if it might have been changed and there are no dirty buffers, MS-DOS invalidates all buffers for the drive, calls the device, and requests a new BPB. Once the BPB has been returned, MS-DOS builds a DPB and proceeds with the access after reading the directory and the FAT. NOTE If the media ID byte in the returned BPB is the same as the previous media ID byte, MS-DOS will assume that the format of the disk is the same and will skip the step of creating a new DPB. Therefore all BPBs must have unique media bytes regardless of FAT ID bytes. RESIDENT DEVICE DRIVERS Page 5-17 W5.8.3 BUILD BPB (Command Code 2) Figure 9 illustrates the format of the BUILD BPB call. +------------------------------------+ | 13-BYTE Request Header | +------------------------------------+ | BYTE Media descriptor from DPB | +------------------------------------+ | DWORD Transfer Address | | (points to one sector's worth of | | scratch space or first sector | | of FAT depending on the value | | of the NON IBM FORMAT bit) | +------------------------------------+ | DWORD Pointer to BPB | +------------------------------------+ Figure 9. BUILD BPB Format As described in the MEDIA CHECK call, the Build BPB call will be made any time that a preceding MEDIA CHECK call indicates that the disk has been changed. The device driver returns a pointer to a BPB. This is different from the INIT call where a pointer to an array of word offsets to BPBs is returned. The data passed in the request packet depends on how the NON IBM FORMAT bit is set in the attribute word of the device driver header. If the NON IBM FORMAT bit is set, then the DWORD Transfer Address points to a one-sector buffer which can be used for any purpose. If the NON IBM FORMAT bit is 0, this buffer contains the first sector of the FAT; in this case, the driver must not alter this buffer. (This mode is useful if all you want to do is read the FAT ID byte.) If IBM-compatible format is used (NON IBM FORMAT bit = 0), then the first sector of the first FAT must be the second physical sector on the disk for all possible media. This is because the FAT sector will be read before the media is determined. In MS-DOS 2.0, the media descriptor byte identifies different media. 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.0 to determine the disk media and may be used as well under 2.0 disk device drivers. However, FAT ID bytes only have significance for IBM format-compatible block device drivers. RESIDENT DEVICE DRIVERS Page 5-18 The following values have been defined for 5-1/4" floppy disks: FE - 1 side 512 bytes per sector 8 sectors per track FC - 1 side 512 bytes per sector 9 sectors per track FF - 2 sides 512 bytes per sector 8 sectors per track FD - 2 sides 512 bytes per sector 9 sectors per track For complete details, see the MS-DOS 2.0 Programmer's ______ ___ ____________ Reference Manual. _________ ______ Values of the media descriptor byte or the FAT ID byte have no significance to MS-DOS. They are passed to the device driver to facilitate media determination in any way the OEM chooses to implement. IMPORTANT When the BPB call is made, if the media byte returned in the new BPB is the same as the old media byte, a new DPB is not built. MS-DOS will treat the disk as though the format has not changed, even though the physical disk might have changed. Therefore, each BPB must have a unique media descriptor byte. RESIDENT DEVICE DRIVERS Page 5-19 To enable OEMs to read each other's disks, the information relating to the BPB should be kept in the boot sector of the disk. The format of the boot sector is shown in Figure 10. +------------------------------------+ | 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 | | +------------------------------------+ | | BYTE Number of FATs | | +------------------------------------+ | | WORD Number of root dir entries | | +------------------------------------+ | | WORD Number of sectors in logical | | | image | | +------------------------------------+ B | BYTE The media descriptor | P +------------------------------------+ B | WORD Number of sectors per FAT | ---+------------------------------------+ | WORD Sectors per track (optional) | +------------------------------------+ | WORD Number of heads (optional) | +------------------------------------+ | WORD Number of hidden sectors | | (optional) | +------------------------------------+ Figure 10. Format of Boot Sector Table The last three words in the boot sector are optional. "Number of heads" is useful for supporting different multihead drives which have the same storage capacity, but a different number of surfaces. "Number of hidden sectors" supports drive partitioning schemes. The following procedure is recommended for media determination by NON IBM FORMAT drivers: 1. Read the boot sector of the drive into the 1-sector scratch space pointed to by the DWORD transfer address. 2. Determine if the first byte of the boot sector is an E9H (the first byte of a 3 byte jump). If so, a BPB is located there. Return a pointer to it. If the boot sector does not have a BPB table, it RESIDENT DEVICE DRIVERS Page 5-20 must be a pre-2.0 IBM format disk that uses a FAT ID byte. 3. Read the FAT into the 1-sector scratch area and read the first byte to determine which of the four recognized 5-1/4" formats are present. Return a pointer to a hard-coded BPB. W5.8.4 READ OR WRITE Including IOCTL Figure 11 illustrates the format of the READ OR WRITE call. +------------------------------------+ | 13-BYTE Request Header | +------------------------------------+ | BYTE Media descriptor from DPB | +------------------------------------+ | DWORD Transfer address | +------------------------------------+ | WORD Byte/sector count | +------------------------------------+ | WORD Starting sector number | | (ignored on character devices | +------------------------------------+ COMMAND CODE REQUEST 3 IOCTL READ 4 READ (block or character) 8 WRITE (block or character) 9 WRITE WITH VERIFY (block ) 12 IOCTL WRITE Figure 11. READ OR WRITE Format 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. This should be done even if an error prevented the transfer from being completed. Setting the error bit and error code alone is not sufficient. RESIDENT DEVICE DRIVERS Page 5-21 NOTE No error check is performed on an IOCTL call. The driver must correctly set the return sector (byte) count to the actual number of bytes transferred. If the verify switch is on, the block device driver will be called with command code 9 (WRITE WITH VERIFY). Your device driver will be responsible for verifying the write. The following applies to block device drivers: ___ _________ _______ __ _____ ______ _______ Under certain circumstances, a block device driver may be asked to do a write operation of 64K bytes, which seems to be a wrap around of the transfer address in the I/O packet. This arises due to an optimization added to the write code in MS-DOS. It will only occur during user writes within a sector size of 64K bytes on files that are growing past the current EOF. The BIOS can ignore the balance of the write which wraps around. For example, a write of 10000H bytes 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 cause a wrap around (even to 0) in the transfer segment. W5.8.5 NON DESTRUCTIVE READ NO WAIT - (Command Code 5) Figure 12 illustrates the format of the NON DESTRUCTIVE READ NO WAIT call. +------------------------------------+ | 13-BYTE Request Header | +------------------------------------+ | BYTE Read from device | +------------------------------------+ Figure 12. NON DESTRUCTIVE READ NO WAIT Format This call allows MS-DOS to look ahead one input character. The device sets the done bit in the status word. The busy bit in the status word is set as follows: Busy bit = 0 characters in buffer The next character that would be read is returned. This character is not removed from the input buffer (hence the ___ term Non Destructive Read). RESIDENT DEVICE DRIVERS Page 5-22 W5.8.6 STATUS Calls (Command Code 6, 10) Figure 13 illustrates the format of Status calls. +------------------------------------+ | 13-BYTE Request Header | +------------------------------------+ Figure 13. STATUS Call Format For Status calls, the driver must set the status word and set the busy bit as follows: For output on character devices: BIT = 1 Busy; on return, a write request (if made) would wait for completion of a current request. BIT = 0 Not Busy; there is no current request and a write request (if made) would start immediately. For input on character devices with a buffer, a return of 1 means a read request (if made) would go to the physical device. If it is 0 on return, there are characters in the device's buffer and a read returns quickly. It also indicates that the user has typed something. MS-DOS assumes all character devices have an input type-ahead buffer. Devices that don't have one should always return busy = 0 so that MS-DOS does not hang waiting for something to get into a buffer that doesn't exist. W5.8.7 FLUSH Calls (Command Codes 7, 11) These calls tell the driver to flush (terminate) all pending requests. Their primary use is to flush the input queue on character devices. Figure 14 illustrates the format of FLUSH calls. +------------------------------------+ | 13-BYTE Request Header | +------------------------------------+ Figure 14. FLUSH Call Format The device driver performs the flush function, sets the status word and returns. RESIDENT DEVICE DRIVERS Page 5-23 W5.9 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. MS-DOS 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 to an index into a dispatch table and control passes to the disk write routine. 6. The device driver reads the unit code (offset 1) to determine which disk drive is supposed to write. 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 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 transfer address indicated in the request packet. 9. 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. (This is not necessary if the number of sectors is the same as requested.) RESIDENT DEVICE DRIVERS Page 5-24 10. The device driver does a FAR return to MS-DOS. 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. The device drivers should preserve the state of MS-DOS. This means that all registers (including flags) should be preserved. 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 employs extensive stack operations. W CONTENTS W 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 W CHAPTER 6 W SYSINIT AND MS-DOS INITIALIZATION W6.1 INTRODUCTION In addition to implementing the resident drivers and performing any hardware initialization, the IO.ASM (BIOS) code must initialize certain external variables. These variables are declared public in the SYSINIT module 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 MS-DOS' idea of where memory starts. 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. MEMORY_SIZE WORD This word is the paragraph number of the highest location in RAM. If you do not initialize MEMORY_SIZE, SYSINIT AND MS-DOS INITIALIZATION Page 6-2 SYSINIT will do a memory scan to determine the amount of memory. It does this by reading evry 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, 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. If no value is set, it will default to two. It should be greater than 1. FILES BYTE This is the default number of open files that system calls 2FH-57H 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 your BIOS as follows: EXTRN SYSINIT:FAR After your BIOS 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 the BIOS 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 do writes 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). WARNING RE_INIT must not change any DOS registers or flags. W6.2 THE ROLE OF SYSINIT The following steps illustrate the role of SYSINIT in MS-DOS initialization: 1. When SYSINIT gains control from the BIOS initialization code, it determines the size of memory (performing a scan if requested) 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 later in this section). 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 RET 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 for reserving space for an installable device with a larger sector size rather than actually reflecting the format of the installed disk. In this case, these dummy BPBs must have media bytes which do not have the same value as those used in real BPBs. 5. SYSINIT calls RE_INIT in the BIOS (IO.ASM) to allow the OEM to print headers or handle any other initialization. WARNING Do not attempt to modify memory. 6. After the BIOS 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, SHELL, and so on. 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 completely reconfigure the BIOS. 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 BIOS. 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 except the standard error handle (handle 2), 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 does an EXEC of COMMAND.COM 11. COMMAND.COM allocates memory for its transient and loads it MS-DOS is now up and running. W6.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 a reload 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 | +- - - - - - - - - - - - - - -+ | | | | | | +-----------------------------+ | | | MSDOS.SYS | MS-DOS disk operating system | | in temporary location | | +-----------------------------+ | SYSINIT | Microsoft-supplied system ini- +- - - - - - - - - - - - - - -+ tialization 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 | and installable drivers | drivers and buffers here +-----------------------------+ | | | MSDOS.SYS | SYSINIT moves MS-DOS | relocated by SYSINIT | down to OEM designated | to fill hole in 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, buffers, | (TPA) | etc. +-----------------------------+ | COMMAND.COM (resident) | COMMAND.COM loads its +-----------------------------+ transient part into top of | | largest available memory | MS-DOS structures, buffers | | 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. W CONTENTS WCHAPTER 7 WRITING THE FORMAT MODULE W 7.1 Skeletal Format Module 7-9 W CHAPTER 7 W WRITING THE FORMAT MODULE 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 which have no equivalent in MS-DOS function calls, FORMAT is shipped in two hardware-independent object modules which must be linked to a hardware specific module which must be 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 command syntax for FORMAT 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. The OEM must supply five NEAR routines to the FORMAT program. These routines must be declared PUBLIC in the OEM-supplied module. The routines are: 1. INIT An initialization routine. This routine is called once at the start of FORMAT after the switches have been processed. This routine should perform functions that must be done once per FORMAT run. For example, this routine could 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, there is an error. In this case, FORMAT will print "Format failure" and then quit. This feature can be used to detect the setting of conflicting switches, such as specifying both single and double density. WRITING THE FORMAT MODULE Page 7-2 2. DISKFORMAT Formats the disk according to the options indicated by the switches. The value of FATID must be defined when it returns (INIT may have already defined 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, it sets the carry flag and returns to FORMAT. FORMAT will report a "Format failure" and prompt for another disk. (If you only require a clear directory and FAT, DISKFORMAT will only have to set the appropriate FATID, if this has not been done by INIT.) 3. BADSECTOR Reports the sector number of any bad sectors that were 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 AX is zero or the carry flag is set. The carry flag is used just as it is 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 register BX, the number of consecutive bad sectors in register AX, and carry clear. FORMAT will then process the bad sectors and call BADSECTOR again. When BADSECTOR returns AX = 0, there are no more bad sectors; FORMAT clears the directory and proceeds to WRTFAT and DONE. BX does not need to contain meaningful information for this last return. FORMAT processes bad sectors by determining their corresponding allocation unit and marking that unit with an FF7H in the File Allocation Table. CHKDSK reads the FF7 mark as a flag for bad sectors and reports the number of bytes marked in this way. WRITING THE FORMAT MODULE Page 7-3 NOTE Formatting of the disk can be done in BADSECTOR instead of DISKFORMAT on a "report as you go" basis. Formatting proceeds until a group of bad sectors is encountered; BADSECTOR then reports them by returning with AX and BX set. FORMAT calls BADSECTOR again, and formatting can continue. 4. 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 or a direct BIOS call to perform the write. This depends on whether or not 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 FAT ID byte on the disk yet (in this case WRTFAT's primary job is to get the FAT ID byte out on the disk to solve the problem). 5. DONE This routine is called after formatting is complete, the disk directory has been initialized, and the system has been transferred. It is called once for each disk to be formatted. This provides the opportunity to do any finishing operations, if needed. Putting extra files on the disk by default, or with a switch, can be accomplished with DONE. Again, as in BADSECTOR and DISKFORMAT, a carry flag set on return means an error has occurred: The message "Format failure" is printed, and FORMAT prompts for another disk. WRITING THE FORMAT MODULE Page 7-4 Figure 15 illustrates the control flow of the five NEAR routines by the Microsoft module: | +---------+ | INIT | +---------+ | |<------------------------------+ +------------+ | | DISKFORMAT | | +------------+ | |<-------+ | +-----------+ |-This loop is done |-This loop is | BADSECTOR | | for each group of | done once for each +-----------+ | bad sectors | disk to be formatted. |----->--+ | If HARDFLAG variable | | is set, then the loop +----------+ | is only performed | | | once. | WRTFAT | | +----------+ | | | +------+ | | DONE | | +------+ | +---->--------------------------+ Figure 15. NEAR Routine Control Flow The INIT, DISKFORMAT, and BADSECTOR routines may use any MS-DOS system calls, except calls that cause disk access on the disk being formatted. DONE may use any calls, since the new disk has been formatted by the time it is called. WRITING THE FORMAT MODULE Page 7-5 The following six data items must be supplied to the FORMAT program. They must be declared PUBLIC in a module provided by the OEM. 1. SWITCHLIST A string of bytes. The first byte is count n, _ followed by n characters, which 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 predefined meanings. When the /O switch is specified, FORMAT produces a disk that is compatible with IBM Personal Computer DOS version 1.x. Without the /O switch, FORMAT places a 0 byte in the first byte of each directory entry instead of the 0E5H free entry designator. This increases directory search performance due to an optimization in MS-DOS. Since IBM PC DOS 1.x versions do not have this optimization, disks made using the /O switch do not work on that version. (To IBM 1.x versions, 0 byte entries are allocated instead of free.) The /V switch causes FORMAT to prompt the user for a volume label after is formatted. As with the /S switch, the letter is not important, but its position in the list is. The /S switch transfers the system files IO.SYS, MSDOS.SYS, and COMMAND.COM to the formatted disk. This makes a "system" disk. The switch can be a letter other than "S", but the last switch in the list is assumed to mean "transfer system." NOTE IBM Personal Computer DOS version 2.00 and MS-DOS version 1.25 can use these disks, since they have the same optimization. The /O switch causes FORMAT to rebuild the directory with a 0E5H byte at the start of each entry so that the disk can be used with 1.x versions of IBM PC DOS, as well as MS-DOS 1.25 and 2.00 and IBM PC DOS 2.00. This switch should be specified only when needed because it takes time for FORMAT to perform the conversion, and it noticeably decreases 1.25 and 2.00 performance on WRITING THE FORMAT MODULE Page 7-6 disks with few directory entries. Up to 16 switches are permitted. A /C switch is specified for "clear" and causes 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. 2. HARDFLAG BYTE location specifying whether the OEM routine is formatting a fixed disk or a drive with removable media. A zero indicates 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. 3. FATID BYTE location containing the value used in the first byte of the FAT. Must be in the range F8H to FFH. 4. STARTSECTOR WORD location containing the sector number of the first sector of the data area. 5. 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 routine. 6K is sufficient to store any FAT. This area must not overlap the FREESPACE area. 6. FREESPACE WORD location containing 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-7 The following data is declared PUBLIC in Microsoft's FORMAT module: SWITCHMAP A word with a bit vector indicating what switches have been included in the command line. The correspondence of the bits to the switches is determined by SWITCHLIST. The right (highest-addressed) switch in SWITCHLIST (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, nor /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 twice: 1. After INIT has been called to determine if it is necessary to load the system. 2. After the last BADSECTOR call to determine if the system will be written, E5 directory conversion will be done, and/or a volume label will be asked for. INIT may force these bits set or reset if desired (for example, some drives may never be used as the system disk drive such as hard disks). After INIT, if something happens that indicates that the system should not be transferred, the "S" bit may be turned off but not on (since the system was never read). After INIT, a second copy of SWITCHMAP is made internally. This copy is used to restore SWITCHMAP for each disk to be formatted. FORMAT turns off the system bit if bad sectors are reported in the system area. DISKFORMAT and BADSECTOR are also allowed to change the map. 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-8 DRIVE A byte containing the drive specified in the command line. 0=A, 1=B, etc. Once the OEM-supplied module has been prepared, it must be linked with Microsoft's FORMAT.OBJ module and the FORMES.OBJ module. If the OEM-supplied module is named OEMFOR.OBJ, then the following Linker command links the three modules: LINK FORMAT FORMES OEMFOR; This command produces a file named FORMAT.EXE. FORMAT has been designed to run under MS-DOS as a simple binary with the command: EXE2BIN FORMAT.EXE FORMAT.COM This produces the file FORMAT.COM. WRITING THE FORMAT MODULE Page 7-9 W7.1 SKELETAL FORMAT MODULE The following is a sample OEM module for FORMAT. ;***************************************** ; ; Sample OEM Module ; ;***************************************** CODE SEGMENT BYTE PUBLIC 'CODE' ; This segment must be ; named CODE, it must be ; PUBLIC, and it's ; classname must be 'CODE' ASSUME CS:CODE,DS:CODE,ES:NOTHING ; IF an OEM uses ES, it is up to the OEM to establish the value of ES ; Must declare data and routines PUBLIC PUBLIC FATID,STARTSECTOR,SWITCHLIST,FREESPACE PUBLIC INIT,DISKFORMAT,BADSECTOR,DONE,WRTFAT PUBLIC FATSPACE,HARDFLAG ; This data defined in Microsoft-supplied module EXTRN SWITCHMAP:WORD,DRIVE:BYTE INIT: ; Read the boot sector into memory CALL READBOOT ... ; Set FATID to double sided if "D" switch specified TEST SWITCHMAP,10H JNZ SETDBLSIDE ... RET DISKFORMAT: ... ; Use the bit map in SWITCHMAP to determine ; what switches are set TEST SWITCHMAP,8 ; Is there a "/C"? JNZ CLEAR ; Yes -- clear operation ; requested jump around the ; format code < format the disk > WRITING THE FORMAT MODULE Page 7-10 CLEAR: ... ; Transfer the boot from memory to the new disk CALL TRANSBOOT ... RET ; Error return - set carry ERRET: STC RET BADSECTOR: ... RET WRTFAT: ... WRTFATLOOP: < Set up call to write out a FAT to disk> ... MOV BX,[FATSPACE] < Write out one FAT to disk> JC ERRET ... < Decrement fat counter > JNZ WRTFATLOOP CLC ;Good return RET DONE: ... RET ; Default Single-sided FATID DB 0FEH HARDFLAG DB 0 STARTSECTOR DW 9 SWITCHLIST DB 5,"DCOVS" ; "OVS" must be the last ; switches in the list FATSPACE DW FATBUF FREESPACE DW ENDBOOT WRITING THE FORMAT MODULE Page 7-11 BOOT DB BOOTSIZE DUP(?) ; Buffer for the ; boot sector FATBUF DB 6 * 1024 DUP(?) ; FAT buffer ENDBOOT LABEL BYTE CODE ENDS END W CONTENTS WCHAPTER 8 TROUBLE SHOOTING W CHAPTER 8 W 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 doing an EXEC of 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 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 correct BPB being returned and that COMMAND.COM is on disk. Install debugging code in device driver to make sure requests to 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. It should be present. If it is not found, some of your BIOS 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. 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 beginning of device list. Recommendation: Check value passed to SYSINIT to make sure that it is the correct value for the beginning of the list. Typical Cause 4: Driver attributes are wrong. MS-DOS will not look for the end of list mark if the attributes are wrong. Recommendation: Check device driver attribute words. 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 device INIT routine. This points to the first byte of free memory after the device code and data. Recommendation: Set break address. Problem: Everything works OK until I define a new drive in my BIOS. Then the system won't come up. TROUBLE SHOOTING Page 8-4 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. 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: 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." TROUBLE SHOOTING Page 8-5 Typical Cause: The INIT call is only defining 1 disk drive and support for swapping has not been implemented in your BIOS. Recommendation: Support for disk swapping is implemented at the BIOS level rather than at the MS-DOS level. The driver reports 2 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 BIOS 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. Recommendation: Fix the block device driver INIT call. Problem: Every time I try to do an ALLOCate memory call or an EXEC call, I get a return code of 8, "Not enough memory." Typical Cause: There is no free memory. Recommendation: Do a Modify memory call to shrink the size of the currently allocated block, freeing some memory. See the sections on arenas and memory management in the Glossary. TROUBLE SHOOTING Page 8-6 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 nondestructive console read routine is not implemented properly. Recommendation: Check the nondestructive 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 input queue and put the CONTROL-S/CONTROL-Q at the beginning of the type-ahead buffer. TROUBLE SHOOTING Page 8-7 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. W APPENDIX A W FILES ON MS-DOS RELEASE DISKS The following is an index of the files on the MS-DOS 5-1/4" release disks. This list is subject to change. Please check the README file for changes. Disk Number 1 IO.ASM.................Sample Resident Device Driver Source Guide..................Adaptation Guide (Documentation on disk) Disk Number 2 GENFOR.ASM.............Sample OEM Format Module FORMAT.DOC.............Description of Format Routine DOSPATCH...............Instructions for Patching Serial Number SPECIAL................Undocumented features for OEM use only README.................Addenda and Errata Disk Number 3 MSDOS.OBJ..............MS-DOS Object Module MSCODE.OBJ.............MS-DOS Object Module DOSMES.ASM.............Source to International Tables for MS-DOS MISC.OBJ...............MS-DOS Object Module GETSET.OBJ.............MS-DOS Object Module DIRCALL.OBJ............MS-DOS Object Module ALLOC.OBJ..............MS-DOS Object Module DEV.OBJ................MS-DOS Object Module DIR.OBJ................MS-DOS Object Module DISK.OBJ...............MS-DOS Object Module FAT.OBJ................MS-DOS Object Module ROM.OBJ................MS-DOS Object Module STDBUF.OBJ.............MS-DOS Object Module STDCALL.OBJ............MS-Dos Object Module STDCTRLC.OBJ...........MS-DOS Object Module STDFCB.OBJ.............MS-DOS Object Module STDPRO.OBJ.............MS-DOS Object Module FILES ON MS-DOS RELEASE DISKS Page A-2 STDIO.OBJ..............MS-DOS Object Module TIME.OBJ...............MS-DOS Object Module XENIX.OBJ..............MS-DOS Object Module XENIX2.OBJ.............MS-DOS Object Module DOSLINK................Link Script for linking MS-DOS DOSMAC.ASM.............Include File for Print Spooler DOSSYM. ASM............Include File for Print Spooler STDSW.ASM..............Include File for DOSMES.ASM DOSBUILD.BAT...........Batch file for building MS-DOS SYSINIT.OBJ............System Initialization File Link to IO.ASM (BIOS) SYSIMES.OBJ............System Initialization Message File FORMAT.OBJ.............Hardware Independent Format Module FORMES.OBJ.............Format Messages EXE2BIN.EXE............Utility to convert EXE files to Binary Files SORT.OBJ...............Sort Object Module SORTMES.ASM............Sort Message Source File with Collation Table SORTBILD.BAT...........Sort Build Batch File EXEFIX.EXE.............Utility used to build SORT Disk Number 4 COMMAND.COM............MS-DOS Command Interpreter EDLIN.COM..............MS-DOS Text Editor CHKDSK.COM.............Disk Check, Repair Utility FIND.EXE...............Filter for finding text strings FC.EXE.................File Compare Utility SYS.COM................System Transfer Utility DISKCOPY.COM...........Disk Copy Utility RECOVER.COM............Disk Directory Recovery Utility MORE.COM...............Screen Pagination Filter LINK.EXE...............MS-DOS Object Module Linker DEBUG.COM..............Debug Utility PRINT.ASM..............Source to Print Spooler Macro Assembler Evaluation Copy provided for BIOS and FORMAT Module Development MASM.EXE...............Macro Assembler LIB.EXE................MS-DOS Library Utility (MS-LIB) CREF.EXE...............Macro Assembler Cross Reference Utility (MS-CREF) Your MS-DOS release to your customers should consist of the following files: MSDOS.SYS Operating System Invisible File IO.SYS Resident Drivers (BIOS) Invisible File FILES ON MS-DOS RELEASE DISKS Page A-3 Commands and Utilities: COMMAND.COM FORMAT.COM LINK.EXE DEBUG.COM EDLIN.COM FIND.EXE EDLIN.COM EXE2BIN.EXE SORT.EXE MORE.COM CHKDSK.COM PRINT.COM DISKCOPY.COM FC.EXE RECOVER.COM SYS.COM W APPENDIX B W CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION WB.1 CUSTOMIZING MS-DOS Most manufacturers find it necessary to customize MS-DOS (as distinct from a BIOS) 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. 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 CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page B-2 two-digit numbers are employed. Message files are available for several foreign languages. 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 sorts 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. WB.2 KANJI CONSIDERATIONS Microsoft supplies a version of MS-DOS for the Japanese market to accommodate the Kanji characters of the Japanese language. All Kanji 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 BIOS keyboard and screen drivers. MS-DOS ensures that 16-bit Kanji 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 B-3 WB.3 INPUT On input, it is the responsibility of the BIOS to pass Kanji characters to MS-DOS. The BIOS must handle all Kata-kana-to-Kanji conversion or any other method used to enter Kanji. The BIOS always places both bytes of the Kanji character into its buffer at once; however, they are passed to MS-DOS as if they are two separate single-byte characters. Therefore, even noninterrupt-driven keyboards should always have the second byte of the Kanji character waiting by the time the first byte is accepted by MS-DOS. The BIOS should never pass an invalid Kanji sequence to MS-DOS. WB.4 OUTPUT On output, the BIOS must identify the first byte of a Kanji character, set a flag, and wait for the second byte. Once the entire Kanji character has been received, the BIOS must index into the font table. The font table may be in memory, on disk, or in a combination memory-disk caching scheme. The BIOS may call MS-DOS to read font files stored on the disk in MS-DOS format. These files should be opened in the BIOS when control is passed back to RE_INIT, after MS-DOS has been initialized. The BIOS performs error recovery in case the font files are on a disk that has been removed. Door-open 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 the BIOS to facilitate recovery from this error. A solution to the problem of missing font files is to display all Kanji characters for which no font is in memory as double-width reverse video blanks. The BIOS also must perform error handling in the data stream where an invalid Kanji 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 Kanji data. 3. The manipulation of fixed length fields may have split a Kanji character between its two bytes. If any of these occur, the recommended procedure is to CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page B-4 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 Kanji 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"). The BIOS should ensure that a Kanji character is never split across the last column of one physical line and the first column of the next line. The entire Kanji character must start on the next line. The BIOS 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 Kanji character be displayed. The BIOS: 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 Kanji character. If a third backspace is issued, the BIOS 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 Kanji character to be block transferred without blanking it in scrolling regions. This rule also applies to the region being moved and the area into which it is being moved. W APPENDIX C W USE OF THE MS-DOS EXEC CALL ;The following program is an example of the use of ;the MS-DOS EXEC call. The program, after being assembled ;linked and run through EXE2BIN to create a .COM file can be used ;to EXEC a new copy of the COMMAND interpreter which will ;then perform any built in or external command. ; ;To invoke the program, type: ; ; FOO /C ; ;for example: ; ; FOO /C DIR ; ;The /C switch tells COMMAND.COM to perform the command and ;return immediately. ; CODE SEGMENT ASSUME CS:CODE, DS:CODE, ES:CODE, SS:CODE org 100h start: mov bx,20h ;reserve 20 paragraphs for this program mov ah,4ah ;free some memory int 21h mov ax,cs mov mseg1, ax ;set up parameter block for exec mov mseg2, ax mov mseg3, ax mov dx, offset cs:command mov bx, offset cs:block mov ah, 4bh mov al, 00 ;execute a load and go mov cx, es:[02ch] ;pointer to environment mov block, cx mov [stakptr], sp int 21h push cs pop ss mov sp, [stakptr] USE OF THE MS-DOS EXEC CALL Page C-2 mov ax, cs mov ds, ax mov dx, offset cs:message mov ah, 09h int 21h mov ah,4ch int 21h message db "back from exec ",13, 10, "$" stakptr dw ? command db "A:\COMMAND.COM",0 block dw ? dw 80h mseg1 dw ? dw 5ch mseg2 dw ? dw 6ch mseg3 dw ? code ends end start USE OF THE MS-DOS EXEC CALL Page C-3 GLOSSARY OF MS-DOS TERMINOLOGY ALLOCATE, MODIFY, and DEALLOCATE Memory Calls The allocate, modify and deallocate memory calls (as described in the MS-DOS 2.0 Programmer's ______ ___ ____________ Reference Manual) manipulate arena blocks used for _________ ______ software memory management. The arena blocks form a linked list throughout memory. The EXE file has a 512-byte header which contains initial segment offsets and a table of relocation items. In addition, there two fields which specify how much memory the file requires. Currently, the "maxalloc" field is set to FFFF by the Linker causing MS-DOS to attempt to allocate FFFF paragraphs of memory to the program. This means that all of the largest free block of memory will be allocated to an EXE file. Since there is usually only 1 free block, no available memory will be available for an ALLOCATE or an EXEC call unless it is first preceded by a MODIFY memory call which shrinks the size of the program's currently allocated block freeing some memory. EXE files which are run through EXEFIX to set the size of the maxalloc field to the minalloc field will not request all of memory. This procedure can also be carried out easily with the debugger. (See the section on the EXE header in the MS-DOS 2.0 ______ ___ Programmer's Reference Manual.) ____________ _________ ______ For .COM files, there is no table of information which MS-DOS can read to find out how much memory the program will use. MS-DOS always allocates as much memory as it can to .COM files. To do an ALLOCATE or EXEC from a .COM file you will always have to use the MODIFY memory call to free up some memory first. 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 USE OF THE MS-DOS EXEC CALL Page C-4 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 which 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. Currently, MS-DOS limits the maximum number of clusters for a disk to 4084. Block device drivers perform I/O in sectors, not clusters. Cooked/Raw Mode Character devices have two modes which have significance when performing I/O via the reads and writes compatible with the XENIX operating system (Functions 3FH and 40H. These modes are "raw" and "cooked" mode. A device driver can be set to raw mode via 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 is 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. USE OF THE MS-DOS EXEC CALL Page C-5 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 is complete. 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 to be used by COMMAND.COM, are stored in the environment. Application programs will be able to use the environment to find overlays or special files which may not be located in the current directory. This technique is used by COMMAND 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. FAT ID Byte The FAT ID byte is the first byte of the File Allocation table which starts at the sector immediately after the reserved sectors of the disk. The FAT ID byte was used by OEMs in MS-DOS 1.x for identification of disk media. This byte is constrained to be between F8H and FFH. To read MS-DOS 1.x disks, one must read this byte, determine which of the four predefined FAT ID bytes is present and return a pointer to the appropriate USE OF THE MS-DOS EXEC CALL Page C-6 BPB. This method of determining media is less general and less desirable than the BPB table method (see MEDIA ID Byte). File Handle In MS-DOS 2.0, 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 ..... AUX 4 ..... PRN As new files are opened via XENIX-compatible opens, 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. USE OF THE MS-DOS EXEC CALL Page C-7 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 FAT ID 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. This permits MS-DOS to skip making a new Drive Parameter Block (DPB) unless the MEDIA ID byte actually changes. 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 FAT ID byte method and is the preferred method. The significance of the media byte and FAT ID byte depends on whether you have decided to make your block device driver IBM format-compatible. You must indicate NON IBM FORMAT 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 IBM FORMAT bit set, you can support various media, including IBM format media. If the device driver is IBM format compatible, use FAT ID bytes to determine the media in the drive. The correspondence between FAT ID bytes and various media is defined in the MS-DOS 2.0 Programmer's ______ ___ ____________ Reference Manual. _________ ______ If your system is NON 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 jump and there is a BIOS Parameter Block table in the boot sector. USE OF THE MS-DOS EXEC CALL Page C-8 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 presume 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 FAT ID bytes it is, and return a pointer to the appropriate BPB. Refer to the MS-DOS 2.0 Programmer's Reference ______ ___ ____________ _________ Manual for a list of valid FAT ID bytes. Any ______ other media should be defined in the boot sector and should use a FAT ID 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). Page Index-1 W INDEX 8086 Assembler code . . . . . 1-2 Allocation unit . . . . . . . C-3 Arena . . . . . . . . . . . . C-3 ASCIZ . . . . . . . . . . . . C-4 Assembler code, 8086 . . . . . 1-2 AUX device . . . . . . . . . . 5-8 Bad or missing command interpreter 8-1 BADSECTOR . . . . . . . . . . 7-2 Base address . . . . . . . . . 3-2 Basic Input Output System (BIOS) 1-5 BIN format file . . . . . . . 5-6 Binary core image file . . . . 3-2 Binary Date Time Format (CLOCK) 5-8 BIOS Parameter Block (BPB) . . 5-13, 5-18 Block devices definition . . . . . . . . . 5-3 drive designations . . . . . 5-3 units . . . . . . . . . . . 5-3 Boot sector format . . . . . . . . . . . 5-19 responsibilities . . . . . . 4-4 BOOT.ASM . . . . . . . . . . . 3-2 BOOT.BIN . . . . . . . . . . . 3-3 Bootstrap loader . . . . . . . 1-5, 3-2 Break Address . . . . . . . . 5-13 BUFFERS . . . . . . . . . . . 6-2 BUILD BPB . . . . . . . . . . 5-17 Busy bit . . . . . . . . . . . 5-21 Case conversion routine . . . B-1 Character devices . . . . . . 5-3 Character sets foreign . . . . . . . . . . B-1 IBM PC . . . . . . . . . . . B-1 CLOCK device . . . . . . . . . 5-8 Cluster . . . . . . . . . . . C-4 Command code 0 (INIT) . . . . 5-12 Command code 1 (MEDIA CHECK) . 5-14 Command code 2 (BUILD BPB) . . 5-17 Command code 3 (READ OR WRITE) 5-20 Command code 4 (READ OR WRITE) 5-20 Command code 5 (NON DESTRUCTIVE READ NO WAIT) 5-21 Command code 6 (STATUS calls) 5-22 Command code 7 (FLUSH call) . 5-22 Command code 8 (READ OR WRITE) 5-20 Command code 9 (WRITE WITH VERIFY) 5-21 Page Index-2 Command code 10 (STATUS calls) 5-22 Command code 11 (FLUSH call) . 5-22 Command code 12 (READ OR WRITE) 5-20 COMMAND.COM . . . . . . . . . 1-5, 6-2, 6-5 CON device . . . . . . . . . . 5-8 CONFIG.SYS file . . . . . . . 5-1, 5-7, 6-2, 6-4, B-1 Consultants, MS-DOS . . . . . 1-3 Cooked mode . . . . . . . . . C-4 CURRENT_DOS_LOCATION . . . . . 6-1 Customizing FORMAT . . . . . . B-1 Customizing MS-DOS . . . . . . B-1 DATE command . . . . . . . . . 5-8 DEBUG . . . . . . . . . . . . 2-2 DEFAULT_DRIVE . . . . . . . . 6-2 Development machine . . . . . 1-2 Device driver functions . . . 5-11 Device driver header, format . 5-4 Device driver interrupt routine 5-9 Device driver strategy routine 5-9 Device drivers installable . . . . . . . . 5-1 installation . . . . . . . . 5-7 non-resident . . . . . . . . 5-1 preserving registers . . . . 5-24 resident . . . . . . . . . . 5-1 DEVICE_LIST . . . . . . . . . 6-1 Devices block . . . . . . . . . . . 5-3 character . . . . . . . . . 5-3 Disk files . . . . . . . . . . A-1 Disk formats, MS-DOS . . . . . 1-2 DISKFORMAT . . . . . . . . . . 7-2 Dispatch table . . . . . . . . 5-23 DONE . . . . . . . . . . . . . 7-3 Done bit . . . . . . . . . . . 5-21, 5-23 to 5-24 DOS.SYS . . . . . . . . . . . 1-5 DOSMES.ASM . . . . . . . . . . B-1 DRIVE . . . . . . . . . . . . 7-8 Drive designations . . . . . . 5-3 Drive Parameter Block (DPB) . 5-13 EDLIN . . . . . . . . . . . . 2-1 Environment . . . . . . . . . C-5 Error bit . . . . . . . . . . 5-24 Error recovery (Kanji) . . . . B-3 EXE device drivers . . . . . . 5-6 EXE format file . . . . . . . 5-6 EXE loader . . . . . . . . . . 5-6 EXE2BIN . . . . . . . . . . . 2-2, 5-7 FAR memory references . . . . 5-7 FAT ID byte . . . . . . . . . 5-17 to 5-18, C-5 FATID . . . . . . . . . . . . 7-6 FATSPACE . . . . . . . . . . . 7-6 File Allocation Table . . . . 4-1 size . . . . . . . . . . . . 4-2 Page Index-3 structure . . . . . . . . . 4-2 File handle . . . . . . . . . C-6 FILES . . . . . . . . . . . . 6-2 Files on disk . . . . . . . . A-1 FINAL_DOS_LOCATION . . . . . . 6-1 FLUSH calls . . . . . . . . . 5-22 Font table . . . . . . . . . . B-3 Foreign character sets . . . . B-1 FORMAT command definition . . . . . . . . . 7-1 syntax . . . . . . . . . . . 7-1 Format failure . . . . . . . . 7-2 FORMAT module, skeletal . . . 7-9 FORMAT program . . . . . . . . 2-2 FORMAT, customizing . . . . . B-1 FREESPACE . . . . . . . . . . 7-6 Function 38H . . . . . . . . . B-1 GENFOR.ASM . . . . . . . . . . 3-4 GET BPB device call . . . . . 5-5 Glossary . . . . . . . . . . . C-3 HARDFLAG . . . . . . . . . . . 7-4, 7-6 Hardware initialization . . . 6-1 Hardware requirements . . . . 1-3 IBM PC character set . . . . . B-1 Implementation . . . . . . . . 1-5 INIT . . . . . . . . . . . . . 5-12, 7-1 Initialization, MS-DOS . . . . 6-1 Installation kit . . . . . . . 1-1 Installing character devices . 5-7 Installing MS-DOS, steps . . . 3-1 INTEL format . . . . . . . . . 1-2 Internal commands . . . . . . 6-5 Internal stack . . . . . . . . 5-24 Internationalization . . . . . B-1 Interrupt 29H . . . . . . . . 5-6 Interrupt entry point . . . . 5-1, 5-23 Interrupt routine . . . . . . 5-9 Invalid drive specification . 8-4 IO.ASM . . . . . . . . . . . . 6-1 IO.OBJ . . . . . . . . . . . . 6-1 IO.SYS . . . . . . . . . . . . 4-5, 5-7, 6-4 IOCTL bit . . . . . . . . . . 5-5 IOCTL system call . . . . . . 5-5 Kanji input . . . . . . . . . . . B-3 output . . . . . . . . . . . B-3 support . . . . . . . . . . B-2 Linker . . . . . . . . . . . . 2-1 Macro Assembler . . . . . . . 2-1 Page Index-4 Mainframe computer . . . . . . 1-2 MASM.EXE . . . . . . . . . . . 3-1 MEDIA CHECK . . . . . . . . . 5-14 Media description table . . . 4-3 Media descriptor byte . . . . 5-17 to 5-18, C-5 Media, determining . . . . . . 5-19 Memory, unprotected . . . . . 6-5 MEMORY_SIZE . . . . . . . . . 6-1 Message files . . . . . . . . B-2 MS-DOS initialization . . . . 6-1 MS-DOS, customizing . . . . . B-1 Multitasking . . . . . . . . . 5-1 NON DESTRUCTIVE READ NO WAIT . 5-21 NON IBM FORMAT bit . . . . . . 5-5, 5-17 NUL device . . . . . . . . . . 5-5 Paragraph . . . . . . . . . . C-8 PRN device . . . . . . . . . . 5-8 Program/data area . . . . . . 4-1 Raw mode . . . . . . . . . . . 5-6, C-4 RE_INIT . . . . . . . . . . . 6-3 READ OR WRITE . . . . . . . . 5-20 Request packet . . . . . . . . 5-2, 5-9 Request packet header . . . . 5-10 Reserved area . . . . . . . . 4-1 Resident device drivers . . . 5-1 ROM . . . . . . . . . . . . . 1-5 Root directory . . . . . . . . 4-1 Sample OEM FORMAT module . . . 7-9 Scrolling regions . . . . . . B-4 Sector count . . . . . . . . . 5-23 SORTMES.ASM file . . . . . . . B-2 Source code, MS-DOS . . . . . 1-2 Special bit . . . . . . . . . 5-5 to 5-6 Start sector . . . . . . . . . 5-23 STARTSECTOR . . . . . . . . . 7-6 Static request header . . . . 5-2 STATUS calls . . . . . . . . . 5-22 Status word . . . . . . . . . 5-10 Strategy entry point . . . . . 5-1, 5-23 Strategy routine . . . . . . . 5-9 STRIN.ASM . . . . . . . . . . B-1 SWITCHLIST . . . . . . . . . . 7-5 SWITCHMAP . . . . . . . . . . 7-7 SYS command . . . . . . . . . 4-4 SYSIMES.OBJ . . . . . . . . . 5-7 SYSINIT . . . . . . . . . . . 1-5, 5-7, 6-1, 6-3 System ROM . . . . . . . . . . 1-5 Terminology . . . . . . . . . C-3 Time and date formats (foreign) B-1 TIME command . . . . . . . . . 5-8 Page Index-5 Transfer address . . . . . . . 5-23 Transient part (COMMAND.COM) . 6-5 Transient Program Area (TPA) . 6-5 Trouble shooting . . . . . . . 8-1 Unprotected memory . . . . . . 6-5 WRTFAT . . . . . . . . . . . . 7-3