diff --git a/v2.0/bin/ANSI.DOC b/v2.0/bin/ANSI.DOC new file mode 100644 index 00000000..040d9d27 Binary files /dev/null and b/v2.0/bin/ANSI.DOC differ diff --git a/v2.0/bin/CHKDSK.COM b/v2.0/bin/CHKDSK.COM new file mode 100644 index 00000000..152bc38d Binary files /dev/null and b/v2.0/bin/CHKDSK.COM differ diff --git a/v2.0/bin/COMMAND.COM b/v2.0/bin/COMMAND.COM new file mode 100644 index 00000000..820f3932 Binary files /dev/null and b/v2.0/bin/COMMAND.COM differ diff --git a/v2.0/bin/CONFIG.DOC b/v2.0/bin/CONFIG.DOC new file mode 100644 index 00000000..bfb1985d Binary files /dev/null and b/v2.0/bin/CONFIG.DOC differ diff --git a/v2.0/bin/CREF.EXE b/v2.0/bin/CREF.EXE new file mode 100644 index 00000000..a88c2fa3 Binary files /dev/null and b/v2.0/bin/CREF.EXE differ diff --git a/v2.0/bin/DEBUG.COM b/v2.0/bin/DEBUG.COM new file mode 100644 index 00000000..41d127b0 Binary files /dev/null and b/v2.0/bin/DEBUG.COM differ diff --git a/v2.0/bin/DEVDRIV.DOC b/v2.0/bin/DEVDRIV.DOC new file mode 100644 index 00000000..3c827938 --- /dev/null +++ b/v2.0/bin/DEVDRIV.DOC @@ -0,0 +1,802 @@ + MS-DOS 2.0 Device Drivers + +INTRODUCTION + + In the past, DOS-device driver (BIOS for those who are +familiar with CP/M) communication has been mediated with +registers and a fixed-address jump-table. This approach +has suffered heavily from the following two observations: + + o The old jump-table ideas of the past are fixed in + scope and allow no extensibility. + + o The past device driver interfaces have been written + without regard for the true power of the hardware. + When a multitasking system or interrupt driven + hardware is installed a new BIOS must be written + largely from scratch. + + In MSDOS 2.0, the DOS-device driver interface has changed +from the old jump-table style to one in which the device +drivers are linked together in a list. This allows new +drivers for optional hardware to be installed (and even +written) in the field by other vendors or the user himself. +This flexibility is one of the major new features of MS-DOS +2.0. + + Each driver in the chain defines two entry points; the +strategy routine and the interrupt routine. The 2.0 DOS +does not really make use of two entry points (it simply calls +strategy, then immediately calls interrupt). This dual entry +point scheme is designed to facilitate future multi-tasking +versions of MS-DOS. In multi-tasking environments I/O must +be asynchronous, to accomplish this the strategy routine +will be called to queue (internally) a request and return +quickly. It is then the responsibility of the interrupt +routine to perform the actual I/O at interrupt time by picking +requests off the internal queue (set up by the strategy +routine), and process them. When a request is complete, +it is flagged as "done" by the interrupt routine. The DOS +periodically scans the list of requests looking for ones +flagged as done, and "wakes up" the process waiting for the +completion of the request. + + In order for requests to be queued as above it is no +longer sufficient to pass I/O information in registers, since +many requests may be pending at any one time. Therefore +the new device interface uses data "packets" to pass request +information. A device is called with a pointer to a packet, +this packet is linked into a global chain of all pending +I/O requests maintained by the DOS. The device then links +the packet into its own local chain of requests for this +particular device. The device interrupt routine picks +requests of the local chain for processing. The DOS scans +the global chain looking for completed requests. These +packets are composed of two pieces, a static piece which +has the same format for all requests (called the static +request header), which is followed by information specific +to the request. Thus packets have a variable size and format. + + At this points it should be emphasized that MS-DOS 2.0 +does not implement most of these features, as future versions +will. There is no global or local queue. Only one request +is pending at any one time, and the DOS waits for this current +request to be completed. For 2.0 it is sufficient for the +strategy routine to simply store the address of the packet +at a fixed location, and for the interrupt routine to then +process this packet by doing the request and returning. +Remember: the DOS just calls the strategy routine and then +immediately calls the interrupt routine, it is assumed that +the request is completed when the interrupt routine returns. +This additional functionality is defined at this time so +that people will be aware and thinking about the future. + + +FORMAT OF A DEVICE DRIVER + + A device driver is simply a relocatable memory image +with all of the code in it to implement the device (like +a .COM file, but not ORGed at 100 Hex). In addition it has +a special header at the front of it which identifies it as +a device, defines the strategy and interrupt entry points, +and defines various attributes. It should also be noted +that there are two basic types of devices. + + The first is character devices. These are devices which +are designed to do character I/O in a serial manner like +CON, AUX, and PRN. These devices are named (ie. CON, AUX, +CLOCK, etc.), and users may open channels (FCBs) to do I/O +to them. + + The second class of devices is block devices. These +devices are the "disk drives" on the system, they can do +random I/O in pieces called blocks (usually the physical +sector size) and hence the name. These devices are not +"named" as the character devices are, and therefore cannot +be "opened" directly. Instead they are "mapped" via the +drive letters (A,B,C, etc.). + + Block devices also have units. In other words a single +driver may be responsible for one or more disk drives. For +instance block device driver ALPHA (please note that we cannot +actually refer to block devices by a name!) may be +responsible for drives A,B,C and D, this simply means that +it has four units (0-3) defined and therefore takes up four +drive letters. Which units correspond to which drive letters +is determined by the position of the driver in the chain +of all drivers: if driver ALPHA is the first block driver +in the device chain, and it defines 4 units (0-3), then they +will be A,B,C and D. If BETA is the second block driver +and defines three units (0-2), then they will be E,F and +G and so on. MS-DOS 2.0 is not limited to 16 block device +units, as previous versions were. The theoretical limit +is 63 (2^6 - 1), but it should be noted that after 26 the +drive letters get a little strange (like ] \ and ^). NOTE: +Character devices cannot define multiple units (this because +they have only one name). + + +Here is what that special device header looks like: + + +--------------------------------------+ + | DWORD Pointer to next device | + | (Must be set to -1) | + +--------------------------------------+ + | WORD Attributes | + | Bit 15 = 1 if char device 0 if blk | + | if bit 15 is 1 | + | Bit 0 = 1 if Current sti device | + | Bit 1 = 1 if Current sto output | + | Bit 2 = 1 if Current NUL device | + | Bit 3 = 1 if Current CLOCK dev | + | Bit 4 = 1 if SPECIAL | + | Bit 14 is the IOCTL bit (see below) | + | Bit 13 is the NON IBM FORMAT bit | + +--------------------------------------+ + | WORD Pointer to Device strategy | + | entry point | + +--------------------------------------+ + | WORD Pointer to Device interrupt | + | entry point | + +--------------------------------------+ + | 8-BYTE character device name field | + | Character devices set a device name | + | For block devices the first byte is | + | The number of units | + +--------------------------------------+ + + Note that the device entry points are words. They must +be offsets from the same segment number used to point to +this table. Ie. if XXX.YYY points to the start of this +table, then XXX.strategy and XXX.interrupt are the entry +points. + + A word about the Attribute field. This field is used +most importantly to tell the system whether this device is +a block or character device (bit 15). Most of other bits +are used to give selected character devices certain special +treatment (NOTE: these bits mean nothing on a block device). +Let's say a user has a new device driver which he wants to +be the standard input and output. Besides just installing +the driver he needs to tell SYSINIT (and the DOS) that he +wishes his new driver to override the current sti and sto +(the "CON" device). This is accomplished by setting the +attributes to the desired characteristics, so he would set +Bits 0 and 1 to 1 (note that they are separate!!). Similarly +a new CLOCK device could be installed by setting that +attribute, see the section at the end on the CLOCK device. +NOTE: that although there is a NUL device attribute, the +NUL device cannot be re-assigned. This attribute exists +for the DOS so that it can tell if the NUL device is being +used. + + The NON IBM FORMAT bit applies only to block devices +and effects the operation of the get BPB device call (see +below). + + The other bit of interest is the IOCTL bit which has +meaning on character or block devices. This bit tells the +DOS whether this device can handle control strings (via the +IOCTL system call). + + If a driver cannot process control strings, it should +initially set this bit to 0. This tells the DOS to return +an error if an attempt is made (via IOCTL system call) to +send or receive control strings to this device. A device +which can process control strings should initialize it to +1. For drivers of this type, the DOS will make calls to +the IOCTL INPUT and OUTPUT device functions to send and +receive IOCTL strings (see IOCTL in the SYSTEM-CALLS +document). + + The IOCTL functions allow data to be sent and received +by the device itself for its own use (to set baud rate, stop +bits, form length etc., etc.), instead of passing data over +the device channel as a normal read or write does. The +interpretation of the passed information is up to the device, +but it MUST NOT simply be treated as a normal I/O. + + The SPECIAL bit applies only to character drivers and +more particularly to CON drivers. The new 2.0 interface +is a much more general and consistent interface than the +old 1.25 DOS interface. It allows for a number of additional +features of 2.0. It is also slower than 1.25 if old style +"single byte" system calls are made. To make most efficient +use of the interface all applications should block their +I/O as much as possible. This means make one XENIX style +system call to output X bytes rather than X system calls +to output one byte each. Also putting a device channel in +RAW mode (see IOCTL) provides a means of putting out +characters even FASTER than 1.25. To help alleviate the +CON output speed problem for older programs which use the +1 - 12 system calls to output large amounts of data the +SPECIAL bit has been implemented. If this bit is 1 it means +the device is the CON output device, and has implemented +an interrupt 29 Hex handler, where the 29 Hex handler is +defined as follows: + + Interrupt 29h handlers + + Input: + Character in AL + + Function: + output the character in al to the user + screen. + Output: + None + Registers: + all registers except bx must be preserved. + No registers except for al have a known or + consistent value. + + If a character device implements the SPECIAL bit, it +is the responsibility of the driver to install an address +at the correct location in the interrupt table for interrupt +29 Hex as part of its INIT code. IMPLICATION: There can +be only one device driver with the SPECIAL bit set in the +system. There is no check to insure this state. + +WARNING: THIS FEATURE WILL NOT BE SUPPORTED IN FUTURE VERSIONS + OF THE OPERATING SYSTEM. IMPLICATION: Any application + (not device driver) which uses INT 29H directly will + not work on future versions, YOU HAVE BEEN WARNED. + + In order to "make" a device driver that SYSINIT can +install, a memory image or .EXE (non-IBM only) format file +must be created with the above header at the start. The +link field should be initialized to -1 (SYSINIT fills it +in). The attribute field and entry points must be set +correctly, and if the device is a character device, the name +field must be filled in with the name (if a block device +SYSINIT will fill in the correct unit count). This name +can be any 8 character "legal" file name. In fact SYSINIT +always installs character devices at the start of the device +list, so if you want to install a new CON device all you +have to do is name it "CON". The new one is ahead of the +old one in the list and thus preempts the old one as the +search for devices stops on the first match. Be sure to +set the sti and sto bits on a new CON device! + +NOTE: Since SYSINIT may install the driver anywhere, you + must be very careful about FAR memory references. You + should NOT expect that your driver will go in the same + place every time (The default BIOS drivers are exempted + from this of course). + + +INSTALLATION OF DEVICE DRIVERS + + Unlike past versions MS-DOS 2.0 allows new device drivers +to be installed dynamically at boot time. This is +accomplished by the new SYSINIT module supplied by Microsoft, +which reads and processes the CONFIG.SYS file. This module +is linked together with the OEM default BIOS in a similar +manner to the way FORMAT is built. + + One of the functions defined for each device is INIT. +This routine is called once when the device is installed, +and never again. The only thing returned by the init routine +is a location (DS:DX) which is a pointer to the first free +byte of memory after the device driver, (like a terminate +and stay resident). This pointer method can be used to "throw +away" initialization code that is only needed once, saving +on space. + + Block devices are installed the same way and also return +a first free byte pointer as above, additional information +is also returned: + + o The number of units is returned, this determines + logical device names. If the current maximum logical + device letter is F at the time of the install call, + and the init routine returns 4 as the number of units, + then they will have logical names G, H, I and J. + This mapping is determined by by the position of + the driver in the device list and the number of units + on the device (stored in the first byte of the device + name field). + + o A pointer to a BPB (Bios Parameter Block) pointer + array is also returned. This will be similar to + the INIT table used in previous versions, but will + have more information in it. There is one table + for each unit defined. These blocks will be used + to build a DPB (Drive Parameter Block) for each of + the units. The pointer passed to the DOS from the + driver points to an array of n word pointers to BPBs + where n is the number of units defined. In this + way if all units are the same, all of the pointers + can point to the same BPB, saving space. NOTE: this + array must be protected (below the free pointer set + by the return) since the DPB will be built starting + at the byte pointed to by the free pointer. The + sector size defined must be less than or equal to + the maximum sector size defined at default BIOS init + time. If it isn't the install will fail. One new + piece of DPB info set from this table will be a "media + descriptor byte". This byte means nothing to the + DOS, but is passed to devices so that they know what + form of a DPB the DOS is currently using for a + particular Drive-Unit. + + Block devices may take several approaches; they may be +dumb or smart. A dumb device would define a unit (and +therefore a DPB) for each possible media drive combination. +Unit 0 = drive 0 single side, unit 1 = drive 0 double side, +etc. For this approach media descriptor bytes would mean +nothing. A smart device would allow multiple media per unit, +in this case the BPB table returned at init must define space +large enough to accommodate the largest possible media +supported. Smart drivers will use the "media byte" to pass +around info about what media is currently in a unit. NOTE: +If the DPB is a "hybrid" made to get the right sizes, it +should give an invalid "media byte" back to the DOS. + + The BOOT (default BIOS) drivers are installed pretty +much as above. The preset device list is scanned. If block +drivers are encountered they are installed as above (with +the exception that the break is not moved since the drivers +are already resident in the BIOS). Note that the logical +drive letters are assigned in list order, thus the driver +which is to have logical A must be the first unit of the +first block device in the list. The order of character +devices is also important. There must be at least 4 character +devices defined at boot which must be the first four devices +(of either type), the first will become standard input, +standard output, and standard error output. The second will +become standard auxiliary input and output, the third will +become standard list output, and the forth will become the +date/time (CLOCK) device. Thus the BIOS device list must +look like this: + +->CON->AUX->PRN->CLOCK->any other block or character devices + +THE DRIVER + + A device driver will define the following functions: + + Command Function + Code + + 0 INIT + 1 MEDIA CHECK (Block only, NOP for character) + 2 BUILD BPB " " " " " + 3 IOCTL INPUT (Only called if device has IOCTL) + 4 INPUT (read) + 5 NON-DESTRUCTIVE INPUT NO WAIT (Char devs only) + 6 INPUT STATUS " " " + 7 INPUT FLUSH " " " + 8 OUTPUT (write) + 9 OUTPUT (Write) with verify + 10 OUTPUT STATUS " " " + 11 OUTPUT FLUSH " " " + 12 IOCTL OUTPUT (Only called if device has IOCTL) + + As mentioned before, the first entry point is the strategy +routine which is called with a pointer to a data block. This +call does not perform the request, all it does is queue it +(save the data block pointer). The second interrupt entry +point is called immediately after the strategy call. The +"interrupt" routine is called with no parameters, its primary +function is to perform the operation based on the queued +data block and set up any returns. + + The "BUILD BPB" and "MEDIA CHECK" are the interesting +new ones, these are explained by examining the sequence of +events in the DOS which occurs when a drive access call (other +than read or write) is made: + + I. Turn drive letter into DPB pointer by looking + for DPB with correct driver-unit number. + + II. Call device driver and request media check for + Drive-Unit. DOS passes its current Media + descriptor byte (from DPB). Call returns: + + Media Not Changed + Media Changed + Not Sure + Error + + Error - If an error occurs the error code should + be set accordingly. + + Media Not changed - Current DPB and media byte + are OK, done. + + Media Changed - Current DPB and media are wrong, + invalidate any buffers for this unit, and + goto III. + + Not Sure - If there are dirty buffers for this + unit, assume DPB and media byte are OK and + done. If nothing dirty, assume media changed, + invalidate any buffers for unit, and goto + III. + + NOTE: If a hybrid DPB was built at init and + an invalid Media byte was set, the driver + should return media changed when this invalid + media byte is encountered. + + III. Call device driver to build BPB with media byte + and buffer. + + What the driver must do at step III is determine the +correct media that is currently in the unit, and return a +pointer to a BPB table (same as for the install call). This +table will be used as at init to build a correct DPB for +the unit If the determined media descriptor byte in the table +turns out to be the same as the one passed in, then the DOS +will not build a new table, but rather just use the old one. +Therefore in this case the driver doesn't have to correctly +fill in the other entries if desired. + + The build BPB call also gets a pointer to a one sector +buffer. What this buffer contains is determined by the NON +IBM FORMAT bit in the attribute field. If the bit is zero +(device is IBM format compatible) then the buffer contains +the first sector of the first FAT, in particular the FAT +ID byte is the first byte of this buffer. NOTE: It must +be true that the BPB is the same, as far as location of the +FAT is concerned, for all possible media. This is because +this first FAT sector must be read BEFORE the actual BPB +is returned. If the NON IBM FORMAT bit is set then the +pointer points to one sector of scratch space which may be +used for anything. + +CALL FORMAT + + When the DOS calls a device driver to perform a finction, +it passes a structure (Drive Request Structure) in ES:BX +to perform operations and does a long call to the driver's +strategy entry point. This structure is a fixed length header +(Static Request Header) followed by data pertinent to the +operation being performed. NOTE: It is the drivers +responsibility to preserve machine state. + +STATIC REQUEST HEADER -> + +-----------------------------+ + | BYTE length of record | + | Length in bytes of this | + | Drive Request Structure | + +-----------------------------+ + | BYTE unit code | + | The subunit the operation | + | is for (minor device) | + | (no meaning on character | + | devices) | + +-----------------------------+ + | BYTE command code | + +-----------------------------+ + | WORD Status | + +-----------------------------+ + | 8 bytes reserved here for | + | two DWORD links. One will | + | be a link for the DOS queue | + | The other for the device | + | queue | + +-----------------------------+ + +STATUS WORD + + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+ + | E | | B | D | | + | R | RESERVED | U | O | ERROR CODE (bit 15 on)| + | R | | I | N | | + +---+---+--+--+--+--+---+---+--+--+--+--+--+--+--+--+ + + The status word is zero on entry and is set by the driver +interrupt routine on return. + + Bit 8 is the done bit, it means the operation is complete. +For the moment the Driver just sets it to one when it exits, +in the future this will be set by the interrupt routine to +tell the DOS the operation is complete. + + Bit 15 is the error bit, if it is set then the low 8 +bits indicate the error: + + 0 Write Protect violation + (NEW) 1 Unknown Unit + 2 Drive not ready + (NEW) 3 Unknown command + 4 CRC error + (NEW) 5 Bad Drive Request Structure length + 6 Seek error + (NEW) 7 Unknown media + 8 Sector not found + (NEW) 9 Printer out of paper + A Write Fault + (NEW) B Read Fault + C General Failure + +Bit 9 is the busy bit which is set only by status calls (see +STATUS CALL below). + + + Here is the data block format for each function: + +READ or WRITE - ES:BX (Including IOCTL) -> + +------------------------------------+ + | 13-BYTE Static Request Header | + +------------------------------------+ + | BYTE Media descriptor from DPB | + +------------------------------------+ + | DWORD transfer address | + +------------------------------------+ + | WORD byte/sector Count | + ---+------------------------------------+--- + | WORD starting sector number | + | (ignored on Char Devs) | + +------------------------------------+ + + In addition to setting the status word, the driver must +set the Sector count to the actual number of sectors (or +bytes) transferred. NOTE: No error check is performed on +an IOCTL I/O call, driver MUST correctly set the return sector +(byte) count to the actual number of bytes transferred, +however. + +NOTE: THE FOLLOWING APPLIES TO BLOCK DEVICE DRIVERS. + + Under certain circumstances the BIOS may be asked to +do a write operation of 64K bytes which seems to be a "wrap +around" of the transfer address in the BIOS I/O packet. This +arises due to an optimization added to the write code in +MS-DOS. It will only manifest on user WRITEs which are within +a sector size of 64K bytes on files which are "growing" past +the current EOF. IT IS ALLOWABLE FOR THE BIOS TO IGNORE +THE BALANCE OF THE WRITE WHICH "WRAPS AROUND" IF IT SO +CHOOSES. For instance a WRITE of 10000H bytes worth of +sectors with a transfer address of XXX:1 could ignore the +last two bytes (remember that a user program can never request +an I/O of more than FFFFH bytes and cannot wrap around (even +to 0) in his transfer segment, so in this case the last two +bytes can be ignored). + + +NON DESRUCTIVE READ NO WAIT - ES:BX -> + +------------------------------------+ + | 13-BYTE Static Request Header | + +------------------------------------+ + | BYTE read from device | + +------------------------------------+ + + This call is analogous to the console input status call +on MS-DOS 1.25. If the character device returns Busy bit += 0 (characters in buffer), then the next character that +would be read is returned. This character is NOT removed +from the input buffer (hence the term Non Destructive Read). +In essence this call allows the DOS to look ahead one input +character. + + +MEDIA CHECK - ES:BX -> + +------------------------------------+ + | 13-BYTE Static Request Header | + +------------------------------------+ + | BYTE Media Descriptor from DPB | + +------------------------------------+ + | BYTE returned | + +------------------------------------+ + + In addition to setting status word, driver must set the +return byte. + + Return Byte : + -1 Media has been changed + 0 Don't know if media has been changed + 1 Media has not been changed + + If the driver can return -1 or 1 (by having a door-lock +or other interlock mechanism) the performance of MSDOS 2.0 +is enhanced as the DOS need not reread the FAT for each +directory access. + + +BUILD BPB - ES:BX -> + +------------------------------------+ + | 13-BYTE Static Request Header | + +------------------------------------+ + | BYTE Media Descriptor from DPB | + +------------------------------------+ + | DWORD Transfer Address | + | (points to one sectors worth of | + | scratch space or first sector | + | of FAT depending on the value | + | of the NON IBM FORMAT bit) | + +------------------------------------+ + | DWORD Pointer to BPB | + +------------------------------------+ + + If the NON IBM FORMAT bit of the device is set, then +the DWORD Transfer Address points to a one sector buffer +which can be used for any purpose. If the NON IBM FORMAT +bit is 0, then this buffer contains the first sector of the +FAT; in this case the driver must not alter this buffer (this +mode is useful if all that is desired is to read the FAT +ID byte). + + If IBM compatible format is used (NON IBM FORMAT BIT += 0), then it must be true that the first sector of the first +FAT is located at the same sector on all possible media. +This is because the FAT sector will be read BEFORE the media +is actually determined. + + In addition to setting status word, driver must set the +Pointer to the BPB on return. + + + In order to allow for many different OEMs to read each +other's disks, the following standard is suggested: The +information relating to the BPB for a particular piece of +media is kept in the boot sector for the media. In +particular, the format of the boot sector is: + + +------------------------------------+ + | 3 BYTE near JUMP to boot code | + +------------------------------------+ + | 8 BYTES OEM name and version | + ---+------------------------------------+--- + B | WORD bytes per sector | + P +------------------------------------+ + B | BYTE sectors per allocation unit | + +------------------------------------+ + | | WORD reserved sectors | + V +------------------------------------+ + | BYTE number of FATs | + +------------------------------------+ + | WORD number of root dir entries | + +------------------------------------+ + | WORD number of sectors in logical | + ^ | image | + | +------------------------------------+ + B | BYTE media descriptor | + P +------------------------------------+ + B | WORD number of FAT sectors | + ---+------------------------------------+--- + | WORD sectors per track | + +------------------------------------+ + | WORD number of heads | + +------------------------------------+ + | WORD number of hidden sectors | + +------------------------------------+ + + The three words at the end are optional, the DOS doesn't +care about them (since they are not part of the BPB). They +are intended to help the BIOS understand the media. Sectors +per track may be redundant (could be figured out from total +size of the disk). Number of heads is useful for supporting +different multi-head drives which have the same storage +capacity, but a different number of surfaces. Number of +hidden sectors is useful for supporting drive partitioning +schemes. + + + Currently, the media descriptor byte has been defined +for a small range of media: + + 5 1/4" diskettes: + + Flag bits: + 01h - on -> 2 double sided + + All other bits must be on. + + 8" disks: + FEh - IBM 3740 format, singled-sided, single-density, + 128 bytes per sector, soft sectored, 4 sectors + per allocation unit, 1 reserved sector, 2 FATs, + 68 directory entries, 77*26 sectors + + FDh - 8" IBM 3740 format, singled-sided, + single-density, 128 bytes per sector, soft + sectored, 4 sectors per allocation unit, 4 + reserved sectors, 2 FATs, 68 directory entries, + 77*26 sectors + + FEh - 8" Double-sided, double-density, 1024 bytes + per sector, soft sectored, 1 sector per allocation + unit, 1 reserved sector, 2 FATs, 192 directory + entries, 77*8*2 sectors + + +STATUS Calls - ES:BX -> + +------------------------------------+ + | 13-BYTE Static Request Header | + +------------------------------------+ + + All driver must do is set status word accordingly and +set the busy bit as follows: + + o For output on character devices: If it is 1 on + return, a write request (if made) would wait for + completion of a current request. If it is 0, there + is no current request and a write request (if made) + would start immediately. + + o For input on character devices with a buffer a return + of 1 means, a read request (if made) would go to + the physical device. If it is 0 on return, then + there are characters in the devices buffer and a + read would return quickly, it also indicates that + the user has typed something. The DOS assumes all + character devices have an input type ahead buffer. + Devices which don't have them should always return + busy = 0 so that the DOS won't hang waiting for + something to get into a buffer which doesn't exist. + + +FLUSH Calls - ES:BX -> + +------------------------------------+ + | 13-BYTE Static Request Header | + +------------------------------------+ + + This call tells the driver to flush (terminate) all +pending requests that it has knowledge of. Its primary use +is to flush the input queue on character devices. + + +INIT - ES:BX -> + +------------------------------------+ + | 13-BYTE Static Request Header | + +------------------------------------+ + | BYTE # of units | + +------------------------------------+ + | DWORD Break Address | + ---+------------------------------------+--- + | DWORD Pointer to BPB array | + | (not set by Character devices) | + +------------------------------------+ + + The number of units, break address, and BPB pointer are +set by the driver. + + +FORMAT OF BPB (Bios Parameter Block) - + + +------------------------------------+ + | WORD Sector size in Bytes | + | Must be at least 32 | + +------------------------------------+ + | BYTE Sectors/Allocation unit | + | Must be a power of 2 | + +------------------------------------+ + | WORD Number of reserved sectors | + | May be zero | + +------------------------------------+ + | BYTE Number of FATS | + +------------------------------------+ + | WORD Number of directory entries | + +------------------------------------+ + | WORD Total number of sectors | + +------------------------------------+ + | BYTE Media descriptor | + +------------------------------------+ + | WORD Number of sectors occupied by | + | FAT | + +------------------------------------+ + + +THE CLOCK DEVICE + + One of the most popular add on boards seems to be "Real +Time CLOCK Boards". To allow these boards to be integrated +into the system for TIME and DATE, there is a special device +(determined by the attribute word) which is the CLOCK device. +In all respects this device defines and performs functions +like any other character device (most functions will be "set +done bit, reset error bit, return). When a read or write +to this device occurs, exactly 6 bytes are transferred. This +I/O can be thought of as transferring 3 words which correspond +exactly to the values of AX, CX and DX which were used in +the old 1.25 DOS date and time routines. Thus the first +two bytes are a word which is the count of days since 1-1-80. +The third byte is minutes, the fourth hours, the fifth +hundredths of seconds, and the sixth seconds. Reading the +CLOCK device gets the date and time, writing to it sets the +date and time. + \ No newline at end of file diff --git a/v2.0/bin/DISKCOPY.COM b/v2.0/bin/DISKCOPY.COM new file mode 100644 index 00000000..ea4e0d2f Binary files /dev/null and b/v2.0/bin/DISKCOPY.COM differ diff --git a/v2.0/bin/DOSPATCH.TXT b/v2.0/bin/DOSPATCH.TXT new file mode 100644 index 00000000..20ebd953 --- /dev/null +++ b/v2.0/bin/DOSPATCH.TXT @@ -0,0 +1,62 @@ +There are three locations in the DOS where OEMs may want to +patch in information specific to their installation. + + +The first is the location of the default switch character. +This character is one byte at DEBUG location 1E5, and is +set to '/'. To change it to '-' (XENIX compatible) +do: + + DEBUG MSDOS.SYS + + >e1e5 + XXXX:01E5 2F. + >w + Writing YYYY Bytes + >q + +If the byte at 1E5 is not 2F, look around in the immediate +vacinity (do d1e0) for it. It is the only 2F in that area. + + +The second is the location of the 24 bit user number and the +8 bit OEM number. These values are returned by the GET_VERSION +system call. +The user number is 3 bytes starting at +debug location 683, The OEM number is one byte at debug location +686. The user number is initialized to 0, the OEM number to -1 +and they immediatly follow the Microsoft Copyright message. If these +bytes are not zero, look for the four bytes following the +Copyright message which should be in the vacinity of 683. +OEMs should request an OEM number from Microsoft if they +want one of their very own, this prevents selecting one someone +else already has. + + +The third is the location of the editing template definitions. +This is a table which defines the two byte edit function keys +for system call 10 and for EDLIN. This table is at debug location +33EA, and should start with a 1B. If the byte at 33EA is not +1B, look around in the immediate vacinity. Here is what the +default table looks like. It is a definition for the Zenith +Z-19 terminal: + +ESCCHAR DB 1BH ;The Escape character, Nul (0) on IBM +ESCTAB: + DB "Z" ;5AH Put a ^Z in the template, F6 on IBM + DB "S" ;53H Copy one char, --> on IBM + DB "V" ;56H Skip one char, DEL on IBM + DB "T" ;54H Copy to char, F2 on IBM + DB "W" ;57H Skip to char, F4 on IBM + DB "U" ;55H Copy line, F3 on IBM + DB "E" ;45H Kill line, Not used on IBM + DB "J" ;4AH Reedit line, F5 on IBM + DB "D" ;44H Backspace, <-- on IBM + DB "P" ;50H Toggle insert mode, INS on IBM + DB "Q" ;51H Toggle insert mode, INS on IBM + DB "R" ;52H Escape char, F7 on IBM + DB "R" ;52H End of table, must be same as previos character + + \ 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 00000000..81e097b9 Binary files /dev/null and b/v2.0/bin/EDLIN.COM differ diff --git a/v2.0/bin/EXE2BIN.EXE b/v2.0/bin/EXE2BIN.EXE new file mode 100644 index 00000000..f4b0dd75 Binary files /dev/null and b/v2.0/bin/EXE2BIN.EXE differ diff --git a/v2.0/bin/FC.EXE b/v2.0/bin/FC.EXE new file mode 100644 index 00000000..aa06624e Binary files /dev/null and b/v2.0/bin/FC.EXE differ diff --git a/v2.0/bin/FILBP.PAS b/v2.0/bin/FILBP.PAS new file mode 100644 index 00000000..71decc88 Binary files /dev/null and b/v2.0/bin/FILBP.PAS differ diff --git a/v2.0/bin/FIND.EXE b/v2.0/bin/FIND.EXE new file mode 100644 index 00000000..b5d07d00 Binary files /dev/null and b/v2.0/bin/FIND.EXE differ diff --git a/v2.0/bin/FORMAT.DOC b/v2.0/bin/FORMAT.DOC new file mode 100644 index 00000000..ab47f54d --- /dev/null +++ b/v2.0/bin/FORMAT.DOC @@ -0,0 +1,393 @@ +FORMAT - formats a new disk, clears the FAT and DIRECTORY +and optionally copies the SYSTEM and COMMAND.COM to this +new disk. + +Command syntax: + + FORMAT [drive:][/switch1][/switch2]...[/switch16] + + Where "drive:" is a legal drive specification and if + omitted indicates that the default drive will be used. + There may be up to 16 legal switches included in the + command line. + + + The OEM must supply five (NEAR) routines to the program +along with 6 data items. The names of the routines are INIT, +DISKFORMAT, BADSECTOR, WRTFAT and DONE, and their flow of +control (by the Microsoft module) is like this: + + | + +---------+ + | INIT | + +---------+ + | + |<------------------------------+ ++------------+ | +| DISKFORMAT | | ++------------+ | + |<-------+ | ++-----------+ |-This loop is done |- This loop done +| BADSECTOR | | for each group of | once for each disk ++-----------+ | bad sectors | to be formatted. + |----->--+ | If variable HARDFLAG + | | is set then the loop ++----------+ | is only performed +| | | once. +| WRTFAT | | ++----------+ | + | | + +------+ | + | DONE | | + +------+ | + +---->--------------------------+ + + The INIT, DISKFORMAT, and BADSECTOR routines are free +to use any MS-DOS system calls, except for calls that cause +disk accesses on the disk being formatted. DONE may use +ANY calls, since by the time it is called the new disk has +been formatted. + +The following data must be declared PUBLIC in a module +provided by the OEM: + + SWITCHLIST - A string of bytes. The first byte is count + N, followed by N characters which are the switches to + be accepted by the command line scanner. Alphabetic + characters must be in upper case (the numeric + characters 0-9 are allowed). The last three switches, + normally "O", "V" and "S", have pre-defined meanings. + + The "S" switch is the switch which causes the + system files IO.SYS, MSDOS.SYS, and COMMAND.COM to be + transfered to the disk after it is formatted thus + making a "S"ystem disk. The switch can be some letter + other than "S", but the last switch in the list is + assumed to have the meaning "transfer system", + regardles of what the particular letter is. + + The second to the last switch, "V", causes FORMAT + to prompt the user for a volume label after the disk + is formatted. Again, as with "S", the particular + letter is not important but rather the position in the + list. + + The third to the last switch, "O", causes FORMAT to + produce an IBM Personal Computer DOS version 1.X + compatible disk. Normally FORMAT causes a 0 byte to + be placed in the first byte of each directory entry + instead of the 0E5 Hex free entry designator. This + results in a very marked directory search performance + increase due to an optimization in the DOS. Disks + made this way cause trouble on IBM PC DOS 1.X + versions, however, which did not have this + optimization. The 0 byte fools IBM 1.X versions into + thinking these entries are allocated instead of free, + NOTE that IBM Personnal Computer DOS version 2.00 and + MS-DOS version 1.25 will have no trouble with these + disks, since they have the same optimization. The "O" + switch causes FORMAT to re-do the directory with a 0E5 + Hex byte at the start of each entry so that the disk + may be used with 1.X versions of IBM PC DOS, as well + as MS-DOS 1.25/2.00 and IBM PC DOS 2.00. This switch + should only be given when needed because it takes a + fair amount of time for FORMAT to perform the + conversion, and it noticably decreases 1.25 and 2.00 + performance on disks with few directory entries. + + Up to 16 switches are permitted. Normally a "C" + switch is specified for "Clear". This switch should + cause the formatting operation to be bypassed (within + DISKFORMAT or BADSECTOR). This is provided as a + time-saving convenience to the user, who may wish + to "start fresh" on a previosly formatted and used + disk. + + HARDFLAG - BYTE location which specifies whether the + OEM routine is formatting a fixed disk or a a drive + with removable media. A zero indicates removable + media, any other value indicates a fixed disk. The + status of this byte only effect the messages printed + by the main format module. This value should be + set or reset by the OEM supplied INIT routine. + + FATID - BYTE location containing the value to be used + in the first byte of the FAT. Must be in the range + F8 hex to FF hex. + + STARTSECTOR - WORD location containing the sector number + of the first sector of the data area. + + FATSPACE - WORD location containing the address of the + start of the FAT area. A FAT built in this area + will be written to disk using the OEM supplied WRTFAT + subroutine. 6k is sufficient to store any FAT. This + area must not overlap the FREESPACE area. + + FREESPACE - WORD location which contains the address + of the start of free memory space. This is where + the system will be loaded, by the Microsoft module, + for transferring to the newly formatted disk. Memory + should be available from this address to the end + of memory, so it is typically the address of the + end of the OEM module. + +The following routines must be declared PUBLIC in the +OEM-supplied module: + + INIT - An initialization routine. This routine is called + once at the start of the FORMAT run after the switches + have been processed. This routine should perform + any functions that only need to be done once per + FORMAT run. An example of what this routine might + do is read the boot sector into a buffer so that + it can be transferred to the new disks by DISKFORMAT. + If this routine returns with the CARRY flag set it + indicates an error, and FORMAT will print "Format + failure" and quit. This feature can be used to detect + conflicting switches (like specifying both single + and double density) and cause FORMAT to quit without + doing anything. + + DISKFORMAT - Formats the disk according to the options + indicated by the switches and the value of FATID + must be defined when it returns (although INIT may + have already done it). This routine is called once + for EACH disk to be formatted. If neccessary it + must transfer the Bootstrap loader. If any error + conditions are detected, set the CARRY flag and return + to FORMAT. FORMAT will report a 'Format failure' + and prompt for another disk. (If you only require + a clear directory and FAT then simply setting the + appropriate FATID, if not done by INIT, will be all + that DISKFORMAT must do.) + + BADSECTOR - Reports the sector number of any bad sectors + that may have been found during the formatting of + the disk. This routine is called at least once for + EACH disk to be formatted, and is called repeatedly + until AX is zero or the carry flag is set. The carry + flag is used just as in DISKFORMAT to indicate an + error, and FORMAT handles it in the same way. The + first sector in the data area must be in STARTSECTOR + for the returns from this routine to be interpreted + correctly. If there are bad sectors, BADSECTOR must + return a sector number in in register BX, the number + of consecutive bad sectors in register AX, and carry + clear. FORMAT will then process the bad sectors + and call BADSECTOR again. When BADSECTOR returns + with AX = 0 this means there are no more bad sectors; + FORMAT clears the directory and goes on to DONE, + so for this last return BX need not contain anything + meaningful. + + FORMAT processes bad sectors by determining their + corresponding allocation unit and marking that unit + with an FF7 hex in the File Allocation Table. CHKDSK + understands the FF7 mark as a flag for bad sectors + and accordingly reports the number of bytes marked + in this way. + + NOTE: Actual formatting of the disk can be done in + BADSECTOR instead of DISKFORMAT on a "report as you + go" basis. Formatting goes until a group of bad + sectors is encountered, BADSECTOR then reports them + by returning with AX and BX set. FORMAT will then + call BADSECTOR again and formatting can continue. + + WRTFAT - This routine is called after the disk is + formatted and bad sectors have been reported. Its + purpose is to write all copies of the FAT from the + area of memory referenced by FATSPACE to the drive + just formatted. It may be possible to use INT 26H + to perform the write, or a direct BIOS call. Whether + this is possible depends on whether the FAT ID byte + is used by the BIOS to determine the media in the + drive. If it is, these methods will probably fail + because there is no FAT ID byte on the disk yet (in + this case WRTFATs primary job is to get the FAT ID + byte out on the disk and thus solve the chicken and + egg problem). + + DONE - This routine is called after the formatting is + complete, the disk directory has been initialized, + and the system has been transferred. It is called + once for EACH disk to be formatted. This gives the + chance for any finishing-up operations, if needed. + If the OEM desires certain extra files to be put + on the diskette by default, or according to a switch, + this could be done in DONE. Again, as in BADSECTOR + and DISKFORMAT, carry flag set on return means an + error has occurred: 'Format failure' will be printed + and FORMAT will prompt for another disk. + + +The following data is declared PUBLIC in Microsoft's FORMAT +module: + + SWITCHMAP - A word with a bit vector indicating what + switches have been included in the command line. The + correspondence of the bits to the switches is + determined by SWITCHLIST. The right-most + (highest-addressed) switch in SWITCHLIST (which must + be the system transfer switch, normally "S") + corresponds to bit 0, the second from the right, + normally "V" to bit 1, etc. For example, if + SWITCHLIST is the string "7,'AGI2OVS'", and the user + specifies "/G/S" on the command line, then bit 6 will + be 0 (A not specified), bit 5 will be 1 (G specified), + bits 4,3,2 and 1 will be 0 (neither I,2,O or V + specified), and bit 0 will be 1 (S specified). + + Bits 0,1 and 2 are the only switches used in + Microsoft's FORMAT module. These switches are used 1) + after INIT has been called, to determine if it is + necessary to load the system; 2) after the last + BADSECTOR call, to determine if the system is to be + written, E5 directory conversion is to be done, and/or + a volume label is to be asked for. INIT may force + these bits set or reset if desired (for example, some + drives may never be used as system disk, such as hard + disks). After INIT, the "S" bit may be turned off + (but not on, since the system was never read) if + something happens that means the system should not be + transferred. + + After INIT, a second copy of SWITCHMAP is made + internally which is used to restore SWITCHMAP for + each disk to be formatted. FORMAT itself will turn + off the system bit if bad sectors are reported in + the system area; DISKFORMAT and BADSECTOR are also + allowed to change the map. However, these changes + affect only the current disk being formatted, since + SWITCHMAP is restored after each disk. (Changes + made to SWITCHMAP by INIT do affect ALL disks.) + + DRIVE - A byte containing the drive specified in the + command line. 0=A, 1=B, etc. + +Once the OEM-supplied module has been prepared, it must linked +with Microsoft's FORMAT.OBJ module and the FORMES.OBJ module. +If the OEM-supplied module is called OEMFOR.OBJ, then the +following linker command will do: + + LINK FORMAT FORMES OEMFOR; + +This command will produce a file called FORMAT.EXE. FORMAT +has been designed to run under MS-DOS as a simple binary +.COM file. This conversion is performed by LOCATE (EXE2BIN) +with the command + + LOCATE FORMAT.EXE FORMAT.COM + +which will produce the file FORMAT.COM. + +;***************************************** +; +; A Sample OEM module +; +;***************************************** + +CODE SEGMENT BYTE PUBLIC 'CODE' +; This segment must be +; named CODE, it must be +; PUBLIC, and it's +; classname must be 'CODE' + + + ASSUME CS:CODE,DS:CODE,ES:CODE + +; Must declare data and routines PUBLIC + +PUBLIC FATID,STARTSECTOR,SWITCHLIST,FREESPACE +PUBLIC INIT,DISKFORMAT,BADSECTOR,DONE,WRTFAT +PUBLIC FATSPACE,HARDFLAG + +; This data defined in Microsoft-supplied module + + EXTRN SWITCHMAP:WORD,DRIVE:BYTE + +INIT: + +; Read the boot sector into memory + CALL READBOOT + ... +; Set FATID to double sided if "D" switch specified + TEST SWITCHMAP,10H + JNZ SETDBLSIDE + ... + RET + +DISKFORMAT: + ... + +; Use the bit map in SWITCHMAP to determine +; what switches are set + + TEST SWITCHMAP,8 ;Is there a "/C"? + JNZ CLEAR ; Yes -- clear operation + ; requested jump around the + ; format code + < format the disk > +CLEAR: + ... +; Transfer the boot from memory to the new disk + CALL TRANSBOOT + ... + RET + +; Error return - set carry + +ERRET: + STC + RET + +BADSECTOR: + ... + RET + + +WRTFAT: + ... + +WRTFATLOOP: + < Set up call to write out a fat to disk> + ... + MOV BX,[FATSPACE] + + < Write out one fat to disk> + JC ERRET + ... + < Decrement fat counter > + JNZ WRTFATLOOP + CLC ;Good return + RET + + +DONE: + ... + RET + +; Default Single sided +FATID DB 0FEH + +HARDFLAG DB 0 + +STARTSECTOR DW 9 + +SWITCHLIST DB 5,"DCOVS" ; "OVS" must be the last + ; switches in the list + +FATSPACE DW FATBUF + +FREESPACE DW ENDBOOT + +BOOT DB BOOTSIZE DUP(?) ; Buffer for the + ; boot sector + +FATBUF DB 6 * 1024 DUP(?) ; Fat buffer +ENDBOOT LABEL BYTE + +CODE ENDS + END + \ No newline at end of file diff --git a/v2.0/bin/FORMAT.OBJ b/v2.0/bin/FORMAT.OBJ new file mode 100644 index 00000000..61fe1070 Binary files /dev/null and b/v2.0/bin/FORMAT.OBJ differ diff --git a/v2.0/bin/FORMES.OBJ b/v2.0/bin/FORMES.OBJ new file mode 100644 index 00000000..247f39e8 Binary files /dev/null and b/v2.0/bin/FORMES.OBJ differ diff --git a/v2.0/bin/INCOMP.DOC b/v2.0/bin/INCOMP.DOC new file mode 100644 index 00000000..6c187b62 Binary files /dev/null and b/v2.0/bin/INCOMP.DOC differ diff --git a/v2.0/bin/INT24.DOC b/v2.0/bin/INT24.DOC new file mode 100644 index 00000000..d38d6fa8 Binary files /dev/null and b/v2.0/bin/INT24.DOC differ diff --git a/v2.0/bin/LINK.EXE b/v2.0/bin/LINK.EXE new file mode 100644 index 00000000..aa58151c Binary files /dev/null and b/v2.0/bin/LINK.EXE differ diff --git a/v2.0/bin/MASM.EXE b/v2.0/bin/MASM.EXE new file mode 100644 index 00000000..d43bfb75 Binary files /dev/null and b/v2.0/bin/MASM.EXE differ diff --git a/v2.0/bin/MORE.COM b/v2.0/bin/MORE.COM new file mode 100644 index 00000000..b28f8070 Binary files /dev/null and b/v2.0/bin/MORE.COM differ diff --git a/v2.0/bin/MSDOS.SYS b/v2.0/bin/MSDOS.SYS new file mode 100644 index 00000000..803eb700 Binary files /dev/null and b/v2.0/bin/MSDOS.SYS differ diff --git a/v2.0/bin/PRINT.COM b/v2.0/bin/PRINT.COM new file mode 100644 index 00000000..b2788d37 Binary files /dev/null and b/v2.0/bin/PRINT.COM differ diff --git a/v2.0/bin/PROFIL.OBJ b/v2.0/bin/PROFIL.OBJ new file mode 100644 index 00000000..66946b38 Binary files /dev/null and b/v2.0/bin/PROFIL.OBJ differ diff --git a/v2.0/bin/PROFILE.DOC b/v2.0/bin/PROFILE.DOC new file mode 100644 index 00000000..2d50631b Binary files /dev/null and b/v2.0/bin/PROFILE.DOC differ diff --git a/v2.0/bin/PROHST.EXE b/v2.0/bin/PROHST.EXE new file mode 100644 index 00000000..dfa8983f Binary files /dev/null and b/v2.0/bin/PROHST.EXE differ diff --git a/v2.0/bin/PROHST.PAS b/v2.0/bin/PROHST.PAS new file mode 100644 index 00000000..4ee13fc6 --- /dev/null +++ b/v2.0/bin/PROHST.PAS @@ -0,0 +1,403 @@ +PROGRAM prohst(input,output); +{$debug- $line- $symtab+} + +{**********************************************************************} +{* *} +{* prohst *} +{* *} +{* This program produces a histogram from the profile file produced *} +{* by the MS-DOS profile utility. It optionally reads the map file *} +{* generated when the program being profiled was linked, and writes *} +{* either the module address or, if available, the line number as *} +{* a prefix to the line of the graph which describes a particular *} +{* bucket. *} +{* *} +{* After using filbm (derived from the Pascal and Fortran front end *} +{* command scanner) to parse its parameters, prohst opens the map *} +{* file if specified, searches for the heading line, and then reads *} +{* the lines giving the names and positions of the modules. It builds *} +{* a linked list of module names and start addresses. *} +{* *} +{* It then reads the bucket file header and and bucket array elements *} +{* into a variable created on the heap. It simultaneously calculates *} +{* a normalization factor. It writes the profile listing header and *} +{* starts to write the profile lines. For each bucket, the address *} +{* is calculated. The first entry in the address/name linked list *} +{* is the lowest addressed module. This is initially the 'current' *} +{* module. The bucket address is compared with the current module *} +{* address. When it becomes the greater, the module name is written *} +{* to the listing and the next entry in the address/name list becomes *} +{* the current module. If line numbers are available, the bucket *} +{* address is also compared to the current line/address. This is *} +{* read and calculated directly from the file. Since there may be *} +{* more than one line per bucket, several entries may be read until *} +{* the addresses compare within the span of addresses encompassed by *} +{* a bucket (its 'width'). Note that the idiosyncracies of Pascal i/o *} +{* make it necessary to continually check for the end of the map file *} +{* and the complexity of this code is mainly due to an attempt to *} +{* make it reasonably resilient to changes in the format of the map *} +{* file. *} +{* *} +{**********************************************************************} + + +CONST + max_file = 32; + + +TYPE + filenam = LSTRING (max_file); + sets = SET OF 0..31; + address_pointer = ^address_record; + address_record = RECORD + next: address_pointer; + name: STRING (15); + address: WORD; + END; + + + + + +VAR + + i: INTEGER; + bucket: FILE OF WORD; + hist: TEXT; + map: TEXT; + + first_address, + this_address: address_pointer; + current_base: WORD; + bucket_name, + hist_name, + map_name: filenam; + + switches: sets; + + line: LSTRING (100); + + map_avail: BOOLEAN; + line_nos_avail: BOOLEAN; + + norm: REAL; + per_cent: INTEGER; + real_bucket, + norm_bucket: REAL; + cum_per_cent, + real_per_cent: REAL; + + bucket_num, + clock_grain, + bucket_size, + prog_low_pa, + prog_high_pa, + dos_pa, + hit_io, + hit_dos, + hit_high: WORD; + + seg, + offset, + parcel: WORD; + + address: WORD; + new_line_no, + line_no: WORD; + + dummy : LSTRING (8); + name: LSTRING (20); + line_no_part: LSTRING (17); + start: LSTRING (6); + + buckets: ^SUPER ARRAY [1 .. *] OF REAL; + + this_bucket: WORD; + +LABEL 1; + + +PROCEDURE filbm (VAR prffil, hstfil, mapfil: filenam; + VAR switches: sets); EXTERN; + +FUNCTION realword (w: WORD): REAL; +BEGIN + IF ORD (w) < 0 THEN BEGIN + realword := FLOAT (maxint) + FLOAT (ORD (w - maxint)); + END + ELSE BEGIN + realword := FLOAT (ORD(w)); + END {IF}; +END {realword}; + + + +PROCEDURE skip_spaces; +BEGIN + WHILE NOT eof(map) AND THEN map^ = ' ' DO BEGIN + get (map); + END {WHILE}; +END {skip_spaces}; + + +FUNCTION hex_char (ch: CHAR): WORD; +BEGIN + IF ch >= '0' AND THEN ch <= '9' THEN BEGIN + hex_char := WRD (ch) - WRD ('0'); + END + ELSE IF ch >= 'A' AND THEN ch <= 'F' THEN BEGIN + hex_char := WRD (ch) - WRD ('A') + 10; + END + ELSE BEGIN + WRITELN ('Invalid hex character'); + hex_char := 0; + END {IF}; +END {hex_char}; + + +FUNCTION read_hex (i :WORD): WORD; +VAR + hex_val: WORD; +BEGIN + skip_spaces; + hex_val := 0; + WHILE NOT eof (map) AND THEN i <> 0 DO BEGIN + hex_val := hex_val * 16 + hex_char (map^); + GET (map); + i := i - 1; + END {WHILE}; + read_hex := hex_val; +END {read_hex}; + +FUNCTION read_h: WORD; +BEGIN + read_h := read_hex (4); + get (map); + get (map); +END; + +FUNCTION read_word: WORD; +VAR + int_value: WORD; +BEGIN + int_value := 0; + IF NOT EOF (map) THEN BEGIN + READ (map, int_value); + END {IF}; + read_word := int_value; +END {read_word}; + + +FUNCTION map_digit: BOOLEAN; +BEGIN + map_digit := (map^ >= '0') OR (map^ <= '9'); +END {map_digit}; + +BEGIN {prohst} + writeln (output, ' Profile Histogram Utility - Version 1.0'); + writeln (output); + writeln (output, ' Copyright - Microsoft, 1983'); + + start := ' '; + + filbm (bucket_name, hist_name, map_name, switches); + + IF 31 IN switches THEN BEGIN + ABORT ('Map file must not be terminal', 0, 0); + END {IF}; + + IF NOT (28 IN switches) THEN BEGIN + ABORT ('No histogram file specified', 0, 0); + END {IF}; + + ASSIGN (bucket, bucket_name); + reset (bucket); + ASSIGN (hist, hist_name); + rewrite (hist); + + map_avail := 29 IN switches; + line_nos_avail := FALSE; + + IF map_avail THEN BEGIN + ASSIGN (map, map_name); + RESET (map); + + WHILE NOT EOF (map) AND THEN start <> ' Start' DO BEGIN + READLN (map, start); + END {WHILE}; + + NEW (first_address); + this_address := NIL; + + WHILE NOT EOF(map) DO BEGIN + READLN (map, line); + IF line.len < 6 OR ELSE line [2] < '0' OR ELSE + line [2] > '9' THEN BEGIN + BREAK; + END {IF}; + + IF this_address <> NIL THEN BEGIN + NEW (this_address^.next); + this_address := this_address^.next; + END + ELSE BEGIN + this_address := first_address; + END {IF}; + this_address^.next := NIL; + + this_address^.address := (hex_char (line [2]) * 4096) + + (hex_char (line [3]) * 256) + + (hex_char (line [4]) * 16) + + hex_char (line [5]); + + FOR i := 1 TO 15 DO BEGIN + this_address^.name [i] := line [22 + i]; + END {FOR}; + + END {WHILE}; + + WHILE NOT EOF (map) DO BEGIN + READLN (map, line_no_part); + IF line_no_part = 'Line numbers for ' THEN BEGIN + line_nos_avail := TRUE; + BREAK; + END {IF}; + END {WHILE}; + + END {IF}; + + read (bucket, clock_grain, bucket_num, bucket_size, + prog_low_pa, prog_high_pa, dos_pa, hit_io, hit_dos, hit_high); + + NEW (buckets,ORD (bucket_num)); + + norm := 0.0; + norm_bucket := 0.0; + + FOR i := 1 TO ORD (bucket_num) DO BEGIN + read (bucket, this_bucket); + real_bucket := realword (this_bucket); + + IF real_bucket > norm_bucket THEN BEGIN + norm_bucket := real_bucket; + END {IF}; + + norm := norm + real_bucket; + buckets^[i] := real_bucket; + END {FOR}; + norm_bucket := 45.0/norm_bucket; + norm := 100.0/norm; + + WRITELN (hist, 'Microsoft Profiler Output Listing'); + + WRITELN (hist); + WRITELN (hist, ORD (bucket_num):6, bucket_size:4,'-byte buckets.'); + + WRITELN (hist); + WRITELN (hist, 'Profile taken between ', prog_low_pa*16::16, + ' and ', prog_high_pa*16::16, '.'); + + WRITELN (hist); + WRITELN (hist, 'DOS program address:', dos_pa::16); + + WRITELN (hist); + WRITELN (hist, 'Number of hits in DOS: ', hit_dos:5, + ' or ', realword (hit_dos) * norm:4:1, '%.'); + WRITELN (hist, 'Number of hits in I/O: ', hit_io:5, + ' or ', realword (hit_io) * norm:4:1, '%.'); + WRITELN (hist, 'Number of hits high : ', hit_high:5, + ' or ', realword (hit_high) * norm:4:1, '%.'); + WRITELN (hist); + WRITELN (hist, ' Hits Addr. Line/ Cumul. % 0.0 ', + ' ', + 1.0/norm:1:1); + + WRITELN (hist, ' Offset +----------------', + '----------------------------'); + WRITELN (hist, name); + i := 0; + parcel := 0; + current_base := 0; + line_no := 0; + new_line_no := 0; + cum_per_cent := 0.0; + + WHILE i < ORD (bucket_num) DO BEGIN + i := i + 1; + IF buckets^[i] < 0.9 THEN BEGIN + WRITELN (hist); + REPEAT + i := i + 1; + UNTIL (i = ORD (bucket_num)) OR ELSE buckets^[i] > 0.0; + END {IF}; + + address := bucket_size * (WRD (i) - 1); + + WHILE map_avail AND THEN + address >= first_address^.address DO BEGIN + WRITELN (hist, ' ', first_address^.name); + current_base := first_address^.address; + first_address := first_address^.next; + END {WHILE}; + + WHILE line_nos_avail AND THEN NOT eof (map) AND THEN + address >= parcel DO BEGIN + skip_spaces; + WHILE (map^ < '0') OR (map^ > '9') DO BEGIN + + IF EOF (map) THEN BEGIN + goto 1; + END {IF}; + READLN (map); + skip_spaces; + END {WHILE}; + + + line_no := new_line_no; + new_line_no := read_word; + seg := read_hex (4); + IF EOF (map) THEN BEGIN + GOTO 1; + END {IF}; + IF map^ <> ':' THEN BEGIN + WRITELN ('Invalid map file'); + END {IF}; + get (map); + IF EOF (map) THEN BEGIN + GOTO 1; + END {IF}; + offset := read_hex (3) + WRD (hex_char (map^) > 0); + get (map); + IF map^ <> 'H' THEN BEGIN + WRITELN ('Invalid map file'); + END {IF}; + IF EOF (map) THEN BEGIN + GOTO 1; + END {IF}; + get (map); + parcel := seg + offset; + END {WHILE}; +1: real_per_cent := buckets^[i] * norm; + cum_per_cent := cum_per_cent + real_per_cent; + per_cent := ROUND ( buckets^[i] * norm_bucket); + + WRITE (hist, buckets^ [i]:6:0, ' ', + address*16:6:16); + IF line_no <> 0 THEN BEGIN + WRITE (hist, line_no:6); + line_no := 0; + END + ELSE IF map_avail AND THEN first_address <> NIL THEN BEGIN + WRITE (hist, ' #', address - first_address^.address:4:16); + END + ELSE BEGIN + WRITE (hist, ' '); + END {IF}; + + WRITELN (hist, ' ', cum_per_cent:5:1, ' ', real_per_cent:4:1, ' |', + '*': per_cent); + END {WHILE}; + WRITELN (hist, ' +-----------------', + '------------------'); +END. + \ No newline at end of file diff --git a/v2.0/bin/QUICK.DOC b/v2.0/bin/QUICK.DOC new file mode 100644 index 00000000..d443b8ed Binary files /dev/null and b/v2.0/bin/QUICK.DOC differ diff --git a/v2.0/bin/README.DOC b/v2.0/bin/README.DOC new file mode 100644 index 00000000..c5bbf256 --- /dev/null +++ b/v2.0/bin/README.DOC @@ -0,0 +1,177 @@ + MSDOS 2.0 RELEASE + + +The 2.0 Release of MSDOS includes five 5 1/4 double density single sided +diskettes or three 8 iinch CP/M 80 format diskettes. + +The software/documentation on the five inch diskettes is arranged +as follows: + +1. DOS distribution diskette. This diskette contains files which + should be distriibuted to all users. This allows the DOS distri- + bution diskette to meet the requirements of users of high level + language compilers as well as users running only applications. + Many compilers marketed independently through the retail channel + (including those of Microsoft) assume LINK comes with the DOS, as + in the case of IBM. How you choose to distrubute BASIC (contracted + for separately) is up to you. + +2. Assembly Language Development System diskette. This diskette + contains files of interest to assembly language programmers. + High level language programmers do not need these programs unless + they are writing assembly language subroutines. IBM chose to + unbundle this package from the DOS distribution diskette (except + for DEBUG), but you do not have to do so. + +3. PRINT and FORMAT diskette. This diskette contains .ASM source + files which are necessary to assemble the print spooler, which you + may wish to customize for greater performance. .OBJ files are also + included for the FORMAT utility. + +4. Skeltal BIOS and documentation diskette. This diskette contains + the skeltal BIOS source code and the SYSINIT and SYSIMES object + modules which must be linked with your BIOS module. The proper + sequence for linking is BIOS - SYSINIT - SYSIMES. + A profiler utiliity is also included on the diskette, but this + is not intended for end-users. This is distributed for use by + your development staff only and is not supported by Microsoft + If you do decide to distribute it, it is at your own risk! + + +5. Documentation. Features of 2.0 are documented on this disk. + +The user manual contains some significant errors. Most of these are +due to last minute changes to achieve a greater degree of compatibility +with IBM's implementation of MS-DOS (PC DOS). This includes the use +of "\" instead of "/" as the path separator, and "/" instead of "-" +as the switch character. For transporting of batch files across +machines, Microsoft encourages the use of "\" and "/" respectively +in the U.S. market. (See DOSPATCH.TXT for how you can overide this. +The user guide explains how the end-user can override this in CONFIG.SYS). +Both the printer echo keys and insert mode keys have now been made to +toggle. The default prompt (this may also be changed by the user +with the PROMPT command) has been changed from "A:" to "A>". +We apologize for any inconveniences these changes may have caused +your technical publications staff. + + +Here is what you need to do to MSDOS 2.0 to create a shipable product: +(see "Making a Bootable Diskette" below) + +1. BIOS. If you have developed a BIOS for the Beta Test 2.0 version + You should link your BIOS module to SYSINIT.OBJ and SYSIMES.OBJ. + You must modify your BIOS to accomodate the call back to the BIOS + at the end of SYSINIT. If you have no need for this call, simply + find a far RET and label it RE_INIT and declare it public. + An example of this can be found in the skeletal BIOS. In addition + please add support for the new fast console output routine as + described in the device drivers document. We strongly recommend + that you adapt the standard boot sector format also described in + device drivers. Once again, please refer to the skeletal BIOS. + If you have not yet implemented version 2.0 please read the device + drivers document. Microsoft strongly recommends that machines + incorporating integrated display devices with memory mapped video + RAM implement some sort of terminal emulations through the use of + escape sequences. The skeletal BIOS includes a sample ANSI + terminal driver. + +2. Please refer to DOSPATCH.TXT for possible changes you might wish + to make. We strongly recommend that you not patch the switch + characters for the U.S. market. Your one byte serial number + will be issued upon signing the license agreement. Please patch + the DOS accordingly. If you wish to serialize the DOS, this is + described in DOSPATCH.TXT. Please patch the editing template + definitions. Please note the addition of the Control-Z entry + at the beginning of the table. Also note that the insert switches + have now both been made to toggle. + +3. Utilities. FORMAT must be configured for each specific system. + GENFOR is a generic example of a system independent format module, + but it is not recommended that this be distributed to your customers. + Link in the following order: FORMAT, FORMES, (your format module). + The print spooler is distributed as an executable file, which only + prints during wait for keyboard input. If you wish with your + implementation to steal some compute time when printing as well, + you will need to customize it and reassemble. Please note that + you can use a printer-ready or timer interrupt. The former is more + efficient, but ties the user to a specific device. Sample code + is conditionaled out for the IBM PC timer interrupt. + +The following problems are known to exist: + +1. Macro assembler does not support the initialization of 10-byte + floating point constants in 8087 emulation mode - the last two bytes + are zero filled. + +2. LIB has not been provided. The version which incorporates support + for 2.0 path names will be completed in a couple of weeks. The + 1.x version should work fine if you cannot wait. Because the library + manager acts as a counterpart to the linker, we recommend that it + be distributed with the DOS distribution diskette as opposed to the + assembly language development system. + +3. International (French, German, Japanese, and U.K.) versions will be + available in several months. + +4. COMMAND.ASM is currently too large to assemble on a micro. It is + being broken down into separate modules so it can be asembled on + a machine. Source licensees should realize that the resultant + binaries from the new version will not correspond exactly to the + old version. + +5. If you have any further questions regarding the MSDOS 2.0 distribution + please contact Don Immerwahr (OEM technical support (206) 828-8086). + + + Sincerely yours, + + + Chris Larson + MS-DOS Product Marketing Manager + (206) 828-8080 + + + + BUILDING A BOOTABLE (MSDOS FORMAT) DISKETTE + + +1. In implementing MSDOS on a new machine, it is highly recommended + that an MSDOS machine be available for the development. + Please note that utilities shipped with MSDOS 2.0 use MSDOS 2.0 + system calls and WILL NOT not run under MSDOS 1.25. + +2. Use your MSDOS development machine and EDLIN or a word processor + package to write BOOT.ASM, your bootstrap loader BIOS.ASM and + your Format module. + +3. Use MASM, the Microsoft Macro-86 Assembler, to assemble these + modules. LINK is then used to link together the .OBJ modules in + the order specified. + +4. Link creates .EXE format files which are not memory image files + and contain relocation information in their headers. Since your + BIOS and BOOT routines will not be loaded by the EXE loader in + MSDOS, they must first be turned into memory image files by + using the EXE2BIN utility. + +5. The easiest thing to do is to (using your development machine) + FORMAT a single sided diskette without the system. Use DEBUG + to load and write your BOOT.COM bootstrap loader to the BOOT + sector of that diskette. You may decide to have your bootstrap + load BIOS and let the BIOS load MSDOS or it may load both. Note that + the Bootstrap loader will have to know physically where to go on + the disk to get the BIOS and the DOS. COMMAND.COM is loaded + by the SYSINIT module. + +6. Use the COPY command to copy your IO.SYS file (what the + BIOS-SYSINIT-SYSIMES module is usually called) onto the disk + followed by MSDOS.SYS and COMMAND.COM. You may use DEBUG + to change the directory attribute bytes to make these files hidden. + +CAUTION: + +At all times, the BIOS writer should be careful to preserve the state +of the DOS - including the flags. You should be also be cautioned that +the MSDOS stack is not deep. You should not count on more than one or +two pushes of the registers. + \ No newline at end of file diff --git a/v2.0/bin/RECOVER.COM b/v2.0/bin/RECOVER.COM new file mode 100644 index 00000000..fa51faef Binary files /dev/null and b/v2.0/bin/RECOVER.COM differ diff --git a/v2.0/bin/SORT.EXE b/v2.0/bin/SORT.EXE new file mode 100644 index 00000000..9e2c19a5 Binary files /dev/null and b/v2.0/bin/SORT.EXE differ diff --git a/v2.0/bin/SYS.COM b/v2.0/bin/SYS.COM new file mode 100644 index 00000000..2d315d73 Binary files /dev/null and b/v2.0/bin/SYS.COM differ diff --git a/v2.0/bin/SYSCALL.DOC b/v2.0/bin/SYSCALL.DOC new file mode 100644 index 00000000..26d47296 --- /dev/null +++ b/v2.0/bin/SYSCALL.DOC @@ -0,0 +1,1657 @@ + + + + + + + + + + + + + + + + + + + MS-DOS 2.0 + + System Calls Reference + + + + + + + + + + + + ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| | +| C A V E A T P R O G R A M M E R | +| | +| Certain structures, constants and system calls below | +| are private to the DOS and are extremely | +| version-dependent. They may change at any time at the | +| implementors' whim. As a result, they must not be | +| documented to the general public. If an extreme case | +| arises, they must be documented with this warning. | +| | +| Those structures and constants that are subject to the | +| above will be marked and bracketed with the flag: | +| | +| C A V E A T P R O G R A M M E R | +| | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + + + + + + + + + + + + + + + + + + Section 1 + + Extensions to existing call structure + + + Name: * Alloc - allocate memory + + Assembler usage: + MOV BX,size + MOV AH,Alloc + INT 21h + ; AX:0 is pointer to allocated memory + ; if alloc fails, BX is the largest block available + + Description: + Alloc returns a pointer to a free block of memory + that has the requested size in paragraphs. + + Error return: + AX = error_not_enough_memory + The largest available free block is smaller + than that requested or there is no free block. + = error_arena_trashed + The internal consistency of the memory arena + has been destroyed. This is due to a user + program changing memory that does not belong + to it. + + + Name: * CharOper - change incompatible configuration + parameters + + Assembler usage: + MOV AH, CharOper + MOV AL, func + MOV DL, data + INT 21h + ; on read functions, data is returned in DL + + Description: + CharOper allows a program to change system + parameters to allow for switch indicators and whether + devices are available at every level of the directory + tree. + + A function code is passed in AL: + + AL Function + -- -------- + 0 DL, on return, will contain the DOS switch + character. On most systems this will default to + '-'. + 1 Set the switch character to the character in DL. + 2 Read the device availability byte into DL. If + this byte is 0, then devices must be accessed in + file I/O calls by /dev/device. If this byte is + non-zero, then the devices are available at every + node of the directory tree (i.e. CON is the + console device not the file CON). This byte is + generally 0. + 3 Set the device availability byte to the value in + DL. + + Error returns: + AL = FF + The function code specified in AL is not in + the range 0:3 + + + Name: * CurrentDir - return text of current directory + + Assembler usage: + MOV AH,CurrentDir + LDS SI,area + MOV DL,drive + INT 21h + ; DS:SI is a pointer to 64 byte area that contains + ; drive current directory. + + Description: + CurrentDir returns the current directory for a + particular drive. The directory is root-relative and + does not contain the drive specifier. The drive code + passed in DL is 0=default, 1=A, 2=B, etc. + + Error returns: + AX = error_invalid_drive + The drive specified in DL was invalid. + + + Name: * Dealloc - free allocated memory + + Assembler usage: + MOV ES,block + MOV AH,dealloc + INT 21h + + Description: + Dealloc returns a piece of memory to the system + pool that was allocated by alloc. + + Error return: + AX = error_invalid_block + The block passed in ES is not one allocated + via Alloc. + = error_arena_trashed + The internal consistency of the memory arena + has been destroyed. This is due to a user + program changing memory that does not belong + to it. + + + Name: * FileTimes - get/set the write times of a + handle + + Assembler usage: + MOV AH, FileTimes + MOV AL, func + MOV BX, handle + ; if AL = 1 then then next two are mandatory + MOV CX, time + MOV DX, date + INT 21h + ; if AL = 0 then CX/DX has the last write time/date + ; for the handle. + + Description: + FileTimes returns or sets the last-write time for + a handle. These times are not recorded until the file + is closed. + + A function code is passed in AL: + + AL Function + -- -------- + 0 Return the time/date of the handle in CX/DX + 1 Set the time/date of the handle to CX/DX + + Error returns: + AX = error_invalid_function + The function passed in AL was not in the range + 0:1. + = error_invalid_handle + The handle passed in BX was not currently + open. + + + Name: * FindFirst - find matching file + + Assembler usage: + MOV AH, FindFirst + LDS DX, pathname + MOV CX, attr + INT 21h + ; DMA address has datablock + + Description: + FindFirst takes a pathname with wildcards in the + last component (passed in DS:DX), a set of attributes + (passed in CX) and attempts to find all files that + match the pathname and have a subset of the required + attributes. A datablock at the current DMA is written + that contains information in the following form: + + find_buf STRUC ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | + find_buf_sattr DB ? ; attribute of search + find_buf_drive DB ? ; drive of search + find_buf_name DB 11 DUP (?); search name + find_buf_LastEnt DW ? ; LastEnt + find_buf_ThisDPB DD ? ; This DPB + find_buf_DirStart DW ? ; DirStart +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + find_buf_attr DB ? ; attribute found + find_buf_time DW ? ; time + find_buf_date DW ? ; date + find_buf_size_l DW ? ; low(size) + find_buf_size_h DW ? ; high(size) + find_buf_pname DB 13 DUP (?) ; packed name + find_buf ENDS + + To obtain the subsequent matches of the pathname, + see the description of FindNext + + Error Returns: + AX = error_file_not_found + The path specified in DS:DX was an invalid + path. + = error_no_more_files + There were no files matching this + specification. + + + Name: * FindNext - step through a directory matching + files + + Assembler usage: + ; DMA points at area returned by find_first + MOV AH, findnext + INT 21h + ; next entry is at dma + + Description: + FindNext finds the next matching entry in a + directory. The current DMA address must point at a + block returned by FindFirst (see FindFirst). + + Error Returns: + AX = error_no_more_files + There are no more files matching this pattern. + + + Name: * GetDMA - get current DMA transfer address + + Assembler usage: + MOV AH,GetDMA + INT 21h + ; ES:BX has current DMA transfer address + + Description: + Return DMA transfer address. + + Error returns: + None. + ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | + + Name: * GetDSKPT(DL) - get pointer to drive parameter + block + + Assembler usage: + MOV AH,GetDSKPT + INT 21h + ; DS:BX has address of drive parameter block + + Description: + Return pointer to default drive parameter block. + + Error returns: + None. + + Assembler usage: + MOV DL,DrvNUM + MOV AH,GetDSKPTDL + INT 21h + ; DS:BX has address of drive parameter block + + Description: + Return pointer to drive parameter block for drive + designated in DL (0=Default, A=1, B=2 ...) + + Error returns: + AL = FF + The drive given in DL is invalid. +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + + Name: * GetFreespace - get Disk free space + + Assembler usage: + MOV AH,GetFreespace + MOV DL,Drive ;0 = default, A = 1 + INT 21h + ; BX = Number of free allocation units on drive + ; DX = Total number of allocation units on drive + ; CX = Bytes per sector + ; AX = Sectors per allocation unit + + Description: + Return Free space on disk along with additional + information about the disk. + + Error returns: + AX = FFFF + The drive number given in DL was invalid. + + NOTE: This call returns the same information in the same + registers (except for the FAT pointer) as the get FAT + pointer calls did in previous versions of the DOS. + + + Name: * GetInDOSF - get DOS critical-section flag + + Assembler usage: + MOV AH,GetInDOSF + INT 21h + ; ES:BX has location of the flag + MOV CritSEG, ES + MOV CritOFF, BX + ... + IntVec: + MOV AX, DWORD PTR Crit + CMP AX,0 + JZ DoFunc + IRET + DoFunc: ... + + Description: + Return location of indos flag. On return ES:BX is + the address of a byte memory cell inside the DOS. If + used in an interrupt service routine, it indicates + whether or not the DOS was interrupted in a critical + section. If the cell was zero, then the DOS was not + in a critical section and thus can be called by the + interrupt routine. If the cell was non-zero, the DOS + should be considered to be in an uninterruptable state + and for reliability, no DOS calls should be given. + + Error returns: + None. + + + Name: * GetVector - get interrupt vector + + Assembler usage: + MOV AH,GetVector + MOV AL,interrupt + INT 21h + ; ES:BX now has long pointer to interrupt routine + + Description: + Return interrupt vector associated with an + interrupt. + + Error returns: + None. + + + Name: * GetVerifyFlag - return current setting of the + verify after write flag. + + Assembler usage: + MOV AH,GetVerifyFlag + INT 21h + ; AL is the current verify flag value + + Description: + The current value of the verify flag is returned + in AL. + + Error returns: + None. + + + Name: * GetVersion - get DOS version number + + Assembler usage: + MOV AH,GetVersion + INT 21h + ; AL is the major version number + ; AH is the minor version number + ; BH is the OEM number + ; BL:CX is the (24 bit) user number + + Description: + Return MS-DOS version number. On return AL.AH + will be the two part version designation, ie. for + MS-DOS 1.28 AL would be 1 and AH would be 28. For pre + 1.28 DOS AL = 0. Note that version 1.1 is the same as + 1.10, not the same as 1.01. + + Error returns: + None. + + + Name: * International - return country dependent + information + + Assembler usage: + LDS DX, blk + MOV AH, International + MOV AL, func + INT 21h + + Description: + This call returns in the block of memory pointed + to by DS:DX, the following information pertinent to + international applications: + + +---------------------------+ + | WORD Date/time format | + +---------------------------+ + | BYTE ASCIZ string | + | currency symbol | + +---------------------------+ + | BYTE ASCIZ string | + | thousands separator | + +---------------------------+ + | BYTE ASCIZ string decimal | + | separator | + +---------------------------+ + + The date/time format has the following values and + meanings: + + 0 - USA standard h:m:s m/d/y + 1 - Europe standard h:m:s d/m/y + 2 - Japan standard y/m/d h:m:s + + The value passed in AL is either 0 (for current + country) or a country code (to be defined later. + Currently the country code must be zero). + + Error returns: + AX = error_invalid_function + The function passed in AL was not 0 + (currently). + + + Name: * KeepProcess - terminate process and remain + resident + + Assembler usage: + MOV AL, exitcode + MOV DX, parasize + MOV AH, KeepProcess + INT 21h + + Description: + This call terminates the current process and + attempts to set the initial allocation block to a + specific size in paragraphs. It will not free up any + other allocation blocks belonging to that process. + The exit code passed in AX is retrievable by the + parent via Wait. + + Error Returns: + None. + + + Name: * Rename - move a directory entry + + Assembler usage: + LDS DX, source + LES DI, dest + MOV AH, Rename + INT 21h + + Description: + Rename will attempt to rename a file into another + path. The paths must be on the same device. + + Error returns: + AX = error_file_not_found + The file name specifed by DS:DX was not found. + = error_not_same_device + The source and destination are on different + drives. + = error_access_denied + The path specified in DS:DX was a directory or + the file specified by ES:DI exists or the + destination directory entry could not be + created. + + + Name: * SetBlock - modify allocated blocks + + Assembler usage: + MOV ES,block + MOV BX,newsize + MOV AH,setblock + INT 21h + ; if setblock fails for growing, BX will have the + ; maximum size possible + + Description: + Setblock will attempt to grow/shrink an allocated + block of memory. + + Error return: + AX = error_invalid_block + The block passed in ES is not one allocated + via Alloc. + = error_arena_trashed + The internal consistency of the memory arena + has been destroyed. This is due to a user + program changing memory that does not belong + to it. + = error_not_enough_memory + There was not enough free memory after the + specified block to satisfy the grow request. + + + Name: * SetCtrlCTrapping - turn on/off broad ^C + checking + + Assembler usage: + MOV DL,val + MOV AH,SetCtrlCTrapping + MOV AL,func + INT 21h + ; If AL was 0, then DL has the current value of the + ; ^C check + + Description: + MSDOS ordinarily checks for a ^C on the + controlling device only when doing a function 1-12 + operation to that device. SetCtrlCTrapping allows the + user to expand this checking to include any system + call. For example, with the ^C trapping off, all disk + I/O will proceed without interruption while with ^C + trapping on, the ^C interrupt is given at the system + call that initiates the disk operation. + + Error return: + AL = FF + The function passed in AL was not in the range + 0:1. + ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | + + Name: * Set_OEM_Handler - set handler for OEM + specific INT 21H calls. + + Assembler usage: + LDS DX,handler_address + MOV AH,Set_OEM_Handler + INT 21H + + Description: + Set handler address for 0F9H-0FFH INT 21H system + calls to DS:DX. To return the 0F9H-0FFH calls to + the uninitialized state, give DS=DX=-1. + + Error returns: + None. + + Handler entry: + All registers as user set them when INT 21H + issued (including SS:SP). INT 21 return is on + stack, so the correct method for the OEM handler + to return to the user is to give an IRET. The + OEM handler is free to make any INT 21H system + call (including the 0F9H- 0FFH group if the OEM + handler is re-entrant). + + + The AH INT 21H function codes 0F8H through 0FFH are + reserved for OEM extensions to the INT 21H calling + convention. These calls have two states, initialized + and uninitialized. There will be one handler for all 7 + (0F9-0FFH) functions. When the DOS is first + initialized, these calls are uninitialized. The AH=0F8H + call is the call which will set the handler address for + the 0F9-0FFH calls. If the 0F9-0FFH calls are + uninitialized, an attempt to call them results in the + normal invalid system call number return. + OEMs should NOT document the 0F8 call. +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + + + + + + + + + + + + + + + + + + Section 2 + + XENIX-compatible system calls + + + + Previous to version 2.0, MSDOS had a simple single + directory structure that sufficed for small (160k to 320K) + diskettes. As the need for hard disk support grows, and + as MSDOS 2.0 will support a wide variety of hard disks, + the need for better disk organization also grows. Merely + expanding the directory is not an effective solution; + doing a 'DIR' on a directory with 1000 files is not a + user-friendly characteristic. + + People, by nature, think in hierarchical terms: + organization charts and family trees, for example. It + would be nice to allow users to organize their files on + disk in a similar manner. Consider the following: + + In a particular business, both sales and accounting + share a computer with a large disk and the individual + employees use it for preparation of reports and + maintaining accounting information. One would naturally + view the organization of files on the disk in this + fashion: + + +-disk-+ + / \ + / \ + / \ + sales accounting + / | | \ + / | | \ + / | | \ + John Mary Steve Sue + / | (A) | | | \ + / | | | | \ + / | | | | \ + report accts. report accts. report report + receiv. receiv + + In MSDOS 2.0 the user can arrange his files in such a + manner that files that are not part of his current task do + not interfere with that task. Pre-2.0 versions of MSDOS + has a single directory that contains files. MSDOS extends + this concept to allow a directory to contain both files + and directories and to introduce the notion of the + 'current' directory. + + To specify a filename, the user could use one of two + methods, either specify a path from the root node to the + file, or specify a path from the current node to the file. + A path is a series of directory names separated by '/' and + ending with a filename. A path that starts at the root + begins with a '/'. + + There is a special directory entry in each directory, + denoted by '..' that is the parent of the directory. The + root directory's parent is itself (who created God?). + + Using a directory structure like the hierarchy above, + and assuming that the current directory is at point (D), + to reference the report under John, the following are all + equivalent: + + report + /sales/John/report + ../John/report + + To refer to the report under Mary, the following are + all equivalent: + + ../Mary/report + /sales/Mary/report + + To refer to the report under Sue, the following are + all equivalent. + + ../../accounting/Sue/report + /accounting/Sue/report + + There is no restriction in MSDOS 2.0 on the depth of a + tree (the length of the longest path from root to leaf) + except in the number of allocation units available. The + root directory will have a fixed number of entries, 64 for + the single sided diskettes to XXX for a large hard disk. + For non-root directories, there is no limit to the number + of files per directory excepting in the number of + allocation units available. + + Old (pre-2.0) disks will appear to MSDOS 2.0 as having + only a root directory with files in it and no + subdirectories whatever. + + Implementation of the tree-structure is simple. The + root directory is the pre-2.0 directory. Subdirectories + of the root have a special attribute set indicating that + they are directories. The subdirectories themselves are + files, linked through the FAT as usual. Their contents + are identical in character to the contents of the root + directory. + + Pre-2.0 programs that use system calls not described + below will not be able to make use of files in other + directories. They will only be able to access files in + the current directory. This is no great loss of + functionality as users will aggregate their files into + sub-directories on basis of functionality; the files that + are being used will be found in the current directory. + Those that are not necessary for the current task will be + placed in other directories. Out of sight, out of mind. + + There are also new attributes in 2.0. These and the + old attributes apply to the tree structured directories in + the following manner: + + Attribute Meaning/Function Meaning/Function + for files for directories + + volume_id Present at the root. Meaningless. + Only one file may have + this set. + + directory Meaningless. Indicates that the + directory entry is a + directory. Cannot be + changed with ChMod. + + read_only Old fcb-create, new Meaningless. + Creat, new open (for + write or read/write) + will fail. + + archive Set when file is Meaningless. + written. Set/reset via + ChMod. + + hidden/ Prevents file from Prevents directory + system being found in search entry from being + first/search next. found. ChDir to + New open will fail. directory will still + work. + + + Name: * ChDir - Change the current directory + + Assembler usage: + LDS DX, name + MOV AH, ChDir + INT 21h + + Description: + ChDir is given the ASCIZ name of the directory + which is to become the current directory. If any + member of the specified pathname does not exist, then + the current directory is unchanged. Otherwise, the + current directory is set to the string. + + Error returns: + AX = error_path_not_found + The path specified in DS:DX either indicated a + file or the path was invalid. + + + Name: * ChMod - change write protection + + Assembler usage: + LDS DX, name + MOV CX, attribute + MOV AL, func + MOV AH, ChMod + INT 21h + + Description: + Given an ASCIZ name, ChMod will set/get the + attributes of the file to those given in CX. + + A function code is passed in AL: + + AL Function + -- -------- + 0 Return the attributes of the file in CX + 1 Set the attributes of the file to those in CX + + Error returns: + AX = error_path_not_found + The path specified was invalid. + = error_access_denied + The attributes specified in CX contained one + that could not be changed (directory, volume + ID). + = error_invalid_function + The function passed in AL was not in the range + 0:1. + + + Name: * Close - close a file handle + + Assembler usage: + MOV BX, handle + MOV AH, Close + INT 21h + + Description: + In BX is passed a file handle (like that returned + by Open, Creat or Dup); the Close call will close the + associated file. Internal buffers are flushed. + + Error return: + AX = error_invalid_handle + The handle passed in BX was not currently + open. + + + Name: * Creat - create a file + + Assembler usage: + LDS DX, name + MOV AH, Creat + MOV CX, attribute + INT 21h + ; AX now has the handle + + Description: + Creat creates a new file or truncates an old file + to zero length in preparation for writing. If the + file did not exist, then the file is created in the + appropriate directory and the file is given the + read/write protection code of access. + + CX contains the default attributes to be set for + the file. Currently, the read-only bit must be off. + + Error returns: + AX = error_access_denied + The attributes specified in CX contained one + that could not be created (directory, volume + ID), a file already existed with a more + inclusive set of attributes, or a directory + existed with the same name. + = error_path_not_found + The path specified was invalid. + = error_too_many_open_files + The file was created with the specified + attributes, but there were no free handles + available for the process or that the internal + system tables were full. + + + Name: * Dup - duplicate a file handle + + Assembler usage: + MOV BX, fh + MOV AH, Dup + INT 21h + ; AX has the returned handle + + Description: + Dup takes an already opened file handle and + returns a new handle that refers to the same file at + the same position. + + Error returns: + AX = error_invalid_handle + The handle passed in BX was not currently + open. + = error_too_many_open_files + There were no free handles available in the + current process or the internal system tables + were full. + + + Name: * Dup2 - force a duplicate of a handle + + Assembler usage: + MOV BX, fh + MOV CX, newfh + MOV AH, Dup2 + INT 21h + + Description: + Dup2 will cause newfh to refer to the same stream + as fh. If there was an open file on newfh, then it is + closed first. + + Error returns: + AX = error_invalid_handle + The handle passed in BX was not currently + open. + + + Name: * Exec - load / execute a program + + Assembler usage: + LDS DX, name + LES BX, blk + MOV AH, Exec + MOV AL, func + INT 21h + + Description: + This call allows a program to load another program + into memory and (default) begin execution of it. + DS:DX points to the ASCIZ name of the file to be + loaded. ES:BX points to a parameter block for the + load. + + A function code is passed in AL: + + AL Function + -- -------- + 0 Load and execute the program. A program header is + established for the program and the terminate and + ^C addresses are set to the instruction after the + EXEC system call. + + NOTE: When control is returned, via a ^C or + terminate, from the program being EXECed ALL + registers are altered including the stack. + This is because control is returned from the + EXECed program, not the system. To regain + your stack, store an SS:SP value in a data + location reachable from your CS. + ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | + 1 Load, create the program header but do not begin + execution. The CS:IP/SS:SP of the program are + returned in the area provided by the user. +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + 3 Load, do not create the program header, and do not + begin execution. This is useful in loading + program overlays. + + For each value of AL, the block has the following + format: + + AL = 0 -> load/execute program + + +---------------------------+ + | WORD segment address of | + | environment. | + +---------------------------+ + | DWORD pointer to command | + | line at 80h | + +---------------------------+ + | DWORD pointer to default | + | FCB to be passed at 5Ch | + +---------------------------+ + | DWORD pointer to default | + | FCB to be passed at 6Ch | + +---------------------------+ + ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | + AL = 1 -> load program + + +---------------------------+ + | WORD segment address of | + | environment. | + +---------------------------+ + | DWORD pointer to command | + | line at 80h | + +---------------------------+ + | DWORD pointer to default | + | FCB to be passed at 5Ch | + +---------------------------+ + | DWORD pointer to default | + | FCB to be passed at 6Ch | + +---------------------------+ + | DWORD returned value of | + | SS:SP | + +---------------------------+ + | DWORD returned value of | + | CS:IP | + +---------------------------+ +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + + AL = 3 -> load overlay + + +---------------------------+ + | WORD segment address where| + | file will be loaded. | + +---------------------------+ + | WORD relocation factor to | + | be applied to the image. | + +---------------------------+ + + Note that all open files of a process are + duplicated in the child process after an Exec. This + is extremely powerful; the parent process has control + over the meanings of stdin, stdout, stderr, stdaux and + stdprn. The parent could, for example, write a series + of records to a file, open the file as standard input, + open a listing file as standard output and then Exec a + sort program that takes its input from stdin and + writes to stdout. + + Also inherited (or passed from the parent) is an + 'environment'. This is a block of text strings (less + than 32K bytes total) that convey various + configurations parameters. The format of the + environment is as follows: + + (paragraph boundary) + +---------------------------+ + | BYTE asciz string 1 | + +---------------------------+ + | BYTE asciz string 2 | + +---------------------------+ + | ... | + +---------------------------+ + | BYTE asciz string n | + +---------------------------+ + | BYTE of zero | + +---------------------------+ + + Typically the environment strings have the form: + + parameter=value + + for example, COMMAND.COM always passes its execution + search path as: + + PATH=A:/BIN;B:/BASIC/LIB + + A zero value of the environment address will cause the + child process to inherit the parent's environment + unchanged. + + Note that on a successful return from EXEC, all + registers, except for CS:IP, are changed. + + Error return: + AX = error_invalid_function + The function passed in AL was not 0, 1 or 3. + = error_bad_environment + The environment was larger than 32Kb. + = error_bad_format + The file pointed to by DS:DX was an EXE format + file and contained information that was + internally inconsistent. + = error_not_enough_memory + There was not enough memory for the process to + be created. + = error_file_not_found + The path specified was invalid or not found. + + + Name: * Exit - terminate a process + + Assembler usage: + MOV AL, code + MOV AH, Exit + INT 21h + + Description: + Exit will terminate the current process, + transferring control to the invoking process. In + addition, a return code may be sent. All files open + at the time are closed. + + Error returns: + None. + + + Name: * Ioctl - I/O control for devices + + Assembler usage: + MOV BX, Handle + + (or MOV BL, drive for calls AL=4,5 + 0=default,A=1...) + + MOV DX, Data + + (or LDS DX, buf and + MOV CX, count for calls AL=2,3,4,5) + + MOV AH, Ioctl + MOV AL, func + INT 21h + ; For calls AL=2,3,4,5 AX is the number of bytes + ; transferred (same as READ and WRITE). + ; For calls AL=6,7 AL is status returned, AL=0 if + ; status is not ready, AL=0FFH otherwise. + + Description: + Set or Get device information associated with open + Handle, or send/receive control string to device + Handle or device. + + The following values are allowed for func: + + Request Function + ------ -------- + 0 Get device information (returned in DX) + 1 Set device information (as determined by DX) + 2 Read CX number of bytes into DS:DX from device + control channel. + 3 Write CX number of bytes from DS:DX to device + control channel. + 4 Same as 2 only drive number in BL + 0=default,A=1,B=2,... + 5 Same as 3 only drive number in BL + 0=default,A=1,B=2,... + 6 Get input status + 7 Get output status + + Ioctl can be used to get information about device + channels. It is ok to make Ioctl calls on regular + files but only calls 0,6 and 7 are defined in that + case (AL=0,6,7), all other calls return an + error_invalid_function error. + + CALLS AL=0 and AL=1 + + The bits of DX are defined as follows for calls + AL=0 and AL=1. Note that the upper byte MUST be zero + on a set call. + + | + 15 14 13 12 11 10 9 8|7 6 5 4 3 2 1 0 + +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+ + | R| C| |I|E|R|S|I|I|I|I| + | e| T| |S|O|A|P|S|S|S|S| + | s| R| Reserved |D|F|W|E|C|N|C|C| + | | L| |E| | |C|L|U|O|I| + | | | |V| | |L|K|L|T|N| + +--+--+--+--+--+--+-+-+-+-+-+-+-+-+-+-+ + | + + ISDEV = 1 if this channel is a device + = 0 if this channel is a disk file (Bits 8-15 = + 0 in this case) + + If ISDEV = 1 + + EOF = 0 if End Of File on input + RAW = 1 if this device is in Raw mode + = 0 if this device is cooked + ISCLK = 1 if this device is the clock device + ISNUL = 1 if this device is the null device + ISCOT = 1 if this device is the console output + ISCIN = 1 if this device is the console input + SPECL = 1 if this device is special + + CTRL = 0 if this device can NOT do control strings + via calls AL=2 and AL=3. + CTRL = 1 if this device can process control + strings via calls AL=2 and AL=3. + NOTE that this bit cannot be set. + + If ISDEV = 0 + EOF = 0 if channel has been written + Bits 0-5 are the block device number for the + channel (0 = A, 1 = B, ...) + + Bits 15,8-13,4 are reserved and should not be altered. + + Calls 2..5: + These four calls allow arbitrary control strings to be + sent or received from a device. The Call syntax is + the same as the READ and WRITE calls, except for 4 and + 5 which take a drive number in BL instead of a handle + in BX. + + An error_invalid_function error is returned if the + CTRL bit (see above) is 0. + + An error_access_denied is returned by calls AL=4,5 if + the drive number is invalid. + + Calls 6,7: + These two calls allow the user to check if a file + handle is ready for input or output. Status of + handles open to a device is the intended use of these + calls, but status of a handle open to a disk file is + OK and is defined as follows: + + Input: + Always ready (AL=FF) until EOF reached, then + always not ready (AL=0) unless current + position changed via LSEEK. + Output: + Always ready (even if disk full). + + IMPORTANT NOTE: + The status is defined at the time the system is + CALLED. On future versions, by the time control is + returned to the user from the system, the status + returned may NOT correctly reflect the true current + state of the device or file. + + Error returns: + AX = error_invalid_handle + The handle passed in BX was not currently + open. + = error_invalid_function + The function passed in AL was not in the range + 0:7. + = error_invalid_data + = error_access_denied (calls AL=4..7) + + + Name: * LSeek - move file read/write pointer + + Assembler usage: + MOV DX, offsetlow + MOV CX, offsethigh + MOV AL, method + MOV BX, handle + MOV AH, LSeek + INT 21h + ; DX:AX has the new location of the pointer + + Description: + LSeek moves the read/write pointer according to + method: + + Method Function + ------ -------- + 0 The pointer is moved to offset bytes from the + beginning of the file. + 1 The pointer is moved to the current location + plus offset. + 2 The pointer is moved to the end of file plus + offset. + + Offset should be regarded as a 32-bit integer with + CX occupying the most significant 16 bits. + + Error returns: + AX = error_invalid_handle + The handle passed in BX was not currently + open. + = error_invalid_function + The function passed in AL was not in the range + 0:2. + + + Name: * MkDir - Create a directory entry + + Assembler usage: + LDS DX, name + MOV AH, MkDir + INT 21h + + Description: + Given a pointer to an ASCIZ name, create a new + directory entry at the end. + + Error returns: + AX = error_path_not_found + The path specified was invalid or not found. + = error_access_denied + The directory could not be created (no room in + parent directory), the directory/file already + existed or a device name was specified. + + + Name: * Open - access a file + + Assembler usage: + LDS DX, name + MOV AH, Open + MOV AL, access + INT 21h + ; AX has error or file handle + ; If successful open + + Description: + Open associates a 16-bit file handle with a file. + + The following values are allowed for access: + + ACCESS Function + ------ -------- + 0 file is opened for reading + 1 file is opened for writing + 2 file is opened for both reading and writing. + + DS:DX point to an ASCIZ name of the file to be + opened. + + The read/write pointer is set at the first byte of + the file and the record size of the file is 1 byte. + The returned file handle must be used for subsequent + I/O to the file. + + The DOS, on initialization, will have a maximum + number of files. See the configuration file document + for information on changing this default. + + Error returns: + AX = error_invalid_access + The access specified in AL was not in the + range 0:2. + = error_file_not_found + The path specified was invalid or not found. + = error_access_denied + The user attempted to open a directory or + volume-id, or open a read-only file for + writing. + = error_too_many_open_files + There were no free handles available in the + current process or the internal system tables + were full. + + + Name: * Read - Do file/device I/O + + Assembler usage: + LDS DX, buf + MOV CX, count + MOV BX, handle + MOV AH, Read + INT 21h + ; AX has number of bytes read + + Description: + Read transfers count bytes from a file into a + buffer location. It is not guaranteed that all count + bytes will be read; for example, reading from the + keyboard will read at most one line of text. If the + returned value is zero, then the program has tried to + read from the end of file. + + All I/O is done using normalized pointers; no + segment wraparound will occur. + + Error returns: + AX = error_invalid_handle + The handle passed in BX was not currently + open. + = error_access_denied + The handle passed in BX was opened in a mode + that did not allow reading. + + + Name: * RmDir - Remove a directory entry + + Assembler usage: + LDS DX, name + MOV AH, RmDir + INT 21h + + Description: + RmDir is given an asciz name of a directory. That + directory is removed from its parent + + Error returns: + AX = error_path_not_found + The path specified was invalid or not found. + = error_access_denied + The path specified was not empty, not a + directory, the root directory or contained + invalid information. + = error_current_directory + The path specified was the current directory + on a drive. + + + Name: * Unlink - delete a directory entry + + Assembler usage: + LDS DX, name + MOV AH, Unlink + INT 21h + + Description: + Unlink removes a directory entry associated with a + filename. If the file is currently open on another + handle, then no removal will take place. + + Error returns: + AX = error_file_not_found + The path specified was invalid or not found. + = error_access_denied + The path specified was a directory or + read-only. + + + Name: * Wait - retrieve the return code of a child + + Assembler usage: + MOV AH, Wait + INT 21h + ; AX has the exit code + + Description: + Wait will return the Exit code specified by a + child process. It will return this Exit code only + once. The low byte of this code is that sent by the + Exit routine. The high byte is one of the following: + + 0 - terminate/abort + 1 - ^C + 2 - Hard error + 3 - Terminate and stay resident + + Error returns: + None. + + + Name: * Write - write to a file + + Assembler usage: + LDS DX, buf + MOV CX, count + MOV BX, handle + MOV AH, Write + INT 21h + ; AX has number of bytes written + + Description: + Write transfers count bytes from a buffer into + a file. It should be regarded as an error if the + number of bytes written is not the same as the number + requested. + + It is important to note that the write system + call with a count of zero (CX = 0) will truncate + the file at the current position. + + All I/O is done using normalized pointers; no + segment wraparound will occur. + + Error Returns: + AX = error_invalid_handle + The handle passed in BX was not currently + open. + = error_access_denied + The handle was not opened in a mode that + allowed writing. + + +The following XENIX convention is followed for the new 2.0 +system calls: + + o If no error occurred, then the carry flag will be + reset and register AX will contain the appropriate + information. + + o If an error occurred, then the carry flag will be + set and register AX will contain the error code. + +The following code sample illustrates the recommended method +of detecting these errors: + + ... + MOV errno,0 + INT 21h + JNC continue + MOV errno,AX +continue: + ... + +The word variable errno will now have the correct error code +for that system call. + +The current equates for the error codes are: + +no_error_occurred EQU 0 + +error_invalid_function EQU 1 +error_file_not_found EQU 2 +error_path_not_found EQU 3 +error_too_many_open_files EQU 4 +error_access_denied EQU 5 +error_invalid_handle EQU 6 +error_arena_trashed EQU 7 +error_not_enough_memory EQU 8 +error_invalid_block EQU 9 +error_bad_environment EQU 10 +error_bad_format EQU 11 +error_invalid_access EQU 12 +error_invalid_data EQU 13 +error_invalid_drive EQU 15 +error_current_directory EQU 16 +error_not_same_device EQU 17 +error_no_more_files EQU 18 + + +System call assignments: + +ABORT EQU 0 ; 0 0 +STD_CON_INPUT EQU 1 ; 1 1 +STD_CON_OUTPUT EQU 2 ; 2 2 +STD_AUX_INPUT EQU 3 ; 3 3 +STD_AUX_OUTPUT EQU 4 ; 4 4 +STD_PRINTER_OUTPUT EQU 5 ; 5 5 +RAW_CON_IO EQU 6 ; 6 6 +RAW_CON_INPUT EQU 7 ; 7 7 +STD_CON_INPUT_NO_ECHO EQU 8 ; 8 8 +STD_CON_STRING_OUTPUT EQU 9 ; 9 9 +STD_CON_STRING_INPUT EQU 10 ; 10 A +STD_CON_INPUT_STATUS EQU 11 ; 11 B +STD_CON_INPUT_FLUSH EQU 12 ; 12 C +DISK_RESET EQU 13 ; 13 D +SET_DEFAULT_DRIVE EQU 14 ; 14 E +FCB_OPEN EQU 15 ; 15 F +FCB_CLOSE EQU 16 ; 16 10 +DIR_SEARCH_FIRST EQU 17 ; 17 11 +DIR_SEARCH_NEXT EQU 18 ; 18 12 +FCB_DELETE EQU 19 ; 19 13 +FCB_SEQ_READ EQU 20 ; 20 14 +FCB_SEQ_WRITE EQU 21 ; 21 15 +FCB_CREATE EQU 22 ; 22 16 +FCB_RENAME EQU 23 ; 23 17 +GET_DEFAULT_DRIVE EQU 25 ; 25 19 +SET_DMA EQU 26 ; 26 1A ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | +GET_DEFAULT_DPB EQU 31 ; 31 1F +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +FCB_RANDOM_READ EQU 33 ; 33 21 +FCB_RANDOM_WRITE EQU 34 ; 34 22 +GET_FCB_FILE_LENGTH EQU 35 ; 35 23 +GET_FCB_POSITION EQU 36 ; 36 24 +SET_INTERRUPT_VECTOR EQU 37 ; 37 25 +CREATE_PROCESS_DATA_BLOCK EQU 38 ; 38 26 +FCB_RANDOM_READ_BLOCK EQU 39 ; 39 27 +FCB_RANDOM_WRITE_BLOCK EQU 40 ; 40 28 +PARSE_FILE_DESCRIPTOR EQU 41 ; 41 29 +GET_DATE EQU 42 ; 42 2A +SET_DATE EQU 43 ; 43 2B +GET_TIME EQU 44 ; 44 2C +SET_TIME EQU 45 ; 45 2D +SET_VERIFY_ON_WRITE EQU 46 ; 46 2E +; Extended functionality group +GET_DMA EQU 47 ; 47 2F +GET_VERSION EQU 48 ; 48 30 +KEEP_PROCESS EQU 49 ; 49 31 ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | +GET_DPB EQU 50 ; 50 32 +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +SET_CTRL_C_TRAPPING EQU 51 ; 51 33 +GET_INDOS_FLAG EQU 52 ; 52 34 +GET_INTERRUPT_VECTOR EQU 53 ; 53 35 +GET_DRIVE_FREESPACE EQU 54 ; 54 36 +CHAR_OPER EQU 55 ; 55 37 +INTERNATIONAL EQU 56 ; 56 38 +; XENIX CALLS +; Directory Group +MKDIR EQU 57 ; 57 39 +RMDIR EQU 58 ; 58 3A +CHDIR EQU 59 ; 59 3B +; File Group +CREAT EQU 60 ; 60 3C +OPEN EQU 61 ; 61 3D +CLOSE EQU 62 ; 62 3E +READ EQU 63 ; 63 3F +WRITE EQU 64 ; 64 40 +UNLINK EQU 65 ; 65 41 +LSEEK EQU 66 ; 66 42 +CHMOD EQU 67 ; 67 43 +IOCTL EQU 68 ; 68 44 +XDUP EQU 69 ; 69 45 +XDUP2 EQU 70 ; 70 46 +CURRENT_DIR EQU 71 ; 71 47 +; Memory Group +ALLOC EQU 72 ; 72 48 +DEALLOC EQU 73 ; 73 49 +SETBLOCK EQU 74 ; 74 4A +; Process Group +EXEC EQU 75 ; 75 4B +EXIT EQU 76 ; 76 4C +WAIT EQU 77 ; 77 4D +FIND_FIRST EQU 78 ; 78 4E +; Special Group +FIND_NEXT EQU 79 ; 79 4F +; SPECIAL SYSTEM GROUP ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | +SET_CURRENT_PDB EQU 80 ; 80 50 +GET_CURRENT_PDB EQU 81 ; 81 51 +GET_IN_VARS EQU 82 ; 82 52 +SETDPB EQU 83 ; 83 53 +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +GET_VERIFY_ON_WRITE EQU 84 ; 84 54 ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +| C A V E A T P R O G R A M M E R | +| | +DUP_PDB EQU 85 ; 85 55 +| | +| C A V E A T P R O G R A M M E R | ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +RENAME EQU 86 ; 86 56 +FILE_TIMES EQU 87 ; 87 57 + \ No newline at end of file diff --git a/v2.0/bin/SYSIMES.OBJ b/v2.0/bin/SYSIMES.OBJ new file mode 100644 index 00000000..3172652e Binary files /dev/null and b/v2.0/bin/SYSIMES.OBJ differ diff --git a/v2.0/bin/SYSINIT.DOC b/v2.0/bin/SYSINIT.DOC new file mode 100644 index 00000000..fa20d083 Binary files /dev/null and b/v2.0/bin/SYSINIT.DOC differ diff --git a/v2.0/bin/SYSINIT.OBJ b/v2.0/bin/SYSINIT.OBJ new file mode 100644 index 00000000..3dc2c13b Binary files /dev/null and b/v2.0/bin/SYSINIT.OBJ differ diff --git a/v2.0/bin/UTILITY.DOC b/v2.0/bin/UTILITY.DOC new file mode 100644 index 00000000..a63793cd --- /dev/null +++ b/v2.0/bin/UTILITY.DOC @@ -0,0 +1,813 @@ + + + + + + + + + + + + + + + + + + + MS-DOS 2.0 + + Utility Extensions + + + + + + + + + The following notation is used below: + + [item] item is optional. + item* item is repeated 0 or more times. + item+ item is repeated 1 or more times. + {item1 | item2} + item1 is present or item 2 is present but + not both. + indicates a syntactic variable. + + +COMMAND invokation + +COMMAND [[:]] [] [-D] [-P] [-C ] + + -P If present COMMAND will be permanent, otherwise + this is a transient command. + + -D If present COMMAND will not prompt for DATE and + TIME when it comes up. + + d: Specifies device where command will look for + COMMAND.COM current default drive if absent. + + Specifies a directory on device d: root + directory if absent. + + Name of the CTTY device. /DEV/CON if absent + and command is permanent. The /DEV/ may be left + off if AVAILDEV is TRUE (see sysinit doc). + + -C If present -C must be the last switch. + This causes COMMAND to try to execute the string + as if the user had typed it at the standard input. + COMMAND executes this single command string and + then exits. If the -P switch is present it is + ignored (can't have a single command, permanent + COMMAND). NOTE: ALL of the text on the command + line after the -C is just passed on. It is not + processed for more arguments, this is why -C must + be last. + +COMMAND extensions + +IF + + where is one of the following: + + ERRORLEVEL + true if and only if the previous program EXECed by + COMMAND had an exit code of or higher. + + == + true if and only if and are + identical after parameter substitution. Strings + may not have embedded delimiters. + + EXIST + true if and only if exists. + + NOT + true if and only if is false. + + The IF statement allows conditional execution of commands. + When the is true, then the is + executed otherwise, the is skipped. + + Examples: + + IF not exist /tmp/foo ECHO Can't find file /tmp/foo + + IF $1x == x ECHO Need at least one parameter + + IF NOT ERRORLEVEL 3 LINK $1,,; + + +FOR %% IN DO + + can be any character but 0,1,2,3,..,9 (so there is no + confusion with the %0 - %9 batch parameters). + + is ( * ) + + The %% variable is sequentially set to each member of + and then is evaluated. If a member of + is an expression involving * and/or ?, then the + variable is set to each matching pattern from disk. In + this case only one such may be in the set, any + s after the first are ignored. + + Example: + + FOR %%f IN ( *.ASM ) DO MASM %%f; + + for %%f in (FOO BAR BLECH) do REM %%f to you + + NOTE: The '%%' is needed so that after Batch parameter + (%0 - %9) processing is done, there is one '%' left. + If only '%f' were there, the batch parameter processor + would see the '%' then look at 'f', decide that '%f' + was an error (bad parameter reference) and throw out + the '%f' so that FOR would never see it. If the FOR + is NOT in a batch file, then only ONE '%' should be + used. + + +SHIFT + + Currently, command files are limited to handling 10 + parameters: %0 through %9. To allow access to more than + these, the command SHIFT will perform a 'pop' of the + command line parameters: + + if %0 = "foo" + %1 = "bar" + %2 = "blech" + %3...%9 are empty + + then a SHIFT will result in the following: + + %0 = "bar" + %1 = "blech" + %2...%9 are empty + + If there are more than 10 parameters given on a command + line, then the those that appear after the 10th (%9) will + be shifted one at a time into %9 by successive shifts. + +: