mirror of
https://github.com/microsoft/MS-DOS.git
synced 2024-11-25 15:15:47 +00:00
393 lines
16 KiB
Plaintext
393 lines
16 KiB
Plaintext
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
|
||
|