]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/CMD/FASTOPEN/FASTSEEK.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / CMD / FASTOPEN / FASTSEEK.ASM
1 Page 84,132 ;\ f
2 Title FASTOPEN
3
4 ;--------------- INCLUDE FILES -----------------
5 .xcref
6 .xlist
7 debug=0 ;this is an equate only for DOSMAC.inc
8 INCLUDE DOSMAC.inc
9 .list
10 .cref
11 INCLUDE dirent.inc
12 INCLUDE fastsegs.inc ; Cannot declare this in DOS includes
13 INCLUDE fastopen.inc ; This include file also contains DOS equates
14
15
16 CSEG_MAIN SEGMENT PARA PUBLIC 'CODE' ; Cseg_Seek segment
17
18 EXTRN VECTOR_DELETE:dword ; jump vector inside Cseg_Seek to make
19 ; a FAR call to FSeek Delete function within
20 ; the segment
21
22 CSEG_MAIN ENDS
23
24
25 ;*****************************************************************************
26 ; ALL FastSeek functions are kept in a seperate segment. They are accessed
27 ; by a FAR indirect call from the MAIN routine.
28
29 ; ADDRESSABILTY: DS is for accessing local data in Cseg_Seek segment
30 ; ES is for accessing data in the extent cache buffer
31 ; in the Cseg_Init segment
32 ; On entry, only DS is set, ES is set to Cache segment later
33 ;*****************************************************************************
34
35 CSEG_SEEK SEGMENT PARA PUBLIC 'code'
36 assume cs:cseg_seek,ds:nothing,es:nothing,ss:nothing
37
38 PUBLIC Seek_name_cache_seg ;AN000;
39 PUBLIC Seek_Num_Of_drives
40 PUBLIC Seek_extent_drive_Buff ;AN000;
41 PUBLIC Seek_Total_Ext_Count ;AN000;
42 PUBLIC Seek_Total_Name_Count ;AN000;
43 PUBLIC Seek_Name_Drive_Buff ;AN000;
44 PUBLIC Seek_Name_Cache_Buff ;AN000;
45 PUBLIC End_Seek
46 PUBLIC Check_Flag
47 ;AN000;
48 PUBLIC Fk_Open
49 PUBLIC Fk_Close ;AN000;
50 PUBLIC Fk_Insert ;AN000;
51 PUBLIC Fk_Delete
52 PUBLIC Fk_Lookup ;AN000;
53 PUBLIC Fk_Truncate
54 PUBLIC Fk_Purge
55
56
57 ;;---------- FASTSEEK LOCAL VARIABLES ---------------------
58
59 First_Phys_ClusNum dw 0 ; first phys clus num of file (file id) ;AN000;
60 Logical_ClusNum dw 0 ; logical cluster num to be searched ;AN000;
61 Physical_ClusNum dw 0 ; physical clus num of above logical clus num ;AN000;
62 Extent_buff_Ptr dw 0 ; starting offset of extent cache ;AN000;
63 drv_id db -1 ; drive id of last fastseek function
64 func_cod db 0 ; function code
65
66 Cur_Hdr_Ptr dw 0 ; address of current header ;AN000;
67 Cur_Extn_Ptr dw 0 ; address of current extent ;AN000;
68 New_Extn_Ptr dw 0 ; address of area where new extent will be created
69 New_Hdr_Ptr dw 0 ; address of area where new header will be created ;AN000;
70 Prev_Hdr_Ptr dw 0 ; address of previous header ;AN000;
71 Prev_Extn_Ptr dw 0 ; address of previous extent ;AN000;
72
73 Prev_MRU_Extn_Ptr dw 0 ; address of previous MRU extent ;AN000;
74 LRU_Prev_Hdr dw 0 ; address of previous hdr to the LRU header ;AN000;
75 LRU_Prev_Extent dw 0 ; address of previous extent to LRU extent ;AN000;
76 LRU_Extent dw 0 ; address of LRU extent ;AN000;
77 LRU_Hdr dw 0 ; address of LRU header ;AN000;
78
79 Drive_Hdr_Ptr dw 0 ; address of drive header of current drive ;AN000;
80 From_FreeBuff dw 0 ; 1 = if call from Free_Buff routine ;AN000;
81 Hdr_Flag dw 0 ; 1 = current header is the only
82 ; remaining header in Queue
83 Extn_Flag dw 0 ; 1 = current extent is the only ;AN000;;AN000;
84 ; remaining extent under this header
85 Fully_Flag dw 0 ; 1= cluster fully found in extent ;AN000;;AN000;
86 ; 0= cluster partially found
87 Find_Flag dw 0 ; # = specifies the relative location of the new cluster ;AN000;
88 Open_Queue_Flag dw 0 ; 1 = if open queue is empty ;AN000;
89 Free_Flag dw 0 ; Free area Type: 0 - continuous ;AN000;
90 ; 1 - non-continuous
91 Queue_Type dw 0 ; Queue Type: 0 - Open Queue ;AN000;
92 ; 1 - Close Queue
93 phys_num dw 0 ; ** for queue analyser
94 logic_num dw 0 ; ** for queue analyser
95
96
97 ; Following data area is initialized during initialization
98 Check_Flag dw 0
99 Seek_name_cache_seg dw Cseg_Init ; Seg ID of Ccahe buffer
100 Seek_Num_Of_drives dw 0 ; number of drives ;AN000;
101 Seek_Total_Name_Count dw 0 ; total name count
102 Seek_Total_Ext_Count dw 0 ; total extent count
103 Seek_Name_Drive_Buff dw 0 ; starting address of name drive buffers ;AN000;
104 Seek_Name_Cache_Buff dw 0 ; starting address of name cahe buffers ;AN000;
105 Seek_extent_drive_Buff dw 0 ; starting address of extent ;AN000;
106 ; cache in the cache buffer
107 \f
108
109
110
111 ;-------------------------------------------------------------------------------
112 ;-------------------------------------------------------------------------------
113 ; PROCEDURE: FK_OPEN
114 ;
115 ; FUNCTION: Create and initialize a file header using the starting
116 ; Physical Cluster number (file id) of the file.
117 ;
118 ; If the file header already exist in the OPEN Queue, then increase
119 ; the file reference count by one and make the header
120 ; MRU header.
121 ;
122 ; If header is not found in the OPEN Queue, then check to
123 ; see if it exists in the CLOSE Queue. If found in the
124 ; CLOSE Queue, move the header and the extents to the top of
125 ; OPEN Queue and make the header MRU header.
126 ;
127 ; If the header is not found in both Queues, create a new
128 ; header at the top of the OPEN Queue and initialize with the
129 ; given first physical cluster number.
130 ;
131 ; If not enough space for new header in OPEN Queue, find the
132 ; LRU header and Last Exetent in the CLOSED Queue. Delete this
133 ; extent and use the space for the new header. If none in
134 ; CLOSE Queue, find the LRU header and the LRU extent in the
135 ; OPEN Queue. Delete this extent and use this space.
136 ;
137 ;
138 ; INPUT: CX = First Physical Cluster Number of the file
139 ; DL = Drive ID
140 ;
141 ;
142 ; OUTPUT: Created a new file header. If header already exist, then the file
143 ; reference count is incremented by one.
144 ;
145 ; ROUTINES REFERENCED: Find_File_Header, Find_Drive_Header
146 ;
147 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
148 ; "Version 4.00 (C) Copyright 1988 Microsoft"
149 ; "Licensed Material - Property of Microsoft "
150 ;
151 ;-------------------------------------------------------------------------------
152
153
154 FK_OPEN PROC FAR
155
156 push cs ; establish addressability ;AN000;
157 pop ds ; DS --> code segment ;AN000;
158 assume ds:Cseg_Seek ;AN000;
159 mov es, Seek_Name_Cache_Seg ; setup cache buff segment ;AN000;
160 assume es:Cseg_Init ; ES --> cache buffer segment ;AN000;
161 mov First_Phys_Clusnum,cx ; save physical cluster number ;AN000;
162 mov func_cod,al
163
164 ;-------------------------------------------------------------------------------
165 ; Search for Drive header in the cache buffer using Drive ID in DL
166 ;-------------------------------------------------------------------------------
167 CALL FIND_DRIVE_HEADER ; get drive buffer Header ;AN000;
168 ; DI-->drive header
169 jnc open_Search_Header ; header found - check for file header ;AN000;
170 jmp open_exit ; drive header not found - exit ;AN000;
171
172 ;------------------------------------------------------------------------------
173 ; Check if both OPEN and CLOSE Queues are empty. If empty, create a new
174 ; file header at the top of OPEN Queue. If there are headers, search OPEN
175 ; queue. If found, increment file count by one. If not found, check if
176 ; the file header exists in CLOSE Queue. If found, move header to the
177 ; top of the OPEN Queue.
178 ;------------------------------------------------------------------------------
179 Open_Search_Header:
180 inc es:[di].Extent_Count ; increment sequence count ( DEBUG)
181 mov ax,es:[di].Buff_Size ; total buffer size equal ;AN000;
182 cmp es:[di].Free_Size,ax ; to current free area ;AN000;
183 jne Search_Open_List ; yes, check OPEN and CLOSE Queues ;AN000;
184 ; for header
185 jmp Open_Make_Hdr ; no, make new header ;AN000;
186
187
188 ;------------------------------------------------------------------------------
189 ; Search for header in the OPEN Queues. If found, increment file reference
190 ; count by one.
191 ;------------------------------------------------------------------------------
192
193 Search_Open_List:
194 mov cx,First_Phys_Clusnum ; CX = first phys clus number ;AN000;
195 mov si,es:[di].MRU_Hdr_Ptr ;AN000;
196 cmp si, -1 ; Any header in OPEN Queue ?? ;AN000;
197 je Open_Chk_Close_list ; none, check CLOSE Queue ;AN000;
198
199 CALL FIND_FILE_HEADER ; search header in OPEN Queue ;AN000;
200 jc Open_chk_CLOSE_list ; if not found check in CLOSE Queue ;AN000;
201
202 ;------------------------------------------------------------------------------
203 ; Found in the OPEN Queue. Now, increment the file reference count by one
204 ; and also make the header MRU header. If header found is LRU header then
205 ; make previous header LRU header. If header is not LRU header, connect
206 ; previous header to next header. If the header is the first header in the
207 ; Queue, dont make it to MRU header since it is already at the top of Queue.
208 ;------------------------------------------------------------------------------
209 ; DI-->Header found
210 inc es:[di].FH_refer_Count ; increment file reference count ;AN000;
211 cmp Hdr_Flag, 1 ; current header Single header ?? ;AN000;
212 jne Open_Chk_Last_Hdr ; No, Check for last header ;AN000;
213 clc ; make sure caary is clear
214 jmp Open_Exit ; yes, exit ;AN000;
215
216 Open_Chk_Last_Hdr:
217 cmp Hdr_Flag, 3 ; current header LRU header ?? ;AN000;
218 jne Open_Join_Gap ; no, close the gap ;AN000;
219
220 Mark_Previous_Hdr: ; yes - mark previous hdr
221 mov si, Prev_Hdr_Ptr ;AN000;
222 mov es:[si].FH_Next_Hdr_Ptr,-1 ; yes, Mark previous Hdr LRU hdr ;AN000;
223
224 ; Make current Hdr MRU header. No need to close the gap
225 CALL MAKE_MRU_HEADER ; move header to top of Queue ;AN000;
226 clc ; make sure caary is clear
227 jmp Open_Exit ; then EXIT ;AN000;
228
229
230 ;-----------------------------------------------------------------------------
231 ; Comes here if current header is first of many headers or in between a previous
232 ; and next header. Make current header MRU header and close the gap.
233 ;-----------------------------------------------------------------------------
234 Open_Join_Gap:
235 ; DI-->Current header
236 cmp Hdr_Flag, 2 ; current Header First Hdr in Queue ?? ;AN000;
237 jne Open_Make_MRU_Hdr ; no, jump ;AN000;
238 clc ; MAKE SURE caary is clear
239 jmp Open_Exit ; yes, no need to make MRU hdr, or ;AN000;
240 ; or close the gap
241
242 Open_Make_MRU_Hdr: ; header is between 1st and last headers
243 CALL MAKE_MRU_HEADER ; move header to top of Queue ;AN000;
244
245 clc ; make sure caary is clear
246 jmp Open_exit ; then EXIT ;AN000;
247
248
249 ;------------------------------------------------------------------------------
250 ; Look for a header in the CLOSE Queue. If found, move file header and
251 ; and extents (if any) to top of OPEN Queue. If not found in the CLOSE
252 ; queue, create a new header at the top of OPEN queue.
253 ;------------------------------------------------------------------------------
254 Open_Chk_Close_List:
255 mov di,drive_Hdr_Ptr ; DI-->current drive header ;AN000;
256 cmp es:[di].CLOSE_Ptr,-1 ; anything in CLOSE Queue ?? ;AN000;
257 jne open_search_hdr ; if any, search CLOSE Queue ;AN000;
258 jmp open_make_hdr ; if none, make a new header ;AN000;
259
260
261 ;------------------------------------------------------------------------------
262 ; CLOSE Queue is not empty, next search for header in the CLOSE Queue using
263 ; starting physical cluster number of the file.
264 ;------------------------------------------------------------------------------
265 Open_Search_Hdr: ;
266 mov si,es:[di].Close_Ptr ; SI-->first header in the ;AN000;
267 ; in the CLOSE Queue ;AN000;
268 mov cx,First_Phys_Clusnum ; CX = first phys clus number ;AN000;
269 CALL FIND_FILE_HEADER ; find file header in CLOSE Queue ;AN000;
270 ; DI-->header found
271 jnc open_chk_only_hdr ; if found, check only header ;AN000;
272 jmp short open_make_hdr ; if not, make a new header ;AN000;
273
274 ;------------------------------------------------------------------------------
275 ; Found header in the CLOSE Queue. Check if the header found is the single HDR
276 ; in the CLOSE Queue, If single header, then, mark the CLOSE Queue as empty
277 ; before copy the this header to the OPEN Queue.
278 ;------------------------------------------------------------------------------
279 Open_Chk_only_Hdr: ;
280 cmp Hdr_flag, 1 ; Only Header in the CLOSE Queue?? ;AN000;
281 jne Open_chk_Last_header ; if not check header is LRU header ;AN000;
282
283 mov di,Drive_Hdr_Ptr ; only header in the CLOSE Queue ;AN000;
284 mov es:[di].Close_Ptr,-1 ; mark CLOSE Queue as empty ;AN000;
285 jmp short Open_Move_Hdr ; then move header to OPEN Queue ;AN000;
286
287 ;------------------------------------------------------------------------------
288 ; Current header is not the only header in the CLOSE Queue. Now check if the
289 ; current header is the LRU header in CLOSE Queue. If true, mark previous
290 ; header as LRU header before moving it from from CLOSE Queue to OPEN queue.
291 ;------------------------------------------------------------------------------
292 Open_Chk_Last_Header: ;
293 cmp Hdr_Flag, 3 ; Current header last header ?? ;AN000;
294 jne Open_Close_gap ; no, close the gap before move it ;AN000;
295 ; to OPEN Queue
296 mov si, Prev_Hdr_Ptr ;AN000;
297 mov es:[si].Fh_Next_Hdr_Ptr,-1 ; yes, mark the previous hdr as last ;AN000;
298 jmp short open_move_Hdr ; header then move to the top of ;AN000;
299 ; OPEN Queue
300
301 ;------------------------------------------------------------------------------
302 ; Close the gap in the CLOSE Queue.
303 ;------------------------------------------------------------------------------
304 Open_Close_Gap:
305 mov Queue_Type, 1 ; set flag to indicate CLOSE Queue ;AN000;
306 CALL JOIN_PREV_TO_NEXT ; join previous header to next header ;AN000;
307
308 ;------------------------------------------------------------------------------
309 ; Now move the current header from CLOSE Queue to top of OPEN Queue
310 ;------------------------------------------------------------------------------
311 Open_Move_Hdr:
312 mov si,Cur_Hdr_Ptr ; SI-->Current header ;AN000;
313 mov di,drive_Hdr_Ptr ; DI-->drive header ;AN000;
314
315 ;------------------------------------------------------------------------------
316 ;Update the file refernce count to 1 before move header to OPEN Queue
317 ;------------------------------------------------------------------------------
318 mov es:[si].FH_Refer_Count, 1 ; set refernce count = 1 ;AN000;
319 mov ax,es:[di].MRU_Hdr_Ptr ; address of current MRU header ;AN000;
320 mov es:[si].FH_Next_Hdr_Ptr,ax ; connect new header to the ;AN000;
321 ; current MRU header
322 mov es:[di].MRU_Hdr_Ptr,si ; make the header MRU header ;AN000;
323 clc ;AN000;
324 jmp short open_exit ; then exit. ;AN000;
325
326 ;------------------------------------------------------------------------------
327 ; If header is not found in both OPEN and CLOSE Queues, then make a new
328 ; header in the next available free area and initialize the new header and
329 ; make it MRU header (mov it to the top of the OPEN Queue).
330 ; If no free space to create a new header, get space from CLOSE Queue.
331 ; If none in CLOSE Queue, then get space from from OPEN Queue. See the
332 ; Procedure (Find_Free_Buffer )
333 ;------------------------------------------------------------------------------
334 Open_Make_Hdr:
335
336 CALL MAKE_NEW_HEADER ; create new header ;AN000;
337 clc ;AN000;
338
339 Open_exit:
340 CALL Check_it
341 ret ; return ;AN000;
342
343 Fk_Open endp
344
345 \f
346
347
348
349
350
351 ;--------------------------------------------------------------------------
352 ; PROCEDURE: FK_CLOSE
353 ;
354 ; FUNCTION: Search for the header on OPEN Queue. If the header is found,
355 ; decrement the file reference count by one. If the resultant
356 ; count is zero, then move the header and the extents under it
357 ; to the CLOSE Queue. If not, make the header MRU header in the
358 ; OPEN Queue.
359 ;
360 ; INPUT: DL = Drive Number
361 ; CX = First Physical Cluster Number of the file
362 ;
363 ; OUTPUT: Moved the file header and the extents to the close Queue
364 ;
365 ; ROUTINES REFERENCED: Find_File_Header, Find_Drive_Header
366 ;
367 ; REVISION HISTORY: New (5/87)
368 ;
369 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
370 ; "Version 4.00 (C) Copyright 1988 Microsoft"
371 ; "Licensed Material - Property of Microsoft "
372 ;
373 ;---------------------------------------------------------------------------
374
375 FK_CLOSE PROC FAR
376 ;AN000;
377 ; Search for Drive header in the Cache buffer using Drive ID in DL
378 push cs ; establish addressability ;AN000;
379 pop ds ; DS --> code segment ;AN000;
380 assume ds:Cseg_Seek ;AN000;
381 mov es, Seek_Name_Cache_Seg ; setup cache buff segment register ;AN000;
382 assume es:Cseg_Init ; ES --> cache buffer segment ;AN000;
383 mov First_Phys_Clusnum, CX ; save phys cluster number ;AN000;
384 mov func_cod,al
385
386 CALL FIND_DRIVE_HEADER ; search for drive header
387 ; DI-->Current drive buffer
388 jnc Close_search_hdr ; found, search for file header ;AN000;
389 clc ; MAKE SURE carry is clear
390 jmp Close_Exit ; not found, error ;AN000;
391
392 ;--------------------------------------------------------------------------
393 ; Search for file header in the OPEN Queue using given physical cluster number
394 ;--------------------------------------------------------------------------
395 Close_Search_Hdr:
396 inc es:[di].Extent_Count ; increment sequence coutn (DEBUG)
397 mov si,es:[di].MRU_Hdr_Ptr ; SI-->first header in OPEN Queue ;AN000;
398 mov cx,First_Phys_Clusnum ; CX = First phys clus num ;AN000;
399 CALL FIND_FILE_HEADER ; find the header in OPEN Queue
400 ; DI-->header found ;AN000;
401 jnc Close_Chk_Last_Hdr ; jump if header found ;AN000;
402 clc ; clear carry ;AN000;
403 jmp short close_exit ; headr not found - exit ;AN000;
404
405 ;--------------------------------------------------------------------------
406 ; Check if the header found is the only header in the OPEN Queue. If true
407 ; go and decrement file reference count by one.
408 ;--------------------------------------------------------------------------
409 Close_Chk_Last_Hdr:
410 cmp Hdr_Flag, 1 ; Only header in the Queue ?? ;AN000;
411 je Dec_Ref_Count ; yes - decrement count, if count =0 ;AN000;
412 ; then move to the top of CLOSE Queue
413 cmp Hdr_Flag, 3 ; no - Last Header in the CLOSE Queue?? ;AN000;
414 jne Close_Join_Hdr ; no, close gap ;AN000;
415 mov si,Prev_Hdr_Ptr ; make the previous header LRU Hdr ;AN000;
416 mov es:[si].FH_Next_Hdr_Ptr, -1 ; mark previous hdr ;AN000;
417 jmp short Dec_Ref_Count ; decrement count and move to ;AN000;
418 ; CLOSE Queue
419
420 ;--------------------------------------------------------------------------
421 ; Connect previous header to next header to close the gap in OPEN Queue
422 ;--------------------------------------------------------------------------
423 Close_Join_Hdr:
424 mov si,Cur_Hdr_Ptr ; SI-->Current header
425 dec es:[si].FH_Refer_Count ; decrement fiel refernce count
426 cmp es:[si].FH_Refer_Count,0 ; count = 0 ??
427 jne Close_Make_MRU ; no - make current header MRU header
428
429 mov Queue_Type, 0 ; else set flag to indicate OPEN Queue ;AN000;
430 CALL JOIN_PREV_TO_NEXT ; close gap before move to CLOSE queue ;AN000;
431 jmp short move_to_Close_List ; move header to CLOSE queue
432
433 ;--------------------------------------------------------------------------
434 ; Decrement the reference count by one. If count = 0, then move the header to
435 ; the top of CLOSE Queue. Else, dont move to CLOSE queue, since the file has
436 ; have multiple open before. In this case make the header MRU header in the
437 ; OPEN queue.
438 ;--------------------------------------------------------------------------
439 Dec_Ref_Count:
440 mov si,Cur_Hdr_Ptr ; SI-->Current header ;AN000;
441 dec es:[si].FH_Refer_Count ; decrement refernece count ;AN000;
442 cmp es:[si].FH_Refer_Count,0 ; reference count = 0 ?? ;AN000;
443 je Move_to_Close_List ; yes, move header to CLOSE Queue ;AN000;
444
445 ;--------------------------------------------------------------------------
446 ; Else, move current Header to top of OPEN Queue. Move to the top of the queue
447 ; only if the header is not the first header in the queue.
448 ;--------------------------------------------------------------------------
449 Close_Make_MRU:
450 cmp Prev_Hdr_Ptr,-1 ; first header in the Queue ?? ;AN000;
451 je Dont_Move_To_Top ; yes, dont move to top ;AN000;
452
453 CALL MAKE_MRU_HEADER ; move header to top of queue ;AN000;
454
455 Dont_Move_To_Top:
456 clc ;AN000;
457 jmp short Close_Exit ; exit ;AN000;
458
459
460 ;--------------------------------------------------------------------------
461 ; Move header to the top of the CLOSE Queue. If the header is the only header
462 ; header in the OPEN Queue, mark OPEN Queue empty.
463 ;--------------------------------------------------------------------------
464 Move_To_Close_List:
465 mov si,Cur_Hdr_Ptr ; SI-->Cur_Hdr_Ptr ;AN000;
466 cmp hdr_flag,1 ; single header in the Queue ?? ;AN000;
467 jne Join_To_Close_List ; no, move header to CLOSE queue ;AN000;
468 mov di,Drive_Hdr_Ptr ;AN000;
469 mov es:[di].MRU_Hdr_Ptr, -1 ; else mark OPEN Queue empty ;AN000;
470
471 Join_To_Close_List:
472 mov di,Drive_Hdr_Ptr ; DI-->current drive header ;AN000;
473 mov ax,es:[di].Close_Ptr ; connect current header to the ;AN000;
474 mov es:[si].FH_Next_Hdr_Ptr,ax ; previous first hdr in CLOSE queue ;AN000;
475 mov es:[di].Close_Ptr,si ; make the current header first
476 ; header in the CLOSE queue
477 clc ;AN000;
478
479 Close_Exit:
480 CALL Check_it
481 ret ; return ;AN000;
482
483 FK_CLOSE ENDP
484
485 \f
486
487
488
489
490 ;------------------------------------------------------------------------
491 ;
492 ; PROCEDURE: FK_DELETE
493 ;
494 ; FUNCTION: Delete a specific header and extents under the header
495 ; and release the buffers to the FREE pool
496 ;
497 ; Search OPEN Queue for file header. If found, delete header and
498 ; extents and release the buffer to FREE area. If not found in OPEN
499 ; queue, search CLOSE Queue. If found, delete header and extents
500 ; under the header and release the area to FREE area.
501 ;
502 ; INPUT: CX = First Physical Cluster Number of the file
503 ; DL = drive id
504 ;
505 ; OUTPUT: The file header and the extents are deleted
506 ;
507 ; ROUTINES REFERENCED: Find_File_Header, Find_Drive_Header
508 ;
509 ; REVISION HISTORY: New (5/87)
510 ;
511 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
512 ; "Version 4.00 (C) Copyright 1988 Microsoft"
513 ; "Licensed Material - Property of Microsoft "
514 ;
515 ;-------------------------------------------------------------------------
516
517 FK_DELETE PROC FAR
518
519 push cs ; establish addressability ;AN000;
520 pop ds ; DS --> code segment ;AN000;
521 assume ds:Cseg_Seek ;AN000;
522 mov es, Seek_Name_Cache_Seg ; setup cache buff segment register ;AN000;
523 assume es:Cseg_Init ; ES --> cache buffer segment ;AN000;
524 mov First_Phys_Clusnum,cx ; save phys cluster number ;AN000;
525 mov func_cod,al
526
527 ;--------------------------------------------------------------------------
528 ; If the delete call is from Free_Buff, then go straight to file header
529 ; search. Else usual delete request from DOS
530 ;--------------------------------------------------------------------------
531 cmp From_FreeBuff,1 ; call from Free_Buff routine ??
532 je Del_Search_Close_List ; yes - find file header in CLOSE queue
533
534 ;--------------------------------------------------------------------------
535 ; Search for Drive Cache buffer using Drive ID in DL
536 ;--------------------------------------------------------------------------
537 CALL FIND_DRIVE_HEADER ; get drive buffer ;AN000;
538 jnc Delete_search_hdr ; found, search for file header ;AN000;
539 jmp Delete_Exit ; not found, error ;AN000;
540
541 ;--------------------------------------------------------------------------
542 ; Search for a header in the OPEN Queue using given physical cluster number
543 ;--------------------------------------------------------------------------
544 Delete_Search_Hdr:
545 inc es:[di].Extent_Count ; ;***;
546 mov si,es:[di].MRU_Hdr_Ptr ; SI-->first header in the ;AN000;
547 ; in the OPEN queue ;AN000;
548 cmp si, -1 ; any header in OPEN Queue ?? ;AN000;
549 je Del_search_Close_list ; none, search CLOSE queue ;AN000;
550 mov cx,First_Phys_Clusnum ; CX = first phys clus number ;AN000;
551 CALL FIND_FILE_HEADER ; find the header in OPEN queue ;AN000;
552 jnc Del_Open_Last_Hdr ; if found, jump ;AN000;
553
554
555 ;--------------------------------------------------------------------------
556 ; Not found in OPEN queue. Search in CLOSE queue
557 ;--------------------------------------------------------------------------
558 Del_Search_Close_List:
559 mov di,Drive_Hdr_Ptr ;AN000;
560 mov si,es:[di].Close_Ptr ; SI-->first header in the ;AN000;
561 ; in the CLOSE queue
562 cmp si, -1 ; anything in CLOSE Queue ?? ;AN000;
563 jne Del_scan_close_list ; yes, jump ;AN000;
564 clc ; none, header not found ;AN000;
565 jmp delete_exit ; exit ;AN000;
566
567 Del_Scan_Close_List:
568 mov cx,First_Phys_Clusnum ; CX = first phys clus number ;AN000;
569 CALL FIND_FILE_HEADER ; find the header in CLOSE queue ;AN000;
570 ;AN000;
571 jnc Del_Close_last_hdr ; if found, chk if this header ;AN000;
572 ; is the last header in CLOSE queue
573 clc ; else, set header not found ;AN000;
574 jmp delete_exit ; and then exit ;AN000;
575
576
577 ;-------------------------------------------------------------------------
578 ; Header found in CLOSE queue. Check header found is the only single
579 ; header left in the queue.
580 ;-------------------------------------------------------------------------
581 Del_Close_Last_Hdr:
582 cmp Hdr_Flag, 1 ; Single Header in CLOSE Queue ?? ;AN000;
583 jne Del_Chk_LRU_Hdr ; no, check for LRU header ;AN000;
584
585 ;--------------------------------------------------------------------------
586 ; Yes, single header in the queue, make CLOSE_PTR empty before delete the
587 ; header from the queue.
588 ;--------------------------------------------------------------------------
589 mov di,Drive_Hdr_Ptr ;AN000;
590 mov es:[di].Close_Ptr, -1 ; mark CLOSE_Ptr as empty ;AN000;
591 jmp short delete_Free_Buff ; release the deleted header ;AN000;
592
593 Del_Chk_LRU_Hdr:
594 cmp Hdr_Flag, 3 ; Last Header in the CLOSE Queue ?? ;AN000;
595 jne Del_Join_Hdr ; no, close gap ;AN000;
596 mov si,Prev_Hdr_Ptr ; make the previous header LRU Hdr ;AN000;
597 mov es:[si].FH_Next_Hdr_Ptr, -1 ; mark previous hdr ;AN000;
598 jmp short delete_Free_Buff ; release the deleted header ;AN000;
599
600 ;--------------------------------------------------------------------------
601 ; Connect previous header to next header to close the gap in CLOSE Queue
602 ;--------------------------------------------------------------------------
603 Del_Join_Hdr:
604 mov Queue_Type, 1 ; set flag to indicate CLOSE Queue ;AN000;
605 CALL JOIN_PREV_TO_NEXT ; close gap ;AN000;
606 ;AN000;
607 jmp short Delete_Free_Buff ; release header to FREE area ;AN000;
608
609
610
611 ;-------------------------------------------------------------------------
612 ; Header found in OPEN queue. Check header found is the only single
613 ; header left in the queue.
614 ;-------------------------------------------------------------------------
615 Del_Open_Last_Hdr:
616 cmp Hdr_Flag, 1 ; Single Header in OPEN Queue?? ;AN000;
617 jne Del_Chk_Opn_LRU_Hdr ; no, check for LRU header ;AN000;
618
619 ;--------------------------------------------------------------------------
620 ; Yes, single header in the queue, mark OPEN Queue empty before delete
621 ;--------------------------------------------------------------------------
622 ; the header from the queue.
623 mov di,Drive_Hdr_Ptr ;AN000;
624 mov es:[di].MRU_Hdr_Ptr, -1 ; mark OPEN Queue as empty ;AN000;
625 jmp short delete_Free_Buff ; release the delete header ;AN000;
626
627 Del_Chk_OPN_LRU_Hdr:
628 cmp Hdr_Flag, 3 ; Last Header in the CLOSE Queue ?? ;AN000;
629 jne Del_Opn_Join_Hdr ; no, close gap ;AN000;
630 mov si,Prev_Hdr_Ptr ; make the previous header LRU Hdr ;AN000;
631 mov es:[si].FH_Next_Hdr_Ptr, -1 ; mark previous hdr ;AN000;
632 jmp short Delete_Free_Buff ; release header to FREE area ;AN000;
633
634 ;--------------------------------------------------------------------------
635 ; Connect previous header to next header to close the gap in OPEN queue
636 ;--------------------------------------------------------------------------
637 Del_Opn_Join_Hdr:
638 mov Queue_Type, 0 ; set flag to indicate OPEN Queue ;AN000;
639 CALL JOIN_PREV_TO_NEXT ; close gap ;AN000;
640 ;AN000;
641
642 ;----------------------------------------------------------------------------
643 ; Header and extends found. Mark the beginning of this free area with "-2".
644 ; Connect this header to the FREE area. Mark all extnts under this header
645 ; and chain them together through the 4th word. Connect the last extent to
646 ; the OLD free area. This process will effectively release the header to the
647 ; FREE area. Finally update the FREE area size in the Drive header.
648 ;
649 ; NOTE: The deleted buffers have size same as the size of a header or extent.
650 ; Each buffers first location contains a marker (-2) to indicate that
651 ; the buffer is a discontinuous buffer. Each discontinuos buffer is
652 ; connected to the next discontinuous buffer through the 4TH word.
653 ;---------------------------------------------------------------------------
654
655 Delete_Free_buff:
656 mov di,Drive_Hdr_Ptr ; SI-->drive header ;AN000;
657 mov si,Cur_Hdr_Ptr ; DI-->current header ;AN000;
658
659 ;-------------------------------------------------------------------------
660 ; Put (-2) in the beginning of the released area to indicate that this is
661 ; a discontinuous free area. Each Free area is 8 bytes which is same size
662 ; as an extent or header.
663 ;-------------------------------------------------------------------------
664 mov ax,-2 ;AN000;
665 mov es:[si], ax ;AN000;
666 cmp es:[si].FH_Next_Extn_Ptr, -1 ; any extents under this header ?? ;AN000;
667 jne del_look_extent ; yes, jump ;AN000;
668
669 ;-------------------------------------------------------------------------
670 ; There is no extents under this header. Connect relased header to the
671 ; Free area and update Free area size in drive header before exit.
672 ;-------------------------------------------------------------------------
673 mov si,Cur_Hdr_Ptr ; SI-->Current Header ;AN000;
674 mov di,Drive_Hdr_Ptr ; DI-->Drive Header ;AN000;
675 mov ax,es:[di].Free_Ptr ; connect current header ;AN000;
676 mov es:[si].FH_Next_Hdr_Ptr, ax ; to the Free AREA ;AN000;
677 mov es:[di].Free_Ptr,si ;AN000;
678 mov cx, SIZE File_Header ; start with file header size ;AN000;
679 mov di,Drive_Hdr_Ptr ;AN000;
680 add es:[di].Free_Size,cx ; update free area size ;AN000;
681 clc ; make sure caary is clear
682 jmp short Delete_Exit ; Then exit ;AN000;
683
684
685 ;-------------------------------------------------------------------------
686 ; Yes, one or more extents under this header. Connect the header to the
687 ; the first extent through 4th word (FH_Next_Hdr_Ptr). Subsequent free
688 ; extents are connected through the 4th word (EH_Next_Extn_Ptr). Next calculate
689 ; the size of the header and possible extendta and update the free area
690 ; size in the drive header.
691 ;-------------------------------------------------------------------------
692 Del_Look_Extent:
693 mov si,Cur_Hdr_Ptr ; SI-->Current Header ;AN000;
694 mov ax, -2 ; mark header as discontinuous ;AN000;
695 mov es:[si],ax ; free area (12/28) ;AN000;
696 mov cx, SIZE File_Header ; start with file header size ;AN000;
697
698 mov ax,es:[si].FH_Next_Extn_Ptr ; AX-->first extent under this hdr ;AN000;
699 mov es:[si].FH_Next_Hdr_Ptr,ax ; connect this header to first extnt ;AN000;
700 ; through the 4th word ;AN000;
701 mov si,ax ; SI-->First extent ;AN000;
702 mov ax, -2 ; mark first extent as discontinous ;AN000;
703 mov es:[si],ax ; free area ;AN000;
704
705 Delete_Loop:
706 add cx, SIZE Extent_Header ; add size of extent ;AN000;
707 cmp es:[si].EH_Next_Extn_Ptr, -1 ; current extent last extent ? ;AN000;
708 je Del_Update_Free_Size ; yes - jump (12/28) ;AN000;
709 mov ax,es:[si].EH_Next_Extn_Ptr ; get pointer to next extent ;AN000;
710 mov es:[si].FH_Next_Hdr_Ptr,ax ; connect curr ext to next extent ;AN000;
711 mov si,ax ; SI-->next extent ;AN000;
712 mov ax, -2 ; mark subsequent extents as ;AN000;
713 mov es:[si],ax ; discontinuous free areas ;AN000;
714 jmp Delete_Loop ; adding the size until last extent ;AN000;
715
716 Del_Update_Free_Size:
717 mov di,Drive_Hdr_Ptr ;AN000;
718 add es:[di].Free_Size,cx ; update free area in drive header ;AN000;
719 ;AN000;
720 ; At this point SI-->Last extent
721 mov di,Drive_Hdr_Ptr ; DI-->drive header ;AN000;
722 mov ax,es:[di].Free_Ptr ;AN000;
723 mov es:[si].FH_Next_Hdr_Ptr,ax ; connect last extent under this ;AN000;
724 ; header to the Free area
725 mov ax,Cur_Hdr_Ptr ; AX-->Current header ;AN000;
726 mov es:[di].Free_Ptr,ax ; connect header being deleted to ;AN000;
727 ; the free pool ;AN000;
728 Delete_Exit:
729 clc
730 cmp check_flag,0
731 jne open_chk_Que
732 clc
733 ret
734 Open_Chk_Que:
735 CALL Check_it
736 ret ; exit ;AN000;
737
738 FK_DELETE ENDP
739
740
741 \f
742
743
744
745
746
747 ;--------------------------------------------------------------------------
748 ; PROCEDURE: FK_INSERT
749 ;
750 ; FUNCTION: Search for a specific extent using the starting physical
751 ; cluster number and the given logical cluster number.
752 ; Insert the given physical cluster number in the extent
753 ; indexed by the given logical cluster number. If extent is
754 ; not found, create a new extent. If free space is not
755 ; available, take free space free CLOSE or OPEN Queue.
756 ;
757 ; INPUT DL = drive number
758 ; CX = First Physical Cluster Number of the file
759 ; BX = Logical Cluster Number
760 ; DI = Physical Cluster Number
761 ;
762 ; OUTPUT: Physical cluster number is inserted. If extent is not found,
763 ; a new file is created
764 ;
765 ; ROUTINES REFERENCED: Find_File_Header, Find_Extent, Find_LRU_Header
766 ;
767 ; REVISION HISTORY: New (5/87)
768 ;
769 ;------------------------------------------------------------------------
770
771 FK_INSERT PROC FAR
772 push cs ; Establish addressability ;AN000;
773 pop ds ; DS --> code segment ;AN000;
774 assume ds:Cseg_Seek ;AN000;
775 mov es, Seek_Name_Cache_Seg ; setup cache buff segment register ;AN000;
776 assume es:Cseg_Init ; ES --> cache buffer segment ;AN000;
777
778 mov first_phys_clusNum,cx ; save cluster numbers ;AN000;
779 mov Logical_ClusNum,bx ;AN000;
780 mov Physical_ClusNum,di ;AN000;
781 mov func_cod,al
782
783 ; Search for Drive Cache buffer using Drive ID in DL
784 CALL FIND_DRIVE_HEADER ; get drive buffer ;AN000;
785 jnc Insert_Search_Hdr ; found, search for file header ;AN000;
786 jmp Insert_Exit ; not found, error ;AN000;
787
788 ;--------------------------------------------------------------------------
789 ; If there are no free buffers and there is only a single header in the
790 ; OPEN queue then there is no headers in the CLOSE queue, then the new
791 ; clusters wont be insterted. This is because, file header should not consume
792 ; its own extent if no free space is available.
793 ;--------------------------------------------------------------------------
794 Insert_Search_Hdr:
795 inc es:[di].Extent_Count ; increment sequence count (DEBUGGING)
796 mov si,es:[di].MRU_Hdr_Ptr ; SI-->first header in OPEN queue ;AN000;
797 cmp es:[si].FH_Next_Hdr_Ptr, -1 ; only one header in OPEN queue??
798 je insert_chk_buff ; yes - check free buffer
799 jmp short insert_Inc_count ; no - go and insert clusters
800
801 Insert_Chk_Buff:
802 cmp es:[di].Free_Size, 0 ; any free buffers ??
803 jne Insert_Inc_Count ; yes - go insert clusters
804 cmp es:[di].Close_Ptr, -1 ; any headers in close queue?? (1/7/88 ;AN000;
805 jne Insert_Inc_Count ; yes - go insert clusters
806 clc ; no - dont insert clusters
807 jmp Insert_Exit ; exit
808
809 insert_Inc_Count:
810 mov si,es:[di].MRU_Hdr_Ptr ; SI-->first header in the OPEN queue ;AN000;
811 mov cx,first_phys_clusnum ; CX = physical cluster number ;AN000;
812 CALL FIND_FILE_HEADER ; find the header in OPEN queue ;AN000;
813 ; DI-->Header
814 jc Insert_Make_Hdr ; header not found, make new header ;AN000;
815 jmp Insert_Find_extent ; header is found, now go and ;AN000;
816 ; search for the extent
817
818 ;--------------------------------------------------------------------------
819 ; If header not found, create a new header in the free area and connect it
820 ; to the top of the OPEN queue. Mark the new header with no extents. Insert
821 ; the first logical and physical cluster number into the header. At this
822 ; point CX=First Physical Cluster number.
823 ;--------------------------------------------------------------------------
824 Insert_Make_Hdr:
825 CALL MAKE_NEW_HEADER ; make a new header at the top ;AN000;
826 ; top of the queue
827 ;--------------------------------------------------------------------------
828 ; Now the header is created, next create an extent and put both logical and
829 ; physical cluster number in the extent. The new extent should be
830 ; created at the bottom end of the current queue, except if AX =3,
831 ; then the new extent will be created between current and previous extent.
832 ; Use Find_Free_Buffer to check the free space.
833 ;--------------------------------------------------------------------------
834 CALL FIND_FREE_BUFFER ; get free area for new extent ;AN000;
835 jnc ins_save_addrs1 ; found, jump ;AN000;
836 jmp Insert_Exit ; if free area found is its own ;AN000;
837 ; header, exit
838 Ins_Save_Addrs1:
839 mov di,Drive_Hdr_Ptr ; DI-->Drive header ;AN000;
840 mov ax,es:[di].Free_Ptr ;AN000;
841 mov New_Extn_Ptr,ax ; save new extent address ;AN000;
842 CALL UPDATE_FREE_AREA ; update Free area ;AN000;
843
844 mov di,Drive_Hdr_Ptr ; DI-->Drive header ;AN000;
845 mov ax,New_Extn_Ptr ; beginning of new extent ;AN000;
846 mov si,Cur_Hdr_Ptr ; SI-->Current header ;AN000;
847 mov es:[si].FH_Next_Extn_Ptr,ax ; connect current header to adj CHAIN ;AN000;
848 mov es:[si].FH_MRU_EXTN_Ptr,ax ; connect current header to LRU chain ;AN000;
849 mov si,New_Extn_Ptr ; SI-->New extent
850 mov bx,Logical_ClusNum ;AN000;
851 mov es:[si].EH_Logic_Clus_Num,bx ; insert logical clus num ;AN000;
852 mov cx,Physical_ClusNum ;AN000;
853 mov es:[si].EH_Phys_Clus_Num,cx ; insert physical clus num ;AN000;
854 mov es:[si].EH_Count,0 ; set initial count = 0 ;AN000;
855
856 ;--------------------------------------------------------------------------
857 ; Make new extent LRU extent
858 ;--------------------------------------------------------------------------
859 mov es:[si].EH_Next_Extn_Ptr, -1 ; mark no next extent in sorted chain
860 mov es:[si].EH_Prev_Extn_Ptr, -1 ; mark no previous extent in sorted chain ;AN000;
861 mov es:[si].EH_Next_LRU_Ptr, -1 ; mark no next extent in MRU-LRU chain ;AN000;
862 mov es:[si].EH_Prev_LRU_Ptr, -1 ; mark no previous extent in MRU-LRU chain
863 clc ;
864 jmp Insert_Exit ; exit ;AN000;
865
866 ;--------------------------------------------------------------------------
867 ; Header found, Check to see any extent under this header. If not create
868 ; new extent. If there are extents, search for the relative position of the
869 ; given cluster number among the extents under current header.
870 ;--------------------------------------------------------------------------
871 Insert_Find_Extent:
872 mov di,Cur_Hdr_Ptr ; DI-->Current header
873 mov si,es:[di].FH_Next_Extn_Ptr ; SI-->first extent under current hdr ;AN000;
874 cmp si,-1 ; any extent under this header ? ;AN000;
875 jne Find_relative_location ; yes, Find relative location of the
876 ; given cluster numbers ;AN000;
877
878 ; Else create new extent under the current header.
879 CALL FIND_FREE_BUFFER ; get free area for new extent ;AN000;
880 jnc ins_save_addrs2 ; found, jump ;AN000;
881 jmp Insert_Exit ; else free area found is its own ;AN000;
882 ; header, *** ERROR **** exit
883 Ins_save_addrs2:
884 mov di,Drive_Hdr_Ptr ; DI-->Drive header ;AN000;
885 mov ax,es:[di].Free_Ptr ;AN000;
886 mov New_Extn_Ptr,ax ; save new extent address ;AN000;
887
888 CALL UPDATE_FREE_AREA ; update Free area pointers ;AN000;
889
890 mov di,Drive_Hdr_Ptr ; DI-->Drive header pointer ;AN000;
891 mov ax,New_Extn_Ptr ;AN000;
892 mov si,Cur_Hdr_Ptr ; SI-->Current header ;AN000;
893 mov es:[si].FH_Next_Extn_Ptr,ax ; connect new extent to header ;AN000;
894 mov es:[si].FH_MRU_EXTN_Ptr,ax
895 mov si,New_Extn_Ptr ;### next extent start in the free_ptr ;AN000;
896 mov bx,Logical_ClusNum ;AN000;
897 mov es:[si].EH_Logic_Clus_Num,bx ; insert logical ;AN000;
898 mov cx,Physical_ClusNum ;AN000;
899 mov es:[si].EH_Phys_Clus_Num,cx ; insert physical cluster numbe ;AN000;
900 mov es:[si].EH_Count,0 ; ;AN000;
901 mov es:[si].EH_Next_Extn_Ptr,-1 ; mark this extent as last extent ;AN000;
902 mov es:[si].EH_Next_LRU_Ptr,-1 ; ### mark this extent as last extent ;AN000;
903 mov es:[si].EH_Prev_Extn_Ptr,-1 ; mark there is no prev extent ;AN000;
904 mov es:[si].EH_Prev_LRU_Ptr,-1 ; mark there is no prev LRU extent
905 jmp Insert_Make_MRU ; make current header MRU header ;AN000;
906
907
908 ;--------------------------------------------------------------------------
909 ; Check if the given cluster number will be continuous to either High or Low
910 ; end of any extent under current header or should create a new extent
911 ; If not, check whether a new extent for the cluster is to be created
912 ; between current and previous extent - Current and next extent or new
913 ; extent at the bottom of the queue.
914 ;--------------------------------------------------------------------------
915 Find_Relative_Location:
916 CALL FIND_CLUSTER_LOCATION ; find relative position of new extent ;AN000;
917 jnc chk_continuity ; position found ;AN000;
918 clc ; clusters already exist in an extent.
919 jmp Insert_exit ; return to DOS ;AN000;
920
921 ;--------------------------------------------------------------------------
922 ; Extent found. Check for LOW end contiguous. If true insert in the current
923 ; extent and update the count
924 ;--------------------------------------------------------------------------
925 Chk_continuity:
926 cmp find_flag,1 ; LO end contiguous to current extent? ;AN000;
927 jne Insert_chk_HI ; no - check high end contiguous ;AN000;
928 mov si,Cur_Extn_Ptr ; yes - insert and update ;AN000;
929 mov cx,Logical_ClusNum ; save new logical and pysical ;AN000;
930 mov es:[si].EH_Logic_Clus_Num,cx ; cluster numbers as first clusters ;AN000;
931 mov cx,Physical_ClusNum
932 mov es:[si].EH_Phys_Clus_Num,cx ;AN000;
933 inc es:[si].EH_Count ; update extent range count ;AN000;
934 mov di,Drive_Hdr_Ptr ; DI-->drive header
935 cmp es:[di].Free_Ptr,0 ; any free buffer ??
936 je Chk_low_MRU ; no - make current extent MRU extent
937 jmp Insert_Make_MRU ; yes - make current header MRU header ;AN000;
938
939 Chk_Low_MRU:
940 mov Cur_Extn_Ptr, si
941 CALL Make_MRU_Extent ; Move extent next to current header
942 jmp Insert_Make_MRU ; Make current header MRU header ;AN000;
943
944 ;--------------------------------------------------------------------------
945 ; Check if clusters are high end contiguous to current extent. If true
946 ; increment count and then make the extent MRU extent only if no free
947 ; buffer is available.
948 ;--------------------------------------------------------------------------
949 Insert_Chk_HI:
950 cmp find_flag,2 ; HI end contiguous to current extent? ;AN000;
951 jne Insert_chk_between ; no, jump ;AN000;
952 mov si,Cur_Extn_Ptr ; SI-->Current extent ;AN000;
953 inc es:[si].EH_Count ; increment the cluster range count ;AN000;
954 mov di,Drive_Hdr_Ptr ; DI-->current drive header
955 cmp es:[di].Free_Ptr,0 ; any free buffers ??
956 je Chk_Hi_MRU ; no - make current extent MRU extent
957 jmp Insert_Make_MRU ; yes - current header MRU header ;AN000;
958
959 Chk_Hi_MRU:
960 mov Cur_Extn_Ptr, si ; SI -->extent to be MRU
961 CALL Make_MRU_Extent ; move extent next to current header
962 jmp Insert_Make_MRU ; Make current header MRU header ;AN000;
963
964
965 ;--------------------------------------------------------------------------
966 ; Check to see the cluster number belongs to a new extent between current
967 ; and Previous extent or header. If not it belongs to a new extent at the
968 ; bottom end of the queue.
969 ;--------------------------------------------------------------------------
970 Insert_Chk_Between:
971 cmp find_flag,3 ; between current and previous exts?? ;AN000;
972 je Connect_prev_next ; yes, jump ;AN000;
973
974 cmp find_flag,5 ; between current and next extents?? ;AN000;
975 jne Connect_to_end ; no, create new extent at bottom ;AN000;
976 ; bottom of the queue
977 jmp Connect_cur_next ; yes create new extent between ;AN000;
978 ; current and next extent
979
980 ;--------------------------------------------------------------------------
981 ; No, make new extent at the BOTTOM of the queue.
982 ;--------------------------------------------------------------------------
983 CONNECT_TO_END: ; At this point SI-->Last extent in queue ;AN000;
984 CALL FIND_FREE_BUFFER ; Check for free area ;AN000;
985 jnc ins_save_addrs3 ;AN000;
986 jmp Insert_Exit ; if free area found is its own ;AN000;
987 ; header, *** ERROR *** exit
988 Ins_Save_Addrs3:
989 mov di,Drive_Hdr_Ptr ;AN000;
990 mov ax,es:[di].Free_Ptr ;AN000;
991 mov New_Extn_Ptr,ax ; save new extent address ;AN000;
992 CALL UPDATE_FREE_AREA ; update Free_Ptr and Free_Size ;AN000;
993
994 mov ax,New_Extn_Ptr ;AN000;
995 mov di,Cur_Extn_Ptr ; SI-->Current extent ;AN000;
996 cmp ax, di ; If free area got is the last
997 jne Use_Cur_Extent ; last extent itself then use previous extent
998 mov di, Prev_Extn_Ptr ; SI-->Previous extent
999
1000 Use_Cur_extent:
1001 mov es:[di].EH_Next_Extn_Ptr,ax ; connect new extent to current or previous extent ;AN000;
1002 mov si,New_Extn_Ptr ; next extent start in the free_ptr ;AN000;
1003 mov es:[si].EH_Prev_Extn_Ptr, di ; set previous extent address
1004 mov bx,Logical_ClusNum ;AN000;
1005 mov es:[si].EH_Logic_Clus_Num,bx ; insert logical ;AN000;
1006 mov cx,Physical_ClusNum ;AN000;
1007 mov es:[si].EH_Phys_Clus_Num,cx ; insert physical cluster numbe ;AN000;
1008 mov es:[si].EH_Count,0 ; initial cluster range
1009
1010 ; Make new extent last extent in the sorted chain
1011 mov es:[si].EH_Next_Extn_Ptr, -1 ; mark as Last extent of the queue ;AN000;
1012 ; make the new extent MRU extent in the MRU_LRU chain
1013 mov di,Cur_Hdr_Ptr ; DI-->Current header
1014 mov ax,es:[di].FH_MRU_Extn_Ptr ; AX-->Previous MRU extent
1015 mov es:[si].EH_NEXT_LRU_Ptr,ax ; connect previous to current extent
1016 mov es:[si].EH_Prev_LRU_Ptr, -1 ; mark no previous LRU extent ;AN000;
1017 mov es:[di].FH_MRU_Extn_Ptr,si ; make current extent MRU extent
1018 mov di,ax
1019 mov es:[di].EH_Prev_LRU_Ptr,si ; connect previous to current extent
1020 jmp Insert_Make_MRU ; make current header MRU header
1021 ;AN000;
1022
1023
1024 ;--------------------------------------------------------------------------
1025 ; Make new extent between current and previous extents. If no previous extent
1026 ; connect the new extent to the current header.
1027 ;--------------------------------------------------------------------------
1028 CONNECT_PREV_NEXT:
1029 CALL FIND_FREE_BUFFER ; get free area for new extent ;AN000;
1030 jnc Prev_Next_Update ; found, jump ;AN000;
1031 jmp Insert_Exit ; if free area found is its own ;AN000;
1032 ; header, **ERROR** exit
1033 Prev_Next_Update:
1034 mov di,Drive_Hdr_Ptr ; DI-->Drive header ;AN000;
1035 mov ax,es:[di].Free_Ptr ;AN000;
1036 mov New_Extn_Ptr,ax ; save new extent address ;AN000;
1037 ;AN000;
1038 CALL UPDATE_FREE_AREA ; update Free_Ptr and Free_Size ;AN000;
1039
1040 mov di,Drive_Hdr_Ptr ; DI-->Drive Header ;AN000;
1041 cmp Prev_Extn_Ptr, -1 ; Any previous extents ?? ;AN000;
1042 jne join_to_Prev_Extn ; yes - connect new extent to previous ;AN000;
1043 ; extent
1044 ; No, connect new extent to header
1045 mov si,Cur_Hdr_Ptr ; SI-->current header ;AN000;
1046 mov di,New_Extn_Ptr ;AN000;
1047 mov ax,es:[si].FH_Next_Extn_Ptr ; AX-->first extent under header
1048 mov es:[di].EH_Next_Extn_Ptr,ax ; connect new extent to this extent
1049 mov es:[si].FH_Next_Extn_Ptr, di ; connect new extent to cur hdr ;AN000;
1050 mov es:[di].EH_Prev_Extn_Ptr, -1 ; address of previous extent (-1) since header
1051 mov bx,Logical_Clusnum ; ;AN000;
1052 mov es:[di].EH_Logic_Clus_Num,bx ; insert logical clus num ;AN000;
1053 mov cx,Physical_Clusnum ;AN000;
1054 mov es:[di].EH_Phys_Clus_Num,cx ; insert physical cluster numbe ;AN000;
1055 mov es:[di].EH_Count,0 ; set count ;AN000;
1056 mov si,ax ; SI-->previous MRU extent
1057 mov es:[si].EH_Prev_Extn_Ptr,di ; set prev extent of prev MRU extent
1058
1059 ; Make the new extent MRU extent
1060 mov si,Cur_Hdr_Ptr ; SI-->current header ;AN000;
1061 mov ax,es:[si].FH_MRU_EXTN_Ptr ; AX-->MRU extent under header
1062 mov di,New_Extn_Ptr ; SI-->current header ;AN000;
1063 mov es:[di].EH_Next_LRU_Ptr,ax ; connect new extent to current extent
1064 mov es:[di].EH_Prev_LRU_Ptr, -1 ; mark no previous LRU extent ;AN000;
1065 mov es:[si].FH_MRU_Extn_Ptr,di ; connect new extent to header
1066 mov si,ax
1067 mov es:[si].EH_Prev_LRU_Ptr,di ; connect previous to current extent
1068 Jmp Insert_Make_MRU ; make current header MRU hdr ;AN000;
1069
1070 ; Connect new extent to previous extent
1071 Join_To_Prev_Extn:
1072 mov si,New_Extn_Ptr ; SI-->New extent, connect new to ;AN000;
1073 mov ax,Cur_Extn_Ptr ; connect previous extent ;AN000;
1074 cmp si,ax ; new extent is created from
1075 je join_set_adj ; current extent ??
1076
1077 mov si,Prev_Extn_Ptr ; no - SI-->Previous extent ;AN000;
1078 mov ax,New_Extn_Ptr ; connect new extent to ;AN000;
1079 mov es:[si].EH_Next_Extn_Ptr,ax ; previous extent ;AN000;
1080 mov ax,Cur_Extn_Ptr
1081 jmp short Join_Set_Next ; current extent
1082
1083 Join_set_adj: ; yes -
1084 mov si,Prev_Extn_Ptr ; no - SI-->Previous extent ;AN000;
1085 mov bx,es:[si].EH_Next_Extn_Ptr ; get next extent address
1086 mov ax,New_Extn_Ptr ; connect new extent to ;AN000;
1087 mov es:[si].EH_Next_Extn_Ptr,ax ; previous extent ;AN000;
1088 mov ax, bx ; extent to next extent
1089 mov Cur_Extn_Ptr,bx ; change current extent
1090
1091 Join_set_Next: ; from current extent
1092 mov si,New_Extn_Ptr ; SI-->New extent, connect new to ;AN000;
1093 mov es:[si].EH_Next_Extn_Ptr,ax ; current extent ;AN000;
1094 mov bx,Logical_Clusnum ; then save cluster numbers ;AN000;
1095 mov es:[si].EH_Logic_Clus_Num,bx ; insert logical ;AN000;
1096 mov cx,Physical_Clusnum ;AN000;
1097 mov es:[si].EH_Phys_Clus_Num,cx ; insert physical cluster numbe ;AN000;
1098 mov es:[si].EH_Count,0 ; ;AN000;
1099 mov ax, Prev_Extn_Ptr
1100 mov es:[si].EH_Prev_Extn_Ptr,ax ; connect previous to current extent
1101 mov di, Cur_Extn_Ptr ; setup previous extent link of
1102 mov es:[di].EH_Prev_Extn_Ptr,si ; current extent
1103
1104 ; Make the new extent MRU extent
1105 mov si,Cur_Hdr_Ptr ; SI-->current header ;AN000;
1106 mov ax,es:[si].FH_MRU_EXTN_Ptr ; AX-->MRU extent under header
1107 mov di,New_Extn_Ptr ; SI-->current header ;AN000;
1108 mov es:[di].EH_Next_LRU_Ptr,ax ; connect new extent to current extent
1109 mov es:[di].EH_Prev_LRU_Ptr, -1 ; mark no previous LRU extent ;AN000;
1110 mov es:[si].FH_MRU_Extn_Ptr,di ; connect new extent to header
1111 mov si,ax
1112 mov es:[si].EH_Prev_LRU_Ptr,di ; connect previous to current extent
1113 Jmp short Insert_Make_MRU ; make current header MRU hdr ;AN000;
1114
1115
1116
1117 ;--------------------------------------------------------------------------
1118 ; Make new extent between current and next extents. If no next extent
1119 ; connect the new extent to the end of queue.
1120 ;--------------------------------------------------------------------------
1121 CONNECT_CUR_NEXT:
1122 mov si,Cur_Extn_Ptr ; current extent ;AN000;
1123 cmp es:[si].EH_Next_Extn_Ptr,-1 ; any next extent ?? ;AN000;
1124 jne join_to_next_extn ; yes, join to next extent ;AN000;
1125 jmp Connect_To_End ; make new extent at the bottom of ;AN000;
1126 ; the current queue
1127 Join_To_Next_Extn:
1128 CALL FIND_FREE_BUFFER ; Find free area ;AN000;
1129 jc Insert_Exit ; if free area found is its own ;AN000;
1130 ; header, exit
1131 mov di,Drive_Hdr_Ptr ;AN000;
1132 mov ax,es:[di].Free_Ptr ;AN000;
1133 mov New_Extn_Ptr,ax ; save new extent address ;AN000;
1134
1135 CALL UPDATE_FREE_AREA ; update Free_Ptr and Free_Size ;AN000;
1136 ;AN000;
1137 mov si,Cur_Extn_Ptr ; SI-->Current extent
1138 mov DX,es:[si].EH_Next_Extn_Ptr ; DI-->Next extent ;AN000;
1139 mov ax,New_Extn_Ptr ;AN000;
1140 mov es:[si].EH_Next_Extn_Ptr,ax ;connect new extent to cur extent ;AN000;
1141
1142 mov si,New_Extn_Ptr ; SI-->New extent, connect new ext ;AN000;;AN000;
1143 mov es:[si].EH_Next_Extn_Ptr,DX ; to next extent ;AN000;
1144 mov ax, Cur_Extn_Ptr ; AX = address of current extent
1145 mov es:[si].EH_Prev_Extn_Ptr, ax ; save address of previous extent
1146 mov bx,Logical_Clusnum ; then save cluster numbers ;AN000;
1147 mov es:[si].EH_Logic_Clus_Num,bx ; insert logical ;AN000;
1148 mov cx,Physical_Clusnum ;AN000;
1149 mov es:[si].EH_Phys_Clus_Num,cx ; insert physical cluster numbe ;AN000;
1150 mov es:[si].EH_Count,0 ; set cluster range ;AN000;
1151 mov di,DX ; setup prev extent link of the
1152 mov es:[di].EH_Prev_Extn_Ptr,si ; next extent
1153
1154 ; Make the new extent MRU extent
1155 mov si,Cur_Hdr_Ptr ; SI-->current header ;AN000;
1156 mov ax,es:[si].FH_MRU_EXTN_Ptr ; AX-->MRU extent under header
1157 mov di,New_Extn_Ptr ; SI-->current header ;AN000;
1158 mov es:[di].EH_Next_LRU_Ptr,ax ; connect new extent to current extent
1159 mov es:[di].EH_Prev_LRU_Ptr, -1 ; mark no previous LRU extent ;AN000;
1160 mov es:[si].FH_MRU_Extn_Ptr,di ; connect new extent to header
1161 mov si,ax
1162 mov es:[si].EH_Prev_LRU_Ptr,di ; connect previous to current extent
1163
1164
1165 ;--------------------------------------------------------------------------
1166 ; Make the Current header MRU header. If the header is MRU header, then
1167 ; dont make the header MRU header.
1168 ;--------------------------------------------------------------------------
1169 Insert_Make_MRU:
1170 cmp Prev_Hdr_Ptr, -1 ; first header ?? ;AN000;
1171 jne Ins_mru_hdr ; no, make MRU header ;AN000;
1172 clc ; make sure caary is clear
1173 jmp short insert_exit ; yes, exit ;AN000;
1174
1175 Ins_MRU_Hdr:
1176 CALL MAKE_MRU_HEADER ; move header to top of OPEN Queue ;AN000;
1177 clc ; make sure caary is clear
1178
1179 Insert_exit:
1180 CALL Check_it ; analyse the queue (debugging)
1181 ret ; EXIT ;AN000;
1182
1183 FK_INSERT ENDP
1184
1185 \f
1186
1187
1188
1189
1190
1191
1192 ;-------------------------------------------------------------------------
1193 ; PROCEDURE: FK_LOOKUP
1194 ;
1195 ; FUNCTION: Search through the OPEN Queue for a specific Header and
1196 ; extent. If header is not found, create a new header and
1197 ; make it MRU header. Else search for a specific extent which
1198 ; contains the logical cluster number. If the extent is not
1199 ; found, return partial information from previous extent or
1200 ; header. If extent is found, return physical cluster number
1201 ; corresponds to the given logical cluster number.
1202 ;
1203 ; INPUT: DL = drive number
1204 ; CX = First Physical Cluster Number of the file
1205 ; BX = Logical Cluster NUmber
1206 ;
1207 ; OUTPUT: If Carry = 0 Fully Found
1208 ; DI = Physical Cluster Number indexed by es:[BX]
1209 ; BX = Physical Cluster Number indexed by es:[BX-1]
1210 ;
1211 ; If Carry = 1 Partially Found
1212 ; BX = Last logical cluster number in previous extent
1213 ; DI = Last Physical Cluster Number indexed by es:[Last logic clus]
1214 ;
1215 ; If header not found, a new header will be created. In this case
1216 ; BX = First Logical Cluster number (0)
1217 ; DI = First Physical Cluster number of the header created
1218 ;
1219 ; NOTE: The clusters are fully found if the logical cluster has
1220 ; continuity to the previous logical cluster in the same
1221 ; extent or previous extent or previous header.
1222 ;
1223 ; ROUTINES REFERENCED: Find_File_Header, Find_Extent, Find_Drive_Header
1224 ;
1225 ; REVISION HISTORY: New (5/87)
1226 ;
1227 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
1228 ; "Version 4.00 (C) Copyright 1988 Microsoft"
1229 ; "Licensed Material - Property of Microsoft "
1230 ;
1231 ;---------------------------------------------------------------
1232
1233 FK_LOOKUP PROC FAR ; on entry DS = seg ID of INIT
1234
1235 push cs ; establish addressability ;AN000;
1236 pop ds ; DS --> code segment ;AN000;
1237 assume ds:Cseg_Seek ;AN000;
1238 mov es, Seek_Name_Cache_Seg ; setup cache buff segment register ;AN000;
1239 assume es:Cseg_Init ; ES --> cache buffer segment ;AN000;
1240 mov First_Phys_Clusnum,cx ; save phys cluster number ;AN000;
1241 mov Logical_ClusNum,bx
1242 mov func_cod,al
1243
1244 ;--------------------------------------------------------------------------
1245 ; Search for Drive header in the Cache buffer using Drive ID in DL
1246 ;--------------------------------------------------------------------------
1247 CALL FIND_DRIVE_HEADER ; Search for drive header ;AN000;
1248 jnc Look_search_hdr ; found, search for file header ;AN000;
1249 jmp Look_Exit ; not found, error ;AN000;
1250
1251 ;--------------------------------------------------------------------------
1252 ; Search for a header in the OPEN Queue using given physical cluster number
1253 ;--------------------------------------------------------------------------
1254 Look_Search_Hdr:
1255 inc es:[di].Extent_Count ; ;***;
1256 mov si,es:[di].MRU_Hdr_Ptr ; SI-->first header in the ;AN000;
1257 ; in the OPEN Queue
1258 mov cx,First_Phys_Clusnum ; CX = Physical Cluster number ;AN000;
1259 CALL FIND_FILE_HEADER ; find the header in CLOSE Queue
1260 ;AN000;
1261 jnc Look_Find_extent ; if found, find extent under this header
1262 ; else create a new header ;AN000;
1263 ;--------------------------------------------------------------------------
1264 ; If the header is not found, create a new header at the top of OPEN queue.
1265 ; Insert physical cluster number and set next header and first extent pointers
1266 ; Return partially found information.
1267 ;--------------------------------------------------------------------------
1268 pushf ; save carry set
1269 CALL MAKE_NEW_HEADER ; Make a new header at the top of the queue ;AN000;
1270 xor bx,bx ; BX = First Logical cluster number ;AN000;
1271 mov di, First_Phys_Clusnum ; DI = First physical cluster number
1272 popf ; carry should be set
1273 jmp Look_exit ; exit ;AN000;
1274
1275
1276 ;--------------------------------------------------------------------------
1277 ; If the header is found, next search for the extent that contains the
1278 ; logical and physical cluster numbers. DI--> current header
1279 ;--------------------------------------------------------------------------
1280 Look_Find_Extent:
1281 cmp es:[di].FH_Next_Extn_Ptr,-1 ; any extent under this header ?? ;AN000;
1282 jne look_search_extent ; yes, search for right extent ;AN000;
1283
1284 xor bx,bx ; no, return partial info from header ;AN000;
1285 mov di,es:[di].FH_Phys_Clus_Num ; DI = first phys clus num ;AN000;
1286 push di ; ;AN000;
1287 push bx ; BX = 1st logc clus num = 0 ;AN000;
1288 mov fully_flag, 0 ; set partially found flag ;AN000;
1289 jmp look_make_MRU_hdr ; move header to top of the OPEN queue ;AN000;
1290
1291
1292 ;--------------------------------------------------------------------------
1293 ; Search for cluster numbers in extents starting from 1st extent.
1294 ;--------------------------------------------------------------------------
1295 Look_Search_Extent:
1296 mov si,es:[di].FH_Next_Extn_Ptr ; SI-->first extent under curr hdr ;AN000;
1297 mov Cur_Extn_Ptr,si ; save it ;AN000;
1298 mov cx,Logical_ClusNum ; CX = logic clus num to search for ;AN000;
1299 mov Prev_Extn_Ptr, -1 ; reset flags ;AN000;
1300 mov Extn_Flag, 0 ; ;AN000;
1301 cmp cx,es:[si].EH_Logic_Clus_Num ; 1st logic clus num in the ;AN000;
1302 jl Look_proc_less
1303
1304 Look_Loop1:
1305 cmp cx,es:[si].EH_Logic_Clus_Num ; 1st logic clus num in the ;AN000;
1306 ; current extent matches ??
1307 je Look_Proc_First ; yes, process 1st extent case ;AN000;
1308 mov ax,es:[si].EH_Logic_Clus_Num ; else check subsequent extents
1309 add ax,es:[si].EH_Count ; last logic clus num in cur extent ;AN000;
1310 cmp cx,ax ; extent found in the cur extent ??
1311 jg Look_Next_Extn ; no,try next extent ;AN000;;AN000;;AN000;
1312 jmp Look_Extn_within ; yes, process current extent ;AN000;
1313
1314 Look_Next_Extn: ;
1315 mov ax,es:[si].EH_Next_Extn_ptr ; get address of next extent ;AN000;
1316 cmp ax,-1 ; is this last extent ?? ;AN000;
1317 je Look_last_done ; yes, get partial ;AN000;
1318
1319 mov Prev_Extn_Ptr,si ; save previous extent address ;AN000;
1320 mov si,ax ;AN000;
1321 mov Cur_Extn_Ptr,si ; save current extent address ;AN000;
1322 cmp cx,es:[si].EH_Logic_Clus_Num ; logic clus num in cur extent ?? ;AN000;
1323 jge Look_Loop1 ; may be!!, check it out ;AN000;
1324
1325 jmp Look_Proc_Prev ; else get partial info from ;AN000;
1326 ; previous extent
1327 ;-------------------------------------------------------------------------
1328 ; There are no further extents. In this case partially found. Return last
1329 ; logical and physical clusters of the last extent.
1330 ;-------------------------------------------------------------------------
1331 Look_Last_Done:
1332 mov si,Cur_Extn_Ptr ; SI-->Previous extent ;AN000;
1333 mov bx,es:[si].EH_Logic_Clus_Num ; DI = first logic clus num ofprevext ;AN000;
1334 mov di,es:[si].EH_Phys_Clus_Num ; BX = first logic clus num ofprevext ;AN000;
1335 add di,es:[si].EH_Count ; DI = last phys clus number in extent ;AN000;
1336 add bx,es:[si].EH_Count ; BX = last logic clus number in extent ;AN000;
1337 push di ; last logical cluster number ;AN000;;AN000;
1338 push bx ; last physical cluster number ;AN000;
1339 mov fully_flag,0 ; partially found case ;AN000;
1340 jmp Look_Make_MRU_Hdr ; make current header MRU header ;AN000;
1341
1342
1343
1344 ;--------------------------------------------------------------------------
1345 ; Less than starting logical cluster of first extent. In this case return
1346 ; header info as partially found.
1347 ;--------------------------------------------------------------------------
1348 Look_Proc_Less:
1349 xor bx,bx ; BX = logical cluster number = 0 ;AN000;
1350 mov ax,es:[di].FH_Phys_Clus_Num ;AN000;
1351 push ax ; first phys clus of current hdr ;AN000;
1352 push bx ; first logic clus (0) of cur hdr ;AN000;
1353 mov fully_flag,0 ; partially found case ;AN000;
1354 jmp Look_Make_MRU_Hdr ; make current header MRU header ;AN000;
1355
1356
1357
1358 ;--------------------------------------------------------------------------
1359 ; If first logical cluster number of the current extent matches with the given
1360 ; logical cluster number, see if previous logical cluster in previous header
1361 ; or extent is contiguous. If true, fully found. I this case return
1362 ; BX = first physical cluster of cuurent extent and DI = first physical
1363 ; cluster number of header if it is a header or last physical cluster number
1364 ; of previous extent. If this is not true, partially found case. In this case,
1365 ; return BX = last logical cluster number and DI = last physical cluster number
1366 ; from the previous extent. If no previous extent, then return DI = first
1367 ; physical cluster and BX = 0 from the header
1368 ;
1369 ; NOTE: The clusters are fully found if the logical cluster has
1370 ; continuity to the previous logical cluster in the same
1371 ; extent or previous extent or previous header.
1372 ;--------------------------------------------------------------------------
1373 Look_Proc_First:
1374 mov si,Cur_Extn_Ptr ; SI-->current extent ;AN000;
1375 mov di,Cur_Hdr_Ptr ; DI-->current header ;AN000;
1376 cmp Prev_Extn_Ptr, -1 ; any previous extent ?? ;AN000;
1377 jne look_get_prev_extent ; yes, get from previous extent ;AN000;
1378
1379 ;--------------------------------------------------------------------------
1380 ; No, look for current header logical cluster number continuity
1381 ;--------------------------------------------------------------------------
1382 mov ax,es:[si].EH_Logic_Clus_Num ; AX = First physical cluster number ;AN000;
1383 dec ax ; of current extent ;AN000;
1384 cmp ax,0 ; continuity to first logical clus num ;AN000;
1385 ; of current header which is (0)
1386 jne Look_first_partial ; no, partially found ;AN000;
1387
1388
1389 ; Yes, fully found
1390 mov bx,es:[si].EH_Phys_Clus_Num ; BX = First physical cluster number ;AN000;
1391 ; current extent
1392 mov ax,es:[di].FH_Phys_Clus_Num ; AX = First physical cluster number ;AN000;
1393 ; of current header
1394 push bx ; BX = 1st phys clus of current extent ;AN000;
1395 push ax ; AX = 1st phys clus of prev header ;AN000;
1396 mov fully_flag,1 ; FULLY found case ;AN000;
1397 jmp Look_Make_MRU_Hdr ; mov cur header to top of the Queue ;AN000;
1398
1399
1400 Look_First_Partial:
1401 xor bx,bx ; BX = logical cluster number = 0 ;AN000;
1402 mov ax,es:[di].FH_Phys_Clus_Num ;AN000;
1403 push ax ; first phys clus of current hdr ;AN000;
1404 push bx ; first logic clus (0) of cur hdr ;AN000;
1405 mov fully_flag,0 ; partially found case ;AN000;
1406 jmp short Look_Make_MRU_Hdr ; make current header MRU header ;AN000;
1407
1408
1409 ;--------------------------------------------------------------------------
1410 ; Get last physical and logical cluster number of the previous extent
1411 ;--------------------------------------------------------------------------
1412 Look_Get_Prev_Extent:
1413 mov di,Prev_Extn_Ptr ; DI-->Previous extent ;AN000;
1414 mov ax,es:[si].EH_Logic_Clus_Num ; AX = First logical cluster number ;AN000;
1415 dec ax ; of current extent ;AN000;
1416 mov bx,es:[di].EH_Logic_Clus_Num ; continuity to last logical clus num ;AN000;
1417 add bx,es:[di].EH_Count ; of previous extent ?? ;AN000;
1418 cmp ax,bx ;AN000;
1419 jne Look_first_partial2 ; no, partially found ;AN000;
1420
1421 ; Fully found case
1422 mov bx,es:[si].EH_Phys_Clus_Num ; BX = First physical cluster number ;AN000;
1423 mov ax,es:[di].EH_Phys_Clus_Num ; AX = Last physical cluster number ;AN000;
1424 add ax,es:[di].EH_Count ; from previous extent ;AN000;
1425 push bx ; BX = 1st phys clus num from cur extn ;AN000;
1426 push ax ; AX = last phys clus num from prev extn ;AN000;
1427 mov fully_flag,1 ; FULLY found case ;AN000;
1428 jmp short Look_Make_MRU_Hdr ; mov current header to top of OPEN que ;AN000;
1429
1430
1431 Look_First_Partial2:
1432 mov bx,es:[di].EH_Logic_Clus_Num ; BX = First Logical cluster number ;AN000;
1433 ; of current extent
1434 add bx,es:[di].EH_Count ; BX = Last Logic clus from prev extn ;AN000;
1435 mov ax,es:[di].EH_Phys_Clus_Num ; AX = First physical cluster number ;AN000;
1436 ; of previous extent
1437 add ax,es:[di].EH_Count ; last phys clus num of prev extent ;AN000;
1438 push ax ; AX = last phys clus of prev extent ;AN000;
1439 push bx ; BX = last logic clus of prev extent ;AN000;
1440 mov fully_flag,0 ; partially found case ;AN000;
1441 jmp short Look_Make_MRU_Hdr ; make current header MRU header ;AN000;
1442
1443
1444
1445 ;----------------------------------------------------------------------------
1446 ; If the given cluster number matches with any logic cluster number starting
1447 ; from 2nd and above, then fully found. Return BX=Phys clus num[log_clusnum]
1448 ; and DI=Phys clus num[log_clusnum-1]
1449 ;----------------------------------------------------------------------------
1450 Look_Extn_Within:
1451 mov si,Cur_Extn_Ptr ; SI-->Current extent ;AN000;
1452 sub cx,es:[si].EH_Logic_Clus_Num ;AN000;
1453 mov di,es:[si].EH_Phys_Clus_Num ; DI = first phys clus num of ;AN000;
1454 ; current extent
1455 add di,cx ; DI = Phys clus num [logic clus num] ;AN000;
1456 mov bx,di ; ;AN000;
1457 dec bx ; BX = Phys clus num [logic clus num -1] ;AN000;
1458 push di ; DI = Phys clus num [logic clus num] ;AN000;
1459 push bx ;AN000;
1460 mov fully_flag,1 ; fully found case ;AN000;
1461 jmp short Look_Make_MRU_Hdr ; make current header to top of OPEN Que ;AN000;
1462
1463
1464 ;--------------------------------------------------------------------------
1465 ; Given extent is above the upper limit of the current extent, but lower than the
1466 ; next extent. In this case, cluters are partially found. Return BX = last
1467 ; logical cluster number of the previous extent and DI = last physical cluster
1468 ; number of the previous extent.
1469 ;----------------------------------------------------------------------------
1470 Look_Proc_Prev:
1471 mov si,Prev_Extn_Ptr ; SI-->Previous extent ;AN000;
1472 mov bx,es:[si].EH_Logic_Clus_Num ; DI = first logic clus num of prev ;AN000;
1473 ; extent
1474 mov di,es:[si].EH_Phys_Clus_Num ; BX = first phys clus num of prev ;AN000;
1475 ; extent
1476 add di,es:[si].EH_Count ; DI = last phys clus number in extent ;AN000;
1477 add bx,es:[si].EH_Count ; BX = last logic clus number in extent
1478 push di ; save clusters to return ;AN000;
1479 push bx ;AN000;
1480 mov fully_flag,0 ; partially found case ;AN000;
1481
1482 ;----------------------------------------------------------------------------
1483 ; Move the current header to the top of the OPEN queue
1484 ;----------------------------------------------------------------------------
1485 Look_Make_MRU_Hdr:
1486 cmp Prev_Hdr_Ptr,-1 ; first header in the Queue ?? ;AN000;
1487 je Look_Dont_Move_To_Top ; yes, dont move to top ;AN000;
1488
1489 CALL MAKE_MRU_HEADER ;AN000;
1490
1491 Look_Dont_Move_To_Top:
1492 cmp fully_flag, 0 ; fully found ?? ;AN000;
1493 je Look_set_carry ; no, partially found ;AN000;
1494 clc ; fully found ;AN000;
1495 jmp short Look_Restore ; restore registers ;AN000;
1496
1497 Look_Set_Carry:
1498 stc ; set flag for partially found ;AN000;
1499
1500 Look_restore:
1501 pop bx ; restore values to be reurned
1502 pop di ; to DOS
1503
1504 Look_Exit:
1505 nop
1506 CALL Check_it
1507 ret ; exit
1508
1509 FK_LOOKUP endp
1510
1511 \f
1512
1513
1514
1515
1516
1517 ;----------------------------------------------------------------
1518 ; PROCEDURE: Fk_Truncate
1519 ;
1520 ; FUNCTION: Using the given physical and logical clutser numbers,
1521 ; find the extent which contains the given cluster number.
1522 ; Delete all clusters folloing the given cluster and the
1523 ; subsequent extents and free the buffers.
1524 ;
1525 ; INPUT: CX = First Physical Cluster Number of the file
1526 ; BX = Logical Cluster Number
1527 ; DL = Drive number
1528 ;
1529 ; OUTPUT: CY = 0 Extents are truncated
1530 ;
1531 ; CY = 1 Extent no found DI = 0
1532 ;
1533 ; ROUTINES REFERENCED: Find_File_Header, Find_Extent
1534 ;
1535 ; REVISION HISTORY: New (5/87)
1536 ;
1537 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
1538 ; "Version 4.00 (C) Copyright 1988 Microsoft"
1539 ; "Licensed Material - Property of Microsoft "
1540 ;
1541 ;---------------------------------------------------------------
1542
1543 Fk_TRUNCATE PROC FAR
1544
1545 push cs ; establish addressability ;AN000;
1546 pop ds ; DS --> code segment ;AN000;
1547 assume ds:Cseg_Seek ;AN000;
1548 mov es, Seek_Name_Cache_Seg ; setup cache buff segment register ;AN000;
1549 assume es:Cseg_Init ; ES --> cache buffer segment ;AN000;
1550 mov First_Phys_Clusnum,cx ; save phys cluster number ;AN000;
1551 mov Logical_ClusNum,bx ;AN000;
1552 mov func_cod,al
1553
1554 ;--------------------------------------------------------------------------
1555 ; Search for Drive Cache buffer using Drive ID in DL
1556 ;--------------------------------------------------------------------------
1557 CALL FIND_DRIVE_HEADER ; get drive buffer ;AN000;
1558 jnc Trunc_search_hdr ; if found, search for file header ;AN000;
1559 jmp Trunc_Exit ; if not found, error ;AN000;
1560 ;AN000;
1561 ;--------------------------------------------------------------------------
1562 ; Search for a header in the OPEN Queue using given physical clusternum
1563 ;--------------------------------------------------------------------------
1564 Trunc_Search_Hdr:
1565 inc es:[di].Extent_Count ; ;***;
1566 mov si,es:[di].MRU_Hdr_Ptr ; SI-->first header in the ;AN000;
1567 ; in the OPEN Queue
1568 mov cx,First_Phys_Clusnum ; CX = Physical Cluster number ;AN000;
1569
1570 CALL FIND_FILE_HEADER ; find file header in OPEN Queue ;AN000;
1571 jnc Trunc_Find_extent ; if found, get extent ;AN000;
1572
1573 ;--------------------------------------------------------------------------
1574 ; If the header is not found, create a new header and make it as MRU header
1575 ; insert first physical cluster number in the header
1576 ;--------------------------------------------------------------------------
1577 CALL MAKE_NEW_HEADER ; make new header ;AN000;
1578 clc ;AN000;
1579 jmp Trunc_exit ; exit ;AN000;
1580
1581
1582 ;--------------------------------------------------------------------------
1583 ; Header is found. Next search for the extent which contains the
1584 ; given logical cluster number.
1585 ;--------------------------------------------------------------------------
1586 Trunc_Find_Extent: ; ;AN000;
1587 mov Cur_Hdr_Ptr,di ; save current pointer ;AN000;
1588 mov si,es:[di].FH_Next_Extn_Ptr ; SI-->first extent in the ;AN000;
1589 ; current header
1590 cmp si, -1 ; any extent under this header ?? ;AN000;
1591 je trunc_no_extent ; none, exit ;AN000;
1592 mov cx,Logical_Clusnum ; CX = given logical cluster number ;AN000;
1593
1594 CALL FIND_EXTENT ; find the extent ;AN000;
1595 jnc Trunc_shrink_extent ; found extent ?? ;AN000;
1596
1597 Trunc_No_Extent: ; extent not found
1598 xor di,di ; no, return DI = 0 ;AN000;
1599 clc ; clear carry
1600 jmp Trunc_exit ; exit ;AN000;
1601
1602
1603
1604 ;--------------------------------------------------------------------------
1605 ; Found extent. Shrink the current extent and delete all subsequent extents.
1606 ; If the given logic clus num is the first cluster number in current extent,
1607 ; then delete the current extent and the subsequent ones.
1608 ; DI--->Extent found (starting extent)
1609 ;--------------------------------------------------------------------------
1610 Trunc_Shrink_Extent:
1611 mov bx,Logical_Clusnum ;AN000;
1612 cmp bx,es:[di].EH_Logic_Clus_Num ; first logic cluster match ?? ;AN000;
1613 jne shrink_cur_extent ; no, shrink current extent ;AN000;
1614
1615 ;--------------------------------------------------------------------------
1616 ; First logical clus num matched. mark previous header or extent as last
1617 ; DI--->Extent found (starting extent)
1618 ;--------------------------------------------------------------------------
1619 mov si,es:[di].EH_Prev_Extn_Ptr ; SI-->Previous extent ;AN000;
1620 cmp si, -1 ; any previous extent ?? ;AN000;
1621 je trunc_no_prev ; no, jump ;AN000;
1622 mov es:[si].EH_Next_Extn_Ptr,-1 ; mark previous extent as last extn ;AN000;
1623 mov si,di ; save the current extent ptr ;AN000;
1624 mov cx, 0 ; CX = buffer release counter ;AN000;
1625 jmp trunc_more ; release successive extents ;AN000;
1626
1627 ;--------------------------------------------------------------------------
1628 ; Previous one is header. Mark so that there is no extents under it
1629 ;--------------------------------------------------------------------------
1630 Trunc_No_Prev:
1631 mov si,Cur_Hdr_Ptr ; get current header ;AN000;
1632 mov es:[si].FH_Next_Extn_Ptr,-1 ; mark header for no extent ;AN000;
1633 mov es:[si].FH_MRU_Extn_Ptr, -1
1634 mov si,di ; save the current extent ptr ;AN000;
1635 mov cx, 0 ; CX = buffer release counter ;AN000;;AN000;
1636 jmp short trunc_more ; release the extent ;AN000;
1637
1638
1639 Shrink_Cur_Extent:
1640 sub bx,es:[di].EH_Logic_Clus_Num ; compute the amount to shrunk ;AN000;
1641 dec bx ;AN000;
1642 mov es:[di].EH_Count,bx ; save it in count to shrink extent ;AN000;
1643
1644 ;--------------------------------------------------------------------------
1645 ; Mark the current extent as the last extent and delete subsequent extents.
1646 ;--------------------------------------------------------------------------
1647 mov si,es:[di].EH_Next_Extn_Ptr ; SI-->Next extent ;AN000;
1648 cmp si,-1 ; current extent last extent ?? ;AN000;
1649 jne Trunc_Last_extent
1650 jmp Trunc_Make_MRU_Hdr ; YES, In this case no subsequent ;AN000;
1651 ; extents left to delete.
1652 Trunc_Last_Extent:
1653 mov es:[di].EH_Next_Extn_Ptr, -1 ; NO, mark last extent ;AN000;
1654 xor cx,cx ;AN000;
1655
1656 ;--------------------------------------------------------------------------
1657 ; Remove extents and release the buffer
1658 ; SI--->Current extent
1659 ;--------------------------------------------------------------------------
1660 Trunc_More:
1661 push si ; save the beginning of first ;AN000;
1662 ; extent to be deleted
1663 TRUNC_LOOP: ; loop for subsequent extents
1664 mov ax, -2 ; mark current extent as free ;AN000;
1665 mov es:[si],ax ; discontinuous free areas ;AN000;
1666 add cx, SIZE Extent_Header ; add size of extent ;AN000;
1667
1668 mov ax,es:[si].EH_Next_LRU_Ptr ; AX = address of Next LRU extent
1669 cmp ax, -1 ; any next LRU extent??
1670 jne Trunc_Set_Next_LRU ; yes - there is a next LRU extent
1671
1672 ;-----------------------------------------------------------------------------
1673 ; No - this is the LRU extent
1674 ;-----------------------------------------------------------------------------
1675 mov di,es:[si].EH_Prev_LRU_Ptr ; no - DI=address of previous LRU extent
1676 cmp di, -1 ; any prev LRU extent ??
1677 je Trunc_Mark_Prev_Hdr ; no - previous is header
1678 mov es:[di].EH_Next_LRU_Ptr, -1 ; yes - mark previous extnt LRU extent
1679 jmp short Trunc_Chk_Next_ext ; no - check next adj extent
1680
1681 Trunc_Mark_Prev_Hdr:
1682 mov di, Cur_Hdr_Ptr ; DI = address of current header
1683 mov es:[di].FH_Next_Extn_Ptr,-1 ; mark header for no extent ;AN000;
1684 mov es:[di].FH_MRU_Extn_Ptr, -1
1685 jmp short Trunc_Chk_Next_Ext ; look for next extent
1686
1687 ;-----------------------------------------------------------------------------
1688 ; There is a next LRU extent AX-->Next_LRU_Extent
1689 ;-----------------------------------------------------------------------------
1690 Trunc_Set_Next_LRU:
1691 mov di,es:[si].EH_Prev_LRU_Ptr ; DI = address of previous LRU extent
1692 cmp di, -1 ; any previous LRU extent ??
1693 jne Trunc_Set_Prev_LRU ; yes - connect prev LRU to Next LRU
1694
1695 mov di, Cur_Hdr_Ptr ; DI = address of current header
1696 mov es:[di].FH_MRU_Extn_Ptr, ax ; Connect next LRU extent to Hdr
1697 push si ; save current extent
1698 mov si,ax
1699 mov es:[si].EH_Prev_LRU_Ptr, -1 ; mark no previous extent
1700 pop si ; resetore current extent
1701 jmp short Trunc_Chk_Next_Ext
1702
1703
1704 Trunc_Set_Prev_LRU: ; DI-->Previous LRU extent
1705 mov es:[di].EH_Next_LRU_Ptr,ax ; connect previous LRU to Next LRU extent
1706 push si ; save Current extent
1707 mov si,ax ; SI-->Next LRU extent
1708 mov es:[si].EH_Prev_LRU_Ptr, di ; set previous LRU header address
1709 pop si ; get current extent
1710
1711
1712 Trunc_Chk_Next_Ext: ; SI-->Current extent
1713 mov ax,es:[si].EH_Next_Extn_Ptr ; AX-->next extent ;AN000;
1714 cmp ax, -1 ; last extent ? ;AN000;
1715 je Trunc_Update_Free_Size ; yes, jump ;AN000;
1716
1717 mov es:[si].FH_Next_Hdr_Ptr,ax ; connect freed buffers togther ;AN000;
1718 mov si,ax ; SI-->next extent ;AN000;
1719 jmp Trunc_Loop ; delete next extent ;AN000;
1720
1721 ;-------------------------------------------------------------------------
1722 ; Update free size in the File header and connect the FREE_Ptr to the first
1723 ; extent released and connect the old Free_Ptr to end of the last extent
1724 ; SI--->Current extent
1725 ;-------------------------------------------------------------------------
1726 Trunc_Update_Free_Size: ; SI-->Last extent released
1727 mov di,Drive_Hdr_Ptr ; DI-->Drive header ;AN000;
1728 add es:[di].Free_Size,cx ; update free area in drive header ;AN000;
1729
1730 Trunc_Join_Free_Area:
1731 ; At this point SI-->Last extent
1732 mov ax,es:[di].Free_Ptr ;AN000;
1733 mov es:[si].EH_Next_Extn_Ptr,ax ; connect last extent under this ;AN000;
1734 ; header to the Free area ;AN000;
1735 pop ax ; beginning of truncated extent ;AN000;
1736 mov es:[di].Free_Ptr,ax ; connect current extent to ;AN000;
1737 ; the beginning of truncated extent
1738
1739 ;--------------------------------------------------------------------------
1740 ; Make the Current header MRU header ( move current header to top of current Q)
1741 ;--------------------------------------------------------------------------
1742 Trunc_make_MRU_Hdr:
1743 cmp Prev_Hdr_Ptr,-1 ; first header in the Queue?? ;AN000;
1744 jne Trunc_move_Hdr
1745 clc
1746 jmp short Trunc_Exit ; yes, dont move to top ;AN000;
1747
1748 Trunc_move_Hdr:
1749 CALL MAKE_MRU_HEADER ; move header to TOP of the Queue ;AN000;
1750 clc
1751
1752 Trunc_Exit:
1753 CALL Check_it
1754 ret ; return ;AN000;
1755
1756 FK_TRUNCATE ENDP
1757
1758
1759
1760 \f
1761
1762
1763
1764
1765 ;-----------------------------------------------------------------------------
1766 ; Procedure: PURGE_BUFFERS
1767 ;
1768 ; Function: Reset both extent and name cache buffers of a specific
1769 ; drive id
1770 ;
1771 ; Input: DL = drive ID
1772 ;
1773 ; Output: Buffers are initialized
1774 ;
1775 ; REVISION HISTORY: New (5/87)
1776 ;
1777 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
1778 ; "Version 4.00 (C) Copyright 1988 Microsoft"
1779 ; "Licensed Material - Property of Microsoft "
1780 ;
1781 ;-----------------------------------------------------------------------------
1782
1783 FK_PURGE PROC FAR ; Purge Cache buffers
1784
1785 push cs
1786 pop ds ; DS=Code seg id used for addressing
1787 ASSUME ds:Cseg_Seek ; local variables ;AN000;
1788
1789 mov si,Seek_Extent_Drive_Buff ; SI-->beginning of extent drive ;AN000;
1790 mov es,Seek_Name_Cache_Seg ; ES = addressability to Cseg_Init ;AN000;
1791 ASSUME es:Cseg_Init ; ;AN000;
1792 mov cx,Seek_Num_Of_drives ; number of drives
1793
1794 Main_Loop2: ; ES:SI-->cache buffer
1795 mov ax,es:[si].Drive_Number ; get drive id
1796 cmp al,dl ; drive id found ??
1797 je purge_buffer ; yes - purge drive id buffer
1798 mov ax, size Drive_Header ; ax size of drive heder
1799 add ax, es:[si].Buff_Size ; ax = offset to next header
1800 add si,ax ; (2/11)SI-->next drive header ;AN000;
1801 LOOP main_loop2 ; try next header
1802
1803 Purge_Buffer: ; SI-->drive header
1804 mov es:[si].MRU_Hdr_Ptr,-1 ; Make OPEN QUEUE empty ;AN000;
1805 mov es:[si].CLOSE_Ptr,-1 ; Make CLOSE QUEUE empty ;AN000;
1806 mov cx,es:[si].BUFF_size ; drive extent cache size ;AN000;
1807 mov es:[si].FREE_Size,cx ; set drive free buffer size ;AN000;
1808 mov ax,si
1809 add ax, size Drive_Header ; ax = size of drive header
1810 mov es:[si].FREE_Ptr,ax ; set Free buffer address
1811
1812 ; Makesure to fill extent cache buffer with zeros. Otherwise, Free Mark left
1813 ; previous run will generate illegal Free_Buff pointer.
1814 mov al,0
1815 add si, size Drive_Header ; SI-->first extent area
1816 Ext_loop: ; fill extent cahe buffer with zeros
1817 mov es:[si],al ; CX = extent cache size
1818 inc si ; next byte
1819 Loop Ext_Loop ; make it zero
1820
1821 FK_Exit:
1822 clc
1823 CALL Check_it
1824 ret ;AN000;
1825
1826 FK_PURGE ENDP
1827
1828
1829
1830
1831 \f
1832
1833
1834 ;----------------------------------------------------------------------
1835 ; ******* SUPPORT ROUTINES *******
1836 ;----------------------------------------------------------------------
1837 ;
1838 ;----------------------------------------------------------------------
1839 ; PROCEDURE: Find_Drive_Header
1840 ;
1841 ; FUNCTION: Find starting address of drive header in extent Cache Buffer using
1842 ; drive ID in DL
1843 ;
1844 ; INPUT: DL = drive id
1845 ; Extent_Drive_Buff (Ptr to the beginning of extent buffer)
1846 ; ES--> Cache Buffer Segment
1847 ;
1848 ; OUTPUT: If Carry = 0 DI --> Drive header
1849 ; Drive_Hdr_Ptr = address of drive header
1850 ;
1851 ; If Carry = 1 Drive buffer not found
1852 ;
1853 ; NOTE: If drive id in DL is same as the drive id in previous request,
1854 ; no need to search the drive header. Use the previous drive header
1855 ;
1856 ;----------------------------------------------------------------------
1857
1858 FIND_DRIVE_HEADER PROC NEAR
1859
1860 mov di,Drive_Hdr_Ptr ; DI-->address of prev drive header
1861 cmp drv_id,dl ; drive id same as previous drive id (1/11/88)
1862 jne Search_drv_hdr ; no - search drive header
1863 clc ; yes - dont search
1864 jmp short drive_exit ; exit
1865
1866 Search_Drv_Hdr:
1867 mov cx,Seek_Num_of_Drives ; get number of drives ;AN000;
1868 mov si,Seek_Extent_Drive_Buff ; SI-->start of extend drive hdr ;AN000;
1869
1870 Drive_Loop:
1871 mov al,es:[si] ; get drive ID from cache drive hdr ;AN000;
1872 cmp al,dl ; found ?? ;AN000;
1873 je drive_buff_found ; yes, exit ;AN000;
1874 cmp es:[si].Next_Drv_Hdr_Ptr,-1 ; last header ?? ;AN000;
1875 je drive_Buff_not_found ; yes - drive header not found ;AN000;
1876 mov si,es:[si].Next_Drv_Hdr_Ptr ; SI-->next drive header ;AN000;
1877 dec cx ; update drive count ;AN000;
1878 jz drive_Buff_not_found ; last drive ;AN000;
1879 jmp drive_Loop ; search for more ;AN000;
1880
1881 Drive_Buff_Not_Found: ; drive buffer not found
1882 stc ; set carry flag ;AN000;
1883 jmp short Drive_Exit ; exit ;AN000;
1884
1885 Drive_Buff_Found: ; drive buffer found
1886 mov drv_id,dl ; save drive id
1887 mov Drive_Hdr_ptr,si ; save drive buffer pointer ;AN000;
1888 mov di,si ; DI-->drive header ;AN000;
1889 clc ;AN000;
1890
1891 Drive_Exit: ; return
1892 ret ;AN000;
1893
1894 FIND_DRIVE_HEADER endp
1895
1896 \f
1897
1898
1899
1900 ;---------------------------------------------------------------
1901 ; PROCEDURE: Find_File_Header
1902 ;
1903 ; FUNCTION: Find starting address of the specific file header with
1904 ; a specific starting physical cluster number. Also
1905 ; determine the type of header found.
1906 ;
1907 ; INPUT: SI --> First header in the queue
1908 ; CX = First Physical Cluster Number (file id)
1909 ; ES--> Cache Buffer Segment id
1910 ;
1911 ; OUTPUT: If Carry = 0 DI --> header found
1912 ; Cur_Hdr_Ptr = address of header found
1913 ; Prev_Hdr_Ptr = address of previous header
1914 ;
1915 ; Prev_Hdr_Ptr = -1 No Previous Header
1916 ;
1917 ; hdr_flag - Type of header found
1918 ; = 0 Header between first & last in queue
1919 ; = 1 Single header in the queue
1920 ; = 2 First header in the queue
1921 ; = 3 LRU (Last) header in the queue
1922 ;
1923 ; If Carry = 1 Header not found
1924 ;
1925 ;---------------------------------------------------------------
1926
1927 FIND_FILE_HEADER PROC NEAR
1928
1929 push si ; save registers ;AN000;
1930 push cx ;AN000;
1931
1932 cmp si, -1 ; any file header in this queue ?? ;AN000;
1933 jne Fh_search_hdr ; yes, search for it ;AN000;
1934 stc ; no, set carry and return ;AN000;
1935 jmp short Fh_Exit ;AN000;
1936
1937 Fh_Search_Hdr:
1938 mov Prev_Hdr_Ptr,-1 ; reset flags ;AN000;
1939 mov Hdr_Flag, 0 ; reset header type flag ;AN000;
1940
1941 Fh_Loop1:
1942 cmp es:[si].FH_Phys_Clus_Num,CX ; check current header ;AN000;
1943 jne Fh_next_header ; if not found branch ;AN000;
1944 mov di,si ; DI --> header found ;AN000;
1945 mov Cur_Hdr_Ptr,si ; save current Hdr pointer ;AN000;
1946 jmp short Fh_header_found ; then take exit ;AN000;
1947
1948 Fh_Next_header: ; else try next header
1949 mov ax,es:[si].FH_Next_Hdr_ptr ; get address of next header ;AN000;
1950 cmp ax,-1 ; is this last header?? ;AN000;
1951 je Fh_not_found ; yes, header no found ;AN000;
1952
1953 mov Prev_Hdr_Ptr,si ; save previous header ;AN000;
1954 mov si,ax ; SI= next header ;AN000;
1955 jmp Fh_Loop1 ; check next header ;AN000;
1956
1957 ; Determine the type of header found
1958 Fh_Header_Found: ; header found
1959 cmp Prev_Hdr_Ptr, -1 ; any previous headers ?? ;AN000;;AN000;
1960 jne Fh_LRU ; yes, jump ;AN000;
1961 cmp es:[si].Fh_Next_Hdr_Ptr, -1 ; any headers following this hdr ?? ;AN000;
1962 jne Fh_First ; yes, jump ;AN000;
1963 mov Hdr_Flag, 1 ; single header in the queue ;AN000;
1964 clc ; ;AN000;
1965 jmp short FH_Exit ; exit ;AN000;
1966
1967 Fh_First:
1968 mov Hdr_Flag, 2 ; Header found is first header in QUE ;AN000;
1969 clc ; set flag ;AN000;
1970 jmp short FH_Exit ; exit ;AN000;
1971
1972 Fh_LRU:
1973 cmp es:[si].Fh_Next_Hdr_Ptr, -1 ; Last header in the queue ?? ;AN000;
1974 jne Fh_middle_hdr ; no, Header between first and last ;AN000;
1975 mov Hdr_Flag, 3 ; set flag indicating LRU header ;AN000;
1976 clc ;AN000;
1977 jmp short Fh_Exit ; exit ;AN000;
1978 ;AN000;
1979 Fh_Middle_Hdr:
1980 clc ;AN000;
1981 jmp short Fh_Exit ; exit ;AN000;
1982
1983 Fh_Not_found:
1984 stc ; header not found ;AN000;
1985
1986 Fh_Exit:
1987 pop cx ;AN000;
1988 pop si ;AN000;
1989 ret ; return ;AN000;
1990
1991 FIND_FILE_HEADER ENDP
1992
1993 \f
1994
1995
1996
1997
1998
1999 ;---------------------------------------------------------------
2000 ; PROCEDURE: Find_Extent
2001 ;
2002 ; FUNCTION: Find starting address of the specific Extent that contains
2003 ; the given logical cluster mumber.
2004 ; Verifiy that the extent found is the LRU Extent.
2005 ;
2006 ; INPUT: SI --> First Extent under current queue
2007 ; CX = Logical Cluster number to be searched
2008 ; ES--> Cache Buffer Segment Id
2009 ;
2010 ; OUTPUT: If Carry = 0 DI --> Extent found
2011 ; Cur_Extn_Ptr = address of extent found
2012 ; Prev_Extn_Ptr = address of previous extent
2013 ; IF Extn_Flag = 1, extent found is the only
2014 ; extent under this header
2015 ;
2016 ; If Carry = 1 Extent not found
2017 ;
2018 ; REVISION HISTORY: New (5/87)
2019 ;---------------------------------------------------------------
2020
2021 FIND_EXTENT PROC NEAR
2022
2023 push si ; save registers ;AN000;
2024 push cx ;AN000;
2025 ;AN000;
2026 mov Prev_Extn_Ptr,-1 ; reset flags
2027 mov Extn_Flag, 0 ;AN000;
2028 ;AN000;
2029 Eh_Loop1:
2030 cmp cx,es:[si].EH_Logic_Clus_Num ;AN000;
2031 jl Eh_Next_Extn ; try next extent ;AN000;
2032 mov ax,es:[si].EH_Count ; get range ;AN000;
2033 add ax,es:[si].EH_Logic_Clus_Num ; get upper range ;AN000;
2034 cmp cx,ax ;AN000;
2035 jg Eh_Next_Extn ; try next extent ;AN000;
2036
2037 Eh_Not_LRU:
2038 mov di,si ; DI --> Extent found ;AN000;
2039 mov Cur_Extn_Ptr,si ; save current extent pointer ;AN000;
2040 clc ; set flag ;AN000;
2041 jmp Eh_Extn_found ; then take exit ;AN000;
2042
2043 Eh_Next_Extn: ; else try next extent
2044 mov ax,es:[si].EH_Next_Extn_ptr ; get address of next extent ;AN000;
2045 cmp ax,-1 ; is this last extent?? ;AN000;
2046 je Eh_Not_Found ; yes, exit ;AN000;
2047 mov Prev_Extn_Ptr,si ; save previous extent ;AN000;
2048 mov si,ax ; SI=next extent ;AN000;
2049 jmp Eh_Loop1 ; check next extent ;AN000;
2050
2051 stc ; else set flag for extent not found ;AN000;
2052 jmp short Eh_Exit ; then exit ;AN000;
2053
2054 Eh_Extn_Found: ; Extent found
2055 cmp Prev_Extn_Ptr, -1 ; any previous extents ?? ;AN000;
2056 jne Eh_yes ; yes, jump ;AN000;
2057 cmp es:[di].Eh_Next_Extn_Ptr, -1 ; any extents following this extents ?? ;AN000;
2058 jne Eh_yes ; yes, jump ;AN000;
2059 mov Extn_Flag, 1 ; no, set flag indicating single extnt ;AN000;
2060 ; in the queue
2061 Eh_Yes:
2062 clc ;AN000;
2063 jmp short Eh_Exit ; exit ;AN000;
2064
2065 Eh_Not_Found: ; extent not found
2066 stc ;AN000;
2067
2068 Eh_Exit:
2069 pop cx ;AN000;
2070 pop si ;AN000;
2071
2072 ret ; return ;AN000;
2073
2074 FIND_EXTENT ENDP
2075
2076 \f
2077
2078
2079
2080
2081 ;---------------------------------------------------------------------------
2082 ; PROCEDURE: FIND_CLUSTER_LOCATION
2083 ;
2084 ; FUNCTION: Find starting address of a specific extent which identifies
2085 ; the relative position of the new cluster in the queue.
2086 ;
2087 ; INPUT: SI--> First extent under current header
2088 ; ES--> Cache Buffer Segment
2089 ;
2090 ; OUTPUT: If Carry = 0 Cluster location identified
2091 ; Cur_Extn_Ptr = Current extent
2092 ; Prev_Extn_Ptr = Previous extent
2093 ;
2094 ; Find_Flag = 1 Clusters are contiguous in
2095 ; the LO end of the current extent
2096 ;
2097 ; Find_Flag = 2 Clusters are contiguous in
2098 ; the HI end of the current extent
2099 ;
2100 ; Find_Flag = 3 Clusters belong to a new
2101 ; extent between current and previous
2102 ; extent
2103 ;
2104 ; Find_Flag = 4 Clusters belong to a new
2105 ; extent at the end of the queue
2106 ; Cur_Extn_Ptr-->Last extent in queue
2107 ;
2108 ; Find_Flag = 5 Clusters belong to a new
2109 ; extent between current and next
2110 ;
2111 ; If Carry = 1 Clusters already exist
2112 ;
2113 ;-----------------------------------------------------------------------
2114
2115
2116 FIND_CLUSTER_LOCATION PROC NEAR
2117
2118 ;--------------------------------------------------------------------------
2119 ; Check to see that the given logical cluster number falls within the
2120 ; current extent. If true it is an error.
2121 ;--------------------------------------------------------------------------
2122 push di
2123 mov Prev_Extn_Ptr, -1 ; initialize the flag ;AN000;
2124 mov Cur_Extn_Ptr,si ; SI-->First extent under header ;AN000;
2125 mov Find_Flag, -1 ; reset with illegal value
2126 ;AN000;
2127 Fe_LOOP1:
2128 mov ax,es:[si].EH_Logic_Clus_Num ; AX = starting logi clus number ;AN000;
2129 mov bx,Logical_Clusnum ; BX = given logical clus num ;AN000;
2130 cmp bx,ax ; LOW end ?? ;AN000;
2131 jl Fe_Chk_Low_end ; yes - jump ;AN000;
2132 add ax,es:[si].EH_Count ; ending logical clus number ;AN000;
2133 cmp bx,ax ; HIGH end ?? ;AN000;
2134 jg Fe_Chk_High_end ; yes - jump ;AN000;
2135
2136 ;--------------------------------------------------------------------------
2137 ; Found the given logical cluster number within the extent.
2138 ; This is a normal condition. In this case the clusters wont be insterted.
2139 ;--------------------------------------------------------------------------
2140 stc ; set flag
2141 jmp Fe_Extent_Exit ; return ;AN000;
2142
2143
2144 ;--------------------------------------------------------------------------
2145 ; If not in the extent, then see the logical clus number has continuity at
2146 ; LOW end of the current extent.
2147 ;--------------------------------------------------------------------------
2148 Fe_Chk_LOW_END:
2149 mov ax,es:[si].EH_Logic_Clus_Num ; starting logi clus number ;AN000;
2150 dec ax ; one below the lowest ;AN000;
2151 mov bx,Logical_Clusnum ; BX = given logical clus num ;AN000;
2152 cmp bx,ax ; contiguous at LOW end ?? ;AN000;
2153 jl Fe_Curr_Prev ; no, build a new extent between ;AN000;
2154 ; current and previous
2155 ; Logical clus has continuity at low end. Now check physical cluster number
2156 ; foe continuity.
2157 mov ax,es:[si].EH_Phys_Clus_Num ; starting Phys clus number ;AN000;
2158 dec ax ; one below the lowest in the extent ;AN000;
2159 mov bx,Physical_Clusnum ; BX = given logical clus num ;AN000;
2160 cmp bx,ax ; within low end ?? ;AN000;
2161 jne Fe_Curr_Prev ; no, create a new extent between ;AN000;
2162 ; current and previous extent
2163 mov Find_Flag,1 ; yes, set flag for LOW END continuity ;AN000;
2164 jmp Fe_Extent_found ; then RETURN ;AN000;
2165
2166
2167 ;--------------------------------------------------------------------------
2168 ; Check the logical clus number has continuity at High end of the current
2169 ; extent cluster range. Check physical cluster number has continuity at the
2170 ; high end. If true, check the first logical and phys cluster number is the
2171 ; the same as this one. In this case clusters exist and therefore wont be
2172 ; insterted.
2173 ;--------------------------------------------------------------------------
2174 Fe_CHK_HIGH_END:
2175 mov ax,es:[si].EH_Logic_Clus_Num ; starting logi clus number ;AN000;
2176 add ax,es:[si].EH_Count ; ending logical clus number ;AN000;
2177 inc ax ;AN000;
2178 mov bx,Logical_Clusnum ; BX = given logical clus num ;AN000;
2179 cmp bx,ax ; within high end ?? ;AN000;
2180 jg Fe_Chk_Next_Extent ; no, check next extent ;AN000;
2181
2182 ; Logical clus num has high end continuity, Check the Physical cluster number
2183 ; for continuity.
2184 mov ax,es:[si].EH_Phys_Clus_Num ; starting phys clus number ;AN000;
2185 add ax,es:[si].EH_Count ; ending phys clus number ;AN000;
2186 inc ax ;AN000;
2187 mov bx,Physical_Clusnum ; BX = given logical clus num ;AN000;
2188 cmp bx,ax ; within high end ?? ;AN000;
2189 jne Fe_Chk_Next_Extent ; no - check next extent ;AN000;
2190 ;
2191 ; Yes - check first logical and physical cluster number of next extent
2192 mov di,es:[si].EH_Next_Extn_Ptr ; get address of next extent ;AN000;
2193 cmp di, -1 ; any next extent ??
2194 je Fe_High_End ; none - jump
2195 mov ax,es:[di].EH_Logic_Clus_Num ; starting logi clus number ;AN000;
2196 cmp ax,Logical_Clusnum ; logical cluster matches ??
2197 jne Fe_high_end ; no - jump
2198 mov ax,es:[di].EH_Phys_Clus_Num ; starting phys clus number ;AN000;
2199 cmp ax,Physical_Clusnum ; physical cluster match ??
2200 jne Fe_High_End ; no -jump
2201 stc ; clusters already exist in next extent
2202 jmp short Fe_Extent_Exit ; return ;AN000;
2203
2204 Fe_High_End:
2205 mov Find_Flag,2 ; set flag for HIGH end continuity ;AN000;
2206 jmp short Fe_Extent_found ; then RETURN ;AN000;
2207
2208
2209 Fe_Chk_Cur_Next:
2210 cmp es:[si].EH_Next_Extn_Ptr, -1 ; Current extent last extent ?? ;AN000;
2211 je Fe_flag_4 ; yes, set flag-4 ;AN000;
2212
2213 mov Find_Flag,5 ; set flag for new extent between ;AN000;
2214 jmp short Fe_Extent_Found ; current and next extent ;AN000;
2215
2216 Fe_Flag_4:
2217 mov Find_Flag,4 ; set flag for new extent at the ;AN000;
2218 jmp short Fe_Extent_Found ; bottom end of current queue ;AN000;
2219
2220 ;--------------------------------------------------------------------------
2221 ; Given cluster number has no continuity but must stay between current extent
2222 ; and previous extent
2223 ;--------------------------------------------------------------------------
2224 Fe_CURR_PREV:
2225 mov Find_Flag,3 ; set flag for between current and prev ;AN000;
2226 jmp short Fe_Extent_found ; then RETURN ;AN000;
2227
2228
2229 ;--------------------------------------------------------------------------
2230 ; Given cluster number has no continuity. Try the next extent.
2231 ;--------------------------------------------------------------------------
2232 Fe_Chk_NEXT_EXTENT: ; else try next extent
2233 mov ax,es:[si].EH_Next_Extn_Ptr ; get address of next extent ;AN000;
2234 cmp ax,-1 ; is this last extent ?? ;AN000;
2235 je Extent_at_Bottom ; yes, Clustr belongs to a new ;AN000;
2236 ; extent at the bottom ;AN000;
2237 mov Prev_Extn_Ptr,si ; save current extend as previous extnt
2238 mov si,ax ; SI-->Next extent ;AN000;
2239 mov Cur_Extn_Ptr, si ; save new extent as cur extent ;AN000;
2240 jmp Fe_Loop1 ; check next extent ;AN000;
2241
2242
2243 ;--------------------------------------------------------------------------
2244 ; Given cluster number has no continuity but stays in a new extent at
2245 ; bottom (last) of the current queue.
2246 ;--------------------------------------------------------------------------
2247 Extent_AT_BOTTOM:
2248 mov Find_Flag,4 ; else set flag for new extent ;AN000;
2249
2250 Fe_Extent_Found:
2251 clc ;AN000;
2252
2253 Fe_Extent_Exit:
2254 pop di
2255
2256 RET ; exit ;AN000;
2257
2258
2259 FIND_CLUSTER_LOCATION ENDP
2260
2261 \f
2262
2263
2264
2265
2266
2267 ;-----------------------------------------------------------------------
2268 ; PROCEDURE: FIND_LRU_HEADER
2269 ;
2270 ; FUNCTION: Find address of the LRU header in the current queue
2271 ;
2272 ; INPUT: SI --> First header in the current queue
2273 ; ES--> Cache Buffer Segment
2274 ;
2275 ; OUTPUT: DI --> LRU header found
2276 ;
2277 ; LRU_Prev_Hdr = Previous header address
2278 ; LRU_Hdr = Address of LRU header found
2279 ; If Hdr_Flag = 1 - Header found is only header in the queue
2280 ;
2281 ;-----------------------------------------------------------------------
2282
2283 FIND_LRU_HEADER PROC NEAR
2284
2285 push bx ;AN000;
2286 mov hdr_flag,0 ; initilialize flags ;AN000;
2287 mov LRU_Prev_Hdr, -1 ; ;AN000;
2288
2289 Flh_Loop1:
2290 cmp es:[si].FH_Next_Hdr_Ptr,-1 ; current header is last hdr ? ;AN000;
2291 jne Flh_next_header ; if not check next header ;AN000;
2292 mov di,si ; DI --> LRU header found ;AN000;
2293 mov LRU_Hdr,si ; save it ;AN000;
2294 jmp short Flh_header_found ; then take exit ;AN000;
2295
2296 Flh_Next_Header: ; else try next header
2297 mov LRU_Prev_Hdr,si ; save previous header address ;AN000;
2298 mov si,es:[si].FH_Next_Hdr_ptr ;AN000;
2299 jmp Flh_Loop1 ; check next header ;AN000;
2300
2301 Flh_Header_Found:
2302 cmp LRU_Prev_Hdr, -1 ; any previous header ?? ;AN000;
2303 je F1h_Set_Flag ; no, set flag ;AN000;
2304 clc ; yes ;AN000;
2305 jmp short F1H_Exit ; exit ;AN000;
2306
2307 F1h_Set_Flag:
2308 mov hdr_flag,1 ; LRU header is the only hdr in queue ;AN000;
2309 clc ;AN000;
2310
2311 F1h_Exit: ; exit
2312 pop bx ;AN000;
2313
2314 ret ;AN000;
2315
2316 FIND_LRU_HEADER endp
2317 \f
2318
2319
2320
2321 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2322 ; PROCEDURE: FIND_LRU_EXTENT
2323 ;
2324 ; FUNCTION: Find address of LRU Extent under current header
2325 ;
2326 ; INPUT: ES--> Cache Buffer Segment
2327 ; SI--> Header to be searched
2328 ;
2329 ; OUTPUT: If CY = 0 LRU_Prev_Extent = Previous extent to the LRU extent
2330 ; LRU_Extent = LRU extent found
2331 ; Extn_Flag = 1 Extent is the only extent under header
2332 ;
2333 ; If CY = 1 Not found
2334 ;
2335 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2336
2337 FIND_LRU_EXTENT PROC NEAR
2338
2339 mov LRU_Prev_Extent, -1 ; reset flags ;AN000;
2340 mov LRU_Extent, -1 ; ;AN000;
2341 mov Extn_Flag, 0
2342 mov si, es:[si].FH_MRU_Extn_Ptr ; SI--> First extent under header
2343 cmp si, -1 ; any extent under this header ??
2344 jne Fle_Loop1 ; yes - check extent
2345 stc ; no - set flag
2346 jmp Fle_Exit ; exit
2347
2348 Fle_Loop1:
2349 cmp es:[si].EH_Next_LRU_Ptr,-1 ; last extent in the queue??
2350 jne Fle_next_extent ; if not found branch ;AN000;
2351 mov LRU_Extent,si ; save LRU extent address
2352 jmp short Fle_Extend_found ; exit
2353
2354 Fle_Next_Extent: ; else try next extend
2355 mov LRU_Prev_Extent,si ; save previous extent address
2356 mov si,es:[si].EH_Next_LRU_Ptr ; get address of next extent
2357 jmp Fle_Loop1 ; check next extent ;AN000;
2358
2359 Fle_Extend_Found:
2360 cmp LRU_Prev_Extent, -1 ; any previous extent ??
2361 je Fle_Set_Flag ; no - set flag
2362 clc ; ;AN000;
2363 jmp short Fle_Exit
2364
2365 Fle_Set_Flag:
2366 mov Extn_Flag, 1 ; set flag to indicate only flag
2367 clc
2368
2369 Fle_Exit:
2370 ret ; exit ;AN000;
2371
2372 FIND_LRU_EXTENT ENDP
2373
2374
2375 \f
2376
2377
2378
2379
2380 ;----------------------------------------------------------------------
2381 ; PROCEDURE: Make_New_Header
2382 ;
2383 ; FUNCTION: Create a new header in the next available free area.
2384 ; Initialize the new header and make it MRU header ( move it
2385 ; to the top of the queue). If no free space in OPEN queue, delete
2386 ; and extent from the CLOSE queue. If no space in CLOSE queue, then
2387 ; delete an extent from OPEN Queue to make space.
2388 ;
2389 ; INPUT: Drive_Hdr_Ptr - Address of drive header
2390 ; Free_Ptr - Address of FREE area
2391 ; ES--> Cache Buffer Segment
2392 ;
2393 ; OUTPUT: Header is created
2394 ;
2395 ;----------------------------------------------------------------------
2396
2397 MAKE_NEW_HEADER PROC
2398
2399 ; Check if the OPEN Queue was previously empty using two cases. If open queue
2400 ; is empty, then the new header should be marked as first header in the queue.
2401 mov Open_Queue_Flag, 0 ; clear flag open queue empty ;AN000;
2402 mov di,Drive_Hdr_Ptr ;AN000;
2403
2404 ; case - 1
2405 mov ax,es:[di].Free_Size ; FREE size ;AN000;
2406 cmp es:[di].Buff_Size,ax ; both are equal ? ;AN000;
2407 je Make_Set_Entries ; if true, this is the first header ;AN000;
2408
2409 ; case - 2
2410 cmp es:[di].MRU_Hdr_Ptr, -1 ; check for empty mark ;AN000;
2411 je Make_Set_Entries ; yes, set flag queue empty ;AN000;
2412 jmp short Make_Set_Entry2 ; not empty ;AN000;
2413
2414 Make_set_Entries: ; set up File Header entries
2415 ; When creating first header under drive header, mark header as first
2416 ; This flag is set for this purpose.
2417 mov Open_Queue_Flag, 1 ; set flag open queue was empty ;AN000;
2418
2419 Make_Set_Entry2:
2420 CALL FIND_FREE_BUFFER ; Look for some Free area. If none ;AN000;
2421 ;AN000;
2422 mov di,Drive_Hdr_Ptr ; DI-->Drive header ;AN000;
2423 mov ax,es:[di].Free_Ptr ;AN000;
2424 mov New_Hdr_Ptr,ax ; save new Header address
2425 mov ax,es:[di].Free_Size ;AN000;
2426
2427 CALL UPDATE_FREE_AREA ; update Free_Ptr and Free_Size ;AN000;
2428 ; create some free area
2429
2430 ;-----------------------------------------------------------------------------
2431 ; Connect the new header to the Top of the OPEN Queue. If the Queue is
2432 ; previously empty, mark the new header indicating nothing under this header.
2433 ;-----------------------------------------------------------------------------
2434 Join_To_Drive_Buff:
2435 mov di, drive_Hdr_Ptr ; DI-->drive buffer ;AN000;
2436 mov si,New_Hdr_Ptr ;AN000;
2437 mov Cur_Hdr_Ptr, si ; save as current header pointer ;AN000;
2438 mov ax,es:[di].MRU_Hdr_Ptr ; connect current header to ;AN000;
2439 mov es:[si].FH_Next_Hdr_Ptr,ax ; previous MRU header
2440 mov es:[di].MRU_Hdr_Ptr,si ; make new header MRU hdr
2441
2442 ; When a header is created, it should contain no extents
2443 mov es:[si].FH_Next_Extn_Ptr,-1 ; mark header with no extents ;AN000;
2444 mov es:[si].FH_MRU_Extn_Ptr,-1 ; ###mark header with no extents ;AN000;
2445 mov es:[si].FH_Refer_Count,1 ; save starting file reference count ;AN000;
2446 mov ax,First_Phys_Clusnum ;AN000;
2447 mov es:[si].FH_Phys_Clus_Num,ax ; save physical cluster number ;AN000;
2448
2449 cmp Open_Queue_Flag, 1 ; OPEN Queue empty ?? ;AN000;
2450 je Set_Single_Header ; no, jump ;AN000;
2451 clc
2452 ret ;AN000;
2453
2454 Set_Single_Header: ; yes mark new header as last hdr
2455 mov si,New_Hdr_Ptr ;AN000;
2456 mov es:[si].FH_Next_Hdr_Ptr,-1 ; mark as only header ;AN000;
2457 clc
2458 ret ; exit
2459
2460 MAKE_NEW_HEADER ENDP
2461 \f
2462
2463
2464
2465
2466
2467 ;----------------------------------------------------------------------
2468 ; PROCEDURE: Find_Free_Buffer
2469 ;
2470 ; FUNCTION: Find free buffer space. If no free space, delete last extent
2471 ; under last header in the CLOSE queue. If none in CLOSE queue,
2472 ; delete the last extent of the LRU header in the OPEN queue.
2473 ;
2474 ; INPUT: Drive_Hdr_Ptr - Pointer to drive header
2475 ; ES--> Cache Buffer Segment
2476 ;
2477 ; OUTPUT: Released Header or extent buffer space will be addded to the
2478 ; Free area as discontinuous free area. Free size in drive head
2479 ; will be updated.
2480 ;
2481 ; If CARRY = 0
2482 ; Free_Flag: 0 - Free area is continuous
2483 ; 1 - Free area is discontinuous
2484 ;
2485 ; if CARRY = 1 Fatal error ( no free space to spare )
2486 ;
2487 ; NOTE: The deleted buffers have size same as the size of a header or extent.
2488 ; Each buffers first location contains a marker (-2) to indicate that
2489 ; the buffer is a discontinuous buffer. Each buffer is connected to
2490 ; the next dicontinous buffer through the 4th word.
2491 ;
2492 ;----------------------------------------------------------------------
2493
2494 FIND_FREE_BUFFER PROC NEAR
2495
2496 mov di,drive_Hdr_Ptr ; DI-->Drive Header ;AN000;
2497 cmp es:[di].free_size,0 ; any free area left ?? ;AN000;
2498 je Free_Chk_Close_List ; none, check CLOSE queue ;AN000;
2499
2500 mov si,es:[di].Free_Ptr ; check for discontinuous ;AN000;
2501 mov ax, -2 ;AN000;
2502 cmp es:[si], ax ; discontinuous free buffer?? ;AN000;
2503 je Free_Set_One ; yes, set flag for discontinuous
2504
2505 mov Free_Flag,0 ; no, clear flag ;AN000;
2506 clc ;AN000;
2507 jmp Free_Exit
2508
2509 Free_Set_one:
2510 mov Free_Flag,1 ; set flag ;AN000;
2511 clc ;AN000;
2512 jmp Free_exit ; yes, Free space is available ;AN000;
2513 ; exit
2514
2515
2516 ;--------------------------------------------------------------------------
2517 ; No free space , look for space in CLOSE Queue. Search for the LRU header
2518 ; delete the header and any extents under this header.
2519 ;--------------------------------------------------------------------------
2520 Free_Chk_Close_List:
2521 mov si,es:[di].CLOSE_Ptr ; SI-->CLOSE queue ;AN000;
2522 cmp si,-1 ; anything in CLOSE Queue ?? ;AN000;
2523 jne Free_Chk_CLOSE_QUE ; yes - get space from CLOSE queue
2524 jmp short Free_Look_Open_Queue ; if none, make space from OPEN Queue ;AN000;
2525
2526
2527 ; Else get space from CLOSE queue
2528 Free_Chk_Close_QUE: ; SI-->CLOSE queue
2529 mov si,es:[di].CLOSE_Ptr ; select OPEN Queue ;AN000;
2530 CALL FIND_LRU_HEADER ; find LRU header in CLOSE Queue ;AN000;
2531 ; DI-->LRU header
2532
2533 ; Makesure to save all local variables before calling DELETE
2534 ; since, this variables may be altered by DELETE routine.
2535 mov ax,Hdr_Flag
2536 push ax
2537 mov ax,Prev_Hdr_Ptr
2538 push ax
2539 mov ax,Queue_Type
2540 push ax
2541 mov ax,Cur_Hdr_Ptr
2542 push ax
2543 mov ax,First_Phys_Clusnum ; save original first phys from OPEN call
2544 push ax ; in the stack
2545 mov cx,es:[di].FH_Phys_Clus_Num ; CX= starting phys clus num of LRU header
2546 mov From_FreeBuff,1 ; set flag
2547
2548 push ds
2549 mov ax,Cseg_Main
2550 mov ds,ax
2551 assume ds:Cseg_Main
2552 CALL VECTOR_DELETE ; delete the file
2553 pop ds
2554 assume ds:Cseg_Seek
2555
2556 mov From_FreeBuff,0 ; clear flag
2557 mov Free_Flag,1 ; set flag to indicate discontinuous free area
2558 pop ax ; restore first phys clus
2559 mov First_Phys_Clusnum,ax ; save it back where it belongs
2560 pop ax ; restore current header
2561 mov Cur_Hdr_Ptr,ax ; save it back where it belongs
2562 pop ax ; restore current header
2563 mov Queue_Type,ax ; save it back where it belongs
2564 pop ax ; restore current header
2565 mov Prev_Hdr_Ptr,ax ; save it back where it belongs
2566 pop ax ; restore current header
2567 mov Hdr_Flag,ax ; save it back where it belongs
2568 clc
2569 jmp Free_exit ; exit ;AN000;
2570
2571
2572
2573 ;----------------------------------------------------------------------------
2574 ; No space available in CLOSE Queue . Now get some free space from OPEN Queue
2575 ; and add it to the free area.
2576 ;----------------------------------------------------------------------------
2577 Free_Look_Open_Queue:
2578 mov si,es:[di].MRU_Hdr_Ptr ; SI-->First header in OPEN Queue ;AN000;
2579 CALL FIND_LRU_HEADER ; find last header in Queue ;AN000;
2580 ; DI-->last header
2581 mov si,es:[di].FH_MRU_Extn_Ptr ;### SI-->first extent in this header ;AN000;
2582 cmp si, -1 ; any extent under this header ?? ;AN000;
2583 jne Free_Open_Find_Extent ; yes, find last extent ;AN000;
2584
2585 ; if no extents under this header, delete this header and free the space
2586 cmp di,Cur_Hdr_Ptr ; header found is its own header ?? ;AN000;
2587 jne Free_OPen_Mark_Prev ; no - free the header ;AN000;
2588 stc ; Yes - set carry, exit ;AN000;
2589 jmp Free_Exit ; ERROR exit ;AN000;
2590
2591 Free_Open_Mark_Prev: ; mark previous header as LRU before deleting this header
2592 mov si,LRU_Prev_Hdr ; SI-->previous header ;AN000;
2593 mov es:[si].FH_Next_Hdr_Ptr, -1 ; mark previous header as last hdr ;AN000;
2594 jmp Free_Open_Cl_Buffer ;AN000;
2595
2596 Free_Open_Find_Extent:
2597 mov si,di ; SI-->header to be searched
2598 CALL FIND_LRU_EXTENT ; ### find last extent in the header ;AN000;
2599 mov di, LRU_Extent ; DI-->LRU extent
2600 cmp Extn_flag,1 ; Is this the only extent in the queue ? ;AN000;
2601 jne free_Open_prev_extn ; no, mark previous extent as last extn ;AN000;
2602 push di ; save pointer to Last extent ;AN000;
2603 mov di,LRU_Hdr ; DI-->LRU header ;AN000;
2604 mov es:[di].FH_Next_Extn_Ptr,-1 ; mark current HEADER with no extents ;AN000;
2605 mov es:[di].FH_MRU_Extn_Ptr,-1 ; ### mark current HEADER with no extents ;AN000;
2606 pop di ; DI-->LRU extent ;AN000;
2607 jmp Free_Open_Cl_Buffer ; release this extent ;AN000;
2608
2609 ;----------------------------------------------------------------------
2610 ; Mark Previous MRU extent as LRU extent and also connect the previous
2611 ; adjucent extent to the next adjcent extent.
2612 ;----------------------------------------------------------------------
2613 Free_Open_Prev_Extn: ; mark previous MRU extent as LRU extnt
2614 mov si, es:[di].EH_Prev_LRU_Ptr ; no - SI-->Previous adj extent
2615 mov es:[si].EH_Next_LRU_Ptr, -1 ;mark previous extent as last extent ;AN000;
2616
2617 cmp es:[di].EH_Next_Extn_Ptr, -1 ; any next adjucent extent ??
2618 jne OPen_Join_extents ; yes - join previous to next
2619
2620 mov si, es:[di].EH_Prev_Extn_Ptr ; no - SI-->Previous adj extent
2621 cmp si, -1 ; any previous adj extent ??
2622 je Open_Prev_Hdrx ; no - previous is a header
2623 mov es:[si].EH_Next_Extn_Ptr, -1 ; mark previous extent as the last
2624 jmp short Free_Open_Cl_Buffer ; free the current extent
2625
2626 Open_Prev_Hdrx:
2627 push di ; DI-->extent to be deleted
2628 mov di,LRU_Hdr ; DI-->LRU header
2629 mov es:[di].FH_Next_Extn_Ptr, -1 ; mark header with no extents
2630 mov es:[di].FH_MRU_Extn_Ptr, -1 ; mark header with no extents
2631 pop di
2632 jmp short Free_Open_Cl_Buffer ; free current extent
2633
2634 Open_Join_Extents: ; DI-->current extent to be freed
2635 mov si, es:[di].EH_Prev_Extn_Ptr ; no - SI-->Previous adj extent
2636 cmp si, -1 ; any previous extent ??
2637 je Open_Prev_Hdry ; no - previous is a header - join header
2638 ; to extent
2639 mov ax, es:[di].EH_Next_Extn_Ptr ; AX = address of next adjucent extent
2640 mov es:[si].EH_Next_Extn_Ptr,ax ; connect prev adj extent to next adj extent
2641 push di ; save addrs of extent to be deleted
2642 mov di, ax ; SI = address of previous LRU extent
2643 mov es:[di].EH_Prev_Extn_Ptr,si ; address of next LRU extent
2644 pop di ; restore address
2645 jmp short Free_Open_Cl_Buffer ; free the extent
2646
2647 Open_Prev_Hdry:
2648 mov si, LRU_Hdr ; SI-->LRU_Hdr
2649 mov ax, es:[di].EH_Next_Extn_Ptr ; AX = address of next adjucent extent
2650 mov es:[si].FH_Next_Extn_Ptr,ax ; connect hdr to next adj extent
2651 mov si,ax ; SI = addrss of next adj extent
2652 mov es:[si].EH_Prev_Extn_Ptr,-1 ; mark no previous extent
2653 mov di,LRU_Extent ; DI-->extent to be deleted
2654
2655 ;----------------------------------------------------------------------------
2656 ; Free the current Extent or Header
2657 ;----------------------------------------------------------------------------
2658 Free_Open_Cl_Buffer: ;
2659 mov si,di ; SI-->LRU extent or header ;AN000;
2660 mov di,Drive_Hdr_Ptr ; DI-->drive buffer ;AN000;
2661 mov ax,es:[di].Free_Ptr ;AN000;
2662 mov es:[si].EH_Next_Extn_Ptr,ax ; connect Free ptr to last ;AN000;
2663 ; extent in the queue
2664 mov ax, -2 ; discontinuous mark (-2) ;AN000;
2665 mov es:[si], ax ; mark freed area as discontinuous ;AN000;
2666 mov es:[di].Free_Ptr,si ; connect header or extent to free area ;AN000;
2667
2668 ; Increase the Free_Size entry in Drive Header
2669 mov ax, Size File_Header ; size is same for both header or extent ;AN000;
2670 add es:[di].Free_Size, ax ; update free buffer count ;AN000;
2671 mov Free_Flag,1 ; set flag for discontinuous free area ;AN000;
2672 clc
2673 Free_Exit: ; exit
2674 ret ; return ;AN000;
2675
2676 FIND_FREE_BUFFER endp
2677
2678 \f
2679
2680
2681
2682
2683 ;----------------------------------------------------------------------
2684 ; PROCEDURE: Make_MRU_Header
2685 ;
2686 ; FUNCTION: Move header to the top of the queue. If the header is at the
2687 ; bottom of the queue, mark previous header as LRU header
2688 ; before moving the header to the top of the queue.
2689 ;
2690 ; INPUT: Drive_Hdr_Ptr - Points to drive header
2691 ; Cur_Hdr_Ptr - Points to current header
2692 ; ES--> Cache Buffer Segment
2693 ;
2694 ; OUTPUT: Header is moved to top of the current queue
2695 ; SI-->current header
2696 ;
2697 ;----------------------------------------------------------------------
2698
2699 MAKE_MRU_HEADER PROC NEAR
2700
2701 mov si,Cur_Hdr_Ptr ; SI-->Current Header ;AN000;
2702 cmp es:[si].FH_Next_Hdr_Ptr,-1 ; current header LRU header ;AN000;
2703 jne Move_close_gap ; no, jump ;AN000;
2704 ;AN000;
2705 mov di,Prev_Hdr_Ptr ; yes, make previous header
2706 mov es:[di].FH_Next_Hdr_Ptr,-1 ; LRU header ;AN000;
2707 jmp short move_to_top
2708
2709 Move_Close_Gap:
2710 mov di,Prev_Hdr_Ptr ; yes, get previous header
2711 mov ax,es:[si].FH_Next_Hdr_Ptr ; get next header address
2712 mov es:[di].FH_Next_Hdr_Ptr,ax ; connect previous hdr to next hdr
2713 ;AN000;
2714 Move_To_Top:
2715 mov di,drive_Hdr_Ptr ; DI-->drive buffer ;AN000;
2716 mov ax,es:[di].MRU_Hdr_Ptr ; connect current header to ;AN000;
2717 mov es:[si].FH_Next_Hdr_Ptr,ax ; previous MRU header ;AN000;
2718 mov es:[di].MRU_Hdr_Ptr,si ; make current header MRU hdr ;AN000;
2719 ;
2720 ret
2721
2722 Make_MRU_Header ENDP
2723
2724 \f
2725
2726
2727
2728
2729 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2730 ; PROCEDURE: MAKE_MRU_EXTENT
2731 ;
2732 ; FUNCTION: Move Extent to the top of the queue. If the extent is at the
2733 ; bottom of the queue, mark previous extent as LRU extent
2734 ; before moving the extent to the top of the queue. If the extent
2735 ; is between first and last, then close the MRU-LRU chain gap.
2736 ; If the extent is already MRU then exit.
2737 ;
2738 ; This routine is called if clusters are inserted or looked up
2739 ; from an existing extent.
2740 ;
2741 ; INPUT: Cur_Hdr_Ptr - Address of current header
2742 ; Cur_Extn_Ptr - Address of current extent
2743 ; ES--> Cache Buffer Segment
2744 ;
2745 ; OUTPUT: Extent is moved next to the current header
2746 ; SI-->current extent
2747 ;
2748 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2749
2750 MAKE_MRU_EXTENT PROC NEAR
2751
2752 mov si,Cur_Hdr_Ptr ; SI-->Current Header ;AN000;
2753 mov ax,Cur_Extn_Ptr
2754 cmp es:[si].FH_MRU_Extn_Ptr, ax ; current extent already MRU?? ;AN000;
2755 je Make_MRU_Exit ; yes - exit
2756
2757 mov si, Cur_Extn_Ptr ; SI-->Current extent
2758 mov di,es:[si].EH_Prev_LRU_Ptr ; get address of previous MRU extent
2759 cmp di, -1 ; any previous MRU extent ??
2760 je Make_MRU_Exit ; none - exit- current extent is already MRU
2761
2762 ; Close the gap (connect previous to next extent)
2763 mov si, Cur_Extn_Ptr
2764 cmp es:[si].EH_Next_LRU_Ptr, -1 ; current extent LRU extent ??
2765 jne join_the_gap ; no - close the gap
2766 mov es:[di].EH_Next_LRU_Ptr, -1 ; mark the previous extent MRU
2767 jmp short move_MRU_Extent ; make mru extent
2768
2769 Join_The_Gap:
2770 mov ax, es:[si].EH_Next_LRU_Ptr ; AX-->next LRU extent
2771 mov es:[di].EH_Next_LRU_Ptr,ax ; connect previous to next
2772 mov bx,di ; BX-->prev LRU extent
2773 mov di,ax ; DI-->Next LRU extent
2774 mov es:[di].EH_Prev_LRU_Ptr, bx ; set previous LRU extent address
2775
2776
2777 ; Make the current extent MRU extent
2778 Move_MRU_Extent:
2779 mov di,Cur_Hdr_Ptr ; DI-->Current header
2780 mov ax,es:[di].FH_MRU_Extn_Ptr ; AX-->Previous MRU extent
2781 mov es:[si].EH_NEXT_LRU_Ptr,ax ; connect previous to current extent
2782 mov es:[di].FH_MRU_Extn_Ptr,si ; make current extent MRU extent
2783 mov es:[si].EH_Prev_LRU_Ptr, -1 ; mark no previous LRU extent
2784
2785 mov di,ax ;(12/29) set prev LRU addrs of prev MRU extent
2786 mov es:[di].EH_Prev_LRU_Ptr,si ;(12/29)
2787
2788 Make_MRU_Exit:
2789 clc
2790 ret ; return
2791
2792 MAKE_MRU_EXTENT ENDP
2793
2794 \f
2795
2796
2797
2798
2799 ;----------------------------------------------------------------------
2800 ; PROCEDURE: JOIN_PREV_TO_NEXT
2801 ;
2802 ; FUNCTION: Connect previous header to next header inorder to close the
2803 ; gap created when a header is moved to top of the Queue or to
2804 ; the top of CLOSE queue. If the file header is the first header
2805 ; under the current Drive header, connect header to the MRU_Hdr_Ptr.
2806 ;
2807 ; INPUT: Prev_Hdr_Ptr - Points to Previous header
2808 ; Cur_Hdr_Ptr - Points to Current Header
2809 ; Queue_Type - Queue Type: 0 = Open Queue
2810 ; 1 = Close Queue
2811 ; ES--> Cache Buffer Segment
2812 ; OUTPUT: Gap is closed
2813 ;
2814 ;----------------------------------------------------------------------
2815
2816 JOIN_PREV_TO_NEXT PROC
2817
2818 cmp Prev_Hdr_Ptr, -1 ; current hdr first file header ?? ;AN000;
2819 jne join_prev_hdr ; no, close gap ;AN000;
2820
2821 ; Yes, in this case close gap by connecting Drive header to next header
2822 mov di,Drive_Hdr_Ptr ; DI-->drive header ;AN000;
2823 mov si,Cur_Hdr_Ptr ; SI-->Current header ;AN000;
2824 mov ax,es:[si].FH_Next_Hdr_Ptr ; AX-->Next Header ;AN000;
2825 cmp Queue_Type, 1 ; Is this Close Queue ?? ;AN000;
2826 je Join_Sel_Close_Ptr ; Yes, jump ;AN000;
2827 mov es:[di].MRU_Hdr_Ptr,ax ; join next header to Drive Header ;AN000;
2828 jmp short join_exit ; exit ;AN000;
2829
2830 Join_Sel_Close_Ptr:
2831 mov es:[di].Close_Ptr,ax ; join next header to Drive Header ;AN000;
2832 jmp short join_exit ; exit ;AN000;
2833
2834
2835 ; Connect previous header to next header ( close the gap )
2836 Join_Prev_Hdr:
2837 mov di,Prev_Hdr_Ptr ; DI-->Previous header ;AN000;
2838 mov si,Cur_Hdr_Ptr ; SI-->Current Header ;AN000;
2839 mov ax,es:[si].FH_Next_Hdr_Ptr ; connect previous header ;AN000;
2840 mov es:[di].FH_Next_Hdr_Ptr,ax ; to next header ;AN000;
2841
2842 Join_Exit:
2843 ret ; exit ;AN000;
2844
2845 JOIN_PREV_TO_NEXT ENDP
2846
2847
2848 \f
2849
2850
2851
2852 ;----------------------------------------------------------------------
2853 ; PROCEDURE: UPDATE_FREE_AREA
2854 ;
2855 ; FUNCTION: Update Free area pointer and Free area size before creating
2856 ; a new extent or new header
2857 ;
2858 ; INPUT: Prev_Hdr_Ptr - Points to Previous header
2859 ; Cur_Hdr_Ptr - Points to Current Header
2860 ; Queue_Type - Queue Type: 0 = Open Queue
2861 ; 1 = Close Queue
2862 ; Free_Flag - Free area type: 0 = continous free area
2863 ; 1 = non-contiguous free area
2864 ; ES--> Cache Buffer Segment
2865 ;
2866 ;
2867 ; OUTPUT: Free pool address and size is updated
2868 ;
2869 ;----------------------------------------------------------------------
2870
2871 UPDATE_FREE_AREA PROC
2872
2873 mov di,Drive_Hdr_Ptr ; DI-->drive header ;AN000;
2874 mov si,es:[di].Free_Ptr ; SI-->current free pointerted ;AN000;
2875 ;
2876 mov ax, Size Extent_Header ;AN000;
2877 sub es:[di].Free_Size, ax ; update free area size ;AN000;
2878
2879 cmp Free_Flag, 1 ; continuous free area ?? ;AN000;
2880 jne ext_add_free_ptr ; yes - update free area pointer ;AN000;
2881
2882 ;----------------------------------------------------------------------
2883 ; If discontinuous Free area. Update the Free pointer by getting pointer
2884 ; to next free from the 4th word using header or extent structure.
2885 ; This is because the discontinuous areas are connected chained through
2886 ; the 4th word
2887 ;----------------------------------------------------------------------
2888 mov ax,es:[si].FH_Next_Hdr_Ptr ; no, update FREE area pointer ;AN000;
2889 mov es:[di].Free_Ptr,ax ; using the Header structure ;AN000;
2890 jmp short Update_Free_Exit ; Exit ;AN000;
2891
2892 ;----------------------------------------------------------------------
2893 ; If continuous Free area. Next free area address is computed by adding
2894 ; the size of extent of header structure.
2895 ;----------------------------------------------------------------------
2896 Ext_Add_Free_Ptr:
2897 mov ax, size File_Header ; calculate the address of ;AN000;
2898 add es:[di].Free_Ptr,ax ; next free area by adding size of ;AN000;
2899 ; a extent or header. Both same size
2900 Update_Free_Exit:
2901 ret ; exit ;AN000;
2902
2903 UPDATE_FREE_AREA ENDP
2904
2905
2906
2907
2908 ;----------------------------------------------------------------------
2909 ; Procedure: CHECK_IT Checks the validity of the queues
2910 ;
2911 ;----------------------------------------------------------------------
2912
2913 CHECK_IT PROC NEAR
2914
2915 pushf ; save all registers
2916 push bx
2917 push di
2918 cmp check_flag,0
2919 je check_exit
2920 mov ah,090h
2921 xor al,al
2922 xor cx,cx
2923 mov cl,func_cod
2924 mov di, Drive_Hdr_Ptr
2925 INT 2FH
2926 check_exit:
2927 pop di
2928 pop bx
2929 popf
2930 ret
2931
2932 CHECK_IT ENDP
2933
2934
2935
2936 ; Calculate the size of the Cseg_Seek module in bytes
2937 IF ($-Cseg_Seek) MOD 16 ;AN000;
2938 ORG ($-Cseg_Seek)+16-(($-Cseg_Seek) MOD 16) ;AN000;
2939 ENDIF ;AN000;
2940 END_SEEK label word
2941
2942
2943 CSEG_SEEK ENDS
2944 END