summaryrefslogtreecommitdiff
path: root/v2.0/source/FAT.ASM
diff options
context:
space:
mode:
authorGravatar Rich Turner1983-08-12 17:53:34 -0700
committerGravatar Rich Turner2018-09-21 17:53:34 -0700
commit80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 (patch)
treeee4357f7f3dd0f2ded59b9c6e7384432d85e7ec9 /v2.0/source/FAT.ASM
parentMS-DOS v1.25 Release (diff)
downloadms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.gz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.tar.xz
ms-dos-80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6.zip
MS-DOS v2.0 Release
Diffstat (limited to 'v2.0/source/FAT.ASM')
-rw-r--r--v2.0/source/FAT.ASM362
1 files changed, 362 insertions, 0 deletions
diff --git a/v2.0/source/FAT.ASM b/v2.0/source/FAT.ASM
new file mode 100644
index 0000000..b1a4863
--- /dev/null
+++ b/v2.0/source/FAT.ASM
@@ -0,0 +1,362 @@
1;
2; FAT operations for MSDOS
3;
4
5INCLUDE DOSSEG.ASM
6
7CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10.xlist
11.xcref
12INCLUDE DOSSYM.ASM
13INCLUDE DEVSYM.ASM
14.cref
15.list
16
17TITLE FAT - FAT maintenance routines
18NAME FAT
19
20 i_need CURBUF,DWORD
21 i_need CLUSSPLIT,BYTE
22 i_need CLUSSAVE,WORD
23 i_need CLUSSEC,WORD
24 i_need THISDRV,BYTE
25 i_need DEVCALL,BYTE
26 i_need CALLMED,BYTE
27 i_need CALLRBYT,BYTE
28 i_need BUFFHEAD,DWORD
29 i_need CALLXAD,DWORD
30 i_need CALLBPB,DWORD
31
32SUBTTL UNPACK -- UNPACK FAT ENTRIES
33PAGE
34
35ASSUME SS:DOSGROUP
36 procedure UNPACK,NEAR
37ASSUME DS:DOSGROUP,ES:NOTHING
38
39; Inputs:
40; BX = Cluster number
41; ES:BP = Base of drive parameters
42; Outputs:
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.
46
47 CMP BX,ES:[BP.dpb_max_cluster]
48 JA HURTFAT
49 CALL MAPCLUSTER
50ASSUME DS:NOTHING
51 MOV DI,[DI]
52 JNC HAVCLUS
53 PUSH CX
54 MOV CL,4
55 SHR DI,CL
56 POP CX
57 STC
58HAVCLUS:
59 AND DI,0FFFH
60 PUSH SS
61 POP DS
62 return
63
64HURTFAT:
65 PUSH AX
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)
68 invoke FATAL
69 POP AX ; Try to ignore bad FAT
70 return
71UNPACK ENDP
72
73SUBTTL PACK -- PACK FAT ENTRIES
74PAGE
75 procedure PACK,NEAR
76ASSUME DS:DOSGROUP,ES:NOTHING
77
78; Inputs:
79; BX = Cluster number
80; DX = Data
81; ES:BP = Pointer to drive DPB
82; Outputs:
83; The data is stored in the FAT at the given cluster.
84; SI,DX,DI all destroyed
85; No other registers affected
86
87 CALL MAPCLUSTER
88ASSUME DS:NOTHING
89 MOV SI,[DI]
90 JNC ALIGNED
91 PUSH CX
92 MOV CL,4
93 SHL DX,CL
94 POP CX
95 AND SI,0FH
96 JMP SHORT PACKIN
97ALIGNED:
98 AND SI,0F000H
99PACKIN:
100 OR SI,DX
101 MOV [DI],SI
102 LDS SI,[CURBUF]
103 MOV [SI.BUFDIRTY],1
104 CMP BYTE PTR [CLUSSPLIT],0
105 PUSH SS
106 POP DS
107ASSUME DS:DOSGROUP
108 retz
109 PUSH AX
110 PUSH BX
111 PUSH CX
112 MOV AX,[CLUSSAVE]
113 MOV DS,WORD PTR [CURBUF+2]
114ASSUME DS:NOTHING
115 ADD SI,BUFINSIZ
116 MOV [SI],AH
117 PUSH SS
118 POP DS
119ASSUME DS:DOSGROUP
120 PUSH AX
121 MOV DX,[CLUSSEC]
122 MOV SI,1
123 XOR AL,AL
124 invoke GETBUFFRB
125 LDS DI,[CURBUF]
126ASSUME DS:NOTHING
127 MOV [DI.BUFDIRTY],1
128 ADD DI,BUFINSIZ
129 DEC DI
130 ADD DI,ES:[BP.dpb_sector_size]
131 POP AX
132 MOV [DI],AL
133 PUSH SS
134 POP DS
135 POP CX
136 POP BX
137 POP AX
138 return
139PACK ENDP
140
141SUBTTL MAPCLUSTER - BUFFER A FAT SECTOR
142PAGE
143 procedure MAPCLUSTER,NEAR
144ASSUME DS:DOSGROUP,ES:NOTHING
145
146; Inputs:
147; ES:BP Points to DPB
148; BX Is cluster number
149; Function:
150; Get a pointer to the cluster
151; Outputs:
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
156
157 MOV BYTE PTR [CLUSSPLIT],0
158 PUSH AX
159 PUSH BX
160 PUSH CX
161 PUSH DX
162 MOV AX,BX
163 SHR AX,1
164 ADD AX,BX
165 XOR DX,DX
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]
169 DEC CX
170 PUSH AX
171 PUSH DX
172 PUSH CX
173 MOV DX,AX
174 XOR AL,AL
175 MOV SI,1
176 invoke GETBUFFRB
177 LDS SI,[CURBUF]
178ASSUME DS:NOTHING
179 LEA DI,[SI.BufInSiz]
180 POP CX
181 POP AX
182 POP DX
183 ADD DI,AX
184 CMP AX,CX
185 JNZ MAPRET
186 MOV AL,[DI]
187 PUSH SS
188 POP DS
189ASSUME DS:DOSGROUP
190 INC BYTE PTR [CLUSSPLIT]
191 MOV BYTE PTR [CLUSSAVE],AL
192 MOV [CLUSSEC],DX
193 INC DX
194 XOR AL,AL
195 MOV SI,1
196 invoke GETBUFFRB
197 LDS SI,[CURBUF]
198ASSUME DS:NOTHING
199 LEA DI,[SI.BufInSiz]
200 MOV AL,[DI]
201 PUSH SS
202 POP DS
203ASSUME DS:DOSGROUP
204 MOV BYTE PTR [CLUSSAVE+1],AL
205 MOV DI,OFFSET DOSGROUP:CLUSSAVE
206MAPRET:
207 POP DX
208 POP CX
209 POP BX
210 MOV AX,BX
211 SHR AX,1
212 POP AX
213 return
214MAPCLUSTER ENDP
215
216SUBTTL FATREAD -- CHECK DRIVE GET FAT
217PAGE
218ASSUME DS:DOSGROUP,ES:NOTHING
219
220 procedure FAT_operation,NEAR
221FATERR:
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
225 invoke FATAL1
226
227 entry FATREAD
228ASSUME DS:DOSGROUP,ES:NOTHING
229
230; Function:
231; If disk may have been changed, FAT is read in and buffers are
232; flagged invalid. If not, no action is taken.
233; Outputs:
234; ES:BP = Base of drive parameters
235; All other registers destroyed
236
237 MOV AL,BYTE PTR [THISDRV]
238 invoke GETBP
239 MOV AL,DMEDHL
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
246 PUSH ES
247 PUSH DS
248 MOV BX,OFFSET DOSGROUP:DEVCALL
249 LDS SI,ES:[BP.dpb_driver_addr] ; DS:SI Points to device header
250ASSUME DS:NOTHING
251 POP ES ; ES:BX Points to call header
252 invoke DEVIOCALL2
253 PUSH SS
254 POP DS
255ASSUME DS:DOSGROUP
256 POP ES ; Restore ES:BP
257 MOV DI,[DEVCALL.REQSTAT]
258 TEST DI,STERR
259 JNZ FATERR
260 XOR AH,AH
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?
265 JZ CHKBUFFDIRT
266 return ; If Media not changed
267CHKBUFFDIRT:
268 INC AH ; Here if ?Media..Check buffers
269 LDS DI,[BUFFHEAD]
270ASSUME DS:NOTHING
271NBUFFER: ; Look for dirty buffers
272 CMP AX,WORD PTR [DI.BUFDRV]
273 retz ; There is a dirty buffer, assume Media OK
274 LDS DI,[DI.NEXTBUF]
275 CMP DI,-1
276 JNZ NBUFFER
277; If no dirty buffers, assume Media changed
278NEWDSK:
279 invoke SETVISIT
280NXBUFFER:
281 MOV [DI.VISIT],1
282 CMP AL,[DI.BUFDRV] ; For this drive?
283 JNZ SKPBUFF
284 MOV WORD PTR [DI.BUFDRV],00FFH ; Free up buffer
285 invoke SCANPLACE
286SKPBUFF:
287 invoke SKIPVISIT
288 JNZ NXBUFFER
289 LDS DI,ES:[BP.dpb_driver_addr]
290 TEST [DI.SDEVATT],ISFATBYDEV
291 JNZ GETFREEBUF
292 context DS
293 MOV BX,2
294 CALL UNPACK ; Read the first FAT sector into CURBUF
295 LDS DI,[CURBUF]
296 JMP SHORT GOTGETBUF
297GETFREEBUF:
298ASSUME DS:NOTHING
299 PUSH ES ; Get a free buffer for BIOS to use
300 PUSH BP
301 LDS DI,[BUFFHEAD]
302 invoke BUFWRITE
303 POP BP
304 POP ES
305GOTGETBUF:
306 ADD DI,BUFINSIZ
307 MOV WORD PTR [CALLXAD+2],DS
308 PUSH SS
309 POP DS
310ASSUME DS:DOSGROUP
311 MOV WORD PTR [CALLXAD],DI
312 MOV AL,DBPBHL
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]
318 MOV [CALLMED],AL
319 PUSH ES
320 PUSH DS
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
324 POP SI
325 POP DS ; DS:SI Points to device header
326ASSUME DS:NOTHING
327 POP ES ; ES:BX Points to call header
328 invoke DEVIOCALL2
329 POP ES ; Restore ES:BP
330 PUSH SS
331 POP DS
332ASSUME DS:DOSGROUP
333 MOV DI,[DEVCALL.REQSTAT]
334 TEST DI,STERR
335 JNZ FATERRJ
336 MOV AL,BYTE PTR ES:[BP.dpb_media]
337 LDS SI,[CALLBPB]
338ASSUME DS:NOTHING
339 CMP AL,BYTE PTR [SI.BPMEDIA]
340 JZ DPBOK
341 invoke $SETDPB
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
346DPBOK:
347 context ds
348 MOV AX,-1
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
352 return
353
354FATERRJ: JMP FATERR
355
356FAT_operation ENDP
357
358do_ext
359
360CODE ENDS
361 END
362