diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/FASTOPEN/FASTOPEN.TXT | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/CMD/FASTOPEN/FASTOPEN.TXT')
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTOPEN.TXT | 615 |
1 files changed, 615 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FASTOPEN/FASTOPEN.TXT b/v4.0/src/CMD/FASTOPEN/FASTOPEN.TXT new file mode 100644 index 0000000..b1cf286 --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTOPEN.TXT | |||
| @@ -0,0 +1,615 @@ | |||
| 1 | |||
| 2 | .* | ||
| 3 | .pm 5 | ||
| 4 | :gdoc sec='' | ||
| 5 | :frontm | ||
| 6 | :titlep | ||
| 7 | :title.FASTOPEN UTILITY HIGH LEVEL DESIGN | ||
| 8 | :date. | ||
| 9 | :author.J. K. | ||
| 10 | :ETITLEP | ||
| 11 | :toc | ||
| 12 | :body | ||
| 13 | .DH NUM | ||
| 14 | .*.pa | ||
| 15 | &SYSDATE. | ||
| 16 | .*:H1.INTRODUCTION | ||
| 17 | .*:H1.ARCHITECTURE OVERVIEW | ||
| 18 | |||
| 19 | :H1.FASTOPEN DESIGN | ||
| 20 | :H2.FASTOPEN UTILITY | ||
| 21 | :H3.FASTOPEN Overview | ||
| 22 | FASTOPEN is a utility that allows DOS to maintain the information about | ||
| 23 | files that have been opened. The purpose is to reduce the number of times DOS | ||
| 24 | has to look into the directory area of the disk for information on the file once | ||
| 25 | the information is stored by FASTOPEN. In real life, many application | ||
| 26 | programs, especially current database systems on the market, tend to open the | ||
| 27 | same file repeatedly and every open operation needs an access to the disk if the | ||
| 28 | information does not exist in the DOS buffer. The FASTOPEN utility will | ||
| 29 | eliminate these disk accesses, and hence will increase the efficiency of DOS | ||
| 30 | performance. | ||
| 31 | |||
| 32 | |||
| 33 | :H3.FASTOPEN Operational Description | ||
| 34 | Conceptually FASTOPEN itself is a database maintained by DOS. The data will | ||
| 35 | be stored and maintained in the system RAM. | ||
| 36 | |||
| 37 | FASTOPEN is a user-installable, stay resident utility loaded by entering a | ||
| 38 | command | ||
| 39 | .fo off | ||
| 40 | 1). FASTOPEN D:{=L} ... | ||
| 41 | |||
| 42 | where "..." means a possible repetition. | ||
| 43 | |||
| 44 | "D:" is a drive letter for a non_removable media. | ||
| 45 | |||
| 46 | "L" is the maxium number of files and subdirectories that can be | ||
| 47 | stored in the drive cache. The default value is 34, minimum | ||
| 48 | value, 10. The total number for all the drives is less | ||
| 49 | than 1000. | ||
| 50 | |||
| 51 | .fo on | ||
| 52 | |||
| 53 | :H4.Name Caching | ||
| 54 | FASTOPEN will keep the history of the accessed subdirectory and file | ||
| 55 | information in LRU fashion. The data are stored in a partial tree | ||
| 56 | structure that represents all the recently accessed files and | ||
| 57 | subdirectories of that drive. The number of entries entered by the | ||
| 58 | user, or the default number of 34, represents the maximum number of | ||
| 59 | nodes and leaves of the tree. As it suggests, the bigger the | ||
| 60 | number is, the more the efficient it will be. Currently each additional | ||
| 61 | increase of the entry will take 36 bytes, which is the fixed length of | ||
| 62 | a node. | ||
| 63 | |||
| 64 | The number entered by the user should be bigger than the deepest nesting | ||
| 65 | of path entries in the drive. | ||
| 66 | |||
| 67 | The operation on this name cache is similar to the operation on the | ||
| 68 | physical drive. | ||
| 69 | With the look up request, FASTOPEN will traverse the name cache tree from the | ||
| 70 | root to the bottom to find the requested path, filename. If found, then the | ||
| 71 | pointer to the file or subdirectory information packet will be returned, else FASTOPEN | ||
| 72 | will return the string pointer that points up to the matching subdirectory name. | ||
| 73 | In this case, if DOS wants to insert the rest of the subdirectory/file information | ||
| 74 | an insert operation should be requested for every subdirectory/file. FASTOPEN | ||
| 75 | will use the information from the previous Look_up operation for a sequence of Insert operations. | ||
| 76 | |||
| 77 | At this moment, if there are any free entries left, then it will be used. | ||
| 78 | Otherwise, FASTOPEN will delete the least recently used leaf. Any node cannot | ||
| 79 | be deleted until the node becomes an empty leaf, i.e., without children. | ||
| 80 | If a file or a directory has been removed, then DOS will update the name | ||
| 81 | cache tree with the Delete request. The path, file will be looked up | ||
| 82 | first, and if found, then the corresponding entries will be free to the | ||
| 83 | free entry chain. If not found, then still it is O.K. since the matching file | ||
| 84 | entries had been removed by the LRU scheme. | ||
| 85 | |||
| 86 | |||
| 87 | :H3.Fastopen Interface | ||
| 88 | When installed, by the nature of the functionality, FASTOPEN becomes | ||
| 89 | a part of DOS and a private communication mechanism will be | ||
| 90 | established. | ||
| 91 | Inside DOS, vector pointers are established for FASTOPEN and will be | ||
| 92 | initialized by the call "CALLinstall" macro by the FASTOPEN initialization. | ||
| 93 | The structure of the FASTOPEN entry will look like; | ||
| 94 | |||
| 95 | .fo off | ||
| 96 | FASTOPEN_ENTRY struc | ||
| 97 | FASTOPEN_ENTRY_SIZE dw 4 ;size of the following | ||
| 98 | FASTOPEN_NAME_CACHING dd ? | ||
| 99 | ;FASTOPEN_FATCHAIN_CACHING dd ? ;not for DOS 3.3 | ||
| 100 | ;NUMBER_OF_SFTS dw ? ;# of files - 3 | ||
| 101 | FASTOPEN_ENTRY ends | ||
| 102 | .fo on | ||
| 103 | |||
| 104 | The initial vector pointer for FASTOPEN_NAME_CACHING | ||
| 105 | points to a dummy routine in DOS which simply set the carry flag and set AX to 0FFFFh. | ||
| 106 | |||
| 107 | When FASTOPEN is installed, then this vectors table will be established to | ||
| 108 | point to the matching procedures in FASTOPEN module. | ||
| 109 | |||
| 110 | The register AL will contain subfunction value on entry to FASTOPEN. | ||
| 111 | |||
| 112 | .fo off | ||
| 113 | ;FASTOPEN NAME CACHING Subfunctions | ||
| 114 | fastopen_name_look_up equ 1 | ||
| 115 | fastopen_name_insert equ 2 | ||
| 116 | fastopen_name_delete equ 3 | ||
| 117 | ;fastopen_name_purge equ 4 ;Not for DOS 3.3 | ||
| 118 | |||
| 119 | .fo off | ||
| 120 | 1. Name Caching | ||
| 121 | |||
| 122 | a. Look up | ||
| 123 | IN) DS:SI -> d:path | ||
| 124 | ES:DI -> DIR_INFO buffer in DOS to be filled by FASTOPEN | ||
| 125 | ES:CX -> Extended_Info buffer in DOS to be filled by FASTOPEN | ||
| 126 | OUT) | ||
| 127 | if found, DS:SI -> the last character of the path, i.e., 0. | ||
| 128 | ES:DI -> DIR INFO | ||
| 129 | ES:CX -> Extended INFO (explained in the data structure) | ||
| 130 | else if there exist the name cache for the drive, but could not | ||
| 131 | completely find the matching path, | ||
| 132 | DS:SI -> "\" following the directory that FASTOPEN can | ||
| 133 | find the match, | ||
| 134 | Will points to "\" after "d:" if no matching | ||
| 135 | root directory is found. | ||
| 136 | ES:DI -> Compct_Dir_Info of the subdirectory FASTOPEN | ||
| 137 | can find the match. | ||
| 138 | ES:CX -> the matching directory's Extended INFO | ||
| 139 | If cannot find the matching root directory entry, then | ||
| 140 | ES:DI, ES:CX are undetermined. | ||
| 141 | else carry flag set and AX = 0FFFFh. | ||
| 142 | |||
| 143 | b. Insert | ||
| 144 | IN) DS:DI -> DIR info | ||
| 145 | ES:BX -> Extended info | ||
| 146 | |||
| 147 | OUT) | ||
| 148 | If failed, then carry flag set and AX = 0FFFFh. | ||
| 149 | Insert operation handles only one file or subdirectory at a time. | ||
| 150 | So, usually insert operations are performed in a sequential manner. | ||
| 151 | A look up operation should be performed before any new sequential | ||
| 152 | insert operation. | ||
| 153 | FASTOPEN will keep the information of the pervious look up | ||
| 154 | operation in CURRENT_NODE. The CURRENT_NODE points to the matching | ||
| 155 | directory node of the previous Look up operation. The next insert | ||
| 156 | operation will use this CURRENT_NODE information to insert the | ||
| 157 | directory or file information. So, DOS will call only one Look_ | ||
| 158 | up operation and possibly several Insert operation to insert the | ||
| 159 | path. | ||
| 160 | |||
| 161 | For example, suppose DOS wants to look up C:\DIR1\DIR2\FILE1 and | ||
| 162 | FASTOPEN only has the inforamtion up to C:DIR1. After the | ||
| 163 | look up operation, FASTOPEN will return with DS:SI points "\" | ||
| 164 | following C:\DIR1. | ||
| 165 | At this moment, if DOS decides to insert this information,then | ||
| 166 | it sets DS:DI to DIR_INFO, and ES:BX to EXTENDED_INFO of the | ||
| 167 | subdirectory DIR2, and will request an insert operation. | ||
| 168 | When control returned back to DOS, then it will set this time | ||
| 169 | DS:DI and ES:BX to those of FILE1, and will call an another | ||
| 170 | insert operation. | ||
| 171 | At the first insert operation, FASTOPEN automatically knows | ||
| 172 | that those informaton given by DOS belong to the child of | ||
| 173 | C:\DIR1, and will install it as a child. In the second operation, | ||
| 174 | again FASTOPEN knows that it is for the child of C:\DIR1\DIR2 | ||
| 175 | and will accordingly install the information for FILE1. | ||
| 176 | |||
| 177 | c. Delete | ||
| 178 | IN) DS:SI -> d:path | ||
| 179 | |||
| 180 | OUT) | ||
| 181 | If failed, then carry flag set and AX = 0FFFFh. | ||
| 182 | |||
| 183 | .fo on | ||
| 184 | |||
| 185 | :H3.FASTOPEN Special Considerations | ||
| 186 | FASTOPEN uses the following DOS function calls in its initialization | ||
| 187 | rouitine. No DOS or BIOS function calls are allowed inside the | ||
| 188 | main routine that is resident once installed. | ||
| 189 | :ul | ||
| 190 | :li.AH = 40h, Int 21h; Write to device for the messages, | ||
| 191 | :li.AH = 31h, Int 21h; Terminate Process and Remain Resident, | ||
| 192 | :li.AH = 48h, AH = 49h, AH = 4Ah, Int 21h; Allocate, free and | ||
| 193 | modify memory block. | ||
| 194 | :eul | ||
| 195 | :p. | ||
| 196 | |||
| 197 | To prevent the corruption of any DOS operation, once FASTOPEN is | ||
| 198 | loaded it cannot be reloaded. | ||
| 199 | |||
| 200 | |||
| 201 | :H4.FASTOPEN Top Level Design | ||
| 202 | |||
| 203 | :H5.Data Structure | ||
| 204 | |||
| 205 | The structures of the records in FASTOPEN are: | ||
| 206 | |||
| 207 | .fo off | ||
| 208 | NAME_record struc | ||
| 209 | LRU_pointer dw -1 | ||
| 210 | Child_pointer dw -1 | ||
| 211 | Sibling_pointer dw -1 | ||
| 212 | MRU_pointer dw -1 | ||
| 213 | Compct_Dir_info db 22 dup (?) | ||
| 214 | Extended_Info db 5 dup (?) | ||
| 215 | NAME_record ends | ||
| 216 | |||
| 217 | Extended_Info struc | ||
| 218 | dirpos db 0 | ||
| 219 | dirsec dw 0 | ||
| 220 | clusnum dw 0 | ||
| 221 | Extended_Info ends | ||
| 222 | |||
| 223 | Drive_cache_header struc | ||
| 224 | LRU_ROOT dw 0 ;Start of LRU chain for this Name cache | ||
| 225 | Child_ptr dw -1 ;points to the name cache | ||
| 226 | Sibling_ptr dw -1 ;points to the next drive header | ||
| 227 | MRU_ROOT dw 0 ;set to the end of LRU chain | ||
| 228 | Drive_letter db 'C' | ||
| 229 | Num_Entries dw 0 | ||
| 230 | Name_Cache_start dw 0 ;Start of name cache for this drive | ||
| 231 | Drive_cache_header ends | ||
| 232 | |||
| 233 | Cmpct_Dir_Info struc | ||
| 234 | CD_File_name db 11 dup (0) | ||
| 235 | CD_File_attr db ? | ||
| 236 | CD_time dw ? | ||
| 237 | CD_date dw ? | ||
| 238 | CD_cluster dw ? | ||
| 239 | CD_Filesize dd ? | ||
| 240 | Cmpct_Dir_Info ends | ||
| 241 | |||
| 242 | Dir_Info struc ;= full directory entry information. | ||
| 243 | DI_head db 12 dup (?) | ||
| 244 | DI_skip db 10 dup (0) ;reserved area. All the time 0. | ||
| 245 | DI_tail db 10 dup (?) | ||
| 246 | Dir_Info ends | ||
| 247 | |||
| 248 | .fo | ||
| 249 | |||
| 250 | |||
| 251 | :H5.FASTOPEN Hierarch | ||
| 252 | :H6.FASTOPEN Components | ||
| 253 | |||
| 254 | .fo off | ||
| 255 | |||
| 256 | ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 257 | ³ FASTOPEN ³ | ||
| 258 | ÀÄÄÄÄÄÄÂÄÄÄÄÄÄÄÙ | ||
| 259 | ³ | ||
| 260 | ³ | ||
| 261 | ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 262 | ³ ³ | ||
| 263 | V V | ||
| 264 | ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 265 | ³ INIT ³ ³ MAIN ³ | ||
| 266 | ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÂÄÄÄÄÄÄÄÙ | ||
| 267 | ³ | ||
| 268 | V | ||
| 269 | ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ | ||
| 270 | ³ ³ | ||
| 271 | ³ LOOK_UP, INSERT, DELETE, INIT_TREE ³ | ||
| 272 | ³ ³ | ||
| 273 | ³ (SUPPORTING MODULES) ³ | ||
| 274 | ³ ³ | ||
| 275 | ³ GET_FREE_NODE, PRE_LRU_STACK, ³ | ||
| 276 | ³ SET_LRU, MAKE_NAME_RECORD, ³ | ||
| 277 | ³ UNFOLD_NAME_RECORD, PACK_DIR_NAME, ³ | ||
| 278 | ³ REMOVEFROMLRUCHAIN ³ | ||
| 279 | ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ | ||
| 280 | |||
| 281 | .fo | ||
| 282 | |||
| 283 | :H6.FASTOPEN Memory Structure | ||
| 284 | |||
| 285 | .fo off | ||
| 286 | Lo_memory ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÄÂÄ | ||
| 287 | ³ LOOK_UP, ³ ³ | ||
| 288 | ³ INSERT, ³ M | ||
| 289 | ³ DELETE, ³ A | ||
| 290 | ³ & Supporting Routines ³ I | ||
| 291 | ³ ³ N | ||
| 292 | ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ | ||
| 293 | ³ INIT_TREE ³ ³ | ||
| 294 | ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÄÅÄ | ||
| 295 | ³ DRIVE_CACHE_HEADER ³ I | ||
| 296 | ³ (After Init, this ³ N | ||
| 297 | ³ area will be used ³ I | ||
| 298 | ³ for name caches.) ³ T | ||
| 299 | ³ SHOW_ERR_MESSAGE ³ ³ | ||
| 300 | ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÄÁÄ | ||
| 301 | |||
| 302 | High_memory | ||
| 303 | .fo | ||
| 304 | |||
| 305 | .pa | ||
| 306 | :H5.FASTOPEN Component Interfaces | ||
| 307 | |||
| 308 | .fo off | ||
| 309 | ;************************************************************************* | ||
| 310 | ; | ||
| 311 | ;SUBROUTINE: INIT | ||
| 312 | ; | ||
| 313 | ;INPUT: | ||
| 314 | ; | ||
| 315 | ;OUTPUT: | ||
| 316 | ; | ||
| 317 | ;DESCRIPTION: | ||
| 318 | ; | ||
| 319 | ; 1:(Installation check) | ||
| 320 | ; { Get the entry pointer of FASTOPEN from DOS. | ||
| 321 | ; Check the signature ($FASTOPEN01$) | ||
| 322 | ; If already installed, | ||
| 323 | ; then Show 'FASTOPEN already installed'; Exit | ||
| 324 | ; } | ||
| 325 | ; | ||
| 326 | ; 2:(Parse the command line) | ||
| 327 | ; Input: User input | ||
| 328 | ; | ||
| 329 | ; Output: Total_Entry_Num. | ||
| 330 | ; Drive_Cache_Headers set. | ||
| 331 | ; End_Cache_Header. | ||
| 332 | ; | ||
| 333 | ; { For every drive entered | ||
| 334 | ; { Drive sanity check; | ||
| 335 | ; Get_Num; | ||
| 336 | ; if success and Total_Entry_Num < 1000, then | ||
| 337 | ; Set Drive_Cache_Header; | ||
| 338 | ; } | ||
| 339 | ; } | ||
| 340 | ; | ||
| 341 | ; 3:(Check the system memory) - Check if the system has enough | ||
| 342 | ; memory for the Name caches. | ||
| 343 | ; Name cache will start from the | ||
| 344 | ; End_Cache_Header. | ||
| 345 | ; | ||
| 346 | ; Input: Total_Entry_Num, End_Cache_Header, End_Init, | ||
| 347 | ; Output: End_Caches | ||
| 348 | ; { | ||
| 349 | ; Needed_space = size of (Name_Record) * Total_Entry_Num; | ||
| 350 | ; Needed_space = Needed_space - (End_Init - End_Cache_Header); | ||
| 351 | ; Free allocated memory from End_Init (AH = 4Ah); | ||
| 352 | ; Set memory block from End_Init to Needed_Space (AH = 48h); | ||
| 353 | ; if fail, Show 'Insufficient memory for FASTOPEN cache'; | ||
| 354 | ; Set End_Caches; | ||
| 355 | ; } | ||
| 356 | ; | ||
| 357 | ; 4: jmp to INIT_TREE | ||
| 358 | ; | ||
| 359 | ;************************************************************************* | ||
| 360 | |||
| 361 | |||
| 362 | .pa | ||
| 363 | .fo off | ||
| 364 | ;************************************************************************* | ||
| 365 | ; | ||
| 366 | ;SUBROUTINE: INIT_TREE | ||
| 367 | ; | ||
| 368 | ;INPUT: Drive_cache_header, End_Caches | ||
| 369 | ; | ||
| 370 | ;OUTPUT:Name_cache entries installed for every drive requested. | ||
| 371 | ; LRU chain established for every drive. | ||
| 372 | ; FASTOPEN entry pointer set in DOS. | ||
| 373 | ; Terminate & stay resident. (Up to End_Caches) | ||
| 374 | ; | ||
| 375 | ;DESCRIPTION: | ||
| 376 | ; | ||
| 377 | ; 1:(Install_Name_Cache) | ||
| 378 | ; Input: Drive cache header, End_cache_header (= Name cache start) | ||
| 379 | ; Output:According to the information in the header, | ||
| 380 | ; the name cache entries will be established. | ||
| 381 | ; Also, LRU chain, MRU_pointer are established. | ||
| 382 | ; | ||
| 383 | ; { Buffer_start = End_cache_header; | ||
| 384 | ; For every drive header | ||
| 385 | ; { LRU_ROOT = Buffer_start; | ||
| 386 | ; For (i=1;i=Num_Entries;i++) | ||
| 387 | ; { MRU_pointer = Buffer_start; | ||
| 388 | ; Buffer_start= Buffer_start + size_of (Name_record); | ||
| 389 | ; if i = Num_Entries then LRU_pointer = -1 | ||
| 390 | ; else LRU_pointer = Buffer_start; | ||
| 391 | ; } | ||
| 392 | ; } | ||
| 393 | ; } | ||
| 394 | ; | ||
| 395 | ; 2:(Set FASTOPEN entry pointer in DOS) | ||
| 396 | ; Use CALL INSTALL macro. | ||
| 397 | ; | ||
| 398 | ; 3: Terminate and stay resident up to Buffer_start; | ||
| 399 | ; | ||
| 400 | ;************************************************************************* | ||
| 401 | |||
| 402 | |||
| 403 | .pa | ||
| 404 | .fo off | ||
| 405 | ;************************************************************************* | ||
| 406 | ; | ||
| 407 | ;SUBROUTINE: MAIN | ||
| 408 | ; | ||
| 409 | ;INPUT: Called by DOS throught Look_up, Insert, Delete requests. | ||
| 410 | ; | ||
| 411 | ;OUTPUT:Request performed based on LRU scheme. | ||
| 412 | ; CX, DX, DS, ES, BP value saved. Other register are destroyed. | ||
| 413 | ; | ||
| 414 | ;DESCRIPTION: | ||
| 415 | ; Call Pack_Dir_Name ;get the drive letter in BL | ||
| 416 | ; Call Get_Drive_Cache_Header ;find the matching drive header | ||
| 417 | ; if not found, then AX = 0ffffh, Carry set | ||
| 418 | ; else if AL = Look_up then Call Look_up | ||
| 419 | ; else if AL = Insert then Call Insert | ||
| 420 | ; else if AL = Delete then Call Delete | ||
| 421 | ; else AX = 0ffffh, Carry set. | ||
| 422 | ; | ||
| 423 | ; MAJOR SUBROUTINES: | ||
| 424 | ; (Look_up) - Refer to Look_up subroutine. | ||
| 425 | ; (Delete) - Refer to Delete subroutine. | ||
| 426 | ; (Insert) - Refer to Insert subroutine. | ||
| 427 | ; | ||
| 428 | ; SUPPORTING SUBROUTINES: | ||
| 429 | ; 1:(Get_Free_Node) - Get the entry from the LRU_ROOT, | ||
| 430 | ; Set LRU_ROOT to the next entry of the | ||
| 431 | ; LRU chain | ||
| 432 | ; Input: none | ||
| 433 | ; Output:Entry address. LRU_ROOT updated to the next entry. | ||
| 434 | ; | ||
| 435 | ; 2:(Pre_LRU_Stack) - This is needed to implement LRU scheme in | ||
| 436 | ; a tree structure. Since the order of traversing a tree is | ||
| 437 | ; from the root to bottom and from left to right, the direct | ||
| 438 | ; implementation of LRU will result the parent the least mostly | ||
| 439 | ; used one instead of the child. This is exactly in the reverse | ||
| 440 | ; order to what had been expected. This procedure will | ||
| 441 | ; solve this problem without loss of any efficiency. In the | ||
| 442 | ; Look_up operation and found the match, the found entris will | ||
| 443 | ; be saved with each of its LRU, MRU pointer modified to reflect | ||
| 444 | ; the desired LRU order. | ||
| 445 | ; These created mini LRU chain will be attached to the | ||
| 446 | ; LRU chain again by SET_LRU. SET_LRU and PRE_LRU_STACK | ||
| 447 | ; should work in a synchronized fashion. SET_LRU routine | ||
| 448 | ; will be called in the beginning of every Look_up, Insert | ||
| 449 | ; operation. PRE_LRU_Stack will be called whenever a matching | ||
| 450 | ; entry is found in a Look_up operation, or whenever a new | ||
| 451 | ; entry is inserted by the Insert operation. | ||
| 452 | ; Input: Current_Drive,Target node. | ||
| 453 | ; Output:Depth, Top, Bottom set | ||
| 454 | ; | ||
| 455 | ; 3:(SET_LRU) | ||
| 456 | ; Input: Depth, Top, Bottom, Current_Drive | ||
| 457 | ; Output:Mini LRU chain created by Pre_LRU_Stack will be | ||
| 458 | ; placed at the end of LRU chain. | ||
| 459 | ; | ||
| 460 | ; 4:(MAKE_NAME_RECORD) - At Insert time, BOS will give | ||
| 461 | ; two types of information. DS:DI -> Dir_Info, ES:BX -> Extended_ | ||
| 462 | ; Info. The Name_Record is composed of Cmpct_Dir_Info and | ||
| 463 | ; Extend_Info. MAKE_NAME_RECORD will simply make a Name_Record | ||
| 464 | ; from the informations from DOS. | ||
| 465 | ; Input: Dir_Info, Extended_Info | ||
| 466 | ; Output:Name_Record | ||
| 467 | ; | ||
| 468 | ; 5:(UNFOLD_NAME_RECORD) - Inverse function of above. When Look_up | ||
| 469 | ; operation finishes, then unfold the Name_Record of the current_ | ||
| 470 | ; node for DOS. If the Current_Node is a drive_cache_header, | ||
| 471 | ; then will just return. | ||
| 472 | ; Input: CS:Current_Node, ES, DI, BX set for the buffer | ||
| 473 | ; Output:ES:DI->Dir_Info, ES:BX->Extended_Info buffer in DOS. | ||
| 474 | ; | ||
| 475 | ; 6:(PACK_DIR_NAME) - At Look_up or Delete operation, DS:SI points | ||
| 476 | ; to the requested full path, for ex., "C:\DIR1.EXT\DIR2\FILE.EXT", | ||
| 477 | ; 0. This routine is smart enough to recognize ":","\" and 0 as | ||
| 478 | ; a delimeter and will parse until the next delimeter and leave | ||
| 479 | ; SI to the next delimeter found. Also, if it is a drive name | ||
| 480 | ; it will set SI to the "\" after ":" for consistency and | ||
| 481 | ; it will set BL to the drive letter. | ||
| 482 | ; The main function of this routine is "pack" the given directory | ||
| 483 | ; name into 11 bytes format. PACKED_NAME will be filled with | ||
| 484 | ; the result. For example, when it is called the first time, | ||
| 485 | ; DL = "C" and SI will point to "\" before DIR1.EXT. | ||
| 486 | ; The second time, PACKED_NAME will be filled with | ||
| 487 | ; "DIR1 EXT" and SI will points to "\" before "DIR2". | ||
| 488 | ; Likewize, if this routine is called the fourth time, | ||
| 489 | ; FILE.EXT has been parsed and DS:SI will points to 0. | ||
| 490 | ; When this routine is called again, then it will return | ||
| 491 | ; with carry signaling that it has reached the end. | ||
| 492 | ; The user is required to call this routine consequtively | ||
| 493 | ; until it returns with carry. | ||
| 494 | ; Input: | ||
| 495 | ; Output: | ||
| 496 | ; | ||
| 497 | ;************************************************************************* | ||
| 498 | |||
| 499 | |||
| 500 | .pa | ||
| 501 | .fo off | ||
| 502 | ;************************************************************************* | ||
| 503 | ; | ||
| 504 | ;SUBROUTINE: LOOK_UP | ||
| 505 | ; | ||
| 506 | ;INPUT: DS:SI -> path | ||
| 507 | ; ES:DI -> DIR_INFO buffer in DOS to be filled by FASTOPEN | ||
| 508 | ; ES:CX -> Extended_Info buffer in DOS to be filled by FASTOPEN | ||
| 509 | ; CS:BP -> Matching Drive_cache_header | ||
| 510 | ; | ||
| 511 | ;OUTPUT:if found, DS:SI -> the last character of the path, i.e., 0. | ||
| 512 | ; ES:DI -> DIR_INFO | ||
| 513 | ; ES:CX -> Extended_INFO (explained in the data structure) | ||
| 514 | ; else if there exist the name cache for the drive, but could not | ||
| 515 | ; completely find the matching path, | ||
| 516 | ; DS:SI -> "\" following the directory that FASTOPEN can | ||
| 517 | ; find the match, | ||
| 518 | ; Will points to "\" after "d:" if no matching | ||
| 519 | ; root directory is found. | ||
| 520 | ; ES:DI -> Dir_Info of the subdirectory FASTOPEN | ||
| 521 | ; can find the match. | ||
| 522 | ; ES:CX -> the matching directory's Extended INFO | ||
| 523 | ; If cannot find the matching root directory entry, then | ||
| 524 | ; ES:DI, ES:BX are undetermined. | ||
| 525 | ; If the requested path is "D:\,0" then FASTOPEN will | ||
| 526 | ; return with carry flag set and, AX = 0ffffh. | ||
| 527 | ; else carry flag set and AX = 0FFFFh. | ||
| 528 | ; | ||
| 529 | ;GLOBAL VARIABLES: | ||
| 530 | ; CURRENT_NODE, | ||
| 531 | ; CURRENT_SIBLING, | ||
| 532 | ; | ||
| 533 | ;DESCRIPTION: | ||
| 534 | ; Save Dir_Info, Extended_Info buffer address in DOS. | ||
| 535 | ; Set ES to Name_Cache_Seg | ||
| 536 | ; SET_LRU; | ||
| 537 | ; 1: | ||
| 538 | ; Current_Node = BP | ||
| 539 | ; Current_Sibling = 0 | ||
| 540 | ; PACK_DIR_NAME (from the path); | ||
| 541 | ; if CX = 0, then jmp to 3 /*Found*/; | ||
| 542 | ; Find_child (from the current_node); | ||
| 543 | ; if not found then jmp to 3 | ||
| 544 | ; 2: Compare Packed_name with Child_pointer.CD_filename | ||
| 545 | ; if yes, then PRE_LRU_STACK; JMP to 1 | ||
| 546 | ; else Find_Sibling;Current_sibling=Sibling_pointer | ||
| 547 | ; if found a sibling, then Current_Node = Current_Sibling | ||
| 548 | ; jmp to 2 | ||
| 549 | ; else jmp to 3; | ||
| 550 | ; 3: UNFOLD_NAME_RECORD /*for the info packet to DOS */ | ||
| 551 | ; Exit | ||
| 552 | ; | ||
| 553 | ;************************************************************************* | ||
| 554 | |||
| 555 | |||
| 556 | .pa | ||
| 557 | .fo off | ||
| 558 | ;************************************************************************* | ||
| 559 | ; | ||
| 560 | ;SUBROUTINE: INSERT | ||
| 561 | ; | ||
| 562 | ;INPUT: DS:DI -> DIR info | ||
| 563 | ; ES:BX -> Extended info | ||
| 564 | ; | ||
| 565 | ;OUTPUT:Automatic insertion based on CURRENT_NODE, CURRENT_SIBLING | ||
| 566 | ; If failed, then carry flag set and AX = 0FFFFh. | ||
| 567 | ; Insert operation handles only one file or subdirectory at a time. | ||
| 568 | ; So, usually insert operations are performed in a sequential manner. | ||
| 569 | ; A look up operation should be performed before any new sequential | ||
| 570 | ; insert operation. | ||
| 571 | ; | ||
| 572 | ;GLOBAL VARIABLES: | ||
| 573 | ; CURRENT_NODE, | ||
| 574 | ; CURRENT_SIBLING, | ||
| 575 | ; | ||
| 576 | ;DESCRIPTION: | ||
| 577 | ; | ||
| 578 | ; Make_Name_Record ;Make Name Record from the input | ||
| 579 | ; Get_Free_Node | ||
| 580 | ; Set_LRU ;(from TEMP_LRU_STACK) | ||
| 581 | ; if current_sibling <> 0 (or current_sibling=0FFh) | ||
| 582 | ; then Install as a sibling of Current_Node | ||
| 583 | ; else Install as a child under Current_Node; | ||
| 584 | ; Pre_LRU_stack ;(pre operation for LRU) | ||
| 585 | ; Exit | ||
| 586 | ; | ||
| 587 | ;************************************************************************* | ||
| 588 | |||
| 589 | |||
| 590 | .pa | ||
| 591 | .fo off | ||
| 592 | ;************************************************************************* | ||
| 593 | ; | ||
| 594 | ;SUBROUTINE: Delete | ||
| 595 | ; | ||
| 596 | ;INPUT: DS:SI -> d:path | ||
| 597 | ; | ||
| 598 | ;OUTPUT: If found, then remove the item from the Tree and from the | ||
| 599 | ; LRU chain. Move that slot to the Top of the LRU chain. | ||
| 600 | ; | ||
| 601 | ;GLOBAL VARIABLES: | ||
| 602 | ; | ||
| 603 | ;DESCRIPTION: | ||
| 604 | ; Look_Up | ||
| 605 | ; If ds:si -> 0, then Remove that entry from Tree, LRU chain, | ||
| 606 | ; Put that entry to the top of LRU chain | ||
| 607 | ; else AX = 0FFFFh, Carry set, | ||
| 608 | ; Exit | ||
| 609 | ; | ||
| 610 | ;************************************************************************* | ||
| 611 | |||
| 612 | |||
| 613 | .fo | ||
| 614 | :egdoc. | ||
| 615 | |||