Source code of Windows XP (NT5)
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

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