mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-20 21:43:39 -07:00
MS-DOS v2.0 Release
This commit is contained in:
parent
fce0f75959
commit
80ab2fddfd
156 changed files with 56403 additions and 0 deletions
362
v2.0/source/FAT.ASM
Normal file
362
v2.0/source/FAT.ASM
Normal file
|
@ -0,0 +1,362 @@
|
|||
;
|
||||
; FAT operations for MSDOS
|
||||
;
|
||||
|
||||
INCLUDE DOSSEG.ASM
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME SS:DOSGROUP,CS:DOSGROUP
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.ASM
|
||||
INCLUDE DEVSYM.ASM
|
||||
.cref
|
||||
.list
|
||||
|
||||
TITLE FAT - FAT maintenance routines
|
||||
NAME FAT
|
||||
|
||||
i_need CURBUF,DWORD
|
||||
i_need CLUSSPLIT,BYTE
|
||||
i_need CLUSSAVE,WORD
|
||||
i_need CLUSSEC,WORD
|
||||
i_need THISDRV,BYTE
|
||||
i_need DEVCALL,BYTE
|
||||
i_need CALLMED,BYTE
|
||||
i_need CALLRBYT,BYTE
|
||||
i_need BUFFHEAD,DWORD
|
||||
i_need CALLXAD,DWORD
|
||||
i_need CALLBPB,DWORD
|
||||
|
||||
SUBTTL UNPACK -- UNPACK FAT ENTRIES
|
||||
PAGE
|
||||
|
||||
ASSUME SS:DOSGROUP
|
||||
procedure UNPACK,NEAR
|
||||
ASSUME DS:DOSGROUP,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; BX = Cluster number
|
||||
; ES:BP = Base of drive parameters
|
||||
; Outputs:
|
||||
; DI = Contents of FAT for given cluster
|
||||
; Zero set means DI=0 (free cluster)
|
||||
; SI Destroyed, No other registers affected. Fatal error if cluster too big.
|
||||
|
||||
CMP BX,ES:[BP.dpb_max_cluster]
|
||||
JA HURTFAT
|
||||
CALL MAPCLUSTER
|
||||
ASSUME DS:NOTHING
|
||||
MOV DI,[DI]
|
||||
JNC HAVCLUS
|
||||
PUSH CX
|
||||
MOV CL,4
|
||||
SHR DI,CL
|
||||
POP CX
|
||||
STC
|
||||
HAVCLUS:
|
||||
AND DI,0FFFH
|
||||
PUSH SS
|
||||
POP DS
|
||||
return
|
||||
|
||||
HURTFAT:
|
||||
PUSH AX
|
||||
MOV AH,80H ; Signal Bad FAT to INT int_fatal_abort handler
|
||||
MOV DI,0FFFH ; In case INT int_fatal_abort returns (it shouldn't)
|
||||
invoke FATAL
|
||||
POP AX ; Try to ignore bad FAT
|
||||
return
|
||||
UNPACK ENDP
|
||||
|
||||
SUBTTL PACK -- PACK FAT ENTRIES
|
||||
PAGE
|
||||
procedure PACK,NEAR
|
||||
ASSUME DS:DOSGROUP,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; BX = Cluster number
|
||||
; DX = Data
|
||||
; ES:BP = Pointer to drive DPB
|
||||
; Outputs:
|
||||
; The data is stored in the FAT at the given cluster.
|
||||
; SI,DX,DI all destroyed
|
||||
; No other registers affected
|
||||
|
||||
CALL MAPCLUSTER
|
||||
ASSUME DS:NOTHING
|
||||
MOV SI,[DI]
|
||||
JNC ALIGNED
|
||||
PUSH CX
|
||||
MOV CL,4
|
||||
SHL DX,CL
|
||||
POP CX
|
||||
AND SI,0FH
|
||||
JMP SHORT PACKIN
|
||||
ALIGNED:
|
||||
AND SI,0F000H
|
||||
PACKIN:
|
||||
OR SI,DX
|
||||
MOV [DI],SI
|
||||
LDS SI,[CURBUF]
|
||||
MOV [SI.BUFDIRTY],1
|
||||
CMP BYTE PTR [CLUSSPLIT],0
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
retz
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
MOV AX,[CLUSSAVE]
|
||||
MOV DS,WORD PTR [CURBUF+2]
|
||||
ASSUME DS:NOTHING
|
||||
ADD SI,BUFINSIZ
|
||||
MOV [SI],AH
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
PUSH AX
|
||||
MOV DX,[CLUSSEC]
|
||||
MOV SI,1
|
||||
XOR AL,AL
|
||||
invoke GETBUFFRB
|
||||
LDS DI,[CURBUF]
|
||||
ASSUME DS:NOTHING
|
||||
MOV [DI.BUFDIRTY],1
|
||||
ADD DI,BUFINSIZ
|
||||
DEC DI
|
||||
ADD DI,ES:[BP.dpb_sector_size]
|
||||
POP AX
|
||||
MOV [DI],AL
|
||||
PUSH SS
|
||||
POP DS
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
return
|
||||
PACK ENDP
|
||||
|
||||
SUBTTL MAPCLUSTER - BUFFER A FAT SECTOR
|
||||
PAGE
|
||||
procedure MAPCLUSTER,NEAR
|
||||
ASSUME DS:DOSGROUP,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; ES:BP Points to DPB
|
||||
; BX Is cluster number
|
||||
; Function:
|
||||
; Get a pointer to the cluster
|
||||
; Outputs:
|
||||
; DS:DI Points to contents of FAT for given cluster
|
||||
; DS:SI Points to start of buffer
|
||||
; Carry set if cluster data is in high 12 bits of word
|
||||
; No other registers effected
|
||||
|
||||
MOV BYTE PTR [CLUSSPLIT],0
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
PUSH DX
|
||||
MOV AX,BX
|
||||
SHR AX,1
|
||||
ADD AX,BX
|
||||
XOR DX,DX
|
||||
MOV CX,ES:[BP.dpb_sector_size]
|
||||
DIV CX ; AX is FAT sector # DX is sector index
|
||||
ADD AX,ES:[BP.dpb_first_FAT]
|
||||
DEC CX
|
||||
PUSH AX
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
MOV DX,AX
|
||||
XOR AL,AL
|
||||
MOV SI,1
|
||||
invoke GETBUFFRB
|
||||
LDS SI,[CURBUF]
|
||||
ASSUME DS:NOTHING
|
||||
LEA DI,[SI.BufInSiz]
|
||||
POP CX
|
||||
POP AX
|
||||
POP DX
|
||||
ADD DI,AX
|
||||
CMP AX,CX
|
||||
JNZ MAPRET
|
||||
MOV AL,[DI]
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
INC BYTE PTR [CLUSSPLIT]
|
||||
MOV BYTE PTR [CLUSSAVE],AL
|
||||
MOV [CLUSSEC],DX
|
||||
INC DX
|
||||
XOR AL,AL
|
||||
MOV SI,1
|
||||
invoke GETBUFFRB
|
||||
LDS SI,[CURBUF]
|
||||
ASSUME DS:NOTHING
|
||||
LEA DI,[SI.BufInSiz]
|
||||
MOV AL,[DI]
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
MOV BYTE PTR [CLUSSAVE+1],AL
|
||||
MOV DI,OFFSET DOSGROUP:CLUSSAVE
|
||||
MAPRET:
|
||||
POP DX
|
||||
POP CX
|
||||
POP BX
|
||||
MOV AX,BX
|
||||
SHR AX,1
|
||||
POP AX
|
||||
return
|
||||
MAPCLUSTER ENDP
|
||||
|
||||
SUBTTL FATREAD -- CHECK DRIVE GET FAT
|
||||
PAGE
|
||||
ASSUME DS:DOSGROUP,ES:NOTHING
|
||||
|
||||
procedure FAT_operation,NEAR
|
||||
FATERR:
|
||||
AND DI,STECODE ; Put error code in DI
|
||||
MOV AH,2 ; While trying to read FAT
|
||||
MOV AL,BYTE PTR [THISDRV] ; Tell which drive
|
||||
invoke FATAL1
|
||||
|
||||
entry FATREAD
|
||||
ASSUME DS:DOSGROUP,ES:NOTHING
|
||||
|
||||
; Function:
|
||||
; If disk may have been changed, FAT is read in and buffers are
|
||||
; flagged invalid. If not, no action is taken.
|
||||
; Outputs:
|
||||
; ES:BP = Base of drive parameters
|
||||
; All other registers destroyed
|
||||
|
||||
MOV AL,BYTE PTR [THISDRV]
|
||||
invoke GETBP
|
||||
MOV AL,DMEDHL
|
||||
MOV AH,ES:[BP.dpb_UNIT]
|
||||
MOV WORD PTR [DEVCALL],AX
|
||||
MOV BYTE PTR [DEVCALL.REQFUNC],DEVMDCH
|
||||
MOV [DEVCALL.REQSTAT],0
|
||||
MOV AL,ES:[BP.dpb_media]
|
||||
MOV BYTE PTR [CALLMED],AL
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
MOV BX,OFFSET DOSGROUP:DEVCALL
|
||||
LDS SI,ES:[BP.dpb_driver_addr] ; DS:SI Points to device header
|
||||
ASSUME DS:NOTHING
|
||||
POP ES ; ES:BX Points to call header
|
||||
invoke DEVIOCALL2
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
POP ES ; Restore ES:BP
|
||||
MOV DI,[DEVCALL.REQSTAT]
|
||||
TEST DI,STERR
|
||||
JNZ FATERR
|
||||
XOR AH,AH
|
||||
XCHG AH,ES:[BP.dpb_first_access] ; Reset dpb_first_access
|
||||
MOV AL,BYTE PTR [THISDRV] ; Use physical unit number
|
||||
OR AH,BYTE PTR [CALLRBYT]
|
||||
JS NEWDSK ; new disk or first access?
|
||||
JZ CHKBUFFDIRT
|
||||
return ; If Media not changed
|
||||
CHKBUFFDIRT:
|
||||
INC AH ; Here if ?Media..Check buffers
|
||||
LDS DI,[BUFFHEAD]
|
||||
ASSUME DS:NOTHING
|
||||
NBUFFER: ; Look for dirty buffers
|
||||
CMP AX,WORD PTR [DI.BUFDRV]
|
||||
retz ; There is a dirty buffer, assume Media OK
|
||||
LDS DI,[DI.NEXTBUF]
|
||||
CMP DI,-1
|
||||
JNZ NBUFFER
|
||||
; If no dirty buffers, assume Media changed
|
||||
NEWDSK:
|
||||
invoke SETVISIT
|
||||
NXBUFFER:
|
||||
MOV [DI.VISIT],1
|
||||
CMP AL,[DI.BUFDRV] ; For this drive?
|
||||
JNZ SKPBUFF
|
||||
MOV WORD PTR [DI.BUFDRV],00FFH ; Free up buffer
|
||||
invoke SCANPLACE
|
||||
SKPBUFF:
|
||||
invoke SKIPVISIT
|
||||
JNZ NXBUFFER
|
||||
LDS DI,ES:[BP.dpb_driver_addr]
|
||||
TEST [DI.SDEVATT],ISFATBYDEV
|
||||
JNZ GETFREEBUF
|
||||
context DS
|
||||
MOV BX,2
|
||||
CALL UNPACK ; Read the first FAT sector into CURBUF
|
||||
LDS DI,[CURBUF]
|
||||
JMP SHORT GOTGETBUF
|
||||
GETFREEBUF:
|
||||
ASSUME DS:NOTHING
|
||||
PUSH ES ; Get a free buffer for BIOS to use
|
||||
PUSH BP
|
||||
LDS DI,[BUFFHEAD]
|
||||
invoke BUFWRITE
|
||||
POP BP
|
||||
POP ES
|
||||
GOTGETBUF:
|
||||
ADD DI,BUFINSIZ
|
||||
MOV WORD PTR [CALLXAD+2],DS
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
MOV WORD PTR [CALLXAD],DI
|
||||
MOV AL,DBPBHL
|
||||
MOV AH,BYTE PTR ES:[BP.dpb_UNIT]
|
||||
MOV WORD PTR [DEVCALL],AX
|
||||
MOV BYTE PTR [DEVCALL.REQFUNC],DEVBPB
|
||||
MOV [DEVCALL.REQSTAT],0
|
||||
MOV AL,BYTE PTR ES:[BP.dpb_media]
|
||||
MOV [CALLMED],AL
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
PUSH WORD PTR ES:[BP.dpb_driver_addr+2]
|
||||
PUSH WORD PTR ES:[BP.dpb_driver_addr]
|
||||
MOV BX,OFFSET DOSGROUP:DEVCALL
|
||||
POP SI
|
||||
POP DS ; DS:SI Points to device header
|
||||
ASSUME DS:NOTHING
|
||||
POP ES ; ES:BX Points to call header
|
||||
invoke DEVIOCALL2
|
||||
POP ES ; Restore ES:BP
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
MOV DI,[DEVCALL.REQSTAT]
|
||||
TEST DI,STERR
|
||||
JNZ FATERRJ
|
||||
MOV AL,BYTE PTR ES:[BP.dpb_media]
|
||||
LDS SI,[CALLBPB]
|
||||
ASSUME DS:NOTHING
|
||||
CMP AL,BYTE PTR [SI.BPMEDIA]
|
||||
JZ DPBOK
|
||||
invoke $SETDPB
|
||||
LDS DI,[CALLXAD] ; Get back buffer pointer
|
||||
MOV AL,BYTE PTR ES:[BP.dpb_FAT_count]
|
||||
MOV AH,BYTE PTR ES:[BP.dpb_FAT_size]
|
||||
MOV WORD PTR [DI.BUFWRTCNT-BUFINSIZ],AX ;Correct buffer info
|
||||
DPBOK:
|
||||
context ds
|
||||
MOV AX,-1
|
||||
TEST ES:[BP.dpb_current_dir],AX
|
||||
retz ; If root, leave as root
|
||||
MOV ES:[BP.dpb_current_dir],AX ; Path may be bad, mark invalid
|
||||
return
|
||||
|
||||
FATERRJ: JMP FATERR
|
||||
|
||||
FAT_operation ENDP
|
||||
|
||||
do_ext
|
||||
|
||||
CODE ENDS
|
||||
END
|
||||
|