mirror of https://github.com/tongzx/nt5src
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.
947 lines
24 KiB
947 lines
24 KiB
;/*
|
|
; * Microsoft Confidential
|
|
; * Copyright (C) Microsoft Corporation 1991
|
|
; * All Rights Reserved.
|
|
; */
|
|
;===========================================================================
|
|
;
|
|
; FILE: GLBLINIT.ASM
|
|
;
|
|
;===========================================================================
|
|
|
|
;===========================================================================
|
|
;Declaration of include files
|
|
;===========================================================================
|
|
|
|
;
|
|
;---------------------------------------------------------------------------
|
|
;
|
|
; M024 : B#5495. Added "Insufficient memory" message when FORMAT cannot
|
|
; allocate memory for FAT, Directory... etc
|
|
;
|
|
;---------------------------------------------------------------------------
|
|
;
|
|
debug equ 0
|
|
|
|
.xlist
|
|
|
|
INCLUDE BPB.INC
|
|
INCLUDE DOSEQUS.INC
|
|
INCLUDE DOSMAC.INC
|
|
INCLUDE SYSCALL.INC
|
|
INCLUDE FOREQU.INC
|
|
INCLUDE FORMACRO.INC
|
|
INCLUDE IOCTL.INC
|
|
INCLUDE FORSWTCH.INC
|
|
INCLUDE SAFEDEF.INC
|
|
INCLUDE SYSVAR.INC
|
|
.list
|
|
|
|
|
|
;===========================================================================
|
|
; Data segment
|
|
;===========================================================================
|
|
|
|
DATA SEGMENT PUBLIC PARA 'DATA'
|
|
|
|
SECTORS_FOR_MIRROR EQU 7 ; # extra buffer sectors
|
|
; required by Mirror utility,
|
|
; apart from FAT & Root Dir
|
|
|
|
;===========================================================================
|
|
; Declarations for all publics in other modules used by this module
|
|
;===========================================================================
|
|
|
|
;Bytes
|
|
EXTRN msgCrLF :BYTE
|
|
EXTRN DriveToFormat :BYTE
|
|
EXTRN ClustBound_Flag :BYTE
|
|
EXTRN FileStat :BYTE
|
|
EXTRN SystemDriveLetter :BYTE
|
|
EXTRN SecPerClus :BYTE
|
|
EXTRN CMCDDFlag :BYTE
|
|
|
|
;Words
|
|
EXTRN SwitchMap :WORD
|
|
EXTRN mSize :WORD
|
|
EXTRN mStart :WORD
|
|
EXTRN ClustBound_Buffer_Seg :WORD
|
|
EXTRN Paras_per_fat :WORD
|
|
|
|
;Pointers and DWORDs
|
|
EXTRN DirectorySector :DWORD
|
|
EXTRN FatSpace :DWORD
|
|
EXTRN FatSector :DWORD
|
|
EXTRN DirBuf :DWORD
|
|
EXTRN TotalClusters :DWORD
|
|
|
|
;Messages
|
|
EXTRN msgFormatNotSupported :BYTE
|
|
EXTRN msgCantZThisDrive :BYTE
|
|
EXTRN msgCantZWithQ :BYTE
|
|
EXTRN msgCantZFAT16 :BYTE
|
|
EXTRN msgCantZFAT32 :BYTE
|
|
EXTRN msgZFAT32Huge :BYTE
|
|
EXTRN msgZFAT32TooHuge :BYTE
|
|
EXTRN msgOutOfMemory :BYTE
|
|
EXTRN msgInsufficientMemory :BYTE
|
|
IFNDEF OPKBLD
|
|
EXTRN msgNoSysSwitch :BYTE
|
|
ENDIF ;OPKBLD
|
|
|
|
;Structures
|
|
EXTRN SavedParams :BYTE
|
|
EXTRN DeviceParameters :BYTE
|
|
EXTRN IsExtRAWIODrv :BYTE
|
|
EXTRN Bios :BYTE
|
|
EXTRN dos :BYTE
|
|
EXTRN Command :BYTE
|
|
IFDEF DBLSPACE_HOOKS
|
|
EXTRN DblSpaceBin :BYTE
|
|
ENDIF
|
|
|
|
PUBLIC FATNotAllInMem
|
|
PUBLIC FATSecCntInMem
|
|
|
|
FATNotAllInMem db 0
|
|
FATSecCntInMem dd 0
|
|
|
|
ifdef NEC_98
|
|
AllocSectorSize DW ? ; fixed #16585
|
|
endif
|
|
DATA ENDS
|
|
|
|
;===========================================================================
|
|
; Executable code segment
|
|
;===========================================================================
|
|
|
|
CODE SEGMENT PUBLIC PARA 'CODE'
|
|
ASSUME CS:CODE, DS:DATA, ES:DATA
|
|
|
|
|
|
;===========================================================================
|
|
; Declarations for all publics in other modules used by this module
|
|
;===========================================================================
|
|
|
|
;Functions
|
|
|
|
;Labels
|
|
EXTRN FatalExit :NEAR
|
|
EXTRN ReadDos :NEAR
|
|
EXTRN SysPrm :NEAR
|
|
EXTRN exclusive_access_failed :NEAR
|
|
EXTRN IsLockErr? :NEAR
|
|
EXTRN Calc_Big32_Fat :NEAR
|
|
EXTRN Calc_Big16_Fat :NEAR
|
|
EXTRN GetTotalClusters :NEAR
|
|
EXTRN Yes? :NEAR
|
|
|
|
;===========================================================================
|
|
; Declarations for all publics in this module
|
|
;===========================================================================
|
|
|
|
PUBLIC Global_Init
|
|
PUBLIC GetDeviceParameters
|
|
PUBLIC ModifyDevPrmsForZSwich
|
|
|
|
; for debug
|
|
|
|
PUBLIC Copy_Device_Parameters
|
|
PUBLIC Alloc_Dir_Buf
|
|
PUBLIC Alloc_Fat_Buf
|
|
PUBLIC Alloc_Fat_Sec_Buf
|
|
PUBLIC Alloc_DirBuf2
|
|
PUBLIC Alloc_Cluster_Buf
|
|
IFDEF OPKBLD
|
|
PUBLIC Do_Switch_S
|
|
ENDIF ;OPKBLD
|
|
|
|
|
|
;===========================================================================
|
|
;
|
|
; Global_Init : This procedure first gets the default drive parameters.
|
|
; It then allocates buffer space for the root directory
|
|
; sector, FAT,a fat sector, a file header and first
|
|
; root DIR sector based on these parameters. It
|
|
; then checks for the /s switch and if this is present,
|
|
; a buffer is allocated for the system files and these
|
|
; are read into memory. A prompt to insert the system
|
|
; disk will be given in the case of removable media.
|
|
;
|
|
;===========================================================================
|
|
|
|
Global_Init proc near
|
|
|
|
lea DX, DeviceParameters ; Get the default drive parameters
|
|
mov DeviceParameters.DP_SpecialFunctions, 0
|
|
.errnz EDP_SPECIALFUNCTIONS NE DP_SPECIALFUNCTIONS
|
|
call GetDeviceParameters
|
|
|
|
jnc GotDeviceParameters
|
|
call IsLockErr?
|
|
jnc @f
|
|
jmp exclusive_access_failed
|
|
@@:
|
|
Message msgFormatNotSupported
|
|
stc ; Let the jump to FatalExit be made
|
|
ret ; in the main routine, upon returning
|
|
|
|
GotDeviceParameters:
|
|
ifdef NEC_98 ; fixed #16585
|
|
cmp DeviceParameters.DP_DeviceType,DEV_HARDDISK
|
|
je @f
|
|
cmp DeviceParameters.DP_DeviceType,DEV_OPTICAL
|
|
je @f
|
|
mov AllocSectorSize,0400h
|
|
jmp short Set_ok
|
|
@@:
|
|
push bx
|
|
mov bx, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
mov AllocSectorSize,bx
|
|
pop bx
|
|
Set_ok:
|
|
endif ; fixed #16585
|
|
call Copy_Device_Parameters ; Save the device parameters
|
|
; for when we exit
|
|
cmp SecPerClus,0
|
|
je NoZSwtch
|
|
mov ax,1 ; Noisy version
|
|
call ModifyDevPrmsForZSwich
|
|
jc gi_err
|
|
NoZSwtch:
|
|
ifdef NEC_98
|
|
; If 3.5"MO, allcate memory after updating default BPB
|
|
cmp DeviceParameters.DP_DeviceType, DEV_HARDDISK ; Hard disk?
|
|
.errnz EDP_DEVICETYPE NE DP_DEVICETYPE
|
|
jne @F ; No
|
|
|
|
test DeviceParameters.DP_DeviceAttributes, 1 ; Removable?
|
|
.errnz EDP_DEVICEATTRIBUTES NE DP_DEVICEATTRIBUTES
|
|
jz $$IF100 ; Yes
|
|
@@:
|
|
endif
|
|
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
|
|
ELSE
|
|
test SwitchMap,SWITCH_S
|
|
jz NoS1 ; Carry clear if jump
|
|
Message msgNoSysSwitch
|
|
jmp short gi_err
|
|
|
|
NoS1:
|
|
ENDIF ;OPKBLD
|
|
; carry flag determined by Do_Switch_S
|
|
ifdef NEC_98
|
|
$$IF100:
|
|
endif
|
|
ret
|
|
|
|
gi_memerr:
|
|
Message msgInsufficientMemory
|
|
gi_err:
|
|
stc
|
|
ret
|
|
|
|
Global_Init endp
|
|
|
|
; =========================================================================
|
|
;
|
|
; ModifyDevPrmsForZSwich:
|
|
; Modify the device parameters for a different sec/clus value
|
|
;
|
|
; Input:
|
|
; DeviceParameters set
|
|
; AX != 0 for noisy version (do the message thing)
|
|
; Output:
|
|
; carry set if problem.
|
|
;
|
|
; =========================================================================
|
|
|
|
ModifyDevPrmsForZSwich proc near
|
|
|
|
push ax ; Save noisy switch on stack
|
|
.386
|
|
movzx cx,SecPerClus
|
|
.8086
|
|
or cx,cx
|
|
jz MFZDoneJ ; Carry clear if jump
|
|
cmp CMCDDFlag, Yes
|
|
jne DrvOk1
|
|
DispErrMsg:
|
|
mov dx,offset data:msgCantZThisDrive
|
|
DispErrMsgSet:
|
|
pop ax
|
|
push ax
|
|
or ax,ax
|
|
jz MFZDoneErrJ
|
|
call Display_Interface
|
|
MFZDoneErrJ:
|
|
stc
|
|
MFZDoneJ:
|
|
jmp MFZDone
|
|
|
|
DrvOk1:
|
|
;;
|
|
;; This used to ignore things if you weren't actually making a change.
|
|
;; This is now out as it is important to poke Mr. User if he is making
|
|
;; a huge FAT drive.
|
|
;;
|
|
;; cmp cl,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
|
;; je MFZDoneJ ; Carry clear if jump
|
|
;;;;
|
|
mov dx,offset data:msgCantZWithQ
|
|
test SwitchMap,SWITCH_Q ; Check for quick format
|
|
jnz DispErrMsgSet
|
|
mov DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster,cl
|
|
cmp DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFAT,0
|
|
je IsFAT32
|
|
call Calc_Big16_Fat
|
|
mov dx,0002h
|
|
xor ax,ax ; DX:AX = 128k bytes
|
|
mov cx,DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
div cx ; AX = Sectors in 128k
|
|
cmp ax,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFAT
|
|
jb Bad16
|
|
.386
|
|
ja MFZDone ; Carry clear if jump
|
|
.8086
|
|
call GetTotalClusters
|
|
.386
|
|
cmp TotalClusters,0000FFF0h
|
|
.8086
|
|
cmc ; Change "JB Is-OK" to "JNC Is-OK"
|
|
jnc MFZDone
|
|
Bad16:
|
|
mov dx,offset data:msgCantZFAT16
|
|
jmp short DispErrMsgSet
|
|
|
|
IsFAT32:
|
|
call Calc_Big32_Fat
|
|
call GetTotalClusters
|
|
.386
|
|
cmp TotalClusters,65536-10
|
|
.8086
|
|
mov dx,offset data:msgCantZFAT32
|
|
jb DispErrMsgSet
|
|
.386
|
|
mov eax,TotalClusters
|
|
inc eax ; EAX now count including clus 0 and 1
|
|
;
|
|
; GUI SCANDISK is a 16-bit windows app. GlobalAlloc in 16-bit windows is
|
|
; limited to 16Meg-64k per block. Check if we have made a drive with a huge FAT
|
|
; that may result in slow disk util perf.
|
|
;
|
|
cmp eax, ((16 * 1024 * 1024) - (64 * 1024)) / 4
|
|
je short MFZDone ; carry clear if jump
|
|
cmc ; Turn carry around so clear if below limit
|
|
jnc short MFZDone
|
|
.8086
|
|
pop ax
|
|
push ax
|
|
or ax,ax ; Noisy?
|
|
jz MFZDone ; No, Carry clear if jump
|
|
Message msgZFAT32Huge
|
|
call Yes? ; Carry clear if YES, set if NO
|
|
pushf
|
|
Message msgCrlf
|
|
popf
|
|
MFZDone:
|
|
pop ax
|
|
ret
|
|
|
|
ModifyDevPrmsForZSwich endp
|
|
|
|
; =========================================================================
|
|
;
|
|
; GetDeviceParameters:
|
|
; Get the device parameters
|
|
;
|
|
; Input:
|
|
; DriveToFormat
|
|
; DX - pointer to device parameters
|
|
; =========================================================================
|
|
|
|
GetDeviceParameters proc near
|
|
|
|
mov AX, (IOCTL shl 8) or GENERIC_IOCTL
|
|
mov bl, DriveToFormat
|
|
inc bl
|
|
mov CX, (EXTRAWIO shl 8) or GET_DEVICE_PARAMETERS
|
|
int 21H
|
|
jc TryOldForm
|
|
mov IsExtRAWIODrv,1
|
|
DoRet:
|
|
jc realdoret
|
|
push bx
|
|
mov bx,dx
|
|
cmp [bx.DP_BPB.oldBPB.BPB_TotalSectors],0
|
|
je realdoretP
|
|
;
|
|
; the WORD total sectors field is non-zero, make sure the DWORD
|
|
; total sectors field is 0. Having BigTotalSectors be a DWORD
|
|
; version of TotalSectors in this case is SUPPOSED to be perfectly
|
|
; ok but it turns out that several apps (mostly SETUP apps) get
|
|
; upset about this (on floppies in particular).
|
|
;
|
|
mov [bx.DP_BPB.oldBPB.BPB_BigTotalSectors],0
|
|
mov [bx.DP_BPB.oldBPB.BPB_BigTotalSectors+2],0
|
|
realdoretP:
|
|
pop bx
|
|
clc
|
|
realdoret:
|
|
return
|
|
|
|
TryOldForm:
|
|
mov IsExtRAWIODrv,0
|
|
mov AX, (IOCTL shl 8) or GENERIC_IOCTL
|
|
mov bl, DriveToFormat
|
|
inc bl
|
|
mov CX, (RAWIO shl 8) or GET_DEVICE_PARAMETERS
|
|
int 21H
|
|
jmp short DoRet
|
|
|
|
GetDeviceParameters endp
|
|
|
|
;==========================================================================
|
|
;
|
|
; Copy_Device_Parameters : This procedure saves a copy of the original
|
|
; device parameters in the structure
|
|
; SavedParams.
|
|
;
|
|
;==========================================================================
|
|
|
|
Copy_Device_Parameters proc near
|
|
|
|
lea SI, DeviceParameters
|
|
lea DI, SavedParams
|
|
mov CX, size EA_DeviceParameters
|
|
push DS
|
|
pop ES
|
|
rep movsb
|
|
ret
|
|
|
|
Copy_Device_Parameters endp
|
|
|
|
|
|
;==========================================================================
|
|
;
|
|
; Alloc_Dir_Buf : This procedure allocates a memory block for the root
|
|
; directory buffer, based on the device parameters only.
|
|
;
|
|
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
; Outputs : CY CLEAR - DirectorySector pointer to buffer
|
|
; CY SET - failure
|
|
; Modifies : AX, BX, DirectorySector
|
|
;
|
|
;==========================================================================
|
|
|
|
Alloc_Dir_Buf proc near
|
|
; DirectorySector =
|
|
; malloc( Bytes Per Sector )
|
|
ifdef NEC_98 ; fixed #16585
|
|
mov BX, AllocSectorSize
|
|
else
|
|
mov BX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
endif
|
|
.errnz EDP_BPB NE DP_BPB
|
|
add BX, 0fH
|
|
.386
|
|
shr bx, 4 ; Divide by 16 to get #paragraphs
|
|
.8086
|
|
mov AH, Alloc
|
|
int 21h
|
|
jc Exit_Alloc_Dir_Buf
|
|
; Base address of newly allocated
|
|
; block is AX:0000
|
|
mov WORD PTR DirectorySector+2,AX
|
|
xor AX,AX
|
|
mov WORD PTR DirectorySector,AX
|
|
|
|
Exit_Alloc_Dir_Buf:
|
|
ret
|
|
|
|
Alloc_Dir_Buf endp
|
|
|
|
;==========================================================================
|
|
;
|
|
; Alloc_Fat_Buf : This procedure allocates a memory block for the FAT
|
|
; buffer, based on the device parameters only. In order
|
|
; to ensure there is enough buffer space for the Mirror
|
|
; utility, the FatSpace buffer is initially allocated
|
|
; with size:
|
|
; FAT + RootDir + 6 sectors + 1 surplus sector
|
|
; which is all the buffer space required by Mirror.
|
|
;
|
|
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
; DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
|
|
; DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
|
|
; DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
|
|
;
|
|
; Outputs : CY CLEAR - FatSpace pointer to buffer
|
|
; CY SET - failure
|
|
;
|
|
; Modifies : AX, BX, DX, FatSpace
|
|
;
|
|
;==========================================================================
|
|
|
|
Alloc_Fat_Buf proc near
|
|
|
|
xor ax,ax
|
|
mov FATNotAllInMem,al ; Assume FAT will fit in mem
|
|
.386
|
|
ifdef NEC_98 ; fixed #16585
|
|
cmp DeviceParameters.DP_DeviceType, DEV_3INCH1440KB
|
|
jne short $$IF101
|
|
cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors, 0
|
|
je short $$IF101
|
|
movzx EAX, AllocSectorSize
|
|
jmp short $$EN101
|
|
$$IF101:
|
|
movzx EAX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
$$EN101:
|
|
else
|
|
movzx EAX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
endif
|
|
.errnz EDP_BPB NE DP_BPB
|
|
add EAX, 0fH ; round up for next para
|
|
shr eax, 4 ; convert to paras
|
|
movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerFat
|
|
or bx,bx
|
|
jnz short GotFSz
|
|
mov ebx,dword ptr DeviceParameters.DP_BPB.BGBPB_BigSectorsPerFat
|
|
GotFSz:
|
|
mul ebx
|
|
or edx,edx
|
|
jz short NotHi
|
|
GotBigFat:
|
|
mov FATNotAllInMem,1
|
|
mov eax,128*1024
|
|
movzx ebx,DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
xor edx,edx
|
|
div ebx
|
|
mov FATSecCntInMem,eax
|
|
mov ax,(128*1024)/16
|
|
jmp short SetRestFatBuf
|
|
|
|
NotHi:
|
|
cmp eax,(128*1024)/16 ; FAT bigger than 128k?
|
|
ja short GotBigFat ; Yes
|
|
SetRestFatBuf:
|
|
.8086
|
|
mov BX,AX ; Save FAT size in paras in BX
|
|
mov Paras_per_fat,BX ; Set paras_per_fat here, to
|
|
; avoid having to calculate it later
|
|
; Now add on root dir + extra sectors
|
|
mov AX,DeviceParameters.DP_BPB.oldBPB.BPB_RootEntries
|
|
;; shl ax,5 ; * 32 bytes per dor entry
|
|
;; shr ax,4 ; / 16 bytes per para
|
|
;; Combine above two shifts....
|
|
shl AX,1 ; AX = para size of root dir
|
|
|
|
add BX,AX ; BX = FAT + root dir
|
|
|
|
ifdef NEC_98 ; fixed #16585
|
|
cmp DeviceParameters.DP_DeviceType, DEV_3INCH1440KB
|
|
jne $$IF102
|
|
cmp DeviceParameters.DP_BPB.oldBPB.BPB_TotalSectors, 0
|
|
je $$IF102
|
|
mov AX, AllocSectorSize
|
|
jmp short $$EN102
|
|
$$IF102:
|
|
mov AX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
$$EN102:
|
|
else
|
|
mov AX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
endif
|
|
add AX, 0fH ; round up for next para
|
|
.386
|
|
shr AX, 4 ; convert to paras
|
|
.8086
|
|
mov CX,SECTORS_FOR_MIRROR ; CX = # additional sectors needed by Mirror
|
|
mul CX ; AX = total extra sector size in paras
|
|
|
|
add BX,AX ; BX = FAT + root dir + extra sectors
|
|
; in paras
|
|
mov AH,Alloc
|
|
int 21h
|
|
jc Exit_Alloc_Fat_Buf
|
|
|
|
mov WORD PTR FatSpace+2,AX
|
|
xor AX,AX
|
|
mov WORD PTR FatSpace,AX
|
|
|
|
Exit_Alloc_Fat_Buf:
|
|
ret
|
|
|
|
Alloc_Fat_Buf endp
|
|
|
|
;==========================================================================
|
|
;
|
|
; Alloc_Fat_Sec_Buf : This procedure allocates a memory block for the fat
|
|
; sector buffer which is used when copying chains from
|
|
; the old FAT to the new FAT.
|
|
;
|
|
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
; Outputs : CY CLEAR - FatSector pointer to buffer
|
|
; CY SET - failure
|
|
; Modifies : AX, BX, FatSector
|
|
;
|
|
;==========================================================================
|
|
|
|
Alloc_Fat_Sec_Buf proc near
|
|
; FatSector =
|
|
; malloc( Bytes Per Sector )
|
|
ifdef NEC_98 ; fixed #16585
|
|
mov BX, AllocSectorSize
|
|
else
|
|
mov BX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
endif
|
|
.errnz EDP_BPB NE DP_BPB
|
|
add BX, 0fH
|
|
.386
|
|
shr BX, 4 ; Divide by 16 to get #paragraphs
|
|
.8086
|
|
mov AH, Alloc
|
|
int 21h
|
|
jc Exit_Alloc_Fat_Sec_Buf
|
|
; Base address of newly allocated
|
|
; block is AX:0000
|
|
mov WORD PTR FatSector+2,AX
|
|
xor AX,AX
|
|
mov WORD PTR FatSector,AX
|
|
|
|
Exit_Alloc_Fat_Sec_Buf:
|
|
ret
|
|
|
|
Alloc_Fat_Sec_Buf endp
|
|
|
|
;==========================================================================
|
|
;
|
|
; Alloc_DirBuf2 : This procedure allocates a memory block for a 1-sector
|
|
; buffer. This buffer is used when reading in the boot
|
|
; sector in Phase1.
|
|
;
|
|
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
; Outputs : CY CLEAR - DirBuf pointer to buffer
|
|
; CY SET - failure
|
|
; Modifies : AX, BX, DirBuf
|
|
;
|
|
;==========================================================================
|
|
|
|
Alloc_DirBuf2 proc near
|
|
; DirBuf =
|
|
; malloc( Bytes Per Sector )
|
|
ifdef NEC_98 ; fixed #16585
|
|
mov BX, AllocSectorSize
|
|
else
|
|
mov BX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
endif
|
|
.errnz EDP_BPB NE DP_BPB
|
|
add BX, 0fH
|
|
.386
|
|
shr BX, 4 ; Divide by 16 to get #paragraphs
|
|
.8086
|
|
mov AH, Alloc
|
|
int 21h
|
|
jc Exit_Alloc_DirBuf2
|
|
; Base address of newly allocated
|
|
; block is AX:0000
|
|
mov WORD PTR DirBuf+2,AX
|
|
xor AX,AX
|
|
mov WORD PTR DirBuf,AX
|
|
|
|
Exit_Alloc_DirBuf2:
|
|
ret
|
|
|
|
Alloc_DirBuf2 endp
|
|
|
|
;=========================================================================
|
|
; Alloc_Cluster_Buf : This routine will allocate a buffer
|
|
; based on a cluster's size. If enough
|
|
; space does not exist, a cluster will
|
|
; be redefined to a smaller size for
|
|
; purposes of sector retries.
|
|
; Note: This buffer is used only for bad
|
|
; tracks on hard disks.
|
|
;
|
|
; Inputs : DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
; DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
|
;
|
|
; Outputs : ClustBound_Flag - True (space available)
|
|
; False(not enough space)
|
|
; ClustBound_Buffer_Seg - Pointer to buffer
|
|
;=========================================================================
|
|
|
|
Procedure Alloc_Cluster_Buf
|
|
|
|
push AX ; Save regs
|
|
push BX
|
|
|
|
mov AX,(Alloc shl 8) ; Allocate memory
|
|
mov BX,0ffffh ; Get available memory
|
|
int 21h
|
|
|
|
ifdef NEC_98 ; fixed #16585
|
|
mov AX, AllocSectorSize
|
|
else
|
|
mov AX, DeviceParameters.DP_BPB.oldBPB.BPB_BytesPerSector
|
|
endif
|
|
.errnz EDP_BPB NE DP_BPB
|
|
add AX, 0fH
|
|
.386
|
|
shr AX, 4
|
|
.8086
|
|
mul DeviceParameters.DP_BPB.oldBPB.BPB_SectorsPerCluster
|
|
|
|
cmp BX,AX ; Enough room
|
|
jna $$IF137 ; Yes
|
|
|
|
mov BX,AX ; Allocate needed memory
|
|
mov AX,(Alloc shl 8)
|
|
int 21h
|
|
mov ClustBound_Buffer_Seg,AX ; Save pointer to buffer
|
|
mov ClustBound_Flag,True ; Signal space available
|
|
jmp SHORT $$EN137 ; Not enough room
|
|
|
|
$$IF137:
|
|
mov ClustBound_Flag,False ; Signal not enough space
|
|
|
|
$$EN137:
|
|
pop BX ; Restore regs
|
|
pop AX
|
|
|
|
ret
|
|
|
|
Alloc_Cluster_Buf ENDP
|
|
|
|
IFDEF OPKBLD
|
|
|
|
;=========================================================================
|
|
;
|
|
; DO_SWITCH_S : This procedure will load the system files into
|
|
; memory (if there's space) if the /s switch is
|
|
; specified.
|
|
;
|
|
; CALLS : ReadDos
|
|
; SysPrm
|
|
; CALLED BY : Global_Init
|
|
; STRATEGY : The largest block of memory available is first
|
|
; determined. The program is aborted if this is zero.
|
|
; This block is then allocated, and the system files
|
|
; are read into it. A prompt for the system disk
|
|
; will be given if the system files are not found.
|
|
;
|
|
;=========================================================================
|
|
|
|
Do_Switch_S proc near
|
|
|
|
test SwitchMap,SWITCH_S
|
|
.386
|
|
jz End_Do_Switch_S ; System files not required
|
|
; allocate memory for system files
|
|
.8086
|
|
mov BX,0ffffh ; This call will actually fail
|
|
mov AH,Alloc ; so that BX returns max block avlbl
|
|
int 21h
|
|
|
|
or BX,BX
|
|
jz MemErr ; No memory
|
|
mov [mSize],BX ; Now allocate the largest block
|
|
mov AH,alloc
|
|
int 21h
|
|
jnc Mem_OK
|
|
|
|
MemErr:
|
|
mov AX, seg data ; Check for memory allocation error
|
|
mov DS, AX
|
|
Message msgOutOfMemory ; call PrintString
|
|
stc ; Let the jump to FatalExit be made
|
|
jmp End_Do_Switch_S ; in the main routine, upon returning
|
|
|
|
Mem_OK:
|
|
mov [mStart],AX ; Save the starting paragraph
|
|
|
|
; =========================================================================
|
|
; This call to ReadDos may not be able to read in all of the DOS files if
|
|
; there is insufficient memory available. In that case the files will
|
|
; be read in after the disk is formatted. If the Drive being formatted is
|
|
; also the boot Drive this function will read the files from that
|
|
; Drive if there is enough memory. If there is insufficent memory it will
|
|
; force the files to be read from Drive A: if the Drive being formatted
|
|
; is also the boot Drive
|
|
; M011; Wrong: Try Boot, Then Default, Then sysprm (usually "A").
|
|
; If not enough memory at boot time, we fail.
|
|
; =========================================================================
|
|
|
|
RdFrst:
|
|
mov AH,GET_DEFAULT_Drive ; Find out default Drive
|
|
int 21h
|
|
push AX ; save default Drive
|
|
mov ax, 3305h ; get startup drive
|
|
int 21h
|
|
mov al,dl
|
|
add AL,40h ; Make it ASCII
|
|
pop BX ; restore default Drive
|
|
ifndef NEC_98
|
|
cmp AL,41h ; Q: Booted from Drive A?
|
|
jnz go_get_Bios ; N: Not a special case
|
|
cmp bl,1 ; Q: is B: current Drive
|
|
jnz go_get_Bios ; N: Not a special case
|
|
jmp short check_default ; check default Drive
|
|
endif
|
|
|
|
go_get_Bios: ; Here to check booted
|
|
call Get_Host_Drive ; Translate to DblSpace host
|
|
mov SystemDriveLetter,AL ; (if necessary)
|
|
|
|
call ReadDos
|
|
jnc CheckAllFilesIn
|
|
|
|
check_default: ; Here to check default
|
|
mov AH,GET_DEFAULT_Drive ; Find out default Drive
|
|
int 21h
|
|
add AL,41h ; Make it ASCII, 1 based
|
|
call Get_Host_Drive ; Translate to DblSpace host
|
|
mov SystemDriveLetter,AL
|
|
|
|
TryThisOne:
|
|
call ReadDos ; Read BIOS and DOS
|
|
jnc CheckAllFilesIn ; Files read in OK
|
|
NeedSys:
|
|
call SysPrm ; Prompt for system disk
|
|
jmp TryThisOne ; Try again
|
|
|
|
CheckAllFilesIn:
|
|
; abort program here if all system files
|
|
; have not been read into memory, since
|
|
; program fails when trying to read them
|
|
; in after formatting is complete
|
|
and FileStat,3fh ; zero out 2 msb
|
|
cmp FileStat,22h ; BIOS and COMMAND in memory?
|
|
jne MemErr ; no - abort program
|
|
;
|
|
; Now we have all of the files in memory, SETBLOCK the allocation
|
|
; block down to the amount required.
|
|
;
|
|
.386
|
|
mov bx,[dos.fileStartSegment]
|
|
mov eax,[dos.fileSizeInBytes]
|
|
cmp bx,[bios.fileStartSegment]
|
|
ja short Skip1
|
|
mov bx,[bios.fileStartSegment]
|
|
mov eax,[bios.fileSizeInBytes]
|
|
Skip1:
|
|
cmp bx,[command.fileStartSegment]
|
|
ja short Skip2
|
|
mov bx,[command.fileStartSegment]
|
|
mov eax,[command.fileSizeInBytes]
|
|
Skip2:
|
|
IFDEF DBLSPACE_HOOKS
|
|
cmp bx,[DblSpaceBin.fileStartSegment]
|
|
ja short Skip3
|
|
mov bx,[DblSpaceBin.fileStartSegment]
|
|
mov eax,[DblSpaceBin.fileSizeInBytes]
|
|
Skip3:
|
|
ENDIF
|
|
add eax,15
|
|
shr eax,4 ; AX = # of paras from SEG BX
|
|
.8086
|
|
add bx,ax ; SEG after end of sys files
|
|
sub bx,[mStart] ; SIZE of sys area
|
|
mov es,[mStart]
|
|
mov AH,setblock
|
|
int 21h
|
|
clc ; yes
|
|
End_Do_Switch_S:
|
|
ret
|
|
|
|
Do_Switch_S ENDP
|
|
|
|
|
|
;******************* START OF SPECIFICATIONS ***********************************
|
|
;Routine name: Get_Host_Drive
|
|
;*******************************************************************************
|
|
;
|
|
;Description: Given a drive letter in AL, check to see if it is a dblspace
|
|
; drive, and if so, translate the drive letter to the host
|
|
; drive letter.
|
|
;
|
|
;Called Procedures: None
|
|
;
|
|
;Input: ASCII drive letter in AL
|
|
;
|
|
;Output: drive letter in AL
|
|
;
|
|
;Change History: Created 11/21/92 MD
|
|
; Cut and paste from SYS command 12/07/92 JEM
|
|
;
|
|
;******************* END OF SPECIFICATIONS *************************************
|
|
|
|
public Get_Host_Drive
|
|
|
|
Get_Host_Drive PROC NEAR
|
|
|
|
push ax
|
|
mov ax,4a11h ; DBLSPACE multiplex number
|
|
xor bx,bx ; inquire version number
|
|
int 2fh
|
|
or ax,ax ; error?
|
|
jnz not_dblspace
|
|
cmp bx,'DM' ; stamp returned correctly?
|
|
jnz not_dblspace
|
|
|
|
; DBLSPACE.BIN is loaded. At this time:
|
|
;
|
|
; (dx & 0x7fff) == driver internal version number
|
|
; high bit of DH set of driver has not yet been permanently placed
|
|
; cl == first disk letter reserved for DBLSPACE
|
|
; ch == number of disk letters reserved for DBLSPACE
|
|
|
|
mov ax,4a11h ; DBLSPACE multiplex number
|
|
mov bx,1 ; inquire drive map
|
|
pop dx
|
|
push dx
|
|
sub dl, 'A' ; convert drv letter to 0 based drv number
|
|
int 2fh
|
|
test bl,80h ; COMPRESSED bit true?
|
|
jz not_dblspace
|
|
|
|
; Drive is compressed. At this time:
|
|
;
|
|
; (bl & 0x7f) == host drive's CURRENT drive number
|
|
; bh == CVF extension number
|
|
;
|
|
mov al,bl
|
|
and al,7Fh
|
|
add al, 'A' ; convert drv number to drv letter
|
|
cbw
|
|
pop dx
|
|
push ax
|
|
|
|
not_dblspace:
|
|
pop ax
|
|
ret
|
|
|
|
Get_Host_Drive ENDP
|
|
|
|
ENDIF ;OPKBLD
|
|
|
|
CODE ENDS
|
|
|
|
END
|
|
|