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