windows-nt/Source/XPSP1/NT/base/ntsetup/opktools/oformat/glblinit.asm
2020-09-26 16:20:57 +08:00

948 lines
24 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;/*
; * 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