mirror of https://github.com/AR1972/DOS3.3
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1204 lines
34 KiB
1204 lines
34 KiB
; SCCSID = @(#)oemfor.asm 1.28 85/10/15
|
|
name OemFormatRoutines
|
|
|
|
debug equ 0
|
|
;-------------------------------------------------------------------------------
|
|
; Public for debugging only
|
|
|
|
public CheckSwitches
|
|
public LastChanceToSaveIt
|
|
public WriteBootSector
|
|
public OemDone
|
|
public WriteBogusDos
|
|
public ConvertToOldDirectoryFormat
|
|
public SetPartitionTable
|
|
public ReadSector
|
|
public WriteSector
|
|
public SectorIO
|
|
public GetVolumeId
|
|
public CheckVolumeId
|
|
|
|
public customBPBs
|
|
public BootSectorIsFine
|
|
public NotSlashB
|
|
public NotSingleSided
|
|
public EndSwitchCheck
|
|
public WeCanNotIgnoreThisError
|
|
public CanNotWriteBoot
|
|
public HardDisk?
|
|
public BogusDos
|
|
public sys_mess_loop
|
|
public end_sys_loop
|
|
public DirectoryRead
|
|
public wrtdir
|
|
public DirectoryWritten
|
|
public PartitionTableRead
|
|
public partitionscan
|
|
public dochange
|
|
public partitionset
|
|
public BadPartitionTable
|
|
public FCBforVolumeIdSearch
|
|
public CopyVolumeId
|
|
public CompareVolumeIds
|
|
public VolumeToUpper
|
|
public NextLetter
|
|
public BadVolumeId
|
|
|
|
public switchlist
|
|
public boot2
|
|
public boot
|
|
public scratchBuffer
|
|
public bootDrive
|
|
public biosFilename
|
|
public dosFilename
|
|
public oldDrive
|
|
public oldVolumeId
|
|
|
|
public bootSignature
|
|
public ptr_msgWhatIsVolumeId?
|
|
|
|
public trackReadWritePacket
|
|
|
|
public BPB81
|
|
public BPB82
|
|
public BPB91
|
|
public BPB92
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
data segment public 'DATA'
|
|
data ends
|
|
|
|
code segment public 'CODE'
|
|
assume cs:code,ds:data
|
|
|
|
Public AccessDisk
|
|
public CheckSwitches
|
|
public LastChanceToSaveIt
|
|
public WriteBootSector
|
|
public OemDone
|
|
public BiosFile
|
|
public DosFile
|
|
|
|
data segment
|
|
extrn AddToSystemSize:near
|
|
extrn currentCylinder:word
|
|
extrn currentHead:word
|
|
extrn deviceParameters:byte
|
|
extrn drive:byte
|
|
extrn driveLetter:byte
|
|
extrn fBigFAT:byte
|
|
extrn inbuff:byte
|
|
extrn switchmap:word
|
|
extrn Old_Dir:byte
|
|
extrn fLastChance:byte
|
|
|
|
extrn msgBadVolumeId:byte
|
|
extrn msgBadPartitionTable:byte
|
|
extrn msgBootWriteError:byte
|
|
extrn msgDirectoryReadError:byte
|
|
extrn msgDirectoryWriteError:byte
|
|
extrn msgInvalidParameter:byte
|
|
extrn msgIncompatibleParameters:byte
|
|
extrn msgIncompatibleParametersForHardDisk:byte
|
|
extrn msgParametersNotSupportedByDrive:byte
|
|
extrn msgPartitionTableReadError:byte
|
|
extrn msgPartitionTableWriteError:byte
|
|
extrn msgWhatIsVolumeId?:byte
|
|
extrn NumSectors:word, TrackCnt:word
|
|
|
|
IF DEBUG
|
|
extrn msgFormatBroken:byte
|
|
ENDIF
|
|
|
|
data ends
|
|
|
|
extrn PrintString:near
|
|
extrn std_printf:near
|
|
extrn crlf:near
|
|
extrn user_string:near
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; Support Routines
|
|
|
|
Switches macro s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16
|
|
;;
|
|
switchCount = 0
|
|
switchmask = 1
|
|
irp x,<&s1,&s2,&s3,&s4,&s5,&s6,&s7,&s8,&s9,&s10,&s11,&s12,&s13,&s14,&s15,&s16>
|
|
ifnb <x>
|
|
switchCount = switchCount + 1
|
|
SWITCH_&&x = switchmask
|
|
switchmask = 2 * switchmask
|
|
endif
|
|
endm
|
|
public switchlist
|
|
switchlist db switchCount
|
|
db "&s16&&s15&&s14&&s13&&s12&&s11&&s10&&s9&&s8&&s7&&s6&&s5&&s4&&s3&&s2&&s1&"
|
|
endm
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; Constants
|
|
|
|
; Standard dos macros
|
|
INCLUDE DOSMAC.INC
|
|
|
|
; This defines all the int 21H system calls
|
|
INCLUDE SYSCALL.INC
|
|
|
|
; Limits
|
|
|
|
; following were removed into FILESIZE.INC by kwc on 10/04/86
|
|
|
|
;BIOS_SIZE equ 5400h ; Used to set size of
|
|
;DOS_SIZE equ 7600h ; Bogus DOS for /B switch
|
|
|
|
include filesize.inc
|
|
|
|
; end of FILESIZE.INC change by kwc on 10/04/86
|
|
|
|
LOGBOOTSECT equ 1
|
|
;MAX_SECTORS_IN_TRACK equ 20 Already defined in ioctl.INC
|
|
Set_Drv_Owner equ 0Fh ; IOCTL subfunction
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; These are the data structures which we will need
|
|
|
|
INCLUDE DIRENT.INC
|
|
include ioctl.INC
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; And this is the actual data
|
|
data segment
|
|
|
|
BiosFile db "x:\IO.SYS", 0
|
|
DosFile db "x:\MSDOS.SYS", 0
|
|
|
|
trackReadWritePacket a_TrackReadWritePacket <>
|
|
|
|
Switches S,V,H,C,T,N,1,4,8,B
|
|
|
|
; BIOS parameter blocks for various media
|
|
customBPBs label byte
|
|
BPB92 a_BPB <512, 2, 1, 2, 112, 2*9*40, 0fdH, 2, 9, 2, 0, 0, 0, 0>
|
|
BPB91 a_BPB <512, 1, 1, 2, 64, 1*9*40, 0fcH, 2, 9, 1, 0, 0, 0, 0>
|
|
BPB82 a_BPB <512, 2, 1, 2, 112, 2*8*40, 0ffH, 1, 8, 2, 0, 0, 0, 0>
|
|
BPB81 a_BPB <512, 1, 1, 2, 64, 1*8*40, 0feH, 1, 8, 1, 0, 0, 0, 0>
|
|
BPB720 a_BPB <512, 2, 1, 2, 112, 2*9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0>
|
|
|
|
Custom_Media equ 0F0H ; Media byte for custom format
|
|
Dual_8_Media equ 0FFh ; Dual sided 8 sectored
|
|
Single_8_Media equ 0FEh ; Single sided 8 sectored
|
|
Dual_9_Media equ 0FDh ; Dual sided 9 sectored
|
|
Single_9_Media equ 0FCh ; Single sided 9 sectored
|
|
Dual_15_Media equ 0F9h ; Dual sided 15 sectored
|
|
Fixed_Disk equ 0F8h ; Fixed Disk
|
|
|
|
|
|
boot2 db 0,0,0, "Boot 1.x"
|
|
db 512 - 11 dup(?)
|
|
|
|
REORG2 LABEL BYTE
|
|
ORG BOOT2
|
|
INCLUDE ..\BOOT\BOOT11.INC
|
|
ORG REORG2
|
|
|
|
boot db 0,0,0,"Boot 2.x"
|
|
bootBPB a_BPB <>
|
|
db 512 - (size a_BPB + 11 + 3) dup(0)
|
|
|
|
bootDrive db 0
|
|
bootSignature dw 0
|
|
|
|
REORG LABEL BYTE
|
|
ORG BOOT
|
|
INCLUDE ..\BOOT\BOOT.INC
|
|
ORG REORG
|
|
|
|
scratchBuffer db 512 dup(?)
|
|
|
|
ptr_msgWhatIsVolumeId? dw offset msgWhatIsVolumeId?
|
|
dw offset driveLetter
|
|
|
|
data ends
|
|
;-------------------------------------------------------------------------------
|
|
; AccessDisk:
|
|
; Called whenever a different disk is about to be accessed
|
|
;
|
|
; Input:
|
|
; al - drive letter (0=A, 1=B, ...)
|
|
;
|
|
; Output:
|
|
; none
|
|
AccessDisk proc near
|
|
|
|
push ax ; save drive letter
|
|
mov bl,al ; Set up GENERIC IOCTL REQUEST preamble
|
|
inc bl
|
|
mov ax,(IOCTL SHL 8) + Set_Drv_Owner ; IOCTL function
|
|
int 21h
|
|
pop ax
|
|
return
|
|
|
|
AccessDisk endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; CheckSwitches:
|
|
; Check switches against device parameters
|
|
; Use switches to modify device parameters
|
|
;
|
|
; Input:
|
|
; deviceParameters
|
|
;
|
|
; Output:
|
|
; deviceParameters may be modified
|
|
; Carry set if error
|
|
;
|
|
; Algorithm:
|
|
; if hard disk
|
|
; Check Boot Sector for valid Signature
|
|
; IF (valid)
|
|
; Check the volume id
|
|
; Make sure no switches other than /V, /S are specifed
|
|
; else if 96 tpi without /4 or not 5.25" disk
|
|
; Make sure no switches other than /V, /S are specifed
|
|
; else
|
|
; if 48 tpi drive and switch /4
|
|
; turn off switch /4
|
|
; if single sided drive and switch /1 but not switch /8
|
|
; turn off switch /1
|
|
; if any of interesting switches are on (/C, /O, /V, /S are not)
|
|
; set number of cylinders to 40
|
|
; choose new BPB depending on switches /1 and /8
|
|
;
|
|
CheckSwitches proc near
|
|
|
|
IF DEBUG
|
|
; See if the boot sector was initialised correctly
|
|
cmp bootSignature, 0aa55H
|
|
je BootSectorIsFine
|
|
lea dx, msgFormatBroken
|
|
jmp short SwitchError
|
|
ENDIF ; DEBUG
|
|
|
|
BootSectorIsFine:
|
|
|
|
; Disallow /C
|
|
lea dx, msgInvalidParameter
|
|
test switchmap, SWITCH_C
|
|
jz CheckExcl
|
|
|
|
SwitchError:
|
|
call PrintString
|
|
stc
|
|
ret
|
|
|
|
; Only certain permutations of the switches /N /T /V /B /S and /V are legal.
|
|
; For specific cases see the file Switchmap.legal.
|
|
|
|
CheckExcl:
|
|
lea dx, msgIncompatibleParameters ; Error message
|
|
|
|
|
|
test SwitchMap, SWITCH_B ; IF ( SWITCH_B)
|
|
jz SVpermitted
|
|
|
|
test SwitchMap, SWITCH_S or SWITCH_V ; THEN exclude SWITCH_S and
|
|
jnz SwitchError ; SWITCH_V
|
|
|
|
SVpermitted:
|
|
test SwitchMap, SWITCH_8 ; IF ( SWITCH_8 )
|
|
jz Check_N
|
|
; THEN
|
|
test SwitchMap, SWITCH_N or SWITCH_T ; exclude SWITCH_N and
|
|
jnz SwitchError
|
|
|
|
|
|
test SwitchMap, SWITCH_V ; SWITCH_V if unaccompanied
|
|
jz Check_N ; by SWITCH_S
|
|
|
|
test SwitchMap, SWITCH_S
|
|
jz SwitchError ; ENDIF ( SWITCH_8 )
|
|
|
|
|
|
Check_N: ; IF ( SWITCH_N or SWITCH_T )
|
|
test SwitchMap, SWITCH_N or SWITCH_T
|
|
jz ExclChkDone
|
|
|
|
test SwitchMap, SWITCH_1 or SWITCH_4 ; THEN exclude SWITCH_1 and
|
|
jnz SwitchError ; SWITCH_4
|
|
|
|
ExclChkDone:
|
|
; Patch the boot sector so that the boot strap loader knows what disk to
|
|
; boot from
|
|
mov bootDrive, 00H
|
|
|
|
cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
|
|
jne CheckFor5InchDrives
|
|
|
|
; Formatting a hard disk so we must repatch the boot sector
|
|
mov bootDrive, 80H
|
|
test switchmap, not (SWITCH_S or SWITCH_V)
|
|
jz SwitchesOkForHardDisk
|
|
lea dx, msgIncompatibleParametersForHardDisk
|
|
call PrintString
|
|
stc
|
|
ret
|
|
|
|
; Before checking the Volume Id we need to verify that a valid one exists
|
|
; We assume that unless a valid boot sector exists on the target disk, no
|
|
; valid Volume Id can exist.
|
|
|
|
SwitchesOkForHardDisk:
|
|
SaveReg <ax,bx,cx,dx,ds>
|
|
mov al,drive
|
|
mov cx,LogBootSect
|
|
xor dx,dx
|
|
lea bx,scratchBuffer ; ScratchBuffer := Absolute_Disk_Read(
|
|
INT 25h ; Logical_sec_1 )
|
|
pop ax ; Stupid Int 25! leaves flags
|
|
; on the stack. We throw them away
|
|
|
|
jnc CheckSignature
|
|
stc
|
|
RestoreReg <ds,dx,cx,bx,ax>
|
|
ret
|
|
|
|
CheckSignature: ; IF (BootSector.BootSignature != aa55)
|
|
|
|
mov ax, Word Ptr (ScratchBuffer + (BootSignature - boot))
|
|
cmp ax, 0aa55h
|
|
RestoreReg <ds,dx,cx,bx,ax>
|
|
clc ; not an error, just not vol.
|
|
retnz ; THEN RETURN
|
|
|
|
call CheckVolumeId ; ELSE CheckVolumeID
|
|
return
|
|
|
|
OnlyVSpermitted:
|
|
test switchmap, not (SWITCH_S or SWITCH_V)
|
|
retz
|
|
lea dx, msgIncompatibleParameters
|
|
|
|
Print_And_Return:
|
|
call PrintString
|
|
stc
|
|
return
|
|
|
|
|
|
CheckFor5InchDrives:
|
|
|
|
;If drive type is anything other than 48 or 96, then only /V/S/H/N/T allowed
|
|
cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
|
|
je Got96
|
|
|
|
cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
|
|
je Got48
|
|
|
|
test switchmap, not (SWITCH_V or SWITCH_S or SWITCH_N or SWITCH_T or SWITCH_H)
|
|
jz Goto_Got_BPB
|
|
lea dx,msgParametersNotSupportedByDrive
|
|
jmp short Print_And_Return
|
|
|
|
; We have a 96tpi floppy drive
|
|
; /4 allows just about all switches however, /1 requires /4
|
|
Got96:
|
|
test switchmap, SWITCH_4
|
|
jnz CheckForInterestingSwitches ;If /4 check /N/T/V/S
|
|
|
|
test switchmap, SWITCH_1 ;If /1 and /4 check others
|
|
jz Got48
|
|
|
|
;If only /1 with no /4, see if /N/T
|
|
test SwitchMap,(Switch_N or Switch_T)
|
|
jnz CheckForInterestingSwitches
|
|
|
|
lea dx, msgIncompatibleParameters ;If no /4 but /1 die
|
|
jmp short Print_And_Return
|
|
|
|
Got48:
|
|
;Ignore /4 for non-96tpi 5 1/4" drives
|
|
and switchmap, not SWITCH_4
|
|
|
|
;Ignore /1 if drive has only one head and not /8
|
|
cmp word ptr deviceParameters.DP_BPB.BPB_Heads, 1
|
|
ja CheckForInterestingSwitches
|
|
test switchmap, SWITCH_8
|
|
jz CheckForInterestingSwitches
|
|
and switchmap, not SWITCH_1
|
|
|
|
;Are any interesting switches set?
|
|
CheckForInterestingSwitches:
|
|
test switchmap, not (SWITCH_V or SWITCH_S or SWITCH_H) ;Anything but /V/S/H?
|
|
jz Goto_EndSwitchCheck ;No, everything ok
|
|
|
|
;At this point there are switches other than /v/s/h
|
|
test SwitchMap,(SWITCH_N or SWITCH_T)
|
|
jz Use_48tpi ;Not /n/t, so must be /b/1/8/4
|
|
|
|
;We've got /N/T, see if there are others
|
|
test SwitchMap, not (SWITCH_N or SWITCH_T or SWITCH_V or SWITCH_S or SWITCH_H)
|
|
jz NT_Compatible ;Nope, all is well
|
|
|
|
;If 96tpi drive and /1 exists with /N/T, then okay, otherwise error
|
|
cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
|
|
jne Bad_NT_Combo
|
|
|
|
test SwitchMap, not (SWITCH_1 or SWITCH_N or SWITCH_T or SWITCH_V or SWITCH_S or SWITCH_H)
|
|
jz Goto_Got_BPB
|
|
|
|
Bad_NT_Combo:
|
|
lea dx, msgIncompatibleParameters
|
|
jmp Print_And_Return
|
|
|
|
Goto_Got_BPB:
|
|
jmp Got_BPB_Ok ;Sleazy, but je won't reach it
|
|
|
|
Goto_EndSwitchCheck:
|
|
jmp EndSwitchCheck
|
|
;There is a problem with /N/T in that IO.SYS will default to a BPB with the
|
|
;media byte set to F0 (other) if the /N/T combo is used for the format. This
|
|
;will cause problems if we are creating a media that has an assigned media
|
|
;byte, i.e. 160,180,320,360, or 720k media using /N/T. To avoid this problem,
|
|
;if we detect a /N/T combo that would correspond to one of these medias, then
|
|
; we will set things up using the /4/1/8 switches instead of the /N/T
|
|
; MT - 7/17/86 PTR 33D0110
|
|
|
|
; Combo's that we look for - 96tpi drive @ /T:40, /N:9
|
|
; 96tpi drive @ /T:40, /N:8
|
|
;
|
|
; Look for this combo after we set everything up with the /T/N routine
|
|
; 1.44 drive @ /T:80, /N:9
|
|
|
|
NT_Compatible:
|
|
cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
|
|
jne Goto_Got_BPB
|
|
|
|
cmp TrackCnt,40 ;Look for 40 tracks
|
|
jne Got_BPB_Ok
|
|
|
|
cmp NumSectors,9 ;9 sectors?
|
|
je Found_48tpi_Type
|
|
|
|
cmp NumSectors,8 ;8 sectors?
|
|
jne Goto_Got_BPB ;Nope, different type, let it go thru
|
|
|
|
or SwitchMap,SWITCH_8 ;Yes, turn on /8 switch
|
|
|
|
Found_48tpi_Type:
|
|
and SwitchMap,not (SWITCH_N or SWITCH_T) ;Turn off /T/N
|
|
|
|
;******End PTR fix
|
|
|
|
; if we have a 96 tpi drive then we will be using it in 48 tpi mode
|
|
Use_48tpi:
|
|
cmp byte ptr deviceParameters.DP_DeviceType, DEV_5INCH96TPI
|
|
jne Not96tpi
|
|
|
|
mov byte ptr deviceParameters.DP_MediaType, 1
|
|
mov word ptr deviceParameters.DP_Cylinders, 40
|
|
Not96tpi:
|
|
|
|
; Since we know we are formatting in 48 tpi mode turn on /4 switch
|
|
; (We use this info in LastChanceToSaveIt)
|
|
or switchmap, SWITCH_4
|
|
|
|
; At this point we know that we will require a special BPB
|
|
; It will be one of:
|
|
; 0) 9 track 2 sides - if no switches
|
|
; 1) 9 track 1 side - if only /1 specified
|
|
; 2) 8 track 2 sides - if only /8 specified
|
|
; 3) 8 track 1 side - if /8 and /1 specified
|
|
;
|
|
Get_BPBs:
|
|
; ax is used to keep track of which of the above BPB's we want
|
|
xor ax, ax
|
|
|
|
; /B implies /8
|
|
test switchmap, SWITCH_B
|
|
jz NotSlashB
|
|
or switchmap, SWITCH_8
|
|
NotSlashB:
|
|
|
|
test switchmap, SWITCH_1
|
|
jz NotSingleSided
|
|
add ax, 1
|
|
NotSingleSided:
|
|
|
|
test switchmap, SWITCH_8
|
|
jz Not8SectorsPerTrack
|
|
add ax, 2
|
|
; /8 implies Old_Dir = TRUE
|
|
mov Old_Dir,TRUE
|
|
Not8SectorsPerTrack:
|
|
|
|
; Ok now we know which BPB to use so lets move it to the device parameters
|
|
|
|
mov bx, size a_BPB
|
|
mul bx
|
|
lea si, CustomBPBs
|
|
add si, ax
|
|
lea di, deviceParameters.DP_BPB
|
|
mov cx, size a_BPB
|
|
push ds
|
|
pop es
|
|
repnz movsb
|
|
|
|
;*****************************************************************
|
|
;* /N/T DCR stuff. Possible flaw exists if we are dealing with a
|
|
;* HardDisk. If they support the "custom format" features for
|
|
;* Harddisks too, then CheckForInterestingSwitches should
|
|
;* consider /n/t UNinteresting, and instead of returning
|
|
;* after setting up the custom BPB we fall through and do our
|
|
;* Harddisk Check.
|
|
Got_BPB_OK:
|
|
test switchmap,SWITCH_N+SWITCH_T
|
|
jnz Setup_Stuff
|
|
jmp EndSwitchCheck
|
|
Setup_Stuff:
|
|
; Set up NumSectors and SectorsPerTrack entries correctly
|
|
test switchmap,SWITCH_N
|
|
jz No_Custom_Seclim
|
|
mov ax,word ptr NumSectors
|
|
mov DeviceParameters.DP_BPB.BPB_SectorsPerTrack,ax
|
|
jmp short Handle_Cyln
|
|
No_Custom_Seclim:
|
|
mov ax,deviceParameters.DP_BPB.BPB_SectorsPerTrack
|
|
mov NumSectors,ax
|
|
|
|
Handle_Cyln:
|
|
test switchmap,SWITCH_T
|
|
jz No_Custom_Cyln
|
|
; Set up TrackCnt and Cylinders entries correctly
|
|
mov ax,TrackCnt
|
|
mov DeviceParameters.DP_Cylinders,ax
|
|
jmp short Check_720
|
|
No_Custom_Cyln:
|
|
mov ax,DeviceParameters.DP_Cylinders
|
|
mov TrackCnt,ax
|
|
|
|
;****PTM P868 - Always making 3 1/2 media byte 0F0h. If 720, then set to
|
|
; 0F9h and use the DOS 3.20 BPB. Should check all drives
|
|
; at this point (Make sure not 5 inch just for future
|
|
; protection)
|
|
; We will use the known BPB info for 720 3 1/2 diskettes for
|
|
; this special case. All other new diskette media will use the
|
|
; calculations that follow Calc_Total for BPB info.
|
|
; Fix MT 11/12/86
|
|
|
|
Check_720:
|
|
|
|
cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH96TPI
|
|
je Calc_Total
|
|
|
|
cmp byte ptr deviceParameters.DP_DeviceType,DEV_5INCH
|
|
je Calc_Total
|
|
|
|
cmp TrackCnt,80
|
|
jne Calc_Total
|
|
|
|
cmp NumSectors,9
|
|
jne Calc_Total
|
|
|
|
; At this point we know we have a 3 1/2 720kb diskette to format. Use the
|
|
; built in BPB rather than the one handed to us by DOS, because the DOS one
|
|
; will be based on the default for that drive, and it can be different from
|
|
; what we used in DOS 3.20 for the 720's. Short sighted on our part to use
|
|
; 0F9h as the media byte, should have use 0F0h (OTHER) and then we wouldn't
|
|
; have this problem.
|
|
|
|
SaveReg <ds,es,si,di,cx>
|
|
|
|
|
|
mov cx,seg data ;Setup seg regs, just in case they ain't!
|
|
mov ds,cx
|
|
mov es,cx
|
|
|
|
mov si,offset BPB720 ;Copy the BPB!
|
|
mov di,offset deviceParameters.DP_BPB
|
|
mov cx,size a_BPB
|
|
rep movsb
|
|
RestoreReg <cx,di,si,es,ds>
|
|
jmp EndSwitchCheck
|
|
|
|
;End PTM P868 fix ****************************************
|
|
|
|
Calc_Total:
|
|
mov ax,NumSectors
|
|
mov bx,DeviceParameters.DP_BPB.BPB_Heads
|
|
mul bl ; AX = # of sectors * # of heads
|
|
mul TrackCnt ; DX:AX = Total Sectors
|
|
or dx,dx
|
|
jnz Got_BigTotalSectors
|
|
mov DeviceParameters.DP_BPB.BPB_TotalSectors,ax
|
|
jmp short Set_BPB
|
|
Got_BigTotalSectors:
|
|
mov DeviceParameters.DP_BPB.BPB_BigTotalSectors,ax
|
|
mov DeviceParameters.DP_BPB.BPB_BigTotalSectors+2,dx
|
|
push dx ; preserve dx for further use
|
|
xor dx,dx
|
|
mov DeviceParameters.DP_BPB.BPB_TotalSectors,dx
|
|
pop dx
|
|
|
|
Set_BPB:
|
|
; We calculate the number of sectors required in a FAT. This is done as:
|
|
; # of FAT Sectors = TotalSectors / SectorsPerCluster * # of bytes in FAT to
|
|
; represent one cluster (i.e. 3/2) / BytesPerSector (i.e. 512)
|
|
xor bx,bx
|
|
mov bl,DeviceParameters.DP_BPB.BPB_SectorsPerCluster
|
|
div bx ; DX:AX contains # of clusters
|
|
; now multiply by 3/2
|
|
mov bx,3
|
|
mul bx
|
|
mov bx,2
|
|
div bx
|
|
xor dx,dx ; throw away modulo
|
|
; now divide by 512
|
|
mov bx,512
|
|
div bx
|
|
; dx:ax contains number of FAT sectors necessary
|
|
inc ax ; Go one higher
|
|
mov DeviceParameters.DP_BPB.BPB_SectorsPerFAT,ax
|
|
mov DeviceParameters.DP_MediaType,0
|
|
mov DeviceParameters.DP_BPB.BPB_MediaDescriptor,Custom_Media
|
|
|
|
|
|
EndSwitchCheck:
|
|
clc
|
|
return
|
|
|
|
CheckSwitches endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; LastChanceToSaveIt:
|
|
; This routine is called when an error is detected in DiskFormat.
|
|
; If it returns with carry not set then DiskFormat is restarted.
|
|
; It gives the oem one last chance to try formatting differently.
|
|
; fLastChance gets set Then to prevent multiple prompts from being
|
|
; issued for the same diskette.
|
|
;
|
|
; Algorithm:
|
|
; IF (error_loc == Track_0_Head_1) &
|
|
; ( Device_type < 96TPI )
|
|
; THEN
|
|
; fLastChance := TRUE
|
|
; try formatting 48TPI_Single_Sided
|
|
; ELSE return ERROR
|
|
;
|
|
LastChanceToSaveIt proc near
|
|
|
|
cmp currentCylinder, 0
|
|
jne WeCanNotIgnoreThisError
|
|
cmp currentHead, 1
|
|
jne WeCanNotIgnoreThisError
|
|
|
|
cmp deviceParameters.DP_DeviceType, DEV_5INCH
|
|
ja WeCanNotIgnoreThisError
|
|
|
|
mov fLastChance, TRUE
|
|
|
|
or switchmap, SWITCH_1
|
|
call CheckSwitches
|
|
clc
|
|
ret
|
|
|
|
WeCanNotIgnoreThisError:
|
|
stc
|
|
ret
|
|
|
|
LastChanceToSaveIt endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
WriteBootSector proc near
|
|
|
|
; Copy BPB to boot sector
|
|
lea si, deviceParameters.DP_BPB
|
|
lea di, bootBPB
|
|
mov cx, size a_BPB
|
|
push ds
|
|
pop es
|
|
repnz movsb
|
|
|
|
; Write out the boot sector
|
|
mov al, drive
|
|
mov cx, 1
|
|
xor dx, dx
|
|
lea bx, boot
|
|
int 26H
|
|
pop ax
|
|
jc CanNotWriteBoot
|
|
return
|
|
|
|
CanNotWriteBoot:
|
|
lea dx, msgBootWriteError
|
|
call PrintString
|
|
stc
|
|
ret
|
|
|
|
WriteBootSector endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; OemDone:
|
|
;
|
|
OemDone proc near
|
|
|
|
; if /b write out a fake dos & bios
|
|
test switchmap, SWITCH_B
|
|
jz Switch8?
|
|
call WriteBogusDos
|
|
retc
|
|
|
|
Switch8?:
|
|
test switchmap, SWITCH_8
|
|
jz HardDisk?
|
|
call ConvertToOldDirectoryFormat
|
|
retc
|
|
|
|
HardDisk?:
|
|
cmp deviceParameters.DP_DeviceType, DEV_HARDDISK
|
|
clc
|
|
retnz
|
|
call SetPartitionTable
|
|
|
|
return
|
|
|
|
OemDone endp
|
|
|
|
;------------------------------------------------------------------------------
|
|
|
|
data segment
|
|
|
|
biosFilename db "x:\io.sys",0
|
|
dosFilename db "x:\msdos.sys",0
|
|
|
|
data ends
|
|
|
|
; simple code to stuff bogus dos in old-style diskette.
|
|
|
|
|
|
BogusDos:
|
|
push cs
|
|
pop ds
|
|
mov al,20h
|
|
out 20h,al ; turn on the timer so the disk motor
|
|
mov si,mesofs ; shuts off
|
|
sys_mess_loop:
|
|
lodsb
|
|
end_sys_loop:
|
|
or al,al
|
|
jz end_sys_loop
|
|
mov ah,14
|
|
mov bx,7
|
|
int 16
|
|
jmp sys_mess_loop
|
|
|
|
include bootmes.inc
|
|
|
|
mesofs equ no_sys_mess - BogusDos
|
|
|
|
WriteBogusDos proc near
|
|
|
|
mov al,driveLetter
|
|
mov biosFilename,al
|
|
mov dosFilename,al
|
|
mov cx, ATTR_HIDDEN or ATTR_SYSTEM
|
|
lea dx, biosFilename
|
|
mov ah,CREAT
|
|
int 21h
|
|
mov bx,ax
|
|
mov cx, BIOS_SIZE
|
|
push ds
|
|
push cs
|
|
pop ds
|
|
assume ds:code
|
|
lea dx, BogusDos
|
|
mov ah,WRITE
|
|
int 21h
|
|
pop ds
|
|
assume ds:data
|
|
mov ah,CLOSE
|
|
int 21h
|
|
mov cx, ATTR_HIDDEN or ATTR_SYSTEM
|
|
lea dx, dosFilename
|
|
mov ah,CREAT
|
|
int 21h
|
|
mov bx,ax
|
|
mov cx, DOS_SIZE
|
|
lea dx, BogusDos
|
|
mov ah,WRITE
|
|
int 21h
|
|
mov ah,CLOSE
|
|
int 21h
|
|
; Comunicate system size to the main format program
|
|
xor dx,dx
|
|
mov ax,DOS_SIZE
|
|
call AddToSystemSize
|
|
xor dx,dx
|
|
mov ax,BIOS_SIZE
|
|
call AddToSystemSize
|
|
|
|
clc
|
|
return
|
|
|
|
WriteBogusDos endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
ConvertToOldDirectoryFormat proc near
|
|
|
|
;
|
|
; convert to 1.1 directory
|
|
;
|
|
mov al,drive ; Get 1st sector of directory
|
|
mov cx,1 ; 1.1 directory always starts on
|
|
mov dx,3 ; sector 3
|
|
lea bx,scratchBuffer
|
|
int 25h
|
|
pop ax ; clean up stack
|
|
jnc DirectoryRead
|
|
lea dx, msgDirectoryReadError
|
|
call PrintString
|
|
stc
|
|
ret
|
|
DirectoryRead:
|
|
|
|
; fix attribute of io.sys and msdos.sys
|
|
lea bx,scratchBuffer
|
|
mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
|
|
add bx, size dir_entry
|
|
mov byte ptr [bx].dir_attr, ATTR_HIDDEN or ATTR_SYSTEM
|
|
|
|
wrtdir:
|
|
mov al,[drive] ; write out the directory
|
|
cbw
|
|
mov cx,1
|
|
mov dx,3
|
|
lea bx,scratchBuffer
|
|
int 26h
|
|
pop ax ; clean up stack
|
|
jnc DirectoryWritten
|
|
lea dx, msgDirectoryWriteError
|
|
call PrintString
|
|
stc
|
|
ret
|
|
DirectoryWritten:
|
|
|
|
test switchmap, SWITCH_S ; Was system requested?
|
|
retnz ; yes, don't write old boot sector
|
|
mov al,drive
|
|
cbw
|
|
mov bx,offset boot2 ; no, write old boot sector
|
|
cmp deviceParameters.DP_BPB.BPB_Heads, 1
|
|
je bootset8
|
|
mov word ptr [bx+3],0103h ; start address for double sided drives
|
|
bootset8:
|
|
mov cx,1
|
|
xor dx,dx
|
|
int 26h ; write out that boot sector
|
|
pop ax
|
|
retnc
|
|
|
|
lea dx, msgBootWriteError
|
|
call PrintString
|
|
stc
|
|
ret
|
|
|
|
ConvertToOldDirectoryFormat endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
a_PartitionTableEntry struc
|
|
BootInd db ?
|
|
BegHead db ?
|
|
BegSector db ?
|
|
BegCylinder db ?
|
|
SysInd db ?
|
|
EndHead db ?
|
|
EndSector db ?
|
|
EndCylinder db ?
|
|
RelSec dd ?
|
|
CSec dd ?
|
|
a_PartitionTableEntry ends
|
|
|
|
; structure of the IBM hard disk boot sector:
|
|
IBMBoot STRUC
|
|
db 512 - (4*size a_PartitionTableEntry + 2) dup(?)
|
|
PartitionTable db 4*size a_PartitionTableEntry dup(?)
|
|
Signature dw ?
|
|
IBMBoot ENDS
|
|
|
|
|
|
SetPartitionTable proc near
|
|
|
|
mov ax, 0 ; Head
|
|
mov bx, 0 ; Cylinder
|
|
mov cx, 0 ; Sector
|
|
lea dx, boot2
|
|
call ReadSector
|
|
jnc PartitionTableRead
|
|
lea dx, msgPartitionTableReadError
|
|
call PrintString
|
|
stc
|
|
ret
|
|
PartitionTableRead:
|
|
|
|
; Check to see if there is a partition table (by looking for its signature)
|
|
cmp boot2.signature, 0aa55H
|
|
jne BadPartitionTable
|
|
|
|
; Scan all the partitions search for the FIRST DOS partition. We then set the
|
|
; appropriate FAT size in the FIRST DOS partition and return.
|
|
|
|
lea bx, boot2.PartitionTable
|
|
partitionscan:
|
|
|
|
; have we scanned all partitions?
|
|
cmp bx,(offset Boot2.PartitionTable)+4*size a_PartitionTableEntry
|
|
jae BadPartitionTable
|
|
|
|
cmp [bx].sysind,1
|
|
jz dochange
|
|
cmp [bx].sysind,4
|
|
jz dochange
|
|
|
|
add bx,size a_PartitionTableEntry
|
|
jmp partitionscan
|
|
|
|
dochange:
|
|
mov [bx].sysind,4 ; assume 16 bit fat
|
|
cmp fbigfat,0 ; test assumption
|
|
jnz partitionset ; is 16 bit fat, assumption correct
|
|
mov [bx].sysind,1 ; 12 bit fat, pre 3.0 dos can read it
|
|
|
|
partitionset:
|
|
mov ax, 0 ; Head
|
|
mov bx, 0 ; Cylinder
|
|
mov cx, 0 ; Sector
|
|
lea dx, boot2
|
|
call WriteSector
|
|
retnc
|
|
|
|
lea dx, msgPartitionTableWriteError
|
|
call PrintString
|
|
stc
|
|
ret
|
|
|
|
BadPartitionTable:
|
|
lea dx, msgBadPartitionTable
|
|
call PrintString
|
|
stc
|
|
ret
|
|
|
|
SetPartitionTable endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; ReadSector:
|
|
; Read one sector
|
|
;
|
|
; Input:
|
|
; ax - head
|
|
; bx - cylinder
|
|
; cx - sector
|
|
; dx - transfer address
|
|
|
|
ReadSector proc near
|
|
|
|
mov TrackReadWritePacket.TRWP_FirstSector, cx
|
|
mov cx,(RAWIO shl 8) or READ_TRACK
|
|
call SectorIO
|
|
return
|
|
|
|
ReadSector endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; WriteSector:
|
|
; Write one sector
|
|
;
|
|
; Input:
|
|
; ax - head
|
|
; bx - cylinder
|
|
; cx - sector
|
|
; dx - transfer address
|
|
|
|
WriteSector proc near
|
|
|
|
mov TrackReadWritePacket.TRWP_FirstSector, cx
|
|
mov cx,(RAWIO shl 8) or WRITE_TRACK
|
|
call SectorIO
|
|
return
|
|
|
|
WriteSector endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
; SectorIO:
|
|
; Read/Write one sector
|
|
;
|
|
; Input:
|
|
; ax - head
|
|
; bx - cylinder
|
|
; cx - (RAWIO shl 8) or READ_TRACK
|
|
; - (RAWIO shl 8) or WRITE_TRACK
|
|
; dx - transfer address
|
|
|
|
SectorIO proc near
|
|
|
|
mov TrackReadWritePacket.TRWP_Head, ax
|
|
mov TrackReadWritePacket.TRWP_Cylinder, bx
|
|
mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress, dx
|
|
mov WORD PTR TrackReadWritePacket.TRWP_TransferAddress + 2, ds
|
|
mov TrackReadWritePacket.TRWP_SectorsToReadWrite, 1
|
|
|
|
mov bl, drive
|
|
inc bl
|
|
mov ax, (IOCTL shl 8) or GENERIC_IOCTL
|
|
lea dx, trackReadWritePacket
|
|
int 21H
|
|
return
|
|
|
|
SectorIO endp
|
|
|
|
;-------------------------------------------------------------------------------
|
|
|
|
data segment
|
|
|
|
oldDrive db ?
|
|
|
|
FCBforVolumeIdSearch db 0ffH
|
|
db 5 dup(0)
|
|
db 08H
|
|
db 0
|
|
db "???????????"
|
|
db 40 DUP(0)
|
|
|
|
data ends
|
|
|
|
GetVolumeId proc near
|
|
; Input:
|
|
; dl = drive
|
|
; di = name buffer
|
|
|
|
; Save current drive
|
|
mov ah,19H
|
|
int 21H
|
|
mov oldDrive, al
|
|
|
|
; Change current drive to the drive that has the volume id we want
|
|
mov ah, 0eH
|
|
int 21H
|
|
|
|
; Search for the volume id
|
|
mov ah, 11H
|
|
lea dx, FCBforVolumeIdSearch
|
|
int 21H
|
|
push ax
|
|
|
|
; Restore current drive
|
|
mov ah, 0eH
|
|
mov dl,oldDrive
|
|
int 21H
|
|
|
|
; Did the search succeed?
|
|
pop ax
|
|
or al,al
|
|
jz CopyVolumeId
|
|
stc
|
|
ret
|
|
|
|
CopyVolumeId:
|
|
; Find out where the FCB for the located volume id was put
|
|
mov ah,2fH
|
|
int 21H
|
|
|
|
; Copy the Volume Id
|
|
mov si, bx
|
|
add si, 8
|
|
push es
|
|
push ds
|
|
pop es
|
|
pop ds
|
|
mov cx, 11
|
|
rep movsb
|
|
push es
|
|
pop ds
|
|
|
|
clc
|
|
ret
|
|
|
|
GetVolumeId endp
|
|
|
|
data segment
|
|
oldVolumeId db 11 dup(0)
|
|
data ends
|
|
|
|
CheckVolumeId proc near
|
|
|
|
; Get the volume id that's on the disk
|
|
lea di, oldVolumeId
|
|
mov dl, drive
|
|
call GetVolumeId
|
|
jnc Ask_User ;Did we find one?
|
|
clc ;No, return with no error
|
|
ret
|
|
|
|
; Ask the user to enter the volume id that he/she thinks is on the disk
|
|
; (first blank out the input buffer)
|
|
Ask_User:
|
|
lea dx, ptr_msgWhatIsVolumeId?
|
|
call std_printf
|
|
call user_string
|
|
call crlf
|
|
|
|
; If the user just pressed ENTER, then there must be no label
|
|
cmp inbuff+1, 0
|
|
jne CompareVolumeIds
|
|
cmp oldVolumeId, 0
|
|
jne BadVolumeId
|
|
ret
|
|
|
|
CompareVolumeIds:
|
|
; pad the reponse with blanks
|
|
; The buffer is big enough so just add 11 blanks to what the user typed in
|
|
push ds
|
|
pop es
|
|
mov cx, 11
|
|
xor bx,bx
|
|
mov bl, inbuff + 1
|
|
lea di, inbuff + 2
|
|
add di, bx
|
|
mov al, ' '
|
|
rep stosb
|
|
; Make the reply all uppercase
|
|
mov cl, inbuff + 1
|
|
xor ch,ch
|
|
lea si, inbuff + 2
|
|
VolumeToUpper:
|
|
mov al, [si]
|
|
cmp al, 'a'
|
|
jb NextLetter
|
|
cmp al, 'z'
|
|
ja NextLetter
|
|
sub al, 'a' - 'A'
|
|
mov [si],al
|
|
NextLetter:
|
|
inc si
|
|
loop VolumeToUpper
|
|
|
|
; Now compare what the user specified with what is really out there
|
|
mov cx, 11
|
|
lea si, inbuff + 2
|
|
lea di, oldVolumeId
|
|
repe cmpsb
|
|
jne BadVolumeId
|
|
ret
|
|
|
|
BadVolumeId:
|
|
lea dx, msgBadVolumeId
|
|
call PrintString
|
|
stc
|
|
ret
|
|
|
|
CheckVolumeId endp
|
|
|
|
code ends
|
|
end
|