]> wirehaze git hosting - MS-DOS.git/blob - v2.0/source/FAT.ASM

wirehaze git hosting

Add Turkish translation for README
[MS-DOS.git] / v2.0 / source / FAT.ASM
1 ;
2 ; FAT operations for MSDOS
3 ;
4
5 INCLUDE DOSSEG.ASM
6
7 CODE SEGMENT BYTE PUBLIC 'CODE'
8 ASSUME SS:DOSGROUP,CS:DOSGROUP
9
10 .xlist
11 .xcref
12 INCLUDE DOSSYM.ASM
13 INCLUDE DEVSYM.ASM
14 .cref
15 .list
16
17 TITLE FAT - FAT maintenance routines
18 NAME 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
32 SUBTTL UNPACK -- UNPACK FAT ENTRIES
33 PAGE
34
35 ASSUME SS:DOSGROUP
36 procedure UNPACK,NEAR
37 ASSUME 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
50 ASSUME 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
58 HAVCLUS:
59 AND DI,0FFFH
60 PUSH SS
61 POP DS
62 return
63
64 HURTFAT:
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
71 UNPACK ENDP
72
73 SUBTTL PACK -- PACK FAT ENTRIES
74 PAGE
75 procedure PACK,NEAR
76 ASSUME 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
88 ASSUME 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
97 ALIGNED:
98 AND SI,0F000H
99 PACKIN:
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
107 ASSUME DS:DOSGROUP
108 retz
109 PUSH AX
110 PUSH BX
111 PUSH CX
112 MOV AX,[CLUSSAVE]
113 MOV DS,WORD PTR [CURBUF+2]
114 ASSUME DS:NOTHING
115 ADD SI,BUFINSIZ
116 MOV [SI],AH
117 PUSH SS
118 POP DS
119 ASSUME DS:DOSGROUP
120 PUSH AX
121 MOV DX,[CLUSSEC]
122 MOV SI,1
123 XOR AL,AL
124 invoke GETBUFFRB
125 LDS DI,[CURBUF]
126 ASSUME 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
139 PACK ENDP
140
141 SUBTTL MAPCLUSTER - BUFFER A FAT SECTOR
142 PAGE
143 procedure MAPCLUSTER,NEAR
144 ASSUME 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]
178 ASSUME 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
189 ASSUME 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]
198 ASSUME DS:NOTHING
199 LEA DI,[SI.BufInSiz]
200 MOV AL,[DI]
201 PUSH SS
202 POP DS
203 ASSUME DS:DOSGROUP
204 MOV BYTE PTR [CLUSSAVE+1],AL
205 MOV DI,OFFSET DOSGROUP:CLUSSAVE
206 MAPRET:
207 POP DX
208 POP CX
209 POP BX
210 MOV AX,BX
211 SHR AX,1
212 POP AX
213 return
214 MAPCLUSTER ENDP
215
216 SUBTTL FATREAD -- CHECK DRIVE GET FAT
217 PAGE
218 ASSUME DS:DOSGROUP,ES:NOTHING
219
220 procedure FAT_operation,NEAR
221 FATERR:
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
228 ASSUME 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
250 ASSUME DS:NOTHING
251 POP ES ; ES:BX Points to call header
252 invoke DEVIOCALL2
253 PUSH SS
254 POP DS
255 ASSUME 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
267 CHKBUFFDIRT:
268 INC AH ; Here if ?Media..Check buffers
269 LDS DI,[BUFFHEAD]
270 ASSUME DS:NOTHING
271 NBUFFER: ; 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
278 NEWDSK:
279 invoke SETVISIT
280 NXBUFFER:
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
286 SKPBUFF:
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
297 GETFREEBUF:
298 ASSUME 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
305 GOTGETBUF:
306 ADD DI,BUFINSIZ
307 MOV WORD PTR [CALLXAD+2],DS
308 PUSH SS
309 POP DS
310 ASSUME 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
326 ASSUME 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
332 ASSUME 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]
338 ASSUME 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
346 DPBOK:
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
354 FATERRJ: JMP FATERR
355
356 FAT_operation ENDP
357
358 do_ext
359
360 CODE ENDS
361 END
362