1250 lines
29 KiB
NASM
1250 lines
29 KiB
NASM
;/*
|
||
; * Microsoft Confidential
|
||
; * Copyright (C) Microsoft Corporation 1991
|
||
; * All Rights Reserved.
|
||
; */
|
||
;===========================================================================
|
||
;
|
||
; FILE: .ASM
|
||
;
|
||
;===========================================================================
|
||
|
||
;===========================================================================
|
||
;Declaration of include files
|
||
;===========================================================================
|
||
debug equ 0
|
||
.xlist
|
||
INCLUDE DOSEQUS.INC
|
||
INCLUDE DOSMAC.INC
|
||
INCLUDE SYSCALL.INC
|
||
INCLUDE ERROR.INC
|
||
INCLUDE DIRENT.INC
|
||
INCLUDE BPB.INC
|
||
INCLUDE FOREQU.INC
|
||
INCLUDE FORMACRO.INC
|
||
.list
|
||
;
|
||
;---------------------------------------------------------------------------
|
||
;
|
||
; M029 : Remove the assumption that COMSPEC= has an absolute path name.
|
||
; and build the file name (COMMAND.COM) in a different buffer
|
||
; other than the buffer in which COMSPEC was stored.
|
||
;
|
||
;---------------------------------------------------------------------------
|
||
;
|
||
|
||
;===========================================================================
|
||
; Data segment
|
||
;===========================================================================
|
||
|
||
DATA SEGMENT PUBLIC PARA 'DATA'
|
||
|
||
;===========================================================================
|
||
; Declarations for all publics in other modules used by this module
|
||
;===========================================================================
|
||
|
||
;Bytes
|
||
EXTRN DriveLetter :BYTE
|
||
EXTRN SystemDriveLetter :BYTE
|
||
EXTRN Extended_Error_Msg :BYTE
|
||
EXTRN BiosFile :BYTE
|
||
EXTRN AltBiosFile :BYTE
|
||
EXTRN AltBiosLen :ABS
|
||
EXTRN MsdosFile :BYTE
|
||
EXTRN MsdosRemark :BYTE
|
||
EXTRN MsdosRemarkLen :ABS
|
||
IFDEF DBLSPACE_HOOKS
|
||
EXTRN fDblSpace :BYTE
|
||
ENDIF
|
||
|
||
;Words
|
||
EXTRN mStart :WORD
|
||
EXTRN mSize :WORD
|
||
EXTRN Environ_Segment :WORD
|
||
EXTRN PSP_Segment :WORD
|
||
|
||
;Pointers
|
||
|
||
;Structures
|
||
EXTRN Bios :BYTE
|
||
EXTRN dos :BYTE
|
||
EXTRN command :BYTE
|
||
IFDEF DBLSPACE_HOOKS
|
||
EXTRN DblSpaceBin :BYTE
|
||
ENDIF
|
||
|
||
|
||
BiosAttributes equ attr_hidden + attr_system + attr_read_only
|
||
DosAttributes equ attr_hidden + attr_system + attr_read_only
|
||
|
||
IFDEF DBLSPACE_HOOKS
|
||
DblSpaceAttributes equ attr_hidden + attr_system + attr_read_only
|
||
ENDIF
|
||
|
||
CommandAttributes equ 0
|
||
|
||
CommandFile db "X:\COMMAND.COM",0
|
||
db (128 - 15) DUP (0) ; M012
|
||
|
||
Comspec_ID db "COMSPEC=",00 ; Comspec target
|
||
|
||
; DOS status bits in FileStat are unused.
|
||
; Starting with Chicago, IO.SYS and MSDOS.SYS have been combined.
|
||
; For our purposes, the single file will be referred to as BIOS.
|
||
FileStat db ? ; In memory Status of files
|
||
; XXXXXX00B BIOS not in
|
||
; XXXXXX01B BIOS partly in
|
||
; XXXXXX10B BIOS all in
|
||
; XXXX00XXB DOS not in
|
||
; XXXX01XXB DOS partly in
|
||
; XXXX10XXB DOS all in
|
||
; XX00XXXXB COMMAND not in
|
||
; XX01XXXXB COMMAND partly in
|
||
; XX10XXXXB COMMAND all in
|
||
|
||
Command_Com DB "X:\COMMAND.COM",0 ; M029
|
||
|
||
|
||
IFDEF DBLSPACE_HOOKS
|
||
DblSpaceFile db "X:\DRVSPACE.BIN",0 ;full path to source copy
|
||
db 64 DUP (0) ; of DRVSPACE.bin
|
||
|
||
DblSpaceTargetName db "X:\" ;target DRVSPACE.bin name
|
||
DblSpaceBase db "DRVSPACE.BIN",0 ;base name used to srch PATH
|
||
ENDIF
|
||
|
||
|
||
DOS_BUFFER db 45 dup (?) ; Find First/Next buffer
|
||
|
||
TempHandle dw ?
|
||
|
||
IOCNT dd ?
|
||
|
||
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
|
||
EXTRN SysPrm :NEAR
|
||
EXTRN TargPrm :NEAR
|
||
EXTRN Get_PSP_Parms :NEAR
|
||
EXTRN Cap_Char :NEAR
|
||
|
||
;Labels
|
||
EXTRN FatalExit :NEAR
|
||
EXTRN Find_Path_In_Environment:NEAR
|
||
EXTRN Path_Crunch :NEAR
|
||
EXTRN Search :NEAR
|
||
|
||
;===========================================================================
|
||
; Declarations for all publics in this module
|
||
;===========================================================================
|
||
|
||
PUBLIC ReadDos
|
||
PUBLIC WriteDos
|
||
PUBLIC CommandFile
|
||
|
||
IFDEF DBLSPACE_HOOKS
|
||
PUBLIC DblSpaceFile
|
||
ENDIF
|
||
|
||
PUBLIC FileStat
|
||
|
||
; ==========================================================================
|
||
; Copy WINBOOT.SYS, COMMAND.COM, and DRVSPACE.BIN (if present) into
|
||
; data area.
|
||
; Carry set if problems
|
||
; M011; SystemDriveLetter=Drive to Try
|
||
; ==========================================================================
|
||
|
||
ReadDos:
|
||
;M011 - begin
|
||
xor ax, ax
|
||
mov Bios.FileSizeInParagraphs, ax ; Initialize file sizes
|
||
mov Command.FileSizeInParagraphs, ax
|
||
IFDEF DBLSPACE_HOOKS
|
||
mov DblSpaceBin.FileSizeInParagraphs, ax
|
||
ENDIF
|
||
mov AL,SystemDriveLetter
|
||
mov [BiosFile],AL ; Stuff it in file specs.
|
||
mov [CommandFile],AL
|
||
IFDEF DBLSPACE_HOOKS
|
||
mov [DblSpaceFile], al
|
||
ENDIF
|
||
|
||
call Get_Bios
|
||
jnc RdFils
|
||
;M011 - end
|
||
return
|
||
|
||
RdFils:
|
||
mov BYTE PTR [FileStat],0
|
||
mov BX,[Bios.fileHandle]
|
||
mov AX,[mStart]
|
||
mov DX,AX
|
||
add DX,[mSize] ; CX first bad para
|
||
mov [Bios.fileStartSegment],AX
|
||
mov CX,[Bios.fileSizeInParagraphs]
|
||
add AX,CX
|
||
cmp AX,DX
|
||
jbe GotBios
|
||
|
||
mov BYTE PTR [FileStat],00000001B ; Got part of Bios
|
||
mov SI,[mSize]
|
||
xor DI,DI
|
||
call DISIX4
|
||
|
||
push DS
|
||
mov DS,[Bios.fileStartSegment]
|
||
|
||
assume DS:NOTHING
|
||
call ReadFile
|
||
pop DS
|
||
|
||
assume DS:data
|
||
jc ClsAll
|
||
xor DX,DX
|
||
mov CX,DX
|
||
mov AX,(LSEEK shl 8) OR 1
|
||
int 21H
|
||
mov WORD PTR [Bios.fileOffset],AX
|
||
mov WORD PTR [Bios.fileOffset+2],DX
|
||
|
||
FilesDone:
|
||
clc
|
||
|
||
ClsAll:
|
||
pushF
|
||
call FILE_CLS
|
||
popF
|
||
return
|
||
|
||
; ==========================================================================
|
||
|
||
GotBios:
|
||
mov BYTE PTR [FileStat],00000010B ; Got all of Bios
|
||
push ES
|
||
les SI,[Bios.fileSizeInBytes]
|
||
mov DI,ES
|
||
pop ES
|
||
push DS
|
||
mov DS,[Bios.fileStartSegment]
|
||
|
||
assume DS:nothing
|
||
call ReadFile
|
||
pop DS
|
||
|
||
assume DS:data
|
||
jc ClsAll
|
||
|
||
push AX
|
||
push DX
|
||
call File_Cls
|
||
call Get_DOS
|
||
pop DX
|
||
pop AX
|
||
ClsAllJ:
|
||
jnc notClsAll
|
||
jmp ClsAll
|
||
|
||
NotClsAll:
|
||
push AX
|
||
push DX
|
||
call Get_Command_Path ; get path of COMMAND.COM
|
||
call Get_Command ; Point to COMMAND and read it
|
||
pop DX
|
||
pop AX
|
||
jnc Found_Command
|
||
|
||
return
|
||
|
||
; ==========================================================================
|
||
|
||
Found_COMMAND:
|
||
mov BX,[command.fileHandle]
|
||
mov [command.fileStartSegment],AX
|
||
cmp AX,DX ; No room left?
|
||
jz ClsAllJ ; Yes
|
||
|
||
mov CX,[command.fileSizeInParagraphs]
|
||
add AX,CX
|
||
cmp AX,DX
|
||
jbe GotCom
|
||
|
||
or BYTE PTR [FileStat],00010000B ; Got part of COMMAND
|
||
sub DX,[command.fileStartSegment]
|
||
mov SI,DX
|
||
xor DI,DI
|
||
call DISIX4
|
||
push DS
|
||
mov DS,[command.fileStartSegment]
|
||
assume DS:nothing
|
||
call ReadFile
|
||
pop DS
|
||
assume DS:data
|
||
jc ClsAllJ
|
||
|
||
xor DX,DX
|
||
mov CX,DX
|
||
mov AX,(LSEEK shl 8) OR 1
|
||
int 21h
|
||
mov WORD PTR [command.fileOffset],AX
|
||
mov WORD PTR [command.fileOffset+2],DX
|
||
jmp FilesDone
|
||
|
||
GotCom:
|
||
or BYTE PTR [FileStat],00100000B ; Got all of COMMAND
|
||
push ES
|
||
les SI,[command.fileSizeInBytes]
|
||
mov DI,ES
|
||
pop ES
|
||
push DS
|
||
mov DS,[command.fileStartSegment]
|
||
assume DS:nothing
|
||
call ReadFile
|
||
pop DS
|
||
assume DS:data
|
||
jc ClsAllJ
|
||
|
||
|
||
|
||
IFDEF DBLSPACE_HOOKS
|
||
|
||
; Attempt to locate dblspace.bin
|
||
|
||
push ax
|
||
push dx
|
||
call File_cls ; close COMMAND.COM
|
||
call Get_DblSpace
|
||
pop dx
|
||
pop ax
|
||
jnc Found_DblSpace
|
||
|
||
; DblSpace.bin is nowhere to be found! This isn't fatal, clear
|
||
; carry and return.
|
||
|
||
clc
|
||
return
|
||
|
||
; ==========================================================================
|
||
|
||
; DblSpace.bin has been located, will it fit in memory?
|
||
; AX has next free location in memory buffer, DX has
|
||
; (just past) end of buffer address.
|
||
|
||
Found_DblSpace:
|
||
mov bx, [DblSpaceBin.fileHandle]
|
||
mov [DblSpaceBin.fileStartSegment], ax
|
||
|
||
cmp ax, dx ; any room left?
|
||
jz ClsAllJ2 ; no!
|
||
|
||
mov cx, [DblSpaceBin.fileSizeInParagraphs]
|
||
add ax, cx
|
||
cmp ax, dx
|
||
jbe GotDblSpace
|
||
;
|
||
; No mem for dblspace driver. Lets not count its size towards SysSiz
|
||
;
|
||
mov word ptr [DblSpaceBin.fileSizeInBytes], 0
|
||
mov word ptr [DblSpaceBin.fileSizeInBytes].2, 0
|
||
;
|
||
; BUGBUG :: Display a warning message
|
||
;
|
||
|
||
ClsAllJ2: ; insufficient memory, skip
|
||
jmp ClsAll ; DRVSPACE.bin (CY is clear)
|
||
|
||
GotDblSpace:
|
||
mov [fDblSpace], TRUE ; got it!
|
||
mov si, word ptr [DblSpaceBin.fileSizeInBytes]
|
||
mov di, word ptr [DblSpaceBin.fileSizeInBytes+2] ; di:si = size
|
||
push ds
|
||
mov ds, [DblSpaceBin.fileStartSegment] ; ds:0 = addr
|
||
assume ds:nothing
|
||
call ReadFile ; load it
|
||
pop ds
|
||
assume ds:data
|
||
|
||
ENDIF
|
||
|
||
|
||
|
||
jmp ClsAll
|
||
|
||
; ==========================================================================
|
||
; Write Bios DOS COMMAND to the newly formatted disk.
|
||
; ==========================================================================
|
||
|
||
ASSUME DS:DATA
|
||
|
||
WriteDos:
|
||
mov CX,BiosAttributes
|
||
mov DX,OFFSET BiosFile ; DS:DX --> ASCIIZ pathname
|
||
push ES
|
||
les SI,[Bios.fileSizeInBytes]
|
||
mov DI,ES ; DI:SI is file size
|
||
pop ES
|
||
call MakeFil ; create & open file in dest. drive
|
||
retc
|
||
|
||
mov [TempHandle],BX ; save file handle
|
||
test BYTE PTR FileStat,00000010B ; is BIOS all in already?
|
||
jnz GotAllBio ; yes, write it out
|
||
call Get_Bios ; no, read it in
|
||
jnc Got_WBios ; check for error
|
||
ret
|
||
|
||
; ==========================================================================
|
||
|
||
Got_WBios:
|
||
|
||
push ES
|
||
LES SI,[Bios.fileOffset]
|
||
mov DI,ES ; DI:SI is file pointer
|
||
pop ES
|
||
mov WORD PTR [IOCNT],SI
|
||
mov WORD PTR [IOCNT+2],DI
|
||
mov BP,OFFSET Bios ; BP --> parameter block for BIOS file
|
||
call GotTArg
|
||
retc
|
||
jmp SHORT BiosDone
|
||
|
||
GotAllBio:
|
||
push ES
|
||
LES SI,[Bios.fileSizeInBytes]
|
||
mov DI,ES ; DI:SI is BIOS file size
|
||
pop ES
|
||
push DS
|
||
mov DS,[Bios.fileStartSegment] ; DS:0 --> start of BIOS in memory
|
||
assume DS:nothing
|
||
call WriteFile ; write BIOS to disk
|
||
pop DS
|
||
assume DS:data
|
||
BiosDone:
|
||
mov BX,[TempHandle]
|
||
mov CX,Bios.fileTime
|
||
mov DX,Bios.fileDate
|
||
call CloseTarg ; close BIOS file on target disk
|
||
cmp [MsdosFile],0
|
||
je skip_msdos
|
||
|
||
mov CX,DosAttributes
|
||
mov DX,OFFSET MsdosFile ; DS:DX --> ASCIIZ pathname
|
||
sub si,si
|
||
sub di,di ; DI:SI is file size
|
||
call MakeFil ; create & open file in dest. drive
|
||
jc skip_msdos
|
||
|
||
call Get_Dos
|
||
mov dx,offset MsdosRemark
|
||
mov cx,word ptr [dos.fileSizeInBytes]
|
||
mov ah,WRITE
|
||
int 21h
|
||
|
||
mov CX,Bios.fileTime
|
||
mov DX,Bios.fileDate
|
||
call CloseTarg ; close dummy MSDOS file on target disk
|
||
|
||
skip_msdos:
|
||
mov CX,CommandAttributes
|
||
|
||
;M029 call Command_Root ;adjust path for
|
||
;M029 ;COMMAND.COM creation
|
||
|
||
mov DX,OFFSET Command_Com ; M029
|
||
push ES
|
||
les SI,[command.fileSizeInBytes]
|
||
mov DI,ES
|
||
pop ES
|
||
call MakeFil
|
||
retc
|
||
|
||
mov [TempHandle],BX
|
||
test BYTE PTR FileStat,00100000B
|
||
jnz GotAllCom
|
||
call Get_COMMAND
|
||
jnc Got_WCOM
|
||
ret
|
||
|
||
Got_WCOM:
|
||
mov BP,OFFSET command ; BP --> parameter block for COMMAND file
|
||
test BYTE PTR FileStat,00010000B
|
||
jnz PartCom
|
||
mov WORD PTR [command.fileOffset],0
|
||
mov WORD PTR [command.fileOffset+2],0
|
||
call GETSYS3
|
||
retc
|
||
jmp SHORT ComDone
|
||
|
||
PartCom:
|
||
push ES
|
||
LES SI,[command.fileOffset]
|
||
mov DI,ES
|
||
pop ES
|
||
mov WORD PTR [IOCNT],SI
|
||
mov WORD PTR [IOCNT+2],DI
|
||
call GotTArg
|
||
retc
|
||
jmp SHORT ComDone
|
||
|
||
GotAllCom:
|
||
push ES
|
||
les SI,[command.fileSizeInBytes]
|
||
mov DI,ES
|
||
pop ES
|
||
push DS
|
||
mov DS,[command.fileStartSegment]
|
||
assume DS:nothing
|
||
call WriteFile
|
||
pop DS
|
||
assume DS:data
|
||
ComDone:
|
||
mov BX,[TempHandle]
|
||
mov CX,command.fileTime
|
||
mov DX,command.fileDate
|
||
call CloseTarg
|
||
|
||
|
||
|
||
IFDEF DBLSPACE_HOOKS
|
||
|
||
; Write dblspace.bin to target disk if it was located and loaded
|
||
; into memory.
|
||
|
||
cmp [fDblSpace], TRUE ;Have it?
|
||
jne WriteDosDone ; no...
|
||
|
||
mov cx, DblSpaceAttributes ;Create file on
|
||
mov dx, offset DblSpaceTargetName ; target disk
|
||
mov si, word ptr [DblSpaceBin.fileSizeInBytes]
|
||
mov di, word ptr [DblSpaceBin.fileSizeInBytes+2]
|
||
call MakeFil
|
||
retc
|
||
|
||
mov [TempHandle], bx
|
||
|
||
mov si, word ptr [DblSpaceBin.fileSizeInBytes]
|
||
mov di, word ptr [DblSpaceBin.fileSizeInBytes+2]
|
||
push ds
|
||
mov ds, [DblSpaceBin.fileStartSegment]
|
||
assume ds:nothing
|
||
call WriteFile ;Write dblspace.bin image
|
||
pop ds
|
||
assume ds:data
|
||
|
||
mov bx, [TempHandle] ;Set time/date, close
|
||
mov cx, [DblSpaceBin.fileTime] ; DblSpace.bin
|
||
mov dx, [DblSpaceBin.fileDate]
|
||
call ClosetArg
|
||
|
||
WriteDosDone:
|
||
|
||
ENDIF
|
||
clc
|
||
return
|
||
|
||
; ==========================================================================
|
||
; Create a file on target disk
|
||
; CX = attributes, DX points to name
|
||
; DI:SI is size file is to have
|
||
;
|
||
; There is a bug in DOS 2.00 and 2.01 having to do with writes
|
||
; from the end of memory. In order to circumvent it this routine
|
||
; must create files with the length in DI:SI
|
||
;
|
||
; On return BX is handle, carry set if problem
|
||
; ==========================================================================
|
||
|
||
MakeFil:
|
||
mov BX,DX ; BX --> ASCIIZ pathname
|
||
push WORD PTR [BX] ; save drive letter in pathname
|
||
mov AL,DriveLetter
|
||
mov [BX],AL ; set new drive letter in pathname
|
||
mov AH,CREAT
|
||
int 21H ; create the file on disk
|
||
pop WORD PTR [BX] ; restore original drive letter in pathname
|
||
mov BX,AX ; save handle in BX
|
||
jc CheckMany
|
||
mov CX,DI
|
||
mov DX,SI ; CX:DX is size of file
|
||
mov AX,LSEEK shl 8
|
||
int 21H ; Seek to eventual EOF
|
||
xor CX,CX
|
||
mov AH,WRITE
|
||
int 21H ; Set size of file to position
|
||
xor CX,CX
|
||
mov DX,CX
|
||
mov AX,LSEEK shl 8
|
||
int 21H ; Seek back to start
|
||
return
|
||
|
||
; ==========================================================================
|
||
; Examine error code in AX to see if it is too-many-open-files.
|
||
; If it is, we abort right here. Otherwise we return.
|
||
; ==========================================================================
|
||
|
||
CheckMany:
|
||
cmp AX,error_too_many_open_files
|
||
retnz
|
||
Extended_Message
|
||
jmp FatalExit
|
||
|
||
;*********************************************
|
||
; Close a file on the target disk
|
||
; CX/DX is time/date, BX is handle
|
||
|
||
CloseTarg:
|
||
mov AX,(FILE_TIMES shl 8) OR 1
|
||
int 21H
|
||
mov AH,CLOSE
|
||
int 21H
|
||
return
|
||
|
||
;****************************************
|
||
; Transfer system files
|
||
; BP points to data structure for file involved
|
||
; offset is set to current amount read in
|
||
; Start set to start of file in buffer
|
||
; TempHandle is handle to write to on target
|
||
|
||
IoLoop:
|
||
mov AL,[SystemDriveLetter]
|
||
cmp AL,[DriveLetter]
|
||
jnz GotTArg
|
||
mov AH,DISK_RESET
|
||
int 21H
|
||
call TargPrm ;Get target disk
|
||
|
||
|
||
; ==========================================================================
|
||
; Enter here if some of file is already in buffer, IOCNT must be set
|
||
; to size already in buffer.
|
||
; ==========================================================================
|
||
|
||
ASSUME DS:DATA
|
||
GotTArg:
|
||
mov BX,[TempHandle]
|
||
mov SI,WORD PTR [IOCNT]
|
||
mov DI,WORD PTR [IOCNT+2]
|
||
push DS
|
||
mov DS,DS:[BP.fileStartSegment]
|
||
assume DS:nothing
|
||
call WriteFile ; Write next part
|
||
pop DS
|
||
assume DS:data
|
||
retc
|
||
|
||
push ES
|
||
LES AX,DS:[BP.fileOffset]
|
||
cmp AX,WORD PTR DS:[BP.fileSizeInBytes] ; has all the file been written?
|
||
jnz GETSYS3 ; no, read rest in
|
||
mov AX,ES
|
||
cmp AX,WORD PTR DS:[BP.fileSizeInBytes+2]
|
||
jnz GETSYS3
|
||
pop ES
|
||
return ; Carry clear from cmp
|
||
|
||
GETSYS3:
|
||
|
||
; ==========================================================================
|
||
; Enter here if none of file is in buffer
|
||
; (or none of what remains to be written is in buffer)
|
||
; ==========================================================================
|
||
pop ES
|
||
mov AH,DISK_RESET
|
||
int 21H
|
||
mov AX,[mStart] ; Furthur IO done start here
|
||
mov DS:[BP.fileStartSegment],AX ; point to start of buffer
|
||
mov AL,[SystemDriveLetter] ; see if we have system disk
|
||
cmp AL,[DriveLetter]
|
||
jnz TestSys
|
||
gSys:
|
||
; Need to prompt for system disk
|
||
; call File_Cls ;SA; close file that was opened
|
||
mov AH,DISK_RESET
|
||
int 21H
|
||
call SysPrm ; Prompt for system disk
|
||
; inc NeedSysDisk ;SA;signal need for sys disk
|
||
; stc ;SA;force return to caller
|
||
; ret ;SA;handle SysPrm in WriteSysFiles
|
||
|
||
TestSys:
|
||
; call TestSysDISK
|
||
jc gSys ; repeat prompt if needed
|
||
mov BX,WORD PTR DS:[BP.fileHandle] ; CS over ARR 2.30
|
||
push ES
|
||
LES DX,dWORD PTR DS:[BP.fileOffset] ; CS over ARR 2.30
|
||
mov CX,ES ; CX:DX = required offset in file
|
||
pop ES
|
||
push DX
|
||
mov AX,LSEEK shl 8
|
||
int 21H
|
||
pop DX
|
||
push ES
|
||
LES SI,dWORD PTR DS:[BP.fileSizeInBytes] ; CS over
|
||
mov DI,ES ; put high word in di
|
||
pop ES
|
||
SUB SI,DX ; get low word value
|
||
SBB DI,CX ; DI:SI is #bytes to go
|
||
push DI
|
||
push SI
|
||
add SI,15 ; round up 1 para
|
||
ADC DI,0 ; pick up carry
|
||
call DISID4 ; div 16 to get para count
|
||
mov AX,SI ; put para count in AX
|
||
pop SI ; restore bytes remaining
|
||
pop DI ; restore bytes remaining
|
||
cmp AX,[mSize] ; enough memory for remainder?
|
||
jbe GOTSIZ2 ; yes
|
||
mov SI,[mSize]
|
||
xor DI,DI
|
||
call DISIX4
|
||
GOTSIZ2:
|
||
mov WORD PTR [IOCNT],SI ; save byte count for read
|
||
mov WORD PTR [IOCNT+2],DI
|
||
push DS
|
||
mov DS,[mStart]
|
||
assume DS:nothing
|
||
call ReadFile
|
||
pop DS
|
||
assume DS:data
|
||
jnc GetOffs
|
||
call ClsAll
|
||
jmp gSys
|
||
GetOffs:
|
||
xor DX,DX ; clear DX
|
||
mov CX,DX ; clear CX
|
||
mov AX,(LSEEK shl 8) OR 1
|
||
int 21H
|
||
mov WORD PTR DS:[BP.fileOffset],AX
|
||
mov WORD PTR DS:[BP.fileOffset+2],DX
|
||
jmp IoLoop
|
||
|
||
; ==========================================================================
|
||
; Test to see if correct system disk. Open handles
|
||
; ==========================================================================
|
||
|
||
CRET12:
|
||
stc
|
||
return
|
||
|
||
; ==========================================================================
|
||
; TestSysDISK:
|
||
; ==========================================================================
|
||
|
||
Get_Bios:
|
||
mov AX,OPEN shl 8
|
||
mov DX,OFFSET BiosFile ; DS:DX --> ASCIIZ pathname
|
||
int 21H
|
||
jnc SetBios
|
||
|
||
push es
|
||
push ds
|
||
pop es
|
||
mov cx,AltBiosLen
|
||
lea si,AltBiosFile
|
||
mov di,dx
|
||
mov al,[di]
|
||
mov [MsdosFile],al
|
||
add di,3
|
||
cld
|
||
rep movsb
|
||
pop es
|
||
|
||
mov AX,OPEN shl 8
|
||
int 21H
|
||
jnc SetBios
|
||
jmp CheckMany
|
||
|
||
SetBios:
|
||
mov [Bios.fileHandle],AX ; save file handle
|
||
mov BX,AX ; BX = file handle
|
||
call GetFsiz
|
||
cmp [Bios.fileSizeInParagraphs],0
|
||
jz SetBioSize
|
||
cmp [Bios.fileSizeInParagraphs],AX
|
||
jz SetBioSize
|
||
BiosCls:
|
||
mov AH,CLOSE
|
||
mov BX,[Bios.fileHandle]
|
||
int 21h
|
||
ret
|
||
|
||
; ==========================================================================
|
||
|
||
SetBioSize:
|
||
mov [Bios.fileSizeInParagraphs],AX
|
||
mov WORD PTR [Bios.fileSizeInBytes],SI
|
||
mov WORD PTR [Bios.fileSizeInBytes+2],DI
|
||
mov [Bios.fileDate],DX
|
||
mov [Bios.fileTime],CX
|
||
clc
|
||
ret
|
||
; ==========================================================================
|
||
|
||
Get_COMMAND:
|
||
mov AX,OPEN shl 8
|
||
mov DX,OFFSET CommandFile
|
||
int 21H
|
||
jnc GotComHand
|
||
jmp CheckMany
|
||
|
||
Get_DOS:
|
||
mov WORD PTR [dos.fileSizeInBytes],MsdosRemarkLen
|
||
mov WORD PTR [dos.fileSizeInBytes+2],0
|
||
ret
|
||
|
||
GotComHand:
|
||
mov [command.fileHandle],AX
|
||
mov BX,AX
|
||
call GetFsiz
|
||
cmp [command.fileSizeInParagraphs],0
|
||
jz SetComSize
|
||
cmp [command.fileSizeInParagraphs],AX
|
||
jz SetComSize
|
||
ComCls:
|
||
mov AH,CLOSE
|
||
mov BX,[command.fileHandle]
|
||
int 21H
|
||
ret
|
||
|
||
; ==========================================================================
|
||
|
||
SetComSize:
|
||
mov [command.fileSizeInParagraphs],AX
|
||
mov WORD PTR [command.fileSizeInBytes],SI
|
||
mov WORD PTR [command.fileSizeInBytes+2],DI
|
||
mov [command.fileDate],DX
|
||
mov [command.fileTime],CX
|
||
CLC
|
||
return
|
||
|
||
|
||
|
||
IFDEF DBLSPACE_HOOKS
|
||
; ==========================================================================
|
||
Get_DblSpace:
|
||
mov AX,OPEN shl 8
|
||
mov DX,OFFSET DblSpaceFile
|
||
int 21H
|
||
jnc GotDblHand
|
||
|
||
; We didn't locate DblSpace.bin in the root directory, look for
|
||
; it along the PATH
|
||
|
||
call Find_DblSpace_on_Path ; sets CY if not found
|
||
retc
|
||
|
||
mov AX,OPEN shl 8 ; open the copy found
|
||
mov DX,OFFSET DblSpaceFile
|
||
int 21H
|
||
retc
|
||
|
||
GotDblHand:
|
||
mov [DblSpaceBin.fileHandle],AX
|
||
|
||
mov BX,AX
|
||
call GetFsiz
|
||
|
||
mov [DblSpaceBin.fileSizeInParagraphs],AX
|
||
mov WORD PTR [DblSpaceBin.fileSizeInBytes],SI
|
||
mov WORD PTR [DblSpaceBin.fileSizeInBytes+2],DI
|
||
mov [DblSpaceBin.fileDate],DX
|
||
mov [DblSpaceBin.fileTime],CX
|
||
|
||
CLC
|
||
return
|
||
|
||
ENDIF
|
||
|
||
|
||
|
||
; ==========================================================================
|
||
|
||
FILE_CLS:
|
||
mov AH,CLOSE
|
||
int 21H
|
||
ret
|
||
|
||
; ==========================================================================
|
||
; Handle in BX, return file size in para in AX
|
||
; File size in bytes DI:SI, file date in DX, file
|
||
; time in CX.
|
||
; ==========================================================================
|
||
|
||
GetFsiz:
|
||
mov AX,(LSEEK shl 8) OR 2
|
||
xor CX,CX
|
||
mov DX,CX
|
||
int 21h
|
||
mov SI,AX
|
||
mov DI,DX
|
||
add AX,15 ; Para round up
|
||
adc DX,0
|
||
and DX,0fH ; If file is larger than this
|
||
; it is bigger than the 8086
|
||
; address space!
|
||
mov CL,12
|
||
shl DX,CL
|
||
mov CL,4
|
||
shr AX,CL
|
||
or AX,DX
|
||
push AX
|
||
mov AX,LSEEK shl 8
|
||
xor CX,CX
|
||
mov DX,CX
|
||
int 21H
|
||
mov AX,FILE_TIMES shl 8
|
||
int 21H
|
||
pop AX
|
||
return
|
||
|
||
; ==========================================================================
|
||
; Read/Write file
|
||
; DS:0 is Xaddr
|
||
; DI:SI is byte count to I/O
|
||
; BX is handle
|
||
; Carry set if screw up
|
||
;
|
||
; I/O SI bytes
|
||
; I/O 64K - 1 bytes DI times
|
||
; I/O DI bytes
|
||
; ==========================================================================
|
||
|
||
ReadFile: ; Must preserve AX,DX
|
||
push AX
|
||
push DX
|
||
push BP
|
||
mov BP,READ shl 8
|
||
call FilIo
|
||
|
||
pop BP
|
||
pop DX
|
||
pop AX
|
||
return
|
||
|
||
WriteFile:
|
||
push BP
|
||
mov BP,WRITE shl 8
|
||
call FilIo
|
||
pop BP
|
||
return
|
||
|
||
FilIo:
|
||
xor DX,DX
|
||
mov CX,SI
|
||
jCXZ K64IO
|
||
mov AX,BP
|
||
int 21H
|
||
retc
|
||
add DX,AX
|
||
cmp AX,CX ; If not =, AX<CX, carry set.
|
||
retnz
|
||
call Normalize
|
||
K64IO:
|
||
CLC
|
||
mov CX,DI
|
||
jCXZ IoRet
|
||
mov AX,BP
|
||
int 21H
|
||
retc
|
||
add DX,AX
|
||
cmp AX,CX ; If not =, AX<CX, carry set.
|
||
retnz
|
||
call Normalize
|
||
mov CX,DI
|
||
K64M1:
|
||
push CX
|
||
xor AX,AX
|
||
OR DX,DX
|
||
jz NormIo
|
||
mov CX,10H
|
||
SUB CX,DX
|
||
mov AX,BP
|
||
int 21H
|
||
jc IoRetP
|
||
add DX,AX
|
||
cmp AX,CX ; If not =, AX<CX, carry set.
|
||
jnz IoRetP
|
||
call Normalize
|
||
NormIo:
|
||
mov CX,0FFFFH
|
||
SUB CX,AX
|
||
mov AX,BP
|
||
int 21H
|
||
jc IoRetP
|
||
add DX,AX
|
||
cmp AX,CX ; If not =, AX<CX, carry set.
|
||
jnz IoRetP
|
||
call Normalize ; Clears carry
|
||
pop CX
|
||
LOOP K64M1
|
||
push CX
|
||
IoRetP:
|
||
pop CX
|
||
IoRet:
|
||
return
|
||
|
||
|
||
; ==========================================================================
|
||
; Shift DI:SI left 4 bits
|
||
; ==========================================================================
|
||
|
||
DISIX4:
|
||
mov CX,4
|
||
@@:
|
||
shl SI,1
|
||
rcl DI,1
|
||
loop @B
|
||
return
|
||
|
||
; ==========================================================================
|
||
; Shift DI:SI right 4 bits
|
||
; ==========================================================================
|
||
|
||
DISID4:
|
||
mov CX,4
|
||
@@:
|
||
shr DI,1
|
||
rcr SI,1
|
||
loop @B
|
||
return
|
||
|
||
; ==========================================================================
|
||
; Normalize DS:DX
|
||
; ==========================================================================
|
||
|
||
Normalize:
|
||
push DX
|
||
push AX
|
||
SHR DX,1
|
||
SHR DX,1
|
||
SHR DX,1
|
||
SHR DX,1
|
||
mov AX,DS
|
||
add AX,DX
|
||
mov DS,AX
|
||
pop AX
|
||
pop DX
|
||
and DX,0FH ; Clears carry
|
||
return
|
||
|
||
;=========================================================================
|
||
; Get_Command_Path : This routine finds the path where
|
||
; COMMAND.COM resides based on the
|
||
; environmental vector. Once the
|
||
; path is found it is copied to
|
||
; CommandFile.
|
||
;
|
||
; Inputs : Exec_Block.Segment_Env - Segment of environmental vector
|
||
; Comspec_ID - "COMSPEC="
|
||
;
|
||
; Outputs : CommandFile - Holds path to COMMAND.COM
|
||
;=========================================================================
|
||
|
||
Procedure Get_Command_Path
|
||
|
||
push DS
|
||
push ES
|
||
|
||
Set_Data_Segment ; DS,ES = Data
|
||
call Get_PSP_Parms ; Gets PSP info.
|
||
cld ; Clear direction
|
||
mov AX,ES:Environ_Segment ; Get seg. of
|
||
; Environ. vector
|
||
mov DS,AX ; Put it in DS
|
||
assume DS:nothing
|
||
xor SI,SI ; Clear SI
|
||
|
||
;M012 - begin
|
||
|
||
GCP_WhileNotFound:
|
||
mov BX,SI ; Save SI
|
||
cmp byte ptr DS:[SI],0
|
||
jz GCP_NotFound
|
||
|
||
mov DI,offset Comspec_ID
|
||
mov CX,8 ; Loop 8 times
|
||
repe cmpsb ; "COMSPEC=" ?
|
||
jnz GCP_NotThisLine ; "COMSPEC=" not found
|
||
|
||
; "COMSPEC=" found
|
||
mov DI,offset ES:CommandFile
|
||
lodsb ; Priming read
|
||
|
||
; Copy COMSPEC even if COMSPEC drive != boot drive
|
||
; mov DL,AL ; Prepare for capitalization
|
||
; call Cap_Char ; Capitalize character in DL
|
||
; cmp DL,ES:CommandFile ; COMSPEC same as boot Drive?
|
||
; jne GCP_NotFound ; COMSPEC drive != boot drive
|
||
|
||
GCP_GetPath: ; While AL not = 0
|
||
stosb ; Save it
|
||
or al,al ; At end?
|
||
je GCP_Done ; Yes
|
||
|
||
lodsb ; Get character
|
||
jmp SHORT GCP_GetPath
|
||
|
||
GCP_NotThisLine:
|
||
mov SI,BX ; Restore SI
|
||
|
||
GCP_Find0Terminator:
|
||
lodsb ; Loop until past the first 0.
|
||
or al,al
|
||
jnz GCP_Find0Terminator
|
||
jmp GCP_WhileNotFound
|
||
|
||
GCP_NotFound:
|
||
; Nothing to do
|
||
; since commandfile is
|
||
; already patched to try
|
||
; in the root of the
|
||
; default or boot drive
|
||
GCP_Done:
|
||
|
||
;M012 - end
|
||
|
||
pop ES
|
||
pop DS
|
||
|
||
ret
|
||
|
||
Get_Command_Path ENDP
|
||
|
||
comment ^ ; M029
|
||
;
|
||
; This routine is no longer required ; M029
|
||
;
|
||
;=========================================================================
|
||
; Command_Root : This routine sets up CommandFile so that the
|
||
; COMMAND.COM will be written to the root.
|
||
; It does this by copying at offset 3 of CommandFile
|
||
; the literal COMMAND.COM. This effectively
|
||
; overrides the original path, but maintains the
|
||
; Drive letter that is to be written to.
|
||
;
|
||
; Inputs : CommandFile - Holds full path to default COMMAND.COM
|
||
; Outputs : CommandFile - Holds modified path to new COMMAND.COM
|
||
; on target Drive.
|
||
;=========================================================================
|
||
|
||
|
||
|
||
Procedure Command_Root
|
||
|
||
push DS
|
||
push ES
|
||
push DI
|
||
push SI
|
||
push CX
|
||
|
||
Set_Data_Segment
|
||
mov DI,offset CommandFile+3 ; Point to path past drive spec
|
||
mov SI,offset Command_Com ; Holds the literal COMMAND.COM
|
||
mov CX,000ch ; Len. of literal
|
||
rep movsb ; Move it
|
||
|
||
pop CX
|
||
pop SI
|
||
pop DI
|
||
pop ES
|
||
pop DS
|
||
|
||
ret
|
||
|
||
Command_Root ENDP
|
||
|
||
endcomment ^ ; M029
|
||
|
||
|
||
|
||
IFDEF DBLSPACE_HOOKS
|
||
|
||
;******************* START OF SPECIFICATIONS ***********************************
|
||
;Routine name: Find_DblSpace_on_Path
|
||
;*******************************************************************************
|
||
;
|
||
;Description: Search Path for DRVSPACE.bin
|
||
;
|
||
;Output: no error - CF = 0 DblSpaceFile filled in with
|
||
; full path to DRVSPACE.bin
|
||
; error - CF = 1 Dblspace.bin not found
|
||
;
|
||
; Cut and pasted from SYS command code: 12/07/92 JEM
|
||
;
|
||
;******************* END OF SPECIFICATIONS *************************************
|
||
|
||
Find_DblSpace_on_Path PROC NEAR
|
||
|
||
push es
|
||
push ds ; save our segments
|
||
push si ; save DTA address
|
||
|
||
mov ax, PSP_Segment
|
||
mov es, ax ; get our PSP to ES
|
||
|
||
call Find_Path_In_Environment ; returns ptr to path string in ES:DI
|
||
jc fdp_exit ; no path, can't find DRVSPACE.bin
|
||
|
||
assume es:nothing
|
||
mov ax,ds ; swap DS and ES
|
||
push es
|
||
pop ds
|
||
assume ds:nothing
|
||
mov si,di ; DS:SI ==> Path string
|
||
mov es,ax
|
||
assume es:data
|
||
|
||
fdp_path_loop:
|
||
mov bh,';' ; path separator character
|
||
mov dx,offset DblSpaceBase ; base file name
|
||
mov di,offset DblSpaceFile ; buffer to stick full path in
|
||
call Path_Crunch ; concatenate name and path
|
||
pushf ; save result
|
||
push ds ; save segment of Path
|
||
push es
|
||
pop ds
|
||
assume ds:data
|
||
mov dx,offset DblSpaceFile ; buffer with full path name
|
||
mov bx,offset DOS_BUFFER ; DMA buffer for finds
|
||
mov al,1 ; extension is specified
|
||
call Search
|
||
or al,al ; found the file?
|
||
pop ds ; recover path segment
|
||
assume ds:nothing
|
||
pop ax ; recover flags in AX
|
||
jnz fdp_exit ; found it!
|
||
xchg ah,al
|
||
sahf ; check Path_Crunch result
|
||
jnc fdp_path_loop
|
||
|
||
fdp_exit:
|
||
pop si
|
||
pop ds
|
||
pop es
|
||
assume ds:data
|
||
ret
|
||
|
||
Find_DblSpace_on_Path ENDP
|
||
|
||
ENDIF
|
||
|
||
|
||
|
||
CODE ENDS
|
||
|
||
END
|
||
|