📄 format.asm
字号:
jnc Got_WDOS ;mt 12/8/86 P894
ret
Got_WDOS:
MOV BP,OFFSET dos
TEST BYTE PTR FILSTAT,00000100B
JNZ PARTDOS
MOV WORD PTR [dos.fileOffset],0
MOV WORD PTR [dos.fileOffset+2],0
CALL GETSYS3
retc
JMP SHORT DOSDONE
PARTDOS:
LES SI,[dos.fileOffset]
MOV DI,ES
MOV WORD PTR [IOCNT],SI
MOV WORD PTR [IOCNT+2],DI
CALL GOTTARG
retc
JMP SHORT DOSDONE
GOTALLDOS:
LES SI,[dos.fileSizeInBytes]
MOV DI,ES
push ds
MOV DS,[dos.fileStartSegment]
assume ds:nothing
CALL WRITEFILE
pop ds
assume ds:data
DOSDONE:
MOV BX,[TempHandle]
MOV CX,dos.fileTime
MOV DX,dos.fileDate
CALL CLOSETARG
MOV CX,CommandAttributes
MOV DX,OFFSET CommandFile
LES SI,[command.fileSizeInBytes]
MOV DI,ES
CALL MAKEFIL
retc
MOV [TempHandle],BX
TEST BYTE PTR FILSTAT,00100000B
JNZ GOTALLCOM
call Get_COMMAND ; dcl 8/23/86
jnc Got_WCOM ;mt 12/8/86 P894
ret
Got_WCOM:
MOV BP,OFFSET command
TEST BYTE PTR FILSTAT,00010000B
JNZ PARTCOM
MOV WORD PTR [command.fileOffset],0
MOV WORD PTR [command.fileOffset+2],0
CALL GETSYS3
retc
JMP SHORT COMDONE
PARTCOM:
LES SI,[command.fileOffset]
MOV DI,ES
MOV WORD PTR [IOCNT],SI
MOV WORD PTR [IOCNT+2],DI
CALL GOTTARG
retc
JMP SHORT COMDONE
GOTALLCOM:
LES SI,[command.fileSizeInBytes]
MOV DI,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
;****************************************************************
; I don't see the need for the following code!! - RS 3.20
; CMP BYTE PTR [FILSTAT],00101010B
; JZ NOREDOS
;RDFRST2:
; CALL READDOS ; Start back with BIOS
; JNC NOREDOS
; CALL SYSPRM ;Prompt for system disk
; JMP RDFRST2 ;Try again
;NOREDOS:
;****************************************************************
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
PUSH WORD PTR [BX]
MOV AL,DriveLetter
MOV [BX],AL
MOV AH,CREAT
INT 21H
POP WORD PTR [BX]
MOV BX,AX
JC CheckMany
MOV CX,DI
MOV DX,SI
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
lea dx, msgTooManyFilesOpen
call PrintString
JMP FEXIT
;*********************************************
; 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
GOTTARG:
ASSUME DS:DATA
;Enter here if some of file is already in buffer, IOCNT must be set
; to size already in buffer.
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
LES AX,ds:[BP.fileOffset]
CMP AX,WORD PTR ds:[BP.fileSizeInBytes]
JNZ GETSYS3
MOV AX,ES
CMP AX,WORD PTR ds:[BP.fileSizeInBytes+2]
JNZ GETSYS3
return ; Carry clear from CMP
GETSYS3:
;Enter here if none of file is in buffer
MOV AH,DISK_RESET
INT 21H
MOV AX,[MSTART] ;Furthur IO done starting here
MOV ds:[BP.fileStartSegment],AX
MOV AL,[systemDriveLetter]
CMP AL,[DriveLetter]
JNZ TESTSYS
GSYS:
MOV AH,DISK_RESET
INT 21H
CALL SYSPRM ;Prompt for system disk
TESTSYS:
; CALL TESTSYSDISK ; dcl 8/23/86
JC GSYS
MOV BX,word ptr DS:[BP.fileHandle] ; CS over ARR 2.30
LES DX,dword ptr DS:[BP.fileOffset] ; CS over ARR 2.30
PUSH DX
MOV CX,ES
MOV AX,LSEEK SHL 8
INT 21H
POP DX
LES SI,dword ptr DS:[BP.fileSizeInBytes] ; CS over ARR 2.30
MOV DI,ES
SUB SI,DX
SBB DI,CX ; DI:SI is #bytes to go
PUSH DI
PUSH SI
ADD SI,15
ADC DI,0
CALL DISID4
MOV AX,SI
POP SI
POP DI
CMP AX,[MSIZE]
JBE GOTSIZ2
MOV SI,[MSIZE]
XOR DI,DI
CALL DISIX4
GOTSIZ2:
MOV WORD PTR [IOCNT],SI
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
MOV CX,DX
MOV AX,(LSEEK SHL 8) OR 1
INT 21H
MOV WORD PTR DS:[BP.fileOffset],AX ; CS over ARR 2.30
MOV WORD PTR DS:[BP.fileOffset+2],DX ; CS over ARR 2.30
CALL CLSALL
JMP IOLOOP
;*************************************************
; Test to see if correct system disk. Open handles
CRET12:
STC
return
;TESTSYSDISK: ; dcl 8/23/86
Get_BIOS: ; dcl 8/23/86
MOV AX,OPEN SHL 8
MOV DX,OFFSET BiosFile
INT 21H
JNC SETBIOS
; call CheckMany ; dcl 8/23/86
jmp CheckMany ; dcl 8/23/86
SETBIOS:
MOV [Bios.fileHandle],AX
MOV BX,AX
CALL GETFSIZ
CMP [bios.fileSizeInParagraphs],0
JZ SETBIOSSIZ
CMP [bios.fileSizeInParagraphs],AX
JZ SETBIOSSIZ
BIOSCLS:
MOV AH,CLOSE
MOV BX,[Bios.fileHandle]
INT 21H
; JMP CRET12 ; dcl 8/23/86
ret
SETBIOSSIZ:
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 ; dcl 8/23/86
Get_DOS: ; dcl 8/23/86
MOV AX,OPEN SHL 8
MOV DX,OFFSET DosFile
INT 21H
JNC DOSOPNOK
; call CheckMany ; dcl 8/23/86
; JMP BIOSCLS ; dcl 8/23/86 Checkmany no ret.
jmp CheckMany ; dcl 8/23/86
DOSOPNOK:
MOV [dos.fileHandle],AX
MOV BX,AX
CALL GETFSIZ
CMP [dos.fileSizeInParagraphs],0
JZ SETDOSSIZ
CMP [dos.fileSizeInParagraphs],AX
JZ SETDOSSIZ
DOSCLS:
MOV AH,CLOSE
MOV BX,[dos.fileHandle]
INT 21H
; JMP BIOSCLS ; dcl 8/23/86
ret ; dcl 8/23/86
SETDOSSIZ:
MOV [dos.fileSizeInParagraphs],AX
MOV WORD PTR [dos.fileSizeInBytes],SI
MOV WORD PTR [dos.fileSizeInBytes+2],DI
MOV [dos.fileDate],DX
MOV [dos.fileTime],CX
clc
ret ; dcl 8/23/86
Get_COMMAND:
MOV AX,OPEN SHL 8
MOV DX,OFFSET CommandFile
INT 21H
JNC GotComHand
; call CheckMany ; dcl 8/23/86
; JMP DosCls ; dcl 8/23/86
jmp Checkmany ; dcl 8/23/86
GotComHand:
MOV [command.fileHandle],AX
MOV BX,AX
CALL GETFSIZ
CMP [command.fileSizeInParagraphs],0
JZ SETCOMSIZ
CMP [command.fileSizeInParagraphs],AX
JZ SETCOMSIZ
COMCLS:
MOV AH,CLOSE
MOV BX,[command.fileHandle]
INT 21H
; JMP DOSCLS ; dcl 8/23/86
ret ; dcl 8/23/86
SETCOMSIZ:
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
FILE_CLS: ; dcl 8/23/86
MOV AH,CLOSE ; dcl 8/23/86
INT 21H ; dcl 8/23/86
ret ; dcl 8/23/86
;*******************************************
; 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 the 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -