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

7051 lines
242 KiB

4 years ago
  1. MICROSOFT(R)
  2. MS(tm)-DOS
  3. Adaptation Guide
  4. Last Updated on JULY 24, 1987
  5. in conjunction with the MS-DOS 3.30 FINAL RELEASE
  6. Microsoft Corporation
  7. Information in this document is subject to change without
  8. notice and does not represent a commitment on the part of
  9. Microsoft Corporation. The software described in this
  10. document is furnished under a license agreement or
  11. non-disclosure agreement. The software may be used or
  12. copied only in accordance with the terms of that agreement.
  13. It is against the law to copy the MS-DOS Disk Operating
  14. System on magnetic tape, disk, or any other medium for any
  15. purpose other than the purchaser's personal use.
  16. Copyright (C) Microsoft Corporation, 1982, 1983, 1984, 1985, 1986
  17. INTEL is a registered trademark of Intel Corporation.
  18. IBM is a registered trademark of International Business
  19. Machines Corporation.
  20. Microsoft, the Microsoft logo, and MS-DOS are registered
  21. trademarks of Microsoft Corporation.
  22. XENIX is a trademark of Microsoft Corporation.
  23. TABLE OF CONTENTS
  24. CHAPTER 1 MS-DOS INSTALLATION KIT
  25. 1.1 README.DOC File 1-1
  26. CHAPTER 2 MS-DOS DEVELOPMENT TOOLS
  27. CHAPTER 3 INSTALLING MS-DOS
  28. CHAPTER 4 DISK STRUCTURE AND BOOTSTRAP LOADING
  29. CHAPTER 5 RESIDENT DEVICE DRIVERS
  30. CHAPTER 6 SYSINIT AND MS-DOS INITIALIZATION
  31. CHAPTER 7 WRITING THE FORMAT MODULE
  32. CHAPTER 8 TROUBLE SHOOTING
  33. APPENDIX A CUSTOMIZATION OF MS-DOS AND
  34. INTERNATIONALIZATION
  35. A.1 Customizing MS-DOS A-1
  36. A.2 ECS Considerations -- MS-DOS 2.25 A-2
  37. A.3 Input A-3
  38. A.4 Output A-3
  39. APPENDIX B HOW TO UPGRADE A 2.X BIOS TO 3.X
  40. APPENDIX C HOW TO UPGRADE A 3.1 BIOS TO 3.2
  41. APPENDIX D DEVICE DRIVERS - CHAPTER 2 MS-DOS 3.20 PROGRAMMER'S REFERENCE
  42. APPENDIX E MS-DOS 2.25 DEVICE DRIVER EXTENSIONS
  43. APPENDIX F MS-DOS 2.25 APPLICATION LEVEL INTERFACE EXTENSION
  44. APPENDIX G SPECIAL DOC
  45. APPENDIX H PROGRAMMING RECOMMENDATIONS - CHAPTER 7 MS-DOS 3.20
  46. PROGRAMMER'S REFERENCE
  47. GLOSSARY OF MS-DOS TERMS
  48. CONTENTS
  49. CHAPTER 1 MS-DOS INSTALLATION KIT
  50. 1.1 README.DOC File 1-1
  51. 1.2 Contents 1-1
  52. 1.3 Common Questions and Answers 1-2
  53. 1.4 MS-DOS Hardware Requirements 1-3
  54. 1.5 MS-DOS Overview 1-5
  55. CHAPTER 1
  56. MS-DOS INSTALLATION KIT
  57. 1.1 README.DOC FILE
  58. Check the README.DOC file on DISTRIBUTION DISKETTES for
  59. version specific information and any addenda to this document.
  60. 1.2 CONTENTS
  61. The MS-DOS 3.21 Installation Kit is provided on 5-1/4" high capacity
  62. 1.2 Megabyte disks. It consists of the MS-DOS DISTRIBUTION
  63. DISKETTES that include files formerly found
  64. version.
  65. Included with the kit is a Sample MS-DOS 2.XX/3.XX Implementation.
  66. The sample implementation runs on all members of the IBM PC family and
  67. is intended to be functionally equivalent to the IBM implementation.
  68. The purpose of this sample is to assist Microsoft OEMs with their
  69. MS-DOS installations, but can also be used directly as part of the OEMs
  70. product. IO.SYS, the BIOS, has been intended to be self documenting and
  71. Microsoft will support services for it as it run on IBM PCs.
  72. Included in the kit is a copy of the current Microsoft(R) Macro Assembler
  73. featuring SYMDEB, the symbolic debugger. The full MASM retail package is
  74. no longer provided.
  75. The installation kit also includes four manuals:
  76. MS-DOS User's Guide. This is an introduction to ______ ______ _____
  77. MS-DOS, including how to start the system and use
  78. applications.
  79. MS-DOS User's Reference Manual. This manual ______ ______ _________ ______
  80. explains hierarchical directories, the MS-DOS file
  81. structure, and MS-DOS commands and utilities. This
  82. manual is new in 3.XX.
  83. MS-DOS Programmer's Reference Manual. This manual ______ ____________ _________ ______
  84. includes a summary of all published system calls
  85. and MS-DOS structures.
  86. MS-DOS Adaptation Guide. This manual describes how ______ __________ _____
  87. to implement MS-DOS on OEM machines. This guide is
  88. available on diskette only and is the text you are
  89. now reading.
  90. MS-DOS INSTALLATION KIT Page 1-2
  91. 1.3 COMMON QUESTIONS AND ANSWERS
  92. Q. What kind of development machine do you recommend?
  93. A. Microsoft recommends that an MS-DOS machine be used as a
  94. development tool in preparing software for your target
  95. machine. Using an MS-DOS machine avoids problems with
  96. incompatible assemblers and object module formats. You
  97. may want to read standard MS-DOS disk formats. Using
  98. the development machine to build a system disk for the
  99. target machine simplifies the implementation process.
  100. Q. Are sources available?
  101. A. Sources for MS-DOS are not available (except for the sample
  102. BIOS implementation).
  103. Q. What language is MS-DOS written in?
  104. A. The source code for MS-DOS and most utilities is written
  105. in 8086 assembler code. It is compatible with the macro
  106. facility found in Microsoft Macro Assembler for the
  107. MS-DOS operating system. The format of the object
  108. modules provided is a subset of the INTEL(R) format, and
  109. may not be compatible with non-Microsoft linkers.
  110. Q. What does an MS-DOS implementor need to know?
  111. A. To install MS-DOS, you will need to be familiar with
  112. systems programming in 8086 assembler language. This
  113. means you should have experience in writing device
  114. drivers for disk drives, keyboards, printers, and other
  115. peripherals.
  116. Q. How long does it take to install MS-DOS?
  117. A. This depends on whether the low-level I/O routines are
  118. already written. The record time for getting MS-DOS up
  119. and running on a new machine is one weekend. In this
  120. case, all of the low-level routines were in ROM.
  121. Typically, a complete customer-ready MS-DOS
  122. implementation takes two or more months.
  123. MS-DOS INSTALLATION KIT Page 1-3
  124. Q. Are there any consultants who do MS-DOS implementations?
  125. A. Microsoft can supply a list of consultants who have done
  126. MS-DOS implementations. Microsoft cannot make any
  127. recommendations regarding the competence of these
  128. consultants.
  129. Q. Do you recommend that we have an In Circuit Emulator
  130. (ICE) for our machine?
  131. A. Yes. Since there are no MS-DOS debugging tools that can
  132. be used to debug the boot sequence, an ICE is very
  133. helpful.
  134. 1.4 MS-DOS HARDWARE REQUIREMENTS
  135. To be compatible with the MS-DOS operating system, a machine
  136. must conform to certain hardware characteristics. These
  137. characteristics are as follows:
  138. o The processor must be INTEL 8086 compatible.
  139. o The Interrupt vector locations 20H through 3FH must
  140. be reserved for MS-DOS.
  141. o Four character device drivers and one block device
  142. driver are required. They must recognize the
  143. MS-DOS device driver call format.
  144. o An ANSI terminal driver must be implemented.
  145. (MS-DOS sends an ANSI escape sequence to clear the
  146. console.)
  147. o A logical disk, as described in this document, must
  148. be available to MS-DOS. A disk format table, as
  149. described in this document, should be present in
  150. the first logical sector of each disk. Logical
  151. sectors must be a multiple of 64 bytes in size.
  152. o Random Access Memory (RAM) should be contiguous
  153. from the point where MS-DOS is located through top
  154. of memory.
  155. o MS-DOS requires a minimum of 128K of RAM (depending
  156. on IO.SYS size). Microsoft recommends a minimum
  157. configuration of 128K non-video RAM and 192K for
  158. future products.
  159. The sample BIOS that is provided has been designed to only run on
  160. a machine with the exact architecture of IBM PC family.
  161. If MS-DOS can run on the OEMs hardware using the sample BIOS, then
  162. the hardware is compatible with the IBM PC family architecture.
  163. MS-DOS INSTALLATION KIT Page 1-4
  164. In addition to these minimum requirements, the following
  165. hardware features are recommended for optimum performance as
  166. well as compatibility with new Microsoft products. Features
  167. recommended for performance on 2.0 and higher systems are
  168. starred.
  169. o *An interrupt-driven keyboard with a type-ahead
  170. buffer (Interrupt-driven I/O for all devices).
  171. o *Direct memory access.
  172. o *Non-interlaced disks.
  173. o *Disk door locks or a detection mechanism to check
  174. if disks have been changed.
  175. o Support of standard MS-DOS disk formats.
  176. o User-addressable bit-mapped video display with
  177. minimum resolution of 640 by 200 pixels.
  178. o Programmable interval timer.
  179. o Mouse support.
  180. o RS-232 and printer interfaces.
  181. o Minimum 192K RAM memory.
  182. o A Scroll Lock/Break key that puts a Control-S and
  183. Control-C at the beginning of the keyboard
  184. type-ahead buffer when pressed.
  185. MS-DOS INSTALLATION KIT Page 1-5
  186. 1.5 MS-DOS OVERVIEW
  187. An MS-DOS implementation requires seven components:
  188. 1. The resident device drivers (the IO.SYS file), a
  189. collection of hardware-specific device drivers that
  190. must be written by the OEM. The resident device
  191. drivers are called by MS-DOS to handle I/O
  192. requests. These device drivers may be partly ROM
  193. resident or may be completely RAM resident.
  194. 2. The SYSINIT Module(s), (SYSINIT1.OBJ and SYSINIT2.OBJ
  195. in 3.xx and only SYSINIT.OBJ in 2.xx) and SYSIMES.OBJ,
  196. Microsoft-supplied modules which are linked to the
  197. resident device drivers and initialize the system.
  198. The file that contains these device drivers is
  199. named IO.SYS (on the IBM(R) PC, this file is named
  200. IBMBIO.COM).
  201. 3. MSDOS.SYS, the hardware-independent disk operating
  202. system supplied by Microsoft. (On the IBM PC, this
  203. file is named IBMDOS.COM.)
  204. 4. COMMAND.COM, the command interpreter program that
  205. reads and interprets keyboard input, executes
  206. "built-in" commands like DIR, and initiates
  207. external programs.
  208. 5. Bootstrap loader, the OEM-supplied module that
  209. loads the IO.SYS and MSDOS.SYS files into memory.
  210. MSDOS.SYS may optionally be loaded by IO.SYS.
  211. A sample bootstrap loader has been provided with
  212. the OEM kit. This sample bootstrap loader is
  213. compatible with the IBM PC family.
  214. 6. A system ROM which may optionally perform
  215. diagnostics on power-up or reset. The system ROM
  216. loads the boot sector into RAM and transfers
  217. control to it.
  218. 7. MS-DOS utilities, including FORMAT, for which
  219. Microsoft modules are provided and a
  220. hardware-specific section must be written by the
  221. OEM. NOTE: Refer to the MS-DOS 3.3 specific portions
  222. for use of the hardware independent FORMAT utility.
  223. MS-DOS INSTALLATION KIT
  224. CONTENTS
  225. CHAPTER 2 MS-DOS DEVELOPMENT TOOLS
  226. EDLIN Text Editor 2-1
  227. Microsoft Macro Assembler 2-1
  228. Microsoft Linker (MS-LINK) 2-2
  229. MS-DEBUG 2-2
  230. EXE2BIN 2-2
  231. FORMAT 2-2
  232. CHAPTER 2
  233. MS-DOS DEVELOPMENT TOOLS
  234. An assembler, text editor, linker, and other utilities are
  235. required for completing an MS-DOS implementation. We assume
  236. that your development machine has the following standard
  237. utilities:
  238. EDLIN Text Editor
  239. The EDLIN text editor provided with MS-DOS for your
  240. development machine may be used to prepare assembler
  241. source files. The version of EDLIN on MS-DOS 2.x and
  242. 3.x release disks is for versions 2.x and 3.x only, and
  243. will not run under MS-DOS 1.x. A third party full screen
  244. text editor (not a word processor) may be more efficient
  245. for manipulating source files.
  246. Microsoft Macro Assembler
  247. A complimentary copy of the current Microsoft Macro Assembler
  248. is provided with the MS-DOS installation kit.
  249. The assembler is not actually a part of MS-DOS; it must be
  250. licensed separately if you wish to ship it to your
  251. customers. The Cross-Reference Utility (MS-CREF),
  252. included with Microsoft Macro Assembler, can be used to
  253. make cross-reference listings of assembler programs.
  254. The Microsoft Macro Assembler package will only run
  255. under MS-DOS 2.XX and later operating systems. The
  256. output of the assembler is a relocatable object module
  257. (.OBJ file type) which conforms to a subset of the
  258. INTEL MCS 86 object module format description. Refer
  259. to the MS-DOS Programmer's Reference Manual for ______ ____________ _________ ______
  260. information on the INTEL MCS 86 object module format
  261. description.
  262. MS-DOS DEVELOPMENT TOOLS Page 2-2
  263. Microsoft Linker (MS-LINK)
  264. Your MS-DOS development machine should include a linker
  265. named LINK.EXE. Use LINK.EXE for linking object
  266. modules (.OBJ files) produced by the Microsoft Macro
  267. Assembler. The output of the Linker is a file with an
  268. .EXE format. This is an executable program requiring a
  269. special loader that is part of MS-DOS. Refer to the
  270. MS-DOS Programmer's Reference Manual for details on ______ ____________ _________ ______
  271. .EXE formats.
  272. SYMDEB
  273. SYMDEB.EXE is the MS-DOS symbolic debugger. The debugger
  274. can do absolute disk reads and writes. You may use this
  275. facility to write your bootstrap loader program into
  276. the boot sector. Note that since MS-DOS is not
  277. reentrant, this debugger may not be used to set break
  278. points within the DOS or device drivers.
  279. EXE2BIN
  280. The EXE2BIN.EXE utility supplied with your MS-DOS
  281. development machine must be used for converting output
  282. from the Linker (.EXE files) to a pure binary (core
  283. image) format not requiring a special loader. Note
  284. that only .COM files may execute out of ROM.
  285. FORMAT
  286. The FORMAT program (FORMAT.EXE) supplied with your
  287. MS-DOS development machine may be used to format a boot
  288. disk for the target machine, assuming both machines
  289. have compatible media.
  290. EXEFIX
  291. EXEFIX is a special purpose utility used for building
  292. SORT. It sets the maximum memory allocation.
  293. MS-DOS DEVELOPMENT TOOLS
  294. CONTENTS
  295. CHAPTER 3 INSTALLING MS-DOS
  296. CHAPTER 3
  297. INSTALLING MS-DOS
  298. If you are using an MS-DOS machine for development and your
  299. target machine will read MS-DOS standard disk formats,
  300. follow these steps to implement MS-DOS.
  301. NOTE: The steps involved in developing IO.SYS are not necessary
  302. if the sample BIOS provided with the OEM kit is used.
  303. This sample can also be used for technical reference.
  304. 1. Using a text editor on your development machine,
  305. write the 8086 assembler source code for the
  306. resident device drivers. The resident device
  307. drivers are the hardware-specific routines that
  308. will be accessed by MS-DOS to perform I/O. There
  309. must be a minimum of five device drivers: four ____
  310. character drivers and one block device driver (the
  311. disk drive on most systems). In addition to the
  312. device drivers, you may want to include some code
  313. for hardware initialization. The source file
  314. should be named IO.ASM and must not contain a STACK
  315. segment.
  316. For more information, see:
  317. MS-DOS Programmer's Reference Manual ______ ____________ _________ ______
  318. IO.ASM on the distribution disk
  319. The resident device driver section of this manual
  320. 2. Use MASM.EXE, the macro assembler provided with
  321. your MS-DOS installation kit to assemble your
  322. device driver code. MASM will create a file called
  323. IO.OBJ, which is in a special object module format
  324. (a subset of INTEL's object module format).
  325. For more information, see:
  326. Microsoft Macro Assembler Manual (Macro Assembler _________ _____ _________ ______
  327. section)
  328. 3. Use LINK.EXE, the Microsoft Linker, to link your
  329. IO.OBJ module to appropriate SYSINIT.OBJ module(s)and the
  330. appropriate SYSIMES.OBJ module. The
  331. modules must be linked in this order:
  332. 2.xx IO.OBJ+SYSINIT.OBJ+SYSIMES.OBJ
  333. 3.XX IO.OBJ+SYSINIT1.OBJ+SYSINIT2.OBJ+SYSIMES.OBJ
  334. The output file should be named IO.EXE. You
  335. INSTALLING MS-DOS Page 3-2
  336. may get the message "Warning, no STACK segment" while
  337. linking the module. This is a warning message and
  338. is normal with some versions of the linker.
  339. For more information, see:
  340. Microsoft Macro Assembler Manual (Chapter 3 LINK: _________ _____ _________ ______
  341. A Linker)
  342. 4. The file created in step 3 is an .EXE file which is
  343. in a special format recognized by the .EXE loader.
  344. Since the .EXE loader is not available at boot
  345. time, the IO.EXE file must be converted to a pure
  346. binary core image file. This is done with the
  347. EXE2BIN utility provided with the MS-DOS release on
  348. your development machine. The EXE2BIN utility must
  349. know exactly where the code will reside in memory
  350. to resolve any FAR references. You will be
  351. prompted for the base address, the absolute segment
  352. address where the code will begin. The resultant
  353. file must be named IO.SYS. EXE2BIN will change the
  354. name when you type the following command line:
  355. EXE2BIN IO.EXE IO.SYS
  356. ------------------------------------------------------------
  357. | |
  358. | Note |
  359. | |
  360. | It is the responsibility of the bootstrap loader to |
  361. | locate IO.SYS at the location you specified as the base |
  362. | address. The location itself is arbitrary, since one |
  363. | of the parameters that the resident device driver code |
  364. | passes to SYSINIT is the location of the first device |
  365. | driver. |
  366. | |
  367. |__________________________________________________________|
  368. For more information, see:
  369. MS-DOS User's Reference Manual (Chapter 3) ______ ______ _________ ______
  370. 5. Customize the function key table in DOSMES.ASM.
  371. 6. Use MSDOSBLD.BAT on the distribution disk to assemble
  372. appropriate object modules and link them with those
  373. already provided to form MSDOS.SYS.
  374. 7. Write a bootstrap loader program using the text
  375. editor. This step is not necessary if the sample
  376. bootstrap loader included in the OEM kit is used.
  377. The sample bootstrap loader can also be used for
  378. technical reference.
  379. Name this file BOOT.ASM. We assume that you have
  380. a system ROM which will load the first sector of
  381. the system disk into memory when you turn
  382. on or reset the compter. Ideally, the bootstrap
  383. loader fits into the first sector of the boot disk.
  384. In addition to the loader, information relating to
  385. the BIOS Parameter Block (BPB) should be kept in the
  386. boot sector of the disk. The format of the boot
  387. INSTALLING MS-DOS Page 3-3
  388. sector is described in Chapter 4.
  389. The bootstrap loader loads IO.SYS and MSDOS.SYS into
  390. memory. MS-DOS can be located any place in memory
  391. above IO.SYS. (IO.SYS can alternately be used to
  392. load MSDOS.SYS.) Loading IO.SYS and MSDOS.SYS is
  393. simple because these two files must always be the
  394. first files on the disk. This means that a
  395. bootstrap loader could simply load a series of
  396. consecutive sectors into memory. Your bootstrap
  397. loader may also read in the first sector of the
  398. directory before it loads IO.SYS to verify that
  399. these files are the first files on the disk.
  400. For more information, see:
  401. MS-DOS Programmer's Reference Manual ______ ____________ _________ ______
  402. (Chapter 2)
  403. MS-DOS Adaptation Guide (Chapter 4) ______ __________ _____
  404. 8. Assemble, link, and convert to binary (using
  405. EXE2BIN) the BOOT.ASM file to produce BOOT.BIN.
  406. 9. Format a non-system disk using your MS-DOS
  407. development machine.
  408. 10. Using the MS-DOS Copy command, copy IO.SYS,
  409. MSDOS.SYS, and appropriate version of
  410. COMMAND.COM to the formatted disk.
  411. 11. Using DEBUG.COM on the development machine, load
  412. BOOT.BIN and write it to the first sector of the
  413. formatted disk. This can be done as follows:
  414. DEBUG
  415. -N BOOT.BIN
  416. -L (loads BOOT.BIN)
  417. -W 100 0 0 1 (writes BOOT.BIN to drive 0
  418. sector 0)
  419. -Q
  420. Note: More operations may be required depending on
  421. how your boot program is organized.
  422. For more information, see:
  423. Microsoft Macro Assembler Manual (Chapter 4 SYMDEB: _________ _____ _________ ______
  424. A Symbolic Debug Utility
  425. The formatted disk should now be bootable by your
  426. system.
  427. INSTALLING MS-DOS Page 3-4
  428. 12. Write the source code for the hardware-specific part
  429. of the FORMAT program. The MS-DOS 3.3 version of the
  430. FORMAT utility has been structured so that the hardware
  431. specific portions have been placed solely in IO.SYS.
  432. Minimal work should be required for the OEM use of the
  433. MS-DOS 3.2 FORMAT utility.
  434. Assemble and link this to the FORMAT.OBJ and FORMES.OBJ
  435. files supplied by Microsoft. The modules must be linked
  436. in the following order:
  437. 2.XX: FORMAT.OBJ+FORMES.OBJ+OEMFOR.OBJ
  438. where OEMFOR.OBJ is your hardware-specific module.
  439. Use EXE2BIN to convert the OEMFOR.EXE file produced
  440. to FORMAT.COM.
  441. 3.XX: FORMAT.OBJ+FORPROC.OBJ+FORMES.OBJ+OEMFOR.OBJ+PRINTF.OBJ
  442. where OEMFOR is your hardware-specific module.
  443. Although the PRINTF.OBJ module is the last module
  444. specified, it does not follow the OEM module in the
  445. memory image.
  446. For more information, see:
  447. MS-DOS Adaptation Guide (Chapter 7) ______ __________ _____
  448. OEMFOR.ASM Disk file of sample OEM FORMAT module
  449. MS-DOS User's Reference Manual (Format Command, ______ ______ _________ ______
  450. Chapter 3)
  451. MS-DOS Programmer's Reference Manual (Chapter 3) ______ ____________ _________ ______
  452. 13. Install the MS-DOS OEM serial number.
  453. For information on how this is done, refer to the README.DOC
  454. on the distribution diskette.
  455. 14. Modify SORTMES.ASM as appropriate.
  456. 15. Build SORT executable with SORTBLD.BAT.
  457. 16. Modify PRINT source modules as appropriate
  458. 17. Build PRINT executable with PRINTBLD.BAT
  459. INSTALLING MS-DOS
  460. CONTENTS
  461. CHAPTER 4 DISK STRUCTURE AND BOOTSTRAP LOADING
  462. 4.1 Reserved Area 4-1
  463. 4.2 File Allocation Table 4-2
  464. 4.3 MS-DOS File System Limits 4-4
  465. 4.3.1 Disk Format Identification 4-6
  466. 4.4 The role of the Boot Sector 4-7
  467. CHAPTER 4
  468. DISK STRUCTURE AND BOOTSTRAP LOADING
  469. MS-DOS disks are divided into four logical data areas.
  470. 1. Reserved sectors (boot sector)
  471. 2. File Allocation Tables
  472. 3. Root directory
  473. 4. Data area which may include subdirectories
  474. as well as program and data files
  475. When creating non-standard disks or non-removable media
  476. (such as hard disks), the logical disk which your device _______
  477. driver presents to MS-DOS must conform to the above
  478. standard. The physical layout may be completely different. ________
  479. For example, you may want to implement a partitioning scheme
  480. on the hard disk so that it can be shared by multiple
  481. operating systems. In this case, either the device driver
  482. or firmware maps the physical structure into an MS-DOS
  483. logical layout. The MS-DOS file system can even be
  484. logically implemented within another operating system's file
  485. structure.
  486. 4.1 RESERVED AREA
  487. The reserved area is the first part of the disk and is
  488. typically used for boot purposes. Some machines not
  489. specifically designed for MS-DOS may use track 0 for special
  490. purposes (it may even have a different sector size than the
  491. rest of the disk). In this case, the entire track should be
  492. marked as reserved so that the device driver will map
  493. MS-DOS's logical sector 0 to the beginning of track 1
  494. instead of track 0.
  495. It may be difficult to fit the required boot information
  496. into a single sector. Note that disk formats using 128- or
  497. 256-byte sectors and without any firmware support may
  498. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-2
  499. require several sectors.
  500. 4.2 FILE ALLOCATION TABLE
  501. The File Allocation Table (FAT) is the most important data
  502. structure on the disk. Two copies are usually kept at the
  503. OEM's option. (Two copies need not be kept for a virtual
  504. RAM disk because, in this case, the media cannot be damaged.)
  505. MS-DOS files are allocated in "allocation units" or "clusters".
  506. Each cluster is some number of sectors. The number of sectors
  507. per allocation unit must be a power of 2 which fits in a byte.
  508. Thus, the complete list of possible values is:
  509. 1, 2, 4, 8, 16, 32, 64, 128.
  510. The FAT is a physical map of the allocation units in the
  511. data area of the disk. There is one FAT entry for each
  512. allocation unit on the disk plus two reserved entries at the
  513. beginning of the FAT. The entries serve as a linked list of
  514. pointers. For a complete discussion of FAT structure, refer
  515. to Chapter 3 of the MS-DOS Programmer's Reference Manual. ______ ____________ _________ ______
  516. FAT size can be determined by the following formula:
  517. FAT = Q * ( T - R - D + 2)
  518. --------------------
  519. Q * N + ( A * S )
  520. FAT is the number of sectors needed for one FAT and will
  521. usually not be an integer. It must be rounded up to
  522. the next integer value.
  523. Q is the number 1.5 for 12-bit FAT entries and 2.0
  524. for 16-bit FAT entries.
  525. T is the total number of sectors on the disk.
  526. R is the number of reserved sectors.
  527. D is the number of root directory sectors (there must
  528. be 32 bytes for each directory entry).
  529. A is the number of sectors per cluster or allocation
  530. unit.
  531. N is the number of file allocation tables on the disk.
  532. S is the number of bytes per sector.
  533. MS-DOS 3.x can use 16-bit FAT pointers whenever the total
  534. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-3
  535. number of clusters on the disk exceeds 4085 (=4096-10; two
  536. are reserved at the beginning, and eight are reserved at the
  537. end). Although the FAT entries are 16 bits, the present
  538. software only works with 15 bits (up to 32766 clusters).
  539. ____________________________________________________________
  540. | |
  541. | Important |
  542. | |
  543. | Be careful when reducing cluster size as it can cause |
  544. | significant performance degradation. Reducing cluster |
  545. | size results in increased fragmentation, a larger FAT |
  546. | to buffer (increasing the number of disk accesses); and |
  547. | increasing the FAT entries from 12 to 16-bit expands |
  548. | the FAT size by 33%. |
  549. | |
  550. |__________________________________________________________|
  551. The FORMAT program will create a proper FAT. The FAT has an
  552. entry for each allocation unit in the data area of the disk.
  553. It also contains two extra entries at the beginning. These
  554. represent reserved clusters. The first cluster of the data
  555. region of the disk is cluster 2.
  556. The first (0th cluster) of these two reserved entries can be
  557. used to indicate the format of the disk. Only the low 8
  558. bits are used, and this byte is often referred to as the
  559. FATID byte. The high 4 bits (high byte if a 16-bit FAT) of
  560. this first cluster are all set (=1).
  561. The FATID byte is restricted to be in the range 0F8H to
  562. 0FFH, inclusive (8 possible values). The FATID byte is also
  563. an end-of-file (EOF) mark. If a FAT chain contains a zero
  564. entry (which should never happen), it will point to this EOF
  565. marker. The second (1st cluster) of these two reserved
  566. entries is always 0FFFH (0FFFFH for a 16-bit FAT), which is
  567. an end-of-file mark.
  568. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-4
  569. Figure 4.1 illustrates the first two clusters of a 12-bit
  570. File Allocation Table.
  571. FAT BYTE 00 01 02 03
  572. XXH XXH XXH XXH----->Byte 3
  573. || || ||
  574. Middle 4 bits | || High and middle 4 bits of
  575. of cluster 0 | || cluster 1 (always F)
  576. | | High 4 bits of
  577. Low 4 bits of | cluster 0 (always F)
  578. cluster 0 |
  579. | | Low 4 bits of cluster
  580. |------------------| 1 (always F)
  581. |
  582. FATID BYTE
  583. Figure 4.1. First Two Entries of the FAT (12-bit)
  584. 4.3 MS-DOS FILE SYSTEM LIMITS
  585. The following figure shows the file storage limitations
  586. within MS-DOS.
  587. | MS-DOS 2.x | Both | MS-DOS 3.x
  588. _______________|______________|_____________|_______________
  589. |FAT entry size |12 bits | |12 or 16 bits |
  590. |Sector size | |64b-32Kb | |
  591. |No. of Sectors | |Max of 64K | |
  592. |Cluster size | |1-128 sectors| |
  593. |Max. disk size |4085 clusters |64K sectors |32766 clusters|
  594. |Max. file size | |Disk size | |
  595. ________________|______________|_____________|______________|
  596. All ranges in the table are inclusive. As well as the above
  597. limitations, there are also various limits as noted below:
  598. 1. FAT entry size.
  599. This is the only file storage limit difference
  600. between MS-DOS 2.XX and 3.XX; it significantly
  601. increases the maximum number of clusters and hence
  602. the maximum disk size allowed. MS-DOS 3.x
  603. determines whether a 12- or 16-bit FAT is in use by
  604. calculating the number of disk clusters from the
  605. BPB. If the number of clusters is less than or
  606. equal to 4085, a 12-bit FAT is in use; otherwise,
  607. a 16-bit FAT is assumed. A 16-bit FAT cannot be
  608. used if the total number of clusters is less than
  609. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-5
  610. or equal to 4085.
  611. Some existing MS-DOS applications (such as copy
  612. protection schemes and disk maintenance utilities)
  613. bypass MS-DOS and manipulate the FAT directly.
  614. These existing applications will cause problems
  615. with 16-bit FATs until the applications are updated
  616. to recognize the 16-bit FATs.
  617. 2. Sector Size.
  618. Must be a multiple of 64 bytes.
  619. 3. No. of Sectors.
  620. The number of sectors is limited to 64K because
  621. 16-bit sector numbers are passed to the device
  622. drivers.
  623. 4. Cluster Size.
  624. The cluster size (bytes/cluster = sectors/cluster *
  625. bytes/sector) must be less than 64K because MS-DOS
  626. uses 16-bit arithmetic.
  627. Sectors/Cluster must be a power of 2 in the range
  628. 1-128.
  629. Excessively small cluster sizes can seriously
  630. degrade performance. Refer to the MS-DOS ______
  631. Programmer's Reference Manual for sample disk ____________ _________ ______
  632. formats.
  633. 5. Max. Disk Size.
  634. MS-DOS 2.XX: Lesser of 4085 clusters or 64K sectors
  635. (For example, 64K*512 byte sectors = 32Mb disk).
  636. MS-DOS 3.XX: Lesser of 32766 clusters or 64K
  637. sectors.
  638. The total number of sectors is limited to 64K due
  639. to the use of 16-bit arithmetic.
  640. The maximum number of possible clusters is
  641. calculated by the following:
  642. FAT entry size
  643. (2 -10 Reserved)
  644. Reserved: 8 FAT ID/EOF (F8-FF)
  645. 2 RESERVED (0,1)
  646. ------------------------------------------------------------
  647. | |
  648. | Note |
  649. | |
  650. | However, some MS-DOS utilities (such as Chkdsk and |
  651. | Recover) restrict the total FAT size to 32K entries, |
  652. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-6
  653. | hence the MS-DOS 3.x limit of 32,766 clusters and not |
  654. | 65,525 (216-11). |
  655. | |
  656. |__________________________________________________________|
  657. There are 10 MS-DOS reserved FAT entries; two at
  658. the front of the FAT, and eight at the end:
  659. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-7
  660. 4086 = 4K -10
  661. 32766 = 32K -2
  662. The 8 reserved clusters
  663. are in the range 65528-65536.
  664. 6. Max. File Size.
  665. Files cannot be split across disks; therefore, the
  666. maximum file size is normally the maximum disk
  667. size. The file size is also restricted by a 32-bit
  668. file pointer. This means that the maximum possible
  669. file size is 4 gigabytes:
  670. 32
  671. 4 million K, 2 -1
  672. 4.3.1 Disk Format Identification
  673. Beginning with MS-DOS 2.0, Microsoft is promoting the use of
  674. a media descriptor table in the boot sector. This table
  675. contains both a physical description (number of sectors,
  676. sides, tracks, etc.) and a logical description (number of
  677. FATs, directory entries, etc.) of the disk layout. The
  678. media description table allows MS-DOS to accommodate future
  679. floppy disk formats, or formats defined by other
  680. manufacturers but not generated by your FORMAT utility.
  681. Your device driver should assume that the media description
  682. table exists if the first byte of the boot sector is the
  683. first byte of a 3-byte (near) jump or a 2-byte jump.
  684. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-8
  685. 4.4 THE ROLE OF THE BOOT SECTOR
  686. Typically, the system ROM will load the reserved (boot)
  687. sector or sectors into memory at power-up or restart. We
  688. recommend that the boot sector do the following:
  689. 1. It should read the first sector of the directory
  690. and verify that the first two files on the disk are
  691. IO.SYS and MSDOS.SYS, in that order.
  692. You may choose to have your FORMAT utility generate
  693. different boot sectors for each disk format. Or,
  694. you may create a universal boot sector to read the
  695. media description table and determine where to find
  696. the first directory sector both logically and
  697. physically.
  698. 2. If the boot code does not find the MS-DOS files in
  699. the directory, then the boot sector should prompt
  700. the operator that an attempt has been made to boot
  701. from a non-bootable disk. You determine how the
  702. user should continue ("Strike any key" or "Turn
  703. power off").
  704. 3. The boot sector must read in the IO.SYS and
  705. MSDOS.SYS files. Alternatively, the boot sector may
  706. read in only IO.SYS, and IO.SYS may then read in
  707. MSDOS.SYS. Only IO.SYS needs to be contiguous on the
  708. disk.
  709. The boot sector must know or calculate where those
  710. files physically begin on the disk (right after the
  711. last directory sector) and how long they are
  712. (contained in directory entries). You must code
  713. (or calculate) the location at which they should be
  714. loaded into memory in the boot sector.
  715. 4. The boot sector must transfer control to your entry
  716. point in IO.SYS.
  717. The boot sector does not load COMMAND.COM, as it
  718. will be loaded by SYSINIT.
  719. The SYS command allows users to transfer the operating
  720. system onto a formatted disk that contains no files or
  721. contains an old version of the operating system of equal or
  722. greater size. For the MS-DOS 2.XX version on the IBM PC, the
  723. SYS command was modified to transfer MS-DOS 2.XX system files
  724. onto old 1.XX disks. The new MSDOS.SYS can be placed on the
  725. disk in a non-contiguous format. (IO.SYS is still
  726. contiguous because the new IO.SYS is smaller than the
  727. DISK STRUCTURE AND BOOTSTRAP LOADING Page 4-9
  728. combined sizes of the old IO.SYS and MSDOS.SYS.) The boot
  729. sector is only responsible for loading IO.SYS, although it
  730. must check that MSDOS.SYS is the second file on the disk.
  731. Therefore, IO.SYS may load a non-contiguous MSDOS.SYS.
  732. The logic to facilitate checking through the FAT entries
  733. must be added to IO.SYS because the logic normally resides
  734. in the not-yet-loaded MSDOS.SYS. The logic resides in the
  735. installation part of IO.SYS so that it will be overwritten
  736. when MSDOS.SYS is loaded. This technique should only be
  737. used to use the SYS command to transfer a new, bigger MS-DOS
  738. onto an old disk. It is not useful if you do not have old
  739. disks to support in the field. Note that the various FAT
  740. entries for a non-contiguous MSDOS.SYS may reside in
  741. different FAT sectors making it necessary to read more than
  742. just the first FAT sector into memory.
  743. There is an example of a boot sector on the OEM Sample MS-DOS
  744. Implementation Diskette.
  745. DISK STRUCTURE AND BOOTSTRAP LOADING
  746. CONTENTS
  747. CHAPTER 5 RESIDENT DEVICE DRIVERS
  748. 5.1 Introduction 5-1
  749. 5.2 Bit 4 5-3
  750. 5.3 Installation of Device Drivers 5-5
  751. 5.4 The CLOCK Device 5-5
  752. 5.5 INIT (Command Code 0) 5-6
  753. 5.6 Media Check 5-7
  754. 5.7 DMA Boundary Violation 5-9
  755. CHAPTER 5
  756. RESIDENT DEVICE DRIVERS
  757. ------------------------------------------------------------
  758. | |
  759. | Note |
  760. | |
  761. | Chapter 2, "Device Drivers," in the MS-DOS Programmer's |
  762. | Reference Manual contains a description of MS-DOS |
  763. | device drivers. Additional information applicable to |
  764. | OEM is included here. |
  765. | |
  766. ------------------------------------------------------------
  767. 5.1 INTRODUCTION
  768. The IO.SYS file is composed of the "resident" device
  769. drivers. This forms the MS-DOS Basic Input Output System
  770. (BIOS), and these drivers are called upon by MS-DOS to
  771. handle I/O requests initiated by application programs.
  772. One of the most powerful features of MS-DOS is the ability
  773. to add new devices such as printers, plotters, or mouse
  774. input devices without rewriting the BIOS. The MS-DOS BIOS
  775. is "configurable;" that is, new drivers can be added and
  776. existing drivers can be pre-empted. Non-resident device
  777. drivers may be easily added by a user at boot time via the
  778. "DEVICE =" entry in the CONFIG.SYS file. In this section,
  779. these non-resident drivers are called "installable" device
  780. drivers to distinguish them from drivers in the IO.SYS file,
  781. which are considered the resident drivers.
  782. At boot time, a minimum of five resident device drivers (four
  783. character devices and one block device) must be present.
  784. These drivers are in a linked list: the header
  785. of each one contains a DWORD pointer to the next. The last
  786. driver in the chain has an end-of-list marker of -1, -1 (all
  787. bits on).
  788. Each driver in the chain has two entry points: the strategy
  789. entry point and the interrupt entry point. MS-DOS 2.XX/3.XX
  790. does not take advantage of the two entry points: it calls
  791. RESIDENT DEVICE DRIVERS Page 5-2
  792. the strategy routine, then immediately calls the interrupt
  793. routine.
  794. The dual entry points facilitate future multitasking
  795. versions of MS-DOS. In multitasking environments, I/O must
  796. be asynchronous; to accomplish this, the strategy routine
  797. will be called to (internally) queue a request and return
  798. quickly. It is then the responsibility of the interrupt
  799. routine to perform the I/O at interrupt time by getting
  800. requests from the internal queue and processing them. When
  801. a request is completed, it is flagged as "done" by the
  802. interrupt routine. MS-DOS periodically scans the list of
  803. requests looking for those that are flagged as done, and
  804. "wakes up" the process waiting for the completion of the
  805. request.
  806. When requests are queued in this manner, it is no longer
  807. sufficient to pass I/O information in registers, since many
  808. requests may be pending at any time. Therefore, the MS-DOS
  809. 2.x/3.x device interface uses "packets" to pass request
  810. information. These request packets are of variable size and
  811. format, and are composed of two parts:
  812. 1. The static request header, which has the same
  813. format for all requests.
  814. 2. A section that has information specific to the type
  815. of request.
  816. A driver is called with a pointer to a packet. In
  817. multitasking versions, this packet will be linked into a
  818. global chain of all pending I/O requests maintained by
  819. MS-DOS.
  820. The 2.XX and 3.XX versions of MS-DOS do not implement a
  821. global or local queue. Only one request is pending at any
  822. one time. The strategy routine must store the address of
  823. the packet at a fixed location, and the interrupt routine
  824. (which is called immediately after the strategy routine)
  825. should process the packet by completing the request and
  826. returning. It is assumed that the request is completed when
  827. the interrupt routine returns.
  828. To make a device driver that SYSINIT can install, a .BIN
  829. (core image) or .EXE format file must be created with the
  830. device driver header at the beginning of the file. The link
  831. field should be initialized to -1 (SYSINIT fills it in).
  832. Device drivers that are part of the BIOS should have their
  833. headers point to the next device in the list and the last
  834. header should be initialized to -1,-1. The BIOS must be a
  835. BIN (core image) format file produced by using the utility
  836. EXE2BIN.
  837. .EXE format installable device drivers may be used in
  838. RESIDENT DEVICE DRIVERS Page 5-3
  839. non-IBM versions of MS-DOS before 3.0. The reason for this
  840. restriction is that on the IBM PC, the .EXE loader is located
  841. in COMMAND.COM, which is not present at the time that installable
  842. devices are being loaded.
  843. The attribute field and entry points must be set correctly.
  844. If the device is a character device, the name field must be
  845. filled in. (This name can be any 8-character legal
  846. filename). If it is a block device, SYSINIT will fill in the
  847. correct unit count. SYSINIT always installs character
  848. devices at the start of the device list, so if you want to
  849. install a new CON device, simply name it CON. The new one
  850. will be placed ahead of the old one in the list and will
  851. pre-empt the old one because the search for devices stops on
  852. the first match.
  853. Be sure to set the standard input (sti) and standard output
  854. (sto) bits on a new CON device.
  855. ------------------------------------------------------------
  856. | |
  857. | Note |
  858. | |
  859. | Since SYSINIT may install the driver anywhere, be |
  860. | careful when coding FAR memory references. You |
  861. | should NOT expect that your installable driver will be |
  862. | located in the same place every time. This does not |
  863. | apply for the resident device drivers. |
  864. | |
  865. |__________________________________________________________|
  866. 5.2 BIT 4
  867. In the MS-DOS Programmer's Reference Manual, bit 4 of the ______ ____________ _________ ______
  868. device driver header format is defined as reserved. It
  869. actually has special meaning.
  870. Bit 4, the special bit, applies to CON drivers. The new
  871. interface supports many new features, but it is slower than
  872. MS-DOS 1.x if old style "single-byte" system calls are made.
  873. To make most efficient use of the interface, all
  874. applications should block their I/O as much as possible.
  875. For example, you should make one XENIX-style system call to
  876. output x number of bytes rather than x system calls to
  877. output one byte each.
  878. RESIDENT DEVICE DRIVERS Page 5-4
  879. Putting a device channel in raw mode provides an even faster
  880. way to output characters. (See the Glossary for an
  881. explanation of "raw" mode.) Bit 4, has been implemented to
  882. alleviate the CON output speed problem for older programs
  883. that use system calls 01H to 0BH to output large amounts of
  884. data. If this bit is 1, the device is CON and an Interrupt
  885. 29H has been implemented, where the 29H handler is defined
  886. as follows:
  887. CONSOLE OUTPUT via INT 29H handler
  888. Input: Character in AL
  889. Function: Output the character in AL
  890. to the screen at the current
  891. cursor location.
  892. Output: None
  893. Registers: All registers except BX must be
  894. preserved. No registers except
  895. AL have a known or consistent
  896. value.
  897. If a character device implements the special bit, the driver
  898. must install an address at the correct location in the
  899. interrupt table for Interrupt 29H. Only one device driver
  900. can have the special bit set in the system. There is no
  901. check to ensure this state.
  902. ____________________________________________________________
  903. | |
  904. | Warning |
  905. | |
  906. | This feature may not be supported in future versions of |
  907. | MS-DOS. Any application (not device driver) that uses |
  908. | Interrupt 29H directly will not work on future versions.|
  909. | In addition, the console device driver must be tested |
  910. | with bit 4 not set to ensure that it will work with such |
  911. | future versions of MS-DOS. |
  912. | |
  913. ____________________________________________________________
  914. The headers of resident drivers should point to the next
  915. device in the list and the last header should be initialized
  916. to -1,-1. IO.SYS must be a .COM format file.
  917. RESIDENT DEVICE DRIVERS Page 5-5
  918. 5.3 INSTALLATION OF DEVICE DRIVERS
  919. MS-DOS 2.XX/3.XX allows new device drivers to be installed
  920. dynamically at boot time. This is accomplished by the
  921. SYSINIT module(s) supplied by Microsoft, which read(s) and
  922. processes the CONFIG.SYS file. The resident driver source
  923. file (IO.ASM) is assembled and linked to the appropriate SYSINIT
  924. module(s) and SYSIMES.OBJ. The resultant .EXE file must
  925. be converted via EXE2BIN to create the file IO.SYS. This
  926. should be the first file that appears on the system disk.
  927. When block drivers are installed, the logical drive letters
  928. are assigned in list order; thus, the driver that will have
  929. logical A must be the first unit of the first block device
  930. in the list. The order of character devices is also
  931. important. There must be at least four character devices
  932. defined at boot time. The first four character devices must
  933. be as follows:
  934. 1. Standard input, standard output, and standard error
  935. output (CON)
  936. 2. Standard auxiliary input and output (AUX)
  937. 3. Standard list output (PRN)
  938. 4. Date/time (CLOCK)
  939. The linked list of device drivers must look like this:
  940. ->CON->AUX->PRN->CLOCK->any other block or
  941. character devices
  942. 5.4 THE CLOCK DEVICE
  943. The CLOCK device is used by MS-DOS 2.XX/3.XX for marking file
  944. control blocks and directory entries with date and time as
  945. well as providing date/time services to application
  946. programs. It is unique in that MS-DOS will read or write a
  947. 6-byte sequence which encodes the date and time. A write to
  948. this device will set the date and time and a read will get
  949. the date and time.
  950. Figure 5.1 illustrates the binary date and time format used
  951. by the CLOCK device.
  952. RESIDENT DEVICE DRIVERS Page 5-6
  953. byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
  954. +--------+--------+---------+--------+--------+---------+
  955. | | | | | | |
  956. |days since 1-1-80| minutes | hours | sec/100| seconds |
  957. |low byte|hi byte | | | | |
  958. +--------+--------+---------+--------+--------+---------+
  959. Figure 5.1. CLOCK Device Format
  960. 5.5 INIT (COMMAND CODE 0)
  961. One of the functions defined for each device is INIT. This
  962. routine is called only when the device is installed. It is
  963. used for initializing character and block devices.
  964. Figure 5.2 illustrates the format of INIT.
  965. +------------------------------------+
  966. | 13-BYTE Request Header |
  967. +------------------------------------+
  968. | BYTE # of units |
  969. +------------------------------------+
  970. | DWORD Break Address |
  971. +------------------------------------+
  972. | DWORD Pointer to BPB array |
  973. | (not set by character devices) |
  974. +------------------------------------+
  975. Figure 5.2. INIT Format
  976. For resident character devices:___ ________ _________ _______
  977. No parameters are passed, and none are returned.
  978. For resident block drivers:___ ________ _____ _______
  979. Unlike character device drivers, block device drivers must
  980. return a number of parameters. The following data are
  981. returned:
  982. 1. The number of units defined by this block device
  983. driver. This is used to determine logical device
  984. names. If the current maximum logical device
  985. letter is F at the time of installation, and the
  986. INIT routine returns 4 as the number of units, then
  987. those units will have the logical names G, H, I and
  988. J. This mapping is determined by the position of
  989. RESIDENT DEVICE DRIVERS Page 5-7
  990. the driver in the device list and the number of
  991. units defined by the device (stored in the first
  992. byte of the device name field). You must return
  993. this number at offset 13D in the INIT call, even
  994. though the number of units is stored in the device
  995. header.
  996. 2. A DWORD pointer to an array of WORD offsets to BPBs
  997. (BIOS Parameter Blocks). There must be one entry
  998. for each unit defined by the device driver. If the
  999. device driver defines two units, then the DWORD
  1000. pointer points to the first of two one-word offsets
  1001. which, in turn, point to BPBs. If both BPBs are
  1002. the same, this will allow you to save space by
  1003. entering two offsets to the same location.
  1004. The BPB is used by MS-DOS to create an internal DOS
  1005. structure. The BPBs that are returned by the resident
  1006. device drivers are scanned to determine the largest sector
  1007. size. This number is used to set the cache buffer size.
  1008. Installable block devices cannot have larger sector sizes
  1009. than those defined by the resident drivers. For this
  1010. reason, you may want to use dummy BPBs to reserve space.
  1011. Use an invalid media byte so that when you later report the
  1012. correct BPB for the unit. MS-DOS will build the correct
  1013. internal DOS structure for the particular drive unit.
  1014. 5.6 MEDIA CHECK
  1015. The MEDIA CHECK function is called when there is a pending
  1016. drive access call other than a file read or write (i.e access
  1017. to the "FILENAME space" - Open, Close, Get_disk_size, INT 25H,
  1018. INT 26H, etc.). Its purpose is to determine whether the media
  1019. in the drive has been changed. Note that the previous media ID
  1020. byte is passed to the device driver. Although the old media ID
  1021. byte is the same as the new one, the disk may have been changed
  1022. and a new disk may be in the drive; therefore, the FAT, and
  1023. directory and data sectors for the unit are invalid.
  1024. MS-DOS 3.XX imposes stricter conditions than MS-DOS 2.XX on
  1025. when media changes are allowed. This can lead to MEDIA
  1026. CHECK routines that seemed to work correctly under MS-DOS
  1027. 2.XX causing problems under MS-DOS 3.XX.
  1028. MS-DOS performance is greatly improved if MEDIA CHECK uses a
  1029. doorlock or some other detection method so that it can
  1030. guarantee that no disk change has occurred; then MS-DOS
  1031. does not have to reread the FAT before each directory
  1032. access.
  1033. MEDIA CHECK can directly use the door-lock mechanism to
  1034. return "Disk not changed." However, the door-lock mechanism
  1035. RESIDENT DEVICE DRIVERS Page 5-8
  1036. indicating that the door has been opened does not
  1037. necessarily mean that the disk has been changed, since the
  1038. user could have reinserted the same disk. MEDIA CHECK
  1039. routines that return "Disk has been changed" just because
  1040. the door has been opened will cause problems under MS-DOS
  1041. 3.x, but not under MS-DOS 2.XX.
  1042. The recommended behavior for MEDIA CHECK is to return as
  1043. follows:
  1044. Disk has not been changed - whenever the door lock
  1045. indicates that the door
  1046. has not been opened
  1047. Don't know - under all other
  1048. circumstances
  1049. It is possible for MEDIA CHECK to try to determine whether a
  1050. disk has really been changed by checking the Volume ID;
  1051. however, many disks have no Volume ID. Therefore, it is
  1052. safer and quicker for MEDIA CHECK to simply return "Don't
  1053. know." The action that MS-DOS takes depends on the state of
  1054. its internal file storage buffers. In general, if "Don't
  1055. know" is returned when MS-DOS has data in its internal
  1056. buffers (data that needs to be written out), MS-DOS will
  1057. assume no disk change has occurred. Otherwise, with empty
  1058. buffers or all buffers "clean", MS-DOS assumes the disk has
  1059. been changed.
  1060. The possible problems caused by an incorrect MEDIA CHECK
  1061. routine can be checked as follows:
  1062. 1. Load MS-DOS 3.XX
  1063. 2. Ensure the disk is write-protected
  1064. 3. COPY FILE1 FILE2
  1065. 4. Write Protect Error from MS-DOS
  1066. 5. Remove the write protection from the disk
  1067. 6. Reinsert the disk in the drive
  1068. 7. Press "R" to cause MS-DOS to retry
  1069. 8. Copy success message
  1070. If an incorrect MEDIA CHECK routine is in use, the Dir
  1071. command will show FILE2 with a size of zero bytes, and
  1072. Chkdsk will report "lost clusters." Note that the copy
  1073. process always returns the success message even with an
  1074. incorrect MEDIA CHECK routine.
  1075. The above test should also be repeated with a "Drive Not
  1076. Ready" error condition instead of the Write Protect error.
  1077. The same symptoms will be displayed.
  1078. For more information on MEDIA CHECK, refer to the MS-DOS ______
  1079. Programmer's Reference Manual.____________ _________ _______
  1080. RESIDENT DEVICE DRIVERS Page 5-9
  1081. 5.7 DMA BOUNDARY VIOLATIONS
  1082. Some OEMs check for any DMA boundary violations on disk
  1083. operations. If a DMA boundary violation error is detected
  1084. then action is taken to prevent this error from being
  1085. reported to the DOS. The sample IO.SYS handles the problem in
  1086. the following way. The operation is tried and if a DMA boundary
  1087. violation is reported, then a flag (in this case bl) is set
  1088. to indicate that we need to do a memory swap to avoid the
  1089. boundary problem. The sector of data that causes the DMA
  1090. boundary violation is transfered into an internal buffer
  1091. that belongs to IO.SYS and then is copied into the buffer
  1092. specified in the original request.
  1093. In other words, the request is broken into several pieces
  1094. consisting of a request for the data up to the DMA boundary
  1095. violation, then the one sector of data that causes the DMA boundary
  1096. violation (in the sample IO.SYS SwapMemory routine is responsible
  1097. for doing this), and then the rest of the request as specified
  1098. by the original disk operation.
  1099. Applications do not depend on this feature in any direct way.
  1100. However, if you do not implement the DMA boundary checking then
  1101. it would be possible for an application to get an INT24 error because
  1102. of the DMA boundary problem and thus behave differently
  1103. depending on how the BIOS was implemented.
  1104. CHAPTER 6 SYSINIT AND MS-DOS INITIALIZATION
  1105. 6.1 Introduction 6-1
  1106. 6.2 The Role of SYSINIT 6-3
  1107. 6.3 COMMAND.COM 6-5
  1108. CHAPTER 6
  1109. SYSINIT AND MS-DOS INITIALIZATION
  1110. 6.1 INTRODUCTION
  1111. In addition to implementing the resident drivers and
  1112. performing any hardware initialization, the IO.ASM code must
  1113. initialize certain external variables. These variables are
  1114. declared public in the SYSINIT module(s) to which the IO.OBJ
  1115. module is linked. The public variables and their functions
  1116. are described below.
  1117. CURRENT_DOS_LOCATION WORD
  1118. This is the paragraph location where the bootstrap loader
  1119. (or, optionally, IO.SYS) has loaded MSDOS.SYS into memory.
  1120. Typically, MSDOS.SYS is located immediately after IO.SYS.
  1121. FINAL_DOS_LOCATION WORD
  1122. Since SYSINIT immediately relocates itself to high memory,
  1123. there will be a hole right after the resident drivers. By
  1124. telling SYSINIT the paragraph where you want it to relocate
  1125. MSDOS.SYS, you can fill up this hole plus overlay any code
  1126. that IO.SYS used for hardware initialization at boot time.
  1127. SYSINIT will move MSDOS.SYS down to this location,
  1128. conserving space. This location also defines where memory
  1129. starts for MS-DOS.
  1130. DEVICE_LIST DWORD
  1131. IO.SYS must tell SYSINIT where the linked list of device
  1132. drivers begins. This is the location of the CON device
  1133. driver header; the information is passed to MS-DOS so that
  1134. the drivers can be accessed.
  1135. SYSINIT AND MS-DOS INITIALIZATION Page 6-2
  1136. MEMORY_SIZE WORD
  1137. This word is the paragraph number of the highest location in
  1138. RAM. If you do not initialize MEMORY_SIZE, SYSINIT will do
  1139. a memory scan to determine the amount of memory. It does
  1140. this by reading every 16 bytes starting at 32K, writing an
  1141. arbitrary pattern, reading it back for a match, and
  1142. returning the original value. It stops when it gets a
  1143. mismatch. If your system has parity memory, you must
  1144. declare this value, since writing to nonexistent memory will
  1145. cause a parity error.
  1146. MS-DOS should be implemented in systems with contiguous
  1147. memory.
  1148. DEFAULT_DRIVE BYTE
  1149. If you can boot MS-DOS from several drives, you must tell
  1150. SYSINIT which drive you booted from so it can find
  1151. CONFIG.SYS and COMMAND.COM. This variable should be set as
  1152. follows: drive A = 1, drive B = 2, etc. If DEFAULT_DRIVE
  1153. is not set, the default drive (drive A) is assumed.
  1154. BUFFERS BYTE
  1155. This is the default number of sector buffers for the system.
  1156. The BUFFERS value may be overridden by the user in the
  1157. CONFIG.SYS file. On versions of MS-DOS up to 3.1, the default
  1158. number of buffers is 2. On versions of MS-DOS after 3.1,
  1159. 3 buffers will be allocated if there is a floppy drive in the
  1160. hardware configuration with a capacity greater than 360KB.
  1161. Beginning with 3.3, if memory size is greater than 128K, then
  1162. 5 buffers will be allocated, and if memory is greater than
  1163. 256K 10 will be allocated; if memory is greater than 512K, 15
  1164. buffers will be allocated.
  1165. The value specified for the number of buffers must be greater
  1166. than or equal to 1.
  1167. FILES BYTE
  1168. This is the default number of open files that system calls
  1169. 2FH-62H can access. This value may be overridden by the
  1170. user in the CONFIG.SYS file. Its default setting in SYSINIT
  1171. is 8. Values of less than 5 are ignored.
  1172. The entry point in SYSINIT should be defined as a FAR label
  1173. in IO.SYS as follows:
  1174. EXTRN SYSINIT:FAR
  1175. After IO.SYS code has performed any hardware initialization
  1176. and has set the above external variables, it should do a FAR
  1177. jump to this label.
  1178. SYSINIT AND MS-DOS INITIALIZATION Page 6-3
  1179. You must provide a FAR procedure in the IO.ASM code which is
  1180. not subject to being overlayed when SYSINIT relocates
  1181. MS-DOS. This procedure is called RE_INIT. It should be
  1182. declared as follows:
  1183. RE_INIT: PROC FAR
  1184. ........
  1185. ........
  1186. RET
  1187. RE_INIT ENDP
  1188. The RE_INIT procedure is called by SYSINIT after MS-DOS is
  1189. installed. On entry, DS:0 points to a 100H-byte program
  1190. segment prefix which represents the Program Segment Prefix
  1191. of SYSINIT and IO.SYS taken together. This is not a normal
  1192. program because no memory is allocated to it; therefore, if
  1193. you allocate and load or Exec, you may overlay this block.
  1194. SYSINIT is located in the top 10K of memory. Do not write __ ___ _____
  1195. there. The space above the 100H byte header at DS:100 is_____
  1196. available for temporary use during RE_INIT.
  1197. The RE_INIT routine can be used to perform functions such as
  1198. to print headers and read files, and it is handy for IO.SYS
  1199. debugging. If you don't need to use this procedure, simply
  1200. do a return (RET). Note that starting with MS-DOS 3.XX,
  1201. RE_INIT may not use FCB system calls.
  1202. ------------------------------------------------------------
  1203. | |
  1204. | Warning |
  1205. | |
  1206. | RE_INIT must not change any registers or flags. |
  1207. | |
  1208. |__________________________________________________________|
  1209. Beginning with MS-DOS 3.2, another FAR procedure must be provided in
  1210. IO.ASM. The name of this procedure is STACKINIT.
  1211. The purpose of this procedure is to initialize a hardware stack
  1212. switching algorithm. If some of the hardware interrupt handlers in the
  1213. ROM BIOS of the OEM hardware system are stack intensive, then
  1214. this initialization routine would be used to direct the processing
  1215. of the hardware interrupt handlers to another portion of code in
  1216. IO.ASM. This code will save the current stack setup and switch stacks to
  1217. an internal space on occurrence of a hardware interrupt.
  1218. When the stack has been switched the original interrupt handler
  1219. is called. The rest of the interrupt handling will use the internal
  1220. stack and not the stack that was in use when the interrupt occurred.
  1221. When the interrupt handler returns the stack is set to its original
  1222. state.
  1223. The advantage of this feature is that there is greater system reliability
  1224. since a dedicated stack space is being used for interrupt handling.
  1225. The OEM should determine which hardware interrupt handlers are stack
  1226. intensive and redirect only those interrupts to the stack switching code
  1227. in IO.ASM.
  1228. This procedure is similar to the FAR procedure RE_INIT in that the code
  1229. is not subject to being overlayed when SYSINIT relocates MS-DOS.
  1230. The procedure STACKINIT should be declared in the same fashion as RE_INIT.
  1231. After MS-DOS is installed, SYSINIT calls the procedure STACKINIT. If this
  1232. procedure is not going to be used, then simply do a return or the OEM
  1233. can assemble SYSINIT with the conditional STACKSW set to FALSE. On entry
  1234. to this routine, there are three data variables that are available.
  1235. These pieces of data reside in the SYSINIT segment. The following
  1236. declarations should be made in IO.ASM to access these variables.
  1237. SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
  1238. EXTRN STACK_ADDR:DWORD
  1239. EXTRN STACK_SIZE:WORD
  1240. EXTRN STACK_COUNT:WORD
  1241. SYSINITSEG ENDS
  1242. These variables are set by SYSINIT and can be changed by using the
  1243. STACKS option in CONFIG.SYS. The full syntax of the STACKS option is:
  1244. STACKS=STACK_COUNT,STACK_SIZE
  1245. where
  1246. STACK_COUNT is the number of stacks
  1247. (range 8 to 64, default 9)
  1248. STACK_SIZE is the stack size
  1249. (range 32 to 512 bytes, default 128)
  1250. The variable STACK_ADDR is the FAR address of the space that SYSINIT
  1251. has allocated for the internal stacks.
  1252. Beginning with MS DOS 3.3, there is a special case for STACKS=0,0.
  1253. This will result in no dynamic stacks being provided. DOS will not
  1254. intercept any interrupts and will only use it own standard stack.
  1255. ____________________________________________________________
  1256. | |
  1257. | Warning |
  1258. | |
  1259. | STACKINIT must not change any registers or flags. |
  1260. | |
  1261. ------------------------------------------------------------
  1262. 6.2 THE ROLE OF SYSINIT
  1263. The following steps illustrate the role of SYSINIT in MS-DOS
  1264. initialization:
  1265. 1. When SYSINIT gains control from the IO.SYS
  1266. initialization code, it determines the size of
  1267. memory (performing a scan if requested, based on
  1268. value of MEMORY-SIZE) and, based on the highest
  1269. paragraph and the size of SYSINIT, it relocates
  1270. itself to high memory.
  1271. SYSINIT AND MS-DOS INITIALIZATION Page 6-4
  1272. 2. Running in high memory, SYSINIT moves MSDOS.SYS
  1273. from the CURRENT_DOS_LOCATION to the
  1274. FINAL_DOS_LOCATION as specified by IO.SYS (see the
  1275. memory maps in Section 6.3, "COMMAND.COM").
  1276. 3. SYSINIT does a FAR call to MS-DOS. MS-DOS has
  1277. initialization code which steps through the linked
  1278. list of device drivers and performs the INIT call
  1279. to each. The copyright message is then printed out
  1280. on the screen.
  1281. 4. After initializing the resident devices, building
  1282. drive parameter blocks for the resident block
  1283. devices, and installing a sector buffer, MS-DOS
  1284. does a FAR return to SYSINIT.
  1285. During MS-DOS initialization, MS-DOS examines the
  1286. BIOS Parameter Blocks (BPBs) returned by the INIT
  1287. call to the block devices. It uses the largest
  1288. sector size it finds as the default buffer size for
  1289. all buffers. For this reason, the initial BPBs may
  1290. be used to reserve space for an installable device
  1291. with a larger sector size rather than reflecting
  1292. the format of the installed disk. In this case,
  1293. these dummy BPBs must have media bytes that do not
  1294. have the same value as those used in real BPBs.
  1295. 5. SYSINIT calls RE_INIT in IO.ASM to allow the OEM to
  1296. print headers or handle any other initialization.
  1297. ------------------------------------------------------------
  1298. | |
  1299. | Warning |
  1300. | |
  1301. | Do not attempt to modify memory. |
  1302. | |
  1303. |__________________________________________________________|
  1304. 6. After IO.SYS returns control to SYSINIT, SYSINIT
  1305. attempts to open the CONFIG.SYS file. If found,
  1306. this file is loaded in memory and all characters
  1307. are turned to uppercase. It is then parsed looking
  1308. for keywords such as DEVICE, BUFFERS, and SHELL.
  1309. Any new devices are loaded, added to the linked
  1310. list, and installed via the INIT call. Character
  1311. devices are added to the front of the list, and new
  1312. block devices are added to the end. Thus, a new
  1313. CON device can supplant an existing resident CON
  1314. device. This provides the facility to reconfigure
  1315. IO.SYS except for the Resident Disk Block device
  1316. driver.
  1317. SYSINIT AND MS-DOS INITIALIZATION Page 6-5
  1318. 7. SYSINIT allocates all of the memory it needs to
  1319. protect the buffers, installed device driver code,
  1320. and IO.SYS. It sets the "owner" of the memory to a
  1321. special value to ensure that this block of memory
  1322. is never deallocated.
  1323. 8. SYSINIT closes all file handles, and then reopens
  1324. CON, AUX, and PRN. This enables a new CON, AUX or
  1325. PRN device to replace the resident devices.
  1326. 9. SYSINIT allocates memory for the buffers.
  1327. 10. SYSINIT allocates memory for hardware stacks and
  1328. calls STACKINIT to initialize the hardware stack
  1329. switching algorithm (only in versions of DOS 3.2
  1330. and later).
  1331. 11. SYSINIT executes COMMAND.COM.
  1332. 12. COMMAND.COM allocates memory for its transient portion
  1333. and moves it.
  1334. MS-DOS is now up and running.
  1335. 6.3 COMMAND.COM
  1336. During its initialization, COMMAND.COM allocates memory for
  1337. its transient part and reloads it. The transient part of
  1338. COMMAND, which contains the internal commands (Copy, Dir,
  1339. Date, Time, etc.), resides in unprotected memory when a
  1340. user's program is loaded into the Transient Program Area
  1341. (TPA). It will be overlaid by programs needing the space.
  1342. When a user program terminates to the COMMAND resident, the
  1343. transient is checked to see if reloading is necessary.
  1344. SYSINIT AND MS-DOS INITIALIZATION Page 6-6
  1345. Each of the following memory maps represents a step in the
  1346. MS-DOS initialization process.
  1347. +-----------------------------+
  1348. | | High memory
  1349. | |
  1350. | |
  1351. | |
  1352. +-----------------------------+ Loaded at arbitrary
  1353. | Bootstrap loader | location by system ROM
  1354. +-----------------------------+ XX:00
  1355. | |
  1356. | |
  1357. | |
  1358. | |
  1359. | |
  1360. | |
  1361. | |
  1362. | |
  1363. | |
  1364. | |
  1365. | |
  1366. +-----------------------------+ Segment 40H
  1367. | Interrupt Vector Table |
  1368. +-----------------------------+ -0:00
  1369. Memory organization in an MS-DOS
  1370. system after the system ROM
  1371. has loaded the boot sector.
  1372. SYSINIT AND MS-DOS INITIALIZATION Page 6-7
  1373. +-----------------------------+
  1374. | | High memory
  1375. | |
  1376. | |
  1377. +- - - - - - - - - - - - - - -+
  1378. | Spent bootstrap loader |
  1379. +- - - - - - - - - - - - - - -+
  1380. | |
  1381. | |
  1382. | |
  1383. +-----------------------------+
  1384. | | MS-DOS disk operating
  1385. | MSDOS.SYS | system in temporary
  1386. | | location
  1387. | |
  1388. +-----------------------------+ Microsoft-supplied
  1389. | SYSINIT | system initialization
  1390. +- - - - - - - - - - - - - - -+ module (part of IO.SYS)
  1391. | |
  1392. | IO.SYS | IO.SYS (may begin at
  1393. +-----------------------------+ any location)
  1394. | Interrupt Vector Table |
  1395. +-----------------------------+
  1396. Memory after bootstrap loader
  1397. loads IO.SYS and MSDOS.SYS.
  1398. SYSINIT AND MS-DOS INITIALIZATION Page 6-8
  1399. +-----------------------------+
  1400. | SYSINIT | High memory
  1401. | relocates itself to highmem |
  1402. +-----------------------------+
  1403. | |
  1404. | |
  1405. | |
  1406. | |
  1407. | |
  1408. +-----------------------------+
  1409. | |
  1410. | MS-DOS structures, buffers, | SYSINIT loads installable
  1411. | hardware stack space, | drivers and buffers here
  1412. | and installable drivers |
  1413. +-----------------------------+
  1414. | |
  1415. | MSDOS.SYS relocated by | SYSINIT moves MS-DOS
  1416. | SYSINIT to fill hole in | down to OEM-designated
  1417. | memory. | FINAL_DOS_LOCATION
  1418. | |
  1419. +-----------------------------+
  1420. | IO.SYS |
  1421. +-----------------------------+
  1422. | Interrupt Vector Table |
  1423. +-----------------------------+
  1424. Memory during system initialization
  1425. performed by SYSINIT module.
  1426. SYSINIT AND MS-DOS INITIALIZATION Page 6-9
  1427. +-----------------------------+
  1428. | COMMAND.COM | High memory
  1429. | (transient) |
  1430. +-----------------------------+
  1431. | | Start of TPA will vary
  1432. | Transient Program Area | with # of drivers,
  1433. | (TPA) | buffers, etc.
  1434. +-----------------------------+
  1435. | COMMAND.COM (resident) | COMMAND.COM loads its
  1436. +-----------------------------+ transient part into top
  1437. | | of largest available
  1438. | MS-DOS structures, buffers | memory
  1439. | hardware stack space, |
  1440. | and installable drivers |
  1441. +-----------------------------+
  1442. | |
  1443. | |
  1444. | MSDOS.SYS |
  1445. | |
  1446. | |
  1447. +-----------------------------+
  1448. | |
  1449. | IO.SYS |
  1450. | resident device drivers |
  1451. +-----------------------------+
  1452. | Interrupt Vector Table |
  1453. +-----------------------------+
  1454. Memory after SYSINIT installs command interpreter.
  1455. This represents the normal configuration
  1456. during MS-DOS operation.
  1457. SYSINIT AND MS-DOS INITIALIZATION
  1458. CONTENTS
  1459. CHAPTER 7A WRITING THE FORMAT MODULE FOR MS-DOS 3.20/3.21
  1460. 7.1 Introduction 7-1
  1461. 7.2 Format Modules and the ES Register 7-9
  1462. 7.3 Changing the Logical Format of Disks 7-9
  1463. CHAPTER 7B
  1464. WRITING THE FORMAT MODULE
  1465. MS-DOS 3.20/3.21
  1466. HIGHLIGHTS OF CHANGES IN 3.2X OVER PREVIOUS 2.XX FORMAT VERSION:
  1467. o FORMAT is now designed to be an .EXE file.
  1468. o The FBIGFAT variable has been introduced for 16-bit
  1469. FAT support.
  1470. o ALLOCATEFAT routine allows space for the FAT to be
  1471. dynamically allocated.
  1472. o Hardware specific functionality assumed to be provided
  1473. by device drivers.
  1474. HIGHLIGHTS OF CHANGES IN 3.20 OVER PREVIOUS FORMAT VERSIONS:
  1475. The intention of the MS-DOS 3.2 FORMAT utility is to
  1476. reduce the amount of OEM work and also move any machine
  1477. dependencies to the device drivers (software BIOS).
  1478. The following are the new features of the MS-DOS 3.2
  1479. FORMAT utility:
  1480. o FORMAT is now designed to be hardware independent.
  1481. The FORMAT utility no longer makes calls directly to
  1482. the ROM BIOS to perform the format operation. The direct
  1483. calls to the ROM BIOS have been replaced with MS-DOS
  1484. system calls (Generic IOCTL's) that perform the necessary
  1485. format functions. The responsibility for interacting
  1486. with the ROM BIOS to deal with the formating functions is now
  1487. placed in the OEM's device drivers.
  1488. o The current head and cylinder being formated is displayed in the
  1489. layout:
  1490. Head: %d Cylinder: %d
  1491. o Two new switches have been added to FORMAT. The new switches
  1492. are:
  1493. /N:xx - Specifies the number of sectors/cylinder
  1494. on the media.
  1495. /T:yy - Specifies the number of tracks on the media.
  1496. These two options will only be useful if the ROM BIOS has support
  1497. to deal with changing of the disk drive parameters.
  1498. o FORMAT will no longer format the default drive if no drive was
  1499. specified on the command line.
  1500. 7.1 INTRODUCTION
  1501. The MS-DOS Format command formats a new disk, clears the FAT
  1502. and directory, and optionally copies system files and
  1503. COMMAND.COM to the new disk. The 3.2X Format utility no
  1504. longer requires the hardware specific code supplied by the
  1505. OEM in previous versions. Instead, Format relies on the
  1506. drive device driver to provide the functionality required
  1507. to format a track on that drive. The Format utility uses a
  1508. GENERIC_IOCTL function request to access the drive device
  1509. driver to format a track on the drive. If the device driver
  1510. does not support a format track function the Format utility
  1511. will not be able to format the drive.
  1512. FORMAT is shipped in two hardware-independent object
  1513. modules. These must be linked to a system configuration
  1514. dependant module written by the OEM. The following section
  1515. describes the routines required in this module. A sample
  1516. OEM format module is included on the MS-DOS release disks
  1517. to assist in writing these routines.
  1518. The syntax for the Format command is:
  1519. Format drive: [/switch1][/switch2]...[/switch16]
  1520. "drive:" is a legal drive specification. As many as 16
  1521. legal switches can be included in the command line.
  1522. 7.2 CODE AND DATA FROM THE OEM
  1523. As the OEM may need to tailor the FORMAT module for a particular
  1524. system configuration the OEM must supply the routines and data
  1525. items which are specific to that configuration. The OEM should
  1526. produce a module, eg. OEMFOR.ASM, which contains the following
  1527. (NEAR) data items;
  1528. SWITCHLIST
  1529. DOSFILE
  1530. BIOSFILE
  1531. and the following (NEAR) routines;
  1532. OEMDONE
  1533. WRITEBOOTSECTOR
  1534. CHECKSWITCHES
  1535. LASTCHANCETOSAVEIT
  1536. The detailed description of the data items required to be declared
  1537. public in the OEM's module is as follows;
  1538. SWITCHLIST
  1539. A string of bytes. The first byte is count
  1540. n, followed by n characters that are the
  1541. switches to be accepted by the command line
  1542. scanner. Alphabetic characters must be in
  1543. uppercase (the numeric characters 0-9 are
  1544. allowed). The last six switches, normally
  1545. "/N","/T","/C","/O", "/V" and "/S", have
  1546. predefined meanings.
  1547. The "/S" switch is the switch that causes the
  1548. system files IO.SYS, MSDOS.SYS, and
  1549. COMMAND.COM to be transferred to the disk
  1550. after it is formatted, thus making a system
  1551. disk. The switch can be some letter other
  1552. than "S", but the last switch in the list is
  1553. assumed to have the meaning "transfer
  1554. system," regardless of what the particular
  1555. letter is.
  1556. The second to the last switch, "/V", causes
  1557. FORMAT to prompt the user for a volume label
  1558. after the disk is formatted. As with "/S",
  1559. the particular letter is not important but
  1560. rather the position in the list.
  1561. The third to the last switch, "/O", causes
  1562. FORMAT to produce an IBM Personal Computer
  1563. DOS version 1.x-compatible disk. Normally
  1564. FORMAT causes a 0 byte to be placed in the
  1565. first byte of each directory entry instead of
  1566. the 0E5H free entry designator. This
  1567. markedly increases the performance of a
  1568. directory search due to an optimization in
  1569. the DOS. Disks made with this switch cause
  1570. trouble on IBM PC DOS 1.x versions which did
  1571. not have this optimization. The 0 byte fools
  1572. IBM 1.x versions into thinking these entries
  1573. are allocated instead of free. Note that IBM
  1574. Personal Computer DOS version 2.10 and MS-DOS
  1575. version 1.25 have no trouble with these
  1576. disks, since they have the same optimization.
  1577. The "/O" switch causes FORMAT to redo the
  1578. directory with a 0E5H byte at the start of
  1579. each entry so that the disk may be used with
  1580. 1.x versions of IBM PC DOS, as well as with
  1581. MS-DOS 1.25/2.XX and IBM PC DOS 2.00/2.10.
  1582. This switch should only be given when needed
  1583. because it takes a fair amount of time for
  1584. FORMAT to perform the conversion, and it
  1585. noticeably decreases 1.25 and 2.x performance
  1586. on disks with few directory entries.
  1587. A "/C" switch is specified for "Clear". This
  1588. switch should cause the formatting operation
  1589. to be bypassed (within DISKFORMAT or
  1590. BADSECTOR). This is provided as a
  1591. time-saving convenience to the user, who may
  1592. wish to "start fresh" on a previously
  1593. formatted and used disk.
  1594. The "/T:<xx>" option is used to specify the
  1595. number of tracks that Format will place on
  1596. a floppy disk.
  1597. The "/N:<xx>" option is used to specify the
  1598. number of sectors per track that Format will
  1599. use to format a floppy disk.
  1600. BIOSFILE & DOSFILE
  1601. The BIOSFILE and DOSFILE data strings are used to
  1602. specify the filenames for the hidden BIOS and DOS
  1603. system files written to the formatted disk when
  1604. the /s option is selected.
  1605. The filename strings should be null terminated root
  1606. directory specifications commencing with a dummy
  1607. non-zero drive letter byte which will be modified
  1608. by the FORMAT module at run-time.
  1609. eg.
  1610. BIOSFILE db "x:\IO.SYS",0
  1611. DOSFILE db "x:\MSDOS.SYS",0
  1612. The following data is declared PUBLIC in Microsoft's
  1613. FORMAT module and may be used by the OEM's module
  1614. as required.
  1615. SWITCHMAP
  1616. A WORD value with a bit vector indicating
  1617. which switches are included in the command
  1618. line. The correspondence of the bits to the
  1619. switches is determined by SWITCHLIST. The
  1620. extreme right (highest-addressed) switch in
  1621. SWITCHLIST (which must be the system transfer
  1622. switch, normally "/S") corresponds to bit 0,
  1623. the second from the right, normally "/V" to
  1624. bit 1, etc. For example, if SWITCHLIST is
  1625. the string "7,'AGI2OVS'", and the user
  1626. specifies "/G/S" on the command line, then
  1627. bit 6 will be 0 (/A not specified), bit 5
  1628. will be 1 (/G specified), bits 4,3,2 and 1
  1629. will be 0 (neither I,2,O or V specified), and
  1630. bit 0 will be 1 (/S specified).
  1631. FBIGFAT
  1632. BYTE which takes on one of two possible
  1633. values, 0 or 0FFH. WARNING: Any value other
  1634. than 0 or 0FFH will cause FORMAT to do very
  1635. odd things. The value 0 indicates that the
  1636. disk being formatted will have a 12-bit FAT.
  1637. The value 0FFH means that the disk being
  1638. formatted will have a 16-bit FAT.
  1639. DRIVE
  1640. A byte value containing the drive specified
  1641. in the command line. 0=A, 1=B, etc.
  1642. DRIVELETTER
  1643. A byte value containing the ASCII value of
  1644. the drive letter specified in the command
  1645. line.
  1646. DEVICEPARAMETES
  1647. A structue containing the device parameters of
  1648. the drive to be formatted. The format of the
  1649. DEVICEPARAMETERS data structure is as follows;
  1650. DP_SpecialFunctions : BYTE
  1651. DP_DeviceType : BYTE
  1652. DP_DeviceAttributes : WORD
  1653. DP_Cylinders : WORD
  1654. DP_MediaType : BYTE
  1655. DP_BPB : BPB
  1656. DP_TrackTableEntries : WORD
  1657. DP_sectorTable : BYTE TABLE
  1658. INBUFF
  1659. A string buffer used to return a character
  1660. string entered from the keyboard in the
  1661. user_string routine in the FORMAT module.
  1662. CURRENTHEAD
  1663. A word value containing the drive head
  1664. which was being formatted when an error
  1665. occurred.
  1666. CURRENTCYLINDER
  1667. A word value containing the drive cylinder
  1668. which was being formatted when an error
  1669. occured.
  1670. FLASTCHANCE
  1671. A byte value used to flag whether a format
  1672. message is to printed at the start of
  1673. a format attempt.
  1674. NUMSECTORS
  1675. A word value containing the number of
  1676. sectors specified in the command line
  1677. with the /n switch.
  1678. TRACKCNT
  1679. A word value containing the number of
  1680. sectors specified in the command line
  1681. with the /t switch.
  1682. The detailed description of the routines required to be declared
  1683. public in the OEM's module is as follows;
  1684. OEMDONE
  1685. This routine is called after the formatting has
  1686. been completed, the disk directory has been
  1687. initialized and the system has been transferred
  1688. if specified. It is called once for each disk to
  1689. be formatted. This gives the chance for any
  1690. finishing up operations, if needed. If the OEM
  1691. desires extra files to be put on the formatted
  1692. disk by default, or according to a switch, this
  1693. could be done in OEMDONE.
  1694. The OEMDONE routine should also check for the /b
  1695. switch and, if present, should notify the FORMAT
  1696. module of a non-standard system size by calling
  1697. the ADDTOSYSTEMSIZE routine in the FORMAT module.
  1698. The following data items form the inputs to the
  1699. OEMDONE routine;
  1700. SwitchMap : A WORD vaule indicating which
  1701. switches were selected. The
  1702. format of the SwitchMap is
  1703. as described previously.
  1704. The OEMDONE outputs should be;
  1705. Carry Flag : Set on error, else clear.
  1706. If an error status is returned
  1707. by OEMDONE, the error message
  1708. "Format failure" and a prompt
  1709. for another disk will be
  1710. displayed.
  1711. WRITEBOOTSECTOR
  1712. This routine is called once for each disk formatted
  1713. after the format has occured but prior to installing
  1714. a system on the disk.
  1715. The routine writes the OEM specific boot sector(s)
  1716. to the disk. The first boot sector must be written
  1717. to the disk with an initialized BPB. The boot code
  1718. may be contained within the OEMFOR module and copied
  1719. to the boot sectors by this routine or may be
  1720. written to the boot sectors after the format using a
  1721. separate OEM utility as long as the BPB is written
  1722. in this routine.
  1723. The functionality of the code and data required in
  1724. the boot sector(s) is discussed in detail in
  1725. section 4.4 .
  1726. If an error occurs while writing the boot sector(s)
  1727. the routine should display an error message and
  1728. return with the carry flag set.
  1729. CHECKSWITCHES
  1730. This routine is called once before any disks have
  1731. been formatted. It is used to verify that the
  1732. switches selected are a legal combination for the
  1733. drive type to be formatted and to modify the drive
  1734. device parameters according to the selected switches
  1735. if they are valid. For example the valid swith
  1736. combinations for supported drive types could be;
  1737. Disk Type Valid switches
  1738. 160/180KB /l /4 /8 /b /n /t /v /s
  1739. 320/360KB /l /4 /8 /b /n /t /v /s
  1740. 720KB /n /t /v /s
  1741. 1.2MB /n /t /v /s
  1742. Hard disk /v /s
  1743. The CHECKSWITCH routine is included in the OEMFOR
  1744. module so that the OEM may decide what action to
  1745. take for an OEM specific drive type with the switch
  1746. combination selected.
  1747. The following data items form the inputs to the
  1748. CHECKSWITCHES routine;
  1749. deviceParameters : A data structure containing
  1750. the drive parameters for the
  1751. drive to be formatted. The
  1752. fields of this structure are
  1753. as descibed previously.
  1754. SwitchMap : A WORD vaule indicating which
  1755. switches were selected. The
  1756. format of the SwitchMap is
  1757. as described previously.
  1758. NumSectors : A WORD value containing the
  1759. number of sectors specified
  1760. with the /n switch if it was
  1761. present in the command line.
  1762. NumTracks : A WORD value containing the
  1763. number of tracks specified
  1764. with the /t option if it was
  1765. present in the command line.
  1766. The CHECKSWITCHES outputs should be;
  1767. Carry Flag : Set on error, else clear.
  1768. deviceParameters : Device parameters to use in
  1769. the format operation. Should
  1770. have been modified by
  1771. CHECKSWITCES if a legal switch
  1772. combination specifies parameter
  1773. modification.
  1774. NumSectors : If the /n switch was not present
  1775. in the command line then the
  1776. CHECKSWITCHES routine should
  1777. initialize the NumSectors WORD
  1778. from the deviceParamaters
  1779. structure.
  1780. Trackcnt : If the /t switch was not present
  1781. in the command line then the
  1782. CHECKSWITCHES routine should
  1783. initialize the Trackcnt WORD
  1784. from the deviceParamaters
  1785. structure.
  1786. LASTCHANCETOSAVEIT
  1787. This routine is called when an error, other
  1788. than a write protect or not ready error,
  1789. occurs during the disk format. It gives the
  1790. OEM a chance to modify the disk parameters
  1791. to be used in the format operation. The
  1792. format will then be tried with these parameters.
  1793. An example of when this could be used is if
  1794. the format fails on the second head (track
  1795. zero), the OEM may want to try formatting
  1796. the disk single sided.
  1797. The LASTCHANCETOSAVEIT inputs are:
  1798. deviceParameters : A data structure containing
  1799. the drive parameters for the
  1800. drive being formatted when
  1801. the error occurred. The fields
  1802. of this structure are as
  1803. described previously.
  1804. currentCylinder : A WORD value indicating the
  1805. drive cylinder on which the
  1806. error occurred.
  1807. currentHead : A WORD value indicating the
  1808. drive head on which the error
  1809. occurred.
  1810. The LASTCHANCETOSAVEIT outputs should are:
  1811. Carry Flag : Set if the error was fatal and
  1812. no attempt is to be made to
  1813. re-format the drive, else clear.
  1814. deviceParameters : Modified to contain the new
  1815. parameters for the re-format,
  1816. if a re-format attempt required.
  1817. fLastChance : A BYTE value set to TRUE if an
  1818. attempt to re-format the drive
  1819. is required. This prevents
  1820. multiple format messages for
  1821. a single drive format.
  1822. The following routines are declared PUBLIC in Microsoft's
  1823. FORMAT module and may be used by the OEMFOR module
  1824. as required.
  1825. ADDTOSYSTEMSIZE
  1826. Adds to the number of sectors reserved for the system.
  1827. INPUTS : ax = size of system file in bytes.
  1828. OUTPUTS : None.
  1829. PRINTSTRING
  1830. Displays a character string.
  1831. INPUTS : dx = near pointer to null terminated string.
  1832. OUTPUTS : None.
  1833. STD_PRINTF
  1834. Displays a character string.
  1835. INPUTS : dx = near pointer to a near pointer to a
  1836. null terminated string.
  1837. OUTPUTS : None.
  1838. CRLF
  1839. Outputs a carriage return and linefeed to the console.
  1840. INPUTS : None.
  1841. OUTPUTS : None.
  1842. USER_STRING
  1843. Get a string from the keyboard.
  1844. INPUTS : None.
  1845. OUTPUTS : Zero flag set if <CR> only was enterred.
  1846. String length in BYTE at offset INBUFF + 1.
  1847. Console input in INBUFF commencing at offset
  1848. INBUFF +2.
  1849. Once the OEM-supplied module has been prepared, it must be
  1850. linked with Microsoft's FORMAT.OBJ module, and the
  1851. FORMES.OBJ module. In 3.XX, there are additional format
  1852. modules that must be linked in. If the OEM-supplied module
  1853. is called OEMFOR.OBJ, then use the following linker command;
  1854. link format forproc formes oemfor printf;
  1855. This command produces an executable file called FORMAT.EXE.
  1856. NOTE: The OEM's module CAN NOT make the assumption, as it
  1857. could in the previous versions, that it is at the "end" of
  1858. the memory image. It must use function 48h (allocate
  1859. memory) if required.
  1860. 7.3 FORMAT MODULES AND THE ES REGISTER
  1861. If an OEM-written FORMAT module, such as OEMDONE, makes use of
  1862. the ES register, the value of ES should be established by the
  1863. OEM's code. The contents of the ES register cannot be assumed.
  1864. CONTENTS
  1865. CHAPTER 7B WRITING THE FORMAT MODULE FOR MS-DOS 2.25/3.10
  1866. 7.1 Introduction 7-1
  1867. 7.2 Format Modules and the ES Register 7-9
  1868. 7.3 Changing the Logical Format of Disks 7-9
  1869. CHAPTER 7B
  1870. WRITING THE FORMAT MODULE
  1871. MS-DOS 2.25/3.10
  1872. HIGHLIGHTS OF CHANGES IN 3.XX OVER PREVIOUS 2.XX FORMAT VERSION:
  1873. o FORMAT is now designed to be an .EXE file.
  1874. o The FBIGFAT variable has been introduced for 16-bit
  1875. FAT support.
  1876. o ALLOCATEFAT routine allows space for the FAT to be
  1877. dynamically allocated.
  1878. 7.1 INTRODUCTION
  1879. The MS-DOS Format command formats a new disk, clears the FAT
  1880. and directory, and optionally copies system files and
  1881. COMMAND.COM to the new disk. Since the Format command must
  1882. perform functions that have no equivalent in MS-DOS function
  1883. calls, FORMAT is shipped in two hardware-independent object
  1884. modules. These must be linked to a hardware-specific module
  1885. written by the OEM. The following section describes the
  1886. routines required in this module. A sample OEM format
  1887. module is included on the MS-DOS release disks to assist in
  1888. writing these routines.
  1889. The syntax for the Format command is:
  1890. Format [drive:][/switch1][/switch2]...[/switch16]
  1891. "drive:" is a legal drive specification. If it is
  1892. omitted, the default drive will be used. As many as 16
  1893. legal switches can be included in the command line.
  1894. WRITING THE FORMAT MODULE Page 7-2
  1895. In 3.XX the OEM must supply six (NEAR) routines to the program along
  1896. with seven data items. In 2.XX the OEM must supply five (NEAR) routines
  1897. to the program along with six data items. The names of the routines are:
  1898. ALLOCATEFAT
  1899. INIT
  1900. DISKFORMAT
  1901. BADSECTOR
  1902. WRTFAT
  1903. DONE
  1904. ALLOCATEFAT is used only in 3.XX.
  1905. Their flow of control (by the Microsoft module) is like
  1906. this:
  1907. |
  1908. +-------------+
  1909. | ALLOCATEFAT |
  1910. +-------------+
  1911. |
  1912. +---------+
  1913. | INIT |
  1914. +---------+
  1915. |
  1916. |<------------------------------+
  1917. +------------+ |
  1918. | DISKFORMAT | |
  1919. +------------+ |
  1920. |<-------+ |
  1921. +-----------+ |-This loop is done |- This loop is
  1922. | BADSECTOR | | for each group of | done once for
  1923. +-----------+ | bad sectors | each disk to be
  1924. |----->--+ | formatted. If
  1925. | | variable HARDFLAG
  1926. +----------+ | is set then the
  1927. | | | loop is only
  1928. | WRTFAT | | performed once.
  1929. +----------+ |
  1930. | |
  1931. +------+ |
  1932. | DONE | |
  1933. +------+ |
  1934. +---->--------------------------+
  1935. The ALLOCATEFAT, INIT, DISKFORMAT, and BADSECTOR routines
  1936. are free to use any MS-DOS system calls, except for calls
  1937. that cause disk accesses on the disk being formatted. DONE
  1938. may use any calls, since by the time it is called the new ___
  1939. disk has been formatted.
  1940. WRITING THE FORMAT MODULE Page 7-3
  1941. The following data must be declared PUBLIC in a module
  1942. provided by the OEM:
  1943. SWITCHLIST
  1944. A string of bytes. The first byte is count
  1945. n, followed by n characters that are the
  1946. switches to be accepted by the command line
  1947. scanner. Alphabetic characters must be in
  1948. uppercase (the numeric characters 0-9 are
  1949. allowed). The last three switches, normally
  1950. "/O", "/V" and "/S", have pre-defined
  1951. meanings.
  1952. The "/S" switch is the switch that causes the
  1953. system files IO.SYS, MSDOS.SYS, and
  1954. COMMAND.COM to be transferred to the disk
  1955. after it is formatted, thus making a system
  1956. disk. The switch can be some letter other
  1957. than "S", but the last switch in the list is
  1958. assumed to have the meaning "transfer
  1959. system," regardless of what the particular
  1960. letter is.
  1961. The second to the last switch, "/V", causes
  1962. FORMAT to prompt the user for a volume label
  1963. after the disk is formatted. As with "/S",
  1964. the particular letter is not important but
  1965. rather the position in the list.
  1966. The third to the last switch, "/O", causes
  1967. FORMAT to produce an IBM Personal Computer
  1968. DOS version 1.x-compatible disk. Normally
  1969. FORMAT causes a 0 byte to be placed in the
  1970. first byte of each directory entry instead of
  1971. the 0E5H free entry designator. This
  1972. markedly increases the performance of a
  1973. directory search due to an optimization in
  1974. the DOS. Disks made with this switch cause
  1975. trouble on IBM PC DOS 1.x versions which did
  1976. not have this optimization. The 0 byte fools
  1977. IBM 1.x versions into thinking these entries
  1978. are allocated instead of free. Note that IBM
  1979. Personal Computer DOS version 2.10 and MS-DOS
  1980. version 1.25 have no trouble with these
  1981. disks, since they have the same optimization.
  1982. The "/O" switch causes FORMAT to redo the
  1983. directory with a 0E5H byte at the start of
  1984. each entry so that the disk may be used with
  1985. 1.x versions of IBM PC DOS, as well as with
  1986. MS-DOS 1.25/2.XX and IBM PC DOS 2.00/2.10.
  1987. This switch should only be given when needed
  1988. because it takes a fair amount of time for
  1989. WRITING THE FORMAT MODULE Page 7-4
  1990. FORMAT to perform the conversion, and it
  1991. noticeably decreases 1.25 and 2.x performance
  1992. on disks with few directory entries.
  1993. Up to 16 switches are permitted. Normally a
  1994. "/C" switch is specified for "Clear". This
  1995. switch should cause the formatting operation
  1996. to be bypassed (within DISKFORMAT or
  1997. BADSECTOR). This is provided as a
  1998. time-saving convenience to the user, who may
  1999. wish to "start fresh" on a previously
  2000. formatted and used disk.
  2001. HARDFLAG
  2002. BYTE location which specifies whether the OEM
  2003. routine is formatting a fixed disk or a drive
  2004. with removable media. A zero means removable
  2005. media; any other value indicates a fixed
  2006. disk. The status of this byte only affects
  2007. the messages printed by the main FORMAT
  2008. module. This value should be set or reset by
  2009. the OEM-supplied INIT routine.
  2010. FATID
  2011. BYTE location containing the value to be used
  2012. in the first byte of the FAT. Must be in the
  2013. range F8H to FFH.
  2014. STARTSECTOR
  2015. WORD location containing the sector number of
  2016. the first sector of the data area.
  2017. FATSPACE
  2018. WORD location containing the address of the
  2019. start of the FAT area. A FAT built in this
  2020. area will be written to disk using the
  2021. OEM-supplied WRTFAT subroutine. 6K is
  2022. sufficient to store any 12-bit FAT. This
  2023. area must not overlap the FREESPACE area.
  2024. FREESPACE
  2025. WORD location that contains the address of
  2026. the start of free memory space. This is
  2027. where the system will be loaded by the
  2028. Microsoft module for transferring to the
  2029. newly formatted disk. Memory should be
  2030. available from this address to the end of
  2031. memory, so it is typically the address of the
  2032. end of the OEM module.
  2033. WRITING THE FORMAT MODULE Page 7-5
  2034. FBIGFAT
  2035. BYTE which takes on one of two possible
  2036. values, 0 or 0FFH. WARNING: Any value other
  2037. than 0 or 0FFH will cause FORMAT to do very
  2038. odd things. The value 0 indicates that the
  2039. disk being formatted will have a 12-bit FAT.
  2040. The value 0FFH means that the disk being
  2041. formatted will have a 16-bit FAT. See
  2042. ALLOCATEFAT call, below, for details.
  2043. FBIGFAT is used only in 3.XX.
  2044. The following routines must be declared PUBLIC in the
  2045. OEM-supplied module:
  2046. ALLOCATEFAT
  2047. ALLOCATEFAT is used only in 3.XX. It is
  2048. an initialization routine. This routine is
  2049. called once at the start of the FORMAT run
  2050. after the switches have been processed. This
  2051. routine must set the correct values of
  2052. FBIGFAT, FATSPACE, and FREESPACE.
  2053. With only 12-bit FATs it was convenient to
  2054. allocate a FAT area of 6K (maximum size of a
  2055. 12-bit FAT) as part of the memory image of
  2056. FORMAT. With the advent of 16-bit FATs in
  2057. DOS 3.XX this is no longer convenient; the
  2058. maximum size of of a FAT is 32K.
  2059. ALLOCATEFAT is a dynamic space allocator that
  2060. allocates enough memory to hold the FAT by setting
  2061. the values of FATSPACE and FREESPACE.
  2062. ALLOCATEFAT must also set FBIGFAT so that
  2063. FORMAT knows whether the disk has a 12 or a
  2064. 16-bit FAT.
  2065. FBIGFAT must be set consistently with the
  2066. following FAT rule (see below).
  2067. The 16-bit FAT rule:
  2068. - Any disk with less than 4086 clusters has a ____ ____
  2069. 12-bit FAT.
  2070. - Any disk with greater than or equal to 4086 _______ ____ __ _____ __
  2071. clusters has a 16-bit FAT.
  2072. The OEM FORMAT module cannot force a 16-bit
  2073. FAT if the total number of clusters is less
  2074. than 4086. Similarly, you cannot have a
  2075. 12-bit FAT on a disk with more than 4085
  2076. clusters. If the OEM module does not set
  2077. FBIGFAT consistently with the 16-bit FAT
  2078. rule, the disk will not be formatted
  2079. correctly, and MS-DOS will not access the
  2080. disk in the proper manner.
  2081. WRITING THE FORMAT MODULE Page 7-6
  2082. Currently, there is no error return from
  2083. ALLOCATEFAT. It should exit with CARRY
  2084. CLEAR, however, so that it is consistent with
  2085. the other routines.
  2086. The Microsoft 3.XX FORMAT.OBJ is responsible for
  2087. checking that the memory needed for the FAT is
  2088. actually available to the system. It will
  2089. produce a "Insufficient memory for system transfer"
  2090. error when memory is inadequate. This error
  2091. is produced when memory is inadequate for both
  2092. "/S" and non "/S" procedures.
  2093. INIT
  2094. An initialization routine. This routine is
  2095. called once at the start of the FORMAT run
  2096. after the switches have been processed. This
  2097. routine should perform any functions that
  2098. need to be done once per FORMAT run. An
  2099. example of what this routine might do is read
  2100. the boot sector into a buffer so that it can
  2101. be transferred to the new disks by
  2102. DISKFORMAT. If this routine returns with the
  2103. CARRY flag set, it indicates an error, and
  2104. FORMAT will print "Format failure" and quit.
  2105. This feature detects conflicting switches
  2106. (like specifying both single and double
  2107. density) and causes the FORMAT routine to
  2108. abort.
  2109. DISKFORMAT
  2110. Formats the disk according to the options
  2111. indicated by the switches and the value of
  2112. FATID must be defined when it returns
  2113. (although INIT may have already done it).
  2114. This routine is called once for each disk to
  2115. be formatted. If necessary, it must transfer
  2116. the bootstrap loader. If any error
  2117. conditions are detected, the carry flag is
  2118. set. FORMAT will report a "Format failure"
  2119. and prompt for another disk. (If you only
  2120. require a clear directory and FAT, all that
  2121. DISKFORMAT must do is set the appropriate
  2122. FATID, if this has not already been done by
  2123. INIT.
  2124. BADSECTOR
  2125. Reports the sector number of any bad sectors
  2126. that may have been found during the
  2127. formatting of the disk. This routine is
  2128. called at least once for each disk to be
  2129. formatted, and is called repeatedly until the
  2130. AX register is zero or the carry flag is set.
  2131. The carry flag is used just as in DISKFORMAT
  2132. to indicate an error, and FORMAT handles it
  2133. in the same way. The first sector in the
  2134. data area must be in STARTSECTOR for the
  2135. returns from this routine to be interpreted
  2136. correctly. If there are bad sectors,
  2137. BADSECTOR must return a sector number in
  2138. WRITING THE FORMAT MODULE Page 7-7
  2139. register BX, the number of consecutive bad
  2140. sectors in register AX, and clear the carry
  2141. flag. FORMAT will then process the bad
  2142. sectors and call BADSECTOR again. When
  2143. BADSECTOR returns with AX = 0, there are no
  2144. more bad sectors; FORMAT clears the
  2145. directory and goes on to DONE. For this last
  2146. return, BX need not contain anything
  2147. meaningful.
  2148. FORMAT processes bad sectors by determining
  2149. their corresponding allocation unit and
  2150. marking that unit with an FF7H in the File
  2151. Allocation Table. CHKDSK understands the
  2152. FF7H mark as a flag for bad sectors and
  2153. accordingly reports the number of bytes
  2154. marked in this way.
  2155. Actual formatting of the disk can be done in
  2156. BADSECTOR instead of DISKFORMAT on a "report
  2157. as you go" basis. Formatting continues until
  2158. a group of bad sectors is encountered;
  2159. BADSECTOR then reports them by returning with
  2160. AX and BX set. FORMAT will then call
  2161. BADSECTOR again and formatting can continue.
  2162. WRTFAT
  2163. This routine is called after the disk is
  2164. formatted and bad sectors have been reported.
  2165. It writes all copies of the FAT from the area
  2166. of memory referenced by FATSPACE to the drive
  2167. just formatted. It may be possible to use
  2168. INT 26H to perform the write, or a direct
  2169. BIOS call. Whether this is possible depends
  2170. on whether the FAT ID byte is used by the
  2171. BIOS to determine the media in the drive. If
  2172. it is, these methods will probably fail
  2173. because there is no FATID byte on the disk
  2174. yet (in this case WRTFAT's primary job is to
  2175. get the FATID byte out on the disk).
  2176. DONE
  2177. This routine is called after the formatting
  2178. has been completed, the disk directory has
  2179. been initialized, and the system has been
  2180. transferred if specified. It is called once
  2181. for each disk to be formatted. This gives
  2182. the chance for any finishing-up operations,
  2183. if needed. If the OEM desires extra files to
  2184. be put on the disk by default, or according
  2185. to a switch, this could be done in DONE.
  2186. WRITING THE FORMAT MODULE Page 7-8
  2187. Again, as in BADSECTOR and DISKFORMAT, carry
  2188. flag set on return means an error has
  2189. occurred; "Format failure" will be printed
  2190. and FORMAT will prompt for another disk.
  2191. The following data is declared PUBLIC in Microsoft's
  2192. FORMAT module:
  2193. SWITCHMAP
  2194. A WORD value with a bit vector indicating
  2195. which switches are included in the command
  2196. line. The correspondence of the bits to the
  2197. switches is determined by SWITCHLIST. The
  2198. extreme right (highest-addressed) switch in
  2199. SWITCHLIST (which must be the system transfer
  2200. switch, normally "/S") corresponds to bit 0,
  2201. the second from the right, normally "/V" to
  2202. bit 1, etc. For example, if SWITCHLIST is
  2203. the string "7,'AGI2OVS'", and the user
  2204. specifies "/G/S" on the command line, then
  2205. bit 6 will be 0 (/A not specified), bit 5
  2206. will be 1 (/G specified), bits 4,3,2 and 1
  2207. will be 0 (neither I,2,O or V specified), and
  2208. bit 0 will be 1 (/S specified).
  2209. Bits 0,1 and 2 are the only switches used in
  2210. Microsoft's FORMAT module. These switches
  2211. are used 1) after INIT has been called to
  2212. determine if it must load the system; 2)
  2213. after the last BADSECTOR call to determine if
  2214. the system should be written, E5 directory
  2215. conversion should be done, and/or a volume
  2216. label should be asked for. INIT may force
  2217. these bits set or reset if desired (for
  2218. example, some drives may never be used as
  2219. system disk, such as hard disks). After
  2220. INIT, the "/S" bit may be turned off (but not
  2221. on, since the system was never read) if
  2222. something happens that means the system
  2223. should not be transferred.
  2224. After INIT, a second copy of SWITCHMAP is
  2225. made internally.It is used to restore
  2226. SWITCHMAP for each disk to be formatted.
  2227. FORMAT will turn off the system bit if bad
  2228. sectors are reported in the system area;
  2229. DISKFORMAT and BADSECTOR are also allowed to
  2230. change the map. However, these changes
  2231. affect only the current disk being formatted,
  2232. since SWITCHMAP is restored after each disk.
  2233. (Changes made to SWITCHMAP by INIT affect all
  2234. disks.)
  2235. WRITING THE FORMAT MODULE Page 7-9
  2236. DRIVE
  2237. A byte value containing the drive specified
  2238. in the command line. 0=A, 1=B, etc.
  2239. Once the OEM-supplied module has been prepared, it must
  2240. linked with Microsoft's FORMAT.OBJ module, and the
  2241. FORMES.OBJ module. In 3.XX, there are additional format
  2242. that must be linked in. If the OEM-supplied module is called
  2243. OEMFOR.OBJ, then use the appropriate linker command.
  2244. 2.XX LINK FORMAT.OBJ+FORMES.OBJ+OEMFOR.OBJ
  2245. 3.XX LINK FORMAT.OBJ+FORPROC.OBJ+FORMES.OBJ+OEMFOR.OBJ.PRINTF.OBJ
  2246. For 3.XX, the command produces an executable file called
  2247. FORMAT.EXE. Note that although the PRINTF.OBJ module
  2248. is the last module specified, it does not follow the
  2249. OEMFOR module in the memory image. The OEMFOR module
  2250. can still make the assumption, as it has in the past,
  2251. that it is at the "end" of the memory image.
  2252. For 2.XX, the command produces a FORMAT.EXE file which
  2253. must be changed to a simple binary. This should be done
  2254. with the following command.
  2255. EXE2BIN FORMAT.EXE FORMAT.COM
  2256. This produces the 2.XX file, FORMAT.COM.
  2257. 7.2 FORMAT MODULES AND THE ES REGISTER
  2258. If an OEM-written FORMAT module makes use of the ES
  2259. register, such as DISKFORMAT, the value of ES should be
  2260. established by the OEM's code. The contents of the ES
  2261. register cannot be assumed.
  2262. WRITING THE FORMAT MODULE PAGE 7-10
  2263. 7.3 CHANGING THE LOGICAL FORMAT OF DISKS
  2264. MS-DOS has an internal table which it builds from
  2265. information returned by the BIOS BUILDBPB routine.
  2266. There is a table maintained for each drive within the
  2267. system and it is updated to reflect the media type
  2268. whenever a new disk is loaded. Before any access to
  2269. the disk directory, MS-DOS calls the BIOS MEDIACHECK
  2270. routine. If a disk change is reported, MS-DOS calls
  2271. the BIOS BUILDBPB routine to get the new media
  2272. information and updates its internal table. It is
  2273. important to realize that MS-DOS operates with its own
  2274. table and not with any table within the BIOS.
  2275. FORMAT can be used to physically reformat the disk from
  2276. single to double-sided use. Therefore, the WRTFAT
  2277. routine should ensure that the next call to the BIOS
  2278. MEDIA CHECK/BUILD BPB routines made by the DOS will set
  2279. the media type to the type just formatted. This is
  2280. because when the format operation is started, the DPB
  2281. (Drive Parameter Block) reflects the media that existed
  2282. before the format. This may need to be changed because
  2283. the disk media may have been changed due to the format
  2284. process. Since this is basically a communication
  2285. between the OEM part of the FORMAT utility and the OEM
  2286. BIOS, it is up to the OEM to determine the most
  2287. efficient and appropriate way to determine the correct
  2288. media type. As an example, the FORMAT utility can call
  2289. the BIOS and cause the BIOS to return "media changed"
  2290. on the next MEDIA CHECK call made by the DOS. The DOS
  2291. will then call the BUILDBPB BIOS routine; it must
  2292. return the correct BPB for the disk just formatted.
  2293. Trying to determine media change externally with the
  2294. FORMAT utility calling the DOS will not work. You
  2295. must:
  2296. o Have the correct BPB in the BIOS, and your
  2297. FORMAT utility must communicate that
  2298. information down to your BIOS, or
  2299. o Your BIOS must detect that the disk has been
  2300. changed when the FORMAT utility is used.
  2301. Then, the BIOS can look on the disk for the
  2302. BPB and tell the DOS what the new BPB is.
  2303. The OEM may decide how this can be structured. The
  2304. BIOS can be in control and inform FORMAT what was done,
  2305. or FORMAT can be in control and inform the BIOS that
  2306. the media has changed.
  2307. There is an example of an OEM written FORMAT module on the
  2308. Sample MS-DOS Implementation Diskette.
  2309. CONTENTS
  2310. CHAPTER 8 TROUBLE-SHOOTING
  2311. CHAPTER 8
  2312. TROUBLE-SHOOTING
  2313. The following section addresses typical problems that you
  2314. may encounter when installing MS-DOS.
  2315. Problem:
  2316. When I type "r" for Retry when a disk error occurs, the
  2317. system crashes.
  2318. Typical Cause:
  2319. When an error occurs during I/O, your device driver
  2320. must report the number of sectors or characters
  2321. correctly transferred. If you just set the error bit,
  2322. MS-DOS will assume that it was able to read all of the
  2323. sectors since the sector count will be the same as that
  2324. set by MS-DOS.
  2325. Recommendation:
  2326. Report the actual number of sectors/bytes transferred
  2327. in addition to reporting the error.
  2328. Problem:
  2329. I am booting up MS-DOS. I see the MS-DOS copyright
  2330. message on the screen, but then I get the message "Bad
  2331. or missing command interpreter."
  2332. Typical Cause:
  2333. SYSINIT is executing COMMAND.COM. This is the
  2334. conclusion of MS-DOS initialization and is the first
  2335. time that the disk must be read successfully. (Failure
  2336. to find CONFIG.SYS is not an error.) Either COMMAND.COM
  2337. is not on the disk or an invalid Bios Parameter Block
  2338. (BPB) has been returned to MS-DOS so it does not
  2339. correctly understand the format of the disk.
  2340. TROUBLE-SHOOTING Page 8-2
  2341. Recommendation:
  2342. Check that the correct BPB is being returned and that
  2343. COMMAND.COM is on disk. Install debugging code in the
  2344. device driver to make sure requests to the device
  2345. driver make sense.
  2346. Problem:
  2347. I am booting up MS-DOS. I get the MS-DOS copyright
  2348. message on the screen, but then I get the message "Bad
  2349. or missing /DEV/CON."
  2350. Typical Cause:
  2351. SYSINIT has closed all file handles and is now
  2352. reopening them. The first file it opens is /DEV/CON,
  2353. which is your console device. The system file table is
  2354. examined for this device. /DEV/CON should be present.
  2355. If it is not found, some of your IO.SYS code has
  2356. destroyed the system file table or MS-DOS itself. This
  2357. may happen if you have blown the MS-DOS stack, causing
  2358. MS-DOS to write over the file table.
  2359. Recommendation:
  2360. Use a local stack in your device drivers.
  2361. Problem:
  2362. MS-DOS is trying to read some sectors starting at an
  2363. extremely large or invalid sector number.
  2364. Typical Cause:
  2365. The BPB that you returned for the drive is bad.
  2366. Recommendation:
  2367. The INIT and BUILD BPB device driver routines should be
  2368. checked.
  2369. Problem:
  2370. After I jump to SYSINIT, control never comes back.
  2371. Typical Cause 1:
  2372. You may not have loaded MS-DOS correctly with your
  2373. bootstrap loader. SYSINIT must know exactly where
  2374. MS-DOS is. MS-DOS must be on a paragraph boundary and
  2375. CURRENT_DOS_LOCATION and FINAL_DOS_LOCATION must be
  2376. set up accordingly.
  2377. TROUBLE-SHOOTING Page 8-3
  2378. Recommendation:
  2379. Check the location of MSDOS.SYS after bootstrap
  2380. loading.
  2381. Typical Cause 2:
  2382. You are incorrectly reporting the amount of memory in
  2383. the system or the memory scan is failing because of a
  2384. discontinuity.
  2385. Recommendation:
  2386. Don't move MS-DOS after bootstrap loading. Don't
  2387. request a memory scan. Make sure memory is contiguous.
  2388. Typical Cause 3:
  2389. MS-DOS can't find the beginning of the device list.
  2390. Recommendation:
  2391. Check the value passed to SYSINIT to make sure that it
  2392. is the correct value for the beginning of the list.
  2393. Typical Cause 4:
  2394. The driver attributes are wrong. MS-DOS will not look
  2395. for the end of list mark if the attributes are wrong.
  2396. Recommendation:
  2397. Check the device driver attribute words.
  2398. Typical Cause 5:
  2399. You do not have a driver in the linked list of device
  2400. drivers with the CLOCK attribute bit set. This is
  2401. necessary before SYSINIT will start looking for FFFF,
  2402. FFFF in the last device driver.
  2403. Recommendation:
  2404. Be sure you have a CLOCK device in your linked list
  2405. with its attribute word set properly.
  2406. Problem:
  2407. Everything was working great, but when I tried to
  2408. install a new device, the system wouldn't boot.
  2409. Typical Cause:
  2410. You are failing to set the BREAK ADDRESS during the
  2411. TROUBLE-SHOOTING Page 8-4
  2412. device INIT routine. This points to the first byte of
  2413. free memory after the device code and data.
  2414. Recommendation:
  2415. Set the break address.
  2416. Problem:
  2417. Everything works OK until I define a new drive in
  2418. IO.SYS. Then the system won't come up.
  2419. Typical Cause:
  2420. You are returning invalid data from the INIT call to
  2421. the block device driver.
  2422. Recommendation:
  2423. Examine the INIT call. This is probably not being
  2424. handled correctly. You should return a DWORD pointer
  2425. to an array of WORD POINTERS to BPBs. The array must be
  2426. below the 'break address' returned by INIT. There should
  2427. be one array element for each drive defined. The number
  2428. of subunits is also returned by the INIT call.
  2429. Problem:
  2430. My device driver defines two drives, but when I try to
  2431. use drive B, I get an "Invalid drive specification"
  2432. message.
  2433. Typical Cause:
  2434. You are not handling the INIT call to the device driver
  2435. properly.
  2436. Recommendation:
  2437. The INIT call should return the value "2" at offset 13
  2438. from the beginning of the static request header.
  2439. Problem:
  2440. When I have a single-sided disk in drive B and remove
  2441. it and install a double-sided disk, MS-DOS treats the
  2442. double-sided disk like a single-sided disk. I am
  2443. returning the correct BPB for the double-sided disk.
  2444. Typical Cause:
  2445. The media bytes in the BPBs are not unique.
  2446. Recommendation:
  2447. TROUBLE-SHOOTING Page 8-5
  2448. Each BPB has a unique media byte. MS-DOS will not
  2449. rebuild its internal DPB structure if the media byte
  2450. doesn't change.
  2451. Problem:
  2452. I have a one-drive system. When I type B:<Return>, I
  2453. get an "Invalid drive specification" message, but on
  2454. some single-drive machines, MS-DOS prompts me for the
  2455. "disk for drive B:."
  2456. Typical Cause:
  2457. The INIT call is only defining one disk drive and
  2458. support for swapping has not been implemented in
  2459. IO.SYS.
  2460. Recommendation:
  2461. Support for disk swapping is implemented at the IO.SYS
  2462. file level rather than at the MS-DOS level. The driver
  2463. reports two drives and when it sees a request for unit
  2464. 1 (the second drive), it prints the swap message
  2465. directly on the screen.
  2466. Problem:
  2467. Everything is running fine, but when I run Chkdsk I
  2468. find that I only have 60K bytes free, but I have a 128K
  2469. machine. I know that DOS and IO.SYS only take up 24K.
  2470. What is happening to the missing bytes?
  2471. Typical Cause:
  2472. The Block Device Driver INIT call is returning a bad
  2473. BPB pointer which reports an absurdly large sector
  2474. size. This sector size is used to make all of the
  2475. sector buffers, and consequently wastes thousands of
  2476. bytes. You could have incorrectly set FINAL_DOS_LOCATION
  2477. or installed a device driver that returned an 'absurdly
  2478. large' break address.
  2479. Recommendation:
  2480. Fix the block device driver INIT call.
  2481. Problem:
  2482. Every time I try to do an Allocate Memory call
  2483. (Function 48H) or an EXEC call, I get a return code of
  2484. 8, "Not enough memory."
  2485. Typical Cause:
  2486. There is no free memory.
  2487. TROUBLE-SHOOTING Page 8-6
  2488. Recommendation:
  2489. Do a Set Block (Function 4AH) call to shrink the size
  2490. of the currently allocated block, freeing some memory.
  2491. See the section on arenas in the Glossary.
  2492. Problem:
  2493. When running a program that opens a number of files via
  2494. Function Request 3DH, the file open fails even though
  2495. the file is present on the disk.
  2496. Typical Cause:
  2497. You have run out of entries in the system file table.
  2498. Recommendation:
  2499. Increase the "FILES = " entry in CONFIG.SYS and reboot.
  2500. Problem:
  2501. Control-S, Control-P, and the other control characters
  2502. seem to be ignored by MS-DOS.
  2503. Typical Cause:
  2504. The non-destructive console read routine is not
  2505. implemented properly.
  2506. Recommendation:
  2507. Check the non-destructive read routine in the console
  2508. or other character driver where this problem is
  2509. occurring.
  2510. Problem:
  2511. Sometimes when I am typing a long file to the screen
  2512. and press Control-S, the Control-S is ignored and
  2513. doesn't stop the scrolling of the file. I have the
  2514. same problem with Control-C.
  2515. Typical Cause:
  2516. Another character has been typed into the type-ahead
  2517. buffer first, and the nondestructive read keyboard
  2518. status check never sees the Control-S or the Control-C.
  2519. Recommendation:
  2520. Implement Scroll Lock and Break keys which flush the
  2521. TROUBLE-SHOOTING Page 8-7
  2522. input queue and put the Control-S/Control-C at the
  2523. beginning of the type-ahead buffer.
  2524. Problem:
  2525. I am trying to use EXE2BIN to convert IO.EXE to IO.SYS.
  2526. I get the message "File cannot be converted."
  2527. Typical Cause:
  2528. You have a "SEGMENT AT NNNN" statement and there is
  2529. code or initialized data in that segment. You may also
  2530. have a stack segment, which is not permitted.
  2531. Recommendation:
  2532. Remove the "SEGMENT AT" statement or remove code or
  2533. initialized data from the segment.
  2534. It is possible, if your code contains FAR references, that
  2535. EXE2BIN may request a 'Fixup' address. If your IO.SYS will
  2536. always be loaded at the same place in memory, this may be
  2537. OK. Check your FAR references in any case.
  2538. APPENDIX A
  2539. CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION
  2540. A.1 CUSTOMIZING MS-DOS
  2541. Many manufacturers find it necessary to customize MS-DOS (as
  2542. distinct from IO.SYS) to some degree. The function key
  2543. table and OEM serial number are often modified. The
  2544. function key table is found in the DOSMES.ASM file. Extensive
  2545. modification to this table may require modifying the line
  2546. input routines in STRIN.ASM, which is available to source
  2547. licensees only.
  2548. OEM Serial Numbers:
  2549. Each OEM is eligible for a unique OEM Serial Number. The Series
  2550. is 0 to FF (255). IBM is 00 and we are currently at about 50H
  2551. on list.
  2552. These numbers are assigned sequentially by MS-DOS Product Marketing
  2553. as requested through the OEM's Account Manager.
  2554. Once the OEM has this number they can modify the default FF
  2555. value in the file DOSMES.ASM that is part of the adaptation
  2556. kit. If this is done, when MSDOS.SYS file is built
  2557. it will the right value.
  2558. It can be patched after they MSDOS.SYS is built by following
  2559. the instructions in the README.DOC on the MS-DOS DISTRIBUTION
  2560. DISKETTES.
  2561. Function Request 30H - Get MS-DOS Version Number will
  2562. return the version of the DOS that is being run, the OEM
  2563. Serial number and the OEM user number.
  2564. To implement OEM user number concept properly each individual
  2565. disk shipped should have to have a separate user number patched
  2566. in according to the directions in the README.DOC on the
  2567. MS-DOS DISTRIBUTION DISKETTES.
  2568. The OEM serial number can, however, be used without using the
  2569. OEM User Number.
  2570. With these numbers properly installed, an application program
  2571. could tell which version of MS-DOS was being run, which
  2572. OEM had sold it and which customer had bought it.
  2573. Internationalization may also require customizing MS-DOS.
  2574. The file named DOSMES.ASM contains a case conversion routine
  2575. and a table used to translate foreign characters into their
  2576. uppercase equivalents. This routine defaults to no case
  2577. conversion, and a sample for the IBM PC character set is
  2578. included. Note that this table is country-dependent. You
  2579. should not translate a lowercase character available on the
  2580. keyboard into a uppercase equivalent that is not on the ___
  2581. keyboard. For example, in France, translate lowercase c
  2582. cedilla into uppercase C (not C cedilla); in Germany,
  2583. translate lowercase "a umlaut" into uppercase A umlaut.
  2584. DOSMES.ASM also contains country-dependent tables used by
  2585. the international system call (Function 38H). MS-DOS
  2586. utilities and COMMAND.COM make two system calls to determine
  2587. time and date formats and the location of the case
  2588. conversion routine. You may supply as many tables as you
  2589. wish; however, it is not necessary to supply tables for all
  2590. countries in all translations. You should include tables
  2591. for all countries into which a language translation is
  2592. distributed. For example, French might include tables for
  2593. France, Belgium, and Switzerland. All versions should
  2594. include a U.S. table as well. There is a pointer in
  2595. DOSMES.ASM to the table to which MS-DOS should default if
  2596. the user specifies no "COUNTRY =" parameter in CONFIG.SYS.
  2597. Country numbers follow the information telephone codes where
  2598. two-digit numbers are employed.
  2599. CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page A-2
  2600. A non-ASCII character text is represented by variables
  2601. equated at the beginning of the file. These default to the
  2602. IBM PC character set. If your character set is different,
  2603. redefine the equates and reassemble, linking the message
  2604. file with the code files.
  2605. The SORTMES.ASM file contains a table for collating
  2606. sequences. This defaults to no mapping; all uppercase
  2607. ASCII is sorted before all lowercase ASCII. A sample table
  2608. for the IBM PC character set is included. Note that there
  2609. is no capability for equating a single character to a
  2610. multiple character string or vice versa. Therefore, German
  2611. implementations cannot equate an umlaut to "ae", but may
  2612. choose to equate it to "a" or have it fall between "a" and
  2613. "b".
  2614. A.2 EXTENDED CHARACTER SET (ECS) CONSIDERATIONS - MS-DOS 2.25
  2615. All ECS characters are two-byte quantities which also display as two
  2616. physical character positions (double-written) on the screen and
  2617. printer. This imposes some constraints on the IO.SYS keyboard and
  2618. screen drivers. MS-DOS ensures that 16-bit ECS characters are treated
  2619. as a single logical character from the user's standpoint, rather
  2620. than being confused for two characters.
  2621. CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page A-3
  2622. A.3 INPUT
  2623. On input, it is the responsibility of IO.SYS to pass ECS
  2624. characters to MS-DOS. IO.SYS must handle all
  2625. Kata-kana-to-ECS conversion or any other method used to
  2626. enter ECS. IO.SYS always places both bytes of the ECS
  2627. character into its buffer at once; however, they are passed
  2628. to MS-DOS as if they are two separate single-byte
  2629. characters. Therefore, even non-interrupt-driven keyboards
  2630. should always have the second byte of the ECS character
  2631. waiting by the time the first byte is accepted by MS-DOS.
  2632. IO.SYS should never pass an invalid ECS sequence to
  2633. MS-DOS.
  2634. A.4 OUTPUT
  2635. On output, IO.SYS must identify the first byte of an ECS
  2636. character, set a flag, and wait for the second byte. Once
  2637. the entire ECS character has been received, IO.SYS indexes
  2638. into the font table. The font table may be in memory, on
  2639. disk, or in a combined memory-disk caching scheme. IO.SYS
  2640. may call MS-DOS to read font files stored on the disk in
  2641. MS-DOS format. These files should be opened in IO.SYS when
  2642. control is passed back to RE_INIT, after MS-DOS has been
  2643. initialized.
  2644. IO.SYS performs error recovery in case the font files are on
  2645. a disk that has been removed. Door lock detection is most
  2646. helpful here. Files should be reopened whenever the
  2647. potential for a changed disk occurs. MS-DOS screen and
  2648. keyboard routines are not reentrant, and cannot be called
  2649. from within IO.SYS to facilitate recovery from this error.
  2650. A solution to the problem of missing font files is to
  2651. display all ECS characters for which no font is in memory
  2652. as double-width reverse video blanks.
  2653. IO.SYS also must perform error handling in the data stream
  2654. where an invalid ECS sequence is sent. Although invalid
  2655. characters should never be input from the keyboard, they can
  2656. be output by several occurrences:
  2657. 1. The user can display a garbage file, such as a
  2658. binary executable file.
  2659. 2. A program may have executed a file with bad ECS
  2660. data.
  2661. 3. The manipulation of fixed length fields may have
  2662. split a ECS character between its two bytes.
  2663. CUSTOMIZATION OF MS-DOS AND INTERNATIONALIZATION Page A-4
  2664. If any of these occur, the recommended procedure is to
  2665. display a double-width reverse video blank character
  2666. followed by the single-byte ASCII value for the character
  2667. outside of the valid second-byte range. This will help to
  2668. resynchronize the data stream as soon as possible.
  2669. MS-DOS recognizes double-byte values, such as blank space,
  2670. over ECS in its line editing procedures. It also will
  2671. accept and display (if appropriate) the second byte where a
  2672. single-byte response is anticipated ("Strike any key").
  2673. IO.SYS should ensure that a ECS character is never split
  2674. across the last column of one physical line and the first
  2675. column of the next line. The entire ECS character must
  2676. start on the next line. IO.SYS must keep a flag for each
  2677. line to determine whether one or two logical backspace
  2678. operations should be performed. The "Backspace-Space-
  2679. Backspace" destructive operation issued by MS-DOS will work
  2680. properly.
  2681. For example, starting with column 1, assume that text runs
  2682. up to and includes column 79. MS-DOS requests that a
  2683. double-byte ECS character be displayed. IO.SYS:
  2684. 1. Blanks column 80.
  2685. 2. Sets a flag for that physical line.
  2686. 3. Moves to the beginning of the next line.
  2687. 4. Displays both bytes.
  2688. MS-DOS requests two backspaces over this ECS character.
  2689. If a third backspace is issued, IO.SYS must clear the flag
  2690. and perform an extra backspace, returning to column 79
  2691. instead of 80. If a space is issued, column 79 will be
  2692. blanked. Remember that column 80 was originally blank, so
  2693. there is no need to reset it.
  2694. If the ANSI screen driver is also implemented, the driver
  2695. should never allow only one-half of a ECS character to be
  2696. block transferred without blanking it in scrolling regions.
  2697. This rule also applies to both the region being moved and
  2698. the area into which it is being moved.
  2699. APPENDIX B
  2700. HOW TO UPGRADE A 2.XX BIOS TO 3.XX
  2701. MS-DOS 3.XX provides very few new services that impact device
  2702. drivers. The basic BIOS mechanisms are identical to those
  2703. in MS-DOS 2.XX. The only changes are that a few new device
  2704. driver calls have been added. These calls are not required. ___
  2705. There are new device attribute bits that indicate the
  2706. presence of these new functions. Old device drivers do not
  2707. have these bits set, and thus indicate that the functions
  2708. are not present.
  2709. There are several new CONFIG.SYS commands. The code for
  2710. these is contained in the SYSINIT modules, and there are no
  2711. new PUBLICs in SYSINIT, or expected EXTERNs in the BIOS.
  2712. First, to quickly bring up MS-DOS 3.XX with a 2.XX set of
  2713. device drivers, all that you need to do is build a new BIOS
  2714. with the new 3.XX SYSINIT and SYSIMES modules in the same way
  2715. that the 2.XX BIOS was built. This will produce a perfectly
  2716. functional BIOS, but none of the devices will have any of
  2717. the new 3.XX functions implemented.
  2718. Since you have not modified your BIOS, you cannot support
  2719. the following features:
  2720. 1. The IOCTL is Changeable (Function 4408H) call.
  2721. This is useful for FORMAT and other programs that
  2722. want to prompt for a change of media.
  2723. 2. The character device OPEN and CLOSE device driver
  2724. calls. These are useful for flushing
  2725. interrupt-driven I/O.
  2726. 3. The background print utility spooling to a network
  2727. printer.
  2728. 4. Output-until-busy device driver call for
  2729. PRINT/PSPRINT spool devices.
  2730. HOW TO UPGRADE A 2.XX BIOS TO 3.XX Page B-2
  2731. 1. IOCTL Is Changeable Call
  2732. The IOCTL Is Changeable (Function 4408H) call is
  2733. fairly easy to implement. Set the appropriate bit
  2734. in the device-attribute word for your block device
  2735. drivers, and add the necessary code to return the
  2736. particular value for your floppies and hard disks.
  2737. 2. OPEN and CLOSE calls
  2738. OPEN and CLOSE device driver calls are needed only ____
  2739. if you have interrupt-driven I/O. If you omitted
  2740. this feature, then you have nothing to do. If you
  2741. support interrupt-driven I/O, set the appropriate
  2742. bit in the attribute word for your character device
  2743. driver and add the necessary code to wait until
  2744. your buffers are empty.
  2745. ____________________________________________________________
  2746. | |
  2747. | Note |
  2748. | |
  2749. | The same bit in the attribute word is used to indicate |
  2750. | that Is-Removable and OPEN/CLOSE is present. This |
  2751. | means that you must put in NO-OP stubs for those |
  2752. | functions you will not use (simply return with no error |
  2753. | for OPEN/CLOSE). MS-DOS assumes that all three of |
  2754. | these new functions exist if this attribute bit is set. |
  2755. | |
  2756. |__________________________________________________________|
  2757. 3. Background Print Utility
  2758. The third feature (background print spooling to a
  2759. network printer) is difficult to implement. You
  2760. MAY need to add code to the output loop of the
  2761. character device driver that tells the network
  2762. portion of MS-DOS that you sent a character to a
  2763. particular device. You will also need to modify
  2764. the code in NETPS (part of the Redirector) to
  2765. receive this input. The skeleton code in NETPS is
  2766. for INT 17H (output-to-printer) on the IBM PC. So
  2767. there is NO SPECIAL CODE in the IBM PC printer
  2768. device drivers as everything is handled by INT 17H.
  2769. Your architecture may require a different mechanism.
  2770. You may wish to use the INT 2FH mechanism to achieve
  2771. this.
  2772. If your architecture doesn't provide for Redirection
  2773. at the ROM BIOS entry level (INT 17H on the IBM PC),
  2774. your added code in the device driver will signal
  2775. the network piece that you have a character
  2776. destined for a particular device. The network
  2777. piece will decide whether or not that output should
  2778. be routed across the network. If so, it will
  2779. handle the character and return an indication that
  2780. the character was handled. Otherwise, it will
  2781. indicate that the device driver should take care of
  2782. HOW TO UPGRADE A 2.XX BIOS TO 3.XX Page B-3
  2783. it. After this call in the device driver, the code
  2784. should examine the return to see if the device
  2785. driver should process the character or return. The
  2786. code required to do this is quite small, typically
  2787. less than 100 bytes.
  2788. There is more information about how this is done
  2789. in the Redirector Adaptation Guide that is available
  2790. on the MS-NET distribution diskette.
  2791. 4. Output-Until-Busy Call
  2792. The fourth feature is a new device call that helps
  2793. the performance of the PRINT and PSPRINT
  2794. (networking print) utilities. Most printers have
  2795. RAM buffers which typically hold a line of
  2796. characters or some fixed amount of characters.
  2797. These buffers fill up without the printer going
  2798. busy. This yields a "burst" type of behavior. A
  2799. line of characters can be very quickly output to
  2800. the printer, then the printer goes busy for a long
  2801. time while the characters are being printed. This
  2802. new device call allows the background spooling
  2803. programs PRINT and PSPRINT to use this burst
  2804. behavior efficiently. Rather than take the
  2805. overhead of a device driver call for each
  2806. character, or risk getting "stuck" in the device
  2807. driver outputting a block of characters, this call
  2808. allows a burst of characters to be output without
  2809. getting stuck in the device driver waiting for the
  2810. device to come ready.
  2811. APPENDIX C
  2812. HOW TO UPGRADE A 3.10 BIOS TO 3.20
  2813. The major change in the MS-DOS 3.2 BIOS is in the device drivers.
  2814. The device drivers provide the support for the new Generic IOCTL
  2815. requests. If some of the new MS-DOS 3.2 features are going to be
  2816. used, then the Generic IOCTL functions have to implemented in the
  2817. device drivers. For example, the new MS-DOS 3.2 FORMAT utility
  2818. has been designed to be hardware independent and uses Generic IOCTL's
  2819. extensively. If the Generic IOCTL's are implemented in the device
  2820. drivers, then the OEM will not have to modify the FORMAT utility.
  2821. Refer to the MS-DOS 3.2 Device Drivers Guide and the MS-DOS 3.2
  2822. Technical Guide for a complete listing of the use of Generic IOCTL's.
  2823. NOTE: Old device drivers will still work under MS-DOS 3.2 without
  2824. the Generic IOCTL's, but will not get the benefit of this feature.
  2825. The MS-DOS 3.2 BIOS makes use of a new data structure called
  2826. the Block Data Structure (BDS). The BDS is listed in the file
  2827. MSBDS.ASM in the sample BIOS disk. This data structure describes
  2828. the characteristics of a physical block device. The BDS is filled
  2829. in at BIOS initialization time. The physical characteristics
  2830. within the BDS can be changed after initialization time by using the
  2831. DRVPARM option in the CONFIG.SYS file. Any block device drivers that
  2832. have the special MS-DOS 3.2 version bit set in the attribute word
  2833. must contain a BDS. The BDS in the device driver will be linked with
  2834. the other BDS's of the system at initialization time.
  2835. The BDS structure must be used if the Generic Device Driver (DRIVER.SYS)
  2836. is to used in the OEM's system.
  2837. The MS-DOS 3.2 BIOS has extended the concept of logical drives.
  2838. There can now be more than one logical drive associated with each physical
  2839. drive. This logical drive mapping is achieved by using the Generic Device
  2840. Driver, DRIVER.SYS.
  2841. The extension of logical drives has prompted the idea of "Present Physical
  2842. Drive Owner". The Present Physical Drive Owner is the last logical drive
  2843. to have accessed a physical drive. This is an important concept because
  2844. when a reference is made to a logical drive that is NOT the Present
  2845. Physical Drive Owner, the BIOS displays the following message:
  2846. Insert diskette for drive d: and strike
  2847. any key when ready
  2848. where d: is the logical drive that was referenced. The Present Physical
  2849. Drive Owner is stored in the BDS for the particular physical drive.
  2850. Two new IOCTL calls have been introduced in connection with logical
  2851. drives. The new calls are GET/SET LOGICAL DRIVE MAP. These two IOCTL's
  2852. are important for applications that want to control the printing of the
  2853. message to swap disks. The message to swap disks will only be displayed
  2854. if the Present Physical Drive Owner is not the same as the logical drive
  2855. being referenced. Applications that want to control the printing of this
  2856. message (for example, full screen applications that want to display
  2857. the swap disk message in a dialogue box) would use these calls to get and
  2858. set the Present Physical Drive Owner.
  2859. APPENDIX D
  2860. This material was taken from the MS-DOS 3.20 Programmer's Reference
  2861. Manual. It is intended be used with the MS-DOS 2.XX/3.XX Adaptation
  2862. Guide.
  2863. CHAPTER 2
  2864. MS-DOS DEVICE DRIVERS
  2865. 2.1 INTRODUCTION
  2866. The IO.SYS file is composed of the "resident" device
  2867. drivers, and forms the MS-DOS BIOS. MS-DOS calls upon these
  2868. resident drivers to handle I/O requests initiated by
  2869. application programs.
  2870. One of the most powerful features of MS-DOS is that it lets
  2871. you add new devices such as printers, plotters, or mouse
  2872. input devices without rewriting the BIOS. The MS-DOS BIOS
  2873. is "configurable;" that is, you can add and preempt new
  2874. drivers and existing drivers. You can also add non-resident
  2875. device drivers at boot time by using the "DEVICE =" entry in
  2876. the CONFIG.SYS file. In this section, these non-resident
  2877. drivers are referred to as "installable" to distinguish them
  2878. from drivers which, in the IO.SYS file, are considered as
  2879. the resident drivers.
  2880. At boot time, a minimum of five resident device drivers must
  2881. be present. These drivers are in a linked list. The
  2882. "header" of each driver contains a DWORD pointer to the
  2883. next. The last driver in the chain has an end-of-list
  2884. marker of -1, -1 (all bits on).
  2885. Each driver in the chain has two entry points--the strategy
  2886. entry point and the interrupt entry point. MS-DOS does not
  2887. take advantage of the two entry points. Instead, it first
  2888. calls the strategy routine, then immediately calls the
  2889. interrupt routine.
  2890. The dual entry points are provided for future multitasking
  2891. versions of MS-DOS. In multitasking environments, I/O must
  2892. be asynchronous; to accomplish this, the strategy routine
  2893. will be called to (internally) queue a request and return
  2894. quickly. It is then the responsibility of the interrupt
  2895. routine to perform the I/O at interrupt time by getting
  2896. requests from the internal queue and processing them. When
  2897. a request is completed, the interrupt routine flags it as
  2898. "done." MS-DOS periodically scans the list of requests,
  2899. looking for those requests with done flags, and "wakes up"
  2900. MS-DOS DEVICE DRIVERS Page 2-2
  2901. the process that is waiting for the completion of the
  2902. request.
  2903. When requests are queued in this manner, it is no longer
  2904. sufficient to pass I/O information in registers, since many
  2905. requests may be pending at any one time. Therefore, the
  2906. MS-DOS device interface uses "packets" to pass request
  2907. information. These request packets vary in size and format
  2908. and are composed of two parts:
  2909. 1. The static request header section, which has the
  2910. same format for all requests.
  2911. 2. A section that has information specific to the type
  2912. of request.
  2913. A driver is called with a pointer to a packet. In
  2914. multitasking versions, this packet will be linked into a
  2915. global chain of all pending I/O requests maintained by
  2916. MS-DOS.
  2917. MS-DOS does not implement a global or local queue. Only one
  2918. request is pending at any one time. The strategy routine
  2919. must store the address of the packet at a fixed location,
  2920. and the interrupt routine, which is called immediately after
  2921. the strategy routine, should process the packet by
  2922. completing the request and returning. MS-DOS assumes that
  2923. the request is complete when the interrupt routine returns.
  2924. To make a device driver that SYSINIT can install, you must
  2925. create a .BIN (core image) or .EXE format file that contains
  2926. the device driver header at the beginning of the file. The
  2927. link field should be initialized to -1 (SYSINIT fills it
  2928. in). Device drivers that are part of the BIOS should have
  2929. their headers point to the next device in the list and the
  2930. last header should be initialized to -1,-1. The BIOS must
  2931. be a .BIN (core image) format file.
  2932. If you have a non-IBM compatible version of MS-DOS 2.x, you
  2933. can use installable device drivers that are in .EXE format.
  2934. On the IBM PC (or compatible) DOS 2.x versions, the .EXE
  2935. loader is located in COMMAND.COM, which is not present at
  2936. the time that MS-DOS is loading the installable devices.
  2937. 2.2 FORMAT OF A DEVICE DRIVER
  2938. A device driver is a program segment responsible for
  2939. communication between DOS and the system hardware. It has a
  2940. special header at the beginning identifying it as a device
  2941. driver, defining its entry points, and describing its
  2942. various attributes.
  2943. MS-DOS DEVICE DRIVERS Page 2-3
  2944. ------------------------------------------------------------
  2945. | |
  2946. | Note |
  2947. | |
  2948. | For device drivers, the file must not use the ORG 100H |
  2949. | (like .COM files). Because it does not use the Program |
  2950. | Segment Prefix, the device driver is simply loaded; |
  2951. | therefore, the file must have an origin of zero (ORG 0 |
  2952. | or no ORG statement). |
  2953. | |
  2954. |__________________________________________________________|
  2955. There are two kinds of device drivers:
  2956. 1. Character device drivers
  2957. 2. Block device drivers
  2958. Character devices perform serial character I/O. Examples
  2959. are the console, communications port, and printer. These
  2960. devices have specific names (i.e., CON, AUX, CLOCK, etc.),
  2961. and programs may open channels (handles or FCBs) to send I/O
  2962. to them.
  2963. Block devices are the "disk drives" on the system. They can
  2964. perform random I/O in structured pieces called blocks
  2965. (usually the physical sector size). These devices are not
  2966. named as the character devices are, and therefore cannot be
  2967. opened directly. Instead they have unit numbers and are
  2968. identified by drive letters such as A, B, and C.
  2969. A single block device driver may be responsible for one or
  2970. more logically contiguous disk drives. For example, the
  2971. block device driver ALPHA may be responsible for drives A,
  2972. B, C, and D. This means that it has four units defined
  2973. (0-3). The position of the driver in the list of all
  2974. drivers determines which units correspond to which drive
  2975. letters. For example, if driver ALPHA is the first block
  2976. driver in the device list, and it defines 4 units (0-3),
  2977. then they will be A, B, C, and D. If BETA is the second
  2978. block driver and defines three units (0-2), then they will
  2979. be E, F, and G, and so on. The theoretical limit is 63, but
  2980. the device installation code does not allow the installation
  2981. of a device if it would result in a drive letter >`Z' (5AH).
  2982. All block device drivers present in the standard resident
  2983. BIOS are placed ahead of installable block-device drivers in
  2984. the list.
  2985. MS-DOS DEVICE DRIVERS Page 2-4
  2986. ------------------------------------------------------------
  2987. | |
  2988. | Note |
  2989. | |
  2990. | Character devices cannot define multiple units |
  2991. | because they have only one name. |
  2992. | |
  2993. |__________________________________________________________|
  2994. 2.3 HOW TO CREATE A DEVICE DRIVER
  2995. To create a device driver that MS-DOS can install, you must
  2996. create a binary file (.COM or .EXE format) with a device
  2997. header at its beginning. Device driver code should not
  2998. originate at 100H, but at 0. The device header contains a
  2999. link field (pointer to next device header) which should be
  3000. -1, unless there is more than one device driver in the file.
  3001. You must also correctly set the attribute field and entry
  3002. points. The name field for a character device should
  3003. contain the name of that device. This name can be any legal
  3004. 8-character filename. But if it is less than eight
  3005. characters, you should pad it out to eight by typing spaces
  3006. (20H). Note that device names do not include colons (:).
  3007. The fact that "CON" is the same as "CON:" is a property of
  3008. the default MS-DOS command interpreter (COMMAND.COM) and not
  3009. of the device driver or MS-DOS interface. All character
  3010. device names are handled in this way.
  3011. MS-DOS always processes installable device drivers before
  3012. handling the default devices, so to install a new CON
  3013. device, simply name the device "CON". Remember to set the
  3014. standard input and standard output device bits in the
  3015. attribute word on a new CON device. The scan of the device
  3016. list stops on the first match, so the installable device
  3017. driver takes precedence.
  3018. It is not possible to replace the "resident" disk block
  3019. device driver with an installable device driver as you would
  3020. replace other device drivers in the BIOS. Block drivers can
  3021. be used only for devices not supported directly by the
  3022. default disk drivers in IO.SYS.
  3023. ------------------------------------------------------------
  3024. | |
  3025. | Note |
  3026. | |
  3027. | Because MS-DOS can install the driver anywhere in |
  3028. | memory, you must be careful when making far memory |
  3029. | references. You should not expect that your driver |
  3030. | will always be loaded in the same place every time. |
  3031. | |
  3032. |__________________________________________________________|
  3033. MS-DOS DEVICE DRIVERS Page 2-5
  3034. 2.3.1 Device Strategy Routine
  3035. This routine, which MS-DOS calls for each device driver
  3036. service request, is primarily responsible for queuing these
  3037. requests in the order in which they are to be processed by
  3038. the Device Interrupt Routine. Such queuing can be an
  3039. important performance feature in a multitasking environment,
  3040. or where asynchronous I/O is supported. Since MS-DOS does
  3041. not currently support these facilities, only one request
  3042. (usually a short one) can be serviced at a time. In the
  3043. coding examples in Section 2.12, each request is simply
  3044. stored in a single pointer area.
  3045. 2.3.2 Device Interrupt Routine
  3046. This routine contains the code necessary for processing the
  3047. service request. It may interface to the hardware, or it
  3048. may use ROM BIOS calls. It usually consists of a series of
  3049. procedures, which handle the specific command codes to be
  3050. supported, as well as some exit and error-handling routines.
  3051. See the coding examples in Section 2.12.
  3052. 2.4 INSTALLATION OF DEVICE DRIVERS
  3053. MS-DOS allows new device drivers to be installed dynamically
  3054. at boot time. This is accomplished by IO.SYS initialization
  3055. code which reads and processes the CONFIG.SYS file.
  3056. MS-DOS calls upon the device drivers to perform their
  3057. functions in the following manner:
  3058. 1. MS-DOS makes a far call to strategy entry.
  3059. 2. MS-DOS passes device driver information in a
  3060. request header to the strategy routine.
  3061. 3. MS-DOS then makes a far call to the interrupt
  3062. entry.
  3063. This structure can be easily upgraded to support any future
  3064. multitasking environment.
  3065. MS-DOS DEVICE DRIVERS Page 2-6
  3066. 2.5 DEVICE HEADERS
  3067. A device header, which is required at the beginning of every
  3068. device driver, looks like this:
  3069. +--------------------------------------+
  3070. | DWORD Pointer to next device |
  3071. | (Usually set to -1 if this driver |
  3072. | is the last or only driver in the |
  3073. | file) |
  3074. +--------------------------------------+
  3075. | WORD Attributes |
  3076. +--------------------------------------+
  3077. | WORD Pointer to device strategy |
  3078. | entry point |
  3079. +--------------------------------------+
  3080. | WORD Pointer to device interrupt |
  3081. | entry point |
  3082. +--------------------------------------+
  3083. | 8-BYTE Character device name field |
  3084. | Character devices set a device name. |
  3085. | For block devices the first byte is |
  3086. | the number of units. |
  3087. +--------------------------------------+
  3088. Figure 2.1. Sample Device Header
  3089. Note that the device entry points are words. They must be
  3090. offsets from the same segment number used to point to this
  3091. table. For example, if XXX:YYY points to the start of this
  3092. table, then XXX:strategy and XXX:interrupt are the entry
  3093. points.
  3094. The device header fields are described in the following
  3095. section.
  3096. 2.5.1 Pointer to Next Device Field
  3097. This pointer is a double word field (offset followed by
  3098. segment). MS-DOS sets this field so that it points to the
  3099. next driver in the system list at the time the device driver
  3100. is loaded. Unless there is more than one device driver in
  3101. the file, it is important that you set this field to -1
  3102. prior to loading (when it is on the disk as a file). If
  3103. there is more than one driver in the file, the first word of
  3104. the double word pointer should be the offset of the next
  3105. driver's device header.
  3106. MS-DOS DEVICE DRIVERS Page 2-7
  3107. ------------------------------------------------------------
  3108. | |
  3109. | Note |
  3110. | |
  3111. | If there is more than one device driver in the |
  3112. | file, the last driver in the file must have the pointer |
  3113. | to the next device header field set to -1. |
  3114. | |
  3115. |__________________________________________________________|
  3116. 2.5.2 Attribute Field
  3117. The attribute field identifies the type of device this
  3118. driver is responsible for. In addition to distinguishing
  3119. between block and character devices, these bits give
  3120. selected character devices special treatment. (Note that if
  3121. a bit in the attribute word is defined only for one type of
  3122. device, a driver for the other type of device must set that
  3123. bit to 0.)
  3124. For character devices:
  3125. Bit Value Meaning
  3126. 15 1 Character device
  3127. 14 1 Device supports
  3128. IOCTL control strings
  3129. 13 1 Device supports
  3130. Output Until Busy (OUB)
  3131. 12 RESERVED
  3132. 11 1 Device understands
  3133. OPEN/CLOSE
  3134. 10-7 RESERVED
  3135. 6 1 Device supports 3.2 functions
  3136. 5-4 RESERVED
  3137. 3 1 Device is CLOCK device
  3138. 2 1 Device is NUL device
  3139. 1 1 Device is console output (STO)
  3140. 0 1 Device is console input (STI)
  3141. For Block Devices:
  3142. Bit Value Meaning
  3143. 15 0 Block device
  3144. 14 1 Device supports IOCTL control
  3145. strings
  3146. 13 1 Device determines the media by
  3147. examining the FATID byte.
  3148. 12 RESERVED
  3149. 11 1 Device understands
  3150. OPEN/CLOSE/Removable Media.
  3151. MS-DOS DEVICE DRIVERS Page 2-8
  3152. 10-7 RESERVED
  3153. 6 1 Device supports 3.2 functions
  3154. 5-0 RESERVED
  3155. For example, assume that you have a new device driver that
  3156. you want to use as the standard input and output. In
  3157. addition to installing the driver, you must tell MS-DOS that
  3158. you want this new driver to override the current standard
  3159. input and standard output (the CON device). You do this by
  3160. setting bits 0 and 1 to 1 (note that they are separate!).
  3161. Similarly, you could install a new CLOCK device by setting
  3162. the appropriate attribute. (Refer to Section 2.10, "The
  3163. CLOCK Device," in this chapter for more information.)
  3164. Although there is a NUL device attribute, you cannot
  3165. reassign the NUL device. This attribute exists so that
  3166. MS-DOS can determine whether the NUL device is being used.
  3167. The IOCTL bit, bit 14, allows IOCTL functions to send and
  3168. receive data to character and block devices for their own
  3169. use. This allows them to set baud rate, stop bits, form
  3170. length, etc., instead of passing data over the device
  3171. channel as a normal read or write does. The interpretation
  3172. of the passed information is up to the device, but the
  3173. device must not treat this information as normal I/O. This
  3174. bit tells MS-DOS whether the device can handle control
  3175. strings via the IOCTL system call, Function 44H.
  3176. If a driver cannot process control strings, it should set
  3177. this bit initially to 0. This tells MS-DOS to return an
  3178. error if an attempt is made (via Function 44H) to send or
  3179. receive control strings to this device. A device which can
  3180. process control strings should initialize the IOCTL bit to
  3181. 1. For drivers of this type, MS-DOS makes calls to the
  3182. IOCTL INPUT and OUTPUT device functions to send and receive
  3183. IOCTL strings.
  3184. For block devices, bit 13 affects the operation of the BUILD
  3185. BPB (BIOS Parameter Block) device call. If set, it requires
  3186. the first sector of the FAT to reside ALWAYS in the same
  3187. place. Bit 13 has a different meaning on character devices,
  3188. indicating that the device implements the OUTPUT UNTIL BUSY
  3189. device call.
  3190. The OPEN/CLOSE/RM bit, bit 11, signals to MS-DOS 3.x, and
  3191. later versions, whether this driver supports additional
  3192. MS-DOS 3.0 functionality. But to support these old drivers,
  3193. it is necessary to detect them. Bit 11 was reserved in
  3194. MS-DOS 2.x, and is 0. All new devices, however, should
  3195. support the OPEN, CLOSE, and REMOVABLE MEDIA calls and set
  3196. this bit to 1. Since MS-DOS 2.x never makes these calls,
  3197. the driver will be backwardly compatible.
  3198. The MS-DOS 3.2 bit, bit 6, signals whether the device
  3199. supports logical drive mapping via Function 440EH (Get
  3200. Logical Drive Map) and Function 440FH (Set Logical Drive
  3201. MS-DOS DEVICE DRIVERS Page 2-9
  3202. Map). This bit also supports generic IOCTL functions via
  3203. Function 440C (Generic IOCTL for Handles) and Function 440D
  3204. (Generic IOCTL for Block Devices).
  3205. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  3206. ____________________________________________________________
  3207. | C | I | O | | O | | | | | 3 | | | C | N | S | S |
  3208. | H | O | Y | | P | | | | | . | | | L | U | T | T |
  3209. | R | C | B | | N | | | | | 2 | | | K | L | O | I |
  3210. |___|___|___|___|___|___|__|__|__|___|__|__|___|___|___|___|
  3211. Figure 2.? Attribute Word for character devices
  3212. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  3213. ____________________________________________________________
  3214. | | I | F | | O | | | | | 3 | | | | | | |
  3215. | | O | A | | P | | | | | . | | | | | | |
  3216. | | C | T | | N | | | | | 2 | | | | | | |
  3217. |___|___|___|___|___|___|__|__|__|___|__|__|___|___|___|___|
  3218. Figure 2.? Attribute Word for block devices
  3219. 2.5.3 Strategy And Interrupt Routines
  3220. These two fields are the pointers to the entry points of the
  3221. strategy and interrupt routines. They are word values, so
  3222. they must be in the same segment as the device header.
  3223. 2.5.4 Name Field
  3224. This is an 8-byte field that contains the name of a
  3225. character device or the number of units of a block device.
  3226. If it is a block device, the number of units can be put in
  3227. the first byte. This is optional, because MS-DOS fills in
  3228. this location with the value returned by the driver's INIT
  3229. code. Refer to Section 2.4, "Installation of Device
  3230. Drivers," for more information.
  3231. 2.6 REQUEST HEADER
  3232. When MS-DOS calls a device driver to perform a function, it
  3233. passes a request header in ES:BX to the strategy entry
  3234. point. This is a fixed length header, followed by data
  3235. pertinent to the function being performed. Note that it is
  3236. the device driver's responsibility to preserve the machine
  3237. state (for example, save all registers including flags on
  3238. entry and restore them on exit). There is enough room on
  3239. the stack to do about 20 pushes, when MS-DOS calls either
  3240. the strategy or the interrupt routines. If more stack is
  3241. MS-DOS DEVICE DRIVERS Page 2-10
  3242. needed, the driver should set up its own stack.
  3243. The following figure illustrates a request header.
  3244. REQUEST HEADER ->
  3245. +-----------------------------+
  3246. | BYTE Length of record |
  3247. | Length in bytes of this |
  3248. | request header |
  3249. +-----------------------------+
  3250. | BYTE Unit code |
  3251. | The subunit the operation |
  3252. | is for (minor device) |
  3253. | (no meaning on character |
  3254. | devices) |
  3255. +-----------------------------+
  3256. | BYTE Command code |
  3257. +-----------------------------+
  3258. | WORD Status |
  3259. +-----------------------------+
  3260. | 8 BYTES Reserved |
  3261. | |
  3262. |-----------------------------|
  3263. Figure 2.2. Request Header
  3264. The request header fields are described below.
  3265. 2.6.1 Length of Record
  3266. This field contains the length (in bytes) of the request
  3267. header.
  3268. 2.6.2 Unit Code Field
  3269. The unit code field identifies which unit in your device
  3270. driver the request is for. For example, if your device
  3271. driver has 3 units defined, the possible values of the unit
  3272. code field would be 0, 1, and 2.
  3273. 2.6.3 Command Code Field
  3274. The command code field in the request header can have the
  3275. following values:
  3276. Command Function
  3277. Code
  3278. 0 INIT
  3279. MS-DOS DEVICE DRIVERS Page 2-11
  3280. 1 MEDIA CHECK (Block devices only)
  3281. 2 BUILD BPB (Block devices only)
  3282. 3 IOCTL INPUT (Only called if device has IOCTL)
  3283. 4 INPUT (read)
  3284. 5 NON-DESTRUCTIVE INPUT NO WAIT (Char devs only)
  3285. 6 INPUT STATUS (Char devs only)
  3286. 7 INPUT FLUSH (Char devs only)
  3287. 8 OUTPUT (write)
  3288. 9 OUTPUT (Write) with verify
  3289. 10 OUTPUT STATUS (Char devs only)
  3290. 11 OUTPUT FLUSH (Char devs only)
  3291. 12 IOCTL OUTPUT (Only called if device has IOCTL)
  3292. 13 DEVICE OPEN (Only called if OPEN/CLOSE/RM bit set)
  3293. 14 DEVICE CLOSE (Only called if OPEN/CLOSE/RM bit set)
  3294. 15 REMOVABLE MEDIA (Only called if OPEN/CLOSE/RM bit
  3295. set and device is block)
  3296. 16 OUTPUT UNTIL BUSY (Only called if bit 13 is set on
  3297. character devices)
  3298. 19 Generic IOCTL Request (Only called if bit 0 is set
  3299. for block devices)
  3300. 23 Get Drive Map (Only called if bit 6 is set on
  3301. block devices)
  3302. 24 Set Drive Map (Only called if bit 6 is set on
  3303. block devices)
  3304. Unused command codes are reserved.
  3305. 2.6.4 Status Field
  3306. The following figure illustrates the status field in the
  3307. request header.
  3308. 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
  3309. +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+
  3310. | E | | B | D | |
  3311. | R | RESERVED | U | O | ERROR CODE (bit 15 on)|
  3312. | R | | S | N | |
  3313. | | | Y | E | |
  3314. +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+
  3315. The status word is zero on entry and is set by the driver
  3316. interrupt routine on return.
  3317. Bit 8 is the done bit. When set, it means the operation has
  3318. completed. The driver sets it to 1 when it exits.
  3319. Bit 15 is the error bit. If it is set, the low 8 bits
  3320. indicate the error. The errors are:
  3321. 0 Write protect violation
  3322. 1 Unknown unit
  3323. 2 Drive not ready
  3324. MS-DOS DEVICE DRIVERS Page 2-12
  3325. 3 Unknown command
  3326. 4 CRC error
  3327. 5 Bad drive request structure length
  3328. 6 Seek error
  3329. 7 Unknown media
  3330. 8 Sector not found
  3331. 9 Printer out of paper
  3332. A Write fault
  3333. B Read fault
  3334. C General failure
  3335. D Reserved
  3336. E Reserved
  3337. F Invalid disk change
  3338. Bit 9 is the busy bit, which is set only by status calls and
  3339. the removable media call.
  3340. 2.7 DEVICE DRIVER FUNCTIONS
  3341. Device drivers may perform all or some of these nine general
  3342. functions. In some cases, these functions break down into
  3343. several command codes. Each is described in this section.
  3344. 1. INIT
  3345. 2. MEDIA CHECK
  3346. 3. BUILD BPB
  3347. 4. READ or WRITE or WRITE TIL BUSY or Write with
  3348. Verify or Read IOCTL or Write IOCTL
  3349. 5. NON DESTRUCTIVE READ NO WAIT
  3350. 6. OPEN or CLOSE (3.x)
  3351. 7. REMOVABLE MEDIA (3.x)
  3352. 8. STATUS
  3353. 9. FLUSH
  3354. 10. Generic IOCTL
  3355. 11. Get Logical Device
  3356. 12. Set Logical Device
  3357. All strategy routines are called with ES:BX pointing to the
  3358. Request Header. The interrupt routines get the pointers to
  3359. the Request Header from the queue in which the strategy
  3360. MS-DOS DEVICE DRIVERS Page 2-13
  3361. routines store them. The command code in the request header
  3362. tells the driver which function to perform and what data
  3363. follows the request header.
  3364. ------------------------------------------------------------
  3365. | |
  3366. | Note |
  3367. | |
  3368. | All DWORD pointers are stored offset first, segment |
  3369. | second. |
  3370. | |
  3371. |__________________________________________________________|
  3372. 2.7.1 INIT
  3373. Command code = 0
  3374. INIT - ES:BX ->
  3375. +------------------------------------+
  3376. | 13-BYTE Request header |
  3377. +------------------------------------+
  3378. | BYTE Number of units |
  3379. +------------------------------------+
  3380. | DWORD End Address |
  3381. +------------------------------------+
  3382. | DWORD Pointer to BPB array |
  3383. | (Not set by character devices) |
  3384. +------------------------------------+
  3385. | BYTE Block device number |
  3386. +------------------------------------+
  3387. One of the functions defined for each device driver is INIT.
  3388. This routine is called only once when the device is
  3389. installed. The INIT routine must return the END ADDRESS,
  3390. which is a DWORD pointer to the end of the resident portion
  3391. of the device driver. To save space you can use this
  3392. pointer method to delete init code that is needed only once.
  3393. The driver sets the number of units, end address, and BPB
  3394. pointer. For installable block device drivers, the DWORD
  3395. pointer to BPB array now points to the first character after
  3396. the equal sign (=) on the line in CONFIG.SYS (the line that
  3397. caused this device to be loaded). This line is terminated
  3398. by a RETURN or a linefeed. This data is read-only and lets
  3399. the device driver scan the CONFIG.SYS line for arguments.
  3400. device=\dev\vt52.sys /l
  3401. ^
  3402. |_____BPB address points here
  3403. Also, the block device driver defines the first unit and
  3404. assigns it to the drive number in the block device number
  3405. MS-DOS DEVICE DRIVERS Page 2-14
  3406. field (for example, A=0). This field is also read-only.
  3407. Installable character devices must return only the end
  3408. address parameter. This parameter is a pointer to the first
  3409. available byte of memory above the location of the driver
  3410. and which the driver may use to throw away initialization
  3411. code.
  3412. Block devices must return the following information:
  3413. 1. The number of units. MS-DOS uses this number to
  3414. determine logical device names. At the time of the
  3415. install call, if the current maximum logical device
  3416. letter is F, and the INIT routine returns 4 as the
  3417. number of units, these units will have logical
  3418. names G, H, I and J. This mapping is determined by
  3419. the position of the driver in the device list and
  3420. by the number of units on the device (stored in the
  3421. first byte of the device name field).
  3422. 2. A DWORD pointer to an array of one-word offsets
  3423. (pointers) to BPBs (BIOS Parameter Blocks). MS-DOS
  3424. creates an internal structure by using the BPBs
  3425. passed by the device driver. There must be one
  3426. entry in this array for each unit defined by the
  3427. device driver. In this way, if all units are the
  3428. same, all the pointers can point to the same BPB,
  3429. saving space. If the device driver defines two
  3430. units, the DWORD pointer points to the first of two
  3431. one-word offsets. In turn these offsets point to
  3432. BPBs. The format of the BPB is described later in
  3433. this chapter in Section 2.7.3, "BUILD BPB."
  3434. Note that this array of one-word offsets must not
  3435. be above the free pointer set by the return,
  3436. because the device driver builds an internal DOS
  3437. structure, starting at the byte pointed to by the
  3438. free pointer. The defined sector size must be less
  3439. than or equal to the maximum sector size defined by
  3440. the resident device drivers (BIOS) during
  3441. initialization. If it isn't, the installation will
  3442. fail.
  3443. 3. The media descriptor byte. This byte, which is the
  3444. last byte returned by INIT, means nothing to
  3445. MS-DOS, but is passed to devices so that they know
  3446. which parameters MS-DOS is currently using for a
  3447. particular drive unit.
  3448. Block devices may be either dumb or smart. A dumb device ____ _____
  3449. defines a unit (and therefore an internal DOS structure) for
  3450. MS-DOS DEVICE DRIVERS Page 2-15
  3451. each possible media-drive combination. For example, unit 0
  3452. = drive 0, single sided; unit 1 = drive 0, double sided.
  3453. For the "dumb device" approach, media descriptor bytes do
  3454. not mean anything. A smart device allows multiple media per
  3455. unit. In the case of a smart device, the BPB table returned
  3456. upon INIT must define sufficient space to accommodate the
  3457. largest possible media. Smart drivers use the media
  3458. descriptor byte to pass information about what media is
  3459. currently in a unit.
  3460. For more information on the media descriptor byte, see
  3461. Section 2.8, "Media Descriptor Byte."
  3462. ------------------------------------------------------------
  3463. | |
  3464. | Note |
  3465. | |
  3466. | If a file contains multiple device drivers, MS-DOS uses |
  3467. | the ending address returned by the last INIT called. |
  3468. | All the device drivers in a single file should return |
  3469. | the same ending address. The code to remain resident |
  3470. | for all the devices in a file should be grouped |
  3471. | together in low memory with the initialization code for |
  3472. | all devices following it. |
  3473. | |
  3474. |__________________________________________________________|
  3475. 2.7.2 MEDIA CHECK
  3476. Command Code = 1
  3477. MEDIA CHECK - ES:BX ->
  3478. +------------------------------------+
  3479. | 13-BYTE Request header |
  3480. +------------------------------------+
  3481. | BYTE Media descriptor from BPB |
  3482. +------------------------------------+
  3483. | BYTE Returned |
  3484. +------------------------------------+
  3485. | Returned DWORD pointer to previous |
  3486. | Volume ID if bit 11 set and |
  3487. | Media Changed is returned |
  3488. +------------------------------------+
  3489. The MEDIA CHECK function is used with block devices only.
  3490. It is called when there is a pending drive access call other
  3491. than a file read or write, such as open, close, delete, or
  3492. rename. Its purpose is to determine whether the media in
  3493. the drive has been changed. If the driver can ensure that
  3494. MS-DOS DEVICE DRIVERS Page 2-16
  3495. the media has not been changed (through a door-lock or other
  3496. interlock mechanism), MS-DOS does not need to reread the FAT
  3497. and invalidate in-memory buffers for each directory access.
  3498. When such a disk access call to the DOS occurs (other than a
  3499. file read or write), the following sequence of events takes
  3500. place:
  3501. 1. The DOS converts the drive letter into the unit
  3502. number of a particular block device.
  3503. 2. The device driver is then called to request a media
  3504. check on that subunit to see if the disk might have
  3505. been changed. MS-DOS passes the old media
  3506. descriptor byte. The driver returns:
  3507. Media not changed...... (1)
  3508. Don't know if changed...(0)
  3509. Media changed...........(-1)
  3510. Error
  3511. If the media has not been changed, MS-DOS proceeds
  3512. with the disk access.
  3513. If the value returned is "Don't know," and if there
  3514. are any disk sectors that have been modified and
  3515. not yet written back to the disk for this unit,
  3516. MS-DOS assumes that the disk has not been changed
  3517. and proceeds. MS-DOS invalidates any other buffers
  3518. for the unit and does a BUILD BPB device call (see
  3519. step 3, below).
  3520. If the media has been changed, MS-DOS invalidates
  3521. all buffers associated with this unit including
  3522. buffers with modified data that are waiting to be
  3523. written, and requests a new BIOS Parameter Block
  3524. via the BUILD BPB call (see step 3, below).
  3525. 3. Once the BPB has returned, MS-DOS corrects its
  3526. internal structure for the drive from the new BPB
  3527. and, after reading the directory and the FAT,
  3528. proceeds with the access.
  3529. Note that the previous media ID byte is passed to the device
  3530. driver. If the old media ID byte is the same as the new
  3531. one, the disk might have been changed and a new disk may be
  3532. in the drive. Therefore, all FAT, directory, and data
  3533. sectors that are buffered in memory for the unit are
  3534. considered invalid.
  3535. If the driver has bit 11 of the device attribute word set to
  3536. 1, and the driver returns -1, "Media Changed," it must set
  3537. MS-DOS DEVICE DRIVERS Page 2-17
  3538. the DWORD pointer to the previous Volume ID field. If the
  3539. DOS determines that "Media Changed" is an error based on the
  3540. state of the DOS buffer cache, it generates a 0FH error on
  3541. behalf of the device. If the driver does not implement
  3542. Volume ID support, but has bit 11 set, it should set a
  3543. static pointer to the string, "NO NAME",0.
  3544. It is not possible for a user to change a disk in less than
  3545. 2 seconds. So when MEDIA CHECK occurs within 2 seconds of a
  3546. disk access, the driver reports "1," "Media not changed."
  3547. This action increases performance tremendously.
  3548. ------------------------------------------------------------
  3549. | |
  3550. | Note |
  3551. | |
  3552. | For MS-DOS versions before 3.2 if the media ID byte in |
  3553. | the returned BPB is the same as the previous media ID |
  3554. | byte, MS-DOS assumes that the format of the disk is the |
  3555. | same (even though the disk may have been changed) and |
  3556. | skips the step of updating its internal structure. All |
  3557. | BPBs, therefore, must have unique media bytes regardless|
  3558. | of FAT ID bytes. |
  3559. | |
  3560. |__________________________________________________________|
  3561. 2.7.3 BUILD BPB (BIOS Parameter Block)
  3562. Command code = 2
  3563. BUILD BPB - ES:BX ->
  3564. +------------------------------------+
  3565. | 13-BYTE Request header |
  3566. +------------------------------------+
  3567. | BYTE Media descriptor from BPB |
  3568. +------------------------------------+
  3569. | DWORD Transfer address |
  3570. | (Points to one sector worth of |
  3571. | scratch space or first sector |
  3572. | of FAT depending on the value |
  3573. | of Bit 13 in the device attribute |
  3574. | word.) |
  3575. +------------------------------------+
  3576. | DWORD Pointer to BPB |
  3577. +------------------------------------+
  3578. The Build BPB function is used with block devices only. As
  3579. described in the MEDIA CHECK function, the BUILD BPB
  3580. function is called any time that a preceding MEDIA CHECK
  3581. call indicates that the disk has been, or might have been,
  3582. MS-DOS DEVICE DRIVERS Page 2-18
  3583. changed. The device driver must return a pointer to a BPB.
  3584. This is different from the INIT call where the device driver
  3585. returns a pointer to an array of word offsets to BPBs.
  3586. The BUILD BPB call gets a DWORD pointer to a one-sector
  3587. buffer. The contents of this buffer are determined by the
  3588. NON FAT ID bit (bit 13) in the attribute field. If the bit
  3589. is zero, the buffer contains the first sector of the first
  3590. FAT. The FAT ID byte is the first byte of this buffer, so
  3591. in this case, the driver must not alter the buffer. Note
  3592. that the location of the FAT must be the same as for all
  3593. possible media because the DOS must read this FAT sector
  3594. before the driver returns the BPB that the DOS called. If
  3595. the NON FAT ID bit is set, the pointer points to one sector
  3596. of scratch space (space which may be used for anything).
  3597. Refer to Section 2.8, "Media Descriptor Byte,"" and Section
  3598. 2.9, "Format of a Media Descriptor Table," for information
  3599. on how to construct the BPB.
  3600. MS-DOS 3.x includes additional support for devices that have
  3601. door-locks or some other means of telling when a disk has
  3602. been changed. Error 15, a new error that the device driver
  3603. can return, means "the disk has been changed when it
  3604. shouldn't have been." The user is prompted for the correct
  3605. disk using a Volume ID. The driver may generate this error
  3606. for READ or WRITE. The DOS may generate the error for MEDIA
  3607. CHECK if the driver reports media changed, and there are
  3608. buffers in the DOS buffer cache that need to be flushed to
  3609. the previous disk.
  3610. For drivers that support this error, the BUILD BPB function
  3611. is a trigger that causes the driver to read a new Volume ID
  3612. from the disk. This action indicates that the disk has been
  3613. legally changed. The FORMAT or LABEL utility places a
  3614. Volume ID on the disk. This ID is simply an entry in the
  3615. root directory of the disk that has the Volume ID attribute.
  3616. The driver stores the Volume ID as an ASCIZ string.
  3617. The requirement that the driver return a Volume ID does not
  3618. exclude some other Volume identifier scheme as long as the
  3619. scheme uses ASCIZ strings. A NUL (nonexistent or
  3620. unsupported) Volume ID is by convention the string:
  3621. DB "NO NAME ",0
  3622. MS-DOS DEVICE DRIVERS Page 2-19
  3623. 2.7.4 READ or WRITE
  3624. Command codes = 3,4,8,9, 12, and 16
  3625. READ OR WRITE (Including IOCTL) or
  3626. OUTPUT UNTIL BUSY - ES:BX ->
  3627. +------------------------------------+
  3628. | 13-BYTE Request header |
  3629. +------------------------------------+
  3630. | BYTE Media descriptor from BPB |
  3631. +------------------------------------+
  3632. | DWORD Transfer address |
  3633. +------------------------------------+
  3634. | WORD Byte/sector count |
  3635. +------------------------------------+
  3636. | WORD Starting sector number |
  3637. | (Ignored on character devices) |
  3638. +------------------------------------+
  3639. | Returned DWORD pointer to requested|
  3640. | Volume ID if error 0FH |
  3641. +------------------------------------+
  3642. COMMAND CODE REQUEST
  3643. 3 IOCTL READ
  3644. 4 READ (block or character)
  3645. 8 WRITE (block or character)
  3646. 9 WRITE WITH VERIFY
  3647. 12 IOCTL WRITE
  3648. 16 OUTPUT TIL BUSY (char devs only)
  3649. The driver must perform the READ or WRITE call depending on
  3650. which command code is set. Block devices read or write
  3651. sectors; character devices read or write bytes.
  3652. When I/O completes, the device driver must set the status
  3653. word and report the number of sectors or bytes successfully
  3654. transferred, even if an error prevented the transfer from
  3655. being completed. Setting the error bit and error code alone _______ ___ _____ ___ ___ _____ ____ _____
  3656. is not sufficient.__ ___ __________
  3657. In addition to setting the status word, the driver must set
  3658. the sector count to the actual number of sectors (or bytes)
  3659. transferred. No error check is performed on an IOCTL I/O
  3660. call.
  3661. If the verify switch is on, the device driver is called with
  3662. command code 9 (WRITE WITH VERIFY). Your device driver is
  3663. then responsible for verifying the write.
  3664. If the driver returns error code 0FH (Invalid disk change),
  3665. it must return a DWORD pointer to an ASCIZ string (which is
  3666. the correct Volume ID). The return of this error code
  3667. triggers the DOS to prompt the user to re-insert the disk.
  3668. The device driver should have read the Volume ID as a result
  3669. of the BUILD BPB function.
  3670. Drivers may maintain a reference count of open files on the
  3671. disk by monitoring the OPEN and CLOSE functions. This
  3672. allows the driver to determine when to return error 0FH. If
  3673. there are no open files (reference count = 0), and the disk
  3674. MS-DOS DEVICE DRIVERS Page 2-20
  3675. has been changed, the I/O is okay. If there are open files,
  3676. however, an 0FH error may exist.
  3677. The OUTPUT UNTIL BUSY call is a speed optimization on
  3678. character devices only for print spoolers. The device
  3679. driver is expected to output all the characters possible
  3680. until the device returns busy. Under no circumstances
  3681. should the device driver block during this function. Note
  3682. that it is not an error if the device driver returns a
  3683. smaller number of bytes output than bytes requested.
  3684. The OUTPUT UNTIL BUSY call allows spooler programs to take
  3685. advantage of the burst behavior of most printers. Many
  3686. printers have on-board RAM buffers which typically hold a
  3687. line or a fixed amount of characters. These buffers fill up
  3688. without making the printer "busy" between characters for a
  3689. relatively short time (or at least not for more than ten
  3690. instructions). The device driver can quickly output a line
  3691. of characters to the printer, which is then busy for a
  3692. comparatively longer time while it prints. This new device
  3693. call allows background spooling programs to use this burst
  3694. behavior efficiently. Rather than take the overhead of a
  3695. device driver call for each character, or risk getting stuck
  3696. in the device driver outputting a block of characters, this
  3697. call allows a burst of characters to be output without the
  3698. device driver having to wait until the device is ready.
  3699. If the MS-DOS 3.2 bit is set, then MS-DOS can configure the
  3700. number of retries (allowed by the device driver) that the
  3701. printer can make before returning "busy."
  3702. THE FOLLOWING APPLIES TO BLOCK DEVICE DRIVERS:___ _________ _______ __ _____ ______ _______
  3703. Under certain circumstances, the device driver may request
  3704. that the BIOS perform a write operation of 64K bytes, which
  3705. seems to be a "wrap around" of the transfer address in the
  3706. BIOS I/O packet. This request arises due to an optimization
  3707. added to the write code in MS-DOS. It will only manifest
  3708. itself on user writes within a sector size of 64K bytes to
  3709. files "growing" past the current EOF. The BIOS may ignore ___ ____ ___ ______
  3710. the balance of the write that "wraps around," if it so___ _______ __ ___ _____ ____ ______ ________ __ __ __
  3711. chooses. For example, a write of 10000H bytes worth of________
  3712. sectors with a transfer address of XXX:1 could ignore the
  3713. last two bytes. A user program can never request an I/O of
  3714. more than FFFFH bytes and cannot wrap around (even to 0) in
  3715. the transfer segment. Therefore, in this case the BIOS
  3716. ignores the last two bytes.
  3717. MS-DOS maintains two FATs. If the DOS has problems reading
  3718. the first, it automatically tries the second before
  3719. reporting the error. The BIOS is responsible for all
  3720. retries.
  3721. Although the COMMAND.COM handler does no automatic retries,
  3722. there are applications that have their own Interrupt 24H
  3723. MS-DOS DEVICE DRIVERS Page 2-21
  3724. handlers. These handles do automatic retries on certain
  3725. types of Interrupt 24H errors before reporting them.
  3726. 2.7.5 NON DESTRUCTIVE READ NO WAIT
  3727. Command code = 5
  3728. NON DESTRUCTIVE READ NO WAIT - ES:BX ->
  3729. +------------------------------------+
  3730. | 13-BYTE Request header |
  3731. +------------------------------------+
  3732. | BYTE read from device |
  3733. +------------------------------------+
  3734. This call lets MS-DOS look ahead one input character. The
  3735. device sets the done bit in the status word.
  3736. If the character device returns busy bit = 0, characters are
  3737. in the buffer and the next character that would be read is
  3738. returned. This character is not removed from the input ___
  3739. buffer (hence the term "Non Destructive Read"). If the
  3740. character device returns busy bit = 1, there are no
  3741. characters in the buffer.
  3742. 2.7.6 OPEN or CLOSE
  3743. Command codes = 13 and 14
  3744. OPEN or CLOSE - ES:BX ->
  3745. +------------------------------------+
  3746. | 13-BYTE Static request header |
  3747. +------------------------------------+
  3748. These functions are called by MS-DOS 3.x only if the device
  3749. driver sets the OPEN/CLOSE/RM attribute bit in the device
  3750. header. They are designed to inform the device about its
  3751. current file activity. On block devices, these functions
  3752. can manage local buffering, and the device can keep a
  3753. reference count.
  3754. Every OPEN causes the device to increment the count, every
  3755. CLOSE to decrement. When the count goes to zero no open
  3756. files are on the device. Also, the device should flush any
  3757. buffers that it may have used in case the media has been
  3758. changed.
  3759. Block devices can have problems with this mechanism because
  3760. programs that use FCB calls can open files without closing
  3761. MS-DOS DEVICE DRIVERS Page 2-22
  3762. them. Therefore, when the media has been changed and the
  3763. BUILD BPB call has been made to the device, you should reset
  3764. the count to zero without flushing the buffers.
  3765. These calls are more useful on character devices. For
  3766. example, the device could use the OPEN call to send a device
  3767. initialization string. For example, this string might set a
  3768. printer's default characteristics for font and page size.
  3769. Using IOCTL to set these pre- and post-strings provides a
  3770. flexible mechanism of serial I/O device stream control. A
  3771. driver could also use the reference count mechanism to
  3772. detect a simultaneous access error. You may not want to
  3773. allow more than one OPEN on a device at any given time,
  3774. since, in this case, a second OPEN would result in an error.
  3775. Note that since all processes have access to stdin, stdout,
  3776. stderr, stdaux, and stdprn (handles 0,1,2,3,4), the CON,
  3777. AUX, and PRN devices are always open. ______
  3778. 2.7.7 REMOVABLE MEDIA
  3779. Command code = 15
  3780. REMOVABLE MEDIA - ES:BX ->
  3781. +------------------------------------+
  3782. | 13-BYTE Static request header |
  3783. +------------------------------------+
  3784. This function is called by MS-DOS 3.x only if the device
  3785. driver sets the OPEN/CLOSE/RM attribute bit in the device
  3786. header. Only a subfunction of the IOCTL system call can
  3787. issue this call to block devices. Sometimes it is necessary
  3788. for a utility to know whether it is using a non-removable
  3789. media drive (a hard disk), or a removable media drive (a
  3790. floppy). For example, the FORMAT utility prints different
  3791. prompts depending on the media.
  3792. The information returns in the busy bit of the status word.
  3793. If the busy bit is 1, the media is non-removable, and if the
  3794. busy bit is 0, the media is removable. Note that the device
  3795. driver does not check the error bit; it just assumes that
  3796. this call always succeeds.
  3797. MS-DOS DEVICE DRIVERS Page 2-23
  3798. 2.7.8 STATUS
  3799. Command codes = 6 and 10
  3800. STATUS Calls ES:BX ->
  3801. +------------------------------------+
  3802. | 13-BYTE request header |
  3803. +------------------------------------+
  3804. This call returns information to the DOS to let it know if
  3805. data is waiting for input or output. All the driver must do
  3806. is set the status word and the busy bit as follows:
  3807. For output on character devices: If the driver ___ ______ __ _________ _______
  3808. sets bit 9 to 1 on return, it informs the DOS that
  3809. a write request (if made) would wait for completion
  3810. of a current request. If bit 9 is 0, there is no
  3811. current request and a write request (if made) would
  3812. start immediately.
  3813. For input on character devices with a buffer: If ___ _____ __ _________ _______ ____ _ ______
  3814. bit 9 equals 1 this implies that the buffer is
  3815. empty and that a read request (if made) would go to
  3816. the physical device. If bit 9 is 0 on return,
  3817. characters are in the device buffer and a read
  3818. request would start immediately. A return of 0
  3819. implies that you have typed something. MS-DOS
  3820. assumes that all character devices have an input
  3821. type-ahead buffer; devices that do not should
  3822. always return busy = 0 so that the DOS does not
  3823. wait for you to put something into a non-existent
  3824. buffer.
  3825. 2.7.9 FLUSH
  3826. Command codes = 7 and 11
  3827. FLUSH Calls - ES:BX ->
  3828. +------------------------------------+
  3829. | 13-BYTE request header |
  3830. +------------------------------------+
  3831. The FLUSH call tells the driver to flush (terminate) all
  3832. pending requests. This call is used to flush the input
  3833. queue on character devices. The device driver performs the
  3834. flush function, sets the status word, and returns.
  3835. MS-DOS DEVICE DRIVERS Page 2-24
  3836. 2.7.10 Generic IOCTL Request
  3837. Command code = 19
  3838. ES:BX --> +----------------------------------+
  3839. | 13-BYTE Static Request Header |
  3840. +----------------------------------+
  3841. | BYTE Category (Major) Code |
  3842. +----------------------------------+
  3843. | BYTE Function (Minor) Code |
  3844. +----------------------------------+
  3845. | WORD (SI) contents |
  3846. +----------------------------------+
  3847. | WORD (DI) contents |
  3848. +----------------------------------+
  3849. | DWORD pointer to data buffer |
  3850. +----------------------------------+
  3851. This function provides a generic, expandable IOCTL facility
  3852. that replaces and makes the Read IOCTL and Write IOCTL
  3853. device driver functions obsolete. The MS-DOS 2.0 IOCTL
  3854. functions remain to support existing uses of the IOCTL
  3855. system call (subfunctions 2, 3, 4 and 5), but new device
  3856. drivers should use this generic MS-DOS IOCTL facility.
  3857. The generic IOCTL function contains both a category and
  3858. function code. The DOS examines the category field in order
  3859. to intercept and obey device commands that are actually
  3860. serviced by the DOS code; all other command categories are
  3861. forwarded to the device driver for servicing.
  3862. For more information on these category and function codes,
  3863. refer to Functions 440CH (Generic IOCTL for handles) and
  3864. Function 440DH (Generic IOCTL for block devices) in Chapter
  3865. 1, "System Calls."
  3866. 2.7.11 Get/Set Logical Drive Map
  3867. Command code = 23 (Get) or 24 (Set)
  3868. +-------------------------------------------+
  3869. | 13-byte Static Request Header |
  3870. +-------------------------------------------+
  3871. | BYTE Input (unit code) |
  3872. +-------------------------------------------+
  3873. | BYTE Output (last device referenced) |
  3874. +-------------------------------------------+
  3875. | BYTE Command code |
  3876. +-------------------------------------------+
  3877. | WORD Status |
  3878. +-------------------------------------------+
  3879. | DWORD Reserved |
  3880. +-------------------------------------------+
  3881. This function is only called by MS-DOS if the device driver
  3882. sets the DOS 3.2 attribute bit in the device header. The
  3883. call is only issued to block devices by a subfunction of the
  3884. IOCTL system call. The logical drive is passed in the UNIT
  3885. field of the header to the device driver, which returns the
  3886. MS-DOS DEVICE DRIVERS Page 2-25
  3887. current logical drive that is mapped on the physical drive
  3888. in the UNIT field of the header.
  3889. 2.8 MEDIA DESCRIPTOR BYTE
  3890. In MS-DOS, the media descriptor byte informs the DOS that a
  3891. different type of media is present. The media descriptor
  3892. byte can be any value between 0 and FFH. It does not have
  3893. to be the same as the FAT ID byte. The FAT ID byte, which
  3894. is the first byte of the FAT, was used in MS-DOS 1.00 to
  3895. distinguish between different types of disk media. This
  3896. byte may also be used under 2.x and 3.x disk device drivers.
  3897. However, FAT ID bytes have significance only for block
  3898. device drivers where the NON FAT ID bit is not set (0).
  3899. Values of the media descriptor byte or the FAT ID byte have
  3900. no significance to MS-DOS. They are passed directly to the
  3901. device driver so that programs can determine the media type.
  3902. 2.9 FORMAT OF A MEDIA DESCRIPTOR TABLE
  3903. The MS-DOS file system uses a linked list of pointers (one
  3904. for each cluster or allocation unit) called the File
  3905. Allocation Table (FAT). Unused clusters are represented by
  3906. zero and end-of-file by FFF (or FFFF on units with 16-bit
  3907. FAT entries). No valid entry should ever point to a zero
  3908. entry, but if one does, the first FAT entry (which would be
  3909. pointed to by a zero entry) should be reserved and set to
  3910. end-of-chain. Eventually, several end-of-chain values can
  3911. be defined ([F]FF8-[F]FFF), and used to distinguish
  3912. different media types.
  3913. A preferrable technique is to write a complete media
  3914. descriptor table in the boot sector and use it for media
  3915. identification. To ensure backward compatibility for
  3916. systems whose drivers do not set the NON FAT ID bit
  3917. (including the IBM PC implementation), it is necessary to
  3918. write the FAT ID bytes during the FORMAT process.
  3919. In the future to allow more flexibile support for many
  3920. different disk formats, you should keep the information
  3921. relating to the BPB for a particular media in the boot
  3922. sector. Figure 2.3 shows the format of such a boot sector.
  3923. MS-DOS DEVICE DRIVERS Page 2-26
  3924. +------------------------------------+
  3925. | 3 BYTE Near JUMP to boot code |
  3926. +------------------------------------+
  3927. | 8 BYTES OEM name and version |
  3928. ---+------------------------------------+---
  3929. B | WORD Bytes per sector |
  3930. P +------------------------------------+
  3931. B | BYTE Sectors per allocation unit |
  3932. +------------------------------------+
  3933. | | WORD Reserved sectors |
  3934. V +------------------------------------+
  3935. | BYTE Number of FATs |
  3936. +------------------------------------+
  3937. | WORD Number of root dir entries |
  3938. +------------------------------------+
  3939. | WORD Number of sectors in logical |
  3940. ^ | image |
  3941. | +------------------------------------+
  3942. B | BYTE Media descriptor |
  3943. P +------------------------------------+
  3944. B | WORD Number of sectors per FAT |
  3945. ---+------------------------------------+---
  3946. | WORD Sectors per track |
  3947. +------------------------------------+
  3948. | WORD Number of heads |
  3949. +------------------------------------+
  3950. | WORD Number of hidden sectors |
  3951. +------------------------------------+
  3952. | WORD High order number of hidden |
  3953. | sectors |
  3954. +------------------------------------+
  3955. | DWORD Number of logical sectors |
  3956. +------------------------------------+
  3957. Figure 2.3. Format of Boot Sector
  3958. Although MS-DOS does not use the five fields that follow the
  3959. BPB, they may be used by a device driver to help it
  3960. understand the media.
  3961. The "Sectors per track" and "Number of heads" fields are
  3962. useful for supporting different media which may have the
  3963. same logical layout, but a different physical layout (e.g.,
  3964. 40 track double-sided versus 80 track single-sided).
  3965. "Sectors per track" tells the device driver how the logical
  3966. disk format is laid out on the physical disk.
  3967. The "Number of hidden sectors" and the "High order number of
  3968. hidden sectors" fields may be used to suport
  3969. drive-partitioning schemes.
  3970. The "Number of logical sectors" field is not currently used
  3971. but will tell the device driver how many sectors to reserve
  3972. if the "Number of sectors in logical image" field is zero.
  3973. MS-DOS DEVICE DRIVERS Page 2-27
  3974. (This is intended for supporting drives that access more
  3975. than 32 megabytes.)
  3976. NON FAT ID format drivers should use the following procedure
  3977. to determine media type:
  3978. 1. Read the boot sector of the drive into the 1-sector
  3979. scratch space pointed to by the DWORD Transfer
  3980. address.
  3981. 2. Determine whether the first byte of the boot sector
  3982. is either E9H (the first byte of a 3-byte NEAR or
  3983. 2-byte short jump) or EBH (the first byte of a
  3984. 2-byte jump followed by a NOP). If it is, return a
  3985. pointer to a BPB beginning at offset 3.
  3986. 3. If the boot sector does not have a BPB table, it is
  3987. probably a disk formatted under a 1.x version of
  3988. MS-DOS. Therefore, it probably uses a FAT ID byte
  3989. for determining media.
  3990. As an option, the driver may attempt to read the
  3991. first sector of the FAT into the 1-sector scratch
  3992. space and then read the first byte to determine the
  3993. media type. Return a pointer to a hard-coded BPB.
  3994. 2.10 THE CLOCK DEVICE
  3995. MS-DOS assumes that some sort of clock is available in the
  3996. system. This clock may be either a CMOS real-time clock or
  3997. an interval timer which the user initializes at boot time.
  3998. The CLOCK device defines and performs functions like any
  3999. other character device except that the DOS identifies it by
  4000. a bit in the attribute word. Consequently this device may
  4001. take any name. The IBM version uses "$CLOCK" to avoid
  4002. conflict with existing files named "CLOCK."
  4003. The CLOCK device is unique because MS-DOS reads or writes a
  4004. 6-byte sequence that encodes the date and time. A write to
  4005. this device sets the date and time, and a read gets the date
  4006. and time.
  4007. Figure 2.4 illustrates the binary time format which the
  4008. CLOCK device uses:
  4009. MS-DOS DEVICE DRIVERS Page 2-28
  4010. byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
  4011. +--------+--------+---------+--------+--------+---------+
  4012. | | | | | | |
  4013. |days since 1-1-80| minutes | hours | sec/100| seconds |
  4014. |low byte|hi byte | | | | |
  4015. +--------+--------+---------+--------+--------+---------+
  4016. Figure 2.4. CLOCK Device Format
  4017. 2.11 ANATOMY OF A DEVICE CALL
  4018. The following steps illustrate what happens when MS-DOS
  4019. calls on a block device driver to perform a WRITE request:
  4020. 1. MS-DOS writes a request packet in a reserved area
  4021. of memory.
  4022. 2. It then calls the block device driver strategy
  4023. entry point.
  4024. 3. The device driver saves the ES and BX registers
  4025. (ES:BX points to the request packet) and does a FAR
  4026. return.
  4027. 4. MS-DOS calls the interrupt entry point.
  4028. 5. The device driver retrieves the pointer to the
  4029. request packet and reads the command code (offset
  4030. 2) to determine that this is a write request. The
  4031. device driver converts the command code for an
  4032. index into a dispatch table and passes control to
  4033. the disk write routine.
  4034. 6. The device driver reads the unit code (offset 1) to
  4035. determine which disk drive it should write to.
  4036. 7. Since the command is a disk write, the device
  4037. driver must get the transfer address (offset 14),
  4038. the sector count (offset 18), and the start sector
  4039. (offset 20) in the request packet.
  4040. 8. The device driver translates the first logical
  4041. sector number into a track, head, and sector
  4042. number.
  4043. MS-DOS DEVICE DRIVERS Page 2-29
  4044. 9. The device driver writes the specified number of
  4045. sectors, starting at the beginning sector on the
  4046. drive defined by the unit code (the subunit defined
  4047. by this device driver), and transfers data from the
  4048. address indicated in the request packet. Note that
  4049. this may involve multiple write commands to the
  4050. disk controller.
  4051. 10. After the transfer is complete, the device driver
  4052. must report the status of the request to MS-DOS by
  4053. setting the done bit in the status word (offset 3
  4054. in the request packet). It reports the number of
  4055. sectors actually transferred in the sector count
  4056. area of the request packet.
  4057. 11. If an error occurs, the driver sets the done bit
  4058. and the error bit in the status word and fills in
  4059. the error code in the lower half of the status
  4060. word. The number of sectors actually transferred
  4061. must be written in the request header. It is not
  4062. sufficient just to set the error bit of the status
  4063. word.
  4064. 12. Finally, the device driver does a FAR return to
  4065. MS-DOS.
  4066. The device drivers should preserve the state of MS-DOS,
  4067. including all registers (and flags). In particular, the
  4068. direction flag and interrupt enable bits are critical. When
  4069. the interrupt entry point in the device driver is called,
  4070. MS-DOS has room for about 40 to 50 bytes on its internal
  4071. stack. Your device driver should switch to a local stack if
  4072. it uses extensive stack operations.
  4073. APPENDIX E
  4074. MSDOS 2.25 Device Driver Interface Extension.
  4075. MSDOS 2.25 is designed so as to be able to run with
  4076. CONSOLE DEVICE DRIVERS FROM PREVIOUS VERSIONS. If this is
  4077. the case then no interim character processing can be done,
  4078. and all character composition must be handled directly by
  4079. the console device driver.
  4080. The MSDOS 2.25 BIOS interface (IO.SYS) has the
  4081. following differences from the standard MSDOS 2.11 BIOS.
  4082. These changes are extensions to the CON (Console) Device
  4083. driver for hardware which will be utilizing Interim
  4084. Character support. Consult the MSDOS Adapatation Guide
  4085. for overall description of device driver design and
  4086. funtionality
  4087. 1) On the INPUT and NON-DESTRUCTIVE INPUT calls to the
  4088. device driver (DD) the DD must check bit 0 of the byte at
  4089. offset 14 in the request packet. If the bit is 0 then it
  4090. should return only final characters, if the bit is 1 then
  4091. the device driver should return interim as well as final
  4092. characters to the dos.
  4093. Also on INPUT, if the request is for more than ONE byte
  4094. then the DD should return ONLY final characters, no matter
  4095. what the state of bit 0 in the byte at offset 14.
  4096. 2) On return from INPUT, NON-DESTRUCTIVE INPUT and
  4097. INPUT STATUS calls, the device driver should return to the
  4098. dos with bit 10 of the status word SET if the character
  4099. read, or the character available is an interim character, or
  4100. the bit RESET if the character is a final character. (Pre
  4101. 2.25 DD's always return with this bit reset). If more than
  4102. one character is read on an INPUT call then bit 10 should be
  4103. RESET as all the characters returned should be final
  4104. characters (see above).
  4105. 3) On Console WRITE function the device driver should
  4106. check bit 0 of the byte at offset 14 in the request packet.
  4107. If the bit is reset then the character should be output as a
  4108. regular character by printing the character and advancing
  4109. the cursor to the next position. If the bit is SET then the
  4110. character is an interim character and should be treated by
  4111. the device driver display routine accordingly. In most cases
  4112. the character should be displayed without advancing the
  4113. cursor to the next character position. When using interim 16
  4114. bit characters that are output a byte at a time, then the
  4115. routine should handle this correctly, displaying the 16 bit
  4116. interim and not advancing the cursor to the next character
  4117. position.
  4118. Special considerations / requirements.
  4119. If a console device driver is going to return interim
  4120. characters then the device driver MUST be able to handle the
  4121. extension made to character WRITE (described above in 3).
  4122. Device drivers should be able to support requests for
  4123. final / interim characters in any order. Application
  4124. programs may at any time change the way they want
  4125. characters, and device drivers should be capable of changing
  4126. without any other indication than the DD request itself.
  4127. Device drivers should be capable of handling
  4128. composition somehow for those applications that do not do it
  4129. themselves.
  4130. The keyboard typeahead buffer should be kept at the key
  4131. level, without further interpretation. All processing of
  4132. interims in case of an input request for a final character
  4133. is issued (and there are interims in the buffer that have to
  4134. be composed to obtain a final character), should be done at
  4135. the time the request is done to the device driver.
  4136. Sample Device Driver for DOS 2.25 Interim Character Support
  4137. WARNING!! Not Assembleable. This code must be modified for
  4138. the OEM's own hardware and firmware.
  4139. PAGE
  4140. CODE SEGMENT BYTE
  4141. ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
  4142. ;----------------------------------------------------------------
  4143. ;
  4144. ; C O N - CONSOLE DEVICE DRIVER
  4145. ;
  4146. DW -1,-1
  4147. DW 1000000000010011B ; CON IN AND CON OUT + Special bit
  4148. DW STRATEGY
  4149. DW ENTRY
  4150. DB 'CON '
  4151. InterH db 0 ; Interim character flag
  4152. ALTAH DB 0 ; Special key handling
  4153. ;----------------------------------------------------------------
  4154. ;
  4155. ; COMMAND JUMP TABLES
  4156. CONTBL:
  4157. DW CON$INIT
  4158. DW EXIT
  4159. DW EXIT
  4160. DW CMDERR
  4161. DW CON$READ
  4162. DW CON$RDND
  4163. DW EXIT
  4164. DW CON$FLSH
  4165. DW CON$WRIT
  4166. DW CON$WRIT
  4167. DW EXIT
  4168. DW EXIT
  4169. PAGE
  4170. ;----------------------------------------------------------------
  4171. ;
  4172. ; Device entry point
  4173. ;
  4174. CMDLEN = 0 ;LENGTH OF THIS COMMAND
  4175. UNIT = 1 ;SUB UNIT SPECIFIER
  4176. CMD = 2 ;COMMAND CODE
  4177. STATUS = 3 ;STATUS
  4178. MEDIA = 13 ;MEDIA DESCRIPTOR
  4179. TRANS = 14 ;TRANSFER ADDRESS
  4180. COUNT = 18 ;COUNT OF BLOCKS OR CHARACTERS
  4181. START = 20 ;FIRST BLOCK TO TRANSFER
  4182. BRKADR = Oem_Brk ; Break Vector Address
  4183. CHROUT = 29H ; fast con int
  4184. PAGE
  4185. ;----------------------------------------------------------------
  4186. ;
  4187. ; Entry Procedures
  4188. ;
  4189. PTRSAV DD 0
  4190. STRATP PROC FAR
  4191. STRATEGY:
  4192. MOV WORD PTR CS:[PTRSAV],BX
  4193. MOV WORD PTR CS:[PTRSAV+2],ES
  4194. RET
  4195. STRATP ENDP
  4196. ENTRY:
  4197. PUSH SI
  4198. PUSH AX
  4199. PUSH CX
  4200. PUSH DX
  4201. PUSH DI
  4202. PUSH BP
  4203. PUSH DS
  4204. PUSH ES
  4205. PUSH BX
  4206. LDS BX,CS:[PTRSAV] ; DS:BX points to IO packet
  4207. mov cx,word ptr ds:[bx].count ; CX = count
  4208. mov dl,byte ptr ds:[bx].media ; DL = input type flag
  4209. mov al,byte ptr ds:[bx].cmd ; AL = command code
  4210. cbw
  4211. MOV SI,OFFSET CONTBL ; command table
  4212. ADD SI,AX
  4213. ADD SI,AX
  4214. CMP AL,11
  4215. JA CMDERR ; command code out of range
  4216. LES DI,DWORD PTR DS:[BX].TRANS ; transfer address
  4217. PUSH CS
  4218. POP DS
  4219. ASSUME DS:CODE
  4220. JMP WORD PTR [SI] ; GO DO COMMAND
  4221. PAGE
  4222. ;----------------------------------------------------------------
  4223. ;
  4224. ; EXIT - ALL ROUTINES RETURN THROUGH THIS PATH
  4225. ;
  4226. CMDERR:
  4227. MOV AL,3 ; Unknown Command Error
  4228. ERR$EXIT:
  4229. mov ah,10000001b ; Mark Error Return
  4230. jmp short err1
  4231. BUS$EXIT:
  4232. mov ah,00000011b ; Device Busy Exit
  4233. jmp short err1
  4234. HanExit:
  4235. mov [InterH],0 ; reset interim flag
  4236. mov ah,00000101b ; Bit 10 Set for interim chars
  4237. jmp short err1
  4238. EXITP PROC FAR
  4239. EXIT: MOV AH,00000001B
  4240. ERR1: LDS BX,CS:[PTRSAV]
  4241. MOV WORD PTR [BX].STATUS,AX ; Mark Operation Complete
  4242. POP BX
  4243. POP ES
  4244. POP DS
  4245. POP BP
  4246. POP DI
  4247. POP DX
  4248. POP CX
  4249. POP AX
  4250. POP SI
  4251. RET ; RESTORE REGS AND RETURN
  4252. EXITP ENDP
  4253. PAGE
  4254. ;----------------------------------------------------------------
  4255. ;
  4256. ; BREAK KEY HANDLING
  4257. ;
  4258. BREAK:
  4259. MOV CS:ALTAH,3 ; INDICATE BREAK KEY SET
  4260. IRET
  4261. ;----------------------------------------------------------------
  4262. ;
  4263. ; CHROUT - WRITE OUT CHAR IN AL USING CURRENT ATTRIBUTE
  4264. ;
  4265. ; CALLED VIA INT 29H
  4266. ;
  4267. OUTCHR:
  4268. INT OEM_Char_Output
  4269. RET
  4270. PAGE
  4271. ;----------------------------------------------------------------
  4272. ;
  4273. ; INPUT SINGLE CHAR INTO AL
  4274. ;
  4275. ChrIn:
  4276. xor ax,ax
  4277. xchg al,ALTAH ; Get Character & Zero ALTAH
  4278. or al,al
  4279. jnz sj3
  4280. mov ah,Request_Interim ; assume interim char input
  4281. or dl,dl ; Interim chars wanted?
  4282. jnz sj0
  4283. mov ah,Request_Char ; regular whole char input
  4284. sj0:
  4285. int OEM_Kybd_Input ; Get character
  4286. or ax,ax ; Check for non-key after BREAK
  4287. jz ChrIn
  4288. or al,al ; Special Case?
  4289. jnz ChkInter
  4290. mov ALTAH,ah ; Save Special Key
  4291. sj3:
  4292. mov [InterH],0 ; reset interim flag
  4293. ret
  4294. ChkInter:
  4295. cmp ah,Hangeul_Interim ; a Hangeul interim?
  4296. jne sj3
  4297. mov [InterH],1 ; yes flag it
  4298. ret
  4299. PAGE
  4300. ;----------------------------------------------------------------
  4301. ;
  4302. ; CONSOLE READ ROUTINE
  4303. ;
  4304. ; Input:
  4305. ; CX = transfer count
  4306. ; DL = input type flag (0 = whole chars, 1 = interim allowed)
  4307. ; ES:DI = transfer addess
  4308. ;
  4309. CON$READ:
  4310. JCXZ CON$EXIT
  4311. CON$LOOP:
  4312. CALL CHRIN ; GET CHAR IN AL
  4313. STOSB ; STORE CHAR AT ES:DI
  4314. LOOP CON$LOOP
  4315. CON$EXIT:
  4316. cmp [InterH],1 ; An Intermidiate Char?
  4317. jne ExVec ; no, regulear exit
  4318. JMP HanExit ; yes, reset flag and exit new way
  4319. PAGE
  4320. ;----------------------------------------------------------------
  4321. ;
  4322. ; KEYBOARD FLUSH ROUTINE
  4323. ;
  4324. CON$FLSH:
  4325. MOV [ALTAH],0 ; Clear out holding buffer
  4326. mov [InterH],0
  4327. mov ah,Flush_Buffer
  4328. int OEM_Kybd_Input
  4329. JMP EXIT
  4330. PAGE
  4331. ;----------------------------------------------------------------
  4332. ;
  4333. ; KEYBOARD NON DESTRUCTIVE READ, NO WAIT
  4334. ; Input:
  4335. ; DL = input type flag (0 = whole chars, 1 = interim allowed)
  4336. ;
  4337. EXVEC: JMP EXIT
  4338. CONBUS: JMP BUS$EXIT
  4339. CON$RDND:
  4340. MOV AL,[ALTAH]
  4341. OR AL,AL
  4342. JNZ sj6
  4343. MOV AH,Request_Interim_Status ;Assume interim allowed
  4344. or dl,dl ; check interim flag
  4345. jnz sj4
  4346. mov ah,Requst_Std_Status ; regular status wanted
  4347. sj4:
  4348. INT OEM_Kybd_Input ; Get status
  4349. JZ CONBUS
  4350. OR AX,AX
  4351. JNZ sj6 ; CHECK FOR NULL AFTER BREAK
  4352. MOV AH,Request_Char
  4353. INT OEM_Kybd_Input ; READ THE NULL
  4354. JMP short CON$RDND ; AND GET A REAL STATUS
  4355. sj6:
  4356. MOV [InterH],0 ; not interim
  4357. sj7:
  4358. LDS BX,[PTRSAV]
  4359. MOV [BX].MEDIA,AL ; return the char to dos
  4360. cmp [InterH],0
  4361. je EXVEC
  4362. jmp HanExit
  4363. sj8:
  4364. cmp ah,Interim_Char ; a Hangeul interim?
  4365. jne sj6
  4366. mov [InterH],1
  4367. jmp short sj7
  4368. PAGE
  4369. ;----------------------------------------------------------------
  4370. ;
  4371. ; CONSOLE WRITE ROUTINE
  4372. ;
  4373. CON$WRIT:
  4374. JCXZ EXVEC
  4375. cmp dl,01h ; write and not ad cursor?
  4376. je CON$LP2
  4377. CON$LP: MOV AL,ES:[DI] ; GET CHAR
  4378. INC DI
  4379. MOV AH,Output_Char
  4380. INT CHROUT ; OUTPUT CHAR
  4381. LOOP CON$LP ; REPEAT UNTIL ALL THROUGH
  4382. JMP EXIT
  4383. CON$LP2: ; write but do not advance cursor
  4384. MOV AL,ES:[DI] ; GET CHAR
  4385. INC DI
  4386. MOV AH,Output_No_Advance
  4387. INT CHROUT
  4388. LOOP CON$LP2 ; REPEAT UNTIL ALL THROUGH
  4389. JMP EXIT
  4390. PAGE
  4391. ;----------------------------------------------------------------
  4392. ;
  4393. ; Initialization Code
  4394. ;
  4395. CON$INIT:
  4396. XOR BX,BX
  4397. MOV DS,BX
  4398. MOV BX,BRKADR
  4399. MOV WORD PTR [BX],OFFSET BREAK
  4400. MOV WORD PTR [BX+2],CS
  4401. MOV BX,CHROUT*4
  4402. MOV WORD PTR [BX],OFFSET OUTCHR
  4403. MOV WORD PTR [BX+2],CS
  4404. LDS BX,CS:[PTRSAV]
  4405. MOV WORD PTR [BX].TRANS,OFFSET CON$INIT ; SET BREAK ADDRESS
  4406. MOV [BX].TRANS+2,CS
  4407. JMP EXIT
  4408. CODE ENDS
  4409. END
  4410. APPENDIX F
  4411. MSDOS 2.25 Application Level Interface Extension
  4412. 1) System call 63H, get_lead_tbl.
  4413. This call takes an argument in register AL. This
  4414. argument determines what function will this call execute.
  4415. Valid values for the function code are 0, 1 and 2.
  4416. If AL = 0, then the call returns in DS:SI a pointer to
  4417. a table containing the lead byte ranges for the 16 bit
  4418. alphabet in question. The table consists of byte pairs that
  4419. are the boundaries for the lead bytes (both values
  4420. inclusive). The end of the table is marked by two zero byte
  4421. entries.
  4422. Example, for japanese kanji the table would look like
  4423. db 81H,9FH
  4424. db 0E0h,0FCh
  4425. db 0,0
  4426. Note that the values should be read as byte values not
  4427. as word values since otherwise the ranges would be
  4428. transposed due to the byte ordering in the 8086/88.
  4429. This table is empty in the regular version of the dos
  4430. (as there are no 16 bit characters). The table if obtained
  4431. would point to a pair of zero bytes.
  4432. If AL = 1 then the call will set (or reset) the interim
  4433. console flag in the dos depending on the value in DL. If DL
  4434. = 1, then the interim flag will be SET, and certain console
  4435. system calls will return interim characters if these are
  4436. available. If DL = 0 then the interim flag is RESET and only
  4437. final characters will be returned. The default value of the
  4438. flag is RESET. All application programs start with the flag
  4439. RESET. The flag is allways restored to the parents setting
  4440. when an application terminates.
  4441. If AL = 2 then the dos will return in DL the current
  4442. value of the console interim flag (0 if RESET, 1 if SET).
  4443. If an invalid code is used the call will reurn with
  4444. carry set and error code 0 (error_invalid_function).
  4445. IMPORTANT NOTE: This system call unlike all other
  4446. system calls make NO GUARANTEE to preserve ANY registers
  4447. other than SS:SP upon return. So care should be taken to
  4448. save all relevant registers before issuing the call. It is
  4449. advisable that an application either copy the table to its
  4450. private data area or save the pointer to the table at
  4451. initialization time. This should save considerable execution
  4452. time as there is no need to reissue the call everytime a
  4453. check for 16 bit characters is necessary, and consequently
  4454. there is no need to save any registers before issuing the
  4455. call.
  4456. 2) Console i/o system calls.
  4457. Some console i/o system calls are capable of returning
  4458. interim character information to application programs. Only
  4459. those applications that have enabled the feature through the
  4460. 63H call (function 1) will receive interim characters on
  4461. these system calls, otherwise the dos will never return
  4462. interim characters and the system calls will work as in
  4463. previous versions of 2.00.
  4464. * Call 01H, Read & Echo.
  4465. This call never returns interim characters no matter
  4466. what mode the console is on. Composition if any will take
  4467. place at the cursor. It will return when the first byte of
  4468. the final character is obtained.
  4469. * Call 06H, Direct Console i/o.
  4470. Always returns final characters, never interims. Only
  4471. returns character available when a final character is
  4472. available, not when interims are available. Composition if
  4473. any is handled as in call 01H.
  4474. * Call 07H, Direct Console Input.
  4475. Returns interim characters if one is available and the
  4476. console mode has been set to interim through the 63H call.
  4477. Interim characters are returned with the zero flag SET,
  4478. final characters have the flag RESET. In non interim support
  4479. (the default) the zero flag value is undefined.
  4480. * Call 08H, Read Keyboard.
  4481. Same as system call 07H.
  4482. * Call 0AH, Buffered Keyboard input.
  4483. Always returns a string of final characters,
  4484. composition if any, is handled by the dos.
  4485. * Call 0BH, Check Keyboard Status.
  4486. This call supports interim characters if the console
  4487. has been placed in interim mode through the ioctl call. If a
  4488. character is available (AL = 0FFH) then the zero flag will
  4489. be SET if the character is an interim, or RESET if the
  4490. character is a final character. The zero flag is undefined
  4491. if either there is no character available, or the console is
  4492. not in interim mode.
  4493. * Call 0CH, Flush Buffer, Read Keyboard.
  4494. This call will flush the type-ahead buffer and execute
  4495. the specified console i/o call. The con i/o call will work
  4496. as described above for each specific case.
  4497. * Call 3FH, Xenix Read.
  4498. This call always returns final characters, no matter
  4499. what the state of the dos. This call when directed to the
  4500. console it ends up in the buffered console input code, and
  4501. so it will act as that call (0AH) when used to read from the
  4502. console.
  4503. APPENDIX G
  4504. This file is part of what was formerly supplied with MS-DOS 2.11
  4505. as SPECIAL.DOC. It has information about undocumented COMMAND.COM
  4506. switches and the version dependent system call (GET_DPB) which
  4507. OEM's may use when writing format.
  4508. The remaining portions of this file have been incorporated into
  4509. printed MS-DOS documentation.
  4510. COMMAND invocation
  4511. COMMAND [[<drive>:]<path>] [<cttydev>] [/D] [/P] [/C <string>] [/E:nnnn]
  4512. /P If present COMMAND will be permanent, otherwise
  4513. this is a transient command.
  4514. /D If present COMMAND will not prompt for DATE and
  4515. TIME when it comes up.
  4516. d: Specifies device where command will look for
  4517. COMMAND.COM current default drive if absent.
  4518. <Path> Specifies a directory on device d: root
  4519. directory if absent.
  4520. <cttydev> Name of the CTTY device. \DEV\CON if absent
  4521. and command is permanent. The \DEV\ may be left
  4522. off if AVAILDEV is TRUE (see sysinit doc).
  4523. /C <string> If present /C must be the last switch.
  4524. This causes COMMAND to try to execute the string
  4525. as if the user had typed it at the standard input.
  4526. COMMAND executes this single command string and
  4527. then exits. If the /P switch is present it is
  4528. ignored (can't have a single command, permanent
  4529. COMMAND). NOTE: ALL of the text on the command
  4530. line after the /C is just passed on. It is not
  4531. processed for more arguments, this is why /C must
  4532. be last.
  4533. /E:nnnn Set the environment size to nnnn (specified in
  4534. decimal bytes). The environment size can be between
  4535. 128 bytes and 32768 bytes. NOTE: This feature is only
  4536. available in versions of MS-DOS starting with 3.20.
  4537. GET_DPB UNDOCUMENTED SYSTEM CALL. THIS CALL MAY BE USED
  4538. TO GET A POINTER TO THE PHYSICAL LOCATION OF THE DISK DEVICE
  4539. DRIVER. CONSULT THE DBP STRUCTURE DOCUMENTED IN DOSSYM.ASM
  4540. +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  4541. | C A V E A T P R O G R A M M E R |
  4542. | |
  4543. Name: * GET_DPB - get pointer to drive parameter
  4544. block
  4545. Assembler usage:
  4546. MOV AH,GET_DPB
  4547. INT 21h
  4548. ; DS:BX has address of drive parameter block
  4549. Description:
  4550. Return pointer to default drive parameter block.
  4551. Error returns:
  4552. None.
  4553. Assembler usage:
  4554. MOV DL,DrvNUM
  4555. MOV AH,32H
  4556. INT 21h
  4557. ; DS:BX has address of drive parameter block
  4558. Description:
  4559. Return pointer to drive parameter block for drive
  4560. designated in DL (0=Default, A=1, B=2 ...)
  4561. Error returns:
  4562. AL = FF
  4563. The drive given in DL is invalid.
  4564. | |
  4565. | C A V E A T P R O G R A M M E R |
  4566. +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  4567. APPENDIX H
  4568. This material was taken from the MS-DOS 3.10 Programmer's Reference
  4569. Manual. It is intended be used with the MS-DOS 2.XX/3.XX Adaptation
  4570. Guide.
  4571. 7.1 INTRODUCTION
  4572. This chapter describes recommended MS-DOS 3.1 programming
  4573. procedures. By using these programming hints, you can
  4574. ensure compatibility with future versions of MS-DOS.
  4575. The hints are organized into the following categories:
  4576. Interrupts
  4577. System Calls
  4578. Device Management
  4579. Memory Management
  4580. Process Management
  4581. File and Directory Management
  4582. Miscellaneous
  4583. 7.2 INTERRUPTS
  4584. Never explicitly issue Interrupt 22H (Terminate Process Exit
  4585. Address).
  4586. This should only be done by the DOS. To change the
  4587. terminate address, use Function 35H (Get Interrupt
  4588. Vector) to get the current address and save it, then
  4589. use Function 25H (Set Interrupt Vector) to change
  4590. the Interrupt 22H entry in the vector table to point
  4591. to the new terminate address.
  4592. PROGRAMMING HINTS Page 7-2
  4593. Use Interrupt 24H (Critical Error Handler Address) with
  4594. care.
  4595. The Interrupt 24H handler must preserve the ES
  4596. register.
  4597. Only system calls 01H-0CH can be made by an
  4598. Interrupt 24H handler. Making any other calls will
  4599. destroy the MS-DOS stack and prevent successful use
  4600. of the Retry or Ignore options.
  4601. The registers SS, SP, DS, BX, CX, and DX must be
  4602. preserved when using the Retry or Ignore options.
  4603. When an Interrupt 24H (Critical Error Handler Address) is
  4604. received, always IRET back to MS-DOS with one of the
  4605. standard responses.
  4606. Programs that do not IRET from Interrupt 24H leave
  4607. the system in an unpredictable state until a
  4608. function call other than 01H-0CH is made. The
  4609. Ignore option may leave data in internal system
  4610. buffers that is incorrect or invalid.
  4611. Avoid trapping Interrupt 23H (Control-C Handler Address) and
  4612. Interrupt 24H (Critical Error Handler Address). Don't rely
  4613. on trapping errors via Interrupt 24H as part of a copy
  4614. protection scheme.
  4615. These might not be included in future releases of
  4616. the operating system.
  4617. Interrupt 23H (Control-C Handler Address) must never be
  4618. issued by a user program.
  4619. Interrupt 23H must be issued only by MS-DOS.
  4620. Save any registers your program uses before issuing
  4621. Interrupt 25H (Absolute Disk Read) or Interrupt 26H
  4622. (Absolute Disk Write).
  4623. These interrupts destroy all registers except for
  4624. the segment registers.
  4625. Avoid writing or reading an interrupt vector
  4626. directly to or from memory.
  4627. Use Functions 25H and 35H (Set Interrupt Vector and Get
  4628. Interrupt Vector) to set and get values in the interrupt
  4629. table.
  4630. PROGRAMMING HINTS Page 7-3
  4631. 7.3 SYSTEM CALLS
  4632. Use new system calls.
  4633. Avoid using system calls that have been superseded
  4634. by new calls unless a program must maintain backward ____
  4635. compatibility with pre-2.0 versions of MS-DOS. See
  4636. Section 1.8, "Old System Calls," of this manual for
  4637. a list of these new calls.
  4638. Avoid using system calls 01H-0CH and 26H (Create New PSP).
  4639. Use the new "tools" approach for reading and writing
  4640. on standard input and output. Use Function 4B00H
  4641. (Load and Execute Program) instead of 26H to execute
  4642. a child process.
  4643. Use file-sharing calls if more than one process is in
  4644. effect.
  4645. See "File Sharing," in Section 1.5.2, "File-Related
  4646. Function Requests" in Chapter 1 for more
  4647. information.
  4648. Use networking calls where appropriate.
  4649. Some forms of IOCTL can only be used with Microsoft
  4650. Networks. See Section 1.6, "Microsoft Networks," in
  4651. this manual for a list of these calls.
  4652. When selecting a disk with Function 0EH (Select Disk), treat
  4653. the value returned in AL with care.
  4654. The value in AL specifies the maximum number of
  4655. logical drives; it does not specify which drives
  4656. are valid.
  4657. 7.4 DEVICE MANAGEMENT
  4658. Use installable device drivers.
  4659. MS-DOS provides a modular device driver structure
  4660. for the BIOS, allowing you to configure and install
  4661. device drivers at boot time. Block device drivers
  4662. transmit a block of data at a time, while character
  4663. device drivers transmit a byte of data at a time.
  4664. Examples of both types of device drivers are given
  4665. in Chapter 2, "MS-DOS Device Drivers."
  4666. PROGRAMMING HINTS Page 7-4
  4667. Use buffered I/O.
  4668. The device drivers can handle streams of data up to
  4669. 64K. When sending a large amount of output to the
  4670. screen, you can send it with one system call. This
  4671. will increase performance.
  4672. Programs that use direct console I/O via Function 06H and
  4673. 07H (Direct Console I/O and Direct Console Input) and that
  4674. want to read Control-C as data should ensure that Control-C
  4675. checking is off.
  4676. The program should ensure that Control-C checking is
  4677. off by using Function 33H (Control-C Check).
  4678. Be compatible with international support.
  4679. To provide support for international character sets,
  4680. MS-DOS recognizes all possible byte values as
  4681. significant characters in filenames and data
  4682. streams. Pre-2.x versions ignored the high bit in
  4683. the MS-DOS filename.
  4684. 7.5 MEMORY MANAGEMENT
  4685. Use memory management.
  4686. MS-DOS keeps track of allocated memory by writing a
  4687. memory control block at the beginning of each area
  4688. of memory. Programs should use Functions 48H
  4689. (Allocate Memory), 49H (Free Allocated Memory), and
  4690. 4AH (Set Block) to release unneeded memory.
  4691. This will allow for future compatibility.
  4692. See Section 1.3, "Memory Management," for more
  4693. information.
  4694. Only use allocated memory.
  4695. Don't directly access memory that was not provided
  4696. as a result of a system call. Do not use fixed
  4697. addressing, use only relative references.
  4698. A program that uses memory that has not been
  4699. allocated to it may destroy other memory control
  4700. blocks or cause other applications to fail.
  4701. PROGRAMMING HINTS Page 7-5
  4702. 7.6 PROCESS MANAGEMENT
  4703. Use the EXEC Function Call to load and execute programs.
  4704. The EXEC Function (4B00H) is the preferred way to
  4705. load programs and program overlays. Using the EXEC
  4706. call instead of hard-coding information about how to
  4707. load an .EXE file (or always assuming that your file
  4708. is a .COM file) will isolate your program from
  4709. changes in future releases of MS-DOS and .EXE file
  4710. formats.
  4711. Use Function 31H (Keep Process), instead of Interrupt 27H
  4712. (Terminate But Stay Resident). Function 31H allows programs
  4713. to terminate and stay resident that are greater than 64K.
  4714. Programs should terminate using End Process (4CH).
  4715. Programs that terminate by
  4716. - a long jump to offset 0 in the PSP,
  4717. - issuing an Interrupt 20H with CS:0 pointing at the PSP,
  4718. - issuing an Interrupt 21H with AH=0, CS:0 pointing at the
  4719. PSP, or
  4720. - a long call to location 50H in the PSP with AH=0
  4721. must ensure that the CS register contains the segment
  4722. address of the PSP.
  4723. 7.7 FILE AND DIRECTORY MANAGEMENT
  4724. Use the MS-DOS file management system.
  4725. Using the MS-DOS file system will ensure program
  4726. compatibility with future MS-DOS versions through
  4727. compatible disk formats and consistent internal
  4728. storage. This will ensure compatibility with future
  4729. MS-DOS versions.
  4730. Use file handles instead of FCBs.
  4731. A handle is a 16-bit number that is returned by
  4732. MS-DOS when a file is opened or created using
  4733. Functions 3CH, 3DH, 5AH, or 5BH (Create Handle, Open
  4734. Handle, Create Temporary File, or Create New File).
  4735. The MS-DOS file-related function requests that use
  4736. handles are listed in Table 1.5 in Chapter 1,
  4737. "System Calls."
  4738. These calls should be used instead of the old
  4739. file-related functions that use FCBs (file control
  4740. blocks). This is because a file operation can
  4741. simply pass its handle rather than having to
  4742. PROGRAMMING HINTS Page 7-6
  4743. maintain FCB information. If FCBs must be used, be
  4744. sure the program closes them and does not move them
  4745. around in memory.
  4746. Close all files that have changed in length before issuing
  4747. an Interrupt 20H (Program Terminate), Function 00H
  4748. (Terminate Program), Function 4CH (End Process), or Function
  4749. 0DH (Reset Disk).
  4750. If a changed file is not closed, its length will not
  4751. be recorded correctly in the directory.
  4752. Close all files when they are no longer needed.
  4753. Closing unneeded files will optimize performance in
  4754. a networking environment.
  4755. Only change disks if all files on the disk are closed.
  4756. Information in internal system buffers may be
  4757. written incorrectly to a changed disk.
  4758. 7.7.1 Locking Files
  4759. Programs should not rely on being denied access to a locked
  4760. region.
  4761. Determine the status of the region by attempting to
  4762. lock it, and examine the error code.
  4763. Programs should not close a file with a locked region or
  4764. terminate with an open file that contains a locked region.
  4765. The result is undefined. Programs that might be
  4766. terminated by an Interrupt 23H or Interrupt 24H
  4767. (Control-C Handler Address or Critical Error Handler
  4768. Address) should trap these interrupts and unlock any
  4769. locked regions before exiting.
  4770. 7.8 MISCELLANEOUS
  4771. Avoid timing dependencies.
  4772. Various machines use CPUs of different speeds.
  4773. Also, programs that rely upon the speed of the clock
  4774. for timing will not be dependable in a networking
  4775. environment.
  4776. PROGRAMMING HINTS Page 7-7
  4777. Use the documented interface to the operating system. If
  4778. either the hardware or media change, the operating system
  4779. will be able to use the features without modification.
  4780. Don't use the OEM (Original Equipment Manufacturer)
  4781. -provided ROM support.
  4782. Don't directly address the video memory.
  4783. Don't use undocumented function calls, interrupts,
  4784. or features. These items may change or not continue
  4785. to exist in future versions of MS-DOS. Use of these
  4786. features would make your program highly
  4787. non-portable.
  4788. Use the .EXE format rather than the .COM format.
  4789. .EXE files are relocatable and .COM files are direct
  4790. memory images that load at a specific place and have
  4791. no room for additional control information to be
  4792. placed in them. .EXE files have headers that can be
  4793. expanded for compatibility with future versions of
  4794. MS-DOS.
  4795. Use the environment to pass information to applications.
  4796. The environment allows a parent process to pass
  4797. information to a child process. COMMAND.COM is
  4798. usually the parent process to every application, so
  4799. default drive and path information can easily be
  4800. passed to the application.
  4801. GLOSSARY OF MS-DOS TERMS
  4802. Allocation Unit
  4803. (See Cluster)
  4804. Arena
  4805. MS-DOS uses a software memory management scheme.
  4806. Blocks in memory are either owned by processes or
  4807. are free. An owned block has an ID number, which
  4808. is the initial paragraph of the Program Segment
  4809. GLOSSARY OF MS-DOS TERMS
  4810. Prefix of a process in memory (your program). Each
  4811. block has a size as well. When your process is in
  4812. memory, there is a 16-byte arena block which
  4813. identifies it and specifies how much memory is
  4814. allocated.
  4815. ASCIZ
  4816. Any null (zero byte) terminated ASCII string.
  4817. Cluster
  4818. The storage unit that MS-DOS uses to allocate space
  4819. for files on a disk. All files are allocated in
  4820. multiples of clusters. A cluster must be a power
  4821. of two sectors (i.e., 1, 2, 4, 8 ... ). This term
  4822. is synonymous with allocation unit.
  4823. Block device drivers perform I/O in
  4824. sectors, not clusters.
  4825. Cooked/Raw Mode
  4826. Character devices have two modes that have
  4827. significance when performing I/O via the Read
  4828. Handle and Write Handle calls (Functions 3FH and
  4829. 40H). These are "raw" and "cooked" mode. A device
  4830. driver can be set to raw mode via the IOCTL
  4831. Function Request 44H.
  4832. Cooked mode input is buffered input with echoing to
  4833. the screen (if console) and Control-C checking.
  4834. Cooked mode input of a certain number of characters
  4835. will return when the specified number of characters
  4836. is returned or a carriage return is typed. Cooked
  4837. mode output performs Control-C checking between
  4838. characters.
  4839. Raw mode I/O is very fast. When raw mode I/O of
  4840. "n" characters is requested, MS-DOS passes the
  4841. request directly to the indicated device driver.
  4842. The device driver does not return to MS-DOS until
  4843. the I/O has completed. Characters are written or
  4844. read directly from the process buffer. No checking
  4845. of any kind is performed. No characters have any
  4846. significance, including Control-C.
  4847. GLOSSARY OF MS-DOS TERMS
  4848. For example, if the requesting program puts a
  4849. device in raw mode and requests a write of 50,000
  4850. characters to the AUX device, the device driver
  4851. will get a request from MS-DOS to write 50,000
  4852. characters from the buffer located at the DWORD
  4853. transfer address. The driver will not return until
  4854. the request has completed.
  4855. In cooked mode, MS-DOS performs a Control-C check
  4856. at the console after each single character write.
  4857. This is an overhead of 50,000 Control-C checks.
  4858. Environment
  4859. The environment is a maximum of 32K data area which
  4860. consists of ASCIZ strings of the form:
  4861. AAAA=BBBBBBB. The end of the environment is marked
  4862. by two consecutive nulls. The word at 2CH in the
  4863. Program Segment Prefix points to the segment
  4864. containing the start of a program's environment.
  4865. New variables can be added to the environment by
  4866. using the MS-DOS Set command. Since nulls have
  4867. significance, the environment cannot be used for
  4868. storing binary data.
  4869. When a parent process (such as COMMAND.COM)
  4870. executes a child process (any other program), the
  4871. child is given a copy of the parent's environment.
  4872. Parameters such as Prompt, which specifies the
  4873. style of prompt used by COMMAND.COM, are stored in
  4874. the environment. Application programs can use the
  4875. environment to find overlays or special files which
  4876. may not be located in the current directory.
  4877. COMMAND.COM uses this technique to examine the
  4878. elements of the Path looking for binaries and batch
  4879. files. Of course the application program must be
  4880. specifically coded to find the environment and
  4881. parse it for variables.
  4882. FATID Byte
  4883. The FATID byte is the first byte of the File
  4884. Allocation Table that starts at the sector
  4885. immediately after the reserved sectors of the disk.
  4886. The FATID byte was used by OEMs in MS-DOS 1.x for
  4887. identification of disk media. This byte should be
  4888. between F8H and FFH. To read MS-DOS 1.x disks, one
  4889. must read this byte, determine which of the four
  4890. predefined FATID bytes is present and return a
  4891. pointer to the appropriate BPB. This method of
  4892. GLOSSARY OF MS-DOS TERMS
  4893. determining media is less general and less
  4894. desirable than the BPB table method (see MEDIA ID
  4895. Byte).
  4896. File Handle
  4897. In versions of MS-DOS that are 2.0 and higher,
  4898. there is a system file table set up at boot time.
  4899. By the time COMMAND.COM gets control, all of the
  4900. character devices have been entered into the system
  4901. file table. The first five handles are initialized
  4902. as follows.
  4903. HANDLE XENIX NAME DEFAULT SETTING
  4904. 0 Standard Input CON
  4905. 1 Standard Output CON
  4906. 2 Standard Error CON
  4907. 3 Standard AUX AUX
  4908. 4 Standard PRN PRN
  4909. As new files are opened via XENIX-compatible calls,
  4910. they are assigned the first available numbers.
  4911. When COMMAND.COM executes a program, the child
  4912. process inherits all of the handles that
  4913. COMMAND.COM has open. Typing
  4914. prog < infyle > outfyle
  4915. on the command line means that you want PROG to
  4916. read its input from INFYLE and write its output to
  4917. OUTFYLE instead of to console out. COMMAND.COM
  4918. will close handle 0 and open INFYLE; it will DUP
  4919. handle 0. It will then close handle 1, standard
  4920. out, and open OUTFYLE (which is assigned to
  4921. standard out). COMMAND will exec PROG, which
  4922. inherits this environment. When PROG reads from
  4923. standard in, or writes to standard out, it reads
  4924. from and writes to INFYLE and OUTFYLE,
  4925. respectively.
  4926. If a child is executed, it inherits the files of
  4927. its parent. The converse is not true. When a
  4928. child process which opens AUX as standard in and
  4929. PRN as standard out returns, the parent does not ___
  4930. inherit the files of its child.
  4931. GLOSSARY OF MS-DOS TERMS
  4932. MEDIA ID Byte
  4933. The MEDIA ID byte is the byte in the Bios Parameter
  4934. Block (BPB) located at offset 0AH. The MEDIA ID
  4935. byte may have any value between 0 and 0FFH. It may
  4936. or may not have the same value as the FATID byte.
  4937. The major significance of the MEDIA ID byte is that
  4938. there be a one-to-one relationship between unique
  4939. MEDIA ID bytes and disk formats. For disk
  4940. compatibility with other OEMs as well as with
  4941. future releases of MS-DOS, Microsoft recommends
  4942. that the BPB table be located at offset 0BH in the
  4943. first reserved (boot) sector. OEMs may register
  4944. their media byte/format combinations with OEM
  4945. Customer Support. The BPB technique of determining
  4946. disk format is much more general than the limited
  4947. FATID byte method and is the preferred method.
  4948. The significance of the media byte and FATID byte
  4949. depends on whether you have decided to make your
  4950. block device driver IBM format-compatible. You
  4951. must indicate this by setting bit 13 in the device
  4952. driver header. This will alter the way MS-DOS
  4953. performs the GET BPB device call. With the NON
  4954. FATID bit set, you can support various media,
  4955. including IBM format media. If the device driver
  4956. is IBM-format compatible, use FATID bytes to
  4957. determine the media in the drive. The
  4958. correspondence between FATID bytes and various
  4959. media is defined in the MS-DOS Programmer's ______ ____________
  4960. Reference Manual. _________ ______
  4961. If your system is not IBM Format-compatible, you
  4962. are given a pointer to a one-sector scratch buffer
  4963. when your block device gets called by MS-DOS to do
  4964. a BUILD BPB. Follow these steps:
  4965. 1. Read the boot sector of the disk into that
  4966. buffer and check the first byte. If it is an
  4967. E9H, it is the first byte of a 3-byte JMP and
  4968. there is a BIOS Parameter Block table in the
  4969. boot sector.
  4970. Alternately, EBH may be the first byte. This
  4971. is also a 3-byte JMP (actually, a 2-byte JMP
  4972. followed by a NOP).
  4973. GLOSSARY OF MS-DOS TERMS
  4974. 2. Return a pointer to the BPB. Set the status
  4975. word and return. If the first byte of the boot
  4976. sector is not an E9H, then there is not a BPB
  4977. table in the boot sector. You can assume that
  4978. the disk is an IBM format disk and the FAT
  4979. begins with the second sector of the disk.
  4980. Read the FAT into the scratch buffer and check
  4981. the first byte. Determine which one of the
  4982. four defined FATID bytes it is, and return a
  4983. pointer to the appropriate BPB.
  4984. Refer to the MS-DOS Programmer's Reference ______ ____________ _________
  4985. Manual for a list of valid FATID bytes. Any ______
  4986. other media should be defined in the boot
  4987. sector and should use a FATID byte of FFH.
  4988. Paragraph
  4989. Any location in the memory of the 8086 which has an
  4990. address that is a multiple of 16 (i.e., 0, 16, 32).
  4991.