diff options
Diffstat (limited to 'v2.0/bin')
| -rw-r--r-- | v2.0/bin/ANSI.DOC | bin | 0 -> 6784 bytes | |||
| -rw-r--r-- | v2.0/bin/CHKDSK.COM | bin | 0 -> 6330 bytes | |||
| -rw-r--r-- | v2.0/bin/COMMAND.COM | bin | 0 -> 15480 bytes | |||
| -rw-r--r-- | v2.0/bin/CONFIG.DOC | bin | 0 -> 3456 bytes | |||
| -rw-r--r-- | v2.0/bin/CREF.EXE | bin | 0 -> 13824 bytes | |||
| -rw-r--r-- | v2.0/bin/DEBUG.COM | bin | 0 -> 11764 bytes | |||
| -rw-r--r-- | v2.0/bin/DEVDRIV.DOC | 802 | ||||
| -rw-r--r-- | v2.0/bin/DISKCOPY.COM | bin | 0 -> 1419 bytes | |||
| -rw-r--r-- | v2.0/bin/DOSPATCH.TXT | 62 | ||||
| -rw-r--r-- | v2.0/bin/EDLIN.COM | bin | 0 -> 4389 bytes | |||
| -rw-r--r-- | v2.0/bin/EXE2BIN.EXE | bin | 0 -> 1649 bytes | |||
| -rw-r--r-- | v2.0/bin/FC.EXE | bin | 0 -> 2553 bytes | |||
| -rw-r--r-- | v2.0/bin/FILBP.PAS | bin | 0 -> 6144 bytes | |||
| -rw-r--r-- | v2.0/bin/FIND.EXE | bin | 0 -> 5796 bytes | |||
| -rw-r--r-- | v2.0/bin/FORMAT.DOC | 393 | ||||
| -rw-r--r-- | v2.0/bin/FORMAT.OBJ | bin | 0 -> 4864 bytes | |||
| -rw-r--r-- | v2.0/bin/FORMES.OBJ | bin | 0 -> 1152 bytes | |||
| -rw-r--r-- | v2.0/bin/INCOMP.DOC | bin | 0 -> 2688 bytes | |||
| -rw-r--r-- | v2.0/bin/INT24.DOC | bin | 0 -> 4224 bytes | |||
| -rw-r--r-- | v2.0/bin/LINK.EXE | bin | 0 -> 42368 bytes | |||
| -rw-r--r-- | v2.0/bin/MASM.EXE | bin | 0 -> 77440 bytes | |||
| -rw-r--r-- | v2.0/bin/MORE.COM | bin | 0 -> 4364 bytes | |||
| -rw-r--r-- | v2.0/bin/MSDOS.SYS | bin | 0 -> 16690 bytes | |||
| -rw-r--r-- | v2.0/bin/PRINT.COM | bin | 0 -> 3808 bytes | |||
| -rw-r--r-- | v2.0/bin/PROFIL.OBJ | bin | 0 -> 2304 bytes | |||
| -rw-r--r-- | v2.0/bin/PROFILE.DOC | bin | 0 -> 3968 bytes | |||
| -rw-r--r-- | v2.0/bin/PROHST.EXE | bin | 0 -> 41728 bytes | |||
| -rw-r--r-- | v2.0/bin/PROHST.PAS | 403 | ||||
| -rw-r--r-- | v2.0/bin/QUICK.DOC | bin | 0 -> 3456 bytes | |||
| -rw-r--r-- | v2.0/bin/README.DOC | 177 | ||||
| -rw-r--r-- | v2.0/bin/RECOVER.COM | bin | 0 -> 2277 bytes | |||
| -rw-r--r-- | v2.0/bin/SORT.EXE | bin | 0 -> 1216 bytes | |||
| -rw-r--r-- | v2.0/bin/SYS.COM | bin | 0 -> 850 bytes | |||
| -rw-r--r-- | v2.0/bin/SYSCALL.DOC | 1657 | ||||
| -rw-r--r-- | v2.0/bin/SYSIMES.OBJ | bin | 0 -> 384 bytes | |||
| -rw-r--r-- | v2.0/bin/SYSINIT.DOC | bin | 0 -> 3072 bytes | |||
| -rw-r--r-- | v2.0/bin/SYSINIT.OBJ | bin | 0 -> 3328 bytes | |||
| -rw-r--r-- | v2.0/bin/UTILITY.DOC | 813 |
38 files changed, 4307 insertions, 0 deletions
diff --git a/v2.0/bin/ANSI.DOC b/v2.0/bin/ANSI.DOC new file mode 100644 index 0000000..040d9d2 --- /dev/null +++ b/v2.0/bin/ANSI.DOC | |||
| Binary files differ | |||
diff --git a/v2.0/bin/CHKDSK.COM b/v2.0/bin/CHKDSK.COM new file mode 100644 index 0000000..152bc38 --- /dev/null +++ b/v2.0/bin/CHKDSK.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/COMMAND.COM b/v2.0/bin/COMMAND.COM new file mode 100644 index 0000000..820f393 --- /dev/null +++ b/v2.0/bin/COMMAND.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/CONFIG.DOC b/v2.0/bin/CONFIG.DOC new file mode 100644 index 0000000..bfb1985 --- /dev/null +++ b/v2.0/bin/CONFIG.DOC | |||
| Binary files differ | |||
diff --git a/v2.0/bin/CREF.EXE b/v2.0/bin/CREF.EXE new file mode 100644 index 0000000..a88c2fa --- /dev/null +++ b/v2.0/bin/CREF.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/DEBUG.COM b/v2.0/bin/DEBUG.COM new file mode 100644 index 0000000..41d127b --- /dev/null +++ b/v2.0/bin/DEBUG.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/DEVDRIV.DOC b/v2.0/bin/DEVDRIV.DOC new file mode 100644 index 0000000..3c82793 --- /dev/null +++ b/v2.0/bin/DEVDRIV.DOC | |||
| @@ -0,0 +1,802 @@ | |||
| 1 | MS-DOS 2.0 Device Drivers | ||
| 2 | |||
| 3 | INTRODUCTION | ||
| 4 | |||
| 5 | In the past, DOS-device driver (BIOS for those who are | ||
| 6 | familiar with CP/M) communication has been mediated with | ||
| 7 | registers and a fixed-address jump-table. This approach | ||
| 8 | has suffered heavily from the following two observations: | ||
| 9 | |||
| 10 | o The old jump-table ideas of the past are fixed in | ||
| 11 | scope and allow no extensibility. | ||
| 12 | |||
| 13 | o The past device driver interfaces have been written | ||
| 14 | without regard for the true power of the hardware. | ||
| 15 | When a multitasking system or interrupt driven | ||
| 16 | hardware is installed a new BIOS must be written | ||
| 17 | largely from scratch. | ||
| 18 | |||
| 19 | In MSDOS 2.0, the DOS-device driver interface has changed | ||
| 20 | from the old jump-table style to one in which the device | ||
| 21 | drivers are linked together in a list. This allows new | ||
| 22 | drivers for optional hardware to be installed (and even | ||
| 23 | written) in the field by other vendors or the user himself. | ||
| 24 | This flexibility is one of the major new features of MS-DOS | ||
| 25 | 2.0. | ||
| 26 | |||
| 27 | Each driver in the chain defines two entry points; the | ||
| 28 | strategy routine and the interrupt routine. The 2.0 DOS | ||
| 29 | does not really make use of two entry points (it simply calls | ||
| 30 | strategy, then immediately calls interrupt). This dual entry | ||
| 31 | point scheme is designed to facilitate future multi-tasking | ||
| 32 | versions of MS-DOS. In multi-tasking environments I/O must | ||
| 33 | be asynchronous, to accomplish this the strategy routine | ||
| 34 | will be called to queue (internally) a request and return | ||
| 35 | quickly. It is then the responsibility of the interrupt | ||
| 36 | routine to perform the actual I/O at interrupt time by picking | ||
| 37 | requests off the internal queue (set up by the strategy | ||
| 38 | routine), and process them. When a request is complete, | ||
| 39 | it is flagged as "done" by the interrupt routine. The DOS | ||
| 40 | periodically scans the list of requests looking for ones | ||
| 41 | flagged as done, and "wakes up" the process waiting for the | ||
| 42 | completion of the request. | ||
| 43 | |||
| 44 | In order for requests to be queued as above it is no | ||
| 45 | longer sufficient to pass I/O information in registers, since | ||
| 46 | many requests may be pending at any one time. Therefore | ||
| 47 | the new device interface uses data "packets" to pass request | ||
| 48 | information. A device is called with a pointer to a packet, | ||
| 49 | this packet is linked into a global chain of all pending | ||
| 50 | I/O requests maintained by the DOS. The device then links | ||
| 51 | the packet into its own local chain of requests for this | ||
| 52 | particular device. The device interrupt routine picks | ||
| 53 | requests of the local chain for processing. The DOS scans | ||
| 54 | the global chain looking for completed requests. These | ||
| 55 | packets are composed of two pieces, a static piece which | ||
| 56 | has the same format for all requests (called the static | ||
| 57 | request header), which is followed by information specific | ||
| 58 | to the request. Thus packets have a variable size and format. | ||
| 59 | |||
| 60 | At this points it should be emphasized that MS-DOS 2.0 | ||
| 61 | does not implement most of these features, as future versions | ||
| 62 | will. There is no global or local queue. Only one request | ||
| 63 | is pending at any one time, and the DOS waits for this current | ||
| 64 | request to be completed. For 2.0 it is sufficient for the | ||
| 65 | strategy routine to simply store the address of the packet | ||
| 66 | at a fixed location, and for the interrupt routine to then | ||
| 67 | process this packet by doing the request and returning. | ||
| 68 | Remember: the DOS just calls the strategy routine and then | ||
| 69 | immediately calls the interrupt routine, it is assumed that | ||
| 70 | the request is completed when the interrupt routine returns. | ||
| 71 | This additional functionality is defined at this time so | ||
| 72 | that people will be aware and thinking about the future. | ||
| 73 | |||
| 74 | |||
| 75 | FORMAT OF A DEVICE DRIVER | ||
| 76 | |||
| 77 | A device driver is simply a relocatable memory image | ||
| 78 | with all of the code in it to implement the device (like | ||
| 79 | a .COM file, but not ORGed at 100 Hex). In addition it has | ||
| 80 | a special header at the front of it which identifies it as | ||
| 81 | a device, defines the strategy and interrupt entry points, | ||
| 82 | and defines various attributes. It should also be noted | ||
| 83 | that there are two basic types of devices. | ||
| 84 | |||
| 85 | The first is character devices. These are devices which | ||
| 86 | are designed to do character I/O in a serial manner like | ||
| 87 | CON, AUX, and PRN. These devices are named (ie. CON, AUX, | ||
| 88 | CLOCK, etc.), and users may open channels (FCBs) to do I/O | ||
| 89 | to them. | ||
| 90 | |||
| 91 | The second class of devices is block devices. These | ||
| 92 | devices are the "disk drives" on the system, they can do | ||
| 93 | random I/O in pieces called blocks (usually the physical | ||
| 94 | sector size) and hence the name. These devices are not | ||
| 95 | "named" as the character devices are, and therefore cannot | ||
| 96 | be "opened" directly. Instead they are "mapped" via the | ||
| 97 | drive letters (A,B,C, etc.). | ||
| 98 | |||
| 99 | Block devices also have units. In other words a single | ||
| 100 | driver may be responsible for one or more disk drives. For | ||
| 101 | instance block device driver ALPHA (please note that we cannot | ||
| 102 | actually refer to block devices by a name!) may be | ||
| 103 | responsible for drives A,B,C and D, this simply means that | ||
| 104 | it has four units (0-3) defined and therefore takes up four | ||
| 105 | drive letters. Which units correspond to which drive letters | ||
| 106 | is determined by the position of the driver in the chain | ||
| 107 | of all drivers: if driver ALPHA is the first block driver | ||
| 108 | in the device chain, and it defines 4 units (0-3), then they | ||
| 109 | will be A,B,C and D. If BETA is the second block driver | ||
| 110 | and defines three units (0-2), then they will be E,F and | ||
| 111 | G and so on. MS-DOS 2.0 is not limited to 16 block device | ||
| 112 | units, as previous versions were. The theoretical limit | ||
| 113 | is 63 (2^6 - 1), but it should be noted that after 26 the | ||
| 114 | drive letters get a little strange (like ] \ and ^). NOTE: | ||
| 115 | Character devices cannot define multiple units (this because | ||
| 116 | they have only one name). | ||
| 117 | |||
| 118 | |||
| 119 | Here is what that special device header looks like: | ||
| 120 | |||
| 121 | +--------------------------------------+ | ||
| 122 | | DWORD Pointer to next device | | ||
| 123 | | (Must be set to -1) | | ||
| 124 | +--------------------------------------+ | ||
| 125 | | WORD Attributes | | ||
| 126 | | Bit 15 = 1 if char device 0 if blk | | ||
| 127 | | if bit 15 is 1 | | ||
| 128 | | Bit 0 = 1 if Current sti device | | ||
| 129 | | Bit 1 = 1 if Current sto output | | ||
| 130 | | Bit 2 = 1 if Current NUL device | | ||
| 131 | | Bit 3 = 1 if Current CLOCK dev | | ||
| 132 | | Bit 4 = 1 if SPECIAL | | ||
| 133 | | Bit 14 is the IOCTL bit (see below) | | ||
| 134 | | Bit 13 is the NON IBM FORMAT bit | | ||
| 135 | +--------------------------------------+ | ||
| 136 | | WORD Pointer to Device strategy | | ||
| 137 | | entry point | | ||
| 138 | +--------------------------------------+ | ||
| 139 | | WORD Pointer to Device interrupt | | ||
| 140 | | entry point | | ||
| 141 | +--------------------------------------+ | ||
| 142 | | 8-BYTE character device name field | | ||
| 143 | | Character devices set a device name | | ||
| 144 | | For block devices the first byte is | | ||
| 145 | | The number of units | | ||
| 146 | +--------------------------------------+ | ||
| 147 | |||
| 148 | Note that the device entry points are words. They must | ||
| 149 | be offsets from the same segment number used to point to | ||
| 150 | this table. Ie. if XXX.YYY points to the start of this | ||
| 151 | table, then XXX.strategy and XXX.interrupt are the entry | ||
| 152 | points. | ||
| 153 | |||
| 154 | A word about the Attribute field. This field is used | ||
| 155 | most importantly to tell the system whether this device is | ||
| 156 | a block or character device (bit 15). Most of other bits | ||
| 157 | are used to give selected character devices certain special | ||
| 158 | treatment (NOTE: these bits mean nothing on a block device). | ||
| 159 | Let's say a user has a new device driver which he wants to | ||
| 160 | be the standard input and output. Besides just installing | ||
| 161 | the driver he needs to tell SYSINIT (and the DOS) that he | ||
| 162 | wishes his new driver to override the current sti and sto | ||
| 163 | (the "CON" device). This is accomplished by setting the | ||
| 164 | attributes to the desired characteristics, so he would set | ||
| 165 | Bits 0 and 1 to 1 (note that they are separate!!). Similarly | ||
| 166 | a new CLOCK device could be installed by setting that | ||
| 167 | attribute, see the section at the end on the CLOCK device. | ||
| 168 | NOTE: that although there is a NUL device attribute, the | ||
| 169 | NUL device cannot be re-assigned. This attribute exists | ||
| 170 | for the DOS so that it can tell if the NUL device is being | ||
| 171 | used. | ||
| 172 | |||
| 173 | The NON IBM FORMAT bit applies only to block devices | ||
| 174 | and effects the operation of the get BPB device call (see | ||
| 175 | below). | ||
| 176 | |||
| 177 | The other bit of interest is the IOCTL bit which has | ||
| 178 | meaning on character or block devices. This bit tells the | ||
| 179 | DOS whether this device can handle control strings (via the | ||
| 180 | IOCTL system call). | ||
| 181 | |||
| 182 | If a driver cannot process control strings, it should | ||
| 183 | initially set this bit to 0. This tells the DOS to return | ||
| 184 | an error if an attempt is made (via IOCTL system call) to | ||
| 185 | send or receive control strings to this device. A device | ||
| 186 | which can process control strings should initialize it to | ||
| 187 | 1. For drivers of this type, the DOS will make calls to | ||
| 188 | the IOCTL INPUT and OUTPUT device functions to send and | ||
| 189 | receive IOCTL strings (see IOCTL in the SYSTEM-CALLS | ||
| 190 | document). | ||
| 191 | |||
| 192 | The IOCTL functions allow data to be sent and received | ||
| 193 | by the device itself for its own use (to set baud rate, stop | ||
| 194 | bits, form length etc., etc.), instead of passing data over | ||
| 195 | the device channel as a normal read or write does. The | ||
| 196 | interpretation of the passed information is up to the device, | ||
| 197 | but it MUST NOT simply be treated as a normal I/O. | ||
| 198 | |||
| 199 | The SPECIAL bit applies only to character drivers and | ||
| 200 | more particularly to CON drivers. The new 2.0 interface | ||
| 201 | is a much more general and consistent interface than the | ||
| 202 | old 1.25 DOS interface. It allows for a number of additional | ||
| 203 | features of 2.0. It is also slower than 1.25 if old style | ||
| 204 | "single byte" system calls are made. To make most efficient | ||
| 205 | use of the interface all applications should block their | ||
| 206 | I/O as much as possible. This means make one XENIX style | ||
| 207 | system call to output X bytes rather than X system calls | ||
| 208 | to output one byte each. Also putting a device channel in | ||
| 209 | RAW mode (see IOCTL) provides a means of putting out | ||
| 210 | characters even FASTER than 1.25. To help alleviate the | ||
| 211 | CON output speed problem for older programs which use the | ||
| 212 | 1 - 12 system calls to output large amounts of data the | ||
| 213 | SPECIAL bit has been implemented. If this bit is 1 it means | ||
| 214 | the device is the CON output device, and has implemented | ||
| 215 | an interrupt 29 Hex handler, where the 29 Hex handler is | ||
| 216 | defined as follows: | ||
| 217 | |||
| 218 | Interrupt 29h handlers | ||
| 219 | |||
| 220 | Input: | ||
| 221 | Character in AL | ||
| 222 | |||
| 223 | Function: | ||
| 224 | output the character in al to the user | ||
| 225 | screen. | ||
| 226 | Output: | ||
| 227 | None | ||
| 228 | Registers: | ||
| 229 | all registers except bx must be preserved. | ||
| 230 | No registers except for al have a known or | ||
| 231 | consistent value. | ||
| 232 | |||
| 233 | If a character device implements the SPECIAL bit, it | ||
| 234 | is the responsibility of the driver to install an address | ||
| 235 | at the correct location in the interrupt table for interrupt | ||
| 236 | 29 Hex as part of its INIT code. IMPLICATION: There can | ||
| 237 | be only one device driver with the SPECIAL bit set in the | ||
| 238 | system. There is no check to insure this state. | ||
| 239 | |||
| 240 | WARNING: THIS FEATURE WILL NOT BE SUPPORTED IN FUTURE VERSIONS | ||
| 241 | OF THE OPERATING SYSTEM. IMPLICATION: Any application | ||
| 242 | (not device driver) which uses INT 29H directly will | ||
| 243 | not work on future versions, YOU HAVE BEEN WARNED. | ||
| 244 | |||
| 245 | In order to "make" a device driver that SYSINIT can | ||
| 246 | install, a memory image or .EXE (non-IBM only) format file | ||
| 247 | must be created with the above header at the start. The | ||
| 248 | link field should be initialized to -1 (SYSINIT fills it | ||
| 249 | in). The attribute field and entry points must be set | ||
| 250 | correctly, and if the device is a character device, the name | ||
| 251 | field must be filled in with the name (if a block device | ||
| 252 | SYSINIT will fill in the correct unit count). This name | ||
| 253 | can be any 8 character "legal" file name. In fact SYSINIT | ||
| 254 | always installs character devices at the start of the device | ||
| 255 | list, so if you want to install a new CON device all you | ||
| 256 | have to do is name it "CON". The new one is ahead of the | ||
| 257 | old one in the list and thus preempts the old one as the | ||
| 258 | search for devices stops on the first match. Be sure to | ||
| 259 | set the sti and sto bits on a new CON device! | ||
| 260 | |||
| 261 | NOTE: Since SYSINIT may install the driver anywhere, you | ||
| 262 | must be very careful about FAR memory references. You | ||
| 263 | should NOT expect that your driver will go in the same | ||
| 264 | place every time (The default BIOS drivers are exempted | ||
| 265 | from this of course). | ||
| 266 | |||
| 267 | |||
| 268 | INSTALLATION OF DEVICE DRIVERS | ||
| 269 | |||
| 270 | Unlike past versions MS-DOS 2.0 allows new device drivers | ||
| 271 | to be installed dynamically at boot time. This is | ||
| 272 | accomplished by the new SYSINIT module supplied by Microsoft, | ||
| 273 | which reads and processes the CONFIG.SYS file. This module | ||
| 274 | is linked together with the OEM default BIOS in a similar | ||
| 275 | manner to the way FORMAT is built. | ||
| 276 | |||
| 277 | One of the functions defined for each device is INIT. | ||
| 278 | This routine is called once when the device is installed, | ||
| 279 | and never again. The only thing returned by the init routine | ||
| 280 | is a location (DS:DX) which is a pointer to the first free | ||
| 281 | byte of memory after the device driver, (like a terminate | ||
| 282 | and stay resident). This pointer method can be used to "throw | ||
| 283 | away" initialization code that is only needed once, saving | ||
| 284 | on space. | ||
| 285 | |||
| 286 | Block devices are installed the same way and also return | ||
| 287 | a first free byte pointer as above, additional information | ||
| 288 | is also returned: | ||
| 289 | |||
| 290 | o The number of units is returned, this determines | ||
| 291 | logical device names. If the current maximum logical | ||
| 292 | device letter is F at the time of the install call, | ||
| 293 | and the init routine returns 4 as the number of units, | ||
| 294 | then they will have logical names G, H, I and J. | ||
| 295 | This mapping is determined by by the position of | ||
| 296 | the driver in the device list and the number of units | ||
| 297 | on the device (stored in the first byte of the device | ||
| 298 | name field). | ||
| 299 | |||
| 300 | o A pointer to a BPB (Bios Parameter Block) pointer | ||
| 301 | array is also returned. This will be similar to | ||
| 302 | the INIT table used in previous versions, but will | ||
| 303 | have more information in it. There is one table | ||
| 304 | for each unit defined. These blocks will be used | ||
| 305 | to build a DPB (Drive Parameter Block) for each of | ||
| 306 | the units. The pointer passed to the DOS from the | ||
| 307 | driver points to an array of n word pointers to BPBs | ||
| 308 | where n is the number of units defined. In this | ||
| 309 | way if all units are the same, all of the pointers | ||
| 310 | can point to the same BPB, saving space. NOTE: this | ||
| 311 | array must be protected (below the free pointer set | ||
| 312 | by the return) since the DPB will be built starting | ||
| 313 | at the byte pointed to by the free pointer. The | ||
| 314 | sector size defined must be less than or equal to | ||
| 315 | the maximum sector size defined at default BIOS init | ||
| 316 | time. If it isn't the install will fail. One new | ||
| 317 | piece of DPB info set from this table will be a "media | ||
| 318 | descriptor byte". This byte means nothing to the | ||
| 319 | DOS, but is passed to devices so that they know what | ||
| 320 | form of a DPB the DOS is currently using for a | ||
| 321 | particular Drive-Unit. | ||
| 322 | |||
| 323 | Block devices may take several approaches; they may be | ||
| 324 | dumb or smart. A dumb device would define a unit (and | ||
| 325 | therefore a DPB) for each possible media drive combination. | ||
| 326 | Unit 0 = drive 0 single side, unit 1 = drive 0 double side, | ||
| 327 | etc. For this approach media descriptor bytes would mean | ||
| 328 | nothing. A smart device would allow multiple media per unit, | ||
| 329 | in this case the BPB table returned at init must define space | ||
| 330 | large enough to accommodate the largest possible media | ||
| 331 | supported. Smart drivers will use the "media byte" to pass | ||
| 332 | around info about what media is currently in a unit. NOTE: | ||
| 333 | If the DPB is a "hybrid" made to get the right sizes, it | ||
| 334 | should give an invalid "media byte" back to the DOS. | ||
| 335 | |||
| 336 | The BOOT (default BIOS) drivers are installed pretty | ||
| 337 | much as above. The preset device list is scanned. If block | ||
| 338 | drivers are encountered they are installed as above (with | ||
| 339 | the exception that the break is not moved since the drivers | ||
| 340 | are already resident in the BIOS). Note that the logical | ||
| 341 | drive letters are assigned in list order, thus the driver | ||
| 342 | which is to have logical A must be the first unit of the | ||
| 343 | first block device in the list. The order of character | ||
| 344 | devices is also important. There must be at least 4 character | ||
| 345 | devices defined at boot which must be the first four devices | ||
| 346 | (of either type), the first will become standard input, | ||
| 347 | standard output, and standard error output. The second will | ||
| 348 | become standard auxiliary input and output, the third will | ||
| 349 | become standard list output, and the forth will become the | ||
| 350 | date/time (CLOCK) device. Thus the BIOS device list must | ||
| 351 | look like this: | ||
| 352 | |||
| 353 | ->CON->AUX->PRN->CLOCK->any other block or character devices | ||
| 354 | |||
| 355 | THE DRIVER | ||
| 356 | |||
| 357 | A device driver will define the following functions: | ||
| 358 | |||
| 359 | Command Function | ||
| 360 | Code | ||
| 361 | |||
| 362 | 0 INIT | ||
| 363 | 1 MEDIA CHECK (Block only, NOP for character) | ||
| 364 | 2 BUILD BPB " " " " " | ||
| 365 | 3 IOCTL INPUT (Only called if device has IOCTL) | ||
| 366 | 4 INPUT (read) | ||
| 367 | 5 NON-DESTRUCTIVE INPUT NO WAIT (Char devs only) | ||
| 368 | 6 INPUT STATUS " " " | ||
| 369 | 7 INPUT FLUSH " " " | ||
| 370 | 8 OUTPUT (write) | ||
| 371 | 9 OUTPUT (Write) with verify | ||
| 372 | 10 OUTPUT STATUS " " " | ||
| 373 | 11 OUTPUT FLUSH " " " | ||
| 374 | 12 IOCTL OUTPUT (Only called if device has IOCTL) | ||
| 375 | |||
| 376 | As mentioned before, the first entry point is the strategy | ||
| 377 | routine which is called with a pointer to a data block. This | ||
| 378 | call does not perform the request, all it does is queue it | ||
| 379 | (save the data block pointer). The second interrupt entry | ||
| 380 | point is called immediately after the strategy call. The | ||
| 381 | "interrupt" routine is called with no parameters, its primary | ||
| 382 | function is to perform the operation based on the queued | ||
| 383 | data block and set up any returns. | ||
| 384 | |||
| 385 | The "BUILD BPB" and "MEDIA CHECK" are the interesting | ||
| 386 | new ones, these are explained by examining the sequence of | ||
| 387 | events in the DOS which occurs when a drive access call (other | ||
| 388 | than read or write) is made: | ||
| 389 | |||
| 390 | I. Turn drive letter into DPB pointer by looking | ||
| 391 | for DPB with correct driver-unit number. | ||
| 392 | |||
| 393 | II. Call device driver and request media check for | ||
| 394 | Drive-Unit. DOS passes its current Media | ||
| 395 | descriptor byte (from DPB). Call returns: | ||
| 396 | |||
| 397 | Media Not Changed | ||
| 398 | Media Changed | ||
| 399 | Not Sure | ||
| 400 | Error | ||
| 401 | |||
| 402 | Error - If an error occurs the error code should | ||
| 403 | be set accordingly. | ||
| 404 | |||
| 405 | Media Not changed - Current DPB and media byte | ||
| 406 | are OK, done. | ||
| 407 | |||
| 408 | Media Changed - Current DPB and media are wrong, | ||
| 409 | invalidate any buffers for this unit, and | ||
| 410 | goto III. | ||
| 411 | |||
| 412 | Not Sure - If there are dirty buffers for this | ||
| 413 | unit, assume DPB and media byte are OK and | ||
| 414 | done. If nothing dirty, assume media changed, | ||
| 415 | invalidate any buffers for unit, and goto | ||
| 416 | III. | ||
| 417 | |||
| 418 | NOTE: If a hybrid DPB was built at init and | ||
| 419 | an invalid Media byte was set, the driver | ||
| 420 | should return media changed when this invalid | ||
| 421 | media byte is encountered. | ||
| 422 | |||
| 423 | III. Call device driver to build BPB with media byte | ||
| 424 | and buffer. | ||
| 425 | |||
| 426 | What the driver must do at step III is determine the | ||
| 427 | correct media that is currently in the unit, and return a | ||
| 428 | pointer to a BPB table (same as for the install call). This | ||
| 429 | table will be used as at init to build a correct DPB for | ||
| 430 | the unit If the determined media descriptor byte in the table | ||
| 431 | turns out to be the same as the one passed in, then the DOS | ||
| 432 | will not build a new table, but rather just use the old one. | ||
| 433 | Therefore in this case the driver doesn't have to correctly | ||
| 434 | fill in the other entries if desired. | ||
| 435 | |||
| 436 | The build BPB call also gets a pointer to a one sector | ||
| 437 | buffer. What this buffer contains is determined by the NON | ||
| 438 | IBM FORMAT bit in the attribute field. If the bit is zero | ||
| 439 | (device is IBM format compatible) then the buffer contains | ||
| 440 | the first sector of the first FAT, in particular the FAT | ||
| 441 | ID byte is the first byte of this buffer. NOTE: It must | ||
| 442 | be true that the BPB is the same, as far as location of the | ||
| 443 | FAT is concerned, for all possible media. This is because | ||
| 444 | this first FAT sector must be read BEFORE the actual BPB | ||
| 445 | is returned. If the NON IBM FORMAT bit is set then the | ||
| 446 | pointer points to one sector of scratch space which may be | ||
| 447 | used for anything. | ||
| 448 | |||
| 449 | CALL FORMAT | ||
| 450 | |||
| 451 | When the DOS calls a device driver to perform a finction, | ||
| 452 | it passes a structure (Drive Request Structure) in ES:BX | ||
| 453 | to perform operations and does a long call to the driver's | ||
| 454 | strategy entry point. This structure is a fixed length header | ||
| 455 | (Static Request Header) followed by data pertinent to the | ||
| 456 | operation being performed. NOTE: It is the drivers | ||
| 457 | responsibility to preserve machine state. | ||
| 458 | |||
| 459 | STATIC REQUEST HEADER -> | ||
| 460 | +-----------------------------+ | ||
| 461 | | BYTE length of record | | ||
| 462 | | Length in bytes of this | | ||
| 463 | | Drive Request Structure | | ||
| 464 | +-----------------------------+ | ||
| 465 | | BYTE unit code | | ||
| 466 | | The subunit the operation | | ||
| 467 | | is for (minor device) | | ||
| 468 | | (no meaning on character | | ||
| 469 | | devices) | | ||
| 470 | +-----------------------------+ | ||
| 471 | | BYTE command code | | ||
| 472 | +-----------------------------+ | ||
| 473 | | WORD Status | | ||
| 474 | +-----------------------------+ | ||
| 475 | | 8 bytes reserved here for | | ||
| 476 | | two DWORD links. One will | | ||
| 477 | | be a link for the DOS queue | | ||
| 478 | | The other for the device | | ||
| 479 | | queue | | ||
| 480 | +-----------------------------+ | ||
| 481 | |||
| 482 | STATUS WORD | ||
| 483 | |||
| 484 | 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | ||
| 485 | +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+ | ||
| 486 | | E | | B | D | | | ||
| 487 | | R | RESERVED | U | O | ERROR CODE (bit 15 on)| | ||
| 488 | | R | | I | N | | | ||
| 489 | +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+ | ||
| 490 | |||
| 491 | The status word is zero on entry and is set by the driver | ||
| 492 | interrupt routine on return. | ||
| 493 | |||
| 494 | Bit 8 is the done bit, it means the operation is complete. | ||
| 495 | For the moment the Driver just sets it to one when it exits, | ||
| 496 | in the future this will be set by the interrupt routine to | ||
| 497 | tell the DOS the operation is complete. | ||
| 498 | |||
| 499 | Bit 15 is the error bit, if it is set then the low 8 | ||
| 500 | bits indicate the error: | ||
| 501 | |||
| 502 | 0 Write Protect violation | ||
| 503 | (NEW) 1 Unknown Unit | ||
| 504 | 2 Drive not ready | ||
| 505 | (NEW) 3 Unknown command | ||
| 506 | 4 CRC error | ||
| 507 | (NEW) 5 Bad Drive Request Structure length | ||
| 508 | 6 Seek error | ||
| 509 | (NEW) 7 Unknown media | ||
| 510 | 8 Sector not found | ||
| 511 | (NEW) 9 Printer out of paper | ||
| 512 | A Write Fault | ||
| 513 | (NEW) B Read Fault | ||
| 514 | C General Failure | ||
| 515 | |||
| 516 | Bit 9 is the busy bit which is set only by status calls (see | ||
| 517 | STATUS CALL below). | ||
| 518 | |||
| 519 | |||
| 520 | Here is the data block format for each function: | ||
| 521 | |||
| 522 | READ or WRITE - ES:BX (Including IOCTL) -> | ||
| 523 | +------------------------------------+ | ||
| 524 | | 13-BYTE Static Request Header | | ||
| 525 | +------------------------------------+ | ||
| 526 | | BYTE Media descriptor from DPB | | ||
| 527 | +------------------------------------+ | ||
| 528 | | DWORD transfer address | | ||
| 529 | +------------------------------------+ | ||
| 530 | | WORD byte/sector Count | | ||
| 531 | ---+------------------------------------+--- | ||
| 532 | | WORD starting sector number | | ||
| 533 | | (ignored on Char Devs) | | ||
| 534 | +------------------------------------+ | ||
| 535 | |||
| 536 | In addition to setting the status word, the driver must | ||
| 537 | set the Sector count to the actual number of sectors (or | ||
| 538 | bytes) transferred. NOTE: No error check is performed on | ||
| 539 | an IOCTL I/O call, driver MUST correctly set the return sector | ||
| 540 | (byte) count to the actual number of bytes transferred, | ||
| 541 | however. | ||
| 542 | |||
| 543 | NOTE: THE FOLLOWING APPLIES TO BLOCK DEVICE DRIVERS. | ||
| 544 | |||
| 545 | Under certain circumstances the BIOS may be asked to | ||
| 546 | do a write operation of 64K bytes which seems to be a "wrap | ||
| 547 | around" of the transfer address in the BIOS I/O packet. This | ||
| 548 | arises due to an optimization added to the write code in | ||
| 549 | MS-DOS. It will only manifest on user WRITEs which are within | ||
| 550 | a sector size of 64K bytes on files which are "growing" past | ||
| 551 | the current EOF. IT IS ALLOWABLE FOR THE BIOS TO IGNORE | ||
| 552 | THE BALANCE OF THE WRITE WHICH "WRAPS AROUND" IF IT SO | ||
| 553 | CHOOSES. For instance a WRITE of 10000H bytes worth of | ||
| 554 | sectors with a transfer address of XXX:1 could ignore the | ||
| 555 | last two bytes (remember that a user program can never request | ||
| 556 | an I/O of more than FFFFH bytes and cannot wrap around (even | ||
| 557 | to 0) in his transfer segment, so in this case the last two | ||
| 558 | bytes can be ignored). | ||
| 559 | |||
| 560 | |||
| 561 | NON DESRUCTIVE READ NO WAIT - ES:BX -> | ||
| 562 | +------------------------------------+ | ||
| 563 | | 13-BYTE Static Request Header | | ||
| 564 | +------------------------------------+ | ||
| 565 | | BYTE read from device | | ||
| 566 | +------------------------------------+ | ||
| 567 | |||
| 568 | This call is analogous to the console input status call | ||
| 569 | on MS-DOS 1.25. If the character device returns Busy bit | ||
| 570 | = 0 (characters in buffer), then the next character that | ||
| 571 | would be read is returned. This character is NOT removed | ||
| 572 | from the input buffer (hence the term Non Destructive Read). | ||
| 573 | In essence this call allows the DOS to look ahead one input | ||
| 574 | character. | ||
| 575 | |||
| 576 | |||
| 577 | MEDIA CHECK - ES:BX -> | ||
| 578 | +------------------------------------+ | ||
| 579 | | 13-BYTE Static Request Header | | ||
| 580 | +------------------------------------+ | ||
| 581 | | BYTE Media Descriptor from DPB | | ||
| 582 | +------------------------------------+ | ||
| 583 | | BYTE returned | | ||
| 584 | +------------------------------------+ | ||
| 585 | |||
| 586 | In addition to setting status word, driver must set the | ||
| 587 | return byte. | ||
| 588 | |||
| 589 | Return Byte : | ||
| 590 | -1 Media has been changed | ||
| 591 | 0 Don't know if media has been changed | ||
| 592 | 1 Media has not been changed | ||
| 593 | |||
| 594 | If the driver can return -1 or 1 (by having a door-lock | ||
| 595 | or other interlock mechanism) the performance of MSDOS 2.0 | ||
| 596 | is enhanced as the DOS need not reread the FAT for each | ||
| 597 | directory access. | ||
| 598 | |||
| 599 | |||
| 600 | BUILD BPB - ES:BX -> | ||
| 601 | +------------------------------------+ | ||
| 602 | | 13-BYTE Static Request Header | | ||
| 603 | +------------------------------------+ | ||
| 604 | | BYTE Media Descriptor from DPB | | ||
| 605 | +------------------------------------+ | ||
| 606 | | DWORD Transfer Address | | ||
| 607 | | (points to one sectors worth of | | ||
| 608 | | scratch space or first sector | | ||
| 609 | | of FAT depending on the value | | ||
| 610 | | of the NON IBM FORMAT bit) | | ||
| 611 | +------------------------------------+ | ||
| 612 | | DWORD Pointer to BPB | | ||
| 613 | +------------------------------------+ | ||
| 614 | |||
| 615 | If the NON IBM FORMAT bit of the device is set, then | ||
| 616 | the DWORD Transfer Address points to a one sector buffer | ||
| 617 | which can be used for any purpose. If the NON IBM FORMAT | ||
| 618 | bit is 0, then this buffer contains the first sector of the | ||
| 619 | FAT; in this case the driver must not alter this buffer (this | ||
| 620 | mode is useful if all that is desired is to read the FAT | ||
| 621 | ID byte). | ||
| 622 | |||
| 623 | If IBM compatible format is used (NON IBM FORMAT BIT | ||
| 624 | = 0), then it must be true that the first sector of the first | ||
| 625 | FAT is located at the same sector on all possible media. | ||
| 626 | This is because the FAT sector will be read BEFORE the media | ||
| 627 | is actually determined. | ||
| 628 | |||
| 629 | In addition to setting status word, driver must set the | ||
| 630 | Pointer to the BPB on return. | ||
| 631 | |||
| 632 | |||
| 633 | In order to allow for many different OEMs to read each | ||
| 634 | other's disks, the following standard is suggested: The | ||
| 635 | information relating to the BPB for a particular piece of | ||
| 636 | media is kept in the boot sector for the media. In | ||
| 637 | particular, the format of the boot sector is: | ||
| 638 | |||
| 639 | +------------------------------------+ | ||
| 640 | | 3 BYTE near JUMP to boot code | | ||
| 641 | +------------------------------------+ | ||
| 642 | | 8 BYTES OEM name and version | | ||
| 643 | ---+------------------------------------+--- | ||
| 644 | B | WORD bytes per sector | | ||
| 645 | P +------------------------------------+ | ||
| 646 | B | BYTE sectors per allocation unit | | ||
| 647 | +------------------------------------+ | ||
| 648 | | | WORD reserved sectors | | ||
| 649 | V +------------------------------------+ | ||
| 650 | | BYTE number of FATs | | ||
| 651 | +------------------------------------+ | ||
| 652 | | WORD number of root dir entries | | ||
| 653 | +------------------------------------+ | ||
| 654 | | WORD number of sectors in logical | | ||
| 655 | ^ | image | | ||
| 656 | | +------------------------------------+ | ||
| 657 | B | BYTE media descriptor | | ||
| 658 | P +------------------------------------+ | ||
| 659 | B | WORD number of FAT sectors | | ||
| 660 | ---+------------------------------------+--- | ||
| 661 | | WORD sectors per track | | ||
| 662 | +------------------------------------+ | ||
| 663 | | WORD number of heads | | ||
| 664 | +------------------------------------+ | ||
| 665 | | WORD number of hidden sectors | | ||
| 666 | +------------------------------------+ | ||
| 667 | |||
| 668 | The three words at the end are optional, the DOS doesn't | ||
| 669 | care about them (since they are not part of the BPB). They | ||
| 670 | are intended to help the BIOS understand the media. Sectors | ||
| 671 | per track may be redundant (could be figured out from total | ||
| 672 | size of the disk). Number of heads is useful for supporting | ||
| 673 | different multi-head drives which have the same storage | ||
| 674 | capacity, but a different number of surfaces. Number of | ||
| 675 | hidden sectors is useful for supporting drive partitioning | ||
| 676 | schemes. | ||
| 677 | |||
| 678 | |||
| 679 | Currently, the media descriptor byte has been defined | ||
| 680 | for a small range of media: | ||
| 681 | |||
| 682 | 5 1/4" diskettes: | ||
| 683 | |||
| 684 | Flag bits: | ||
| 685 | 01h - on -> 2 double sided | ||
| 686 | |||
| 687 | All other bits must be on. | ||
| 688 | |||
| 689 | 8" disks: | ||
| 690 | FEh - IBM 3740 format, singled-sided, single-density, | ||
| 691 | 128 bytes per sector, soft sectored, 4 sectors | ||
| 692 | per allocation unit, 1 reserved sector, 2 FATs, | ||
| 693 | 68 directory entries, 77*26 sectors | ||
| 694 | |||
| 695 | FDh - 8" IBM 3740 format, singled-sided, | ||
| 696 | single-density, 128 bytes per sector, soft | ||
| 697 | sectored, 4 sectors per allocation unit, 4 | ||
| 698 | reserved sectors, 2 FATs, 68 directory entries, | ||
| 699 | 77*26 sectors | ||
| 700 | |||
| 701 | FEh - 8" Double-sided, double-density, 1024 bytes | ||
| 702 | per sector, soft sectored, 1 sector per allocation | ||
| 703 | unit, 1 reserved sector, 2 FATs, 192 directory | ||
| 704 | entries, 77*8*2 sectors | ||
| 705 | |||
| 706 | |||
| 707 | STATUS Calls - ES:BX -> | ||
| 708 | +------------------------------------+ | ||
| 709 | | 13-BYTE Static Request Header | | ||
| 710 | +------------------------------------+ | ||
| 711 | |||
| 712 | All driver must do is set status word accordingly and | ||
| 713 | set the busy bit as follows: | ||
| 714 | |||
| 715 | o For output on character devices: If it is 1 on | ||
| 716 | return, a write request (if made) would wait for | ||
| 717 | completion of a current request. If it is 0, there | ||
| 718 | is no current request and a write request (if made) | ||
| 719 | would start immediately. | ||
| 720 | |||
| 721 | o For input on character devices with a buffer a return | ||
| 722 | of 1 means, a read request (if made) would go to | ||
| 723 | the physical device. If it is 0 on return, then | ||
| 724 | there are characters in the devices buffer and a | ||
| 725 | read would return quickly, it also indicates that | ||
| 726 | the user has typed something. The DOS assumes all | ||
| 727 | character devices have an input type ahead buffer. | ||
| 728 | Devices which don't have them should always return | ||
| 729 | busy = 0 so that the DOS won't hang waiting for | ||
| 730 | something to get into a buffer which doesn't exist. | ||
| 731 | |||
| 732 | |||
| 733 | FLUSH Calls - ES:BX -> | ||
| 734 | +------------------------------------+ | ||
| 735 | | 13-BYTE Static Request Header | | ||
| 736 | +------------------------------------+ | ||
| 737 | |||
| 738 | This call tells the driver to flush (terminate) all | ||
| 739 | pending requests that it has knowledge of. Its primary use | ||
| 740 | is to flush the input queue on character devices. | ||
| 741 | |||
| 742 | |||
| 743 | INIT - ES:BX -> | ||
| 744 | +------------------------------------+ | ||
| 745 | | 13-BYTE Static Request Header | | ||
| 746 | +------------------------------------+ | ||
| 747 | | BYTE # of units | | ||
| 748 | +------------------------------------+ | ||
| 749 | | DWORD Break Address | | ||
| 750 | ---+------------------------------------+--- | ||
| 751 | | DWORD Pointer to BPB array | | ||
| 752 | | (not set by Character devices) | | ||
| 753 | +------------------------------------+ | ||
| 754 | |||
| 755 | The number of units, break address, and BPB pointer are | ||
| 756 | set by the driver. | ||
| 757 | |||
| 758 | |||
| 759 | FORMAT OF BPB (Bios Parameter Block) - | ||
| 760 | |||
| 761 | +------------------------------------+ | ||
| 762 | | WORD Sector size in Bytes | | ||
| 763 | | Must be at least 32 | | ||
| 764 | +------------------------------------+ | ||
| 765 | | BYTE Sectors/Allocation unit | | ||
| 766 | | Must be a power of 2 | | ||
| 767 | +------------------------------------+ | ||
| 768 | | WORD Number of reserved sectors | | ||
| 769 | | May be zero | | ||
| 770 | +------------------------------------+ | ||
| 771 | | BYTE Number of FATS | | ||
| 772 | +------------------------------------+ | ||
| 773 | | WORD Number of directory entries | | ||
| 774 | +------------------------------------+ | ||
| 775 | | WORD Total number of sectors | | ||
| 776 | +------------------------------------+ | ||
| 777 | | BYTE Media descriptor | | ||
| 778 | +------------------------------------+ | ||
| 779 | | WORD Number of sectors occupied by | | ||
| 780 | | FAT | | ||
| 781 | +------------------------------------+ | ||
| 782 | |||
| 783 | |||
| 784 | THE CLOCK DEVICE | ||
| 785 | |||
| 786 | One of the most popular add on boards seems to be "Real | ||
| 787 | Time CLOCK Boards". To allow these boards to be integrated | ||
| 788 | into the system for TIME and DATE, there is a special device | ||
| 789 | (determined by the attribute word) which is the CLOCK device. | ||
| 790 | In all respects this device defines and performs functions | ||
| 791 | like any other character device (most functions will be "set | ||
| 792 | done bit, reset error bit, return). When a read or write | ||
| 793 | to this device occurs, exactly 6 bytes are transferred. This | ||
| 794 | I/O can be thought of as transferring 3 words which correspond | ||
| 795 | exactly to the values of AX, CX and DX which were used in | ||
| 796 | the old 1.25 DOS date and time routines. Thus the first | ||
| 797 | two bytes are a word which is the count of days since 1-1-80. | ||
| 798 | The third byte is minutes, the fourth hours, the fifth | ||
| 799 | hundredths of seconds, and the sixth seconds. Reading the | ||
| 800 | CLOCK device gets the date and time, writing to it sets the | ||
| 801 | date and time. | ||
| 802 | |||
diff --git a/v2.0/bin/DISKCOPY.COM b/v2.0/bin/DISKCOPY.COM new file mode 100644 index 0000000..ea4e0d2 --- /dev/null +++ b/v2.0/bin/DISKCOPY.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/DOSPATCH.TXT b/v2.0/bin/DOSPATCH.TXT new file mode 100644 index 0000000..20ebd95 --- /dev/null +++ b/v2.0/bin/DOSPATCH.TXT | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | There are three locations in the DOS where OEMs may want to | ||
| 2 | patch in information specific to their installation. | ||
| 3 | |||
| 4 | |||
| 5 | The first is the location of the default switch character. | ||
| 6 | This character is one byte at DEBUG location 1E5, and is | ||
| 7 | set to '/'. To change it to '-' (XENIX compatible) | ||
| 8 | do: | ||
| 9 | |||
| 10 | DEBUG MSDOS.SYS | ||
| 11 | |||
| 12 | >e1e5 | ||
| 13 | XXXX:01E5 2F. <at this point give the desired | ||
| 14 | new switch character in HEX and | ||
| 15 | hit return> | ||
| 16 | >w | ||
| 17 | Writing YYYY Bytes | ||
| 18 | >q | ||
| 19 | |||
| 20 | If the byte at 1E5 is not 2F, look around in the immediate | ||
| 21 | vacinity (do d1e0) for it. It is the only 2F in that area. | ||
| 22 | |||
| 23 | |||
| 24 | The second is the location of the 24 bit user number and the | ||
| 25 | 8 bit OEM number. These values are returned by the GET_VERSION | ||
| 26 | system call. | ||
| 27 | The user number is 3 bytes starting at | ||
| 28 | debug location 683, The OEM number is one byte at debug location | ||
| 29 | 686. The user number is initialized to 0, the OEM number to -1 | ||
| 30 | and they immediatly follow the Microsoft Copyright message. If these | ||
| 31 | bytes are not zero, look for the four bytes following the | ||
| 32 | Copyright message which should be in the vacinity of 683. | ||
| 33 | OEMs should request an OEM number from Microsoft if they | ||
| 34 | want one of their very own, this prevents selecting one someone | ||
| 35 | else already has. | ||
| 36 | |||
| 37 | |||
| 38 | The third is the location of the editing template definitions. | ||
| 39 | This is a table which defines the two byte edit function keys | ||
| 40 | for system call 10 and for EDLIN. This table is at debug location | ||
| 41 | 33EA, and should start with a 1B. If the byte at 33EA is not | ||
| 42 | 1B, look around in the immediate vacinity. Here is what the | ||
| 43 | default table looks like. It is a definition for the Zenith | ||
| 44 | Z-19 terminal: | ||
| 45 | |||
| 46 | ESCCHAR DB 1BH ;The Escape character, Nul (0) on IBM | ||
| 47 | ESCTAB: | ||
| 48 | DB "Z" ;5AH Put a ^Z in the template, F6 on IBM | ||
| 49 | DB "S" ;53H Copy one char, --> on IBM | ||
| 50 | DB "V" ;56H Skip one char, DEL on IBM | ||
| 51 | DB "T" ;54H Copy to char, F2 on IBM | ||
| 52 | DB "W" ;57H Skip to char, F4 on IBM | ||
| 53 | DB "U" ;55H Copy line, F3 on IBM | ||
| 54 | DB "E" ;45H Kill line, Not used on IBM | ||
| 55 | DB "J" ;4AH Reedit line, F5 on IBM | ||
| 56 | DB "D" ;44H Backspace, <-- on IBM | ||
| 57 | DB "P" ;50H Toggle insert mode, INS on IBM | ||
| 58 | DB "Q" ;51H Toggle insert mode, INS on IBM | ||
| 59 | DB "R" ;52H Escape char, F7 on IBM | ||
| 60 | DB "R" ;52H End of table, must be same as previos character | ||
| 61 | |||
| 62 | \ No newline at end of file | ||
diff --git a/v2.0/bin/EDLIN.COM b/v2.0/bin/EDLIN.COM new file mode 100644 index 0000000..81e097b --- /dev/null +++ b/v2.0/bin/EDLIN.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/EXE2BIN.EXE b/v2.0/bin/EXE2BIN.EXE new file mode 100644 index 0000000..f4b0dd7 --- /dev/null +++ b/v2.0/bin/EXE2BIN.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/FC.EXE b/v2.0/bin/FC.EXE new file mode 100644 index 0000000..aa06624 --- /dev/null +++ b/v2.0/bin/FC.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/FILBP.PAS b/v2.0/bin/FILBP.PAS new file mode 100644 index 0000000..71decc8 --- /dev/null +++ b/v2.0/bin/FILBP.PAS | |||
| Binary files differ | |||
diff --git a/v2.0/bin/FIND.EXE b/v2.0/bin/FIND.EXE new file mode 100644 index 0000000..b5d07d0 --- /dev/null +++ b/v2.0/bin/FIND.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/FORMAT.DOC b/v2.0/bin/FORMAT.DOC new file mode 100644 index 0000000..ab47f54 --- /dev/null +++ b/v2.0/bin/FORMAT.DOC | |||
| @@ -0,0 +1,393 @@ | |||
| 1 | FORMAT - formats a new disk, clears the FAT and DIRECTORY | ||
| 2 | and optionally copies the SYSTEM and COMMAND.COM to this | ||
| 3 | new disk. | ||
| 4 | |||
| 5 | Command syntax: | ||
| 6 | |||
| 7 | FORMAT [drive:][/switch1][/switch2]...[/switch16] | ||
| 8 | |||
| 9 | Where "drive:" is a legal drive specification and if | ||
| 10 | omitted indicates that the default drive will be used. | ||
| 11 | There may be up to 16 legal switches included in the | ||
| 12 | command line. | ||
| 13 | |||
| 14 | |||
| 15 | The OEM must supply five (NEAR) routines to the program | ||
| 16 | along with 6 data items. The names of the routines are INIT, | ||
| 17 | DISKFORMAT, BADSECTOR, WRTFAT and DONE, and their flow of | ||
| 18 | control (by the Microsoft module) is like this: | ||
| 19 | |||
| 20 | | | ||
| 21 | +---------+ | ||
| 22 | | INIT | | ||
| 23 | +---------+ | ||
| 24 | | | ||
| 25 | |<------------------------------+ | ||
| 26 | +------------+ | | ||
| 27 | | DISKFORMAT | | | ||
| 28 | +------------+ | | ||
| 29 | |<-------+ | | ||
| 30 | +-----------+ |-This loop is done |- This loop done | ||
| 31 | | BADSECTOR | | for each group of | once for each disk | ||
| 32 | +-----------+ | bad sectors | to be formatted. | ||
| 33 | |----->--+ | If variable HARDFLAG | ||
| 34 | | | is set then the loop | ||
| 35 | +----------+ | is only performed | ||
| 36 | | | | once. | ||
| 37 | | WRTFAT | | | ||
| 38 | +----------+ | | ||
| 39 | | | | ||
| 40 | +------+ | | ||
| 41 | | DONE | | | ||
| 42 | +------+ | | ||
| 43 | +---->--------------------------+ | ||
| 44 | |||
| 45 | The INIT, DISKFORMAT, and BADSECTOR routines are free | ||
| 46 | to use any MS-DOS system calls, except for calls that cause | ||
| 47 | disk accesses on the disk being formatted. DONE may use | ||
| 48 | ANY calls, since by the time it is called the new disk has | ||
| 49 | been formatted. | ||
| 50 | |||
| 51 | The following data must be declared PUBLIC in a module | ||
| 52 | provided by the OEM: | ||
| 53 | |||
| 54 | SWITCHLIST - A string of bytes. The first byte is count | ||
| 55 | N, followed by N characters which are the switches to | ||
| 56 | be accepted by the command line scanner. Alphabetic | ||
| 57 | characters must be in upper case (the numeric | ||
| 58 | characters 0-9 are allowed). The last three switches, | ||
| 59 | normally "O", "V" and "S", have pre-defined meanings. | ||
| 60 | |||
| 61 | The "S" switch is the switch which causes the | ||
| 62 | system files IO.SYS, MSDOS.SYS, and COMMAND.COM to be | ||
| 63 | transfered to the disk after it is formatted thus | ||
| 64 | making a "S"ystem disk. The switch can be some letter | ||
| 65 | other than "S", but the last switch in the list is | ||
| 66 | assumed to have the meaning "transfer system", | ||
| 67 | regardles of what the particular letter is. | ||
| 68 | |||
| 69 | The second to the last switch, "V", causes FORMAT | ||
| 70 | to prompt the user for a volume label after the disk | ||
| 71 | is formatted. Again, as with "S", the particular | ||
| 72 | letter is not important but rather the position in the | ||
| 73 | list. | ||
| 74 | |||
| 75 | The third to the last switch, "O", causes FORMAT to | ||
| 76 | produce an IBM Personal Computer DOS version 1.X | ||
| 77 | compatible disk. Normally FORMAT causes a 0 byte to | ||
| 78 | be placed in the first byte of each directory entry | ||
| 79 | instead of the 0E5 Hex free entry designator. This | ||
| 80 | results in a very marked directory search performance | ||
| 81 | increase due to an optimization in the DOS. Disks | ||
| 82 | made this way cause trouble on IBM PC DOS 1.X | ||
| 83 | versions, however, which did not have this | ||
| 84 | optimization. The 0 byte fools IBM 1.X versions into | ||
| 85 | thinking these entries are allocated instead of free, | ||
| 86 | NOTE that IBM Personnal Computer DOS version 2.00 and | ||
| 87 | MS-DOS version 1.25 will have no trouble with these | ||
| 88 | disks, since they have the same optimization. The "O" | ||
| 89 | switch causes FORMAT to re-do the directory with a 0E5 | ||
| 90 | Hex byte at the start of each entry so that the disk | ||
| 91 | may be used with 1.X versions of IBM PC DOS, as well | ||
| 92 | as MS-DOS 1.25/2.00 and IBM PC DOS 2.00. This switch | ||
| 93 | should only be given when needed because it takes a | ||
| 94 | fair amount of time for FORMAT to perform the | ||
| 95 | conversion, and it noticably decreases 1.25 and 2.00 | ||
| 96 | performance on disks with few directory entries. | ||
| 97 | |||
| 98 | Up to 16 switches are permitted. Normally a "C" | ||
| 99 | switch is specified for "Clear". This switch should | ||
| 100 | cause the formatting operation to be bypassed (within | ||
| 101 | DISKFORMAT or BADSECTOR). This is provided as a | ||
| 102 | time-saving convenience to the user, who may wish | ||
| 103 | to "start fresh" on a previosly formatted and used | ||
| 104 | disk. | ||
| 105 | |||
| 106 | HARDFLAG - BYTE location which specifies whether the | ||
| 107 | OEM routine is formatting a fixed disk or a a drive | ||
| 108 | with removable media. A zero indicates removable | ||
| 109 | media, any other value indicates a fixed disk. The | ||
| 110 | status of this byte only effect the messages printed | ||
| 111 | by the main format module. This value should be | ||
| 112 | set or reset by the OEM supplied INIT routine. | ||
| 113 | |||
| 114 | FATID - BYTE location containing the value to be used | ||
| 115 | in the first byte of the FAT. Must be in the range | ||
| 116 | F8 hex to FF hex. | ||
| 117 | |||
| 118 | STARTSECTOR - WORD location containing the sector number | ||
| 119 | of the first sector of the data area. | ||
| 120 | |||
| 121 | FATSPACE - WORD location containing the address of the | ||
| 122 | start of the FAT area. A FAT built in this area | ||
| 123 | will be written to disk using the OEM supplied WRTFAT | ||
| 124 | subroutine. 6k is sufficient to store any FAT. This | ||
| 125 | area must not overlap the FREESPACE area. | ||
| 126 | |||
| 127 | FREESPACE - WORD location which contains the address | ||
| 128 | of the start of free memory space. This is where | ||
| 129 | the system will be loaded, by the Microsoft module, | ||
| 130 | for transferring to the newly formatted disk. Memory | ||
| 131 | should be available from this address to the end | ||
| 132 | of memory, so it is typically the address of the | ||
| 133 | end of the OEM module. | ||
| 134 | |||
| 135 | The following routines must be declared PUBLIC in the | ||
| 136 | OEM-supplied module: | ||
| 137 | |||
| 138 | INIT - An initialization routine. This routine is called | ||
| 139 | once at the start of the FORMAT run after the switches | ||
| 140 | have been processed. This routine should perform | ||
| 141 | any functions that only need to be done once per | ||
| 142 | FORMAT run. An example of what this routine might | ||
| 143 | do is read the boot sector into a buffer so that | ||
| 144 | it can be transferred to the new disks by DISKFORMAT. | ||
| 145 | If this routine returns with the CARRY flag set it | ||
| 146 | indicates an error, and FORMAT will print "Format | ||
| 147 | failure" and quit. This feature can be used to detect | ||
| 148 | conflicting switches (like specifying both single | ||
| 149 | and double density) and cause FORMAT to quit without | ||
| 150 | doing anything. | ||
| 151 | |||
| 152 | DISKFORMAT - Formats the disk according to the options | ||
| 153 | indicated by the switches and the value of FATID | ||
| 154 | must be defined when it returns (although INIT may | ||
| 155 | have already done it). This routine is called once | ||
| 156 | for EACH disk to be formatted. If neccessary it | ||
| 157 | must transfer the Bootstrap loader. If any error | ||
| 158 | conditions are detected, set the CARRY flag and return | ||
| 159 | to FORMAT. FORMAT will report a 'Format failure' | ||
| 160 | and prompt for another disk. (If you only require | ||
| 161 | a clear directory and FAT then simply setting the | ||
| 162 | appropriate FATID, if not done by INIT, will be all | ||
| 163 | that DISKFORMAT must do.) | ||
| 164 | |||
| 165 | BADSECTOR - Reports the sector number of any bad sectors | ||
| 166 | that may have been found during the formatting of | ||
| 167 | the disk. This routine is called at least once for | ||
| 168 | EACH disk to be formatted, and is called repeatedly | ||
| 169 | until AX is zero or the carry flag is set. The carry | ||
| 170 | flag is used just as in DISKFORMAT to indicate an | ||
| 171 | error, and FORMAT handles it in the same way. The | ||
| 172 | first sector in the data area must be in STARTSECTOR | ||
| 173 | for the returns from this routine to be interpreted | ||
| 174 | correctly. If there are bad sectors, BADSECTOR must | ||
| 175 | return a sector number in in register BX, the number | ||
| 176 | of consecutive bad sectors in register AX, and carry | ||
| 177 | clear. FORMAT will then process the bad sectors | ||
| 178 | and call BADSECTOR again. When BADSECTOR returns | ||
| 179 | with AX = 0 this means there are no more bad sectors; | ||
| 180 | FORMAT clears the directory and goes on to DONE, | ||
| 181 | so for this last return BX need not contain anything | ||
| 182 | meaningful. | ||
| 183 | |||
| 184 | FORMAT processes bad sectors by determining their | ||
| 185 | corresponding allocation unit and marking that unit | ||
| 186 | with an FF7 hex in the File Allocation Table. CHKDSK | ||
| 187 | understands the FF7 mark as a flag for bad sectors | ||
| 188 | and accordingly reports the number of bytes marked | ||
| 189 | in this way. | ||
| 190 | |||
| 191 | NOTE: Actual formatting of the disk can be done in | ||
| 192 | BADSECTOR instead of DISKFORMAT on a "report as you | ||
| 193 | go" basis. Formatting goes until a group of bad | ||
| 194 | sectors is encountered, BADSECTOR then reports them | ||
| 195 | by returning with AX and BX set. FORMAT will then | ||
| 196 | call BADSECTOR again and formatting can continue. | ||
| 197 | |||
| 198 | WRTFAT - This routine is called after the disk is | ||
| 199 | formatted and bad sectors have been reported. Its | ||
| 200 | purpose is to write all copies of the FAT from the | ||
| 201 | area of memory referenced by FATSPACE to the drive | ||
| 202 | just formatted. It may be possible to use INT 26H | ||
| 203 | to perform the write, or a direct BIOS call. Whether | ||
| 204 | this is possible depends on whether the FAT ID byte | ||
| 205 | is used by the BIOS to determine the media in the | ||
| 206 | drive. If it is, these methods will probably fail | ||
| 207 | because there is no FAT ID byte on the disk yet (in | ||
| 208 | this case WRTFATs primary job is to get the FAT ID | ||
| 209 | byte out on the disk and thus solve the chicken and | ||
| 210 | egg problem). | ||
| 211 | |||
| 212 | DONE - This routine is called after the formatting is | ||
| 213 | complete, the disk directory has been initialized, | ||
| 214 | and the system has been transferred. It is called | ||
| 215 | once for EACH disk to be formatted. This gives the | ||
| 216 | chance for any finishing-up operations, if needed. | ||
| 217 | If the OEM desires certain extra files to be put | ||
| 218 | on the diskette by default, or according to a switch, | ||
| 219 | this could be done in DONE. Again, as in BADSECTOR | ||
| 220 | and DISKFORMAT, carry flag set on return means an | ||
| 221 | error has occurred: 'Format failure' will be printed | ||
| 222 | and FORMAT will prompt for another disk. | ||
| 223 | |||
| 224 | |||
| 225 | The following data is declared PUBLIC in Microsoft's FORMAT | ||
| 226 | module: | ||
| 227 | |||
| 228 | SWITCHMAP - A word with a bit vector indicating what | ||
| 229 | switches have been included in the command line. The | ||
| 230 | correspondence of the bits to the switches is | ||
| 231 | determined by SWITCHLIST. The right-most | ||
| 232 | (highest-addressed) switch in SWITCHLIST (which must | ||
| 233 | be the system transfer switch, normally "S") | ||
| 234 | corresponds to bit 0, the second from the right, | ||
| 235 | normally "V" to bit 1, etc. For example, if | ||
| 236 | SWITCHLIST is the string "7,'AGI2OVS'", and the user | ||
| 237 | specifies "/G/S" on the command line, then bit 6 will | ||
| 238 | be 0 (A not specified), bit 5 will be 1 (G specified), | ||
| 239 | bits 4,3,2 and 1 will be 0 (neither I,2,O or V | ||
| 240 | specified), and bit 0 will be 1 (S specified). | ||
| 241 | |||
| 242 | Bits 0,1 and 2 are the only switches used in | ||
| 243 | Microsoft's FORMAT module. These switches are used 1) | ||
| 244 | after INIT has been called, to determine if it is | ||
| 245 | necessary to load the system; 2) after the last | ||
| 246 | BADSECTOR call, to determine if the system is to be | ||
| 247 | written, E5 directory conversion is to be done, and/or | ||
| 248 | a volume label is to be asked for. INIT may force | ||
| 249 | these bits set or reset if desired (for example, some | ||
| 250 | drives may never be used as system disk, such as hard | ||
| 251 | disks). After INIT, the "S" bit may be turned off | ||
| 252 | (but not on, since the system was never read) if | ||
| 253 | something happens that means the system should not be | ||
| 254 | transferred. | ||
| 255 | |||
| 256 | After INIT, a second copy of SWITCHMAP is made | ||
| 257 | internally which is used to restore SWITCHMAP for | ||
| 258 | each disk to be formatted. FORMAT itself will turn | ||
| 259 | off the system bit if bad sectors are reported in | ||
| 260 | the system area; DISKFORMAT and BADSECTOR are also | ||
| 261 | allowed to change the map. However, these changes | ||
| 262 | affect only the current disk being formatted, since | ||
| 263 | SWITCHMAP is restored after each disk. (Changes | ||
| 264 | made to SWITCHMAP by INIT do affect ALL disks.) | ||
| 265 | |||
| 266 | DRIVE - A byte containing the drive specified in the | ||
| 267 | command line. 0=A, 1=B, etc. | ||
| 268 | |||
| 269 | Once the OEM-supplied module has been prepared, it must linked | ||
| 270 | with Microsoft's FORMAT.OBJ module and the FORMES.OBJ module. | ||
| 271 | If the OEM-supplied module is called OEMFOR.OBJ, then the | ||
| 272 | following linker command will do: | ||
| 273 | |||
| 274 | LINK FORMAT FORMES OEMFOR; | ||
| 275 | |||
| 276 | This command will produce a file called FORMAT.EXE. FORMAT | ||
| 277 | has been designed to run under MS-DOS as a simple binary | ||
| 278 | .COM file. This conversion is performed by LOCATE (EXE2BIN) | ||
| 279 | with the command | ||
| 280 | |||
| 281 | LOCATE FORMAT.EXE FORMAT.COM | ||
| 282 | |||
| 283 | which will produce the file FORMAT.COM. | ||
| 284 | |||
| 285 | ;***************************************** | ||
| 286 | ; | ||
| 287 | ; A Sample OEM module | ||
| 288 | ; | ||
| 289 | ;***************************************** | ||
| 290 | |||
| 291 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 292 | ; This segment must be | ||
| 293 | ; named CODE, it must be | ||
| 294 | ; PUBLIC, and it's | ||
| 295 | ; classname must be 'CODE' | ||
| 296 | |||
| 297 | |||
| 298 | ASSUME CS:CODE,DS:CODE,ES:CODE | ||
| 299 | |||
| 300 | ; Must declare data and routines PUBLIC | ||
| 301 | |||
| 302 | PUBLIC FATID,STARTSECTOR,SWITCHLIST,FREESPACE | ||
| 303 | PUBLIC INIT,DISKFORMAT,BADSECTOR,DONE,WRTFAT | ||
| 304 | PUBLIC FATSPACE,HARDFLAG | ||
| 305 | |||
| 306 | ; This data defined in Microsoft-supplied module | ||
| 307 | |||
| 308 | EXTRN SWITCHMAP:WORD,DRIVE:BYTE | ||
| 309 | |||
| 310 | INIT: | ||
| 311 | |||
| 312 | ; Read the boot sector into memory | ||
| 313 | CALL READBOOT | ||
| 314 | ... | ||
| 315 | ; Set FATID to double sided if "D" switch specified | ||
| 316 | TEST SWITCHMAP,10H | ||
| 317 | JNZ SETDBLSIDE | ||
| 318 | ... | ||
| 319 | RET | ||
| 320 | |||
| 321 | DISKFORMAT: | ||
| 322 | ... | ||
| 323 | |||
| 324 | ; Use the bit map in SWITCHMAP to determine | ||
| 325 | ; what switches are set | ||
| 326 | |||
| 327 | TEST SWITCHMAP,8 ;Is there a "/C"? | ||
| 328 | JNZ CLEAR ; Yes -- clear operation | ||
| 329 | ; requested jump around the | ||
| 330 | ; format code | ||
| 331 | < format the disk > | ||
| 332 | CLEAR: | ||
| 333 | ... | ||
| 334 | ; Transfer the boot from memory to the new disk | ||
| 335 | CALL TRANSBOOT | ||
| 336 | ... | ||
| 337 | RET | ||
| 338 | |||
| 339 | ; Error return - set carry | ||
| 340 | |||
| 341 | ERRET: | ||
| 342 | STC | ||
| 343 | RET | ||
| 344 | |||
| 345 | BADSECTOR: | ||
| 346 | ... | ||
| 347 | RET | ||
| 348 | |||
| 349 | |||
| 350 | WRTFAT: | ||
| 351 | ... | ||
| 352 | |||
| 353 | WRTFATLOOP: | ||
| 354 | < Set up call to write out a fat to disk> | ||
| 355 | ... | ||
| 356 | MOV BX,[FATSPACE] | ||
| 357 | |||
| 358 | < Write out one fat to disk> | ||
| 359 | JC ERRET | ||
| 360 | ... | ||
| 361 | < Decrement fat counter > | ||
| 362 | JNZ WRTFATLOOP | ||
| 363 | CLC ;Good return | ||
| 364 | RET | ||
| 365 | |||
| 366 | |||
| 367 | DONE: | ||
| 368 | ... | ||
| 369 | RET | ||
| 370 | |||
| 371 | ; Default Single sided | ||
| 372 | FATID DB 0FEH | ||
| 373 | |||
| 374 | HARDFLAG DB 0 | ||
| 375 | |||
| 376 | STARTSECTOR DW 9 | ||
| 377 | |||
| 378 | SWITCHLIST DB 5,"DCOVS" ; "OVS" must be the last | ||
| 379 | ; switches in the list | ||
| 380 | |||
| 381 | FATSPACE DW FATBUF | ||
| 382 | |||
| 383 | FREESPACE DW ENDBOOT | ||
| 384 | |||
| 385 | BOOT DB BOOTSIZE DUP(?) ; Buffer for the | ||
| 386 | ; boot sector | ||
| 387 | |||
| 388 | FATBUF DB 6 * 1024 DUP(?) ; Fat buffer | ||
| 389 | ENDBOOT LABEL BYTE | ||
| 390 | |||
| 391 | CODE ENDS | ||
| 392 | END | ||
| 393 | |||
diff --git a/v2.0/bin/FORMAT.OBJ b/v2.0/bin/FORMAT.OBJ new file mode 100644 index 0000000..61fe107 --- /dev/null +++ b/v2.0/bin/FORMAT.OBJ | |||
| Binary files differ | |||
diff --git a/v2.0/bin/FORMES.OBJ b/v2.0/bin/FORMES.OBJ new file mode 100644 index 0000000..247f39e --- /dev/null +++ b/v2.0/bin/FORMES.OBJ | |||
| Binary files differ | |||
diff --git a/v2.0/bin/INCOMP.DOC b/v2.0/bin/INCOMP.DOC new file mode 100644 index 0000000..6c187b6 --- /dev/null +++ b/v2.0/bin/INCOMP.DOC | |||
| Binary files differ | |||
diff --git a/v2.0/bin/INT24.DOC b/v2.0/bin/INT24.DOC new file mode 100644 index 0000000..d38d6fa --- /dev/null +++ b/v2.0/bin/INT24.DOC | |||
| Binary files differ | |||
diff --git a/v2.0/bin/LINK.EXE b/v2.0/bin/LINK.EXE new file mode 100644 index 0000000..aa58151 --- /dev/null +++ b/v2.0/bin/LINK.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/MASM.EXE b/v2.0/bin/MASM.EXE new file mode 100644 index 0000000..d43bfb7 --- /dev/null +++ b/v2.0/bin/MASM.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/MORE.COM b/v2.0/bin/MORE.COM new file mode 100644 index 0000000..b28f807 --- /dev/null +++ b/v2.0/bin/MORE.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/MSDOS.SYS b/v2.0/bin/MSDOS.SYS new file mode 100644 index 0000000..803eb70 --- /dev/null +++ b/v2.0/bin/MSDOS.SYS | |||
| Binary files differ | |||
diff --git a/v2.0/bin/PRINT.COM b/v2.0/bin/PRINT.COM new file mode 100644 index 0000000..b2788d3 --- /dev/null +++ b/v2.0/bin/PRINT.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/PROFIL.OBJ b/v2.0/bin/PROFIL.OBJ new file mode 100644 index 0000000..66946b3 --- /dev/null +++ b/v2.0/bin/PROFIL.OBJ | |||
| Binary files differ | |||
diff --git a/v2.0/bin/PROFILE.DOC b/v2.0/bin/PROFILE.DOC new file mode 100644 index 0000000..2d50631 --- /dev/null +++ b/v2.0/bin/PROFILE.DOC | |||
| Binary files differ | |||
diff --git a/v2.0/bin/PROHST.EXE b/v2.0/bin/PROHST.EXE new file mode 100644 index 0000000..dfa8983 --- /dev/null +++ b/v2.0/bin/PROHST.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/PROHST.PAS b/v2.0/bin/PROHST.PAS new file mode 100644 index 0000000..4ee13fc --- /dev/null +++ b/v2.0/bin/PROHST.PAS | |||
| @@ -0,0 +1,403 @@ | |||
| 1 | PROGRAM prohst(input,output); | ||
| 2 | {$debug- $line- $symtab+} | ||
| 3 | |||
| 4 | {**********************************************************************} | ||
| 5 | {* *} | ||
| 6 | {* prohst *} | ||
| 7 | {* *} | ||
| 8 | {* This program produces a histogram from the profile file produced *} | ||
| 9 | {* by the MS-DOS profile utility. It optionally reads the map file *} | ||
| 10 | {* generated when the program being profiled was linked, and writes *} | ||
| 11 | {* either the module address or, if available, the line number as *} | ||
| 12 | {* a prefix to the line of the graph which describes a particular *} | ||
| 13 | {* bucket. *} | ||
| 14 | {* *} | ||
| 15 | {* After using filbm (derived from the Pascal and Fortran front end *} | ||
| 16 | {* command scanner) to parse its parameters, prohst opens the map *} | ||
| 17 | {* file if specified, searches for the heading line, and then reads *} | ||
| 18 | {* the lines giving the names and positions of the modules. It builds *} | ||
| 19 | {* a linked list of module names and start addresses. *} | ||
| 20 | {* *} | ||
| 21 | {* It then reads the bucket file header and and bucket array elements *} | ||
| 22 | {* into a variable created on the heap. It simultaneously calculates *} | ||
| 23 | {* a normalization factor. It writes the profile listing header and *} | ||
| 24 | {* starts to write the profile lines. For each bucket, the address *} | ||
| 25 | {* is calculated. The first entry in the address/name linked list *} | ||
| 26 | {* is the lowest addressed module. This is initially the 'current' *} | ||
| 27 | {* module. The bucket address is compared with the current module *} | ||
| 28 | {* address. When it becomes the greater, the module name is written *} | ||
| 29 | {* to the listing and the next entry in the address/name list becomes *} | ||
| 30 | {* the current module. If line numbers are available, the bucket *} | ||
| 31 | {* address is also compared to the current line/address. This is *} | ||
| 32 | {* read and calculated directly from the file. Since there may be *} | ||
| 33 | {* more than one line per bucket, several entries may be read until *} | ||
| 34 | {* the addresses compare within the span of addresses encompassed by *} | ||
| 35 | {* a bucket (its 'width'). Note that the idiosyncracies of Pascal i/o *} | ||
| 36 | {* make it necessary to continually check for the end of the map file *} | ||
| 37 | {* and the complexity of this code is mainly due to an attempt to *} | ||
| 38 | {* make it reasonably resilient to changes in the format of the map *} | ||
| 39 | {* file. *} | ||
| 40 | {* *} | ||
| 41 | {**********************************************************************} | ||
| 42 | |||
| 43 | |||
| 44 | CONST | ||
| 45 | max_file = 32; | ||
| 46 | |||
| 47 | |||
| 48 | TYPE | ||
| 49 | filenam = LSTRING (max_file); | ||
| 50 | sets = SET OF 0..31; | ||
| 51 | address_pointer = ^address_record; | ||
| 52 | address_record = RECORD | ||
| 53 | next: address_pointer; | ||
| 54 | name: STRING (15); | ||
| 55 | address: WORD; | ||
| 56 | END; | ||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | VAR | ||
| 63 | |||
| 64 | i: INTEGER; | ||
| 65 | bucket: FILE OF WORD; | ||
| 66 | hist: TEXT; | ||
| 67 | map: TEXT; | ||
| 68 | |||
| 69 | first_address, | ||
| 70 | this_address: address_pointer; | ||
| 71 | current_base: WORD; | ||
| 72 | bucket_name, | ||
| 73 | hist_name, | ||
| 74 | map_name: filenam; | ||
| 75 | |||
| 76 | switches: sets; | ||
| 77 | |||
| 78 | line: LSTRING (100); | ||
| 79 | |||
| 80 | map_avail: BOOLEAN; | ||
| 81 | line_nos_avail: BOOLEAN; | ||
| 82 | |||
| 83 | norm: REAL; | ||
| 84 | per_cent: INTEGER; | ||
| 85 | real_bucket, | ||
| 86 | norm_bucket: REAL; | ||
| 87 | cum_per_cent, | ||
| 88 | real_per_cent: REAL; | ||
| 89 | |||
| 90 | bucket_num, | ||
| 91 | clock_grain, | ||
| 92 | bucket_size, | ||
| 93 | prog_low_pa, | ||
| 94 | prog_high_pa, | ||
| 95 | dos_pa, | ||
| 96 | hit_io, | ||
| 97 | hit_dos, | ||
| 98 | hit_high: WORD; | ||
| 99 | |||
| 100 | seg, | ||
| 101 | offset, | ||
| 102 | parcel: WORD; | ||
| 103 | |||
| 104 | address: WORD; | ||
| 105 | new_line_no, | ||
| 106 | line_no: WORD; | ||
| 107 | |||
| 108 | dummy : LSTRING (8); | ||
| 109 | name: LSTRING (20); | ||
| 110 | line_no_part: LSTRING (17); | ||
| 111 | start: LSTRING (6); | ||
| 112 | |||
| 113 | buckets: ^SUPER ARRAY [1 .. *] OF REAL; | ||
| 114 | |||
| 115 | this_bucket: WORD; | ||
| 116 | |||
| 117 | LABEL 1; | ||
| 118 | |||
| 119 | |||
| 120 | PROCEDURE filbm (VAR prffil, hstfil, mapfil: filenam; | ||
| 121 | VAR switches: sets); EXTERN; | ||
| 122 | |||
| 123 | FUNCTION realword (w: WORD): REAL; | ||
| 124 | BEGIN | ||
| 125 | IF ORD (w) < 0 THEN BEGIN | ||
| 126 | realword := FLOAT (maxint) + FLOAT (ORD (w - maxint)); | ||
| 127 | END | ||
| 128 | ELSE BEGIN | ||
| 129 | realword := FLOAT (ORD(w)); | ||
| 130 | END {IF}; | ||
| 131 | END {realword}; | ||
| 132 | |||
| 133 | |||
| 134 | |||
| 135 | PROCEDURE skip_spaces; | ||
| 136 | BEGIN | ||
| 137 | WHILE NOT eof(map) AND THEN map^ = ' ' DO BEGIN | ||
| 138 | get (map); | ||
| 139 | END {WHILE}; | ||
| 140 | END {skip_spaces}; | ||
| 141 | |||
| 142 | |||
| 143 | FUNCTION hex_char (ch: CHAR): WORD; | ||
| 144 | BEGIN | ||
| 145 | IF ch >= '0' AND THEN ch <= '9' THEN BEGIN | ||
| 146 | hex_char := WRD (ch) - WRD ('0'); | ||
| 147 | END | ||
| 148 | ELSE IF ch >= 'A' AND THEN ch <= 'F' THEN BEGIN | ||
| 149 | hex_char := WRD (ch) - WRD ('A') + 10; | ||
| 150 | END | ||
| 151 | ELSE BEGIN | ||
| 152 | WRITELN ('Invalid hex character'); | ||
| 153 | hex_char := 0; | ||
| 154 | END {IF}; | ||
| 155 | END {hex_char}; | ||
| 156 | |||
| 157 | |||
| 158 | FUNCTION read_hex (i :WORD): WORD; | ||
| 159 | VAR | ||
| 160 | hex_val: WORD; | ||
| 161 | BEGIN | ||
| 162 | skip_spaces; | ||
| 163 | hex_val := 0; | ||
| 164 | WHILE NOT eof (map) AND THEN i <> 0 DO BEGIN | ||
| 165 | hex_val := hex_val * 16 + hex_char (map^); | ||
| 166 | GET (map); | ||
| 167 | i := i - 1; | ||
| 168 | END {WHILE}; | ||
| 169 | read_hex := hex_val; | ||
| 170 | END {read_hex}; | ||
| 171 | |||
| 172 | FUNCTION read_h: WORD; | ||
| 173 | BEGIN | ||
| 174 | read_h := read_hex (4); | ||
| 175 | get (map); | ||
| 176 | get (map); | ||
| 177 | END; | ||
| 178 | |||
| 179 | FUNCTION read_word: WORD; | ||
| 180 | VAR | ||
| 181 | int_value: WORD; | ||
| 182 | BEGIN | ||
| 183 | int_value := 0; | ||
| 184 | IF NOT EOF (map) THEN BEGIN | ||
| 185 | READ (map, int_value); | ||
| 186 | END {IF}; | ||
| 187 | read_word := int_value; | ||
| 188 | END {read_word}; | ||
| 189 | |||
| 190 | |||
| 191 | FUNCTION map_digit: BOOLEAN; | ||
| 192 | BEGIN | ||
| 193 | map_digit := (map^ >= '0') OR (map^ <= '9'); | ||
| 194 | END {map_digit}; | ||
| 195 | |||
| 196 | BEGIN {prohst} | ||
| 197 | writeln (output, ' Profile Histogram Utility - Version 1.0'); | ||
| 198 | writeln (output); | ||
| 199 | writeln (output, ' Copyright - Microsoft, 1983'); | ||
| 200 | |||
| 201 | start := ' '; | ||
| 202 | |||
| 203 | filbm (bucket_name, hist_name, map_name, switches); | ||
| 204 | |||
| 205 | IF 31 IN switches THEN BEGIN | ||
| 206 | ABORT ('Map file must not be terminal', 0, 0); | ||
| 207 | END {IF}; | ||
| 208 | |||
| 209 | IF NOT (28 IN switches) THEN BEGIN | ||
| 210 | ABORT ('No histogram file specified', 0, 0); | ||
| 211 | END {IF}; | ||
| 212 | |||
| 213 | ASSIGN (bucket, bucket_name); | ||
| 214 | reset (bucket); | ||
| 215 | ASSIGN (hist, hist_name); | ||
| 216 | rewrite (hist); | ||
| 217 | |||
| 218 | map_avail := 29 IN switches; | ||
| 219 | line_nos_avail := FALSE; | ||
| 220 | |||
| 221 | IF map_avail THEN BEGIN | ||
| 222 | ASSIGN (map, map_name); | ||
| 223 | RESET (map); | ||
| 224 | |||
| 225 | WHILE NOT EOF (map) AND THEN start <> ' Start' DO BEGIN | ||
| 226 | READLN (map, start); | ||
| 227 | END {WHILE}; | ||
| 228 | |||
| 229 | NEW (first_address); | ||
| 230 | this_address := NIL; | ||
| 231 | |||
| 232 | WHILE NOT EOF(map) DO BEGIN | ||
| 233 | READLN (map, line); | ||
| 234 | IF line.len < 6 OR ELSE line [2] < '0' OR ELSE | ||
| 235 | line [2] > '9' THEN BEGIN | ||
| 236 | BREAK; | ||
| 237 | END {IF}; | ||
| 238 | |||
| 239 | IF this_address <> NIL THEN BEGIN | ||
| 240 | NEW (this_address^.next); | ||
| 241 | this_address := this_address^.next; | ||
| 242 | END | ||
| 243 | ELSE BEGIN | ||
| 244 | this_address := first_address; | ||
| 245 | END {IF}; | ||
| 246 | this_address^.next := NIL; | ||
| 247 | |||
| 248 | this_address^.address := (hex_char (line [2]) * 4096) + | ||
| 249 | (hex_char (line [3]) * 256) + | ||
| 250 | (hex_char (line [4]) * 16) + | ||
| 251 | hex_char (line [5]); | ||
| 252 | |||
| 253 | FOR i := 1 TO 15 DO BEGIN | ||
| 254 | this_address^.name [i] := line [22 + i]; | ||
| 255 | END {FOR}; | ||
| 256 | |||
| 257 | END {WHILE}; | ||
| 258 | |||
| 259 | WHILE NOT EOF (map) DO BEGIN | ||
| 260 | READLN (map, line_no_part); | ||
| 261 | IF line_no_part = 'Line numbers for ' THEN BEGIN | ||
| 262 | line_nos_avail := TRUE; | ||
| 263 | BREAK; | ||
| 264 | END {IF}; | ||
| 265 | END {WHILE}; | ||
| 266 | |||
| 267 | END {IF}; | ||
| 268 | |||
| 269 | read (bucket, clock_grain, bucket_num, bucket_size, | ||
| 270 | prog_low_pa, prog_high_pa, dos_pa, hit_io, hit_dos, hit_high); | ||
| 271 | |||
| 272 | NEW (buckets,ORD (bucket_num)); | ||
| 273 | |||
| 274 | norm := 0.0; | ||
| 275 | norm_bucket := 0.0; | ||
| 276 | |||
| 277 | FOR i := 1 TO ORD (bucket_num) DO BEGIN | ||
| 278 | read (bucket, this_bucket); | ||
| 279 | real_bucket := realword (this_bucket); | ||
| 280 | |||
| 281 | IF real_bucket > norm_bucket THEN BEGIN | ||
| 282 | norm_bucket := real_bucket; | ||
| 283 | END {IF}; | ||
| 284 | |||
| 285 | norm := norm + real_bucket; | ||
| 286 | buckets^[i] := real_bucket; | ||
| 287 | END {FOR}; | ||
| 288 | norm_bucket := 45.0/norm_bucket; | ||
| 289 | norm := 100.0/norm; | ||
| 290 | |||
| 291 | WRITELN (hist, 'Microsoft Profiler Output Listing'); | ||
| 292 | |||
| 293 | WRITELN (hist); | ||
| 294 | WRITELN (hist, ORD (bucket_num):6, bucket_size:4,'-byte buckets.'); | ||
| 295 | |||
| 296 | WRITELN (hist); | ||
| 297 | WRITELN (hist, 'Profile taken between ', prog_low_pa*16::16, | ||
| 298 | ' and ', prog_high_pa*16::16, '.'); | ||
| 299 | |||
| 300 | WRITELN (hist); | ||
| 301 | WRITELN (hist, 'DOS program address:', dos_pa::16); | ||
| 302 | |||
| 303 | WRITELN (hist); | ||
| 304 | WRITELN (hist, 'Number of hits in DOS: ', hit_dos:5, | ||
| 305 | ' or ', realword (hit_dos) * norm:4:1, '%.'); | ||
| 306 | WRITELN (hist, 'Number of hits in I/O: ', hit_io:5, | ||
| 307 | ' or ', realword (hit_io) * norm:4:1, '%.'); | ||
| 308 | WRITELN (hist, 'Number of hits high : ', hit_high:5, | ||
| 309 | ' or ', realword (hit_high) * norm:4:1, '%.'); | ||
| 310 | WRITELN (hist); | ||
| 311 | WRITELN (hist, ' Hits Addr. Line/ Cumul. % 0.0 ', | ||
| 312 | ' ', | ||
| 313 | 1.0/norm:1:1); | ||
| 314 | |||
| 315 | WRITELN (hist, ' Offset +----------------', | ||
| 316 | '----------------------------'); | ||
| 317 | WRITELN (hist, name); | ||
| 318 | i := 0; | ||
| 319 | parcel := 0; | ||
| 320 | current_base := 0; | ||
| 321 | line_no := 0; | ||
| 322 | new_line_no := 0; | ||
| 323 | cum_per_cent := 0.0; | ||
| 324 | |||
| 325 | WHILE i < ORD (bucket_num) DO BEGIN | ||
| 326 | i := i + 1; | ||
| 327 | IF buckets^[i] < 0.9 THEN BEGIN | ||
| 328 | WRITELN (hist); | ||
| 329 | REPEAT | ||
| 330 | i := i + 1; | ||
| 331 | UNTIL (i = ORD (bucket_num)) OR ELSE buckets^[i] > 0.0; | ||
| 332 | END {IF}; | ||
| 333 | |||
| 334 | address := bucket_size * (WRD (i) - 1); | ||
| 335 | |||
| 336 | WHILE map_avail AND THEN | ||
| 337 | address >= first_address^.address DO BEGIN | ||
| 338 | WRITELN (hist, ' ', first_address^.name); | ||
| 339 | current_base := first_address^.address; | ||
| 340 | first_address := first_address^.next; | ||
| 341 | END {WHILE}; | ||
| 342 | |||
| 343 | WHILE line_nos_avail AND THEN NOT eof (map) AND THEN | ||
| 344 | address >= parcel DO BEGIN | ||
| 345 | skip_spaces; | ||
| 346 | WHILE (map^ < '0') OR (map^ > '9') DO BEGIN | ||
| 347 | |||
| 348 | IF EOF (map) THEN BEGIN | ||
| 349 | goto 1; | ||
| 350 | END {IF}; | ||
| 351 | READLN (map); | ||
| 352 | skip_spaces; | ||
| 353 | END {WHILE}; | ||
| 354 | |||
| 355 | |||
| 356 | line_no := new_line_no; | ||
| 357 | new_line_no := read_word; | ||
| 358 | seg := read_hex (4); | ||
| 359 | IF EOF (map) THEN BEGIN | ||
| 360 | GOTO 1; | ||
| 361 | END {IF}; | ||
| 362 | IF map^ <> ':' THEN BEGIN | ||
| 363 | WRITELN ('Invalid map file'); | ||
| 364 | END {IF}; | ||
| 365 | get (map); | ||
| 366 | IF EOF (map) THEN BEGIN | ||
| 367 | GOTO 1; | ||
| 368 | END {IF}; | ||
| 369 | offset := read_hex (3) + WRD (hex_char (map^) > 0); | ||
| 370 | get (map); | ||
| 371 | IF map^ <> 'H' THEN BEGIN | ||
| 372 | WRITELN ('Invalid map file'); | ||
| 373 | END {IF}; | ||
| 374 | IF EOF (map) THEN BEGIN | ||
| 375 | GOTO 1; | ||
| 376 | END {IF}; | ||
| 377 | get (map); | ||
| 378 | parcel := seg + offset; | ||
| 379 | END {WHILE}; | ||
| 380 | 1: real_per_cent := buckets^[i] * norm; | ||
| 381 | cum_per_cent := cum_per_cent + real_per_cent; | ||
| 382 | per_cent := ROUND ( buckets^[i] * norm_bucket); | ||
| 383 | |||
| 384 | WRITE (hist, buckets^ [i]:6:0, ' ', | ||
| 385 | address*16:6:16); | ||
| 386 | IF line_no <> 0 THEN BEGIN | ||
| 387 | WRITE (hist, line_no:6); | ||
| 388 | line_no := 0; | ||
| 389 | END | ||
| 390 | ELSE IF map_avail AND THEN first_address <> NIL THEN BEGIN | ||
| 391 | WRITE (hist, ' #', address - first_address^.address:4:16); | ||
| 392 | END | ||
| 393 | ELSE BEGIN | ||
| 394 | WRITE (hist, ' '); | ||
| 395 | END {IF}; | ||
| 396 | |||
| 397 | WRITELN (hist, ' ', cum_per_cent:5:1, ' ', real_per_cent:4:1, ' |', | ||
| 398 | '*': per_cent); | ||
| 399 | END {WHILE}; | ||
| 400 | WRITELN (hist, ' +-----------------', | ||
| 401 | '------------------'); | ||
| 402 | END. | ||
| 403 | |||
diff --git a/v2.0/bin/QUICK.DOC b/v2.0/bin/QUICK.DOC new file mode 100644 index 0000000..d443b8e --- /dev/null +++ b/v2.0/bin/QUICK.DOC | |||
| Binary files differ | |||
diff --git a/v2.0/bin/README.DOC b/v2.0/bin/README.DOC new file mode 100644 index 0000000..c5bbf25 --- /dev/null +++ b/v2.0/bin/README.DOC | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | MSDOS 2.0 RELEASE | ||
| 2 | |||
| 3 | |||
| 4 | The 2.0 Release of MSDOS includes five 5 1/4 double density single sided | ||
| 5 | diskettes or three 8 iinch CP/M 80 format diskettes. | ||
| 6 | |||
| 7 | The software/documentation on the five inch diskettes is arranged | ||
| 8 | as follows: | ||
| 9 | |||
| 10 | 1. DOS distribution diskette. This diskette contains files which | ||
| 11 | should be distriibuted to all users. This allows the DOS distri- | ||
| 12 | bution diskette to meet the requirements of users of high level | ||
| 13 | language compilers as well as users running only applications. | ||
| 14 | Many compilers marketed independently through the retail channel | ||
| 15 | (including those of Microsoft) assume LINK comes with the DOS, as | ||
| 16 | in the case of IBM. How you choose to distrubute BASIC (contracted | ||
| 17 | for separately) is up to you. | ||
| 18 | |||
| 19 | 2. Assembly Language Development System diskette. This diskette | ||
| 20 | contains files of interest to assembly language programmers. | ||
| 21 | High level language programmers do not need these programs unless | ||
| 22 | they are writing assembly language subroutines. IBM chose to | ||
| 23 | unbundle this package from the DOS distribution diskette (except | ||
| 24 | for DEBUG), but you do not have to do so. | ||
| 25 | |||
| 26 | 3. PRINT and FORMAT diskette. This diskette contains .ASM source | ||
| 27 | files which are necessary to assemble the print spooler, which you | ||
| 28 | may wish to customize for greater performance. .OBJ files are also | ||
| 29 | included for the FORMAT utility. | ||
| 30 | |||
| 31 | 4. Skeltal BIOS and documentation diskette. This diskette contains | ||
| 32 | the skeltal BIOS source code and the SYSINIT and SYSIMES object | ||
| 33 | modules which must be linked with your BIOS module. The proper | ||
| 34 | sequence for linking is BIOS - SYSINIT - SYSIMES. | ||
| 35 | A profiler utiliity is also included on the diskette, but this | ||
| 36 | is not intended for end-users. This is distributed for use by | ||
| 37 | your development staff only and is not supported by Microsoft | ||
| 38 | If you do decide to distribute it, it is at your own risk! | ||
| 39 | |||
| 40 | |||
| 41 | 5. Documentation. Features of 2.0 are documented on this disk. | ||
| 42 | |||
| 43 | The user manual contains some significant errors. Most of these are | ||
| 44 | due to last minute changes to achieve a greater degree of compatibility | ||
| 45 | with IBM's implementation of MS-DOS (PC DOS). This includes the use | ||
| 46 | of "\" instead of "/" as the path separator, and "/" instead of "-" | ||
| 47 | as the switch character. For transporting of batch files across | ||
| 48 | machines, Microsoft encourages the use of "\" and "/" respectively | ||
| 49 | in the U.S. market. (See DOSPATCH.TXT for how you can overide this. | ||
| 50 | The user guide explains how the end-user can override this in CONFIG.SYS). | ||
| 51 | Both the printer echo keys and insert mode keys have now been made to | ||
| 52 | toggle. The default prompt (this may also be changed by the user | ||
| 53 | with the PROMPT command) has been changed from "A:" to "A>". | ||
| 54 | We apologize for any inconveniences these changes may have caused | ||
| 55 | your technical publications staff. | ||
| 56 | |||
| 57 | |||
| 58 | Here is what you need to do to MSDOS 2.0 to create a shipable product: | ||
| 59 | (see "Making a Bootable Diskette" below) | ||
| 60 | |||
| 61 | 1. BIOS. If you have developed a BIOS for the Beta Test 2.0 version | ||
| 62 | You should link your BIOS module to SYSINIT.OBJ and SYSIMES.OBJ. | ||
| 63 | You must modify your BIOS to accomodate the call back to the BIOS | ||
| 64 | at the end of SYSINIT. If you have no need for this call, simply | ||
| 65 | find a far RET and label it RE_INIT and declare it public. | ||
| 66 | An example of this can be found in the skeletal BIOS. In addition | ||
| 67 | please add support for the new fast console output routine as | ||
| 68 | described in the device drivers document. We strongly recommend | ||
| 69 | that you adapt the standard boot sector format also described in | ||
| 70 | device drivers. Once again, please refer to the skeletal BIOS. | ||
| 71 | If you have not yet implemented version 2.0 please read the device | ||
| 72 | drivers document. Microsoft strongly recommends that machines | ||
| 73 | incorporating integrated display devices with memory mapped video | ||
| 74 | RAM implement some sort of terminal emulations through the use of | ||
| 75 | escape sequences. The skeletal BIOS includes a sample ANSI | ||
| 76 | terminal driver. | ||
| 77 | |||
| 78 | 2. Please refer to DOSPATCH.TXT for possible changes you might wish | ||
| 79 | to make. We strongly recommend that you not patch the switch | ||
| 80 | characters for the U.S. market. Your one byte serial number | ||
| 81 | will be issued upon signing the license agreement. Please patch | ||
| 82 | the DOS accordingly. If you wish to serialize the DOS, this is | ||
| 83 | described in DOSPATCH.TXT. Please patch the editing template | ||
| 84 | definitions. Please note the addition of the Control-Z entry | ||
| 85 | at the beginning of the table. Also note that the insert switches | ||
| 86 | have now both been made to toggle. | ||
| 87 | |||
| 88 | 3. Utilities. FORMAT must be configured for each specific system. | ||
| 89 | GENFOR is a generic example of a system independent format module, | ||
| 90 | but it is not recommended that this be distributed to your customers. | ||
| 91 | Link in the following order: FORMAT, FORMES, (your format module). | ||
| 92 | The print spooler is distributed as an executable file, which only | ||
| 93 | prints during wait for keyboard input. If you wish with your | ||
| 94 | implementation to steal some compute time when printing as well, | ||
| 95 | you will need to customize it and reassemble. Please note that | ||
| 96 | you can use a printer-ready or timer interrupt. The former is more | ||
| 97 | efficient, but ties the user to a specific device. Sample code | ||
| 98 | is conditionaled out for the IBM PC timer interrupt. | ||
| 99 | |||
| 100 | The following problems are known to exist: | ||
| 101 | |||
| 102 | 1. Macro assembler does not support the initialization of 10-byte | ||
| 103 | floating point constants in 8087 emulation mode - the last two bytes | ||
| 104 | are zero filled. | ||
| 105 | |||
| 106 | 2. LIB has not been provided. The version which incorporates support | ||
| 107 | for 2.0 path names will be completed in a couple of weeks. The | ||
| 108 | 1.x version should work fine if you cannot wait. Because the library | ||
| 109 | manager acts as a counterpart to the linker, we recommend that it | ||
| 110 | be distributed with the DOS distribution diskette as opposed to the | ||
| 111 | assembly language development system. | ||
| 112 | |||
| 113 | 3. International (French, German, Japanese, and U.K.) versions will be | ||
| 114 | available in several months. | ||
| 115 | |||
| 116 | 4. COMMAND.ASM is currently too large to assemble on a micro. It is | ||
| 117 | being broken down into separate modules so it can be asembled on | ||
| 118 | a machine. Source licensees should realize that the resultant | ||
| 119 | binaries from the new version will not correspond exactly to the | ||
| 120 | old version. | ||
| 121 | |||
| 122 | 5. If you have any further questions regarding the MSDOS 2.0 distribution | ||
| 123 | please contact Don Immerwahr (OEM technical support (206) 828-8086). | ||
| 124 | |||
| 125 | |||
| 126 | Sincerely yours, | ||
| 127 | |||
| 128 | |||
| 129 | Chris Larson | ||
| 130 | MS-DOS Product Marketing Manager | ||
| 131 | (206) 828-8080 | ||
| 132 | |||
| 133 | |||
| 134 | |||
| 135 | BUILDING A BOOTABLE (MSDOS FORMAT) DISKETTE | ||
| 136 | |||
| 137 | |||
| 138 | 1. In implementing MSDOS on a new machine, it is highly recommended | ||
| 139 | that an MSDOS machine be available for the development. | ||
| 140 | Please note that utilities shipped with MSDOS 2.0 use MSDOS 2.0 | ||
| 141 | system calls and WILL NOT not run under MSDOS 1.25. | ||
| 142 | |||
| 143 | 2. Use your MSDOS development machine and EDLIN or a word processor | ||
| 144 | package to write BOOT.ASM, your bootstrap loader BIOS.ASM and | ||
| 145 | your Format module. | ||
| 146 | |||
| 147 | 3. Use MASM, the Microsoft Macro-86 Assembler, to assemble these | ||
| 148 | modules. LINK is then used to link together the .OBJ modules in | ||
| 149 | the order specified. | ||
| 150 | |||
| 151 | 4. Link creates .EXE format files which are not memory image files | ||
| 152 | and contain relocation information in their headers. Since your | ||
| 153 | BIOS and BOOT routines will not be loaded by the EXE loader in | ||
| 154 | MSDOS, they must first be turned into memory image files by | ||
| 155 | using the EXE2BIN utility. | ||
| 156 | |||
| 157 | 5. The easiest thing to do is to (using your development machine) | ||
| 158 | FORMAT a single sided diskette without the system. Use DEBUG | ||
| 159 | to load and write your BOOT.COM bootstrap loader to the BOOT | ||
| 160 | sector of that diskette. You may decide to have your bootstrap | ||
| 161 | load BIOS and let the BIOS load MSDOS or it may load both. Note that | ||
| 162 | the Bootstrap loader will have to know physically where to go on | ||
| 163 | the disk to get the BIOS and the DOS. COMMAND.COM is loaded | ||
| 164 | by the SYSINIT module. | ||
| 165 | |||
| 166 | 6. Use the COPY command to copy your IO.SYS file (what the | ||
| 167 | BIOS-SYSINIT-SYSIMES module is usually called) onto the disk | ||
| 168 | followed by MSDOS.SYS and COMMAND.COM. You may use DEBUG | ||
| 169 | to change the directory attribute bytes to make these files hidden. | ||
| 170 | |||
| 171 | CAUTION: | ||
| 172 | |||
| 173 | At all times, the BIOS writer should be careful to preserve the state | ||
| 174 | of the DOS - including the flags. You should be also be cautioned that | ||
| 175 | the MSDOS stack is not deep. You should not count on more than one or | ||
| 176 | two pushes of the registers. | ||
| 177 | |||
diff --git a/v2.0/bin/RECOVER.COM b/v2.0/bin/RECOVER.COM new file mode 100644 index 0000000..fa51fae --- /dev/null +++ b/v2.0/bin/RECOVER.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/SORT.EXE b/v2.0/bin/SORT.EXE new file mode 100644 index 0000000..9e2c19a --- /dev/null +++ b/v2.0/bin/SORT.EXE | |||
| Binary files differ | |||
diff --git a/v2.0/bin/SYS.COM b/v2.0/bin/SYS.COM new file mode 100644 index 0000000..2d315d7 --- /dev/null +++ b/v2.0/bin/SYS.COM | |||
| Binary files differ | |||
diff --git a/v2.0/bin/SYSCALL.DOC b/v2.0/bin/SYSCALL.DOC new file mode 100644 index 0000000..26d4729 --- /dev/null +++ b/v2.0/bin/SYSCALL.DOC | |||
| @@ -0,0 +1,1657 @@ | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | MS-DOS 2.0 | ||
| 20 | |||
| 21 | System Calls Reference | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | |||
| 34 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 35 | | | | ||
| 36 | | C A V E A T P R O G R A M M E R | | ||
| 37 | | | | ||
| 38 | | Certain structures, constants and system calls below | | ||
| 39 | | are private to the DOS and are extremely | | ||
| 40 | | version-dependent. They may change at any time at the | | ||
| 41 | | implementors' whim. As a result, they must not be | | ||
| 42 | | documented to the general public. If an extreme case | | ||
| 43 | | arises, they must be documented with this warning. | | ||
| 44 | | | | ||
| 45 | | Those structures and constants that are subject to the | | ||
| 46 | | above will be marked and bracketed with the flag: | | ||
| 47 | | | | ||
| 48 | | C A V E A T P R O G R A M M E R | | ||
| 49 | | | | ||
| 50 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 51 | |||
| 52 | |||
| 53 | |||
| 54 | |||
| 55 | |||
| 56 | |||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | |||
| 63 | |||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | |||
| 69 | Section 1 | ||
| 70 | |||
| 71 | Extensions to existing call structure | ||
| 72 | |||
| 73 | |||
| 74 | Name: * Alloc - allocate memory | ||
| 75 | |||
| 76 | Assembler usage: | ||
| 77 | MOV BX,size | ||
| 78 | MOV AH,Alloc | ||
| 79 | INT 21h | ||
| 80 | ; AX:0 is pointer to allocated memory | ||
| 81 | ; if alloc fails, BX is the largest block available | ||
| 82 | |||
| 83 | Description: | ||
| 84 | Alloc returns a pointer to a free block of memory | ||
| 85 | that has the requested size in paragraphs. | ||
| 86 | |||
| 87 | Error return: | ||
| 88 | AX = error_not_enough_memory | ||
| 89 | The largest available free block is smaller | ||
| 90 | than that requested or there is no free block. | ||
| 91 | = error_arena_trashed | ||
| 92 | The internal consistency of the memory arena | ||
| 93 | has been destroyed. This is due to a user | ||
| 94 | program changing memory that does not belong | ||
| 95 | to it. | ||
| 96 | |||
| 97 | |||
| 98 | Name: * CharOper - change incompatible configuration | ||
| 99 | parameters | ||
| 100 | |||
| 101 | Assembler usage: | ||
| 102 | MOV AH, CharOper | ||
| 103 | MOV AL, func | ||
| 104 | MOV DL, data | ||
| 105 | INT 21h | ||
| 106 | ; on read functions, data is returned in DL | ||
| 107 | |||
| 108 | Description: | ||
| 109 | CharOper allows a program to change system | ||
| 110 | parameters to allow for switch indicators and whether | ||
| 111 | devices are available at every level of the directory | ||
| 112 | tree. | ||
| 113 | |||
| 114 | A function code is passed in AL: | ||
| 115 | |||
| 116 | AL Function | ||
| 117 | -- -------- | ||
| 118 | 0 DL, on return, will contain the DOS switch | ||
| 119 | character. On most systems this will default to | ||
| 120 | '-'. | ||
| 121 | 1 Set the switch character to the character in DL. | ||
| 122 | 2 Read the device availability byte into DL. If | ||
| 123 | this byte is 0, then devices must be accessed in | ||
| 124 | file I/O calls by /dev/device. If this byte is | ||
| 125 | non-zero, then the devices are available at every | ||
| 126 | node of the directory tree (i.e. CON is the | ||
| 127 | console device not the file CON). This byte is | ||
| 128 | generally 0. | ||
| 129 | 3 Set the device availability byte to the value in | ||
| 130 | DL. | ||
| 131 | |||
| 132 | Error returns: | ||
| 133 | AL = FF | ||
| 134 | The function code specified in AL is not in | ||
| 135 | the range 0:3 | ||
| 136 | |||
| 137 | |||
| 138 | Name: * CurrentDir - return text of current directory | ||
| 139 | |||
| 140 | Assembler usage: | ||
| 141 | MOV AH,CurrentDir | ||
| 142 | LDS SI,area | ||
| 143 | MOV DL,drive | ||
| 144 | INT 21h | ||
| 145 | ; DS:SI is a pointer to 64 byte area that contains | ||
| 146 | ; drive current directory. | ||
| 147 | |||
| 148 | Description: | ||
| 149 | CurrentDir returns the current directory for a | ||
| 150 | particular drive. The directory is root-relative and | ||
| 151 | does not contain the drive specifier. The drive code | ||
| 152 | passed in DL is 0=default, 1=A, 2=B, etc. | ||
| 153 | |||
| 154 | Error returns: | ||
| 155 | AX = error_invalid_drive | ||
| 156 | The drive specified in DL was invalid. | ||
| 157 | |||
| 158 | |||
| 159 | Name: * Dealloc - free allocated memory | ||
| 160 | |||
| 161 | Assembler usage: | ||
| 162 | MOV ES,block | ||
| 163 | MOV AH,dealloc | ||
| 164 | INT 21h | ||
| 165 | |||
| 166 | Description: | ||
| 167 | Dealloc returns a piece of memory to the system | ||
| 168 | pool that was allocated by alloc. | ||
| 169 | |||
| 170 | Error return: | ||
| 171 | AX = error_invalid_block | ||
| 172 | The block passed in ES is not one allocated | ||
| 173 | via Alloc. | ||
| 174 | = error_arena_trashed | ||
| 175 | The internal consistency of the memory arena | ||
| 176 | has been destroyed. This is due to a user | ||
| 177 | program changing memory that does not belong | ||
| 178 | to it. | ||
| 179 | |||
| 180 | |||
| 181 | Name: * FileTimes - get/set the write times of a | ||
| 182 | handle | ||
| 183 | |||
| 184 | Assembler usage: | ||
| 185 | MOV AH, FileTimes | ||
| 186 | MOV AL, func | ||
| 187 | MOV BX, handle | ||
| 188 | ; if AL = 1 then then next two are mandatory | ||
| 189 | MOV CX, time | ||
| 190 | MOV DX, date | ||
| 191 | INT 21h | ||
| 192 | ; if AL = 0 then CX/DX has the last write time/date | ||
| 193 | ; for the handle. | ||
| 194 | |||
| 195 | Description: | ||
| 196 | FileTimes returns or sets the last-write time for | ||
| 197 | a handle. These times are not recorded until the file | ||
| 198 | is closed. | ||
| 199 | |||
| 200 | A function code is passed in AL: | ||
| 201 | |||
| 202 | AL Function | ||
| 203 | -- -------- | ||
| 204 | 0 Return the time/date of the handle in CX/DX | ||
| 205 | 1 Set the time/date of the handle to CX/DX | ||
| 206 | |||
| 207 | Error returns: | ||
| 208 | AX = error_invalid_function | ||
| 209 | The function passed in AL was not in the range | ||
| 210 | 0:1. | ||
| 211 | = error_invalid_handle | ||
| 212 | The handle passed in BX was not currently | ||
| 213 | open. | ||
| 214 | |||
| 215 | |||
| 216 | Name: * FindFirst - find matching file | ||
| 217 | |||
| 218 | Assembler usage: | ||
| 219 | MOV AH, FindFirst | ||
| 220 | LDS DX, pathname | ||
| 221 | MOV CX, attr | ||
| 222 | INT 21h | ||
| 223 | ; DMA address has datablock | ||
| 224 | |||
| 225 | Description: | ||
| 226 | FindFirst takes a pathname with wildcards in the | ||
| 227 | last component (passed in DS:DX), a set of attributes | ||
| 228 | (passed in CX) and attempts to find all files that | ||
| 229 | match the pathname and have a subset of the required | ||
| 230 | attributes. A datablock at the current DMA is written | ||
| 231 | that contains information in the following form: | ||
| 232 | |||
| 233 | find_buf STRUC | ||
| 234 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 235 | | C A V E A T P R O G R A M M E R | | ||
| 236 | | | | ||
| 237 | find_buf_sattr DB ? ; attribute of search | ||
| 238 | find_buf_drive DB ? ; drive of search | ||
| 239 | find_buf_name DB 11 DUP (?); search name | ||
| 240 | find_buf_LastEnt DW ? ; LastEnt | ||
| 241 | find_buf_ThisDPB DD ? ; This DPB | ||
| 242 | find_buf_DirStart DW ? ; DirStart | ||
| 243 | | | | ||
| 244 | | C A V E A T P R O G R A M M E R | | ||
| 245 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 246 | |||
| 247 | find_buf_attr DB ? ; attribute found | ||
| 248 | find_buf_time DW ? ; time | ||
| 249 | find_buf_date DW ? ; date | ||
| 250 | find_buf_size_l DW ? ; low(size) | ||
| 251 | find_buf_size_h DW ? ; high(size) | ||
| 252 | find_buf_pname DB 13 DUP (?) ; packed name | ||
| 253 | find_buf ENDS | ||
| 254 | |||
| 255 | To obtain the subsequent matches of the pathname, | ||
| 256 | see the description of FindNext | ||
| 257 | |||
| 258 | Error Returns: | ||
| 259 | AX = error_file_not_found | ||
| 260 | The path specified in DS:DX was an invalid | ||
| 261 | path. | ||
| 262 | = error_no_more_files | ||
| 263 | There were no files matching this | ||
| 264 | specification. | ||
| 265 | |||
| 266 | |||
| 267 | Name: * FindNext - step through a directory matching | ||
| 268 | files | ||
| 269 | |||
| 270 | Assembler usage: | ||
| 271 | ; DMA points at area returned by find_first | ||
| 272 | MOV AH, findnext | ||
| 273 | INT 21h | ||
| 274 | ; next entry is at dma | ||
| 275 | |||
| 276 | Description: | ||
| 277 | FindNext finds the next matching entry in a | ||
| 278 | directory. The current DMA address must point at a | ||
| 279 | block returned by FindFirst (see FindFirst). | ||
| 280 | |||
| 281 | Error Returns: | ||
| 282 | AX = error_no_more_files | ||
| 283 | There are no more files matching this pattern. | ||
| 284 | |||
| 285 | |||
| 286 | Name: * GetDMA - get current DMA transfer address | ||
| 287 | |||
| 288 | Assembler usage: | ||
| 289 | MOV AH,GetDMA | ||
| 290 | INT 21h | ||
| 291 | ; ES:BX has current DMA transfer address | ||
| 292 | |||
| 293 | Description: | ||
| 294 | Return DMA transfer address. | ||
| 295 | |||
| 296 | Error returns: | ||
| 297 | None. | ||
| 298 | |||
| 299 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 300 | | C A V E A T P R O G R A M M E R | | ||
| 301 | | | | ||
| 302 | |||
| 303 | Name: * GetDSKPT(DL) - get pointer to drive parameter | ||
| 304 | block | ||
| 305 | |||
| 306 | Assembler usage: | ||
| 307 | MOV AH,GetDSKPT | ||
| 308 | INT 21h | ||
| 309 | ; DS:BX has address of drive parameter block | ||
| 310 | |||
| 311 | Description: | ||
| 312 | Return pointer to default drive parameter block. | ||
| 313 | |||
| 314 | Error returns: | ||
| 315 | None. | ||
| 316 | |||
| 317 | Assembler usage: | ||
| 318 | MOV DL,DrvNUM | ||
| 319 | MOV AH,GetDSKPTDL | ||
| 320 | INT 21h | ||
| 321 | ; DS:BX has address of drive parameter block | ||
| 322 | |||
| 323 | Description: | ||
| 324 | Return pointer to drive parameter block for drive | ||
| 325 | designated in DL (0=Default, A=1, B=2 ...) | ||
| 326 | |||
| 327 | Error returns: | ||
| 328 | AL = FF | ||
| 329 | The drive given in DL is invalid. | ||
| 330 | | | | ||
| 331 | | C A V E A T P R O G R A M M E R | | ||
| 332 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 333 | |||
| 334 | |||
| 335 | Name: * GetFreespace - get Disk free space | ||
| 336 | |||
| 337 | Assembler usage: | ||
| 338 | MOV AH,GetFreespace | ||
| 339 | MOV DL,Drive ;0 = default, A = 1 | ||
| 340 | INT 21h | ||
| 341 | ; BX = Number of free allocation units on drive | ||
| 342 | ; DX = Total number of allocation units on drive | ||
| 343 | ; CX = Bytes per sector | ||
| 344 | ; AX = Sectors per allocation unit | ||
| 345 | |||
| 346 | Description: | ||
| 347 | Return Free space on disk along with additional | ||
| 348 | information about the disk. | ||
| 349 | |||
| 350 | Error returns: | ||
| 351 | AX = FFFF | ||
| 352 | The drive number given in DL was invalid. | ||
| 353 | |||
| 354 | NOTE: This call returns the same information in the same | ||
| 355 | registers (except for the FAT pointer) as the get FAT | ||
| 356 | pointer calls did in previous versions of the DOS. | ||
| 357 | |||
| 358 | |||
| 359 | Name: * GetInDOSF - get DOS critical-section flag | ||
| 360 | |||
| 361 | Assembler usage: | ||
| 362 | MOV AH,GetInDOSF | ||
| 363 | INT 21h | ||
| 364 | ; ES:BX has location of the flag | ||
| 365 | MOV CritSEG, ES | ||
| 366 | MOV CritOFF, BX | ||
| 367 | ... | ||
| 368 | IntVec: | ||
| 369 | MOV AX, DWORD PTR Crit | ||
| 370 | CMP AX,0 | ||
| 371 | JZ DoFunc | ||
| 372 | IRET | ||
| 373 | DoFunc: ... | ||
| 374 | |||
| 375 | Description: | ||
| 376 | Return location of indos flag. On return ES:BX is | ||
| 377 | the address of a byte memory cell inside the DOS. If | ||
| 378 | used in an interrupt service routine, it indicates | ||
| 379 | whether or not the DOS was interrupted in a critical | ||
| 380 | section. If the cell was zero, then the DOS was not | ||
| 381 | in a critical section and thus can be called by the | ||
| 382 | interrupt routine. If the cell was non-zero, the DOS | ||
| 383 | should be considered to be in an uninterruptable state | ||
| 384 | and for reliability, no DOS calls should be given. | ||
| 385 | |||
| 386 | Error returns: | ||
| 387 | None. | ||
| 388 | |||
| 389 | |||
| 390 | Name: * GetVector - get interrupt vector | ||
| 391 | |||
| 392 | Assembler usage: | ||
| 393 | MOV AH,GetVector | ||
| 394 | MOV AL,interrupt | ||
| 395 | INT 21h | ||
| 396 | ; ES:BX now has long pointer to interrupt routine | ||
| 397 | |||
| 398 | Description: | ||
| 399 | Return interrupt vector associated with an | ||
| 400 | interrupt. | ||
| 401 | |||
| 402 | Error returns: | ||
| 403 | None. | ||
| 404 | |||
| 405 | |||
| 406 | Name: * GetVerifyFlag - return current setting of the | ||
| 407 | verify after write flag. | ||
| 408 | |||
| 409 | Assembler usage: | ||
| 410 | MOV AH,GetVerifyFlag | ||
| 411 | INT 21h | ||
| 412 | ; AL is the current verify flag value | ||
| 413 | |||
| 414 | Description: | ||
| 415 | The current value of the verify flag is returned | ||
| 416 | in AL. | ||
| 417 | |||
| 418 | Error returns: | ||
| 419 | None. | ||
| 420 | |||
| 421 | |||
| 422 | Name: * GetVersion - get DOS version number | ||
| 423 | |||
| 424 | Assembler usage: | ||
| 425 | MOV AH,GetVersion | ||
| 426 | INT 21h | ||
| 427 | ; AL is the major version number | ||
| 428 | ; AH is the minor version number | ||
| 429 | ; BH is the OEM number | ||
| 430 | ; BL:CX is the (24 bit) user number | ||
| 431 | |||
| 432 | Description: | ||
| 433 | Return MS-DOS version number. On return AL.AH | ||
| 434 | will be the two part version designation, ie. for | ||
| 435 | MS-DOS 1.28 AL would be 1 and AH would be 28. For pre | ||
| 436 | 1.28 DOS AL = 0. Note that version 1.1 is the same as | ||
| 437 | 1.10, not the same as 1.01. | ||
| 438 | |||
| 439 | Error returns: | ||
| 440 | None. | ||
| 441 | |||
| 442 | |||
| 443 | Name: * International - return country dependent | ||
| 444 | information | ||
| 445 | |||
| 446 | Assembler usage: | ||
| 447 | LDS DX, blk | ||
| 448 | MOV AH, International | ||
| 449 | MOV AL, func | ||
| 450 | INT 21h | ||
| 451 | |||
| 452 | Description: | ||
| 453 | This call returns in the block of memory pointed | ||
| 454 | to by DS:DX, the following information pertinent to | ||
| 455 | international applications: | ||
| 456 | |||
| 457 | +---------------------------+ | ||
| 458 | | WORD Date/time format | | ||
| 459 | +---------------------------+ | ||
| 460 | | BYTE ASCIZ string | | ||
| 461 | | currency symbol | | ||
| 462 | +---------------------------+ | ||
| 463 | | BYTE ASCIZ string | | ||
| 464 | | thousands separator | | ||
| 465 | +---------------------------+ | ||
| 466 | | BYTE ASCIZ string decimal | | ||
| 467 | | separator | | ||
| 468 | +---------------------------+ | ||
| 469 | |||
| 470 | The date/time format has the following values and | ||
| 471 | meanings: | ||
| 472 | |||
| 473 | 0 - USA standard h:m:s m/d/y | ||
| 474 | 1 - Europe standard h:m:s d/m/y | ||
| 475 | 2 - Japan standard y/m/d h:m:s | ||
| 476 | |||
| 477 | The value passed in AL is either 0 (for current | ||
| 478 | country) or a country code (to be defined later. | ||
| 479 | Currently the country code must be zero). | ||
| 480 | |||
| 481 | Error returns: | ||
| 482 | AX = error_invalid_function | ||
| 483 | The function passed in AL was not 0 | ||
| 484 | (currently). | ||
| 485 | |||
| 486 | |||
| 487 | Name: * KeepProcess - terminate process and remain | ||
| 488 | resident | ||
| 489 | |||
| 490 | Assembler usage: | ||
| 491 | MOV AL, exitcode | ||
| 492 | MOV DX, parasize | ||
| 493 | MOV AH, KeepProcess | ||
| 494 | INT 21h | ||
| 495 | |||
| 496 | Description: | ||
| 497 | This call terminates the current process and | ||
| 498 | attempts to set the initial allocation block to a | ||
| 499 | specific size in paragraphs. It will not free up any | ||
| 500 | other allocation blocks belonging to that process. | ||
| 501 | The exit code passed in AX is retrievable by the | ||
| 502 | parent via Wait. | ||
| 503 | |||
| 504 | Error Returns: | ||
| 505 | None. | ||
| 506 | |||
| 507 | |||
| 508 | Name: * Rename - move a directory entry | ||
| 509 | |||
| 510 | Assembler usage: | ||
| 511 | LDS DX, source | ||
| 512 | LES DI, dest | ||
| 513 | MOV AH, Rename | ||
| 514 | INT 21h | ||
| 515 | |||
| 516 | Description: | ||
| 517 | Rename will attempt to rename a file into another | ||
| 518 | path. The paths must be on the same device. | ||
| 519 | |||
| 520 | Error returns: | ||
| 521 | AX = error_file_not_found | ||
| 522 | The file name specifed by DS:DX was not found. | ||
| 523 | = error_not_same_device | ||
| 524 | The source and destination are on different | ||
| 525 | drives. | ||
| 526 | = error_access_denied | ||
| 527 | The path specified in DS:DX was a directory or | ||
| 528 | the file specified by ES:DI exists or the | ||
| 529 | destination directory entry could not be | ||
| 530 | created. | ||
| 531 | |||
| 532 | |||
| 533 | Name: * SetBlock - modify allocated blocks | ||
| 534 | |||
| 535 | Assembler usage: | ||
| 536 | MOV ES,block | ||
| 537 | MOV BX,newsize | ||
| 538 | MOV AH,setblock | ||
| 539 | INT 21h | ||
| 540 | ; if setblock fails for growing, BX will have the | ||
| 541 | ; maximum size possible | ||
| 542 | |||
| 543 | Description: | ||
| 544 | Setblock will attempt to grow/shrink an allocated | ||
| 545 | block of memory. | ||
| 546 | |||
| 547 | Error return: | ||
| 548 | AX = error_invalid_block | ||
| 549 | The block passed in ES is not one allocated | ||
| 550 | via Alloc. | ||
| 551 | = error_arena_trashed | ||
| 552 | The internal consistency of the memory arena | ||
| 553 | has been destroyed. This is due to a user | ||
| 554 | program changing memory that does not belong | ||
| 555 | to it. | ||
| 556 | = error_not_enough_memory | ||
| 557 | There was not enough free memory after the | ||
| 558 | specified block to satisfy the grow request. | ||
| 559 | |||
| 560 | |||
| 561 | Name: * SetCtrlCTrapping - turn on/off broad ^C | ||
| 562 | checking | ||
| 563 | |||
| 564 | Assembler usage: | ||
| 565 | MOV DL,val | ||
| 566 | MOV AH,SetCtrlCTrapping | ||
| 567 | MOV AL,func | ||
| 568 | INT 21h | ||
| 569 | ; If AL was 0, then DL has the current value of the | ||
| 570 | ; ^C check | ||
| 571 | |||
| 572 | Description: | ||
| 573 | MSDOS ordinarily checks for a ^C on the | ||
| 574 | controlling device only when doing a function 1-12 | ||
| 575 | operation to that device. SetCtrlCTrapping allows the | ||
| 576 | user to expand this checking to include any system | ||
| 577 | call. For example, with the ^C trapping off, all disk | ||
| 578 | I/O will proceed without interruption while with ^C | ||
| 579 | trapping on, the ^C interrupt is given at the system | ||
| 580 | call that initiates the disk operation. | ||
| 581 | |||
| 582 | Error return: | ||
| 583 | AL = FF | ||
| 584 | The function passed in AL was not in the range | ||
| 585 | 0:1. | ||
| 586 | |||
| 587 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 588 | | C A V E A T P R O G R A M M E R | | ||
| 589 | | | | ||
| 590 | |||
| 591 | Name: * Set_OEM_Handler - set handler for OEM | ||
| 592 | specific INT 21H calls. | ||
| 593 | |||
| 594 | Assembler usage: | ||
| 595 | LDS DX,handler_address | ||
| 596 | MOV AH,Set_OEM_Handler | ||
| 597 | INT 21H | ||
| 598 | |||
| 599 | Description: | ||
| 600 | Set handler address for 0F9H-0FFH INT 21H system | ||
| 601 | calls to DS:DX. To return the 0F9H-0FFH calls to | ||
| 602 | the uninitialized state, give DS=DX=-1. | ||
| 603 | |||
| 604 | Error returns: | ||
| 605 | None. | ||
| 606 | |||
| 607 | Handler entry: | ||
| 608 | All registers as user set them when INT 21H | ||
| 609 | issued (including SS:SP). INT 21 return is on | ||
| 610 | stack, so the correct method for the OEM handler | ||
| 611 | to return to the user is to give an IRET. The | ||
| 612 | OEM handler is free to make any INT 21H system | ||
| 613 | call (including the 0F9H- 0FFH group if the OEM | ||
| 614 | handler is re-entrant). | ||
| 615 | |||
| 616 | |||
| 617 | The AH INT 21H function codes 0F8H through 0FFH are | ||
| 618 | reserved for OEM extensions to the INT 21H calling | ||
| 619 | convention. These calls have two states, initialized | ||
| 620 | and uninitialized. There will be one handler for all 7 | ||
| 621 | (0F9-0FFH) functions. When the DOS is first | ||
| 622 | initialized, these calls are uninitialized. The AH=0F8H | ||
| 623 | call is the call which will set the handler address for | ||
| 624 | the 0F9-0FFH calls. If the 0F9-0FFH calls are | ||
| 625 | uninitialized, an attempt to call them results in the | ||
| 626 | normal invalid system call number return. | ||
| 627 | OEMs should NOT document the 0F8 call. | ||
| 628 | | | | ||
| 629 | | C A V E A T P R O G R A M M E R | | ||
| 630 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 631 | |||
| 632 | |||
| 633 | |||
| 634 | |||
| 635 | |||
| 636 | |||
| 637 | |||
| 638 | |||
| 639 | |||
| 640 | |||
| 641 | |||
| 642 | |||
| 643 | |||
| 644 | |||
| 645 | |||
| 646 | |||
| 647 | |||
| 648 | |||
| 649 | Section 2 | ||
| 650 | |||
| 651 | XENIX-compatible system calls | ||
| 652 | |||
| 653 | |||
| 654 | |||
| 655 | Previous to version 2.0, MSDOS had a simple single | ||
| 656 | directory structure that sufficed for small (160k to 320K) | ||
| 657 | diskettes. As the need for hard disk support grows, and | ||
| 658 | as MSDOS 2.0 will support a wide variety of hard disks, | ||
| 659 | the need for better disk organization also grows. Merely | ||
| 660 | expanding the directory is not an effective solution; | ||
| 661 | doing a 'DIR' on a directory with 1000 files is not a | ||
| 662 | user-friendly characteristic. | ||
| 663 | |||
| 664 | People, by nature, think in hierarchical terms: | ||
| 665 | organization charts and family trees, for example. It | ||
| 666 | would be nice to allow users to organize their files on | ||
| 667 | disk in a similar manner. Consider the following: | ||
| 668 | |||
| 669 | In a particular business, both sales and accounting | ||
| 670 | share a computer with a large disk and the individual | ||
| 671 | employees use it for preparation of reports and | ||
| 672 | maintaining accounting information. One would naturally | ||
| 673 | view the organization of files on the disk in this | ||
| 674 | fashion: | ||
| 675 | |||
| 676 | +-disk-+ | ||
| 677 | / \ | ||
| 678 | / \ | ||
| 679 | / \ | ||
| 680 | sales accounting | ||
| 681 | / | | \ | ||
| 682 | / | | \ | ||
| 683 | / | | \ | ||
| 684 | John Mary Steve Sue | ||
| 685 | / | (A) | | | \ | ||
| 686 | / | | | | \ | ||
| 687 | / | | | | \ | ||
| 688 | report accts. report accts. report report | ||
| 689 | receiv. receiv | ||
| 690 | |||
| 691 | In MSDOS 2.0 the user can arrange his files in such a | ||
| 692 | manner that files that are not part of his current task do | ||
| 693 | not interfere with that task. Pre-2.0 versions of MSDOS | ||
| 694 | has a single directory that contains files. MSDOS extends | ||
| 695 | this concept to allow a directory to contain both files | ||
| 696 | and directories and to introduce the notion of the | ||
| 697 | 'current' directory. | ||
| 698 | |||
| 699 | To specify a filename, the user could use one of two | ||
| 700 | methods, either specify a path from the root node to the | ||
| 701 | file, or specify a path from the current node to the file. | ||
| 702 | A path is a series of directory names separated by '/' and | ||
| 703 | ending with a filename. A path that starts at the root | ||
| 704 | begins with a '/'. | ||
| 705 | |||
| 706 | There is a special directory entry in each directory, | ||
| 707 | denoted by '..' that is the parent of the directory. The | ||
| 708 | root directory's parent is itself (who created God?). | ||
| 709 | |||
| 710 | Using a directory structure like the hierarchy above, | ||
| 711 | and assuming that the current directory is at point (D), | ||
| 712 | to reference the report under John, the following are all | ||
| 713 | equivalent: | ||
| 714 | |||
| 715 | report | ||
| 716 | /sales/John/report | ||
| 717 | ../John/report | ||
| 718 | |||
| 719 | To refer to the report under Mary, the following are | ||
| 720 | all equivalent: | ||
| 721 | |||
| 722 | ../Mary/report | ||
| 723 | /sales/Mary/report | ||
| 724 | |||
| 725 | To refer to the report under Sue, the following are | ||
| 726 | all equivalent. | ||
| 727 | |||
| 728 | ../../accounting/Sue/report | ||
| 729 | /accounting/Sue/report | ||
| 730 | |||
| 731 | There is no restriction in MSDOS 2.0 on the depth of a | ||
| 732 | tree (the length of the longest path from root to leaf) | ||
| 733 | except in the number of allocation units available. The | ||
| 734 | root directory will have a fixed number of entries, 64 for | ||
| 735 | the single sided diskettes to XXX for a large hard disk. | ||
| 736 | For non-root directories, there is no limit to the number | ||
| 737 | of files per directory excepting in the number of | ||
| 738 | allocation units available. | ||
| 739 | |||
| 740 | Old (pre-2.0) disks will appear to MSDOS 2.0 as having | ||
| 741 | only a root directory with files in it and no | ||
| 742 | subdirectories whatever. | ||
| 743 | |||
| 744 | Implementation of the tree-structure is simple. The | ||
| 745 | root directory is the pre-2.0 directory. Subdirectories | ||
| 746 | of the root have a special attribute set indicating that | ||
| 747 | they are directories. The subdirectories themselves are | ||
| 748 | files, linked through the FAT as usual. Their contents | ||
| 749 | are identical in character to the contents of the root | ||
| 750 | directory. | ||
| 751 | |||
| 752 | Pre-2.0 programs that use system calls not described | ||
| 753 | below will not be able to make use of files in other | ||
| 754 | directories. They will only be able to access files in | ||
| 755 | the current directory. This is no great loss of | ||
| 756 | functionality as users will aggregate their files into | ||
| 757 | sub-directories on basis of functionality; the files that | ||
| 758 | are being used will be found in the current directory. | ||
| 759 | Those that are not necessary for the current task will be | ||
| 760 | placed in other directories. Out of sight, out of mind. | ||
| 761 | |||
| 762 | There are also new attributes in 2.0. These and the | ||
| 763 | old attributes apply to the tree structured directories in | ||
| 764 | the following manner: | ||
| 765 | |||
| 766 | Attribute Meaning/Function Meaning/Function | ||
| 767 | for files for directories | ||
| 768 | |||
| 769 | volume_id Present at the root. Meaningless. | ||
| 770 | Only one file may have | ||
| 771 | this set. | ||
| 772 | |||
| 773 | directory Meaningless. Indicates that the | ||
| 774 | directory entry is a | ||
| 775 | directory. Cannot be | ||
| 776 | changed with ChMod. | ||
| 777 | |||
| 778 | read_only Old fcb-create, new Meaningless. | ||
| 779 | Creat, new open (for | ||
| 780 | write or read/write) | ||
| 781 | will fail. | ||
| 782 | |||
| 783 | archive Set when file is Meaningless. | ||
| 784 | written. Set/reset via | ||
| 785 | ChMod. | ||
| 786 | |||
| 787 | hidden/ Prevents file from Prevents directory | ||
| 788 | system being found in search entry from being | ||
| 789 | first/search next. found. ChDir to | ||
| 790 | New open will fail. directory will still | ||
| 791 | work. | ||
| 792 | |||
| 793 | |||
| 794 | Name: * ChDir - Change the current directory | ||
| 795 | |||
| 796 | Assembler usage: | ||
| 797 | LDS DX, name | ||
| 798 | MOV AH, ChDir | ||
| 799 | INT 21h | ||
| 800 | |||
| 801 | Description: | ||
| 802 | ChDir is given the ASCIZ name of the directory | ||
| 803 | which is to become the current directory. If any | ||
| 804 | member of the specified pathname does not exist, then | ||
| 805 | the current directory is unchanged. Otherwise, the | ||
| 806 | current directory is set to the string. | ||
| 807 | |||
| 808 | Error returns: | ||
| 809 | AX = error_path_not_found | ||
| 810 | The path specified in DS:DX either indicated a | ||
| 811 | file or the path was invalid. | ||
| 812 | |||
| 813 | |||
| 814 | Name: * ChMod - change write protection | ||
| 815 | |||
| 816 | Assembler usage: | ||
| 817 | LDS DX, name | ||
| 818 | MOV CX, attribute | ||
| 819 | MOV AL, func | ||
| 820 | MOV AH, ChMod | ||
| 821 | INT 21h | ||
| 822 | |||
| 823 | Description: | ||
| 824 | Given an ASCIZ name, ChMod will set/get the | ||
| 825 | attributes of the file to those given in CX. | ||
| 826 | |||
| 827 | A function code is passed in AL: | ||
| 828 | |||
| 829 | AL Function | ||
| 830 | -- -------- | ||
| 831 | 0 Return the attributes of the file in CX | ||
| 832 | 1 Set the attributes of the file to those in CX | ||
| 833 | |||
| 834 | Error returns: | ||
| 835 | AX = error_path_not_found | ||
| 836 | The path specified was invalid. | ||
| 837 | = error_access_denied | ||
| 838 | The attributes specified in CX contained one | ||
| 839 | that could not be changed (directory, volume | ||
| 840 | ID). | ||
| 841 | = error_invalid_function | ||
| 842 | The function passed in AL was not in the range | ||
| 843 | 0:1. | ||
| 844 | |||
| 845 | |||
| 846 | Name: * Close - close a file handle | ||
| 847 | |||
| 848 | Assembler usage: | ||
| 849 | MOV BX, handle | ||
| 850 | MOV AH, Close | ||
| 851 | INT 21h | ||
| 852 | |||
| 853 | Description: | ||
| 854 | In BX is passed a file handle (like that returned | ||
| 855 | by Open, Creat or Dup); the Close call will close the | ||
| 856 | associated file. Internal buffers are flushed. | ||
| 857 | |||
| 858 | Error return: | ||
| 859 | AX = error_invalid_handle | ||
| 860 | The handle passed in BX was not currently | ||
| 861 | open. | ||
| 862 | |||
| 863 | |||
| 864 | Name: * Creat - create a file | ||
| 865 | |||
| 866 | Assembler usage: | ||
| 867 | LDS DX, name | ||
| 868 | MOV AH, Creat | ||
| 869 | MOV CX, attribute | ||
| 870 | INT 21h | ||
| 871 | ; AX now has the handle | ||
| 872 | |||
| 873 | Description: | ||
| 874 | Creat creates a new file or truncates an old file | ||
| 875 | to zero length in preparation for writing. If the | ||
| 876 | file did not exist, then the file is created in the | ||
| 877 | appropriate directory and the file is given the | ||
| 878 | read/write protection code of access. | ||
| 879 | |||
| 880 | CX contains the default attributes to be set for | ||
| 881 | the file. Currently, the read-only bit must be off. | ||
| 882 | |||
| 883 | Error returns: | ||
| 884 | AX = error_access_denied | ||
| 885 | The attributes specified in CX contained one | ||
| 886 | that could not be created (directory, volume | ||
| 887 | ID), a file already existed with a more | ||
| 888 | inclusive set of attributes, or a directory | ||
| 889 | existed with the same name. | ||
| 890 | = error_path_not_found | ||
| 891 | The path specified was invalid. | ||
| 892 | = error_too_many_open_files | ||
| 893 | The file was created with the specified | ||
| 894 | attributes, but there were no free handles | ||
| 895 | available for the process or that the internal | ||
| 896 | system tables were full. | ||
| 897 | |||
| 898 | |||
| 899 | Name: * Dup - duplicate a file handle | ||
| 900 | |||
| 901 | Assembler usage: | ||
| 902 | MOV BX, fh | ||
| 903 | MOV AH, Dup | ||
| 904 | INT 21h | ||
| 905 | ; AX has the returned handle | ||
| 906 | |||
| 907 | Description: | ||
| 908 | Dup takes an already opened file handle and | ||
| 909 | returns a new handle that refers to the same file at | ||
| 910 | the same position. | ||
| 911 | |||
| 912 | Error returns: | ||
| 913 | AX = error_invalid_handle | ||
| 914 | The handle passed in BX was not currently | ||
| 915 | open. | ||
| 916 | = error_too_many_open_files | ||
| 917 | There were no free handles available in the | ||
| 918 | current process or the internal system tables | ||
| 919 | were full. | ||
| 920 | |||
| 921 | |||
| 922 | Name: * Dup2 - force a duplicate of a handle | ||
| 923 | |||
| 924 | Assembler usage: | ||
| 925 | MOV BX, fh | ||
| 926 | MOV CX, newfh | ||
| 927 | MOV AH, Dup2 | ||
| 928 | INT 21h | ||
| 929 | |||
| 930 | Description: | ||
| 931 | Dup2 will cause newfh to refer to the same stream | ||
| 932 | as fh. If there was an open file on newfh, then it is | ||
| 933 | closed first. | ||
| 934 | |||
| 935 | Error returns: | ||
| 936 | AX = error_invalid_handle | ||
| 937 | The handle passed in BX was not currently | ||
| 938 | open. | ||
| 939 | |||
| 940 | |||
| 941 | Name: * Exec - load / execute a program | ||
| 942 | |||
| 943 | Assembler usage: | ||
| 944 | LDS DX, name | ||
| 945 | LES BX, blk | ||
| 946 | MOV AH, Exec | ||
| 947 | MOV AL, func | ||
| 948 | INT 21h | ||
| 949 | |||
| 950 | Description: | ||
| 951 | This call allows a program to load another program | ||
| 952 | into memory and (default) begin execution of it. | ||
| 953 | DS:DX points to the ASCIZ name of the file to be | ||
| 954 | loaded. ES:BX points to a parameter block for the | ||
| 955 | load. | ||
| 956 | |||
| 957 | A function code is passed in AL: | ||
| 958 | |||
| 959 | AL Function | ||
| 960 | -- -------- | ||
| 961 | 0 Load and execute the program. A program header is | ||
| 962 | established for the program and the terminate and | ||
| 963 | ^C addresses are set to the instruction after the | ||
| 964 | EXEC system call. | ||
| 965 | |||
| 966 | NOTE: When control is returned, via a ^C or | ||
| 967 | terminate, from the program being EXECed ALL | ||
| 968 | registers are altered including the stack. | ||
| 969 | This is because control is returned from the | ||
| 970 | EXECed program, not the system. To regain | ||
| 971 | your stack, store an SS:SP value in a data | ||
| 972 | location reachable from your CS. | ||
| 973 | |||
| 974 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 975 | | C A V E A T P R O G R A M M E R | | ||
| 976 | | | | ||
| 977 | 1 Load, create the program header but do not begin | ||
| 978 | execution. The CS:IP/SS:SP of the program are | ||
| 979 | returned in the area provided by the user. | ||
| 980 | | | | ||
| 981 | | C A V E A T P R O G R A M M E R | | ||
| 982 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 983 | |||
| 984 | 3 Load, do not create the program header, and do not | ||
| 985 | begin execution. This is useful in loading | ||
| 986 | program overlays. | ||
| 987 | |||
| 988 | For each value of AL, the block has the following | ||
| 989 | format: | ||
| 990 | |||
| 991 | AL = 0 -> load/execute program | ||
| 992 | |||
| 993 | +---------------------------+ | ||
| 994 | | WORD segment address of | | ||
| 995 | | environment. | | ||
| 996 | +---------------------------+ | ||
| 997 | | DWORD pointer to command | | ||
| 998 | | line at 80h | | ||
| 999 | +---------------------------+ | ||
| 1000 | | DWORD pointer to default | | ||
| 1001 | | FCB to be passed at 5Ch | | ||
| 1002 | +---------------------------+ | ||
| 1003 | | DWORD pointer to default | | ||
| 1004 | | FCB to be passed at 6Ch | | ||
| 1005 | +---------------------------+ | ||
| 1006 | |||
| 1007 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1008 | | C A V E A T P R O G R A M M E R | | ||
| 1009 | | | | ||
| 1010 | AL = 1 -> load program | ||
| 1011 | |||
| 1012 | +---------------------------+ | ||
| 1013 | | WORD segment address of | | ||
| 1014 | | environment. | | ||
| 1015 | +---------------------------+ | ||
| 1016 | | DWORD pointer to command | | ||
| 1017 | | line at 80h | | ||
| 1018 | +---------------------------+ | ||
| 1019 | | DWORD pointer to default | | ||
| 1020 | | FCB to be passed at 5Ch | | ||
| 1021 | +---------------------------+ | ||
| 1022 | | DWORD pointer to default | | ||
| 1023 | | FCB to be passed at 6Ch | | ||
| 1024 | +---------------------------+ | ||
| 1025 | | DWORD returned value of | | ||
| 1026 | | SS:SP | | ||
| 1027 | +---------------------------+ | ||
| 1028 | | DWORD returned value of | | ||
| 1029 | | CS:IP | | ||
| 1030 | +---------------------------+ | ||
| 1031 | | | | ||
| 1032 | | C A V E A T P R O G R A M M E R | | ||
| 1033 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1034 | |||
| 1035 | AL = 3 -> load overlay | ||
| 1036 | |||
| 1037 | +---------------------------+ | ||
| 1038 | | WORD segment address where| | ||
| 1039 | | file will be loaded. | | ||
| 1040 | +---------------------------+ | ||
| 1041 | | WORD relocation factor to | | ||
| 1042 | | be applied to the image. | | ||
| 1043 | +---------------------------+ | ||
| 1044 | |||
| 1045 | Note that all open files of a process are | ||
| 1046 | duplicated in the child process after an Exec. This | ||
| 1047 | is extremely powerful; the parent process has control | ||
| 1048 | over the meanings of stdin, stdout, stderr, stdaux and | ||
| 1049 | stdprn. The parent could, for example, write a series | ||
| 1050 | of records to a file, open the file as standard input, | ||
| 1051 | open a listing file as standard output and then Exec a | ||
| 1052 | sort program that takes its input from stdin and | ||
| 1053 | writes to stdout. | ||
| 1054 | |||
| 1055 | Also inherited (or passed from the parent) is an | ||
| 1056 | 'environment'. This is a block of text strings (less | ||
| 1057 | than 32K bytes total) that convey various | ||
| 1058 | configurations parameters. The format of the | ||
| 1059 | environment is as follows: | ||
| 1060 | |||
| 1061 | (paragraph boundary) | ||
| 1062 | +---------------------------+ | ||
| 1063 | | BYTE asciz string 1 | | ||
| 1064 | +---------------------------+ | ||
| 1065 | | BYTE asciz string 2 | | ||
| 1066 | +---------------------------+ | ||
| 1067 | | ... | | ||
| 1068 | +---------------------------+ | ||
| 1069 | | BYTE asciz string n | | ||
| 1070 | +---------------------------+ | ||
| 1071 | | BYTE of zero | | ||
| 1072 | +---------------------------+ | ||
| 1073 | |||
| 1074 | Typically the environment strings have the form: | ||
| 1075 | |||
| 1076 | parameter=value | ||
| 1077 | |||
| 1078 | for example, COMMAND.COM always passes its execution | ||
| 1079 | search path as: | ||
| 1080 | |||
| 1081 | PATH=A:/BIN;B:/BASIC/LIB | ||
| 1082 | |||
| 1083 | A zero value of the environment address will cause the | ||
| 1084 | child process to inherit the parent's environment | ||
| 1085 | unchanged. | ||
| 1086 | |||
| 1087 | Note that on a successful return from EXEC, all | ||
| 1088 | registers, except for CS:IP, are changed. | ||
| 1089 | |||
| 1090 | Error return: | ||
| 1091 | AX = error_invalid_function | ||
| 1092 | The function passed in AL was not 0, 1 or 3. | ||
| 1093 | = error_bad_environment | ||
| 1094 | The environment was larger than 32Kb. | ||
| 1095 | = error_bad_format | ||
| 1096 | The file pointed to by DS:DX was an EXE format | ||
| 1097 | file and contained information that was | ||
| 1098 | internally inconsistent. | ||
| 1099 | = error_not_enough_memory | ||
| 1100 | There was not enough memory for the process to | ||
| 1101 | be created. | ||
| 1102 | = error_file_not_found | ||
| 1103 | The path specified was invalid or not found. | ||
| 1104 | |||
| 1105 | |||
| 1106 | Name: * Exit - terminate a process | ||
| 1107 | |||
| 1108 | Assembler usage: | ||
| 1109 | MOV AL, code | ||
| 1110 | MOV AH, Exit | ||
| 1111 | INT 21h | ||
| 1112 | |||
| 1113 | Description: | ||
| 1114 | Exit will terminate the current process, | ||
| 1115 | transferring control to the invoking process. In | ||
| 1116 | addition, a return code may be sent. All files open | ||
| 1117 | at the time are closed. | ||
| 1118 | |||
| 1119 | Error returns: | ||
| 1120 | None. | ||
| 1121 | |||
| 1122 | |||
| 1123 | Name: * Ioctl - I/O control for devices | ||
| 1124 | |||
| 1125 | Assembler usage: | ||
| 1126 | MOV BX, Handle | ||
| 1127 | |||
| 1128 | (or MOV BL, drive for calls AL=4,5 | ||
| 1129 | 0=default,A=1...) | ||
| 1130 | |||
| 1131 | MOV DX, Data | ||
| 1132 | |||
| 1133 | (or LDS DX, buf and | ||
| 1134 | MOV CX, count for calls AL=2,3,4,5) | ||
| 1135 | |||
| 1136 | MOV AH, Ioctl | ||
| 1137 | MOV AL, func | ||
| 1138 | INT 21h | ||
| 1139 | ; For calls AL=2,3,4,5 AX is the number of bytes | ||
| 1140 | ; transferred (same as READ and WRITE). | ||
| 1141 | ; For calls AL=6,7 AL is status returned, AL=0 if | ||
| 1142 | ; status is not ready, AL=0FFH otherwise. | ||
| 1143 | |||
| 1144 | Description: | ||
| 1145 | Set or Get device information associated with open | ||
| 1146 | Handle, or send/receive control string to device | ||
| 1147 | Handle or device. | ||
| 1148 | |||
| 1149 | The following values are allowed for func: | ||
| 1150 | |||
| 1151 | Request Function | ||
| 1152 | ------ -------- | ||
| 1153 | 0 Get device information (returned in DX) | ||
| 1154 | 1 Set device information (as determined by DX) | ||
| 1155 | 2 Read CX number of bytes into DS:DX from device | ||
| 1156 | control channel. | ||
| 1157 | 3 Write CX number of bytes from DS:DX to device | ||
| 1158 | control channel. | ||
| 1159 | 4 Same as 2 only drive number in BL | ||
| 1160 | 0=default,A=1,B=2,... | ||
| 1161 | 5 Same as 3 only drive number in BL | ||
| 1162 | 0=default,A=1,B=2,... | ||
| 1163 | 6 Get input status | ||
| 1164 | 7 Get output status | ||
| 1165 | |||
| 1166 | Ioctl can be used to get information about device | ||
| 1167 | channels. It is ok to make Ioctl calls on regular | ||
| 1168 | files but only calls 0,6 and 7 are defined in that | ||
| 1169 | case (AL=0,6,7), all other calls return an | ||
| 1170 | error_invalid_function error. | ||
| 1171 | |||
| 1172 | CALLS AL=0 and AL=1 | ||
| 1173 | |||
| 1174 | The bits of DX are defined as follows for calls | ||
| 1175 | AL=0 and AL=1. Note that the upper byte MUST be zero | ||
| 1176 | on a set call. | ||
| 1177 | |||
| 1178 | | | ||
| 1179 | 15 14 13 12 11 10 9 8|7 6 5 4 3 2 1 0 | ||
| 1180 | +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+ | ||
| 1181 | | R| C| |I|E|R|S|I|I|I|I| | ||
| 1182 | | e| T| |S|O|A|P|S|S|S|S| | ||
| 1183 | | s| R| Reserved |D|F|W|E|C|N|C|C| | ||
| 1184 | | | L| |E| | |C|L|U|O|I| | ||
| 1185 | | | | |V| | |L|K|L|T|N| | ||
| 1186 | +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+ | ||
| 1187 | | | ||
| 1188 | |||
| 1189 | ISDEV = 1 if this channel is a device | ||
| 1190 | = 0 if this channel is a disk file (Bits 8-15 = | ||
| 1191 | 0 in this case) | ||
| 1192 | |||
| 1193 | If ISDEV = 1 | ||
| 1194 | |||
| 1195 | EOF = 0 if End Of File on input | ||
| 1196 | RAW = 1 if this device is in Raw mode | ||
| 1197 | = 0 if this device is cooked | ||
| 1198 | ISCLK = 1 if this device is the clock device | ||
| 1199 | ISNUL = 1 if this device is the null device | ||
| 1200 | ISCOT = 1 if this device is the console output | ||
| 1201 | ISCIN = 1 if this device is the console input | ||
| 1202 | SPECL = 1 if this device is special | ||
| 1203 | |||
| 1204 | CTRL = 0 if this device can NOT do control strings | ||
| 1205 | via calls AL=2 and AL=3. | ||
| 1206 | CTRL = 1 if this device can process control | ||
| 1207 | strings via calls AL=2 and AL=3. | ||
| 1208 | NOTE that this bit cannot be set. | ||
| 1209 | |||
| 1210 | If ISDEV = 0 | ||
| 1211 | EOF = 0 if channel has been written | ||
| 1212 | Bits 0-5 are the block device number for the | ||
| 1213 | channel (0 = A, 1 = B, ...) | ||
| 1214 | |||
| 1215 | Bits 15,8-13,4 are reserved and should not be altered. | ||
| 1216 | |||
| 1217 | Calls 2..5: | ||
| 1218 | These four calls allow arbitrary control strings to be | ||
| 1219 | sent or received from a device. The Call syntax is | ||
| 1220 | the same as the READ and WRITE calls, except for 4 and | ||
| 1221 | 5 which take a drive number in BL instead of a handle | ||
| 1222 | in BX. | ||
| 1223 | |||
| 1224 | An error_invalid_function error is returned if the | ||
| 1225 | CTRL bit (see above) is 0. | ||
| 1226 | |||
| 1227 | An error_access_denied is returned by calls AL=4,5 if | ||
| 1228 | the drive number is invalid. | ||
| 1229 | |||
| 1230 | Calls 6,7: | ||
| 1231 | These two calls allow the user to check if a file | ||
| 1232 | handle is ready for input or output. Status of | ||
| 1233 | handles open to a device is the intended use of these | ||
| 1234 | calls, but status of a handle open to a disk file is | ||
| 1235 | OK and is defined as follows: | ||
| 1236 | |||
| 1237 | Input: | ||
| 1238 | Always ready (AL=FF) until EOF reached, then | ||
| 1239 | always not ready (AL=0) unless current | ||
| 1240 | position changed via LSEEK. | ||
| 1241 | Output: | ||
| 1242 | Always ready (even if disk full). | ||
| 1243 | |||
| 1244 | IMPORTANT NOTE: | ||
| 1245 | The status is defined at the time the system is | ||
| 1246 | CALLED. On future versions, by the time control is | ||
| 1247 | returned to the user from the system, the status | ||
| 1248 | returned may NOT correctly reflect the true current | ||
| 1249 | state of the device or file. | ||
| 1250 | |||
| 1251 | Error returns: | ||
| 1252 | AX = error_invalid_handle | ||
| 1253 | The handle passed in BX was not currently | ||
| 1254 | open. | ||
| 1255 | = error_invalid_function | ||
| 1256 | The function passed in AL was not in the range | ||
| 1257 | 0:7. | ||
| 1258 | = error_invalid_data | ||
| 1259 | = error_access_denied (calls AL=4..7) | ||
| 1260 | |||
| 1261 | |||
| 1262 | Name: * LSeek - move file read/write pointer | ||
| 1263 | |||
| 1264 | Assembler usage: | ||
| 1265 | MOV DX, offsetlow | ||
| 1266 | MOV CX, offsethigh | ||
| 1267 | MOV AL, method | ||
| 1268 | MOV BX, handle | ||
| 1269 | MOV AH, LSeek | ||
| 1270 | INT 21h | ||
| 1271 | ; DX:AX has the new location of the pointer | ||
| 1272 | |||
| 1273 | Description: | ||
| 1274 | LSeek moves the read/write pointer according to | ||
| 1275 | method: | ||
| 1276 | |||
| 1277 | Method Function | ||
| 1278 | ------ -------- | ||
| 1279 | 0 The pointer is moved to offset bytes from the | ||
| 1280 | beginning of the file. | ||
| 1281 | 1 The pointer is moved to the current location | ||
| 1282 | plus offset. | ||
| 1283 | 2 The pointer is moved to the end of file plus | ||
| 1284 | offset. | ||
| 1285 | |||
| 1286 | Offset should be regarded as a 32-bit integer with | ||
| 1287 | CX occupying the most significant 16 bits. | ||
| 1288 | |||
| 1289 | Error returns: | ||
| 1290 | AX = error_invalid_handle | ||
| 1291 | The handle passed in BX was not currently | ||
| 1292 | open. | ||
| 1293 | = error_invalid_function | ||
| 1294 | The function passed in AL was not in the range | ||
| 1295 | 0:2. | ||
| 1296 | |||
| 1297 | |||
| 1298 | Name: * MkDir - Create a directory entry | ||
| 1299 | |||
| 1300 | Assembler usage: | ||
| 1301 | LDS DX, name | ||
| 1302 | MOV AH, MkDir | ||
| 1303 | INT 21h | ||
| 1304 | |||
| 1305 | Description: | ||
| 1306 | Given a pointer to an ASCIZ name, create a new | ||
| 1307 | directory entry at the end. | ||
| 1308 | |||
| 1309 | Error returns: | ||
| 1310 | AX = error_path_not_found | ||
| 1311 | The path specified was invalid or not found. | ||
| 1312 | = error_access_denied | ||
| 1313 | The directory could not be created (no room in | ||
| 1314 | parent directory), the directory/file already | ||
| 1315 | existed or a device name was specified. | ||
| 1316 | |||
| 1317 | |||
| 1318 | Name: * Open - access a file | ||
| 1319 | |||
| 1320 | Assembler usage: | ||
| 1321 | LDS DX, name | ||
| 1322 | MOV AH, Open | ||
| 1323 | MOV AL, access | ||
| 1324 | INT 21h | ||
| 1325 | ; AX has error or file handle | ||
| 1326 | ; If successful open | ||
| 1327 | |||
| 1328 | Description: | ||
| 1329 | Open associates a 16-bit file handle with a file. | ||
| 1330 | |||
| 1331 | The following values are allowed for access: | ||
| 1332 | |||
| 1333 | ACCESS Function | ||
| 1334 | ------ -------- | ||
| 1335 | 0 file is opened for reading | ||
| 1336 | 1 file is opened for writing | ||
| 1337 | 2 file is opened for both reading and writing. | ||
| 1338 | |||
| 1339 | DS:DX point to an ASCIZ name of the file to be | ||
| 1340 | opened. | ||
| 1341 | |||
| 1342 | The read/write pointer is set at the first byte of | ||
| 1343 | the file and the record size of the file is 1 byte. | ||
| 1344 | The returned file handle must be used for subsequent | ||
| 1345 | I/O to the file. | ||
| 1346 | |||
| 1347 | The DOS, on initialization, will have a maximum | ||
| 1348 | number of files. See the configuration file document | ||
| 1349 | for information on changing this default. | ||
| 1350 | |||
| 1351 | Error returns: | ||
| 1352 | AX = error_invalid_access | ||
| 1353 | The access specified in AL was not in the | ||
| 1354 | range 0:2. | ||
| 1355 | = error_file_not_found | ||
| 1356 | The path specified was invalid or not found. | ||
| 1357 | = error_access_denied | ||
| 1358 | The user attempted to open a directory or | ||
| 1359 | volume-id, or open a read-only file for | ||
| 1360 | writing. | ||
| 1361 | = error_too_many_open_files | ||
| 1362 | There were no free handles available in the | ||
| 1363 | current process or the internal system tables | ||
| 1364 | were full. | ||
| 1365 | |||
| 1366 | |||
| 1367 | Name: * Read - Do file/device I/O | ||
| 1368 | |||
| 1369 | Assembler usage: | ||
| 1370 | LDS DX, buf | ||
| 1371 | MOV CX, count | ||
| 1372 | MOV BX, handle | ||
| 1373 | MOV AH, Read | ||
| 1374 | INT 21h | ||
| 1375 | ; AX has number of bytes read | ||
| 1376 | |||
| 1377 | Description: | ||
| 1378 | Read transfers count bytes from a file into a | ||
| 1379 | buffer location. It is not guaranteed that all count | ||
| 1380 | bytes will be read; for example, reading from the | ||
| 1381 | keyboard will read at most one line of text. If the | ||
| 1382 | returned value is zero, then the program has tried to | ||
| 1383 | read from the end of file. | ||
| 1384 | |||
| 1385 | All I/O is done using normalized pointers; no | ||
| 1386 | segment wraparound will occur. | ||
| 1387 | |||
| 1388 | Error returns: | ||
| 1389 | AX = error_invalid_handle | ||
| 1390 | The handle passed in BX was not currently | ||
| 1391 | open. | ||
| 1392 | = error_access_denied | ||
| 1393 | The handle passed in BX was opened in a mode | ||
| 1394 | that did not allow reading. | ||
| 1395 | |||
| 1396 | |||
| 1397 | Name: * RmDir - Remove a directory entry | ||
| 1398 | |||
| 1399 | Assembler usage: | ||
| 1400 | LDS DX, name | ||
| 1401 | MOV AH, RmDir | ||
| 1402 | INT 21h | ||
| 1403 | |||
| 1404 | Description: | ||
| 1405 | RmDir is given an asciz name of a directory. That | ||
| 1406 | directory is removed from its parent | ||
| 1407 | |||
| 1408 | Error returns: | ||
| 1409 | AX = error_path_not_found | ||
| 1410 | The path specified was invalid or not found. | ||
| 1411 | = error_access_denied | ||
| 1412 | The path specified was not empty, not a | ||
| 1413 | directory, the root directory or contained | ||
| 1414 | invalid information. | ||
| 1415 | = error_current_directory | ||
| 1416 | The path specified was the current directory | ||
| 1417 | on a drive. | ||
| 1418 | |||
| 1419 | |||
| 1420 | Name: * Unlink - delete a directory entry | ||
| 1421 | |||
| 1422 | Assembler usage: | ||
| 1423 | LDS DX, name | ||
| 1424 | MOV AH, Unlink | ||
| 1425 | INT 21h | ||
| 1426 | |||
| 1427 | Description: | ||
| 1428 | Unlink removes a directory entry associated with a | ||
| 1429 | filename. If the file is currently open on another | ||
| 1430 | handle, then no removal will take place. | ||
| 1431 | |||
| 1432 | Error returns: | ||
| 1433 | AX = error_file_not_found | ||
| 1434 | The path specified was invalid or not found. | ||
| 1435 | = error_access_denied | ||
| 1436 | The path specified was a directory or | ||
| 1437 | read-only. | ||
| 1438 | |||
| 1439 | |||
| 1440 | Name: * Wait - retrieve the return code of a child | ||
| 1441 | |||
| 1442 | Assembler usage: | ||
| 1443 | MOV AH, Wait | ||
| 1444 | INT 21h | ||
| 1445 | ; AX has the exit code | ||
| 1446 | |||
| 1447 | Description: | ||
| 1448 | Wait will return the Exit code specified by a | ||
| 1449 | child process. It will return this Exit code only | ||
| 1450 | once. The low byte of this code is that sent by the | ||
| 1451 | Exit routine. The high byte is one of the following: | ||
| 1452 | |||
| 1453 | 0 - terminate/abort | ||
| 1454 | 1 - ^C | ||
| 1455 | 2 - Hard error | ||
| 1456 | 3 - Terminate and stay resident | ||
| 1457 | |||
| 1458 | Error returns: | ||
| 1459 | None. | ||
| 1460 | |||
| 1461 | |||
| 1462 | Name: * Write - write to a file | ||
| 1463 | |||
| 1464 | Assembler usage: | ||
| 1465 | LDS DX, buf | ||
| 1466 | MOV CX, count | ||
| 1467 | MOV BX, handle | ||
| 1468 | MOV AH, Write | ||
| 1469 | INT 21h | ||
| 1470 | ; AX has number of bytes written | ||
| 1471 | |||
| 1472 | Description: | ||
| 1473 | Write transfers count bytes from a buffer into | ||
| 1474 | a file. It should be regarded as an error if the | ||
| 1475 | number of bytes written is not the same as the number | ||
| 1476 | requested. | ||
| 1477 | |||
| 1478 | It is important to note that the write system | ||
| 1479 | call with a count of zero (CX = 0) will truncate | ||
| 1480 | the file at the current position. | ||
| 1481 | |||
| 1482 | All I/O is done using normalized pointers; no | ||
| 1483 | segment wraparound will occur. | ||
| 1484 | |||
| 1485 | Error Returns: | ||
| 1486 | AX = error_invalid_handle | ||
| 1487 | The handle passed in BX was not currently | ||
| 1488 | open. | ||
| 1489 | = error_access_denied | ||
| 1490 | The handle was not opened in a mode that | ||
| 1491 | allowed writing. | ||
| 1492 | |||
| 1493 | |||
| 1494 | The following XENIX convention is followed for the new 2.0 | ||
| 1495 | system calls: | ||
| 1496 | |||
| 1497 | o If no error occurred, then the carry flag will be | ||
| 1498 | reset and register AX will contain the appropriate | ||
| 1499 | information. | ||
| 1500 | |||
| 1501 | o If an error occurred, then the carry flag will be | ||
| 1502 | set and register AX will contain the error code. | ||
| 1503 | |||
| 1504 | The following code sample illustrates the recommended method | ||
| 1505 | of detecting these errors: | ||
| 1506 | |||
| 1507 | ... | ||
| 1508 | MOV errno,0 | ||
| 1509 | INT 21h | ||
| 1510 | JNC continue | ||
| 1511 | MOV errno,AX | ||
| 1512 | continue: | ||
| 1513 | ... | ||
| 1514 | |||
| 1515 | The word variable errno will now have the correct error code | ||
| 1516 | for that system call. | ||
| 1517 | |||
| 1518 | The current equates for the error codes are: | ||
| 1519 | |||
| 1520 | no_error_occurred EQU 0 | ||
| 1521 | |||
| 1522 | error_invalid_function EQU 1 | ||
| 1523 | error_file_not_found EQU 2 | ||
| 1524 | error_path_not_found EQU 3 | ||
| 1525 | error_too_many_open_files EQU 4 | ||
| 1526 | error_access_denied EQU 5 | ||
| 1527 | error_invalid_handle EQU 6 | ||
| 1528 | error_arena_trashed EQU 7 | ||
| 1529 | error_not_enough_memory EQU 8 | ||
| 1530 | error_invalid_block EQU 9 | ||
| 1531 | error_bad_environment EQU 10 | ||
| 1532 | error_bad_format EQU 11 | ||
| 1533 | error_invalid_access EQU 12 | ||
| 1534 | error_invalid_data EQU 13 | ||
| 1535 | error_invalid_drive EQU 15 | ||
| 1536 | error_current_directory EQU 16 | ||
| 1537 | error_not_same_device EQU 17 | ||
| 1538 | error_no_more_files EQU 18 | ||
| 1539 | |||
| 1540 | |||
| 1541 | System call assignments: | ||
| 1542 | |||
| 1543 | ABORT EQU 0 ; 0 0 | ||
| 1544 | STD_CON_INPUT EQU 1 ; 1 1 | ||
| 1545 | STD_CON_OUTPUT EQU 2 ; 2 2 | ||
| 1546 | STD_AUX_INPUT EQU 3 ; 3 3 | ||
| 1547 | STD_AUX_OUTPUT EQU 4 ; 4 4 | ||
| 1548 | STD_PRINTER_OUTPUT EQU 5 ; 5 5 | ||
| 1549 | RAW_CON_IO EQU 6 ; 6 6 | ||
| 1550 | RAW_CON_INPUT EQU 7 ; 7 7 | ||
| 1551 | STD_CON_INPUT_NO_ECHO EQU 8 ; 8 8 | ||
| 1552 | STD_CON_STRING_OUTPUT EQU 9 ; 9 9 | ||
| 1553 | STD_CON_STRING_INPUT EQU 10 ; 10 A | ||
| 1554 | STD_CON_INPUT_STATUS EQU 11 ; 11 B | ||
| 1555 | STD_CON_INPUT_FLUSH EQU 12 ; 12 C | ||
| 1556 | DISK_RESET EQU 13 ; 13 D | ||
| 1557 | SET_DEFAULT_DRIVE EQU 14 ; 14 E | ||
| 1558 | FCB_OPEN EQU 15 ; 15 F | ||
| 1559 | FCB_CLOSE EQU 16 ; 16 10 | ||
| 1560 | DIR_SEARCH_FIRST EQU 17 ; 17 11 | ||
| 1561 | DIR_SEARCH_NEXT EQU 18 ; 18 12 | ||
| 1562 | FCB_DELETE EQU 19 ; 19 13 | ||
| 1563 | FCB_SEQ_READ EQU 20 ; 20 14 | ||
| 1564 | FCB_SEQ_WRITE EQU 21 ; 21 15 | ||
| 1565 | FCB_CREATE EQU 22 ; 22 16 | ||
| 1566 | FCB_RENAME EQU 23 ; 23 17 | ||
| 1567 | GET_DEFAULT_DRIVE EQU 25 ; 25 19 | ||
| 1568 | SET_DMA EQU 26 ; 26 1A | ||
| 1569 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1570 | | C A V E A T P R O G R A M M E R | | ||
| 1571 | | | | ||
| 1572 | GET_DEFAULT_DPB EQU 31 ; 31 1F | ||
| 1573 | | | | ||
| 1574 | | C A V E A T P R O G R A M M E R | | ||
| 1575 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1576 | FCB_RANDOM_READ EQU 33 ; 33 21 | ||
| 1577 | FCB_RANDOM_WRITE EQU 34 ; 34 22 | ||
| 1578 | GET_FCB_FILE_LENGTH EQU 35 ; 35 23 | ||
| 1579 | GET_FCB_POSITION EQU 36 ; 36 24 | ||
| 1580 | SET_INTERRUPT_VECTOR EQU 37 ; 37 25 | ||
| 1581 | CREATE_PROCESS_DATA_BLOCK EQU 38 ; 38 26 | ||
| 1582 | FCB_RANDOM_READ_BLOCK EQU 39 ; 39 27 | ||
| 1583 | FCB_RANDOM_WRITE_BLOCK EQU 40 ; 40 28 | ||
| 1584 | PARSE_FILE_DESCRIPTOR EQU 41 ; 41 29 | ||
| 1585 | GET_DATE EQU 42 ; 42 2A | ||
| 1586 | SET_DATE EQU 43 ; 43 2B | ||
| 1587 | GET_TIME EQU 44 ; 44 2C | ||
| 1588 | SET_TIME EQU 45 ; 45 2D | ||
| 1589 | SET_VERIFY_ON_WRITE EQU 46 ; 46 2E | ||
| 1590 | ; Extended functionality group | ||
| 1591 | GET_DMA EQU 47 ; 47 2F | ||
| 1592 | GET_VERSION EQU 48 ; 48 30 | ||
| 1593 | KEEP_PROCESS EQU 49 ; 49 31 | ||
| 1594 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1595 | | C A V E A T P R O G R A M M E R | | ||
| 1596 | | | | ||
| 1597 | GET_DPB EQU 50 ; 50 32 | ||
| 1598 | | | | ||
| 1599 | | C A V E A T P R O G R A M M E R | | ||
| 1600 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1601 | SET_CTRL_C_TRAPPING EQU 51 ; 51 33 | ||
| 1602 | GET_INDOS_FLAG EQU 52 ; 52 34 | ||
| 1603 | GET_INTERRUPT_VECTOR EQU 53 ; 53 35 | ||
| 1604 | GET_DRIVE_FREESPACE EQU 54 ; 54 36 | ||
| 1605 | CHAR_OPER EQU 55 ; 55 37 | ||
| 1606 | INTERNATIONAL EQU 56 ; 56 38 | ||
| 1607 | ; XENIX CALLS | ||
| 1608 | ; Directory Group | ||
| 1609 | MKDIR EQU 57 ; 57 39 | ||
| 1610 | RMDIR EQU 58 ; 58 3A | ||
| 1611 | CHDIR EQU 59 ; 59 3B | ||
| 1612 | ; File Group | ||
| 1613 | CREAT EQU 60 ; 60 3C | ||
| 1614 | OPEN EQU 61 ; 61 3D | ||
| 1615 | CLOSE EQU 62 ; 62 3E | ||
| 1616 | READ EQU 63 ; 63 3F | ||
| 1617 | WRITE EQU 64 ; 64 40 | ||
| 1618 | UNLINK EQU 65 ; 65 41 | ||
| 1619 | LSEEK EQU 66 ; 66 42 | ||
| 1620 | CHMOD EQU 67 ; 67 43 | ||
| 1621 | IOCTL EQU 68 ; 68 44 | ||
| 1622 | XDUP EQU 69 ; 69 45 | ||
| 1623 | XDUP2 EQU 70 ; 70 46 | ||
| 1624 | CURRENT_DIR EQU 71 ; 71 47 | ||
| 1625 | ; Memory Group | ||
| 1626 | ALLOC EQU 72 ; 72 48 | ||
| 1627 | DEALLOC EQU 73 ; 73 49 | ||
| 1628 | SETBLOCK EQU 74 ; 74 4A | ||
| 1629 | ; Process Group | ||
| 1630 | EXEC EQU 75 ; 75 4B | ||
| 1631 | EXIT EQU 76 ; 76 4C | ||
| 1632 | WAIT EQU 77 ; 77 4D | ||
| 1633 | FIND_FIRST EQU 78 ; 78 4E | ||
| 1634 | ; Special Group | ||
| 1635 | FIND_NEXT EQU 79 ; 79 4F | ||
| 1636 | ; SPECIAL SYSTEM GROUP | ||
| 1637 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1638 | | C A V E A T P R O G R A M M E R | | ||
| 1639 | | | | ||
| 1640 | SET_CURRENT_PDB EQU 80 ; 80 50 | ||
| 1641 | GET_CURRENT_PDB EQU 81 ; 81 51 | ||
| 1642 | GET_IN_VARS EQU 82 ; 82 52 | ||
| 1643 | SETDPB EQU 83 ; 83 53 | ||
| 1644 | | | | ||
| 1645 | | C A V E A T P R O G R A M M E R | | ||
| 1646 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1647 | GET_VERIFY_ON_WRITE EQU 84 ; 84 54 | ||
| 1648 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1649 | | C A V E A T P R O G R A M M E R | | ||
| 1650 | | | | ||
| 1651 | DUP_PDB EQU 85 ; 85 55 | ||
| 1652 | | | | ||
| 1653 | | C A V E A T P R O G R A M M E R | | ||
| 1654 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | ||
| 1655 | RENAME EQU 86 ; 86 56 | ||
| 1656 | FILE_TIMES EQU 87 ; 87 57 | ||
| 1657 | |||
diff --git a/v2.0/bin/SYSIMES.OBJ b/v2.0/bin/SYSIMES.OBJ new file mode 100644 index 0000000..3172652 --- /dev/null +++ b/v2.0/bin/SYSIMES.OBJ | |||
| Binary files differ | |||
diff --git a/v2.0/bin/SYSINIT.DOC b/v2.0/bin/SYSINIT.DOC new file mode 100644 index 0000000..fa20d08 --- /dev/null +++ b/v2.0/bin/SYSINIT.DOC | |||
| Binary files differ | |||
diff --git a/v2.0/bin/SYSINIT.OBJ b/v2.0/bin/SYSINIT.OBJ new file mode 100644 index 0000000..3dc2c13 --- /dev/null +++ b/v2.0/bin/SYSINIT.OBJ | |||
| Binary files differ | |||
diff --git a/v2.0/bin/UTILITY.DOC b/v2.0/bin/UTILITY.DOC new file mode 100644 index 0000000..a63793c --- /dev/null +++ b/v2.0/bin/UTILITY.DOC | |||
| @@ -0,0 +1,813 @@ | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 | |||
| 9 | |||
| 10 | |||
| 11 | |||
| 12 | |||
| 13 | |||
| 14 | |||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | MS-DOS 2.0 | ||
| 20 | |||
| 21 | Utility Extensions | ||
| 22 | |||
| 23 | |||
| 24 | |||
| 25 | |||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | |||
| 30 | The following notation is used below: | ||
| 31 | |||
| 32 | [item] item is optional. | ||
| 33 | item* item is repeated 0 or more times. | ||
| 34 | item+ item is repeated 1 or more times. | ||
| 35 | {item1 | item2} | ||
| 36 | item1 is present or item 2 is present but | ||
| 37 | not both. | ||
| 38 | <object> indicates a syntactic variable. | ||
| 39 | |||
| 40 | |||
| 41 | COMMAND invokation | ||
| 42 | |||
| 43 | COMMAND [[<drive>:]<path>] [<cttydev>] [-D] [-P] [-C <string>] | ||
| 44 | |||
| 45 | -P If present COMMAND will be permanent, otherwise | ||
| 46 | this is a transient command. | ||
| 47 | |||
| 48 | -D If present COMMAND will not prompt for DATE and | ||
| 49 | TIME when it comes up. | ||
| 50 | |||
| 51 | d: Specifies device where command will look for | ||
| 52 | COMMAND.COM current default drive if absent. | ||
| 53 | |||
| 54 | <Path> Specifies a directory on device d: root | ||
| 55 | directory if absent. | ||
| 56 | |||
| 57 | <cttydev> Name of the CTTY device. /DEV/CON if absent | ||
| 58 | and command is permanent. The /DEV/ may be left | ||
| 59 | off if AVAILDEV is TRUE (see sysinit doc). | ||
| 60 | |||
| 61 | -C <string> If present -C must be the last switch. | ||
| 62 | This causes COMMAND to try to execute the string | ||
| 63 | as if the user had typed it at the standard input. | ||
| 64 | COMMAND executes this single command string and | ||
| 65 | then exits. If the -P switch is present it is | ||
| 66 | ignored (can't have a single command, permanent | ||
| 67 | COMMAND). NOTE: ALL of the text on the command | ||
| 68 | line after the -C is just passed on. It is not | ||
| 69 | processed for more arguments, this is why -C must | ||
| 70 | be last. | ||
| 71 | |||
| 72 | COMMAND extensions | ||
| 73 | |||
| 74 | IF <condition> <command> | ||
| 75 | |||
| 76 | where <condition> is one of the following: | ||
| 77 | |||
| 78 | ERRORLEVEL <number> | ||
| 79 | true if and only if the previous program EXECed by | ||
| 80 | COMMAND had an exit code of <number> or higher. | ||
| 81 | |||
| 82 | <string1> == <string2> | ||
| 83 | true if and only if <string1> and <string2> are | ||
| 84 | identical after parameter substitution. Strings | ||
| 85 | may not have embedded delimiters. | ||
| 86 | |||
| 87 | EXIST <filename> | ||
| 88 | true if and only if <filename> exists. | ||
| 89 | |||
| 90 | NOT <condition> | ||
| 91 | true if and only if <condition> is false. | ||
| 92 | |||
| 93 | The IF statement allows conditional execution of commands. | ||
| 94 | When the <condition> is true, then the <command> is | ||
| 95 | executed otherwise, the <command> is skipped. | ||
| 96 | |||
| 97 | Examples: | ||
| 98 | |||
| 99 | IF not exist /tmp/foo ECHO Can't find file /tmp/foo | ||
| 100 | |||
| 101 | IF $1x == x ECHO Need at least one parameter | ||
| 102 | |||
| 103 | IF NOT ERRORLEVEL 3 LINK $1,,; | ||
| 104 | |||
| 105 | |||
| 106 | FOR %%<c> IN <set> DO <command> | ||
| 107 | |||
| 108 | <c> can be any character but 0,1,2,3,..,9 (so there is no | ||
| 109 | confusion with the %0 - %9 batch parameters). | ||
| 110 | |||
| 111 | <set> is ( <item>* ) | ||
| 112 | |||
| 113 | The %%<c> variable is sequentially set to each member of | ||
| 114 | <set> and then <command> is evaluated. If a member of | ||
| 115 | <set> is an expression involving * and/or ?, then the | ||
| 116 | variable is set to each matching pattern from disk. In | ||
| 117 | this case only one such <item> may be in the set, any | ||
| 118 | <item>s after the first are ignored. | ||
| 119 | |||
| 120 | Example: | ||
| 121 | |||
| 122 | FOR %%f IN ( *.ASM ) DO MASM %%f; | ||
| 123 | |||
| 124 | for %%f in (FOO BAR BLECH) do REM %%f to you | ||
| 125 | |||
| 126 | NOTE: The '%%' is needed so that after Batch parameter | ||
| 127 | (%0 - %9) processing is done, there is one '%' left. | ||
| 128 | If only '%f' were there, the batch parameter processor | ||
| 129 | would see the '%' then look at 'f', decide that '%f' | ||
| 130 | was an error (bad parameter reference) and throw out | ||
| 131 | the '%f' so that FOR would never see it. If the FOR | ||
| 132 | is NOT in a batch file, then only ONE '%' should be | ||
| 133 | used. | ||
| 134 | |||
| 135 | |||
| 136 | SHIFT | ||
| 137 | |||
| 138 | Currently, command files are limited to handling 10 | ||
| 139 | parameters: %0 through %9. To allow access to more than | ||
| 140 | these, the command SHIFT will perform a 'pop' of the | ||
| 141 | command line parameters: | ||
| 142 | |||
| 143 | if %0 = "foo" | ||
| 144 | %1 = "bar" | ||
| 145 | %2 = "blech" | ||
| 146 | %3...%9 are empty | ||
| 147 | |||
| 148 | then a SHIFT will result in the following: | ||
| 149 | |||
| 150 | %0 = "bar" | ||
| 151 | %1 = "blech" | ||
| 152 | %2...%9 are empty | ||
| 153 | |||
| 154 | If there are more than 10 parameters given on a command | ||
| 155 | line, then the those that appear after the 10th (%9) will | ||
| 156 | be shifted one at a time into %9 by successive shifts. | ||
| 157 | |||
| 158 | :<label> | ||
| 159 | |||
| 160 | This is essentially a no-op. It defines a label in the | ||
| 161 | batch file for a subsequent GOTO. It may also be used to | ||
| 162 | put comment lines in batch files since all lines that | ||
| 163 | start with ':' are ignored. | ||
| 164 | |||
| 165 | GOTO <label> | ||
| 166 | |||
| 167 | Causes commands to be taken from the batch file beginning | ||
| 168 | with the line after the <label> definition. If no label | ||
| 169 | has been defined, the current batch file will terminate. | ||
| 170 | |||
| 171 | Example: | ||
| 172 | |||
| 173 | :foo | ||
| 174 | REM looping... | ||
| 175 | GOTO foo | ||
| 176 | |||
| 177 | will produce a infinite sequence of messages: | ||
| 178 | 'REM looping...' | ||
| 179 | |||
| 180 | NOTE: Labels are case insensitive, :FOO == :foo == :Foo | ||
| 181 | |||
| 182 | |||
| 183 | ECHO [{ON | OFF | <message>}] | ||
| 184 | |||
| 185 | Normally, commands in a BATCH file are echoed onto the | ||
| 186 | standard output as they are seen by COMMAND. ECHO OFF | ||
| 187 | turns off this feature. ECHO ON turns echoing back on. | ||
| 188 | If ON or OFF is not specified and there is text following | ||
| 189 | the command, that text (a message) is echoed to standard | ||
| 190 | output. If there are no arguments at all, the current | ||
| 191 | setting of echo (on or off) is echoed to the standard | ||
| 192 | output in the form: | ||
| 193 | |||
| 194 | ECHO is xxx | ||
| 195 | |||
| 196 | Where xxx is "on" or "off". | ||
| 197 | |||
| 198 | Redirection of standard input/standard output. | ||
| 199 | |||
| 200 | Programs that read from the keyboard and write to the | ||
| 201 | screen are said to be doing I/O to the standard input and | ||
| 202 | standard output. Using any of the following will result | ||
| 203 | in I/O to these standard devices: | ||
| 204 | |||
| 205 | Writing to default handles 1 / read from default | ||
| 206 | handle 0. | ||
| 207 | |||
| 208 | Doing byte I/O using system calls 1, 2, 6-12. | ||
| 209 | |||
| 210 | These standard devices may be redirected to/from files by | ||
| 211 | the following in command line arguments: | ||
| 212 | |||
| 213 | > <filename> | ||
| 214 | causes <filename> to be created (or truncated to | ||
| 215 | zero length) and then assigns standard output to | ||
| 216 | that file. All output from the command will be | ||
| 217 | placed in the file. | ||
| 218 | |||
| 219 | < <filename> | ||
| 220 | causes standard input to be assigned to | ||
| 221 | <filename>. All input to the command will come | ||
| 222 | from this file. If end-of-file is reached, then | ||
| 223 | system calls 1, 2, 6-12 will return ^Z , while | ||
| 224 | reading from handle 0 will return zero characters. | ||
| 225 | |||
| 226 | >> <filename> | ||
| 227 | causes <filename> to be opened (created if | ||
| 228 | necessary) and positions the write pointer at the | ||
| 229 | end of the file so that all output will be | ||
| 230 | appended to the file. | ||
| 231 | |||
| 232 | Note that the above will not appear in the command line | ||
| 233 | that the program being invoked sees. | ||
| 234 | |||
| 235 | Examples: | ||
| 236 | |||
| 237 | DIR *.ASM > FOO.LST | ||
| 238 | Sends the output of the dir command to the file | ||
| 239 | FOO.LST. | ||
| 240 | |||
| 241 | |||
| 242 | FOR %0 IN (*.ASM) DO MASM %0; >>ERRS.LST | ||
| 243 | Sends all error output from assembling every .ASM file | ||
| 244 | into the file ERRS.LST. | ||
| 245 | |||
| 246 | Piping of standard I/O | ||
| 247 | |||
| 248 | It is often useful for the output of one program to be | ||
| 249 | sent as input to another program. A typical case is a | ||
| 250 | program that produces columnar output that must later be | ||
| 251 | sorted. | ||
| 252 | |||
| 253 | The pipe feature allows this to occur naturally is the | ||
| 254 | programs do all of their I/O to the standard devices. | ||
| 255 | |||
| 256 | For example, if we had a program SORT that read all of | ||
| 257 | it's standard input, sorted it and then wrote it to the | ||
| 258 | standard output, then we could get a sorted directory | ||
| 259 | listing as follows: | ||
| 260 | |||
| 261 | DIR | SORT | ||
| 262 | |||
| 263 | The | would cause all standard output generated by the | ||
| 264 | left-hand command to be sent to the standard input of the | ||
| 265 | right-hand command. | ||
| 266 | |||
| 267 | If we wanted the sorted directory to be sent to a file, we | ||
| 268 | type: | ||
| 269 | |||
| 270 | DIR | SORT >FILE | ||
| 271 | |||
| 272 | and away it goes. | ||
| 273 | |||
| 274 | The piping feature is implemented as sequential execution | ||
| 275 | of the procedures with redirection to and from temporary | ||
| 276 | files. In the example above, the following would be an | ||
| 277 | exact equivalent: | ||
| 278 | |||
| 279 | DIR >/tmp/std1 | ||
| 280 | SORT </tmp/std1 >FILE | ||
| 281 | |||
| 282 | |||
| 283 | |||
| 284 | The pipe is not a real pipe but rather a quasi-pipe | ||
| 285 | that uses temporary files to hold the input and output as | ||
| 286 | it sequentially executes the elements of the pipe. These | ||
| 287 | files are created in the current directory, of the current | ||
| 288 | drive and have the form %PIPEx%.$$$, where x will be 1 or | ||
| 289 | 2. This means that any program that runs in the pipe must | ||
| 290 | be sure to restore the current directory and drive if it | ||
| 291 | has changed them, otherwise the pipe files will be lost. | ||
| 292 | |||
| 293 | |||
| 294 | VER | ||
| 295 | Prints DOS version number. | ||
| 296 | |||
| 297 | VOL [<drive>:] | ||
| 298 | Prints the volume ID of the disk in drive d:. No d: does | ||
| 299 | default drive. | ||
| 300 | |||
| 301 | CHDIR [{<drive>: | <path>}] | ||
| 302 | Change directory, or print current. directory.If no | ||
| 303 | argument is given, the current directory on the default | ||
| 304 | drive is printed. If d: alone is given, the durrent | ||
| 305 | directory of drive d is printed. Otherwise the current | ||
| 306 | directory is set to path. | ||
| 307 | |||
| 308 | NOTE:"CD" is accepted as an abbreviation. | ||
| 309 | |||
| 310 | MKDIR <path> - Make a directory. | ||
| 311 | "MD" is accepted as an abbreviation. | ||
| 312 | |||
| 313 | RMDIR <path> - Remove a directory. | ||
| 314 | "RD" is accepted as an abbreviation. | ||
| 315 | The directory must be empty except for | ||
| 316 | '.' and '..'. | ||
| 317 | |||
| 318 | <path> - A standard XENIX style path with the optional | ||
| 319 | addition of a drive spec: | ||
| 320 | |||
| 321 | A:/FOO/BAR Full path | ||
| 322 | /FOO/BAR Full path, current drive | ||
| 323 | FOO/BAR Current dir relative | ||
| 324 | A:FOO/BAR " " " | ||
| 325 | |||
| 326 | VERIFY [{ON | OFF}] | ||
| 327 | Select/deselect verify after write mode. This supliments | ||
| 328 | the V switch to the COPY command. Once turned ON, it | ||
| 329 | stays on until some program changes it (via the set verify | ||
| 330 | system call) or the VERIFY OFF command is given. If no | ||
| 331 | argument is given, the current setting of VERIFY is | ||
| 332 | printed to the standard output in the form: | ||
| 333 | |||
| 334 | VERIFY is xxx | ||
| 335 | |||
| 336 | Where xxx is "on" or "off". | ||
| 337 | |||
| 338 | PATH [<path>{;<path>}*] | ||
| 339 | Set command search paths. This allows users to set | ||
| 340 | directories that should be searched for external commands | ||
| 341 | after a search of the current directory is made. The | ||
| 342 | default value is /bin. In addition there are two special | ||
| 343 | cases: PATH all by itself with no arguments will print | ||
| 344 | the current path. Path with the single argument ';' (ie. | ||
| 345 | "PATH ;") will set the NUL path (no directories other than | ||
| 346 | the current one searched). If no argument is given, the | ||
| 347 | current value of PATH is printed to the standard output in | ||
| 348 | the form: | ||
| 349 | |||
| 350 | PATH=text of path | ||
| 351 | or | ||
| 352 | No path | ||
| 353 | |||
| 354 | NOTE: On IBM systems, the default value of path is No | ||
| 355 | path. | ||
| 356 | |||
| 357 | EXIT | ||
| 358 | For COMMANDs run without the P switch, this causes COMMAND | ||
| 359 | to return. For a normal COMMAND it causes a return to | ||
| 360 | itself. | ||
| 361 | |||
| 362 | BREAK [{ON | OFF}] | ||
| 363 | Like in CONFIG.SYS, "BREAK ON" turns on the Control C | ||
| 364 | check in the DOS function dispatcher. "BREAK OFF" turns | ||
| 365 | it off. If no argument is given the setting of BREAK is | ||
| 366 | printed to the standard output in the form: | ||
| 367 | |||
| 368 | BREAK is xxx | ||
| 369 | |||
| 370 | Where xxx is "on" or "off". | ||
| 371 | |||
| 372 | PROMPT [<prompt-text>] | ||
| 373 | Set the system prompt. MS-DOS prompts are now user | ||
| 374 | settable, all of the text on the command line is taken to | ||
| 375 | be the new prompt. If no text is present the prompt is | ||
| 376 | set to the default prompt. There are meta strings for | ||
| 377 | various special prompts. These are of the form '$c' where | ||
| 378 | c is one of the following: | ||
| 379 | |||
| 380 | $ - The '$' character. | ||
| 381 | t - The time. | ||
| 382 | d - The date. | ||
| 383 | p - The current directory of the default drive. | ||
| 384 | v - The version number. | ||
| 385 | n - The default drive. | ||
| 386 | g - The '>' character. | ||
| 387 | l - The '<' character. | ||
| 388 | b - The '|' character. | ||
| 389 | s - The ' ' character. | ||
| 390 | e - The ESC character. | ||
| 391 | _ - A CR LF sequence. | ||
| 392 | |||
| 393 | EXAMPLE: | ||
| 394 | PROMPT $n: | ||
| 395 | Would set the normal MS-DOS prompt. | ||
| 396 | PROMPT $n> | ||
| 397 | Would det the normal PC-DOS prompt. | ||
| 398 | PROMPT Time = $t$_Date = $d | ||
| 399 | Would set a two line prompt which printed | ||
| 400 | Time = (current time) | ||
| 401 | Date = (current date) | ||
| 402 | |||
| 403 | NOTE: For '$c' sequences, lower case = upper case, and | ||
| 404 | any character not on the above list is mapped to | ||
| 405 | nothing. | ||
| 406 | |||
| 407 | SET (ENVNAME)=(ENVTEXT) | ||
| 408 | Set environment strings. This command inserts strings in | ||
| 409 | COMMAND's environment. For instance: | ||
| 410 | |||
| 411 | SET PROMPT=$n> | ||
| 412 | Duplicates the function of the PROMPT command. | ||
| 413 | SET PATH=p1;p2 | ||
| 414 | Duplicates the function of the PATH command. | ||
| 415 | SET foo=bar | ||
| 416 | Puts the string FOO=bar into the environment (note the | ||
| 417 | case mapping of (ENVNAME)). | ||
| 418 | |||
| 419 | NOTE: Environments are very flexible, almost anything can | ||
| 420 | be put into the environment with the SET command; the | ||
| 421 | only requirement is that a single '=' be present in | ||
| 422 | the string. | ||
| 423 | |||
| 424 | CLS | ||
| 425 | Clear screen, causes the ANSI escape sequence ESC[2J to be | ||
| 426 | sent to standard output. | ||
| 427 | |||
| 428 | CTTY /DEV/dev - Change console TTY. For instance: | ||
| 429 | |||
| 430 | CTTY /DEV/AUX | ||
| 431 | |||
| 432 | Would move all command I/O to the AUX port. | ||
| 433 | |||
| 434 | CTTY /DEV/CON | ||
| 435 | |||
| 436 | Would move it back to the normal device. The | ||
| 437 | /dev/ prefix may be left off if AVAILDEV is | ||
| 438 | TRUE (see configuration-file doc). | ||
| 439 | |||
| 440 | COMMAND internal commands take path arguments. | ||
| 441 | |||
| 442 | DIR <path> | ||
| 443 | |||
| 444 | COPY <path> <path> | ||
| 445 | |||
| 446 | DEL(ERASE) <path> | ||
| 447 | If the path is a dir, all files in that dir | ||
| 448 | are deleted. | ||
| 449 | NOTE: The "Are you sure (Y/N)" prompt for DEL and | ||
| 450 | ERASE now uses buffered standard input, so | ||
| 451 | users must type a return after their answer. | ||
| 452 | This gives them the chance to correct if they | ||
| 453 | type 'y' by mistake. | ||
| 454 | |||
| 455 | TYPE <path> (must specify a file) | ||
| 456 | |||
| 457 | |||
| 458 | |||
| 459 | |||
| 460 | FILCOM - compare two files | ||
| 461 | |||
| 462 | The FILCOM program compares two files and produces a log | ||
| 463 | of differences between them. The comparison may be made | ||
| 464 | in two fashions; either on a line-by-line basis, or on a | ||
| 465 | byte-by-byte basis. | ||
| 466 | |||
| 467 | The line-by-line compare will isolate blocks of lines that | ||
| 468 | are different between the two files and will print the | ||
| 469 | blocks from each file. The line-by-line compare is the | ||
| 470 | default when neither of the two files being compared has | ||
| 471 | the extension .EXE, .COM, or .OBJ. | ||
| 472 | |||
| 473 | The byte-by-byte compare will display exactly which bytes | ||
| 474 | are different between the two files. If either file being | ||
| 475 | compared has extension .EXE, .COM, or .OBJ then the files | ||
| 476 | will be compared in byte-by-byte mode. | ||
| 477 | |||
| 478 | |||
| 479 | |||
| 480 | RECOVER - recover files from a trashed disk. | ||
| 481 | |||
| 482 | If a sector on a disk goes bad, you can recover either the | ||
| 483 | file that contained that sector (without the sector) or | ||
| 484 | the entire disk (if the bad sector was in the directory). | ||
| 485 | |||
| 486 | To recover a particular file: | ||
| 487 | |||
| 488 | RECOVER <file-to-recover> | ||
| 489 | |||
| 490 | This will cause the file to be read sector by sector and | ||
| 491 | to be have the bad sector skipped. Note that this implies | ||
| 492 | that the allocation unit containing the bad sector will be | ||
| 493 | read as much as possible. When such a bad sector is | ||
| 494 | found, its containing allocation unit is marked as bad, | ||
| 495 | thus preventing future allocations of that bad sector. | ||
| 496 | |||
| 497 | To recover a particular disk: | ||
| 498 | |||
| 499 | RECOVER <drive-letter>: | ||
| 500 | |||
| 501 | This will cause a scan to be made of the drive's FAT for | ||
| 502 | chains of allocation units (files). A new root directory | ||
| 503 | is then written that has entries of the form FILEnnnn. | ||
| 504 | Each FILEnnnn will point to the head of one of the | ||
| 505 | allocation unit chains. | ||
| 506 | |||
| 507 | If there are more chains than directory entries in the | ||
| 508 | root, RECOVER prints a message and leaves the un-RECOVERED | ||
| 509 | chains in the FAT so that RECOVER can be run again once | ||
| 510 | some room has been made in the ROOT. | ||
| 511 | |||
| 512 | |||
| 513 | |||
| 514 | DEBUG ON MS-DOS 2.0 | ||
| 515 | |||
| 516 | |||
| 517 | When 2.0 DEBUG is invoked it sets up a program header | ||
| 518 | atoffset 0 in its program work area. On previous versions it | ||
| 519 | was OK to overwrite this header with impunity: this is true | ||
| 520 | of the default header set up if no <filespec> is given to | ||
| 521 | DEBUG. If DEBUGging a .COM or .EXE file, however, you must be | ||
| 522 | careful not to tamper with the header of the program below | ||
| 523 | address 5CH, to do this will probably result in a crash. It | ||
| 524 | is also important that an attempt is not made to "restart" a | ||
| 525 | program once the "program terminated normally" message is | ||
| 526 | given. The program must be reloaded with the N and L commands | ||
| 527 | in order for it to run properly. | ||
| 528 | |||
| 529 | NEW FEATURES | ||
| 530 | |||
| 531 | The A (Assemble) Command | ||
| 532 | |||
| 533 | FORMAT: A [<address>] | ||
| 534 | |||
| 535 | PURPOSE: To assemble 8086/8087/8088 mnemonics directly into | ||
| 536 | memory. | ||
| 537 | |||
| 538 | o If a syntax error is encountered, DEBUG responds with | ||
| 539 | |||
| 540 | ^ Error | ||
| 541 | |||
| 542 | and redisplays the current assembly address. | ||
| 543 | |||
| 544 | o All numeric values are hexadecimal and may be entered | ||
| 545 | as 1-4 characters. | ||
| 546 | |||
| 547 | o Prefix mnemonics must be entered in front of the opcode | ||
| 548 | to which they refer. They may also be entered on a | ||
| 549 | separate line. | ||
| 550 | |||
| 551 | o The segment override mnemonics are CS:, DS:, ES:, and | ||
| 552 | SS: | ||
| 553 | |||
| 554 | o String manipulation mnemonics must explictly state the | ||
| 555 | string size. For example, the MOVSW must be used to | ||
| 556 | move word strings and MOVSB must be used to move byte | ||
| 557 | strings. | ||
| 558 | |||
| 559 | |||
| 560 | o The mnemonic for the far return is RETF. | ||
| 561 | |||
| 562 | o The assembler will automatically assemble short, near | ||
| 563 | or far jumps and calls depending on byte displacement | ||
| 564 | to the destination address. These may be overridden | ||
| 565 | with the NEAR or FAR prefix. For example: | ||
| 566 | |||
| 567 | 0100:0500 JMP 502 ; a 2 byte short jump | ||
| 568 | 0100:0502 JMP NEAR 505 ; a 3 byte near jump | ||
| 569 | 0100:0505 JMP FAR 50A ; a 5 byte far jump | ||
| 570 | |||
| 571 | The NEAR prefix may be abbreviated to NE but the FAR | ||
| 572 | prefix cannot be abbreviated. | ||
| 573 | |||
| 574 | o DEBUG cannot tell whether some operands refer to a word | ||
| 575 | memory location or a byte memroy location. In this case | ||
| 576 | the data type must be explicity stated with the prefix | ||
| 577 | "WORD PTR" or "BYTE PTR". DEBUG will also except the | ||
| 578 | abbreviations "WO" and "BY". For example: | ||
| 579 | |||
| 580 | NEG BYTE PTR [128] | ||
| 581 | DEC WO [SI] | ||
| 582 | |||
| 583 | o DEBUG also cannot tell whether an operand refers to a | ||
| 584 | memory location or to an immediate operand. DEBUG uses | ||
| 585 | the common convention that operands enclosed in square | ||
| 586 | brackets refer to memory. For example: | ||
| 587 | |||
| 588 | MOV AX,21 ;Load AX with 21H | ||
| 589 | MOV AX,[21] ;Load AX with the contents | ||
| 590 | ;of memory location 21H | ||
| 591 | |||
| 592 | o Two popular pseudo-instructions have also been included. | ||
| 593 | The DB opcode will assemble byte values directly into | ||
| 594 | memory. The DW opcode will assemble word values directly | ||
| 595 | into memory. For example: | ||
| 596 | |||
| 597 | DB 1,2,3,4,"THIS IS AN EXAMPLE" | ||
| 598 | DB 'THIS IS A QUOTE: "' | ||
| 599 | DB "THIS IS A QUOTE: '" | ||
| 600 | |||
| 601 | DW 1000,2000,3000,"BACH" | ||
| 602 | |||
| 603 | |||
| 604 | o All forms of the register indirect commands are supported. | ||
| 605 | For example: | ||
| 606 | |||
| 607 | ADD BX,34[BP+2].[SI-1] | ||
| 608 | POP [BP+DI] | ||
| 609 | PUSH [SI] | ||
| 610 | |||
| 611 | o All opcode synonyms are supported, For example: | ||
| 612 | |||
| 613 | LOOPZ 100 | ||
| 614 | LOOPE 100 | ||
| 615 | |||
| 616 | JA 200 | ||
| 617 | JNBE 200 | ||
| 618 | |||
| 619 | o For 8087 opcodes the WAIT or FWAIT prefix must be | ||
| 620 | explictly specified. For example: | ||
| 621 | |||
| 622 | FWAIT FADD ST,ST(3) ; This lines will assemble | ||
| 623 | ; a FWAIT prefix | ||
| 624 | |||
| 625 | FLD TBYTE PTR [BX] ; This line will not | ||
| 626 | |||
| 627 | |||
| 628 | |||
| 629 | FORMAT enhancements | ||
| 630 | |||
| 631 | FORMAT will now install volume id's during the format | ||
| 632 | process. DIR and CHKDSK will display these volume id's. | ||
| 633 | |||
| 634 | User programs can read the volume id on a particular drive | ||
| 635 | by doing a 'search next' with the volume id attribute. It | ||
| 636 | is impossible, using normal DOS calls, to delete a volume | ||
| 637 | id or to create another one. The only way to create a | ||
| 638 | volume id is to reformat the disk. | ||
| 639 | |||
| 640 | NOTE: On IBM systems the V switch must be given to FORMAT | ||
| 641 | to have it do Volume IDs. | ||
| 642 | |||
| 643 | |||
| 644 | |||
| 645 | |||
| 646 | CHKDSK FOR MS-DOS 2.0 | ||
| 647 | |||
| 648 | |||
| 649 | MS-DOS 2.0 has a tree structured directory scheme which | ||
| 650 | did not exist on previous versions of MS-DOS. As a result | ||
| 651 | CHKDSK is a much more complex program than in previous | ||
| 652 | versions since it must perform a tree traversal to find all of | ||
| 653 | the files on a given disk. It employes a depth first | ||
| 654 | traversal in order to accomplish this. | ||
| 655 | |||
| 656 | Previous versions of CHKDSK automatically "fixed" | ||
| 657 | disks (regardless of whether it was appropriate). CHKDSK 2.00 | ||
| 658 | run normally will not alter the disk in any way, it simply | ||
| 659 | reports on any inconsistencies found. To actually "fix" a | ||
| 660 | disk CHKDSK must be run with the F switch (Fix). This allows | ||
| 661 | you to perhaps take some alternate (to CHKDSK repairs) action | ||
| 662 | before letting CHKDSK loose on your disk. | ||
| 663 | |||
| 664 | CHKDSK 2.00 will report on non-contiguous allocation units | ||
| 665 | (extents) for specified files. This is handy for gaging how | ||
| 666 | "fragmented" a disk volume has become. This is done by simply | ||
| 667 | giving a filespec: | ||
| 668 | |||
| 669 | CHKDSK B:*.* | ||
| 670 | |||
| 671 | This would report extents for all files in the current | ||
| 672 | directory for drive B after doing a normal consistency check | ||
| 673 | on drive B. Files which have many extents can be copied and | ||
| 674 | renamed to restore them to a contiguous state, thus improving | ||
| 675 | I/O performance to the files. | ||
| 676 | |||
| 677 | Previous versions of CHKDSK would simply free | ||
| 678 | allocation units which were marked as used, but were not | ||
| 679 | actually part of any file. CHKDSK 2.00 will recover these | ||
| 680 | "orphan" allocation units if specified. If orphan allocation | ||
| 681 | units are found, CHKDSK prompts for free or recover. Free | ||
| 682 | just frees the orphans as previous versions did, recover will | ||
| 683 | employ allocation chain analysis to create "orphan files" in | ||
| 684 | the root directory of the disk. These files will have the | ||
| 685 | form "%ORPHAN%.l$$" where l will take on some ASCII value | ||
| 686 | greater than '@'. These files may then be inspected to see if | ||
| 687 | valuable data was contained in them. If there is not enough | ||
| 688 | room to make all of the "orphan" files, CHKDSK leaves the | ||
| 689 | unrecovered chains in the FAT so that CHKDSK can be run again | ||
| 690 | (once some entries in the ROOT have been deleted). NOTE: | ||
| 691 | Making ORPHAN files is a SLOW process. | ||
| 692 | |||
| 693 | Verbose mode. CHKDSK 2.00 may be run with the V switch | ||
| 694 | which causes a trace of the files and directories being | ||
| 695 | processed to be printed as CHKDSK runs. | ||
| 696 | |||
| 697 | |||
| 698 | FILTERS FOR MS-DOS 2.0 | ||
| 699 | |||
| 700 | A filter is a utility that reads from standard input, | ||
| 701 | modifies the information in some way, then writes the result | ||
| 702 | to standard output. In this way the data is said to have been | ||
| 703 | "filtered" by the program. Since different filters can be | ||
| 704 | piped together in many different ways a few filters can take | ||
| 705 | the place of a large number of specific purpose programs. The | ||
| 706 | following describes the filters that are provided with MS-DOS | ||
| 707 | 2.0: | ||
| 708 | |||
| 709 | CIPHER <key word> | ||
| 710 | |||
| 711 | Cipher reads a program from standard input, encrypts it | ||
| 712 | using the key word provided by the user, then writes the | ||
| 713 | result to standard output. To decrypt the file simply run | ||
| 714 | CIPHER again using the same keyword. For example: | ||
| 715 | |||
| 716 | A>CIPHER MYSTERY <NSA.CIA >SECRET.FIL | ||
| 717 | |||
| 718 | This command line will read file NSA.CIA, encrypt it using | ||
| 719 | the key word "MYSTERY", then write the result to file | ||
| 720 | SECRET.FIL To view the original file the following command | ||
| 721 | line could be used: | ||
| 722 | |||
| 723 | A>CIPHER MYSTERY <SECRET.FIL | ||
| 724 | |||
| 725 | This will read file SECRET.FIL, decrypt the file using the | ||
| 726 | key word "MYSTERY", then write the result to standard output, | ||
| 727 | which in this case is the console. | ||
| 728 | |||
| 729 | FGREP | ||
| 730 | |||
| 731 | This filter takes as arguments a string and optionally a | ||
| 732 | series of file names. It will send to standard output all | ||
| 733 | lines from the files specified in the command line that | ||
| 734 | contain the string. | ||
| 735 | |||
| 736 | If no files are specified FGREP will take the input from | ||
| 737 | standard in. The format for the command line invocation of | ||
| 738 | FGREP is: | ||
| 739 | |||
| 740 | FGREP [<option>] <string> <filename>* | ||
| 741 | |||
| 742 | The options available are: | ||
| 743 | |||
| 744 | /v Will cause FGREP to output all lines NOT | ||
| 745 | containing the specified string. | ||
| 746 | |||
| 747 | /c Will cause FGREP to only print the count of | ||
| 748 | lines matched in each of the files. | ||
| 749 | |||
| 750 | /n Each line matched is preceded by its relative | ||
| 751 | line number in the file. | ||
| 752 | |||
| 753 | The string argument should be enclosed in double quotes. | ||
| 754 | Two double quotes in succession are taken as a single double | ||
| 755 | quote. So, | ||
| 756 | |||
| 757 | A>FGREP "Fool""s Paradise" book1.txt book2.txt bible | ||
| 758 | |||
| 759 | will output all lines from the book1.txt, book2.txt and bible | ||
| 760 | (in that order that contain the string: Fool"s Paradise . | ||
| 761 | And, | ||
| 762 | |||
| 763 | A>dir b: | fgrep /v "DAT" | ||
| 764 | |||
| 765 | will output all names of the files in disk b: which do not | ||
| 766 | contain the string DAT . | ||
| 767 | |||
| 768 | MORE | ||
| 769 | |||
| 770 | The filter MORE reads from standard input, sends one | ||
| 771 | screen full of information to standard output and then pauses | ||
| 772 | with message: | ||
| 773 | |||
| 774 | -- More -- | ||
| 775 | |||
| 776 | Pressing the RETURN key will cause another screen full of | ||
| 777 | information to be written to standard output. This process | ||
| 778 | continues until all the input data is read. | ||
| 779 | |||
| 780 | SORT [/R] [/+n] | ||
| 781 | |||
| 782 | Sort reads from standard input, sorts the data, the writes | ||
| 783 | the information to standard output. The sort is done using | ||
| 784 | the ASCII collating sequence. There are switches which allow | ||
| 785 | the user to select various options: | ||
| 786 | |||
| 787 | R - Reverse the sort, that is make "Z" come before "A" | ||
| 788 | |||
| 789 | +n - Sort starting with column "n" where n is some integer. | ||
| 790 | The default is start the comparisons with column 1, | ||
| 791 | this switch allows the user to start in any column. | ||
| 792 | |||
| 793 | example: | ||
| 794 | |||
| 795 | A>SORT /R <UNSORT.TXT >SORT.TXT | ||
| 796 | |||
| 797 | This command line will read the file UNSORT.TXT, do a reverse | ||
| 798 | sort, then write the output to file SORT.TXT | ||
| 799 | |||
| 800 | A>DIR | SORT /+14 | ||
| 801 | |||
| 802 | This command line will cause the output of the directory | ||
| 803 | command to be piped to the sort filter, the sort filter will | ||
| 804 | sort starting with column 14 (This is the column the file size | ||
| 805 | starts), then send the output to the console. Thus a | ||
| 806 | directory sorted by file size will be the result. To get real | ||
| 807 | fancy: | ||
| 808 | |||
| 809 | A>DIR | SORT /+14 | MORE | ||
| 810 | |||
| 811 | will do the same thing except that MORE will give you a chance | ||
| 812 | to read the directory before it scrolls off the screen. | ||
| 813 | |||