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