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