WindowsXP-SP1/base/ntsetup/opktools/oformat/switch_s.asm
2020-09-30 16:53:49 +02:00

1250 lines
29 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: .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