]>
wirehaze git hosting - MS-DOS.git/blob - v2.0/source/FAT.ASM
2 ; FAT operations for MSDOS
7 CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME
SS:DOSGROUP
,CS:DOSGROUP
17 TITLE FAT
- FAT maintenance routines
32 SUBTTL UNPACK
-- UNPACK FAT ENTRIES
37 ASSUME
DS:DOSGROUP
,ES:NOTHING
41 ; ES:BP = Base of drive parameters
43 ; DI = Contents of FAT for given cluster
44 ; Zero set means DI=0 (free cluster)
45 ; SI Destroyed, No other registers affected. Fatal error if cluster too big.
47 CMP BX,ES:[BP.dpb_max_cluster
]
66 MOV AH,80H
; Signal Bad FAT to INT int_fatal_abort handler
67 MOV DI,0FFFH ; In case INT int_fatal_abort returns (it shouldn't)
69 POP AX ; Try to ignore bad FAT
73 SUBTTL PACK
-- PACK FAT ENTRIES
76 ASSUME
DS:DOSGROUP
,ES:NOTHING
81 ; ES:BP = Pointer to drive DPB
83 ; The data is stored in the FAT at the given cluster.
84 ; SI,DX,DI all destroyed
85 ; No other registers affected
104 CMP BYTE PTR [CLUSSPLIT
],0
113 MOV DS,WORD PTR [CURBUF
+2]
130 ADD DI,ES:[BP.dpb_sector_size
]
141 SUBTTL MAPCLUSTER
- BUFFER A FAT SECTOR
143 procedure MAPCLUSTER
,NEAR
144 ASSUME
DS:DOSGROUP
,ES:NOTHING
147 ; ES:BP Points to DPB
148 ; BX Is cluster number
150 ; Get a pointer to the cluster
152 ; DS:DI Points to contents of FAT for given cluster
153 ; DS:SI Points to start of buffer
154 ; Carry set if cluster data is in high 12 bits of word
155 ; No other registers effected
157 MOV BYTE PTR [CLUSSPLIT
],0
166 MOV CX,ES:[BP.dpb_sector_size
]
167 DIV CX ; AX is FAT sector # DX is sector index
168 ADD AX,ES:[BP.dpb_first_FAT
]
190 INC BYTE PTR [CLUSSPLIT
]
191 MOV BYTE PTR [CLUSSAVE
],AL
204 MOV BYTE PTR [CLUSSAVE
+1],AL
205 MOV DI,OFFSET DOSGROUP
:CLUSSAVE
216 SUBTTL FATREAD
-- CHECK DRIVE GET FAT
218 ASSUME
DS:DOSGROUP
,ES:NOTHING
220 procedure FAT_operation
,NEAR
222 AND DI,STECODE
; Put error code in DI
223 MOV AH,2 ; While trying to read FAT
224 MOV AL,BYTE PTR [THISDRV
] ; Tell which drive
228 ASSUME
DS:DOSGROUP
,ES:NOTHING
231 ; If disk may have been changed, FAT is read in and buffers are
232 ; flagged invalid. If not, no action is taken.
234 ; ES:BP = Base of drive parameters
235 ; All other registers destroyed
237 MOV AL,BYTE PTR [THISDRV
]
240 MOV AH,ES:[BP.dpb_UNIT
]
241 MOV WORD PTR [DEVCALL
],AX
242 MOV BYTE PTR [DEVCALL
.REQFUNC
],DEVMDCH
243 MOV [DEVCALL
.REQSTAT
],0
244 MOV AL,ES:[BP.dpb_media
]
245 MOV BYTE PTR [CALLMED
],AL
248 MOV BX,OFFSET DOSGROUP
:DEVCALL
249 LDS SI,ES:[BP.dpb_driver_addr
] ; DS:SI Points to device header
251 POP ES ; ES:BX Points to call header
256 POP ES ; Restore ES:BP
257 MOV DI,[DEVCALL
.REQSTAT
]
261 XCHG AH,ES:[BP.dpb_first_access
] ; Reset dpb_first_access
262 MOV AL,BYTE PTR [THISDRV
] ; Use physical unit number
263 OR AH,BYTE PTR [CALLRBYT
]
264 JS NEWDSK
; new disk or first access?
266 return
; If Media not changed
268 INC AH ; Here if ?Media..Check buffers
271 NBUFFER: ; Look for dirty buffers
272 CMP AX,WORD PTR [DI.BUFDRV
]
273 retz
; There is a dirty buffer, assume Media OK
277 ; If no dirty buffers, assume Media changed
282 CMP AL,[DI.BUFDRV
] ; For this drive?
284 MOV WORD PTR [DI.BUFDRV
],00FFH ; Free up buffer
289 LDS DI,ES:[BP.dpb_driver_addr
]
290 TEST [DI.SDEVATT
],ISFATBYDEV
294 CALL UNPACK
; Read the first FAT sector into CURBUF
299 PUSH ES ; Get a free buffer for BIOS to use
307 MOV WORD PTR [CALLXAD
+2],DS
311 MOV WORD PTR [CALLXAD
],DI
313 MOV AH,BYTE PTR ES:[BP.dpb_UNIT
]
314 MOV WORD PTR [DEVCALL
],AX
315 MOV BYTE PTR [DEVCALL
.REQFUNC
],DEVBPB
316 MOV [DEVCALL
.REQSTAT
],0
317 MOV AL,BYTE PTR ES:[BP.dpb_media
]
321 PUSH WORD PTR ES:[BP.dpb_driver_addr
+2]
322 PUSH WORD PTR ES:[BP.dpb_driver_addr
]
323 MOV BX,OFFSET DOSGROUP
:DEVCALL
325 POP DS ; DS:SI Points to device header
327 POP ES ; ES:BX Points to call header
329 POP ES ; Restore ES:BP
333 MOV DI,[DEVCALL
.REQSTAT
]
336 MOV AL,BYTE PTR ES:[BP.dpb_media
]
339 CMP AL,BYTE PTR [SI.BPMEDIA
]
342 LDS DI,[CALLXAD
] ; Get back buffer pointer
343 MOV AL,BYTE PTR ES:[BP.dpb_FAT_count
]
344 MOV AH,BYTE PTR ES:[BP.dpb_FAT_size
]
345 MOV WORD PTR [DI.BUFWRTCNT
-BUFINSIZ
],AX ;Correct buffer info
349 TEST ES:[BP.dpb_current_dir
],AX
350 retz
; If root, leave as root
351 MOV ES:[BP.dpb_current_dir
],AX ; Path may be bad, mark invalid