2030 lines
51 KiB
NASM
2030 lines
51 KiB
NASM
;/*
|
||
; * Microsoft Confidential
|
||
; * Copyright (C) Microsoft Corporation 1991
|
||
; * All Rights Reserved.
|
||
; */
|
||
;===========================================================================
|
||
;
|
||
; FILE: PHASE1.ASM
|
||
;
|
||
;===========================================================================
|
||
|
||
;===========================================================================
|
||
;Include file declarations
|
||
;===========================================================================
|
||
debug equ 0
|
||
.xlist
|
||
INCLUDE DOSEQUS.INC
|
||
INCLUDE DOSMAC.INC
|
||
INCLUDE SYSCALL.INC
|
||
INCLUDE ERROR.INC
|
||
INCLUDE DIRENT.INC
|
||
INCLUDE BPB.INC
|
||
INCLUDE BOOTSEC.INC
|
||
INCLUDE FOREQU.INC
|
||
INCLUDE FORMACRO.INC
|
||
INCLUDE IOCTL.INC
|
||
INCLUDE FORSWTCH.INC
|
||
.list
|
||
;
|
||
;---------------------------------------------------------------------------
|
||
;
|
||
; M020 : Looked for EXT_BOOT_SIG before assuming that the BPB in the boot
|
||
; sector is an extended one. Bug #4946
|
||
;
|
||
;---------------------------------------------------------------------------
|
||
;
|
||
|
||
|
||
|
||
;===========================================================================
|
||
; Data segment
|
||
;===========================================================================
|
||
|
||
DATA SEGMENT PUBLIC PARA 'DATA'
|
||
|
||
;===========================================================================
|
||
; Declarations for all publics in other modules used by this module
|
||
;===========================================================================
|
||
|
||
;Constants
|
||
EXTRN EXIT_NO :ABS
|
||
EXTRN EXIT_FATAL :ABS
|
||
;Bytes
|
||
EXTRN CMCDDFlag :BYTE
|
||
|
||
EXTRN ValidSavedDeviceParameters:BYTE
|
||
EXTRN DriveToFormat :BYTE
|
||
EXTRN msgFormatNotSupported :BYTE
|
||
EXTRN msgInsertDisk :BYTE
|
||
EXTRN msgInvalidDeviceParameters:BYTE
|
||
EXTRN ContinueMsg :BYTE
|
||
EXTRN msgNotCompatablePart :BYTE
|
||
EXTRN msgExistingFormatDiffers :BYTE
|
||
EXTRN msgNoQuickFormat :BYTE
|
||
EXTRN msgCrLf :BYTE
|
||
EXTRN msgCheckExistingDiskFormat:BYTE
|
||
EXTRN Extended_Error_Msg :BYTE
|
||
EXTRN old_dir :BYTE
|
||
EXTRN ExitStatus :BYTE
|
||
ifdef NEC_98
|
||
EXTRN SizeMap :BYTE
|
||
EXTRN msgInsufficientMemory :BYTE
|
||
endif
|
||
|
||
;Words
|
||
EXTRN SectorsInRootDirectory :WORD
|
||
EXTRN Paras_Per_Fat :WORD
|
||
EXTRN SwitchMap :WORD
|
||
EXTRN SwitchMap2 :WORD
|
||
EXTRN SwitchCopy :WORD
|
||
ifdef NEC_98
|
||
EXTRN SASI1024Table :WORD
|
||
EXTRN SCSI1024Table :WORD
|
||
EXTRN Small2048Table :WORD
|
||
EXTRN Large512Table :WORD
|
||
EXTRN Large256Table :WORD
|
||
else
|
||
EXTRN DiskTable :WORD
|
||
EXTRN DiskTable2 :WORD
|
||
endif
|
||
EXTRN RWErrorCode :WORD
|
||
|
||
;Pointers
|
||
EXTRN FatSpace :DWORD
|
||
|
||
;Structures
|
||
EXTRN SavedParams :BYTE
|
||
EXTRN DeviceParameters :BYTE
|
||
EXTRN IsExtRAWIODrv :BYTE
|
||
EXTRN SwitchDevParams :BYTE
|
||
EXTRN Read_Write_Relative :BYTE
|
||
EXTRN SetDPBPacket :BYTE
|
||
|
||
fBigFat DB FALSE
|
||
fBig32Fat DB FALSE
|
||
ThisSysInd DB 0 ; indicates size of FAT
|
||
|
||
StartSector DD ? ; holds first data sector
|
||
TotalClusters DD ? ; holds total #clusters on disk
|
||
|
||
UnformattedHardDrive DB ?
|
||
ifdef NEC_98
|
||
SAV_INT24_OFF DW 0 ; original int 24 vector address
|
||
SAV_INT24_SEG DW 0
|
||
endif
|
||
|
||
MediaSensePacket A_MEDIA_SENSE <> ; structure used in media
|
||
; sensing call
|
||
|
||
; the following table provides templates for
|
||
; BPBs used in CP/M disks.
|
||
; Order is very important (used by both MSFOR and PHASE1)
|
||
|
||
CustomCPMBPBs LABEL BYTE
|
||
BPB320 a_BPB <512, 2, 1, 2, 112, 2*8*40, 0ffh, 1, 8, 2, 0, 0, 0, 0>
|
||
BPB160 a_BPB <512, 1, 1, 2, 64, 1*8*40, 0feh, 1, 8, 1, 0, 0, 0, 0>
|
||
BPB360 a_BPB <512, 2, 1, 2, 112, 2*9*40, 0fdh, 2, 9, 2, 0, 0, 0, 0>
|
||
BPB180 a_BPB <512, 1, 1, 2, 64, 1*9*40, 0fch, 2, 9, 1, 0, 0, 0, 0>
|
||
|
||
EndCustomCPMBPBs LABEL BYTE
|
||
|
||
; This must folow CustomCPMBPBs
|
||
|
||
BPB12 a_BPB <512, 1, 1, 2, 224, 2*15*80, 0F9h, 7, 15, 2, 0, 0, 0, 0>
|
||
BPB720 a_BPB <512, 2, 1, 2, 112, 2* 9*80, 0F9h, 3, 9, 2, 0, 0, 0, 0>
|
||
BPB1440 a_BPB <512, 1, 1, 2, 224, 2*18*80, 0F0h, 9, 18, 2, 0, 0, 0, 0>
|
||
BPB2880 a_BPB <512, 2, 1, 2, 240, 2*36*80, 0F0h, 9, 36, 2, 0, 0, 0, 0>
|
||
ifdef NEC_98
|
||
BPB640 a_BPB <512, 2, 1, 2, 112, 2* 8*80, 0FBh, 2, 8, 2, 0, 0, 0, 0>
|
||
BPB1250 a_BPB <1024,1, 1, 2, 192, 2* 8*77, 0FEh, 2, 8, 2, 0, 0, 0, 0>
|
||
BPB128 a_BPB <512,4,1, 2, 512, 0, 0F0h, 0F3h, 019h, 1, 0,0, 0CBE0h, 03h>
|
||
BPB230 a_BPB <512,8,1, 2, 512, 0, 0F0h, 0DAh, 019h, 1, 0,0, 0CF75h, 06h>
|
||
BPB650 a_BPB <512,020h,1, 2, 512, 0, 0F0h, 09Fh, 019h, 1, 0,0, 0D040h, 013h>
|
||
endif
|
||
EndStandardBPBs LABEL BYTE
|
||
|
||
; the following table indicates the switches
|
||
; which must be set for the given CP/M media
|
||
CPMSwitchTable LABEL BYTE
|
||
dw Switch_4 + Switch_8 ;320K
|
||
dw Switch_1 + Switch_4 + Switch_8 ;160K
|
||
dw Switch_4 ;360K
|
||
dw Switch_1 + Switch_4 ;180K
|
||
|
||
; ========================================================================
|
||
; Tables added for media sense support in 5.00.
|
||
; ========================================================================
|
||
|
||
MediaTable LABEL WORD
|
||
|
||
ifdef NEC_98
|
||
dw 0 ; 0
|
||
dw OFFSET BPB12 ; 1 /5
|
||
dw OFFSET BPB720 ; 2 /9
|
||
dw 0 ; 3
|
||
dw OFFSET BPB1250 ; 4 /M
|
||
dw 0 ; 5
|
||
dw 0 ; 6
|
||
dw OFFSET BPB1440 ; 7 /4
|
||
dw 0 ; 8
|
||
dw OFFSET BPB2880 ; 9 not supported! but rest.
|
||
else
|
||
dw 0 ; 0
|
||
dw 0 ; 1
|
||
dw OFFSET BPB720 ; 2
|
||
dw 0 ; 3
|
||
dw 0 ; 4
|
||
dw 0 ; 5
|
||
dw 0 ; 6
|
||
dw OFFSET BPB1440 ; 7
|
||
dw 0 ; 8
|
||
dw OFFSET BPB2880 ; 9
|
||
endif
|
||
|
||
EndMediaTable LABEL WORD
|
||
|
||
DATA ENDS
|
||
|
||
;===========================================================================
|
||
; Executable code segment
|
||
;===========================================================================
|
||
|
||
CODE SEGMENT PUBLIC PARA 'CODE'
|
||
ASSUME CS:CODE, DS:DATA, ES:DATA
|
||
|
||
|
||
;===========================================================================
|
||
; Declarations for all externs
|
||
;===========================================================================
|
||
|
||
;Functions
|
||
EXTRN AccessDisk :NEAR
|
||
EXTRN USER_STRING :NEAR
|
||
EXTRN CrLf :NEAR
|
||
EXTRN CheckSwitches :NEAR
|
||
EXTRN Read_Disk :NEAR
|
||
EXTRN Yes? :NEAR
|
||
ifdef NEC_98
|
||
EXTRN GetDeviceParameters :NEAR
|
||
EXTRN Alloc_Dir_Buf :NEAR
|
||
EXTRN Alloc_Fat_Buf :NEAR
|
||
EXTRN Alloc_Fat_Sec_Buf :NEAR
|
||
EXTRN Alloc_DirBuf2 :NEAR
|
||
EXTRN Alloc_Cluster_Buf :NEAR
|
||
ifdef OPKBLD
|
||
EXTRN Do_Switch_S :NEAR
|
||
endif ;OPKBLD
|
||
EXTRN ZeroAllBuffers :NEAR
|
||
endif ;NEC_98
|
||
|
||
;Labels
|
||
EXTRN FatalExit :NEAR
|
||
EXTRN ExitProgram :NEAR
|
||
|
||
|
||
;===========================================================================
|
||
; Declarations for all publics in this module
|
||
;===========================================================================
|
||
|
||
PUBLIC Phase1Initialisation
|
||
PUBLIC MediaSense
|
||
PUBLIC TargPrm
|
||
PUBLIC CopyToSwitchDevParams
|
||
PUBLIC CompareDevParams
|
||
PUBLIC LoadSwitchDevParams
|
||
PUBLIC DetermineExistingFormat
|
||
PUBLIC DetermineExistingFormatNomsg
|
||
PUBLIC IsValidBpb
|
||
PUBLIC ResetDeviceParameters
|
||
PUBLIC DetermineCPMFormat
|
||
PUBLIC SetCPMParameters
|
||
PUBLIC Set_BPB_Info
|
||
PUBLIC Scan_Disk_Table
|
||
PUBLIC Calc_Big16_Fat
|
||
PUBLIC Calc_Big32_Fat
|
||
PUBLIC Calc_Small_Fat
|
||
PUBLIC SetStartSector
|
||
PUBLIC SetfBigFat
|
||
PUBLIC GetTotalClusters
|
||
PUBLIC fBigFat
|
||
PUBLIC fBig32Fat
|
||
PUBLIC StartSector
|
||
PUBLIC TotalClusters
|
||
PUBLIC CustomCPMBPBs
|
||
PUBLIC CPMSwitchTable
|
||
PUBLIC EndStandardBPBs
|
||
PUBLIC BPB720
|
||
ifdef NEC_98
|
||
PUBLIC BPB640
|
||
PUBLIC BPB12
|
||
PUBLIC BPB1250
|
||
PUBLIC BPB128
|
||
PUBLIC BPB230
|
||
PUBLIC BPB650
|
||
endif
|
||
PUBLIC UnformattedHardDrive
|
||
|
||
; ==========================================================================
|
||
; Phase1Initialisation:
|
||
; This routine sets up fBigFat
|
||
; It also does most of the other initialisation
|
||
;
|
||
; Algorithm:
|
||
; Perform media sensing and if present adjust DeviceParameters
|
||
; Check switches against parameters
|
||
; Use switches to modify device parameters
|
||
; Save a copy of current DeviceParameters in SwitchDevParams
|
||
;
|
||
; IF (!SWITCH_U)
|
||
; {
|
||
; IF (!ValidBootRecord || !ValidBPB)
|
||
; set SWITCH_U
|
||
; ELSE
|
||
; {
|
||
; get device layout from BPB on disk
|
||
; IF (DeviceParameters = SwitchDevParams)
|
||
; do safe/quick format
|
||
; ELSE
|
||
; {
|
||
; IF (Switch_N || Switch_T || Switch_F)
|
||
; {
|
||
; Issue warning
|
||
; Format with BPB from SwitchDevParams if user continues
|
||
; }
|
||
; ELSE
|
||
; do safe/quick format
|
||
; }
|
||
; }
|
||
; }
|
||
;
|
||
; Calculate start sector (first sector not used by DOS)
|
||
; fBig32Fat = (((TotalSectors - StartSector)/SectorsPerCluster) >= 65526)
|
||
; fBigFat = (((TotalSectors - StartSector)/SectorsPerCluster) >= 4086)
|
||
; ==========================================================================
|
||
|
||
Phase1Initialisation proc near
|
||
|
||
; use DevParms to check for removable
|
||
test DeviceParameters.DP_DeviceAttributes,1
|
||
.errnz EDP_DEVICEATTRIBUTES NE DP_DEVICEATTRIBUTES
|
||
jnz @F ; Bit 0=1 --> not removable
|
||
|
||
; New media sensing call added for 5.00 will see if
|
||
; see if media sensing is avaliable and if it is will
|
||
; reset DeviceParameters to the real parameters for
|
||
; the type of disk being formatted.
|
||
|
||
ifndef NEC_98
|
||
call MediaSense
|
||
else
|
||
cmp DeviceParameters.DP_DeviceType, DEV_HARDDISK ; Hard disk?
|
||
.errnz EDP_DEVICETYPE NE DP_DEVICETYPE
|
||
jne @F ; No
|
||
|
||
; We ignore INT24 in order not to be stop formatting
|
||
; when "INT21 AH=32" is called.
|
||
|
||
; Set my INT24
|
||
push es
|
||
mov ah, 35h
|
||
mov al, 24h
|
||
int 21h ; get INT24's vector address
|
||
mov SAV_INT24_OFF, bx ; save original INT24
|
||
mov SAV_INT24_SEG, es ; save original INT24
|
||
pop es
|
||
|
||
push ds
|
||
push cs
|
||
pop ds
|
||
mov ah, 25h
|
||
mov al, 24h
|
||
mov dx, OFFSET MY_INT24
|
||
int 21h ; set my INT24
|
||
pop ds
|
||
|
||
; Update Default BPB
|
||
push ds
|
||
push bx
|
||
mov ah, 32h
|
||
mov dl, DriveToFormat
|
||
inc dl
|
||
int 21h ; Get Drive Parameter Block
|
||
pop bx
|
||
pop ds
|
||
|
||
; Set original INT 24
|
||
push ds
|
||
push dx
|
||
mov ah, 25h
|
||
mov al, 24h
|
||
mov ds, SAV_INT24_SEG
|
||
mov dx, SAV_INT24_OFF
|
||
int 21h ; set original INT24
|
||
pop dx
|
||
pop ds
|
||
|
||
; Get default BPB
|
||
lea DX, DeviceParameters
|
||
mov DeviceParameters.DP_SpecialFunctions, 0
|
||
call GetDeviceParameters
|
||
|
||
; Allocate memory
|
||
call Alloc_Dir_Buf ; Allocate root directory buffer
|
||
jc gi_memerr
|
||
|
||
call Alloc_Fat_Buf ; Allocate FAT buffer
|
||
jc gi_memerr
|
||
|
||
call Alloc_Fat_Sec_Buf ; Allocate fat sector buffer
|
||
jc gi_memerr
|
||
|
||
call Alloc_DirBuf2 ; Allocate 1-sector buffer DirBuf (general-
|
||
; purpose use)
|
||
jc gi_memerr
|
||
|
||
call Alloc_Cluster_Buf ; get room for retry buffer
|
||
|
||
ifdef OPKBLD
|
||
call Do_Switch_S ; Load system files if needed
|
||
; carry flag determined by Do_Switch_S
|
||
else
|
||
clc
|
||
endif ;OPKBLD
|
||
call ZeroAllBuffers ; initialize buffers
|
||
jmp short @f
|
||
|
||
gi_memerr:
|
||
Message msgInsufficientMemory
|
||
stc
|
||
ret
|
||
endif
|
||
@@:
|
||
; Ensure that there is a valid #
|
||
; of Sectors in the track table
|
||
|
||
mov ValidSavedDeviceParameters, 1
|
||
cmp IsExtRAWIODrv,0
|
||
je OldTabOff2
|
||
|
||
mov SavedParams.EDP_TrackTableEntries, 0
|
||
mov DeviceParameters.EDP_TrackTableEntries,0
|
||
jmp short SetBPBnf
|
||
|
||
OldTabOff2:
|
||
mov SavedParams.DP_TrackTableEntries, 0
|
||
; Initialise to zero to see if
|
||
; CheckSwitches define track layout
|
||
mov DeviceParameters.DP_TrackTableEntries,0
|
||
SetBPBnf:
|
||
call Set_BPB_Info ; Check to see if we are on
|
||
; Fat system.If not set BPB to proper
|
||
; values for format.
|
||
SetMTsupp:
|
||
; Check switches against parameters
|
||
; and use switches to modify device
|
||
; parameters
|
||
call CheckSwitches
|
||
retc
|
||
|
||
call CopyToSwitchDevParams ; Save a copy of deviceparameters as
|
||
; returned by CheckSwitches
|
||
|
||
mov ax,SwitchMap ; No need to check existing format
|
||
and ax,SWITCH_U+SWITCH_Q
|
||
cmp ax,SWITCH_U ; if unconditional format specified
|
||
jnz CheckExistingFormat
|
||
jmp DevParamsOk
|
||
|
||
CheckExistingFormat:
|
||
|
||
; New call added for 5.00 to see if the disk has been
|
||
; previously formatted, and if so this will reset
|
||
; DeviceParameters to those of the existing format.
|
||
|
||
call DetermineExistingFormat
|
||
jnc ValidExistingFormat ; carry clear if valid existing format
|
||
|
||
InvalidExistingFormat:
|
||
and RWErrorCode,0ffh ; check low byte for 'drive not ready' error
|
||
cmp RWErrorCode,ERROR_I24_NOT_READY ;'not ready' error code = 2
|
||
jne CheckForQ ; no error reading disk
|
||
|
||
; 'not ready' error occurred, give msg
|
||
mov AX,21 ; load AX with extended error code for not ready
|
||
SetFatalErr:
|
||
Extended_Message ; deliver message "Not Ready"
|
||
mov ExitStatus,EXIT_FATAL ; M006;
|
||
stc
|
||
jmp EndPhase1
|
||
|
||
CheckForQ:
|
||
test SwitchMap,SWITCH_Q ; Need to give message if /q was specified
|
||
jz MakeUnconditional
|
||
|
||
test SwitchCopy,(SWITCH_T or SWITCH_N or SWITCH_F) ; did user specify size?
|
||
jnz TurnOffQ ; do an unconditional format at specified size
|
||
ifdef OPKBLD
|
||
; Let OEM's quickformat a clean disk
|
||
test DeviceParameters.DP_DeviceAttributes,1
|
||
jnz DevParamsOk ; Bit 0=1 --> not removable
|
||
endif ;OPKBLD
|
||
Message msgNoQuickFormat ; Inform user quick format cannot be done
|
||
call Yes? ; Continue with unconditional format?
|
||
|
||
pushf
|
||
Message msgCrLf
|
||
popf
|
||
|
||
jnc TurnOffQ
|
||
mov ExitStatus,EXIT_NO ; load exit code 5 (response is 'no')
|
||
jmp ExitProgram ; User wants to exit
|
||
|
||
TurnOffQ:
|
||
and SwitchMap,NOT SWITCH_Q ; Turn off /Q to continue
|
||
|
||
MakeUnconditional:
|
||
or SwitchMap,SWITCH_U ; Enable /U since invalid existing format
|
||
or SwitchMap2, Switch2_C ; Enable /C since invalid existing format
|
||
jmp SHORT DevParamsOk ; Device parameters will not have been
|
||
; modified since invalid existing format
|
||
|
||
ValidExistingFormat:
|
||
call CompareDevParams ; see if SwitchDevParams = DeviceParameters
|
||
jnc DevParamsOk ; they are equal
|
||
|
||
; Check if user had specified a format
|
||
; size, since DeviceParameters on disk
|
||
; are different.
|
||
|
||
test SwitchMap,SWITCH_Q ; special case where size was specified
|
||
; together with /Q :- use size specified
|
||
; only if invalid existing format
|
||
jnz DevParamsOk ; use the parameters found on disk
|
||
or SwitchMap,SWITCH_U ; Enable /U since new format specified
|
||
or SwitchMap2, Switch2_C ; Enable /C since new format specified
|
||
call LoadSwitchDevParams ; Set deviceparameters to SwitchDevParams
|
||
; i.e. follow user-specified size
|
||
DevParamsOk:
|
||
call SetDOS_Dpb ; m035 Setup default DOS DPB for this
|
||
; drive (for memory cards).
|
||
jc SetFatalErr
|
||
; Store sector table info (layout of
|
||
; each track)
|
||
mov CX, DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerTrack;CX = loop count
|
||
.errnz EDP_BPB NE DP_BPB
|
||
mov AX, 1 ;AX = sector #
|
||
mov BX, DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector ;BX = sector size
|
||
cmp IsExtRAWIODrv,0
|
||
je OldTabOff
|
||
|
||
cmp DeviceParameters.EDP_TrackTableEntries,0
|
||
jne TrackLayoutSet ; There is a good track layout
|
||
mov DeviceParameters.EDP_TrackTableEntries,CX
|
||
lea DI, DeviceParameters.EDP_SectorTable
|
||
jmp short GotTabOff
|
||
|
||
OldTabOff:
|
||
cmp DeviceParameters.DP_TrackTableEntries,0
|
||
jne TrackLayoutSet ; There is a good track layout
|
||
mov DeviceParameters.DP_TrackTableEntries,CX
|
||
lea DI, DeviceParameters.DP_SectorTable
|
||
GotTabOff:
|
||
cld
|
||
LoadSectorTable:
|
||
stosw ; Write the sector number
|
||
xchg AX, BX ; Get the sector size in bytes
|
||
stosw ; Write the sector size
|
||
xchg AX, BX
|
||
inc AX ; Go to the next sector
|
||
loop LoadSectorTable
|
||
|
||
TrackLayoutSet:
|
||
call SetStartSector
|
||
call SetfBigFat
|
||
call GetTotalClusters
|
||
clc
|
||
|
||
EndPhase1:
|
||
return
|
||
|
||
Phase1Initialisation endp
|
||
|
||
; =========================================================================
|
||
;
|
||
; MediaSense
|
||
; Checks for media sensing via IOCtl 440d subfuction 0868.
|
||
; If sensing is supported the user will be prompted to insert
|
||
; the disk if it's not detect and then the device parameters
|
||
; will be set according to the type of media being used.
|
||
;
|
||
; Before we can use the type returned we must be sure it's
|
||
; not a larger size disk than is formattable in the drive.
|
||
; We can do this by checking the media type byte in the
|
||
; saved device parameters.
|
||
;
|
||
; Input:
|
||
; DriveToFormat - Must have already been set
|
||
;
|
||
; =========================================================================
|
||
|
||
MediaSense PROC NEAR
|
||
|
||
mov BL, DriveToFormat
|
||
inc BX
|
||
|
||
mov CX, (RAWIO shl 8) or SENSE_MEDIA_TYPE
|
||
cmp IsExtRAWIODrv,0
|
||
je DoIOCTL1
|
||
mov CX, (EXTRAWIO shl 8) or SENSE_MEDIA_TYPE
|
||
DoIOCTL1:
|
||
lea DX,MediaSensePacket
|
||
|
||
; First check if BIOS supports call
|
||
mov AX, (IOCTL shl 8) or IOCTL_QUERY_BLOCK
|
||
int 21h
|
||
jc MediaSenseExit
|
||
|
||
; Now do actual call
|
||
mov AX, (IOCTL shl 8) or GENERIC_IOCTL
|
||
int 21h
|
||
|
||
jnc GotMediaSense
|
||
|
||
cmp AL,error_not_ready
|
||
jne MediaSenseExit ; Machine does not support media sensing
|
||
|
||
call TargPrm ; Insert disk prompt
|
||
jmp SHORT MediaSense ; Retry the operation
|
||
|
||
; See if the type of media inserted is the same as the
|
||
; default for this type of drive and if not check to
|
||
; be sure it's
|
||
|
||
GotMediaSense:
|
||
mov AL,MediaSensePacket.MS_DEVICETYPE ; AL == media type
|
||
cmp SavedParams.DP_DEVICETYPE,AL ; If the media in the
|
||
.errnz EDP_DEVICETYPE NE DP_DEVICETYPE
|
||
jl MediaSenseExit ; drv is > default size, use default
|
||
|
||
; Load BPB for sensed media
|
||
xor AH,AH
|
||
shl AX,1 ; AX == word offset in media table
|
||
mov BX, offset MediaTable ; BX -> Start of media table
|
||
add BX, AX ; BX -> Sensed type in media table
|
||
|
||
cmp BX, offset EndMediaTable ; Make sure we're still in the table
|
||
jge MediaSenseExit
|
||
|
||
|
||
mov SI,[BX] ; DS:SI -> Sensed device parameters
|
||
or SI,SI
|
||
je MediaSenseExit ; Unknown Media?!
|
||
|
||
lea DI, DeviceParameters.DP_BPB ; ES:DI -> Format parameters
|
||
.errnz EDP_BPB NE DP_BPB
|
||
|
||
mov CX, size A_BPB ; CX = bytes to move
|
||
cmp IsExtRAWIODrv,0
|
||
je DoIOCTL2
|
||
mov CX, size A_BF_BPB ; CX = bytes to move
|
||
DoIOCTL2:
|
||
cld
|
||
rep movsb
|
||
;
|
||
; Update the D_Cylinders. With 120mb floppies the cylinders field does change
|
||
; as opposed 720/1.44 drives
|
||
; We just back calculate the cylinders from sec/track, heads & total sectors
|
||
;
|
||
|
||
.386
|
||
push edx
|
||
push ecx
|
||
push eax
|
||
movzx eax, DeviceParameters.DP_BPB.A_BPB_Heads
|
||
movzx edx, DeviceParameters.DP_BPB.A_BPB_SectorsPerTrack
|
||
mul edx
|
||
mov ecx, eax ; save sectors per cylinder in ECX
|
||
xor eax, eax
|
||
mov ax, DeviceParameters.DP_BPB.A_BPB_TotalSectors
|
||
or ax, ax
|
||
jnz mse_sec_ok
|
||
mov eax, dword ptr DeviceParameters.DP_BPB.A_BPB_BigTotalSectors
|
||
mse_sec_ok:
|
||
div ecx ; EAX = number of cylinders
|
||
mov DeviceParameters.DP_Cylinders, ax
|
||
pop eax
|
||
pop ecx
|
||
pop edx
|
||
.8086
|
||
|
||
MediaSenseExit:
|
||
ret
|
||
|
||
MediaSense ENDP
|
||
|
||
;========================================================================
|
||
;
|
||
; TargPrm : This procedure prompts the user to insert the target disk
|
||
; into the drive.
|
||
;
|
||
;========================================================================
|
||
|
||
TargPrm PROC NEAR
|
||
|
||
mov AL, DriveToFormat
|
||
call AccessDisk
|
||
Message MsgInsertDisk
|
||
Message ContinueMsg
|
||
call USER_STRING
|
||
call CrLf
|
||
ret
|
||
|
||
TargPrm ENDP
|
||
|
||
;=========================================================================
|
||
;
|
||
; CopyToSwitchDevParams : This procedure copies the structure
|
||
; DeviceParameters into SwitchDevParams.
|
||
; Registers destroyed : CX,DI,SI
|
||
; Assumes : DS:DATA, ES:Nothing
|
||
;
|
||
;=========================================================================
|
||
|
||
CopyToSwitchDevParams proc NEAR
|
||
|
||
push DS
|
||
pop ES
|
||
|
||
mov DI,OFFSET SwitchDevParams ; ES:DI --> dest. parms
|
||
|
||
mov SI,OFFSET DeviceParameters ; DS:SI --> src. parms
|
||
|
||
mov CX,SIZE EA_DEVICEPARAMETERS ; byte transfer count
|
||
|
||
cld
|
||
rep movsb
|
||
|
||
ret
|
||
|
||
CopyToSwitchDevParams endp
|
||
|
||
;=========================================================================
|
||
;
|
||
; CompareDevParams : This procedure compares the structure
|
||
; DeviceParameters with SwitchDevParams.
|
||
; Registers destroyed : CX,DI,SI
|
||
; Assumes : DS:DATA, ES:Nothing
|
||
;
|
||
;=========================================================================
|
||
|
||
CompareDevParams proc NEAR
|
||
|
||
push DS
|
||
pop ES
|
||
|
||
mov DI,OFFSET SwitchDevParams ; ES:DI --> dest. parms
|
||
|
||
mov SI,OFFSET DeviceParameters ; DS:SI --> src. parms
|
||
|
||
mov CX,SIZE A_DEVICEPARAMETERS ; Set up count in bytes
|
||
cmp IsExtRAWIODrv,0
|
||
je DoCmp
|
||
mov CX,SIZE EA_DEVICEPARAMETERS ; Set up count in bytes
|
||
DoCmp:
|
||
cld ; Set the direction
|
||
repe cmpsb ; Compare the two BPBs
|
||
jz EqualParams ; If ZR then BPBs matched
|
||
|
||
NotEqualParams:
|
||
stc ; Signal BPBs don't match
|
||
jmp SHORT CompareParamsExit
|
||
|
||
EqualParams:
|
||
clc ; Signal BPB matches
|
||
|
||
CompareParamsExit:
|
||
ret
|
||
|
||
CompareDevParams endp
|
||
|
||
;=========================================================================
|
||
;
|
||
; LoadSwitchDevParams : This procedure copies the structure
|
||
; SwitchDevParams into DeviceParameters.
|
||
; Registers destroyed : CX,DI,SI
|
||
; Assumes : DS:DATA,ES:Nothing
|
||
;
|
||
;=========================================================================
|
||
|
||
LoadSwitchDevParams proc NEAR
|
||
|
||
push DS
|
||
pop ES
|
||
|
||
mov DI,OFFSET DeviceParameters ; ES:DI --> dest. parms
|
||
|
||
mov SI,OFFSET SwitchDevParams ; DS:SI --> src. parms
|
||
|
||
mov CX,SIZE EA_DEVICEPARAMETERS ; byte transfer count
|
||
|
||
cld
|
||
rep movsb
|
||
|
||
ret
|
||
|
||
LoadSwitchDevParams endp
|
||
|
||
;=========================================================================
|
||
;
|
||
; DetermineExistingFormat : This procedure will check if there is a
|
||
; valid format existing on the disk, in
|
||
; which case DeviceParameters will be reset
|
||
; to that format.
|
||
;
|
||
; It is assumed the destination disk is
|
||
; already in the drive.
|
||
;
|
||
; DetermineExistingFormatNoMsg : alternate entry with no message
|
||
;
|
||
;
|
||
; Calls : IsValidBpb
|
||
; ResetDeviceParameters
|
||
; DetermineCPMFormat
|
||
;
|
||
; Called by : Phase1Initialisation
|
||
;
|
||
;=========================================================================
|
||
|
||
DetermineExistingFormat proc near
|
||
|
||
push DS
|
||
push ES
|
||
Set_Data_Segment ;ensure addressibility
|
||
|
||
cmp UnformattedHardDrive,TRUE
|
||
jne @F
|
||
jmp InvalidBootRecord
|
||
|
||
@@:
|
||
Message msgCheckExistingDiskFormat
|
||
jmp short DetermineExistCommon
|
||
|
||
DetermineExistingFormatNoMsg:
|
||
|
||
push ds
|
||
push es
|
||
set_data_segment
|
||
cmp UnformattedHardDrive,TRUE
|
||
je InvalidBootRecord
|
||
|
||
DetermineExistCommon:
|
||
xor DX,DX ; Starting sector to 0
|
||
mov AL,DriveToFormat ; Set drive number
|
||
mov AH,DH ; Signal this is a read AH=0
|
||
lds BX,FatSpace ; Load transfer address
|
||
assume DS:NOTHING,ES:DATA
|
||
|
||
mov CX,2 ; # of sectors to read
|
||
; we are accessing < 32mb
|
||
mov ES:Read_Write_Relative.Start_Sector_High,0
|
||
|
||
call Read_Disk ; Disk sector read
|
||
|
||
jnc BootCheck
|
||
mov ES:RWErrorCode,AX ; Save error code (if any)
|
||
jmp InvalidbootRecord
|
||
BootCheck:
|
||
cmp word ptr [bx+3], 'SM'
|
||
jne @F
|
||
cmp word ptr [bx+5], 'MD'
|
||
jne @F
|
||
cmp word ptr [bx+7], '3F'
|
||
jne @F
|
||
mov es:RWErrorCode, 0
|
||
stc
|
||
jmp short EndDetermine
|
||
@@:
|
||
cmp BYTE PTR [BX],0e9h ; Check for JMP opcode
|
||
je TestBootSignature ; If Ok then check signature
|
||
; we can not know #reserved sectors)
|
||
cmp BYTE PTR [BX],0ebh ; Else check for SHORT jmp
|
||
jne TryCPM ; No match then not valid boot
|
||
cmp BYTE PTR [BX+2],90h ; Now check for NOP opcode
|
||
jne TryCPM ; No match then not valid boot
|
||
|
||
TestBootSignature:
|
||
ifndef NEC_98
|
||
cmp WORD PTR [BX + 510],0aa55h ; Check for 55 AA sequence
|
||
jne TryCPM ; Error if not equal
|
||
endif
|
||
|
||
CheckTheBpb:
|
||
call IsValidBpb
|
||
jc TryCPM ; CY --> Invalid format
|
||
|
||
call ResetDeviceParameters ; set DeviceParameters to
|
||
clc ; existing ones on the disk
|
||
jmp SHORT EndDetermine
|
||
|
||
TryCPM:
|
||
ifdef NEC_98
|
||
cmp ES:DeviceParameters.DP_DeviceType,DEV_HARDDISK
|
||
je InvalidBootRecord
|
||
endif
|
||
; check in case a CP/M disk is present
|
||
test ES:DeviceParameters.DP_DeviceAttributes,1
|
||
.errnz EDP_DEVICEATTRIBUTES NE DP_DEVICEATTRIBUTES
|
||
jnz InvalidBootRecord ; Bit 0=1 --> not removable
|
||
|
||
call DetermineCPMFormat
|
||
jmp SHORT EndDetermine ; CP/M disk present, DeviceParameters
|
||
; will have been modified
|
||
; Carry propagated up to
|
||
; Note: DS can be anything
|
||
|
||
InvalidBootRecord:
|
||
stc ;flag invalid format
|
||
|
||
EndDetermine:
|
||
pop ES
|
||
pop DS
|
||
|
||
ret
|
||
|
||
DetermineExistingFormat endp
|
||
|
||
;=========================================================================
|
||
;
|
||
; IsValidBpb : This procedure will inspect the BPB loaded into
|
||
; memory by the DetermineExistinFormat procedure.
|
||
;
|
||
; Input : DS:BX Buffer holding boot sector (FatSpace) ; M016
|
||
; Output : BPB is valid - NC
|
||
; BPB is invalid - CY
|
||
;
|
||
; Assumes: DS:BX: FatSpace (preserved); M016
|
||
;
|
||
;=========================================================================
|
||
|
||
IsValidBpb proc near
|
||
|
||
assume DS:NOTHING,ES:DATA
|
||
|
||
push BX ; M016; preserve BX
|
||
lea bx,[bx.bsBPB]
|
||
ifdef NEC_98
|
||
;;; It is possible NEC_98's BPB is not 200h.
|
||
cmp [BX.oldBPB.BPB_BytesPerSector],200h ; check BytesPerSector=512
|
||
je @F
|
||
cmp [BX.oldBPB.BPB_BytesPerSector],400h ; check BytesPerSector=1024
|
||
je @F
|
||
cmp [BX.oldBPB.BPB_BytesPerSector],800h ; check BytesPerSector=2048
|
||
jne NotValidBpb
|
||
@@:
|
||
else
|
||
cmp [BX.oldBPB.BPB_BytesPerSector],200h ; check BytesPerSector=512
|
||
jne NotValidBpb
|
||
endif
|
||
|
||
and [BX.oldBPB.BPB_TotalSectors],0ffffh ; check that both TotalSectors
|
||
jnz ResetBigTotalSectors ; and BigTotalSectors are not zero
|
||
and [BX.oldBPB.BPB_BigTotalSectors],0ffffh ; low word
|
||
jnz CheckMore
|
||
and [BX.oldBPB.BPB_BigTotalSectorsHigh],0ffffh ; high word
|
||
jz NotValidBpb
|
||
jmp SHORT CheckMore
|
||
|
||
ResetBigTotalSectors: ; if TotalSectors<>0 set
|
||
and [BX.oldBPB.BPB_BigTotalSectors],0h ; BigTotalSectors to zero
|
||
and [BX.oldBPB.BPB_BigTotalSectorsHigh],0h
|
||
|
||
CheckMore:
|
||
and [BX.oldBPB.BPB_SectorsPerFAT],0ffffh ; check SectorsPerFat <> 0
|
||
jnz CheckMore2
|
||
;
|
||
; Is a FAT32 BPB
|
||
;
|
||
and [BX.BGBPB_BigSectorsPerFat],0ffffh
|
||
jnz CheckMore2
|
||
and [BX.BGBPB_BigSectorsPerFatHi],0ffffh
|
||
jz NotValidBpb
|
||
CheckMore2:
|
||
cmp [BX.oldBPB.BPB_SectorsPerTrack],1h ; check 0 < SectorsPerTrack < 64
|
||
jb NotValidBpb
|
||
cmp [BX.oldBPB.BPB_SectorsPerTrack],3fh
|
||
ja NotValidBpb
|
||
|
||
cmp [BX.oldBPB.BPB_Heads],1h ; check 0 < Heads < 256
|
||
jb NotValidBpb
|
||
cmp [BX.oldBPB.BPB_Heads],0ffh
|
||
ja NotValidBpb
|
||
|
||
BpbIsValid:
|
||
clc
|
||
jmp SHORT EndIsValidBpb
|
||
|
||
NotValidBpb:
|
||
stc
|
||
|
||
EndIsValidBpb:
|
||
pop BX ; M016; restore BX
|
||
ret
|
||
|
||
IsValidBpb endp
|
||
|
||
;=========================================================================
|
||
;
|
||
; ResetDeviceParameters : This procedure will copy the BPB of the
|
||
; disk into DeviceParameters. It will also
|
||
; set the fields DP_CYLINDERS and DP_MEDIATYPE,
|
||
; for removable media.
|
||
;
|
||
; Inputs : DS:BX Boot sector held in FatSpace ; M016
|
||
; Output : Modified DeviceParameters
|
||
; Modifies: ES,SI,DI,CX,DX,BX,AX
|
||
; Assumes: DS:BX Boot sector, ES:DATA
|
||
;
|
||
;=========================================================================
|
||
|
||
ResetDeviceParameters proc near
|
||
|
||
assume DS:NOTHING,ES:DATA
|
||
|
||
lea si,[bx.bsBPB] ; Use SI instead of BX for copy
|
||
; DS:SI source BPB in buffer
|
||
|
||
;No need to modify DP_CYLINDERS,DP_MEDIATYPE
|
||
;(and DP_DEVICETYPE) for fixed disks.
|
||
|
||
ifdef NEC_98
|
||
cmp ES:DeviceParameters.DP_DeviceType,DEV_HARDDISK
|
||
je CopyBpb
|
||
endif
|
||
;use DevParms to check for removable
|
||
test ES:DeviceParameters.DP_DeviceAttributes,1
|
||
.errnz EDP_DEVICEATTRIBUTES NE DP_DEVICEATTRIBUTES
|
||
jnz CopyBpb ; Bit 0=1 --> not removable
|
||
|
||
;first compute total cylinders as
|
||
;total sectors /(sectors per track)*#heads
|
||
.386
|
||
movzx EAX,[SI.oldBPB.BPB_TotalSectors] ;get total sectors
|
||
.8086
|
||
or AX,AX ;do we need to use Big total sectors?
|
||
jnz GotTotalSectors ;don't need to if not zero
|
||
|
||
UseBigTotalSectors:
|
||
.386
|
||
mov EAX,DWORD PTR [SI.oldBPB.BPB_BigTotalSectors]
|
||
|
||
GotTotalSectors: ;now EAX has total #sectors
|
||
movzx EBX,[SI.oldBPB.BPB_SectorsPerTrack] ;get sectors per track
|
||
xor edx,edx
|
||
div EBX
|
||
.8086
|
||
xor DX,DX ;clear the remainder
|
||
mov CX,[SI.oldBPB.BPB_Heads] ;get number of heads
|
||
div CX
|
||
or DX,DX
|
||
jz CylindersOk
|
||
inc AX
|
||
|
||
;BUGBUG: Arithmetic may result in CYLINDERS being 1 less than actual value,
|
||
; for big disks (hence this calculation is skipped for fixed disks)
|
||
; PYS: fixed using same code as MSINIT.ASM
|
||
|
||
CylindersOk:
|
||
mov ES:DeviceParameters.DP_CYLINDERS,AX
|
||
.errnz EDP_CYLINDERS NE DP_CYLINDERS
|
||
|
||
;now determine DP_MEDIATYPE & DP_DEVICETYPE
|
||
|
||
mov ES:DeviceParameters.DP_MEDIATYPE,0 ; init. to zero
|
||
.errnz EDP_MEDIATYPE NE DP_MEDIATYPE
|
||
cmp AX,40 ; only 360K or less has 40 cylinders
|
||
jne CopyBpb ; MEDIATYPE has been set
|
||
|
||
cmp ES:DeviceParameters.DP_DEVICETYPE,DEV_5INCH96TPI
|
||
.errnz EDP_DEVICETYPE NE DP_DEVICETYPE
|
||
jne CopyBpb
|
||
|
||
Is360K:
|
||
mov ES:DeviceParameters.DP_MEDIATYPE,1 ; set to 1 only for 360K in 1.2M
|
||
.errnz EDP_MEDIATYPE NE DP_MEDIATYPE
|
||
|
||
|
||
;BUGBUG: Changing the value of DEVICETYPE can result in SwitchDevParams !=
|
||
; DeviceParameters, and hence a just-formatted 360K disk may not be
|
||
; recognized! -is it really necessary to set DEVICETYPE?
|
||
|
||
CopyBpb:
|
||
mov DI,OFFSET ES:DeviceParameters.DP_BPB
|
||
.errnz EDP_BPB NE DP_BPB
|
||
|
||
;ES:DI destination BPB in DeviceParameters
|
||
|
||
mov CX,SIZE BIGFATBPB ;byte transfer count
|
||
cmp [si.BPB_SectorsPerFAT],0 ;FAT32 BPB?
|
||
je @f ;Yes
|
||
|
||
mov CX,SIZE BPB ;byte transfer count
|
||
cmp byte ptr [si.bsBootSignature-bsBPB], 29h ; extended BPB ?
|
||
je @f ; Yes
|
||
mov cx,((SIZE BPB)-6) ; no, ancient small BPB
|
||
@@:
|
||
cld ;set the direction
|
||
rep movsb ;write the new BPB
|
||
ret
|
||
|
||
ResetDeviceParameters endp
|
||
|
||
;=========================================================================
|
||
;
|
||
; DetermineCPMFormat : This procedure will check the media
|
||
; descriptor in the FAT of the disk. The
|
||
; disk has a valid CP/M format if this is
|
||
; in the range FCh - FFh.
|
||
;
|
||
; Assumes : DS:BX points to boot sectors. ; M016
|
||
; Modifies : DS ; M016
|
||
; Returns : NC - Valid CP/M format detected
|
||
; DeviceParameters modified
|
||
; CY - Invalid format
|
||
;
|
||
;==========================================================================
|
||
|
||
DetermineCPMFormat proc NEAR
|
||
|
||
assume DS:NOTHING,ES:DATA
|
||
|
||
cmp ES:DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,512
|
||
.errnz EDP_BPB NE DP_BPB
|
||
stc ; Checking default for drive
|
||
; (cannot check BPB since disk
|
||
; may not have one)
|
||
jne ExitDetCPMFormat
|
||
add BX,512 ; DS:BX points to first FAT
|
||
|
||
|
||
mov CL,BYTE PTR [BX] ; load media descriptor byte into CL
|
||
cmp CL,0fch
|
||
jb ExitDetCPMFormat ; below = carry, how practical!
|
||
|
||
Set_Data_Segment ; For the two following calls
|
||
|
||
call SetCPMParameters ; modify DeviceParameters accordingly
|
||
|
||
ExitDetCPMFormat:
|
||
ret
|
||
|
||
DetermineCPMFormat endp
|
||
|
||
;=========================================================================
|
||
;
|
||
; SetCPMParameters : This procedure copies the required BPB from the
|
||
; CP/M BPB table into DeviceParameters.BPB. Also,
|
||
; DeviceParameters.MediaType is set to 1, and
|
||
; DeviceParameters.Cylinders is set to 40.
|
||
;
|
||
; In case the disk has a 160K or 320K format, the /8
|
||
; switch is set, so that
|
||
; Returns : NC - DeviceParameters updated
|
||
; CY - Error (out of table boundaries)
|
||
;
|
||
; Modifies : AX,BX,CX,DX,SI,DI,ES
|
||
; DeviceParameters
|
||
;
|
||
; Assumes : CL contains media descriptor byte
|
||
;
|
||
;=========================================================================
|
||
|
||
SetCPMParameters proc NEAR
|
||
|
||
xor AX,AX ; find index into CP/M BPB table by
|
||
mov AL,0ffh ; subtracting media descriptor from ffh
|
||
sub AL,CL
|
||
|
||
mov BX,SIZE A_BPB ; now find byte offset by multiplying
|
||
mul BX ; by entry size
|
||
|
||
lea SI,CustomCPMBPBs
|
||
add SI,AX
|
||
cmp SI,OFFSET EndCustomCPMBPBs ; check we are still in table
|
||
ja NotInTable
|
||
|
||
lea DI,DeviceParameters.DP_BPB
|
||
.errnz EDP_BPB NE DP_BPB
|
||
|
||
mov CX,SIZE A_BPB ; set up byte transfer count
|
||
|
||
push DS ; set ES=DS
|
||
pop ES
|
||
|
||
cld ;set the direction
|
||
rep movsb ; load the BPB
|
||
|
||
mov BYTE PTR DeviceParameters.DP_MediaType,1
|
||
.errnz EDP_MEDIATYPE NE DP_MEDIATYPE
|
||
mov BYTE PTR DeviceParameters.DP_Cylinders,40
|
||
.errnz EDP_CYLINDERS NE DP_CYLINDERS
|
||
|
||
clc
|
||
jmp SHORT ExitSetCPMParm
|
||
|
||
NotInTable:
|
||
stc
|
||
|
||
ExitSetCPMParm:
|
||
ret
|
||
|
||
SetCPMParameters endp
|
||
|
||
;=========================================================================
|
||
; Set_BPB_Info : When we have a Fat count of 0, we must calculate
|
||
; certain parts of the BPB. The following code
|
||
; will do just that.
|
||
;
|
||
; Inputs : DeviceParameters
|
||
;
|
||
; Outputs : BPB information
|
||
;=========================================================================
|
||
|
||
Procedure Set_BPB_Info ; Calc new BPB
|
||
|
||
Set_Data_Segment ; Set up addressibility
|
||
ifdef NEC_98
|
||
cmp DeviceParameters.DP_BPB.BPB_NumberOfFats,00h
|
||
je @F ; Yes, 0 FatS specified
|
||
|
||
cmp DeviceParameters.DP_DeviceType,DEV_HARDDISK
|
||
je $$IF101
|
||
test DeviceParameters.DP_DeviceAttributes,1
|
||
jnz $$IF101 ; Bit 0=1 --> not removable
|
||
|
||
cmp CMCDDFlag,Yes ; Memory card?
|
||
je $$IF101 ; We don't need current BPB
|
||
|
||
lea DX, DeviceParameters
|
||
mov DeviceParameters.DP_SpecialFunctions,INSTALL_FAKE_BPB
|
||
call GetDeviceParameters
|
||
jmp short $$IF101
|
||
@@:
|
||
else
|
||
; See if we have 0 Fats specified
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFats,00h
|
||
.errnz EDP_BPB NE DP_BPB
|
||
jne $$IF101 ; Yes, 0 FatS specified
|
||
endif
|
||
call Scan_Disk_Table ; Access disk table
|
||
mov BL,BYTE PTR DS:[SI+8] ; Get Fat type
|
||
mov CX,WORD PTR DS:[SI+4] ; Get Sectors/cluster
|
||
mov DX,WORD PTR DS:[SI+6] ; Number of entries for the root DIR
|
||
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries,DX
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster,CH
|
||
ifdef NEC_98
|
||
;;
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_MediaDescriptor,Fixed_Disk
|
||
|
||
;;and ReservedSector not Fixed 1.(Large Partition)
|
||
;; reserved sector >= 1024 bytes (NEC)
|
||
|
||
cmp word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,0200h
|
||
je $$reserved_2
|
||
cmp word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,0100h
|
||
;Chicago is not supported 256 secters but for safely.
|
||
je $$reserved_4
|
||
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0001h
|
||
jmp short @F
|
||
$$reserved_2:
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0002h
|
||
jmp short @F
|
||
$$reserved_4:
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0004h
|
||
@@:
|
||
else
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,0200h
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0001h
|
||
endif
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFats,02h
|
||
.errnz EDP_BPB NE DP_BPB
|
||
|
||
cmp BL,fBig32 ; 32-bit Fat?
|
||
jne $$IF103 ; No
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors,0020h
|
||
call Calc_Big32_Fat ; Calc Fat info
|
||
jmp SHORT $$EN102
|
||
|
||
$$IF103:
|
||
cmp BL,fBig ; 16-bit Fat?
|
||
jne $$IF102 ; no
|
||
call Calc_Big16_Fat ; Calc Fat info
|
||
jmp SHORT $$EN102
|
||
|
||
$$IF102:
|
||
call Calc_Small_Fat ; Calc small Fat info
|
||
$$EN102:
|
||
$$IF101:
|
||
ret
|
||
|
||
Set_BPB_Info ENDP
|
||
|
||
;=========================================================================
|
||
; Scan_Disk_Table : Scans the table containing information on
|
||
; the disk's attributes. When it finds the
|
||
; applicable data, it returns a pointer in
|
||
; DS:SI for reference by the calling proc.
|
||
;
|
||
; Inputs : DiskTable - Contains data about disk types
|
||
;
|
||
; Outputs : DS:SI - Points to applicable disk data
|
||
;=========================================================================
|
||
|
||
Procedure Scan_Disk_Table
|
||
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ; small disk?
|
||
.errnz EDP_BPB NE DP_BPB
|
||
je $$IF106 ; Yes
|
||
|
||
mov DX,00h ; Set high to 0
|
||
mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
jmp SHORT $$EN106
|
||
|
||
$$IF106:
|
||
mov DX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+2]
|
||
mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+0]
|
||
|
||
$$EN106:
|
||
ifdef NEC_98
|
||
call SetDiskTableNEC_98
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector,BX
|
||
cmp dx,0
|
||
je @F
|
||
mov word ptr DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,0
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors,AX
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectorsHigh,DX
|
||
jmp short set_ok
|
||
@@:
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,AX
|
||
mov word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors,0
|
||
mov word ptr DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectorsHigh,0
|
||
set_ok:
|
||
else
|
||
mov SI,offset DiskTable ; Point to disk data
|
||
endif
|
||
Scan:
|
||
|
||
cmp DX,WORD PTR DS:[SI] ; Below?
|
||
jb Scan_Disk_Table_Exit ; Yes, exit
|
||
ja Scan_Next ; No, continue
|
||
|
||
cmp AX,WORD PTR DS:[SI+2] ; Below or equal?
|
||
ifdef NEC_98
|
||
jb Scan_Disk_Table_Exit ; Yes, exit
|
||
else
|
||
jbe Scan_Disk_Table_Exit ; Yes, exit
|
||
endif
|
||
|
||
Scan_Next:
|
||
add SI,5*2 ; Adjust pointer
|
||
jmp Scan ; Continue scan
|
||
|
||
Scan_Disk_Table_Exit:
|
||
|
||
ret
|
||
|
||
Scan_Disk_Table ENDP
|
||
|
||
;=========================================================================
|
||
; Calc_Big32_Fat : Calculates the Sectors per Fat for a 32 bit Fat.
|
||
;
|
||
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors or
|
||
; DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
;
|
||
; Outputs : DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
|
||
; DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
|
||
; DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFatHi
|
||
; DeviceParameters.DP_BPB.BGBPB_ExtFlags
|
||
; DeviceParameters.DP_BPB.BGBPB_FS_Version
|
||
; DeviceParameters.DP_BPB.BGBPB_RootDirStrtClus
|
||
; DeviceParameters.DP_BPB.BGBPB_RootDirStrtClusHi
|
||
;
|
||
;=========================================================================
|
||
|
||
Procedure Calc_Big32_Fat
|
||
|
||
.386
|
||
; Root dir is a cluster chain on FAT32 volumes
|
||
|
||
movzx edx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors ; EDX = Reserved
|
||
.errnz EDP_BPB NE DP_BPB
|
||
; Get total sector count
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ; Small disk?
|
||
je short $$IF109a ; Yes
|
||
movzx EAX,DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
jmp SHORT $$EN109a
|
||
|
||
$$IF109a:
|
||
mov EAX,DWORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors
|
||
|
||
$$EN109a:
|
||
sub EAX,EDX ; EAX = T - R
|
||
xor ebx,ebx
|
||
mov BL,DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFATs
|
||
mov BH,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
||
shr ebx,1 ; At 4 bytes per clus instead of 2,
|
||
; halve divisor
|
||
GotDiv1:
|
||
add EAX,EBX ; EAX = T-R-D+(256*SPC)+nFAT
|
||
dec EAX ; EAX = T-R-D+(256*SPC)+nFAT-1
|
||
xor edx,edx
|
||
div EBX ; Sec/Fat = CEIL((TOTAL-DIR-RES)/
|
||
; (((256*SECPERCLUS)+NUMFATS)/2)
|
||
|
||
mov DWORD PTR DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat,EAX
|
||
xor ax,ax
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,ax
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries,ax
|
||
mov DeviceParameters.DP_BPB.BGBPB_ExtFlags,ax
|
||
;
|
||
; For the moment we set the root dir start clus to 0. Later on, after
|
||
; we determine which clusters are BAD, we will set this to something
|
||
; proper.
|
||
;
|
||
mov DeviceParameters.DP_BPB.BGBPB_RootDirStrtClus,ax
|
||
mov DeviceParameters.DP_BPB.BGBPB_RootDirStrtClusHi,ax
|
||
mov DeviceParameters.DP_BPB.BGBPB_FS_Version,FAT32_Curr_FS_Version
|
||
.8086
|
||
ret
|
||
|
||
Calc_Big32_Fat ENDP
|
||
|
||
|
||
;=========================================================================
|
||
; Calc_Big16_Fat : Calculates the Sectors per Fat for a 16 bit Fat.
|
||
;
|
||
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors or
|
||
; DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
;
|
||
; Outputs : DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
|
||
;
|
||
;=========================================================================
|
||
|
||
Procedure Calc_Big16_Fat
|
||
|
||
; Get root size in sectors and add reserved to it
|
||
|
||
mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
|
||
.errnz EDP_BPB NE DP_BPB
|
||
mov bx,size dir_entry
|
||
mul bx ; DX:AX = bytes in root dir
|
||
mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector
|
||
dec bx ; Round up to sector multiple
|
||
add ax,bx
|
||
adc dx,0
|
||
inc bx ; get back sector size
|
||
div bx ; AX is sectors in root dir
|
||
mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
|
||
add ax,bx ; AX = R + D
|
||
mov bx,ax ; over to BX
|
||
|
||
; Get Total sectors
|
||
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ; Small disk?
|
||
je $$IF109 ; Yes
|
||
|
||
xor DX,DX ; Set high to 0
|
||
mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
jmp SHORT $$EN109
|
||
|
||
$$IF109:
|
||
mov DX,DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+2]
|
||
mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+0]
|
||
|
||
$$EN109:
|
||
sub AX,BX ; DX:AX = T - R - D
|
||
sbb DX,0
|
||
mov BL,DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFATs
|
||
mov BH,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
||
add AX,BX ; AX = T-R-D+(256*SPC)+nFAT
|
||
adc DX,0
|
||
sub AX,1 ; AX = T-R-D+(256*SPC)+nFAT-1
|
||
sbb DX,0
|
||
div BX ; Sec/Fat = CEIL((TOTAL-DIR-RES)/
|
||
; ((256*SECPERCLUS)+NUMFATS)
|
||
|
||
mov WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,AX
|
||
ret
|
||
|
||
Calc_Big16_Fat ENDP
|
||
|
||
|
||
;=========================================================================
|
||
; Calc_Small_Fat: Calculates the Sectors per Fat for a 12 bit Fat.
|
||
;
|
||
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors or
|
||
; DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
;
|
||
; Outputs : DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
|
||
;
|
||
;=========================================================================
|
||
|
||
Procedure Calc_Small_Fat
|
||
|
||
; Get root size in sectors and add reserved to it
|
||
|
||
mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
|
||
.errnz EDP_BPB NE DP_BPB
|
||
mov bx,size dir_entry
|
||
mul bx ; DX:AX = bytes in root dir
|
||
mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector
|
||
dec bx ; Round up to sector multiple
|
||
add ax,bx
|
||
adc dx,0
|
||
inc bx ; get back sector size
|
||
div bx ; AX is sectors in root dir
|
||
mov bx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
|
||
add ax,bx ; AX = R + D
|
||
mov bx,ax ; over to BX
|
||
|
||
; Get total sectors
|
||
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors,00h ;small disk?
|
||
je $$IF112 ; Yes
|
||
|
||
xor DX,DX ; Set high to 0
|
||
mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
jmp SHORT $$EN112
|
||
|
||
$$IF112:
|
||
mov DX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+2]
|
||
mov AX,WORD PTR DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors[+0]
|
||
|
||
$$EN112:
|
||
sub AX,BX ; DX:AX = T - R - D
|
||
sbb DX,0
|
||
|
||
xor BX,BX
|
||
mov BL,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
||
div BX
|
||
; Now multiply by 3/2
|
||
mov BX,3
|
||
mul BX ; Div by log 2 of Sectors/clus
|
||
mov BX,2
|
||
div BX
|
||
xor DX,DX
|
||
; Now divide by 512
|
||
mov BX,512
|
||
div BX
|
||
ifdef NEC_98
|
||
or dx,dx ; for remainder
|
||
jz @F
|
||
inc AX
|
||
@@:
|
||
test ax,01h ; for even
|
||
jz @F
|
||
inc ax
|
||
@@:
|
||
cmp DeviceParameters.DP_BPB.BPB_BytesPerSector,2048
|
||
jne @F
|
||
test ax,02h ; for 2048 bytes/sector
|
||
jz @F
|
||
add ax,2
|
||
@@:
|
||
else
|
||
inc AX
|
||
; DX:AX contains number of Fat
|
||
; sectors necessary
|
||
endif
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,AX
|
||
ret
|
||
|
||
Calc_Small_Fat ENDP
|
||
|
||
; ==========================================================================
|
||
; StartSector = number of reserved Sectors
|
||
; + number of Fat Sectors ( Number of FatS * Sectors Per Fat )
|
||
; + number of directory Sectors ( 32* Root Entries / bytes Per Sector )
|
||
; ( above is rounded up )
|
||
;
|
||
; Calculate the number of directory Sectors
|
||
; ==========================================================================
|
||
|
||
SetStartSector proc near
|
||
|
||
xor ax,ax
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFAT,ax
|
||
je NoRootDir
|
||
mov AX, DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
|
||
.errnz EDP_BPB NE DP_BPB
|
||
mov BX, size dir_entry
|
||
mul BX ; DX:AX is bytes in root dir
|
||
mov bx, DeviceParameters.DP_BPB.oldBPB.BPB_bytesPerSector
|
||
dec bx ; Round up to sector multiple
|
||
add ax,bx
|
||
adc dx,0
|
||
inc bx ; Get sector size back
|
||
div bx ; AX = Sectors in root dir
|
||
NoRootDir:
|
||
mov SectorsInRootDirectory,AX
|
||
.386
|
||
movzx eax,ax
|
||
mov StartSector, EAX ;not done yet!
|
||
|
||
; Calculate the number of Fat Sectors
|
||
|
||
movzx EAX, DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
|
||
or ax,ax
|
||
jnz short NotFat32a
|
||
mov EAX, DWORD PTR DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
|
||
NotFat32a:
|
||
movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_numberOfFats
|
||
mul ebx
|
||
; add in the number of boot Sectors
|
||
movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
|
||
|
||
add EAX,EBX
|
||
add StartSector, EAX
|
||
.8086
|
||
return
|
||
|
||
SetStartSector endp
|
||
|
||
; ==========================================================================
|
||
;
|
||
; fBigFat = ( ( (TotalSectors - StartSector) / SectorsPerCluster) >= 4086 )
|
||
;
|
||
; ==========================================================================
|
||
|
||
SetfBigFat proc near
|
||
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFAT,0
|
||
.errnz EDP_BPB NE DP_BPB
|
||
jne NotFat32b
|
||
mov fBig32Fat, TRUE ; Set flag
|
||
mov ThisSysInd,8
|
||
jmp SHORT $$EN21
|
||
|
||
NotFat32b:
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors+2,0
|
||
je $$IF21 ; no, 12-bit Fat
|
||
mov fBigFat, TRUE ; Set flag
|
||
mov ThisSysInd,6
|
||
jmp SHORT $$EN21 ; Nope, < 32,b
|
||
|
||
$$IF21: ; Assume this used
|
||
mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors
|
||
cmp AX,0 ; Was this field used?
|
||
jne $$IF23 ; Yes
|
||
; No, use other sector field
|
||
mov AX, DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
$$IF23: ; ** Fix for PTM PCDOS P51
|
||
mov ThisSysInd,1 ; Set small Fat for default
|
||
sub AX,word ptr StartSector ; Get Sectors in data area
|
||
xor DX,DX
|
||
xor BX,BX
|
||
mov bl,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
||
div BX ; Get total clusters
|
||
|
||
cmp AX,BIG_Fat_THRESHOLD ; Is clusters >= 4086?
|
||
jnae $$IF25
|
||
|
||
mov fBigFat,TRUE ; 16 bit Fat if >=4096
|
||
; ** END fix for PTM PCDOS P51
|
||
mov ThisSysInd,4 ; set large Fat
|
||
$$IF25:
|
||
$$EN21:
|
||
return
|
||
|
||
SetfBigFat endp
|
||
|
||
;==========================================================================
|
||
;
|
||
; GetTotalClusters : This procedure initializes the variable TotalClusters.
|
||
; This is utilized by Quick Format to check for when all
|
||
; the clusters have been processed.
|
||
; Destroys : AX,BX,CX,DX
|
||
; Strategy : TotalClusters = (TotalSectors-Fats-Root-Reserved)/SectorsPerCluster
|
||
;
|
||
;==========================================================================
|
||
|
||
GetTotalClusters proc NEAR
|
||
|
||
.386
|
||
movzx EAX,DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors
|
||
.errnz EDP_BPB NE DP_BPB
|
||
or AX,AX ; Check if BigTotalSectors must be used
|
||
jnz short GoSubstract ; M015; Substrack Fats, Root and reserved
|
||
|
||
GetBigSectors:
|
||
mov EAX,dword ptr DeviceParameters.DP_BPB.oldBPB.BPB_BigTotalSectors
|
||
|
||
GoSubstract:
|
||
movzx edx,DeviceParameters.DP_BPB.oldBPB.BPB_ReservedSectors
|
||
sub EAX,EDX
|
||
|
||
movzx edx,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
|
||
or dx,dx
|
||
jnz short NotFat32c
|
||
mov DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries,dx ; No root dir on FAT32
|
||
mov edx,dword ptr DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
|
||
NotFat32c:
|
||
movzx cx,DeviceParameters.DP_BPB.oldBPB.BPB_NumberOfFats
|
||
jcxz GoDivide ; M017; if non fat, don't even do the root
|
||
|
||
SubstractAFat:
|
||
sub EAX,EDX
|
||
loop SubstractAFat
|
||
|
||
GoSubstractRoot:
|
||
; Assumes that BytesPerSectors is a power of 2 and at least 32
|
||
; Those are valid assumptions since BIOS requires the same.
|
||
|
||
mov BX,DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
||
shr BX,5 ; divide by 32, BX = root entries per sector (a power of 2)
|
||
|
||
or BX,BX ; Sanity check for infinite looping
|
||
jz short SayWhat
|
||
|
||
mov CX,DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
|
||
|
||
SubstractRootLoop:
|
||
test BX,1
|
||
jnz short SubstractRootReady
|
||
shr BX,1
|
||
shr CX,1
|
||
jmp short SubstractRootLoop
|
||
|
||
SubstractRootReady:
|
||
movzx ecx,cx
|
||
|
||
sub EAX,ECX
|
||
GoDivide:
|
||
movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
||
xor edx,edx
|
||
div EBX
|
||
|
||
inc EAX ; Bump by 1 since start with 2
|
||
cmp DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat,0
|
||
je short NoOvlChk
|
||
cmp EAX,0000FFEFh ; Sanity check
|
||
ja short SayWhat
|
||
NoOvlChk:
|
||
mov TotalClusters,EAX
|
||
.8086
|
||
ret
|
||
|
||
SayWhat:
|
||
Message msgInvalidDeviceParameters
|
||
jmp FatalExit
|
||
|
||
GetTotalClusters endp
|
||
|
||
; SetDOS_Dpb - Need to set the DPB for a memory card because the
|
||
; default will be for the last disk accessed in the
|
||
; the drive and may not be correct for the current
|
||
; disk.
|
||
|
||
SetDOS_Dpb PROC
|
||
|
||
cmp CMCDDFlag, Yes
|
||
je @f
|
||
clc
|
||
ret
|
||
|
||
@@:
|
||
push ds
|
||
pop es
|
||
mov di, offset SetDPBPacket
|
||
mov ax, OFFSET DeviceParameters.DP_BPB ; DS:AX --> BPB for disk
|
||
.errnz EDP_BPB NE DP_BPB
|
||
mov word ptr [di.SetDPB_Value1],ax
|
||
mov word ptr [di.SetDPB_Value1+2],ds
|
||
xor ax,ax
|
||
mov word ptr [di.SetDPB_Value2],ax
|
||
mov word ptr [di.SetDPB_Value2+2],ax
|
||
mov word ptr [di.SetDPB_Value3],ax
|
||
mov word ptr [di.SetDPB_Value3+2],ax
|
||
mov word ptr [di.SetDPB_Value4],ax
|
||
mov word ptr [di.SetDPB_Value4+2],ax
|
||
.386
|
||
mov [di.SetDPB_Function],SetDPB_SetDPBFrmBPB
|
||
movzx dx,DriveToFormat
|
||
.8086
|
||
inc dx ; 1 based drive number
|
||
mov ax,(Get_Set_DriveInfo SHL 8) OR Set_DPBForFormat
|
||
mov cx,size SDPDFormatStruc
|
||
int 21h
|
||
;
|
||
; NOTE: This call fails in protected mode under Win95. VFAT/VDEF do not
|
||
; implement it. This call REALLY isn't necessary anyway. The
|
||
; SetDeviceParameters we do as part of the format is supposed to
|
||
; trigger the device driver to return "media changed" on the next
|
||
; media check call.
|
||
;
|
||
clc
|
||
|
||
ret
|
||
|
||
SetDOS_Dpb ENDP
|
||
|
||
;==========================================================================
|
||
ifdef NEC_98
|
||
; IN : DX:AX total_sectors
|
||
; : DeviceParameters
|
||
; OUT : SI = offset DiskTable
|
||
; : BX = BytesPerSector
|
||
; : DX:AX = total sectors
|
||
;
|
||
; USE : AX,BX,DX,SI
|
||
;
|
||
SetDiskTableNEC_98 proc near
|
||
|
||
mov bx,DeviceParameters.DP_BPB.BPB_BytesPerSector
|
||
|
||
cmp bx,200h
|
||
je large?_512
|
||
cmp bx,100h
|
||
je large?_256
|
||
cmp bx,400h
|
||
jne not_large
|
||
|
||
large?_1024:
|
||
cmp dx,2
|
||
jb not_large
|
||
je @F
|
||
jmp set_large1024 ; 1024 and DX > 2 --> large partition.
|
||
; > 129MB
|
||
|
||
@@:
|
||
cmp ax,200h
|
||
jb not_large
|
||
jmp set_large1024 ; 1024 and DX = 2 and AX >= 512 --> large partition.
|
||
; > 128.5MB
|
||
|
||
large?_512:
|
||
cmp dx,4
|
||
jb not_large
|
||
je @F
|
||
jmp set_large512 ; 512 and DX > 4 --> large partition.
|
||
; > 129MB
|
||
|
||
@@:
|
||
cmp ax,400h
|
||
jb not_large
|
||
jmp set_large512 ; 512 and DX = 4 and AX >= 1024 --> large partition.
|
||
; > 128.5MB
|
||
|
||
large?_256:
|
||
cmp dx,8
|
||
jb not_large
|
||
je @F
|
||
jmp set_large256 ; 256 and DX > 8 --> large partition.
|
||
; > 129MB
|
||
|
||
@@:
|
||
cmp ax,800h
|
||
jb not_large
|
||
jmp set_large256 ; 256 and DX = 8 and AX >= 2048 --> large partition.
|
||
; > 128.5MB
|
||
|
||
not_large:
|
||
cmp bx,800h
|
||
jne @F
|
||
jmp set_2K
|
||
|
||
@@:
|
||
cmp bx,200h
|
||
je sec2K?_512
|
||
cmp bx,100h
|
||
je sec2K?_256
|
||
|
||
sec2K?_1024:
|
||
cmp dx,1
|
||
jb not_2K
|
||
je @F
|
||
|
||
shr dx,1 ;convert 1K->2K
|
||
rcr ax,1
|
||
jmp set_2K ; 1024 and DX > 1 --> 2KB partition.
|
||
; > 65MB
|
||
|
||
@@:
|
||
cmp ax,200h
|
||
jb not_2K
|
||
shr dx,1 ;convert 1K->2K
|
||
rcr ax,1
|
||
jmp set_2K ; 1024 and DX = 1 and AX >= 1024 --> 2KB partition.
|
||
; > 64.5MB
|
||
|
||
sec2K?_512:
|
||
cmp dx,2
|
||
jb not_2K
|
||
je @F
|
||
shr dx,1 ;convert 512->2K
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
jmp set_2K ; 512 and DX > 2 --> 2KB partition.
|
||
; > 65MB
|
||
|
||
@@:
|
||
cmp ax,400h
|
||
jb not_2K
|
||
shr dx,1 ;convert 512->2K
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
jmp set_2K ; 512 and DX = 2 and AX >= 1024 --> 2KB partition.
|
||
; > 64.5MB
|
||
|
||
sec2K?_256:
|
||
cmp dx,4
|
||
jb not_2K
|
||
je @F
|
||
shr dx,1 ;convert 256->2K
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
jmp set_2K ; 256 and DX > 4 --> 2KB partition.
|
||
; > 65MB
|
||
|
||
@@:
|
||
cmp ax,800h
|
||
jb not_2K
|
||
shr dx,1 ;convert 256->2K
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
shr dx,1
|
||
rcr ax,1
|
||
jmp set_2K ; 256 and DX = 4 and AX >= 1024 --> 2KB partition.
|
||
; > 64.5MB
|
||
|
||
not_2K:
|
||
push cx
|
||
push dx
|
||
push ax
|
||
xor dx,dx
|
||
mov ax,1024
|
||
div bx
|
||
mov cx,ax
|
||
pop ax ;DX:AX total sectors
|
||
pop dx
|
||
@@:
|
||
shr cx,1
|
||
jc @F
|
||
shr dx,1
|
||
rcr ax,1
|
||
jmp short @B
|
||
pop cx ;DX:AX convert ->1KB
|
||
|
||
mov bx,1024
|
||
cmp dx,0
|
||
je @F
|
||
mov ax,0FFFFh
|
||
mov dx,0
|
||
@@:
|
||
;;; follow function is NEC_98 only.
|
||
push ax
|
||
push ds
|
||
push dx
|
||
push cx
|
||
|
||
push cs
|
||
pop ds
|
||
mov dx,offset LPTABLE
|
||
mov cl,13h
|
||
int 220 ;GET LPTABLE
|
||
|
||
add dx,001Ah ;EXLPTABLE start offset
|
||
mov al,DriveToFormat
|
||
shl al,1 ;Drive * 2
|
||
xor ah,ah
|
||
add dx,ax
|
||
inc dx ;+1 (=DA/UA)
|
||
mov bx,dx
|
||
mov al,[bx] ;GET DA/UA at al
|
||
pop cx
|
||
pop dx
|
||
pop ds
|
||
mov ah,al ;al copy to ah
|
||
and al,0F0h
|
||
cmp al,80h
|
||
je @F
|
||
jmp set_SCSItable ;STACK AX ;Not 8xh
|
||
|
||
@@:
|
||
push es
|
||
push ax
|
||
mov ax,40h
|
||
mov es,ax ;es = 0040h
|
||
pop ax
|
||
mov al,es:[0057h]
|
||
pop es
|
||
cmp ah,80h
|
||
je IDE1_check ;STACK AX
|
||
and al,00000111b
|
||
cmp al,00000110b
|
||
je set_SASItable ;STACK AX 2nd IDE is 40MB
|
||
cmp al,00000100b
|
||
je set_SASItable ;STACK AX 2nd IDE is 20MB
|
||
jmp short set_SCSItable ;STACK AX
|
||
IDE1_check:
|
||
and al,00111000b
|
||
cmp al,00110000b
|
||
je set_SASItable ;STACK AX 1st IDE is 40MB
|
||
cmp al,00100000b
|
||
je set_SASItable ;STACK AX 1st IDE is 20MB
|
||
jmp short set_SCSItable ;STACK AX
|
||
|
||
LPTABLE DB 96 DUP (?)
|
||
|
||
set_SASItable:
|
||
pop ax
|
||
mov si, offset SASI1024Table
|
||
jmp short exit_disktable
|
||
set_large1024:
|
||
set_SCSItable:
|
||
pop ax
|
||
mov si, offset SCSI1024Table
|
||
jmp short exit_disktable
|
||
set_large256:
|
||
mov si, offset Large256Table
|
||
jmp short exit_disktable
|
||
set_large512:
|
||
mov si, offset Large512Table
|
||
jmp short exit_disktable
|
||
set_2K:
|
||
mov bx,2048
|
||
cmp dx,0
|
||
je @F
|
||
mov ax,0FFFFh
|
||
mov dx,0
|
||
@@:
|
||
mov si, offset Small2048Table
|
||
|
||
exit_disktable:
|
||
ret
|
||
SetDiskTableNEC_98 endp
|
||
|
||
MY_INT24 proc far
|
||
mov al, 0 ; don't display messages
|
||
iret
|
||
MY_INT24 endp
|
||
|
||
endif
|
||
|
||
CODE ENDS
|
||
|
||
END
|
||
|