4 ;--------------- INCLUDE FILES -----------------
7 debug
=0 ;this is an equate only for DOSMAC.inc
12 INCLUDE fastsegs
.inc ; Cannot declare this in DOS includes
13 INCLUDE fastopen
.inc ; This include file also contains DOS equates
16 CSEG_MAIN
SEGMENT PARA
PUBLIC 'CODE' ; Cseg_Seek segment
18 EXTRN VECTOR_DELETE
:dword ; jump vector inside Cseg_Seek to make
19 ; a FAR call to FSeek Delete function within
25 ;*****************************************************************************
26 ; ALL FastSeek functions are kept in a seperate segment. They are accessed
27 ; by a FAR indirect call from the MAIN routine.
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 ;*****************************************************************************
35 CSEG_SEEK
SEGMENT PARA
PUBLIC 'code'
36 assume
cs:cseg_seek
,ds:nothing
,es:nothing
,ss:nothing
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;
49 PUBLIC Fk_Close
;AN000;
50 PUBLIC Fk_Insert
;AN000;
52 PUBLIC Fk_Lookup
;AN000;
57 ;;---------- FASTSEEK LOCAL VARIABLES ---------------------
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
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;
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;
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;
91 Queue_Type dw 0 ; Queue Type: 0 - Open Queue ;AN000;
93 phys_num dw 0 ; ** for queue analyser
94 logic_num dw 0 ; ** for queue analyser
97 ; Following data area is initialized during initialization
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
111 ;-------------------------------------------------------------------------------
112 ;-------------------------------------------------------------------------------
115 ; FUNCTION: Create and initialize a file header using the starting
116 ; Physical Cluster number (file id) of the file.
118 ; If the file header already exist in the OPEN Queue, then increase
119 ; the file reference count by one and make the header
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.
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.
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.
138 ; INPUT: CX = First Physical Cluster Number of the file
142 ; OUTPUT: Created a new file header. If header already exist, then the file
143 ; reference count is incremented by one.
145 ; ROUTINES REFERENCED: Find_File_Header, Find_Drive_Header
147 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
148 ; "Version 4.00 (C) Copyright 1988 Microsoft"
149 ; "Licensed Material - Property of Microsoft "
151 ;-------------------------------------------------------------------------------
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;
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;
169 jnc open_Search_Header
; header found - check for file header ;AN000;
170 jmp open_exit
; drive header not found - exit ;AN000;
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 ;------------------------------------------------------------------------------
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;
185 jmp Open_Make_Hdr
; no, make new header ;AN000;
188 ;------------------------------------------------------------------------------
189 ; Search for header in the OPEN Queues. If found, increment file reference
191 ;------------------------------------------------------------------------------
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;
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;
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 ;------------------------------------------------------------------------------
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;
217 cmp Hdr_Flag
, 3 ; current header LRU header ?? ;AN000;
218 jne Open_Join_Gap
; no, close the gap ;AN000;
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;
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;
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 ;-----------------------------------------------------------------------------
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;
242 Open_Make_MRU_Hdr: ; header is between 1st and last headers
243 CALL MAKE_MRU_HEADER
; move header to top of Queue ;AN000;
245 clc ; make sure caary is clear
246 jmp Open_exit
; then EXIT ;AN000;
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 ;------------------------------------------------------------------------------
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;
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 ;------------------------------------------------------------------------------
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;
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;
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 ;------------------------------------------------------------------------------
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;
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;
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;
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;
301 ;------------------------------------------------------------------------------
302 ; Close the gap in the CLOSE Queue.
303 ;------------------------------------------------------------------------------
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;
308 ;------------------------------------------------------------------------------
309 ; Now move the current header from CLOSE Queue to top of OPEN Queue
310 ;------------------------------------------------------------------------------
312 mov si,Cur_Hdr_Ptr
; SI-->Current header ;AN000;
313 mov di,drive_Hdr_Ptr
; DI-->drive header ;AN000;
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;
322 mov es:[di].MRU_Hdr_Ptr
,si ; make the header MRU header ;AN000;
324 jmp short open_exit
; then exit. ;AN000;
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 ;------------------------------------------------------------------------------
336 CALL MAKE_NEW_HEADER
; create new header ;AN000;
351 ;--------------------------------------------------------------------------
352 ; PROCEDURE: FK_CLOSE
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
360 ; INPUT: DL = Drive Number
361 ; CX = First Physical Cluster Number of the file
363 ; OUTPUT: Moved the file header and the extents to the close Queue
365 ; ROUTINES REFERENCED: Find_File_Header, Find_Drive_Header
367 ; REVISION HISTORY: New (5/87)
369 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
370 ; "Version 4.00 (C) Copyright 1988 Microsoft"
371 ; "Licensed Material - Property of Microsoft "
373 ;---------------------------------------------------------------------------
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;
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;
392 ;--------------------------------------------------------------------------
393 ; Search for file header in the OPEN Queue using given physical cluster number
394 ;--------------------------------------------------------------------------
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;
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 ;--------------------------------------------------------------------------
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;
420 ;--------------------------------------------------------------------------
421 ; Connect previous header to next header to close the gap in OPEN Queue
422 ;--------------------------------------------------------------------------
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
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
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
438 ;--------------------------------------------------------------------------
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;
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 ;--------------------------------------------------------------------------
450 cmp Prev_Hdr_Ptr
,-1 ; first header in the Queue ?? ;AN000;
451 je Dont_Move_To_Top
; yes, dont move to top ;AN000;
453 CALL MAKE_MRU_HEADER
; move header to top of queue ;AN000;
457 jmp short Close_Exit
; exit ;AN000;
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 ;--------------------------------------------------------------------------
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;
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
490 ;------------------------------------------------------------------------
492 ; PROCEDURE: FK_DELETE
494 ; FUNCTION: Delete a specific header and extents under the header
495 ; and release the buffers to the FREE pool
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.
502 ; INPUT: CX = First Physical Cluster Number of the file
505 ; OUTPUT: The file header and the extents are deleted
507 ; ROUTINES REFERENCED: Find_File_Header, Find_Drive_Header
509 ; REVISION HISTORY: New (5/87)
511 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
512 ; "Version 4.00 (C) Copyright 1988 Microsoft"
513 ; "Licensed Material - Property of Microsoft "
515 ;-------------------------------------------------------------------------
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;
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
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;
541 ;--------------------------------------------------------------------------
542 ; Search for a header in the OPEN Queue using given physical cluster number
543 ;--------------------------------------------------------------------------
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;
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;
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;
568 mov cx,First_Phys_Clusnum
; CX = first phys clus number ;AN000;
569 CALL FIND_FILE_HEADER
; find the header in CLOSE queue ;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;
577 ;-------------------------------------------------------------------------
578 ; Header found in CLOSE queue. Check header found is the only single
579 ; header left in the queue.
580 ;-------------------------------------------------------------------------
582 cmp Hdr_Flag
, 1 ; Single Header in CLOSE Queue ?? ;AN000;
583 jne Del_Chk_LRU_Hdr
; no, check for LRU header ;AN000;
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;
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;
600 ;--------------------------------------------------------------------------
601 ; Connect previous header to next header to close the gap in CLOSE Queue
602 ;--------------------------------------------------------------------------
604 mov Queue_Type
, 1 ; set flag to indicate CLOSE Queue ;AN000;
605 CALL JOIN_PREV_TO_NEXT
; close gap ;AN000;
607 jmp short Delete_Free_Buff
; release header to FREE area ;AN000;
611 ;-------------------------------------------------------------------------
612 ; Header found in OPEN queue. Check header found is the only single
613 ; header left in the queue.
614 ;-------------------------------------------------------------------------
616 cmp Hdr_Flag
, 1 ; Single Header in OPEN Queue?? ;AN000;
617 jne Del_Chk_Opn_LRU_Hdr
; no, check for LRU header ;AN000;
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;
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;
634 ;--------------------------------------------------------------------------
635 ; Connect previous header to next header to close the gap in OPEN queue
636 ;--------------------------------------------------------------------------
638 mov Queue_Type
, 0 ; set flag to indicate OPEN Queue ;AN000;
639 CALL JOIN_PREV_TO_NEXT
; close gap ;AN000;
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.
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 ;---------------------------------------------------------------------------
656 mov di,Drive_Hdr_Ptr
; SI-->drive header ;AN000;
657 mov si,Cur_Hdr_Ptr
; DI-->current header ;AN000;
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 ;-------------------------------------------------------------------------
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;
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;
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 ;-------------------------------------------------------------------------
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;
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;
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;
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;
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;
747 ;--------------------------------------------------------------------------
748 ; PROCEDURE: FK_INSERT
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.
757 ; INPUT DL = drive number
758 ; CX = First Physical Cluster Number of the file
759 ; BX = Logical Cluster Number
760 ; DI = Physical Cluster Number
762 ; OUTPUT: Physical cluster number is inserted. If extent is not found,
763 ; a new file is created
765 ; ROUTINES REFERENCED: Find_File_Header, Find_Extent, Find_LRU_Header
767 ; REVISION HISTORY: New (5/87)
769 ;------------------------------------------------------------------------
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;
778 mov first_phys_clusNum
,cx ; save cluster numbers ;AN000;
779 mov Logical_ClusNum
,bx ;AN000;
780 mov Physical_ClusNum
,di ;AN000;
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;
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 ;--------------------------------------------------------------------------
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
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
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;
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
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 ;--------------------------------------------------------------------------
825 CALL MAKE_NEW_HEADER
; make a new header at the top ;AN000;
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;
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;
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;
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
864 jmp Insert_Exit
; exit ;AN000;
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 ;--------------------------------------------------------------------------
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;
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
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;
888 CALL UPDATE_FREE_AREA
; update Free area pointers ;AN000;
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;
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;
921 ;--------------------------------------------------------------------------
922 ; Extent found. Check for LOW end contiguous. If true insert in the current
923 ; extent and update the count
924 ;--------------------------------------------------------------------------
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;
941 CALL Make_MRU_Extent
; Move extent next to current header
942 jmp Insert_Make_MRU
; Make current header MRU header ;AN000;
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 ;--------------------------------------------------------------------------
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;
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;
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 ;--------------------------------------------------------------------------
971 cmp find_flag
,3 ; between current and previous exts?? ;AN000;
972 je Connect_prev_next
; yes, jump ;AN000;
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
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
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;
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
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
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
1019 mov es:[di].EH_Prev_LRU_Ptr
,si ; connect previous to current extent
1020 jmp Insert_Make_MRU
; make current header MRU header
1024 ;--------------------------------------------------------------------------
1025 ; Make new extent between current and previous extents. If no previous extent
1026 ; connect the new extent to the current header.
1027 ;--------------------------------------------------------------------------
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
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;
1038 CALL UPDATE_FREE_AREA
; update Free_Ptr and Free_Size ;AN000;
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;
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
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
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;
1070 ; Connect new extent to previous extent
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 ??
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;
1081 jmp short Join_Set_Next
; current extent
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
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
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
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;
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 ;--------------------------------------------------------------------------
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;
1128 CALL FIND_FREE_BUFFER
; Find free area ;AN000;
1129 jc Insert_Exit
; if free area found is its own ;AN000;
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;
1135 CALL UPDATE_FREE_AREA
; update Free_Ptr and Free_Size ;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;
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
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
1162 mov es:[si].EH_Prev_LRU_Ptr
,di ; connect previous to current extent
1165 ;--------------------------------------------------------------------------
1166 ; Make the Current header MRU header. If the header is MRU header, then
1167 ; dont make the header MRU header.
1168 ;--------------------------------------------------------------------------
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;
1176 CALL MAKE_MRU_HEADER
; move header to top of OPEN Queue ;AN000;
1177 clc ; make sure caary is clear
1180 CALL Check_it
; analyse the queue (debugging)
1192 ;-------------------------------------------------------------------------
1193 ; PROCEDURE: FK_LOOKUP
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.
1203 ; INPUT: DL = drive number
1204 ; CX = First Physical Cluster Number of the file
1205 ; BX = Logical Cluster NUmber
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]
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]
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
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.
1223 ; ROUTINES REFERENCED: Find_File_Header, Find_Extent, Find_Drive_Header
1225 ; REVISION HISTORY: New (5/87)
1227 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
1228 ; "Version 4.00 (C) Copyright 1988 Microsoft"
1229 ; "Licensed Material - Property of Microsoft "
1231 ;---------------------------------------------------------------
1233 FK_LOOKUP PROC
FAR ; on entry DS = seg ID of INIT
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
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;
1251 ;--------------------------------------------------------------------------
1252 ; Search for a header in the OPEN Queue using given physical cluster number
1253 ;--------------------------------------------------------------------------
1255 inc es:[di].Extent_Count
; ;***;
1256 mov si,es:[di].MRU_Hdr_Ptr
; SI-->first header in the ;AN000;
1258 mov cx,First_Phys_Clusnum
; CX = Physical Cluster number ;AN000;
1259 CALL FIND_FILE_HEADER
; find the header in CLOSE Queue
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;
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 ;--------------------------------------------------------------------------
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;
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;
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;
1292 ;--------------------------------------------------------------------------
1293 ; Search for cluster numbers in extents starting from 1st extent.
1294 ;--------------------------------------------------------------------------
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;
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;
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;
1319 mov Prev_Extn_Ptr
,si ; save previous extent address ;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;
1325 jmp Look_Proc_Prev
; else get partial info from ;AN000;
1327 ;-------------------------------------------------------------------------
1328 ; There are no further extents. In this case partially found. Return last
1329 ; logical and physical clusters of the last extent.
1330 ;-------------------------------------------------------------------------
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;
1344 ;--------------------------------------------------------------------------
1345 ; Less than starting logical cluster of first extent. In this case return
1346 ; header info as partially found.
1347 ;--------------------------------------------------------------------------
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;
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
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 ;--------------------------------------------------------------------------
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;
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;
1390 mov bx,es:[si].EH_Phys_Clus_Num
; BX = First physical cluster number ;AN000;
1392 mov ax,es:[di].FH_Phys_Clus_Num
; AX = First physical cluster number ;AN000;
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;
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;
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;
1419 jne Look_first_partial2
; no, partially found ;AN000;
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;
1431 Look_First_Partial2:
1432 mov bx,es:[di].EH_Logic_Clus_Num
; BX = First Logical cluster number ;AN000;
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;
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 ;----------------------------------------------------------------------------
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;
1455 add di,cx ; DI = Phys clus num [logic clus num] ;AN000;
1457 dec bx ; BX = Phys clus num [logic clus num -1] ;AN000;
1458 push di ; DI = Phys clus num [logic clus num] ;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;
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 ;----------------------------------------------------------------------------
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;
1474 mov di,es:[si].EH_Phys_Clus_Num
; BX = first phys clus num of prev ;AN000;
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;
1480 mov fully_flag
,0 ; partially found case ;AN000;
1482 ;----------------------------------------------------------------------------
1483 ; Move the current header to the top of the OPEN queue
1484 ;----------------------------------------------------------------------------
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;
1489 CALL MAKE_MRU_HEADER
;AN000;
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;
1498 stc ; set flag for partially found ;AN000;
1501 pop bx ; restore values to be reurned
1517 ;----------------------------------------------------------------
1518 ; PROCEDURE: Fk_Truncate
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.
1525 ; INPUT: CX = First Physical Cluster Number of the file
1526 ; BX = Logical Cluster Number
1529 ; OUTPUT: CY = 0 Extents are truncated
1531 ; CY = 1 Extent no found DI = 0
1533 ; ROUTINES REFERENCED: Find_File_Header, Find_Extent
1535 ; REVISION HISTORY: New (5/87)
1537 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
1538 ; "Version 4.00 (C) Copyright 1988 Microsoft"
1539 ; "Licensed Material - Property of Microsoft "
1541 ;---------------------------------------------------------------
1543 Fk_TRUNCATE PROC
FAR
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;
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;
1561 ;--------------------------------------------------------------------------
1562 ; Search for a header in the OPEN Queue using given physical clusternum
1563 ;--------------------------------------------------------------------------
1565 inc es:[di].Extent_Count
; ;***;
1566 mov si,es:[di].MRU_Hdr_Ptr
; SI-->first header in the ;AN000;
1568 mov cx,First_Phys_Clusnum
; CX = Physical Cluster number ;AN000;
1570 CALL FIND_FILE_HEADER
; find file header in OPEN Queue ;AN000;
1571 jnc Trunc_Find_extent
; if found, get extent ;AN000;
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;
1579 jmp Trunc_exit
; exit ;AN000;
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;
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;
1594 CALL FIND_EXTENT
; find the extent ;AN000;
1595 jnc Trunc_shrink_extent
; found extent ?? ;AN000;
1597 Trunc_No_Extent: ; extent not found
1598 xor di,di ; no, return DI = 0 ;AN000;
1600 jmp Trunc_exit
; exit ;AN000;
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;
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;
1627 ;--------------------------------------------------------------------------
1628 ; Previous one is header. Mark so that there is no extents under it
1629 ;--------------------------------------------------------------------------
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;
1640 sub bx,es:[di].EH_Logic_Clus_Num
; compute the amount to shrunk ;AN000;
1642 mov es:[di].EH_Count
,bx ; save it in count to shrink extent ;AN000;
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.
1653 mov es:[di].EH_Next_Extn_Ptr
, -1 ; NO, mark last extent ;AN000;
1656 ;--------------------------------------------------------------------------
1657 ; Remove extents and release the buffer
1658 ; SI--->Current extent
1659 ;--------------------------------------------------------------------------
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;
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
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
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
1687 ;-----------------------------------------------------------------------------
1688 ; There is a next LRU extent AX-->Next_LRU_Extent
1689 ;-----------------------------------------------------------------------------
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
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
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
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
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;
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;
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;
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
1739 ;--------------------------------------------------------------------------
1740 ; Make the Current header MRU header ( move current header to top of current Q)
1741 ;--------------------------------------------------------------------------
1743 cmp Prev_Hdr_Ptr
,-1 ; first header in the Queue?? ;AN000;
1746 jmp short Trunc_Exit
; yes, dont move to top ;AN000;
1749 CALL MAKE_MRU_HEADER
; move header to TOP of the Queue ;AN000;
1754 ret ; return ;AN000;
1765 ;-----------------------------------------------------------------------------
1766 ; Procedure: PURGE_BUFFERS
1768 ; Function: Reset both extent and name cache buffers of a specific
1771 ; Input: DL = drive ID
1773 ; Output: Buffers are initialized
1775 ; REVISION HISTORY: New (5/87)
1777 ; COPYRIGHT: "MS DOS 4.00 Fastopen Utility"
1778 ; "Version 4.00 (C) Copyright 1988 Microsoft"
1779 ; "Licensed Material - Property of Microsoft "
1781 ;-----------------------------------------------------------------------------
1783 FK_PURGE PROC
FAR ; Purge Cache buffers
1786 pop ds ; DS=Code seg id used for addressing
1787 ASSUME
ds:Cseg_Seek
; local variables ;AN000;
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
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
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;
1809 add ax, size Drive_Header
; ax = size of drive header
1810 mov es:[si].FREE_Ptr
,ax ; set Free buffer address
1812 ; Makesure to fill extent cache buffer with zeros. Otherwise, Free Mark left
1813 ; previous run will generate illegal Free_Buff pointer.
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
1819 Loop Ext_Loop
; make it zero
1834 ;----------------------------------------------------------------------
1835 ; ******* SUPPORT ROUTINES *******
1836 ;----------------------------------------------------------------------
1838 ;----------------------------------------------------------------------
1839 ; PROCEDURE: Find_Drive_Header
1841 ; FUNCTION: Find starting address of drive header in extent Cache Buffer using
1844 ; INPUT: DL = drive id
1845 ; Extent_Drive_Buff (Ptr to the beginning of extent buffer)
1846 ; ES--> Cache Buffer Segment
1848 ; OUTPUT: If Carry = 0 DI --> Drive header
1849 ; Drive_Hdr_Ptr = address of drive header
1851 ; If Carry = 1 Drive buffer not found
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
1856 ;----------------------------------------------------------------------
1858 FIND_DRIVE_HEADER PROC
NEAR
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
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;
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;
1881 Drive_Buff_Not_Found: ; drive buffer not found
1882 stc ; set carry flag ;AN000;
1883 jmp short Drive_Exit
; exit ;AN000;
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;
1891 Drive_Exit: ; return
1894 FIND_DRIVE_HEADER endp
1900 ;---------------------------------------------------------------
1901 ; PROCEDURE: Find_File_Header
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.
1907 ; INPUT: SI --> First header in the queue
1908 ; CX = First Physical Cluster Number (file id)
1909 ; ES--> Cache Buffer Segment id
1911 ; OUTPUT: If Carry = 0 DI --> header found
1912 ; Cur_Hdr_Ptr = address of header found
1913 ; Prev_Hdr_Ptr = address of previous header
1915 ; Prev_Hdr_Ptr = -1 No Previous Header
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
1923 ; If Carry = 1 Header not found
1925 ;---------------------------------------------------------------
1927 FIND_FILE_HEADER PROC
NEAR
1929 push si ; save registers ;AN000;
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;
1938 mov Prev_Hdr_Ptr
,-1 ; reset flags ;AN000;
1939 mov Hdr_Flag
, 0 ; reset header type flag ;AN000;
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;
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;
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;
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;
1965 jmp short FH_Exit
; exit ;AN000;
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;
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;
1977 jmp short Fh_Exit
; exit ;AN000;
1981 jmp short Fh_Exit
; exit ;AN000;
1984 stc ; header not found ;AN000;
1989 ret ; return ;AN000;
1991 FIND_FILE_HEADER ENDP
1999 ;---------------------------------------------------------------
2000 ; PROCEDURE: Find_Extent
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.
2006 ; INPUT: SI --> First Extent under current queue
2007 ; CX = Logical Cluster number to be searched
2008 ; ES--> Cache Buffer Segment Id
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
2016 ; If Carry = 1 Extent not found
2018 ; REVISION HISTORY: New (5/87)
2019 ;---------------------------------------------------------------
2021 FIND_EXTENT PROC
NEAR
2023 push si ; save registers ;AN000;
2026 mov Prev_Extn_Ptr
,-1 ; reset flags
2027 mov Extn_Flag
, 0 ;AN000;
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;
2035 jg Eh_Next_Extn
; try next extent ;AN000;
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;
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;
2051 stc ; else set flag for extent not found ;AN000;
2052 jmp short Eh_Exit
; then exit ;AN000;
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;
2063 jmp short Eh_Exit
; exit ;AN000;
2065 Eh_Not_Found: ; extent not found
2072 ret ; return ;AN000;
2081 ;---------------------------------------------------------------------------
2082 ; PROCEDURE: FIND_CLUSTER_LOCATION
2084 ; FUNCTION: Find starting address of a specific extent which identifies
2085 ; the relative position of the new cluster in the queue.
2087 ; INPUT: SI--> First extent under current header
2088 ; ES--> Cache Buffer Segment
2090 ; OUTPUT: If Carry = 0 Cluster location identified
2091 ; Cur_Extn_Ptr = Current extent
2092 ; Prev_Extn_Ptr = Previous extent
2094 ; Find_Flag = 1 Clusters are contiguous in
2095 ; the LO end of the current extent
2097 ; Find_Flag = 2 Clusters are contiguous in
2098 ; the HI end of the current extent
2100 ; Find_Flag = 3 Clusters belong to a new
2101 ; extent between current and previous
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
2108 ; Find_Flag = 5 Clusters belong to a new
2109 ; extent between current and next
2111 ; If Carry = 1 Clusters already exist
2113 ;-----------------------------------------------------------------------
2116 FIND_CLUSTER_LOCATION PROC
NEAR
2118 ;--------------------------------------------------------------------------
2119 ; Check to see that the given logical cluster number falls within the
2120 ; current extent. If true it is an error.
2121 ;--------------------------------------------------------------------------
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
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;
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 ;--------------------------------------------------------------------------
2141 jmp Fe_Extent_Exit
; return ;AN000;
2144 ;--------------------------------------------------------------------------
2145 ; If not in the extent, then see the logical clus number has continuity at
2146 ; LOW end of the current extent.
2147 ;--------------------------------------------------------------------------
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
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;
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
2173 ;--------------------------------------------------------------------------
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;
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;
2182 ; Logical clus num has high end continuity, Check the Physical cluster number
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;
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;
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;
2205 mov Find_Flag
,2 ; set flag for HIGH end continuity ;AN000;
2206 jmp short Fe_Extent_found
; then RETURN ;AN000;
2210 cmp es:[si].EH_Next_Extn_Ptr
, -1 ; Current extent last extent ?? ;AN000;
2211 je Fe_flag_4
; yes, set flag-4 ;AN000;
2213 mov Find_Flag
,5 ; set flag for new extent between ;AN000;
2214 jmp short Fe_Extent_Found
; current and next extent ;AN000;
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;
2220 ;--------------------------------------------------------------------------
2221 ; Given cluster number has no continuity but must stay between current extent
2222 ; and previous extent
2223 ;--------------------------------------------------------------------------
2225 mov Find_Flag
,3 ; set flag for between current and prev ;AN000;
2226 jmp short Fe_Extent_found
; then RETURN ;AN000;
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;
2243 ;--------------------------------------------------------------------------
2244 ; Given cluster number has no continuity but stays in a new extent at
2245 ; bottom (last) of the current queue.
2246 ;--------------------------------------------------------------------------
2248 mov Find_Flag
,4 ; else set flag for new extent ;AN000;
2259 FIND_CLUSTER_LOCATION ENDP
2267 ;-----------------------------------------------------------------------
2268 ; PROCEDURE: FIND_LRU_HEADER
2270 ; FUNCTION: Find address of the LRU header in the current queue
2272 ; INPUT: SI --> First header in the current queue
2273 ; ES--> Cache Buffer Segment
2275 ; OUTPUT: DI --> LRU header found
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
2281 ;-----------------------------------------------------------------------
2283 FIND_LRU_HEADER PROC
NEAR
2286 mov hdr_flag
,0 ; initilialize flags ;AN000;
2287 mov LRU_Prev_Hdr
, -1 ; ;AN000;
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;
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;
2302 cmp LRU_Prev_Hdr
, -1 ; any previous header ?? ;AN000;
2303 je F1h_Set_Flag
; no, set flag ;AN000;
2305 jmp short F1H_Exit
; exit ;AN000;
2308 mov hdr_flag
,1 ; LRU header is the only hdr in queue ;AN000;
2316 FIND_LRU_HEADER endp
2321 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2322 ; PROCEDURE: FIND_LRU_EXTENT
2324 ; FUNCTION: Find address of LRU Extent under current header
2326 ; INPUT: ES--> Cache Buffer Segment
2327 ; SI--> Header to be searched
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
2333 ; If CY = 1 Not found
2335 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2337 FIND_LRU_EXTENT PROC
NEAR
2339 mov LRU_Prev_Extent
, -1 ; reset flags ;AN000;
2340 mov LRU_Extent
, -1 ; ;AN000;
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
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
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;
2360 cmp LRU_Prev_Extent
, -1 ; any previous extent ??
2361 je Fle_Set_Flag
; no - set flag
2366 mov Extn_Flag
, 1 ; set flag to indicate only flag
2372 FIND_LRU_EXTENT ENDP
2380 ;----------------------------------------------------------------------
2381 ; PROCEDURE: Make_New_Header
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.
2389 ; INPUT: Drive_Hdr_Ptr - Address of drive header
2390 ; Free_Ptr - Address of FREE area
2391 ; ES--> Cache Buffer Segment
2393 ; OUTPUT: Header is created
2395 ;----------------------------------------------------------------------
2397 MAKE_NEW_HEADER PROC
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;
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;
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;
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;
2420 CALL FIND_FREE_BUFFER
; Look for some Free area. If none ;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;
2427 CALL UPDATE_FREE_AREA
; update Free_Ptr and Free_Size ;AN000;
2428 ; create some free area
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 ;-----------------------------------------------------------------------------
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
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;
2449 cmp Open_Queue_Flag
, 1 ; OPEN Queue empty ?? ;AN000;
2450 je Set_Single_Header
; no, jump ;AN000;
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;
2460 MAKE_NEW_HEADER ENDP
2467 ;----------------------------------------------------------------------
2468 ; PROCEDURE: Find_Free_Buffer
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.
2474 ; INPUT: Drive_Hdr_Ptr - Pointer to drive header
2475 ; ES--> Cache Buffer Segment
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
2482 ; Free_Flag: 0 - Free area is continuous
2483 ; 1 - Free area is discontinuous
2485 ; if CARRY = 1 Fatal error ( no free space to spare )
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.
2492 ;----------------------------------------------------------------------
2494 FIND_FREE_BUFFER PROC
NEAR
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;
2500 mov si,es:[di].Free_Ptr
; check for discontinuous ;AN000;
2502 cmp es:[si], ax ; discontinuous free buffer?? ;AN000;
2503 je Free_Set_One
; yes, set flag for discontinuous
2505 mov Free_Flag
,0 ; no, clear flag ;AN000;
2510 mov Free_Flag
,1 ; set flag ;AN000;
2512 jmp Free_exit
; yes, Free space is available ;AN000;
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;
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;
2533 ; Makesure to save all local variables before calling DELETE
2534 ; since, this variables may be altered by DELETE routine.
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
2552 CALL VECTOR_DELETE
; delete the file
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
2569 jmp Free_exit
; exit ;AN000;
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;
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;
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;
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;
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;
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;
2617 cmp es:[di].EH_Next_Extn_Ptr
, -1 ; any next adjucent extent ??
2618 jne OPen_Join_extents
; yes - join previous to next
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
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
2632 jmp short Free_Open_Cl_Buffer
; free current extent
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
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
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
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;
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;
2674 ret ; return ;AN000;
2676 FIND_FREE_BUFFER endp
2683 ;----------------------------------------------------------------------
2684 ; PROCEDURE: Make_MRU_Header
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.
2690 ; INPUT: Drive_Hdr_Ptr - Points to drive header
2691 ; Cur_Hdr_Ptr - Points to current header
2692 ; ES--> Cache Buffer Segment
2694 ; OUTPUT: Header is moved to top of the current queue
2695 ; SI-->current header
2697 ;----------------------------------------------------------------------
2699 MAKE_MRU_HEADER PROC
NEAR
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;
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
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
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;
2722 Make_MRU_Header ENDP
2729 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2730 ; PROCEDURE: MAKE_MRU_EXTENT
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.
2738 ; This routine is called if clusters are inserted or looked up
2739 ; from an existing extent.
2741 ; INPUT: Cur_Hdr_Ptr - Address of current header
2742 ; Cur_Extn_Ptr - Address of current extent
2743 ; ES--> Cache Buffer Segment
2745 ; OUTPUT: Extent is moved next to the current header
2746 ; SI-->current extent
2748 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2750 MAKE_MRU_EXTENT PROC
NEAR
2752 mov si,Cur_Hdr_Ptr
; SI-->Current Header ;AN000;
2754 cmp es:[si].FH_MRU_Extn_Ptr
, ax ; current extent already MRU?? ;AN000;
2755 je Make_MRU_Exit
; yes - exit
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
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
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
2777 ; Make the current extent 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
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)
2792 MAKE_MRU_EXTENT ENDP
2799 ;----------------------------------------------------------------------
2800 ; PROCEDURE: JOIN_PREV_TO_NEXT
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.
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
2811 ; ES--> Cache Buffer Segment
2812 ; OUTPUT: Gap is closed
2814 ;----------------------------------------------------------------------
2816 JOIN_PREV_TO_NEXT PROC
2818 cmp Prev_Hdr_Ptr
, -1 ; current hdr first file header ?? ;AN000;
2819 jne join_prev_hdr
; no, close gap ;AN000;
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;
2831 mov es:[di].Close_Ptr
,ax ; join next header to Drive Header ;AN000;
2832 jmp short join_exit
; exit ;AN000;
2835 ; Connect previous header to next header ( close the gap )
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;
2845 JOIN_PREV_TO_NEXT ENDP
2852 ;----------------------------------------------------------------------
2853 ; PROCEDURE: UPDATE_FREE_AREA
2855 ; FUNCTION: Update Free area pointer and Free area size before creating
2856 ; a new extent or new header
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
2862 ; Free_Flag - Free area type: 0 = continous free area
2863 ; 1 = non-contiguous free area
2864 ; ES--> Cache Buffer Segment
2867 ; OUTPUT: Free pool address and size is updated
2869 ;----------------------------------------------------------------------
2871 UPDATE_FREE_AREA PROC
2873 mov di,Drive_Hdr_Ptr
; DI-->drive header ;AN000;
2874 mov si,es:[di].Free_Ptr
; SI-->current free pointerted ;AN000;
2876 mov ax, Size Extent_Header
;AN000;
2877 sub es:[di].Free_Size
, ax ; update free area size ;AN000;
2879 cmp Free_Flag
, 1 ; continuous free area ?? ;AN000;
2880 jne ext_add_free_ptr
; yes - update free area pointer ;AN000;
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
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;
2892 ;----------------------------------------------------------------------
2893 ; If continuous Free area. Next free area address is computed by adding
2894 ; the size of extent of header structure.
2895 ;----------------------------------------------------------------------
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
2903 UPDATE_FREE_AREA ENDP
2908 ;----------------------------------------------------------------------
2909 ; Procedure: CHECK_IT Checks the validity of the queues
2911 ;----------------------------------------------------------------------
2915 pushf ; save all registers
2924 mov di, Drive_Hdr_Ptr
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;