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     
���������������������������������