mirror of https://github.com/microsoft/MS-DOS.git
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
|
|||
|
|