diff options
Diffstat (limited to 'v4.0/src/CMD/FASTOPEN')
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTINIT.ASM | 2970 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTOPEN.ASM | 2052 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTOPEN.LNK | 7 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTOPEN.SKL | 28 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTOPEN.TXT | 615 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTP.ASM | 131 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTSEEK.ASM | 2944 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTSEGS.INC | 20 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/FASTSM.ASM | 145 | ||||
| -rw-r--r-- | v4.0/src/CMD/FASTOPEN/MAKEFILE | 47 |
10 files changed, 8959 insertions, 0 deletions
diff --git a/v4.0/src/CMD/FASTOPEN/FASTINIT.ASM b/v4.0/src/CMD/FASTOPEN/FASTINIT.ASM new file mode 100644 index 0000000..db21b58 --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTINIT.ASM | |||
| @@ -0,0 +1,2970 @@ | |||
| 1 | Page 84,132 ; | ||
| 2 | |||
| 3 | TITLE FASTINIT - initialization code for FASTOPEN (May 13, 1988) | ||
| 4 | |||
| 5 | ;ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» | ||
| 6 | ; The entire Fastopen component is divided into 5 modules. They are: | ||
| 7 | ; Fastopen initialization routine-1, Fastopen initialization routine-2, | ||
| 8 | ; Fastopen which manages the directory/file cache buffers, the Fastseek | ||
| 9 | ; which manages the cluster information cache buffers and the | ||
| 10 | ; cache buffer which holds both directory and cluster information. | ||
| 11 | ; | ||
| 12 | ; These modules resides in different segments for the reason that they can | ||
| 13 | ; be overlayed conditionally, depending on the user request. For example | ||
| 14 | ; initially all segments are loaded into the memory. If fastopen reature is | ||
| 15 | ; not requested, the segment which contains Fastseek will be overlayed over | ||
| 16 | ; original Fastopen to save space. Segmentation is also usefull when Fastopen | ||
| 17 | ; and Fstseek need to copy into Expanded memory. Following figure shows | ||
| 18 | ; memory map of the FastOpen. | ||
| 19 | ; | ||
| 20 | ; Modules Segment | ||
| 21 | ; | ||
| 22 | ; Ú-------------------¿ | ||
| 23 | ; ³ MAIN ³ CSEG_MAIN | ||
| 24 | ; Ã-------------------´ | ||
| 25 | ; ³ FASTINIT1 ³ CSEG_MAIN | ||
| 26 | ; Ã-------------------´ | ||
| 27 | ; ³ ³ | ||
| 28 | ; ³ FASTOPEN ³ CSEG_OPEN | ||
| 29 | ; ³ ³ | ||
| 30 | ; Ã-------------------´ | ||
| 31 | ; ³ ³ | ||
| 32 | ; ³ FASTSEEK ³ CSEG_SEEK | ||
| 33 | ; ³ ³ | ||
| 34 | ; Ã-------------------´ | ||
| 35 | ; ³ FASTINIT2 ³ CSEG_INIT | ||
| 36 | ; Ã-------------------´ | ||
| 37 | ; ³ ³ | ||
| 38 | ; ³ NAME AND ³ | ||
| 39 | ; ³ EXTENT ³ | ||
| 40 | ; ³ CACHE BUFFERS ³ CSEG_INIT | ||
| 41 | ; ³ ³ | ||
| 42 | ; À-------------------Ù | ||
| 43 | ; | ||
| 44 | ; MAIN: This module provides DOS entry point into FASTOPEN. It also | ||
| 45 | ; dispatch various Fastopen and Fastseek functions. This module is | ||
| 46 | ; in the file FASTOPEN.asm | ||
| 47 | ; | ||
| 48 | ; FASTINIT-1: This module is called INIT_TREE which is also a part of the | ||
| 49 | ; Cseg_Main segment. This basically initializes both | ||
| 50 | ; Name and Extent drive headers, and sets up name and extent | ||
| 51 | ; cache buffers. This module can be found in the file | ||
| 52 | ; FASTINIT.asm | ||
| 53 | ; | ||
| 54 | ; FASTINIT-1: This module is called INIT which is part of the Cseg_Init | ||
| 55 | ; segment. This module parses the user commad, check memory | ||
| 56 | ; requirements, overlay Fastopen and Fastseek code and finally | ||
| 57 | ; installs the Fastopen to be stay resident. This module is | ||
| 58 | ; eventually overlayed by the cache buffers created during the | ||
| 59 | ; buffer initialization by FASTINIT-1 ( See INIT_TREE) | ||
| 60 | ; This module can be found in FASTINIT.asm | ||
| 61 | ; | ||
| 62 | ; FASTOPEN: This module is a collection of four Fastopen functions which | ||
| 63 | ; manage the File/Directory cache buffers. These functions are | ||
| 64 | ; in the file FASTOPEN.asm | ||
| 65 | ; | ||
| 66 | ; FASTSEEK: This module is a collection of six FastSeek functions which | ||
| 67 | ; manage queues associated with the cluster information | ||
| 68 | ; cache buffers. This module is found in the file FASTSEEK.asm. | ||
| 69 | ; | ||
| 70 | ; | ||
| 71 | ; Fastopen Code and Cache buffer Relocation | ||
| 72 | ; ----------------------------------------- | ||
| 73 | ; If user specifies both n and m in the user command and /x, then | ||
| 74 | ; Cseg_Open, Cseg_Seek and Cseg_Init will be copied into a 16K page of the | ||
| 75 | ; Expanded Memory. If only n is specified, then Cseg_Open and Cseg_Init will | ||
| 76 | ; be copied. If only m is specified, then Cseg_Seek and Cseg_init will be | ||
| 77 | ; copied. After this the total size of the segments transferred will be | ||
| 78 | ; deblocked from the low memory to save available user space. | ||
| 79 | ; | ||
| 80 | ; If /x is not specified and only n is specified, then the Cseg_Init will | ||
| 81 | ; moved over to Cseg_Seek which is followed by a deblock of memory. If only | ||
| 82 | ; m is specified, then Cseg_Seek will moved over to Cseg_Open and the | ||
| 83 | ; Cseg_Init will be moved over to Cseg_Seek then deblocks the size Cseg_Open. | ||
| 84 | ; | ||
| 85 | ; WARNING: After every move you have to recalculate the Seg ID of moved | ||
| 86 | ; modules depending on how far it has been displaced and then | ||
| 87 | ; replace the Seg ID in the jump vectors used for accessing | ||
| 88 | ; functions in the moved modules. A wrong Seg ID can cause | ||
| 89 | ; instant System CRASH ...@%+(@!$#@@*&... | ||
| 90 | ; | ||
| 91 | ; Future Enhancements: | ||
| 92 | ; | ||
| 93 | ; 1. Modify Fastopen so that it can be run on removable media (Diskette). | ||
| 94 | ; At present only fixed disk is supported. | ||
| 95 | ; | ||
| 96 | ; 2. Allocate all Extent buffers during initialization. Now they are | ||
| 97 | ; done in run time. This may avoid using flags (-2) for discontinuous | ||
| 98 | ; buffers. Using (-2) requires buffers be filled with '0's during PURGE. | ||
| 99 | ; | ||
| 100 | ; 3. Mark the LRU extent every time buffer is changed, so that the | ||
| 101 | ; the buffers need not be searched during buffer recycling | ||
| 102 | ; | ||
| 103 | ; 4; Currently Fastopen code and cache is kept in one 16K page of the | ||
| 104 | ; Extended Memory. This puts a restriction on the size of the cache | ||
| 105 | ; buffer available in EMS usually about 8K. This can be avoided by | ||
| 106 | ; keeping code and cache buffers in two seperated pages, so that maximum | ||
| 107 | ; of 16K is available for cache buffers. | ||
| 108 | ;ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ | ||
| 109 | ; | ||
| 110 | IF1 | ||
| 111 | %OUT ASSEMBLING: FASTINIT - FASTOPEN initialization | ||
| 112 | ENDIF | ||
| 113 | NAME FASTINIT | ||
| 114 | |||
| 115 | .XCREF | ||
| 116 | .XLIST | ||
| 117 | |||
| 118 | |||
| 119 | TRUE EQU 0FFFFh ;AN000; | ||
| 120 | FALSE EQU 0 ;AN000; | ||
| 121 | |||
| 122 | DBCS = FALSE ;AN000; | ||
| 123 | Installed = TRUE ;AN000; | ||
| 124 | |||
| 125 | IFNDEF DEBUG | ||
| 126 | DEBUG = FALSE | ||
| 127 | ENDIF | ||
| 128 | |||
| 129 | INCLUDE dosmac.inc ;AN000; | ||
| 130 | INCLUDE vector.inc ;AN000; | ||
| 131 | INCLUDE filemode.inc ;AN000; | ||
| 132 | INCLUDE mult.inc ;AN000; | ||
| 133 | include version.inc | ||
| 134 | |||
| 135 | .LIST | ||
| 136 | .CREF | ||
| 137 | |||
| 138 | INCLUDE fastsegs.inc ;AN000; | ||
| 139 | INCLUDE fastopen.inc ;AN000; | ||
| 140 | INCLUDE SYSCALL.INC ; ;AN000; | ||
| 141 | |||
| 142 | ;----------------------------------------------------------------------- | ||
| 143 | ; EQUATES | ||
| 144 | ;----------------------------------------------------------------------- | ||
| 145 | Top_mem EQU 02h ;Top of memory index in PSP ;AN000; | ||
| 146 | Min_entry_num EQU 10 ;minimum name cache entries ;AN000; | ||
| 147 | Max_entry_num EQU 999 ;maximum name cache entries ;AN000; | ||
| 148 | Default_names EQU 34 ;default name cache entries ;AN000; | ||
| 149 | Debug EQU 0 ;for callinstall ;AN000; | ||
| 150 | Len_source_xname EQU 4 ;used for xname translate ;AN000; | ||
| 151 | No_siblings EQU -1 ;indicate no siblings ;AN000; | ||
| 152 | No_child EQU -1 ;indicate no children ;AN000; | ||
| 153 | No_backward EQU -1 ;no backward pt yet ;AN000; | ||
| 154 | Max_drives EQU 24 ;maximum number of drives allowed ;AN000; | ||
| 155 | |||
| 156 | |||
| 157 | ; ----------------- MESSAGE EQUATES ------------------------------------- | ||
| 158 | |||
| 159 | Not_enough_mem EQU 2 ;AN000; | ||
| 160 | Invalid_switch EQU 3 ;AN000; | ||
| 161 | Install1 EQU 4 ;AN000; | ||
| 162 | Already_install EQU 5 ;AN000; | ||
| 163 | Incorrect_param EQU 6 ;AN000; | ||
| 164 | Too_many_entries EQU 7 ;AN000; | ||
| 165 | Dup_drive EQU 8 ;AN000; | ||
| 166 | Invalid_extent EQU 11 ;AN000; | ||
| 167 | Invalid_name EQU 12 ;AN000; | ||
| 168 | Ems_failed EQU 13 ;AN000; | ||
| 169 | Ems_not_install EQU 14 ;AN000; | ||
| 170 | Invalid_drive EQU 15 ;AN000; | ||
| 171 | No_page_space EQU 16 ;AN000; | ||
| 172 | Bad_Use_Message EQU 17 | ||
| 173 | Many_Ext_Entries EQU 18 | ||
| 174 | Many_Name_Entries EQU 19 | ||
| 175 | |||
| 176 | |||
| 177 | ;------------ E M S SUPPORT EQUATES ------------------------------- | ||
| 178 | |||
| 179 | EMS_GET_STATUS EQU 40H ;AN000; | ||
| 180 | EMS_GET_NUM_PAGES EQU 42H ;AN000; | ||
| 181 | EMS_ALLOC_PAGES EQU 43H ;AN000; | ||
| 182 | EMS_MAP_HANDLE EQU 44H ;AN000; | ||
| 183 | EMS_GET_VERSION EQU 46H ;AN000; | ||
| 184 | EMS_SAVE_STATE EQU 47H ;AN000; | ||
| 185 | EMS_RESTORE_STATE EQU 48H ;AN000;;AN000; | ||
| 186 | EMS_PAGE_SIZE EQU 4FH ;AN000;;AN000; | ||
| 187 | EMS_2F_HANDLER EQU 1BH ;AN000;;AN000; | ||
| 188 | |||
| 189 | IF NOT IBMCOPYRIGHT | ||
| 190 | |||
| 191 | EMS_GET_COUNT EQU 5801H | ||
| 192 | |||
| 193 | ELSE | ||
| 194 | |||
| 195 | EMS_GET_COUNT EQU 5800H ;AN000; | ||
| 196 | |||
| 197 | ENDIF | ||
| 198 | |||
| 199 | EMS_GET_FRAME_ADDR EQU 5800H ;AN000; | ||
| 200 | EMS_HANDLE_NAME EQU 53H | ||
| 201 | EMS_INT EQU 67H ;AN000; | ||
| 202 | SINGLE_SEGMENT EQU 1 ;AN000; | ||
| 203 | |||
| 204 | |||
| 205 | ;-------------------- STRUCTURES --------------------------------- | ||
| 206 | |||
| 207 | PAGE_FRAME_STRUC STRUC ; EMS page frame structure ;AN000; | ||
| 208 | |||
| 209 | PAGE_SEG DW ? ;EMS page segment ;AN000; | ||
| 210 | PAGE_NUM DW ? ;EMS page number (only one page is used) ;AN000; | ||
| 211 | |||
| 212 | PAGE_FRAME_STRUC ENDS | ||
| 213 | |||
| 214 | BUFFER_ENTRY_SIZE EQU TYPE PAGE_FRAME_STRUC | ||
| 215 | |||
| 216 | |||
| 217 | SUB_LIST STRUC ; Message handler sublist structure ;AN000; | ||
| 218 | DB 11 ; ;AN000; | ||
| 219 | DB 0 ; ;AN000; | ||
| 220 | DATA_OFF DW 0 ; offset of data to be inserted ;AN000; | ||
| 221 | DATA_SEG DW 0 ; offset of data to be inserted ;AN000; | ||
| 222 | MSG_ID DB 0 ; n of %n ;AN000; | ||
| 223 | FLAGS DB 0 ; Flags ;AN000; | ||
| 224 | MAX_WIDTH DB 0 ; Maximum field width ;AN000; | ||
| 225 | MIN_WIDTH DB 0 ; Minimum field width ;AN000; | ||
| 226 | PAD_CHAR DB 0 ; character for pad field ;AN000; | ||
| 227 | SUB_LIST ENDS ;AN000; | ||
| 228 | |||
| 229 | ;------------------------------------------------------------------------------- | ||
| 230 | ; Following two segments are used to define external variable that | ||
| 231 | ; are defined in two other segments. | ||
| 232 | ;------------------------------------------------------------------------------- | ||
| 233 | |||
| 234 | CSEG_OPEN SEGMENT PARA PUBLIC 'CODE' ; Cseg_Open segment | ||
| 235 | EXTRN Open_name_cache_seg:word | ||
| 236 | EXTRN Open_Name_Drive_Buff:word | ||
| 237 | EXTRN End_Open:byte | ||
| 238 | EXTRN Chk_Flag:word | ||
| 239 | EXTRN VECTOR_LOOKUP:dword ; jump vector inside Cseg_Main to make | ||
| 240 | ; a FAR call to Fopen LookUp function within | ||
| 241 | ; the segment | ||
| 242 | CSEG_OPEN ENDS | ||
| 243 | |||
| 244 | |||
| 245 | CSEG_SEEK SEGMENT PARA PUBLIC 'CODE' ; Cseg_Seek segment | ||
| 246 | EXTRN Seek_Extent_Drive_buff:word | ||
| 247 | EXTRN Seek_Name_Drive_buff:word | ||
| 248 | EXTRN Seek_Name_Cache_buff:word | ||
| 249 | EXTRN Seek_Name_Cache_Seg:word | ||
| 250 | EXTRN Seek_Num_Of_Drives:word | ||
| 251 | EXTRN Seek_Total_Ext_Count:word | ||
| 252 | EXTRN Seek_Total_Name_Count:word | ||
| 253 | EXTRN End_Seek:byte | ||
| 254 | EXTRN Check_Flag:word | ||
| 255 | EXTRN VECTOR_DELETE:dword ; jump vector inside Cseg_Seek to make | ||
| 256 | ; a FAR call to FSeek Delete function within | ||
| 257 | ; the segment | ||
| 258 | CSEG_SEEK ENDS | ||
| 259 | |||
| 260 | |||
| 261 | |||
| 262 | |||
| 263 | |||
| 264 | ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ | ||
| 265 | CSEG_MAIN SEGMENT PARA PUBLIC 'CODE' ; MAIN segment | ||
| 266 | |||
| 267 | ; This segment is a continuation of the Cseg_Main segment in Fastopen.asm | ||
| 268 | ; and contains code to initializes name and extent drive buffers | ||
| 269 | ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ | ||
| 270 | ASSUME CS:cseg_main,DS:nothing,SS:stack,ES:nothing | ||
| 271 | |||
| 272 | EXTRN MAIN:FAR ;AN000; | ||
| 273 | |||
| 274 | IF BUFFERFLAG | ||
| 275 | |||
| 276 | extrn restore_page_state:near ; HKN 8/25/88 | ||
| 277 | |||
| 278 | extrn ems_save_handle1:word ; HKN | ||
| 279 | extrn ems_page_number:word ; HKN | ||
| 280 | |||
| 281 | ENDIF | ||
| 282 | |||
| 283 | EXTRN Main_Total_Ext_Count:word ;AN000; | ||
| 284 | EXTRN Main_Total_Name_Count:word ;AN000; | ||
| 285 | EXTRN Main_Name_Drive_Buff:word ;AN000; | ||
| 286 | EXTRN Main_Name_Cache_Buff:word ;AN000; | ||
| 287 | EXTRN Main_Name_Cache_Seg:word ;AN000; | ||
| 288 | EXTRN Main_Parambuff:byte ;AN000; | ||
| 289 | EXTRN Main_extent_drive_Buff:word ;AN000; | ||
| 290 | EXTRN Main_Num_Of_drives:word ;AN000; | ||
| 291 | EXTRN Main_Ext_Count:word ;AN000; | ||
| 292 | EXTRN Main_Ext_Cache_Size:word ;AN000; | ||
| 293 | EXTRN Main_EMS_FLAG:word ;AN000; | ||
| 294 | EXTRN Main_Res_Segs:word ;AN000; | ||
| 295 | EXTRN Main_EMS_PAGE_SEG:word ;AN000; | ||
| 296 | EXTRN Main_EMS_PAGE_SIZE:word ;AN000; | ||
| 297 | |||
| 298 | EXTRN FOPEN_Insert:dword ;AN000; | ||
| 299 | EXTRN FOPEN_Update:dword ;AN000; | ||
| 300 | EXTRN FOPEN_Delete:dword ;AN000; | ||
| 301 | EXTRN FOPEN_Lookup:dword ;AN000; | ||
| 302 | IF BUFFERFLAG | ||
| 303 | EXTRN FOPEN_Purge:dword | ||
| 304 | ENDIF | ||
| 305 | |||
| 306 | EXTRN FSEEK_Open:dword | ||
| 307 | EXTRN FSEEK_Close:dword | ||
| 308 | EXTRN FSEEK_Insert:dword | ||
| 309 | EXTRN FSEEK_Delete:dword | ||
| 310 | EXTRN FSEEK_Lookup:dword | ||
| 311 | EXTRN FSEEK_Truncate:dword | ||
| 312 | EXTRN FSEEK_Purge:dword | ||
| 313 | |||
| 314 | ;************************************************************************* | ||
| 315 | ; | ||
| 316 | ;SUBROUTINE: INIT_TREE (FASTINIT-1) | ||
| 317 | ; | ||
| 318 | ;FUNCTION: This routine builds 'N' name directory buffers under each drive | ||
| 319 | ; header. The second half of this routine initializes the extent | ||
| 320 | ; drive headers and makes the Fastopen code resident. | ||
| 321 | ; | ||
| 322 | ;INPUT: Drive_cache_header, End_Caches | ||
| 323 | ; | ||
| 324 | ;OUTPUT: Name_cache and Extent Cache entries installed for every | ||
| 325 | ; drive requested. | ||
| 326 | ; | ||
| 327 | ;************************************************************************* | ||
| 328 | IF ($-Cseg_Main) MOD 16 ;AN000; | ||
| 329 | ORG ($-Cseg_Main)+16-(($-Cseg_Main) MOD 16) ;AN000; | ||
| 330 | ENDIF ;AN000; | ||
| 331 | End_Main1 label word ;AN000; | ||
| 332 | |||
| 333 | |||
| 334 | INIT_TREE: | ||
| 335 | mov ax,cseg_Main ;get addressiblity to ;AN000; | ||
| 336 | mov ds,ax ;DS --> Cseg_Main ;AN000; | ||
| 337 | ASSUME ds:cseg_Main ;AN000; | ||
| 338 | |||
| 339 | cmp Main_Total_Name_Count,0 ;initialize Name drive headers?? ;AN000; | ||
| 340 | je Init_Ext_Drive_Hdrs ;no, init extent drive headers ;AN000; | ||
| 341 | |||
| 342 | ;----------------------------------------------------------------------------- | ||
| 343 | ; Following code adds 'n' directory entry buffers to each Name Drive headers, | ||
| 344 | ; depending on the value of 'n' specified with each drive ID | ||
| 345 | ;----------------------------------------------------------------------------- | ||
| 346 | mov si,Main_Name_Drive_Buff ;SI-->first Name drive cache buff | ||
| 347 | mov bx,Main_Name_Cache_Buff ;BX-->Name cache buffer | ||
| 348 | xor dx,dx | ||
| 349 | xor ax,ax | ||
| 350 | |||
| 351 | mov ax,Main_Name_Cache_Seg ;get addresability to CSeg_Init | ||
| 352 | mov ds,ax ;DS=addressablity to Cseg_Init | ||
| 353 | ASSUME ds:cseg_Init | ||
| 354 | |||
| 355 | Set_Up_Cache: | ||
| 356 | mov [si].DCH_LRU_ROOT,bx ;set to point to first name | ||
| 357 | mov [si].DCH_NAME_BUFF,bx ;set to point to first name | ||
| 358 | mov cx,[si].DCH_num_entries ;get number of name records | ||
| 359 | |||
| 360 | ;----------------------------------------------------------------------------- | ||
| 361 | ; set up MRU and LRU pointers | ||
| 362 | ; AX points to last name record | ||
| 363 | ; BX points to current name record | ||
| 364 | ; DX points to next name record | ||
| 365 | ;----------------------------------------------------------------------------- | ||
| 366 | mov [bx].nMRU_ptr,-1 ;make first MRU -1 | ||
| 367 | jmp short set_start | ||
| 368 | |||
| 369 | Set_Up_Names: | ||
| 370 | mov [bx].nMRU_ptr,ax ;set up MRU | ||
| 371 | add ax,size name_record | ||
| 372 | |||
| 373 | Set_Start: | ||
| 374 | mov [bx].nChild_ptr,no_child ;no children or siblings | ||
| 375 | mov [bx].nsibling_ptr,no_siblings ; right now | ||
| 376 | mov [bx].nBackward_ptr,no_backward | ||
| 377 | push es | ||
| 378 | push di | ||
| 379 | push ax | ||
| 380 | |||
| 381 | push ds | ||
| 382 | pop es ;ES-->name cache buffer | ||
| 383 | ASSUME es:Cseg_Init | ||
| 384 | |||
| 385 | mov ax, ' ' | ||
| 386 | mov di, bx | ||
| 387 | add di, nCmpct_Dir_Info ;blank out the Dir name area | ||
| 388 | stosb ;the directory buffer | ||
| 389 | stosw | ||
| 390 | stosw | ||
| 391 | stosw | ||
| 392 | stosw | ||
| 393 | stosw | ||
| 394 | |||
| 395 | pop ax | ||
| 396 | pop di | ||
| 397 | pop es | ||
| 398 | |||
| 399 | mov dx,bx ;get name offset | ||
| 400 | add dx,size name_record ;get start of next name | ||
| 401 | dec cx ;decrement num_entries | ||
| 402 | jcxz get_next_drive ;if zero - get next drive | ||
| 403 | mov [bx].nLRU_ptr,dx ;LRU pointer - next name | ||
| 404 | add bx,size name_record ; | ||
| 405 | jmp set_up_names | ||
| 406 | |||
| 407 | Get_Next_Drive: | ||
| 408 | mov [bx].nLRU_ptr,-1 ;LRU pointer - next name | ||
| 409 | |||
| 410 | mov [si].DCH_MRU_ROOT,bx ;set to point to last name | ||
| 411 | mov bx,dx ;get pointer to next name | ||
| 412 | cmp [si].dch_sibling_ptr,no_siblings ;is there any more to set up?? | ||
| 413 | jz Init_Ext_Drive_Hdrs ; no - set extent drive headers | ||
| 414 | add ax,size name_record ; yes - get next name directory buffer | ||
| 415 | add si,size drive_cache_header ;point to next drive header | ||
| 416 | jmp set_up_cache | ||
| 417 | |||
| 418 | |||
| 419 | ;---------------------------------------------------------------------------- | ||
| 420 | ; The following section initializes the Extent Drive Headers. | ||
| 421 | ; DS has addressability to MAIN segment (CSEG_MAIN) and ES has | ||
| 422 | ; addressability to Cache buffer segment (CSEG_INIT) | ||
| 423 | ;---------------------------------------------------------------------------- | ||
| 424 | Init_Ext_Drive_Hdrs: | ||
| 425 | mov ax,cseg_Main ;AN000; | ||
| 426 | mov ds,ax ;DS-->Cseg_Main ;AN000; | ||
| 427 | ASSUME ds:cseg_Main ;AN000; | ||
| 428 | ;AN000; | ||
| 429 | cmp Main_Total_Ext_Count,0 ;initialize extent drive buffers ?? ;AN000; | ||
| 430 | jne init_extent_cache ;yes - continue | ||
| 431 | jmp Init_exit ;no - exit ;AN000; | ||
| 432 | |||
| 433 | ;============================================================================ | ||
| 434 | ; Fill extent cache buffer with zeros. Otherwise a (-2) left in the buffer | ||
| 435 | ; could generate a wrong Free buffer pointer since (-2) is the free buffer | ||
| 436 | ; mark. | ||
| 437 | |||
| 438 | Init_Extent_Cache: | ||
| 439 | mov cx, Main_Ext_Cache_Size ; CX = extent buffer size ;AN000; | ||
| 440 | mov si,Main_Extent_Drive_Buff ; SI-->start of extent cache buff ;AN000; | ||
| 441 | push ds ;AN000; | ||
| 442 | mov ax,Main_Name_Cache_Seg | ||
| 443 | mov ds,ax ; DS-->new init seg (init segment ;AN000; | ||
| 444 | ASSUME ds:Cseg_Init ;AN000; | ||
| 445 | mov al,0 ; pattern "0" ;AN000; | ||
| 446 | |||
| 447 | Next_Byte: ; may be in Extended memory) | ||
| 448 | mov [si],al ;AN000; | ||
| 449 | inc si ;AN000; | ||
| 450 | LOOP next_byte ;AN000; | ||
| 451 | pop ds ; retore original init seg ID ;AN000; | ||
| 452 | ;============================================================================ | ||
| 453 | |||
| 454 | |||
| 455 | Init_Set_Cache: | ||
| 456 | mov si,Main_Extent_Drive_Buff ; SI-->first extent drive header ;AN000; | ||
| 457 | mov cx,Main_num_of_drives ; number of drives | ||
| 458 | mov dx,0 ; drive counter | ||
| 459 | lea di,Main_ParamBuff ; DS:DI-->parameter buff contains ;AN000; | ||
| 460 | ; drive ID and number of extents ;AN000; | ||
| 461 | mov es,Main_name_cache_seg ; ES = addressability to Cseg_Init ;AN000; | ||
| 462 | ASSUME es:Cseg_Init ; ;AN000; | ||
| 463 | ;AN000; | ||
| 464 | INIT_LOOP: ; ES:SI-->cache buffer ;AN000; | ||
| 465 | push cx ; save counter ;AN000; | ||
| 466 | add di,dx ; points to drive ID of this driv ;AN000; | ||
| 467 | xor ax,ax ;AN000; | ||
| 468 | mov ax,[di+2] ; get Extent Count ;AN000; | ||
| 469 | cmp ax, -1 ; any extent under this drive ?? ;AN000; | ||
| 470 | je skip_this_drive ; no - dont create header for this ;AN000; | ||
| 471 | ; this drive | ||
| 472 | mov ax,0 ; *** for debugging sequence count | ||
| 473 | mov es:[si].EXTENT_COUNT,ax ; *** use this area for sequence counting | ||
| 474 | xor ax,ax ;AN000; | ||
| 475 | mov ax,[di] ; get drive ID from drive ID buff ;AN000; | ||
| 476 | mov es:[si].DRIVE_NUMBER,ax ; save drive ID in drive header ;AN000; | ||
| 477 | mov bx, size Drive_Header ;AN000; | ||
| 478 | add bx,si ; BX-->Free area ;AN000; | ||
| 479 | mov es:[si].FREE_PTR,bx ; pointing to free area ;AN000; | ||
| 480 | ;AN000; | ||
| 481 | mov es:[si].MRU_HDR_PTR,-1 ; mark OPEN QUEUE empty ;AN000; | ||
| 482 | mov es:[si].CLOSE_PTR,-1 ; make CLOSE QUEUE empty ;AN000; | ||
| 483 | xor ax,ax ;AN000; | ||
| 484 | mov ax,[di+2] ; get extent count (n) ;AN000; | ||
| 485 | mov cx, size Extent_Header ; get extent size ;AN000; | ||
| 486 | mul cx ; AX=total cache for this drive ;AN000; | ||
| 487 | mov es:[si].BUFF_SIZE,ax ; save it as initial available size ;AN000; | ||
| 488 | mov es:[si].FREE_SIZE,ax ; save it as initial free size | ||
| 489 | add ax, size Drive_Header ; (2/9/88) | ||
| 490 | add ax,si ; AX-->offset to next drive hdr ;AN000; | ||
| 491 | mov es:[si].Next_Drv_hdr_Ptr,ax ; save next drive header ptr in ;AN000; | ||
| 492 | ; current drive header ;AN000; | ||
| 493 | mov bx,ax ;AN000; | ||
| 494 | mov ax,si ; save current header pointer ;AN000; | ||
| 495 | mov si,bx ; DS:SI-->next drive header ;AN000; | ||
| 496 | ;AN000; | ||
| 497 | SKIP_THIS_DRIVE: ;AN000; | ||
| 498 | add dx,4 ; update index to next drive/extent ;AN000; | ||
| 499 | pop cx ; restore loop count ;AN000; | ||
| 500 | LOOP init_loop ; repeat for next drive number ;AN000; | ||
| 501 | ;AN000; | ||
| 502 | mov si,ax ;AN000; | ||
| 503 | mov es:[si].Next_Drv_hdr_Ptr,-1 ; mark current header as last | ||
| 504 | ; drive header | ||
| 505 | ;---------------------------------------------------------------------------- | ||
| 506 | ; Close handles 0 - 4 | ||
| 507 | ;---------------------------------------------------------------------------- | ||
| 508 | mov bx,0 | ||
| 509 | Handle_Loop: | ||
| 510 | mov ah,03EH | ||
| 511 | INT 21H | ||
| 512 | inc bx | ||
| 513 | cmp bx,5 | ||
| 514 | jne Handle_Loop | ||
| 515 | |||
| 516 | ;---------------------------------------------------------------------------- | ||
| 517 | ; Get PSP segment and find the program environment segment and deallocate | ||
| 518 | ; the environment space. | ||
| 519 | ;---------------------------------------------------------------------------- | ||
| 520 | INIT_EXIT: | ||
| 521 | push ds | ||
| 522 | mov si,0081H | ||
| 523 | mov ah,62H | ||
| 524 | INT 21H ; get program PSP segment ;AN000; | ||
| 525 | |||
| 526 | mov ds,bx ; DS = PSP segment ;AN000; | ||
| 527 | mov si,02CH ; SI-->address of enviroment segment | ||
| 528 | mov ax,[si] ; AX = environment seg id | ||
| 529 | cmp ax,0 ; environment present ?? | ||
| 530 | je dont_dealloc ; no - dont deallocate | ||
| 531 | mov es,ax | ||
| 532 | mov ah,49H | ||
| 533 | INT 21H ; deallocate environment | ||
| 534 | Dont_Dealloc: | ||
| 535 | pop ds ; restore DS | ||
| 536 | |||
| 537 | ;---------------------------------------------------------------------------- | ||
| 538 | ; Keep resident the Fastopen code and cache buffers. The size of the resident | ||
| 539 | ; area is in (Main_Res_Segs). Size may vary depending on whether Fastopen or | ||
| 540 | ; Fastseek or both or extent memory is specified. | ||
| 541 | ;---------------------------------------------------------------------------- | ||
| 542 | |||
| 543 | IF BUFFERFLAG | ||
| 544 | |||
| 545 | call restore_page_state ; HKN 8/25/88 | ||
| 546 | |||
| 547 | ENDIF | ||
| 548 | |||
| 549 | mov ah,KEEP_PROCESS ;remain resident | ||
| 550 | mov al,0 ;return code | ||
| 551 | mov dx,Main_Res_Segs ;size of area in paragraph | ||
| 552 | INT 21h ;keep resident and then return | ||
| 553 | ;control to DOS | ||
| 554 | |||
| 555 | ;---------------------------------------------------------------------------- | ||
| 556 | ; Calculate the size of the MAIN module in bytes. First potion of this | ||
| 557 | ; segment can be found in the Fastopen.asm | ||
| 558 | ;---------------------------------------------------------------------------- | ||
| 559 | IF ($-Cseg_Main) MOD 16 ;AN000; | ||
| 560 | ORG ($-Cseg_Main)+16-(($-Cseg_Main) MOD 16) ;AN000; | ||
| 561 | ENDIF ;AN000; | ||
| 562 | End_Main label word ;AN000; | ||
| 563 | |||
| 564 | |||
| 565 | CSEG_MAIN ENDS ; End of Cseg_Main segment | ||
| 566 | page | ||
| 567 | |||
| 568 | |||
| 569 | ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ | ||
| 570 | |||
| 571 | CSEG_INIT SEGMENT PUBLIC PARA 'CODE' | ||
| 572 | |||
| 573 | ;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ | ||
| 574 | ASSUME cs:cseg_init,ds:cseg_init,ss:stack,es:cseg_init | ||
| 575 | |||
| 576 | EXTRN SYSPARSE:NEAR ;AN000; | ||
| 577 | EXTRN SYSLOADMSG:NEAR ;AN000; | ||
| 578 | EXTRN SYSDISPMSG:NEAR ;AN000; | ||
| 579 | |||
| 580 | IF BUFFERFLAG | ||
| 581 | extrn save_ems_page_state:far ; HKN 8/25/88 | ||
| 582 | ENDIF | ||
| 583 | |||
| 584 | |||
| 585 | ;---------------------------------------------------------------------------- | ||
| 586 | ; The cache buffers start from the first location of Cseg_Init. | ||
| 587 | ; First portion is the NAME DRIVE HEADERS, which is followed by | ||
| 588 | ; NAME CACHE BUFFER, which is followed by EXTENT DRIVE HEADER. Under each | ||
| 589 | ; extent drive header its cache buffer. 24 Name drive buffers are allocated | ||
| 590 | ; during assembly time. Remaining drive and cache buffers are allocated | ||
| 591 | ; during run time. Eventhough 24 name cache buffers are allocated during | ||
| 592 | ; assembly time, this number may be reduced to the specified number of drive | ||
| 593 | ; numbers during run time by overlaying other drive buffers over the unused ones. | ||
| 594 | ; The initialization code will be overlayed by name and extent cache buffs | ||
| 595 | ; during second half of the initialization which is in the MAIN module (see INit_Tree). | ||
| 596 | ;----------------------------------------------------------------------------- | ||
| 597 | |||
| 598 | Drive_header_start label byte ;Name cache drive buffer | ||
| 599 | Drive_Cache Drive_Cache_Header max_drives DUP (<>) ; header for 24 drives are reserved | ||
| 600 | |||
| 601 | ;----------------------------------------------------------------------------- | ||
| 602 | ; Anything below this point will be overlayed by the Cache Buffers | ||
| 603 | ; MSG retriever is placed after Cache buffer, so that the area can be | ||
| 604 | ;----------------------------------------------------------------------------- | ||
| 605 | ;============================================================================= | ||
| 606 | ; Non_Resident Data Area | ||
| 607 | ;============================================================================= | ||
| 608 | INIT_VECTOR DD INIT_TREE ;jump vector to INIT_TREE ;AN000; | ||
| 609 | MAIN_VECTOR DD MAIN ;entry point to MAIN routine ;AN000; | ||
| 610 | source_xname DB " :\",0 ;used for xname translate ;AN000; | ||
| 611 | target_xname DB 65 DUP (0) ;used for xname translate ;AN000; | ||
| 612 | user_drive db 0 ;current user drive ;AN000; | ||
| 613 | psp_seg dw 0 ;segment of psp ;AN000; | ||
| 614 | stack_seg_start dw 0 ;segment of temporary stack ;AN000; | ||
| 615 | stack_seg_end dw 0 ;AN000; | ||
| 616 | num_of_drives dw 0 ;number of user specified drives ;AN000; | ||
| 617 | Ext_Mem dw 0 ;=1 if exteded memory is enabled ;AN000; | ||
| 618 | drive_id db " :",0 ;AN000; | ||
| 619 | Parambuff db 50 dup (0) | ||
| 620 | Parmbuff_Ptr dw 0 ;AN000; | ||
| 621 | FRAME_COUNT dw 0 ;EMS frame count | ||
| 622 | |||
| 623 | IF IBMCOPYRIGHT | ||
| 624 | |||
| 625 | FRAME_BUFFER DB 30h DUP(0) ;EMS frame buffer | ||
| 626 | |||
| 627 | ELSE | ||
| 628 | |||
| 629 | FRAME_BUFFER DB 100h DUP(0) ; EMS frame buffer | ||
| 630 | |||
| 631 | ENDIF | ||
| 632 | |||
| 633 | IF BUFFERFLAG | ||
| 634 | FST_PAGE DW 0,0 ; holds the second highest page above 640k | ||
| 635 | ENDIF | ||
| 636 | |||
| 637 | Cmdline_buff db 135 dup (0) ;command line buffer ;AN000; | ||
| 638 | name_cache_seg dw Cseg_Init ;default to Init1 seg ;AN000; | ||
| 639 | Ext_Count dw 0 ;total name extent entries ;AN000; | ||
| 640 | extent_drive_Buff dw 0 ;ptr to extent drive ;AN000; | ||
| 641 | name_cache_Buff dw 0 ;pointer to Name cache buffer ;AN000; | ||
| 642 | EMS_FLAG dw 0 ;EMI flag 1= if EMI is enabled ;AN000; | ||
| 643 | CHECK_QUEUE dw 0 ; = 1 if analyser is activated | ||
| 644 | RES_SEGS dw 010H+020H ;PSP SIZE + STACK SIZE resident segment size | ||
| 645 | EMS_PAGE_SEG DW 0 ;EMS code page segment ID ;AN000; | ||
| 646 | EMS_PAGE_NUM DW 0 ;EMS physical page number ;AN000; | ||
| 647 | Total_Ext_Count DW 0 ;Total extent entry count ;AN000; | ||
| 648 | Total_Name_Count DW 0 ;Total Name entry count ;AN000; | ||
| 649 | Total_Cache_Size DW 0 ;Total cache buffer size (name+extent) buffer ;AN000; | ||
| 650 | Name_Cache_Size DW 0 ;Total name cache size (header + entry buffs) | ||
| 651 | Name_Count DW 0 ;name entry count | ||
| 652 | Name_Drive_Buff DW 0 ;name driver buffer address ;AN000; | ||
| 653 | Ext_Cache_Size DW 0 ;extent buffer size ;AN000; | ||
| 654 | Open_SegID DW 0 ;SegId of Cseg_Open after relocation ;AN000; | ||
| 655 | Seek_SegID DW 0 ;SegId of Cseg_Seek " " ;AN000; | ||
| 656 | Init_SegID DW 0 ;SegId of Cseg_Init " " ;AN000; | ||
| 657 | MAIN_Size DW 0 ;size of Cseg_Main in Paragraph ;AN000; | ||
| 658 | OPEN_Size DW 0 ;size of Cseg_Open in paragraph ;AN000; | ||
| 659 | SEEK_Size DW 0 ;size of Cseg_Seek in paragraph ;AN000; | ||
| 660 | |||
| 661 | ;-----------------------------------------------------------------------; | ||
| 662 | ; EMS Support ; | ||
| 663 | ;-----------------------------------------------------------------------; | ||
| 664 | EXT_HANDLE DW ? ; EMS handle for reference ;AN000; | ||
| 665 | EMS_PAGESIZE DW ? ; EMS handle for reference ;AN000; | ||
| 666 | EMS_FRAME_ADDR DW ? ; EMS handle for reference ;AN000; | ||
| 667 | CURR_EMS_PAGE DB ? ; Current EMS page number ;AN000; | ||
| 668 | HANDLE_NAME DB 'FASTOPEN',0 ; EMS handle name ;AN000; | ||
| 669 | |||
| 670 | IF BUFFERFLAG | ||
| 671 | SAVE_MAP_ADDR DD ? ; HKN 8/25/88 | ||
| 672 | ENDIF | ||
| 673 | |||
| 674 | ;--------------------------------------------------------------------------- | ||
| 675 | ; PARSER Support | ||
| 676 | ;--------------------------------------------------------------------------- | ||
| 677 | CURRENT_PARM DW 81H ;POINTER INTO COMMAND OF CUREENT OPERANT ;AN000; | ||
| 678 | NEXT_PARM DW 0 ;POINTER INTO COMMAND OF NEXT OPERAND ;AN000; | ||
| 679 | ORDINAL DW 0 ;ORDINAL NUMBER OF MAIN PARSER LOOP ;AN000; | ||
| 680 | ORDINAL1 DW 0 ;ORDINAL NUMBER OF COMPLEX ITEM LOOP ;AN000; | ||
| 681 | PREV_TYPE DB 0 ;PREVIOUS POSITIONAL PARAMETER TYPE | ||
| 682 | |||
| 683 | ;--------------------------------------------------------------------------- | ||
| 684 | ; PRINT_STDOUT input parameter save area | ||
| 685 | ;---------------------------------------------------------------------------- | ||
| 686 | SUBST_COUNT DW 0 ;message substitution count ;AN000; | ||
| 687 | MSG_CLASS DB 0 ;message class ;AN000; | ||
| 688 | INPUT_FLAG DB 0 ;Type of INT 21 used for KBD ;AN000; | ||
| 689 | MSG_NUM DW 0 ;message number ;AN000; | ||
| 690 | |||
| 691 | |||
| 692 | ;---------------------------------------------------------------------------- | ||
| 693 | ; Following three sublists are used by the Message Retriever | ||
| 694 | ;---------------------------------------------------------------------------- | ||
| 695 | SUBLIST1 LABEL DWORD ;SUBSTITUTE LIST 1 | ||
| 696 | DB 11 ;sublist size ;AN000; | ||
| 697 | DB 0 ;reserved ;AN000; | ||
| 698 | DD 0 ;substition data Offset ;AN000; | ||
| 699 | DB 1 ;n of %n ;AN000; | ||
| 700 | DB 0 ;data type ;AN000; | ||
| 701 | DB 0 ;maximum field width ;AN000; | ||
| 702 | DB 0 ;minimum field width ;AN000; | ||
| 703 | DB 0 ;characters for Pad field ;AN000; | ||
| 704 | |||
| 705 | |||
| 706 | SUBLIST2 LABEL DWORD ;SUBSTITUTE LIST 2 | ||
| 707 | DB 11 ;sublist size ;AN000; | ||
| 708 | DB 0 ;reserved ;AN000; | ||
| 709 | DD 0 ;substition data Offset ;AN000; | ||
| 710 | DB 2 ;n of %n ;AN000; | ||
| 711 | DB 0 ;data type ;AN000; | ||
| 712 | DB 0 ;maximum field width ;AN000; | ||
| 713 | DB 0 ;minimum field width ;AN000; | ||
| 714 | DB 0 ;characters for Pad field ;AN000; | ||
| 715 | |||
| 716 | |||
| 717 | |||
| 718 | ;-------------------------------------------------------------------------- | ||
| 719 | ; PARSER Control Blocks and Buffers | ||
| 720 | ;-------------------------------------------------------------------------- | ||
| 721 | |||
| 722 | PARMS label word | ||
| 723 | DW parmsx ;AN000; | ||
| 724 | DB 1 ; number of delemeters ;AN000; | ||
| 725 | DB 1 ; extra delimeters length ;AN000; | ||
| 726 | DB "=" ; extra delimeter expected ;AN000; | ||
| 727 | DB 0 ; extra end of line length ;AN000; | ||
| 728 | DB 0 ;AN000; | ||
| 729 | |||
| 730 | |||
| 731 | PARMSX label byte ;AN000; | ||
| 732 | par_min DB 1 ; min, max positional operands allowed ;AN000; | ||
| 733 | par_max DB 2 ; min, max positional operands allowed ;AN000; | ||
| 734 | DW Pos1 ; offset into positonal-1 control block ;AN000; | ||
| 735 | DW Pos2 ; offset into positonal-1 control block ;AN000; | ||
| 736 | par_sw DB 1 ; one switch ;AN000; | ||
| 737 | DW Switch ; offset into switch-1 control bloc ;AN000; | ||
| 738 | DB 0 ; no keywords ;AN000; | ||
| 739 | DB 0 ; 0 ;AN000; | ||
| 740 | |||
| 741 | |||
| 742 | |||
| 743 | ;------------------ POS2 CONTROL BLOCK -------------------------------------- | ||
| 744 | |||
| 745 | POS1 label word ; positional-1 control definition | ||
| 746 | Pos1Type DW 0100H ; control type flag (drive only) ;AN000; | ||
| 747 | DW 0 ; function flags ;AN000; | ||
| 748 | DW Result ; offset into result buffer ;AN000; | ||
| 749 | DW value_pos1 ; offset value list buffer ;AN000; | ||
| 750 | DB 0 ; number of keyword/switch synonyms ;AN000; | ||
| 751 | |||
| 752 | |||
| 753 | Value_Pos1 label byte ; postional parameter value expected ;AN000; | ||
| 754 | DB 0 ; no values expected ;AN000; | ||
| 755 | |||
| 756 | |||
| 757 | |||
| 758 | ;---------------- POS1 CONTROL BLOCK ---------------------------------------- | ||
| 759 | |||
| 760 | POS2 label word ; positional-2 control definition ;AN000; | ||
| 761 | Pos2Type DW 08502H ; Control type (complex/integer/drive/ ;AN000; | ||
| 762 | ; repeat) ;AN000; | ||
| 763 | DW 0 ; function flags ;AN000; | ||
| 764 | DW Result ; offset into result buffer ;AN000; | ||
| 765 | DW value_pos2 ; offset value list buffer ;AN000; | ||
| 766 | DB 0 ; number of keyword/switch synonyms ;AN000; | ||
| 767 | |||
| 768 | Value_Pos2 label byte | ||
| 769 | DB 0 ; either (n) or (m) will be returned | ||
| 770 | |||
| 771 | |||
| 772 | |||
| 773 | ;--------------- RESULT BUFFER --------------------------------------------- | ||
| 774 | |||
| 775 | RESULT label byte ; postional2 parameter result buffer ;AN000; | ||
| 776 | PosType DB ? ; type of operand returned ;AN000; | ||
| 777 | Postag DB ? ; type of item tage returned ;AN000; | ||
| 778 | synonym DW ? ; offset into synonyms returned ;AN000; | ||
| 779 | valuelo DW ? ; space for drive number/integer/strin ;AN000; | ||
| 780 | valuehi DW ? ;AN000; | ||
| 781 | |||
| 782 | |||
| 783 | ;---------------- SWITCH CONTROL BLOCK ------------------------------------------ | ||
| 784 | |||
| 785 | SWITCH label word ; switch control definition | ||
| 786 | DW 0 ; no match flag ;AN000; | ||
| 787 | DW 0 ; no function flags ;AN000; | ||
| 788 | DW Result ; offset into result buffer ;AN000; | ||
| 789 | DW value_sw1 ; offset value list buffer ;AN000; | ||
| 790 | DB 1 ; number of keyword/switch synonyms ;AN000; | ||
| 791 | E_Switch DB "/X" ; /X option for extended memory access ;AN000; | ||
| 792 | DB 0 ;AN000; | ||
| 793 | |||
| 794 | |||
| 795 | Result_sw1 label byte ; switch parameter result ;AN000; | ||
| 796 | DB ? ; type of operand returned ;AN000; | ||
| 797 | DB ? ; type of item tage returned ;AN000; | ||
| 798 | Swval DW ? ; offset into synonyms returned ;AN000; | ||
| 799 | DB ? ; switch value ;AN000; | ||
| 800 | |||
| 801 | |||
| 802 | Value_sw1 label byte ; switch parameter value expected ;AN000; | ||
| 803 | DB 0 ; no values expected ;AN000; | ||
| 804 | |||
| 805 | |||
| 806 | |||
| 807 | |||
| 808 | |||
| 809 | |||
| 810 | |||
| 811 | ;----------------------------------------------------------------------------- | ||
| 812 | ; INIT (FASTINIT-2) | ||
| 813 | ;----------------------------------------------------------------------------- | ||
| 814 | ; | ||
| 815 | ;SUBROUTINE: INIT | ||
| 816 | ; | ||
| 817 | ;FUNCTION: Performs FASTOPEN initialization function | ||
| 818 | ; | ||
| 819 | ; | ||
| 820 | ;NOTE: This routine is the starting routine of FASTOPEN | ||
| 821 | ; | ||
| 822 | ;----------------------------------------------------------------------------- | ||
| 823 | |||
| 824 | START: | ||
| 825 | ; on entry DS and ES -->PSP ;AN000; | ||
| 826 | push cs ; DS-->Cseg_Init ;AN000; | ||
| 827 | pop ds ;AN000; | ||
| 828 | ASSUME ds:cseg_init ;AN000; | ||
| 829 | mov psp_seg,es ; save PSP segment for later use ;AN000; | ||
| 830 | push cs ;AN000; | ||
| 831 | pop es ; ES-->Cseg_Init ;AN000; | ||
| 832 | ASSUME es:cseg_init ;AN000; | ||
| 833 | |||
| 834 | CALL SYSLOADMSG ; Preload messages ;AN000; | ||
| 835 | jnc Parse_cmd_line ; If no error, parse command line ;AN000; | ||
| 836 | |||
| 837 | mov ax,1 ;AN000; | ||
| 838 | CALL SYSDISPMSG ; display error ;AN000; | ||
| 839 | |||
| 840 | mov ah,04ch ; Terminate ;AN000; | ||
| 841 | mov al,0 ; Errorlevel 0 (Compatible) ;AN000; | ||
| 842 | INT 021h ; exit to DOS | ||
| 843 | |||
| 844 | Parse_Cmd_Line: ;AN000; | ||
| 845 | CALL PARSE ;Parse command line ;AN000; | ||
| 846 | lea si,parambuff ;drive ID buff address ;AN000; | ||
| 847 | mov ax,Total_name_Count ; ;AN000; | ||
| 848 | mov ax,Total_ext_Count ;AN000; | ||
| 849 | mov ax,num_of_drives ;AN000; | ||
| 850 | mov ax,ext_mem ;AN000; | ||
| 851 | jnc Check_Installed ;no, check if Fastopen already installed | ||
| 852 | jmp error_exit ;yes - exit ;AN000; | ||
| 853 | |||
| 854 | Check_Installed: | ||
| 855 | CALL CHECK_INSTALL ; Fastopen installed ?? | ||
| 856 | jnc Save_SegIDs ; no - save segment IDs | ||
| 857 | jmp error_exit ; yes - exit | ||
| 858 | |||
| 859 | ;----------------------------------------------------------------------------- | ||
| 860 | ; Set seg IDs of three segments. | ||
| 861 | ;----------------------------------------------------------------------------- | ||
| 862 | Save_SegIds: | ||
| 863 | mov Open_SegID, Cseg_Open ;AN000; | ||
| 864 | mov Seek_SegID, Cseg_Seek ;AN000; | ||
| 865 | mov Init_SegID, Cseg_Init ;AN000; | ||
| 866 | |||
| 867 | ;----------------------------------------------------------------------------- | ||
| 868 | ; Compute the size of segments and cache buffers. Setup a temporary stack | ||
| 869 | ; to be used by the second half of initilization. | ||
| 870 | ;----------------------------------------------------------------------------- | ||
| 871 | CALL CHECK_MEM ;See if we have enough memory ;AN000; | ||
| 872 | jnc chk_extended_mem ;yes, check for extended memory ;AN000; | ||
| 873 | jmp error_exit ;no - display not enough mem msg ;AN000; | ||
| 874 | |||
| 875 | ;----------------------------------------------------------------------------- | ||
| 876 | ; Check if Extended Memeory is specified. If true, check if Extended memory is | ||
| 877 | ; available. Get segid of one extended memory page. | ||
| 878 | ;----------------------------------------------------------------------------- | ||
| 879 | Chk_Extended_Mem: | ||
| 880 | cmp ext_mem,1 ; enable EMS ?? ;AN000; | ||
| 881 | jne Set_Data_Areas ; no, set data areas ;AN000; | ||
| 882 | |||
| 883 | CALL SET_EMS ; set expanded memory ;AN000; | ||
| 884 | jnc Set_Data_Areas ; if no error ;AN000; | ||
| 885 | jmp error_exit ; error exit ;AN000; | ||
| 886 | |||
| 887 | ;------------------------------------------------------------------------------ | ||
| 888 | ; Copy Data and segid of Init segments to Main, Open and Seek segments. | ||
| 889 | ; If code is relocated, segids have to be adjusted later. (See Adjust_SegID) | ||
| 890 | ;------------------------------------------------------------------------------ | ||
| 891 | Set_Data_Areas: | ||
| 892 | CALL COPY_DATA ; copy data to other segments ;AN000; | ||
| 893 | |||
| 894 | ;----------------------------------------------------------------------------- | ||
| 895 | ; Relocate code to extended memory if extended memory is specified or | ||
| 896 | ; relocate in lower memory itself. | ||
| 897 | ;----------------------------------------------------------------------------- | ||
| 898 | Relocate_Code: | ||
| 899 | CALL RELOCATE_SEGMENT ; Relocate the code cnd buffers ;AN000; | ||
| 900 | |||
| 901 | ;----------------------------------------------------------------------------- | ||
| 902 | ; Adjust the segids and jump vectors in other segments after code relocation | ||
| 903 | ;----------------------------------------------------------------------------- | ||
| 904 | CALL ADJUST_SEGIDS ; adjust segment ids after relocation ;AN000; | ||
| 905 | |||
| 906 | ;----------------------------------------------------------------------------- | ||
| 907 | ; Display FASTOPEN INSTALLED message. This must be done prior to the actual | ||
| 908 | ; installation. | ||
| 909 | ;----------------------------------------------------------------------------- | ||
| 910 | Disp_Install_Msg: ; display FASTOPEN installed message | ||
| 911 | MOV AX,INSTALL1 ; message number ;AN000; | ||
| 912 | MOV MSG_NUM,AX ; set message number ;AN000; | ||
| 913 | MOV SUBST_COUNT,0 ; no message ;AN000; | ||
| 914 | MOV MSG_CLASS,-1 ; message class ;AN000; | ||
| 915 | MOV INPUT_FLAG,0 ; no input ;AN000; | ||
| 916 | CALL PRINT_STDOUT ; show message ;AN000; | ||
| 917 | |||
| 918 | ;----------------------------------------------------------------------------- | ||
| 919 | ; Install Fastopen | ||
| 920 | ;----------------------------------------------------------------------------- | ||
| 921 | CALL INSTALL_FASTOPEN ; Install Fastopen ;AN000; | ||
| 922 | jnc Setup_Stack ; Installed Ok, setup stack ;AN000; | ||
| 923 | jmp error_exit ; error - exit | ||
| 924 | |||
| 925 | |||
| 926 | ;---------------------------------------------------------------------------- | ||
| 927 | ; Set Stack Values. This stack is used by the cache buffer initilization | ||
| 928 | ; portion of the code. This stack area will be eventually overlayed and | ||
| 929 | ; wont be used by either Fastopen or Fastseek functions in MAIN module. | ||
| 930 | ;---------------------------------------------------------------------------- | ||
| 931 | SETUP_STACK: | ||
| 932 | nop ;AN000; | ||
| 933 | CLI ;no interrupts allowed during stach change ;AN000; | ||
| 934 | mov SS,Stack_Seg_Start ;set up new stack ;AN000; | ||
| 935 | mov SP,0 ; ;AN000; | ||
| 936 | STI ;interrupts ok now ;AN000; | ||
| 937 | jmp INIT_VECTOR ;Jump to Cseg_Main to do second | ||
| 938 | ;phase of the initialization | ||
| 939 | ERROR_EXIT: | ||
| 940 | mov al,1 ;set up return code | ||
| 941 | mov ah,exit ;set function code | ||
| 942 | INT INT_COMMAND ;exit to DOS | ||
| 943 | |||
| 944 | |||
| 945 | |||
| 946 | |||
| 947 | ;---------------------------------------------------------------------------- | ||
| 948 | ; CHECK_INSTALL | ||
| 949 | ;---------------------------------------------------------------------------- | ||
| 950 | ; Input: None | ||
| 951 | ; | ||
| 952 | ; Output: | ||
| 953 | ; IF Carry = 0 - Fastopen is not already installed | ||
| 954 | ; | ||
| 955 | ; IF Carry = 1 - Fastopen is already installed | ||
| 956 | ; | ||
| 957 | ;---------------------------------------------------------------------------- | ||
| 958 | ; Use CALLINSTALL macro to see if FASTOPEN is already installed. | ||
| 959 | ; If carry flag set then FASTOPEN is installed. In this case display | ||
| 960 | ; Already Installed message. | ||
| 961 | ;---------------------------------------------------------------------------- | ||
| 962 | |||
| 963 | CHECK_INSTALL PROC NEAR | ||
| 964 | |||
| 965 | push ax ;save every registers that may | ||
| 966 | push bx ;be destroyed by DOS | ||
| 967 | push cx | ||
| 968 | push dx | ||
| 969 | push si | ||
| 970 | push di | ||
| 971 | push bp | ||
| 972 | |||
| 973 | push ds | ||
| 974 | mov bx, 1 ;Fastopen function code | ||
| 975 | mov si, -1 ;special check install code | ||
| 976 | CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed | ||
| 977 | pop ds | ||
| 978 | jc Install_Msg ;yes, display already installed | ||
| 979 | ;message | ||
| 980 | ;---------------------------------------------------------------------------- | ||
| 981 | ; Check if Fastseek function is enabled. If true display Installed message | ||
| 982 | ;---------------------------------------------------------------------------- ;AN000; | ||
| 983 | push ds ;AN000; | ||
| 984 | mov si, -1 ;special check installed code | ||
| 985 | mov bx, 2 ;for Fastseek | ||
| 986 | CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed ;AN000; | ||
| 987 | pop ds ;AN000; | ||
| 988 | jnc Chk_Install_Exit ; no, exit ;AN000; | ||
| 989 | |||
| 990 | Install_Msg: ;installed previously display message | ||
| 991 | MOV AX,ALREADY_INSTALL ;message number ;AN000; | ||
| 992 | MOV MSG_NUM,AX ;set message number ;AN000; | ||
| 993 | MOV SUBST_COUNT,0 ;no message substitution ;AN000; | ||
| 994 | MOV MSG_CLASS,-1 ;message class ;AN000; | ||
| 995 | MOV INPUT_FLAG,0 ;no input ;AN000; | ||
| 996 | CALL PRINT_STDOUT ;show message "Already Installed" | ||
| 997 | stc | ||
| 998 | |||
| 999 | Chk_Install_Exit: | ||
| 1000 | pop bp ;restore registers | ||
| 1001 | pop di | ||
| 1002 | pop si | ||
| 1003 | pop dx | ||
| 1004 | pop cx | ||
| 1005 | pop bx | ||
| 1006 | pop ax | ||
| 1007 | ret ;return | ||
| 1008 | |||
| 1009 | CHECK_INSTALL ENDP | ||
| 1010 | |||
| 1011 | |||
| 1012 | |||
| 1013 | |||
| 1014 | |||
| 1015 | ;---------------------------------------------------------------------------- | ||
| 1016 | ; INSTALL_FASTOPEN | ||
| 1017 | ;---------------------------------------------------------------------------- | ||
| 1018 | ; Input: Addrss of entry point to Fastopen resident code | ||
| 1019 | ; | ||
| 1020 | ; Output: | ||
| 1021 | ; IF Carry = 0 | ||
| 1022 | ; Entry point to FASTOPEN resident code set | ||
| 1023 | ; | ||
| 1024 | ; IF Carry = 1 Error | ||
| 1025 | ; | ||
| 1026 | ; Calls: none | ||
| 1027 | ;---------------------------------------------------------------------------- | ||
| 1028 | ; Use CALLINSTALL macro to see if FASTOPEN is already installed. | ||
| 1029 | ; If FASTOPEN is not installed, install it. | ||
| 1030 | ; If carry flag set then FASTOPEN is installed. In this case display | ||
| 1031 | ; already installed message. | ||
| 1032 | ;---------------------------------------------------------------------------- | ||
| 1033 | |||
| 1034 | INSTALL_FASTOPEN PROC NEAR | ||
| 1035 | |||
| 1036 | push ax ;Save every registers,point reg since | ||
| 1037 | push bx ;DOS may destroy it. | ||
| 1038 | push cx | ||
| 1039 | push dx | ||
| 1040 | push si | ||
| 1041 | push di | ||
| 1042 | push bp | ||
| 1043 | |||
| 1044 | cmp Total_Name_Count, 0 ;FastOpen enabled ?? ;AN000; | ||
| 1045 | je Install_Ext ;no - jump | ||
| 1046 | |||
| 1047 | push ds ;yes - install fastopen | ||
| 1048 | mov bx, 1 ;tell DOS that this is the | ||
| 1049 | lds si,Main_Vector | ||
| 1050 | CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed | ||
| 1051 | pop ds | ||
| 1052 | jc Install_Exit ;error - exit | ||
| 1053 | |||
| 1054 | ;---------------------------------------------------------------------------- | ||
| 1055 | ; Check if Fastseek functions are enabled. If true, pass MAIN routine entry | ||
| 1056 | ; point and the Fastseek enabled information to DOS | ||
| 1057 | ;---------------------------------------------------------------------------- ;AN000; | ||
| 1058 | Install_Ext: | ||
| 1059 | cmp Total_Ext_Count, 0 ; Fastseek enabled ?? ;AN000; | ||
| 1060 | jne ext_install ; yes - install fastseek ;AN000; | ||
| 1061 | clc ;AN000; | ||
| 1062 | jmp short Install_Exit ; no, exit ;AN000; | ||
| 1063 | |||
| 1064 | Ext_Install: | ||
| 1065 | push ds ;AN000; | ||
| 1066 | mov bx, 2 ;tell DOS that this is the ;AN000; | ||
| 1067 | lds si,Main_Vector ;fastseek entry point ;AN000; | ||
| 1068 | CALLINSTALL fastopencom,multdos,42 ;see if fastopen installed ;AN000; | ||
| 1069 | pop ds ;AN000; | ||
| 1070 | jnc short install_exit | ||
| 1071 | jmp short install_exit | ||
| 1072 | |||
| 1073 | Installx_Msg: ;installed previously display message | ||
| 1074 | MOV AX,ALREADY_INSTALL ;message number ;AN000; | ||
| 1075 | MOV MSG_NUM,AX ;set message number ;AN000; | ||
| 1076 | MOV SUBST_COUNT,0 ;no message substitution ;AN000; | ||
| 1077 | MOV MSG_CLASS,-1 ;message class ;AN000; | ||
| 1078 | MOV INPUT_FLAG,0 ;no input ;AN000; | ||
| 1079 | CALL PRINT_STDOUT ;show message "Already Installed" | ||
| 1080 | stc | ||
| 1081 | |||
| 1082 | Install_Exit: | ||
| 1083 | pop bp ;restore registers | ||
| 1084 | pop di | ||
| 1085 | pop si | ||
| 1086 | pop dx | ||
| 1087 | pop cx | ||
| 1088 | pop bx | ||
| 1089 | pop ax | ||
| 1090 | ret ;return | ||
| 1091 | |||
| 1092 | INSTALL_FASTOPEN ENDP | ||
| 1093 | |||
| 1094 | |||
| 1095 | |||
| 1096 | |||
| 1097 | |||
| 1098 | |||
| 1099 | ;---------------------------------------------------------------------------- | ||
| 1100 | ; CHECK_MEM | ||
| 1101 | ;---------------------------------------------------------------------------- | ||
| 1102 | ; Function: Compute the total size of memory required by the Fasteopen. | ||
| 1103 | ; This includes both code and the cache buffers. | ||
| 1104 | ; | ||
| 1105 | ; Input: Name_Count, extent_count, Drive_cache, num_of_drives | ||
| 1106 | ; | ||
| 1107 | ; Output: Memory is validated, Resident segment size is calculated | ||
| 1108 | ; Temporary stack segment is set | ||
| 1109 | ;---------------------------------------------------------------------------- | ||
| 1110 | CHECK_MEM PROC NEAR ; DS-->Cseg_init | ||
| 1111 | |||
| 1112 | ;** Compute the total resident segment size and then add the cache buffer | ||
| 1113 | ;** size. The Resident segment size should be adjusted again after relocation. | ||
| 1114 | |||
| 1115 | mov Total_Cache_Size,0 ;reset total cache size (Name +Ext) | ||
| 1116 | mov Name_Cache_Size,0 ;reset Name cache buffer size | ||
| 1117 | mov ax, offset End_Main ;size of Main_Seg in bytes ;AN000; | ||
| 1118 | add ax,15 ;AN000; | ||
| 1119 | mov cl,4 ;convert size to paragraph ;AN000; | ||
| 1120 | shr ax,cl ;by dividng by 16 ;AN000; | ||
| 1121 | mov MAIN_Size, ax ;save MAIN segment size in para ;AN000; | ||
| 1122 | add Res_Segs,ax ;update resident seg count ;AN000; | ||
| 1123 | ;AN000; | ||
| 1124 | mov ax, offset End_Open ;size of Open_Seg in bytes ;AN000; | ||
| 1125 | add ax,15 ;AN000; | ||
| 1126 | mov cl,4 ;convert it to paragraph ;AN000; | ||
| 1127 | shr ax,cl ;AN000; | ||
| 1128 | mov OPEN_Size, ax ;save OPEN segment size in para ;AN000; | ||
| 1129 | add RES_SEGS,ax ;update resident seg count ;AN000; | ||
| 1130 | ;AN000; | ||
| 1131 | mov ax, offset End_Seek ;add size of Seek_Seg | ||
| 1132 | add ax,15 ;AN000; | ||
| 1133 | mov cl,4 ;AN000; | ||
| 1134 | shr ax,cl ; convert to para (divide by 16) ;AN000; | ||
| 1135 | mov SEEK_Size, ax ;save Seek segment size in para ;AN000; | ||
| 1136 | add RES_SEGS,ax ;update resident seg count ;AN000; | ||
| 1137 | |||
| 1138 | ;---------------------------------------------------------------------------- | ||
| 1139 | ; Calculate the size of the NAME DRIVE HEADER BUFFERS | ||
| 1140 | ;---------------------------------------------------------------------------- | ||
| 1141 | xor ax,ax ;reset the cache size register | ||
| 1142 | cmp total_Name_Count,0 ;Fastopen enabled ?? | ||
| 1143 | je Check_ext_cache ;no - compute extent cache size | ||
| 1144 | |||
| 1145 | mov bx,offset DRIVE_CACHE ;get beginning of cache buff | ||
| 1146 | xor ax,ax | ||
| 1147 | mov al,size drive_cache_header ;get size of one name entry | ||
| 1148 | mul Num_Of_drives ;get total needed for drive cache | ||
| 1149 | add ax,bx ;set up correct offset | ||
| 1150 | add ax,15 ;round up to paragraph boundary | ||
| 1151 | mov cl,4 | ||
| 1152 | shr ax,cl ;convert to paragraphs | ||
| 1153 | add RES_SEGS,ax ;update resident seg count | ||
| 1154 | mov Total_Cache_Size, ax ;update total cache buff size | ||
| 1155 | mov Name_Cache_Size, ax ;size in paragraph | ||
| 1156 | |||
| 1157 | ; Calculate the offset of the Name cache buffers | ||
| 1158 | shl ax,cl ;AX = offset to Name cache buff | ||
| 1159 | mov NAME_CACHE_BUFF,ax ;save Name cache address | ||
| 1160 | |||
| 1161 | ;----------------------------------------------------------------------------- | ||
| 1162 | ; Compute the size of the NAME CACHE buffer | ||
| 1163 | ;----------------------------------------------------------------------------- | ||
| 1164 | mov ax,size Name_Record | ||
| 1165 | mul Total_Name_Count | ||
| 1166 | add ax,15 ;round up to paragraph boundary | ||
| 1167 | mov cl,4 | ||
| 1168 | shr ax,cl ;convert to paragraphs ( divide 16) | ||
| 1169 | add RES_SEGS,ax ;AX = End of Name cache buffers | ||
| 1170 | add Total_Cache_Size,ax ;update total cache buff size | ||
| 1171 | add Name_Cache_Size, ax ; | ||
| 1172 | |||
| 1173 | Check_Ext_Cache: | ||
| 1174 | cmp total_ext_count,0 ;Fastseek enabled ?? | ||
| 1175 | je Set_Stack ;no, set stack | ||
| 1176 | |||
| 1177 | ;--------------------------------------------------------------------------- | ||
| 1178 | ; Compute the size of the Extent cache including drive headers | ||
| 1179 | ;--------------------------------------------------------------------------- | ||
| 1180 | Compute_Ext_Cache: ;calculate the extent buff offset | ||
| 1181 | mov ax,Name_Cache_Size | ||
| 1182 | mov cl,4 | ||
| 1183 | shl ax,cl ;convert to bytes ( multiply by 16) ;AN000; | ||
| 1184 | mov EXTENT_DRIVE_BUFF, ax ;save EXTENT DRIVE BUFFER address ;AN000; | ||
| 1185 | |||
| 1186 | mov ax, size Drive_Header ;AN000; | ||
| 1187 | mul num_Of_drives ;calc size of drive header buff ;AN000; | ||
| 1188 | mov bx,ax ;save AX in BX ;AN000; | ||
| 1189 | mov ax, size Extent_Header ;size of one extent ;AN000; | ||
| 1190 | mul Total_Ext_Count ;calc size of extent buffers ;AN000; | ||
| 1191 | add ax,bx ;AX = size of extent buff in bytes ;AN000; | ||
| 1192 | mov ext_cache_size,ax ;save it for later use ;AN000; | ||
| 1193 | add ax,15 ;round up to paragraph boundary ;AN000; | ||
| 1194 | mov cl,4 ;AN000; | ||
| 1195 | shr ax,cl ;convert to paragraphs ;AN000; | ||
| 1196 | add RES_SEGS,ax ;update resident seg count ;AN000; | ||
| 1197 | add Total_Cache_Size,ax ;update total cache buff size | ||
| 1198 | |||
| 1199 | |||
| 1200 | ;---------------------------------------------------------------------------- | ||
| 1201 | ; Setup stack segment followed by the extent cache buffers. This is a | ||
| 1202 | ; temporary stack used by the drive buffer initilization code in the | ||
| 1203 | ; Cseg_Main segment. This stack will be overlayed by the cache buffers. | ||
| 1204 | ;---------------------------------------------------------------------------- | ||
| 1205 | Set_Stack: | ||
| 1206 | mov ax,RES_SEGS ;AX=size of code and buffs in para | ||
| 1207 | add ax,PSP_Seg ;AX=segID of stack | ||
| 1208 | mov Stack_Seg_Start,ax ;start of the new STACK | ||
| 1209 | add ax,20h ;add the size of the stack | ||
| 1210 | mov Stack_Seg_End,ax ;get end of what we need | ||
| 1211 | |||
| 1212 | push ds ; | ||
| 1213 | mov ds,PSP_Seg ;access PSP for memory size | ||
| 1214 | mov si,Top_mem | ||
| 1215 | LODSW ;get total memory size | ||
| 1216 | pop ds | ||
| 1217 | sub ax,Stack_Seg_End ;see if there is enough for us | ||
| 1218 | jc Not_Enough_Memory ;no - error exit | ||
| 1219 | sub ax,1000h ;will there still be 64K ?? | ||
| 1220 | jnc Check_Reloc_Size ;and return | ||
| 1221 | |||
| 1222 | Not_Enough_Memory: | ||
| 1223 | MOV AX,NOT_ENOUGH_MEM ;message number ;AN000; | ||
| 1224 | MOV MSG_NUM,AX ;set message number ;AN000; | ||
| 1225 | MOV SUBST_COUNT,0 ;no message substitution ;AN000; | ||
| 1226 | MOV MSG_CLASS,-1 ;message class ;AN000; | ||
| 1227 | MOV INPUT_FLAG,0 ;no input ;AN000; | ||
| 1228 | CALL PRINT_STDOUT ;show message "Insufficient Memory" ;AN000; | ||
| 1229 | stc ;set error flag ;AN000; | ||
| 1230 | jmp short Set_Mem_Ret ;return ;AN000; | ||
| 1231 | |||
| 1232 | ;------------------------------------------------------------------------------ | ||
| 1233 | ; If relocation is needed, then recalculate the size of resident segment | ||
| 1234 | ; If extended memory relocation, OPEN, SEEK and INIT segments will be | ||
| 1235 | ; eliminated from the current resident seg. | ||
| 1236 | ;----------------------------------------------------------------------------- | ||
| 1237 | Check_Reloc_Size: | ||
| 1238 | cmp Ext_Mem,1 ; extended memory relocation ?? | ||
| 1239 | jne Set_Mem_Exit ; no - exit ;AN000; | ||
| 1240 | |||
| 1241 | ;----------------------------------------------------------------------------- | ||
| 1242 | ; Check to see that the both code and the cache buffers fit in the | ||
| 1243 | ; exteneded memory one 16K page. Since the entire code segment and the | ||
| 1244 | ; cache buffers are going to be moved to XMA, that amount should be | ||
| 1245 | ; reduced from the size that should reside in the low memory. | ||
| 1246 | ;----------------------------------------------------------------------------- | ||
| 1247 | xor ax,ax | ||
| 1248 | xor bx,bx | ||
| 1249 | cmp total_Name_Count,0 ;Fastseek enabled ?? | ||
| 1250 | je Skip_name_size ;no - skip name size | ||
| 1251 | mov ax, OPEN_SIZE ;size of Open seg in para ;AN000; | ||
| 1252 | Skip_Name_Size: | ||
| 1253 | cmp total_ext_count,0 ;Fastseek enabled ?? | ||
| 1254 | je Skip_Ext_Size ;no - skip extent size | ||
| 1255 | mov bx, SEEK_Size ;size of Seek_Seg in para ;AN000; | ||
| 1256 | Skip_Ext_Size: | ||
| 1257 | add ax,bx | ||
| 1258 | add ax, Total_Cache_Size ;size of Init_Seg in para ;AN000; | ||
| 1259 | cmp ax, 0404H ;Less than 16K ?? ;AN000; | ||
| 1260 | jge Not_Enough_Space ;no - display message ;AN000; | ||
| 1261 | |||
| 1262 | mov ax, OPEN_SIZE ;size of Open seg in para ;AN000; | ||
| 1263 | add ax, SEEK_Size ;size of Seek_Seg in para ;AN000; | ||
| 1264 | add ax, Total_Cache_Size ;reduce resident seg size ;AN000; | ||
| 1265 | sub RES_SEGS,ax ;update resident seg count ;AN000; | ||
| 1266 | |||
| 1267 | ;----------------------------------------------------------------------------- | ||
| 1268 | ; If the code is to be moved to extended memory. There is no reason to | ||
| 1269 | ; keep Init_Tree in main memory. Remove that also to save space in base memory | ||
| 1270 | ;----------------------------------------------------------------------------- | ||
| 1271 | mov ax, offset End_Main1 ;size of Main_Seg until Init_Tree (bytes) ;AN000; | ||
| 1272 | add ax,15 ;AN000; | ||
| 1273 | mov cl,4 ;convert size to paragraph ;AN000; | ||
| 1274 | shr ax,cl ;by dividng by 16 ;AN000; | ||
| 1275 | mov bx,Main_Size ;bx=total size of Main seg including Init_Tree | ||
| 1276 | sub bx,ax ;bx=size after reducing Init_Tree | ||
| 1277 | sub RES_SEGS,bx ;update base memory resident seg count ;AN000; | ||
| 1278 | jmp short Set_Mem_Exit | ||
| 1279 | ; | ||
| 1280 | Not_Enough_Space: | ||
| 1281 | MOV AX,NO_PAGE_SPACE ; not enough space in EMS page | ||
| 1282 | MOV MSG_NUM,AX ; set message number | ||
| 1283 | MOV SUBST_COUNT,0 ; no message | ||
| 1284 | MOV MSG_CLASS,-1 ; message class | ||
| 1285 | MOV INPUT_FLAG,0 ; no input | ||
| 1286 | CALL PRINT_STDOUT ; display message | ||
| 1287 | mov Ext_Mem, 0 ; RESET XMA FLAG | ||
| 1288 | stc | ||
| 1289 | jmp set_mem_ret | ||
| 1290 | |||
| 1291 | Set_Mem_Exit: ;AN000; | ||
| 1292 | clc ;AN000; | ||
| 1293 | |||
| 1294 | Set_Mem_Ret: | ||
| 1295 | ret ;AN000; | ||
| 1296 | |||
| 1297 | CHECK_MEM endp | ||
| 1298 | |||
| 1299 | |||
| 1300 | |||
| 1301 | |||
| 1302 | |||
| 1303 | ;---------------------------------------------------------------------------- | ||
| 1304 | ; RELOCATE | ||
| 1305 | ;---------------------------------------------------------------------------- | ||
| 1306 | ; Function: Relocate Fastopen code and buffer in base memory or in | ||
| 1307 | ; Extended Memory. If base memory relocation, then | ||
| 1308 | ; relocate Cseg_Seek over Cseg_Open segment if the user | ||
| 1309 | ; didn't specify Fastopen (n). Relocate Cseg_Init over Cseg_Seek | ||
| 1310 | ; if user didn't specify Fastseek feature(m). If extended memory | ||
| 1311 | ; relocation, copy Cseg_Open, Cseg_Seek and Cseg_Init to | ||
| 1312 | ; a single page in extented memory if both Fastopen and Fastseek | ||
| 1313 | ; (n and m) are specified. Copy Cseg_open and Cseg_Init only if Fastseek | ||
| 1314 | ; feature (m) is not specified. Copy Cseg_Seek and Cseg_Init if | ||
| 1315 | ; FastOpen feature (n) is not specified | ||
| 1316 | ; | ||
| 1317 | ;---------------------------------------------------------------------------- | ||
| 1318 | |||
| 1319 | RELOCATE_SEGMENT PROC NEAR | ||
| 1320 | cmp Ext_Mem,1 ; Extended memory enabled ?? ;AN000; | ||
| 1321 | je Set_Seg_Ids ; yes - do extented memory relocation | ||
| 1322 | jmp Reloc_Low_Mem ; no - do low memory relocation ;AN000; | ||
| 1323 | |||
| 1324 | ;---------------------------------------------------------------------------- | ||
| 1325 | ; Move Fastopen, FastSeek or both to the Extended memory | ||
| 1326 | ;---------------------------------------------------------------------------- | ||
| 1327 | Set_Seg_Ids: | ||
| 1328 | cld ; clear direction flag (increment si and di) | ||
| 1329 | cmp Total_Name_Count,0 ; Fastopen enabled ?? | ||
| 1330 | jne Set_Open_Seg ; yes - set open seg in extented memory | ||
| 1331 | |||
| 1332 | mov ax,EMS_Page_Seg ; AX = seg id of Cseg_Seek in ext mem | ||
| 1333 | mov Seek_SegID,ax ; save it | ||
| 1334 | jmp Set_Seek_Seg ; no - fastopen, set Seek segment | ||
| 1335 | |||
| 1336 | ;----------------------------------------------------------------------------- | ||
| 1337 | ; ---- Extended Memory Relocation ----- | ||
| 1338 | ; Setup Cseg_Open segment in Extended Memory | ||
| 1339 | ;------------------------------------------------------------------------------ | ||
| 1340 | Set_Open_Seg: | ||
| 1341 | mov ax,Cseg_Init ; | ||
| 1342 | mov ds,ax ; DS-->Cseg_Init | ||
| 1343 | ASSUME ds:Cseg_Init | ||
| 1344 | mov ax,EMS_Page_Seg ; AX = seg id of Cseg_Open in ext mem | ||
| 1345 | mov Open_SegID,ax ; save it | ||
| 1346 | |||
| 1347 | Copy_Open_Seg: | ||
| 1348 | mov ax, offset End_Open ; size of Open seg in bytes ;AN000; | ||
| 1349 | mov cl,1 | ||
| 1350 | shr ax,cl ; convert to words ;AN000; | ||
| 1351 | mov cx,ax ; CX = number of WORDS to transfer ;AN000; | ||
| 1352 | xor si,si ; offset of the source in low memory ;AN000; | ||
| 1353 | xor di,di ; offset of the destination in XMA ;AN000; | ||
| 1354 | mov ax,Cseg_Open ; set source segID ;AN000; | ||
| 1355 | mov ds,ax ; DS-->Cseg_Open ;AN000; | ||
| 1356 | ASSUME ds:Cseg_Open ;AN000; | ||
| 1357 | mov ax,Open_SegID ; set destination XMA seg id ;AN000; | ||
| 1358 | mov es,ax ; ES-->Extended memory page ;AN000; | ||
| 1359 | ASSUME es:nothing ;AN000; | ||
| 1360 | REP MOVSW ; copy Open segment to extended memory | ||
| 1361 | ; SI-->Cseg_Seek segment | ||
| 1362 | mov ax,Cseg_Init ; no - only Fastseek specified | ||
| 1363 | mov ds,ax ; DS-->Cseg_Init | ||
| 1364 | ASSUME ds:Cseg_Init | ||
| 1365 | cmp Total_Ext_Count,0 ; Fastseek enabled ?? | ||
| 1366 | jne Set_Seek_id ; yes -set seek id | ||
| 1367 | |||
| 1368 | mov ax,Cseg_Seek ; only Fastopen is enabled ;AN000; | ||
| 1369 | sub ax,Cseg_Open ; AX = size of Cesg_Open segment ;AN000; | ||
| 1370 | add ax,EMS_Page_Seg ; AX = new seg ID of Cseg_Init in ext ;AN000; | ||
| 1371 | mov Init_SegID,ax ; only if Fastopen is specified ;AN000; | ||
| 1372 | jmp Copy_Init_Seg ; copy init_seg to extended memory | ||
| 1373 | |||
| 1374 | ;----------------------------------------------------------------------------- | ||
| 1375 | ; Setup Cseg_Seek segment in Extended Memory | ||
| 1376 | ;------------------------------------------------------------------------------ | ||
| 1377 | Set_Seek_Id: | ||
| 1378 | mov ax,Cseg_Seek ; | ||
| 1379 | sub ax,Cseg_Open ; AX = size of Cesg_Open segment ;AN000; | ||
| 1380 | add ax,EMS_Page_Seg ; AX = new seg ID of Cseg_Seek in ;AN000; | ||
| 1381 | mov Seek_SegID,ax ; extended memory ;AN000; | ||
| 1382 | jmp Copy_Seek_Seg | ||
| 1383 | |||
| 1384 | Set_Seek_Seg: ; only Fastseek is specified | ||
| 1385 | xor si,si ; offset of the source in low memory ;AN000; | ||
| 1386 | xor di,di ; offset of the destination in XMA ;AN000; | ||
| 1387 | |||
| 1388 | Copy_Seek_Seg: | ||
| 1389 | mov ax, offset End_Seek ;size of Cseg_Seek in bytes ;AN000; | ||
| 1390 | mov cl,1 | ||
| 1391 | shr ax,cl ; convert to words ;AN000; | ||
| 1392 | mov cx,ax ; CX = number of WORDS to transfer ;AN000; | ||
| 1393 | xor si,si ; offset of the source in low memory ;AN000; | ||
| 1394 | xor di,di ; offset of the destination in XMA ;AN000; | ||
| 1395 | mov ax,Cseg_Seek ; set source segID ;AN000; | ||
| 1396 | mov ds,ax | ||
| 1397 | ASSUME ds:Cseg_Seek ;AN000; | ||
| 1398 | mov ax,Seek_SegID ; set destination XMA seg id ;AN000; | ||
| 1399 | mov es,ax | ||
| 1400 | ASSUME es:nothing ;AN000; | ||
| 1401 | REP MOVSW ; copy Seek segment to extended memory | ||
| 1402 | ; SI-->Cseg_Init segment | ||
| 1403 | mov ax,Cseg_Init ; no - only Fastseek specified | ||
| 1404 | mov ds,ax ; DS-->Cseg_Init | ||
| 1405 | ASSUME ds:Cseg_Init | ||
| 1406 | cmp total_Name_Count,0 ; FastOpen enabled ?? | ||
| 1407 | jne Set_Init_Seg ; yes - set Init Segment | ||
| 1408 | |||
| 1409 | mov ax,Cseg_Init | ||
| 1410 | sub ax,Cseg_Seek ; ax = size of Cseg_Seek | ||
| 1411 | add ax,EMS_Page_Seg ; Cseg_Init id only if Fastseek is specified | ||
| 1412 | mov Init_SegID,ax ; | ||
| 1413 | jmp copy_init_seg ; copy cseg_init area to extentde memory | ||
| 1414 | |||
| 1415 | ;----------------------------------------------------------------------------- | ||
| 1416 | ; Setup Cseg_Init segment in Extended Memory | ||
| 1417 | ;------------------------------------------------------------------------------ | ||
| 1418 | Set_Init_seg: | ||
| 1419 | mov ax,Cseg_Init ; yes - set init seg id | ||
| 1420 | sub ax,Cseg_Open ; AX = size of Open_Cseg+Seek_Cseg | ||
| 1421 | add ax,EMS_Page_Seg ; new Cseg_Init id in XMA if both | ||
| 1422 | mov Init_SegID,ax ; Fastopen and Fastseek are enabled ;AN000; | ||
| 1423 | |||
| 1424 | Copy_Init_Seg: ; comes here if no Cseg_Seek is required | ||
| 1425 | xor si,si ; offset of the source in low memory ;AN000; | ||
| 1426 | xor di,di ; offset of the destination in XMA ;AN000; | ||
| 1427 | mov ax, Total_Cache_Size ; size of Init seg area to be copied ;AN000; | ||
| 1428 | mov cl,4 ; in paragraph ;AN000; | ||
| 1429 | shl ax,cl ; convert to number of bytes ;AN000; | ||
| 1430 | mov cl,1 ; | ||
| 1431 | shr ax,cl ; convert to number ofwords ;AN000; | ||
| 1432 | mov cx,ax ; CX = number of WORDS to transfer ;AN000; | ||
| 1433 | mov ax,Cseg_Init ; set source segID ;AN000; | ||
| 1434 | mov ds,ax | ||
| 1435 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1436 | mov ax,Init_SegID ; set destination XMA seg id ;AN000; | ||
| 1437 | mov es,ax | ||
| 1438 | ASSUME es:nothing ;AN000; | ||
| 1439 | REP MOVSW ; copy Init segment to extended memory | ||
| 1440 | jmp reloc_exit ; then return ;AN000; | ||
| 1441 | |||
| 1442 | |||
| 1443 | ;NOTE: No need to adjust the resident segment size (Res_Segs) since it is | ||
| 1444 | ; done in the routine (Check_Mem). | ||
| 1445 | |||
| 1446 | |||
| 1447 | ;----------------------------------------------------------------------- | ||
| 1448 | ; ---- LOW MEMORY RELOCATION ---- | ||
| 1449 | ; Reloctae FastOpen or FastSeek or both in the low memory and adjust the | ||
| 1450 | ; resident size of the code. | ||
| 1451 | ;----------------------------------------------------------------------- | ||
| 1452 | Reloc_LOW_Mem: | ||
| 1453 | cmp Total_Name_Count,0 ; Fastopen function enabled ?? | ||
| 1454 | jne Check_Seek ; yes, check Fastseek function | ||
| 1455 | |||
| 1456 | ; Relocate Cseg_Seek segment over Cseg_Open segment | ||
| 1457 | mov ax, offset End_Seek ; size of Cseg_Seek in bytes ;AN000; | ||
| 1458 | mov cl,1 | ||
| 1459 | shr ax,cl ; convert to words ;AN000; | ||
| 1460 | mov cx,ax ; CX = number of WORDS to transfer ;AN000; | ||
| 1461 | xor si,si ; offset of the source ;AN000; | ||
| 1462 | xor di,di ; offset of the destination ;AN000;;AN000; | ||
| 1463 | mov ax,Cseg_Seek ; set source segID ;AN000; | ||
| 1464 | mov ds,ax ; DS:SI-->Cseg_Seek ;AN000; | ||
| 1465 | ASSUME ds:Cseg_Seek ;AN000; | ||
| 1466 | mov ax,Cseg_Open ; set destination seg id ;AN000; | ||
| 1467 | mov es,ax ; ES:DI--> Cseg_Open ;AN000; | ||
| 1468 | ASSUME es:Cseg_Open ;AN000; | ||
| 1469 | ;AN000; | ||
| 1470 | REP MOVSW ; relocate code and cache buffer | ||
| 1471 | mov ax,OPEN_Size ; reduce Open seg size from | ||
| 1472 | sub RES_SEGS,ax ; the resident size | ||
| 1473 | |||
| 1474 | ;----------------------------------------------------------------------- | ||
| 1475 | ; Compute the new segID after relocation and save it | ||
| 1476 | ;----------------------------------------------------------------------- | ||
| 1477 | mov ax,Cseg_Init ; | ||
| 1478 | mov ds,ax ; DS-->Cseg_Init | ||
| 1479 | ASSUME ds:Cseg_Init | ||
| 1480 | mov ax,Cseg_Open ; AX = seg id of Cseg_Open in ext mem | ||
| 1481 | mov Seek_SegID,ax ; save it | ||
| 1482 | ;AN000; | ||
| 1483 | mov ax,Seek_Size ; AX = size of Cseg_Seek | ||
| 1484 | add ax,Cseg_Open ; AX = new seg ID of Cseg_Init in ext ;AN000; | ||
| 1485 | mov Init_SegID,ax ; save it ;AN000; | ||
| 1486 | jmp short reloc_exit ;then return ;AN000; | ||
| 1487 | |||
| 1488 | Check_Seek: | ||
| 1489 | cmp Total_Ext_Count,0 ; Fastseek function enabled ?? | ||
| 1490 | jne Reloc_Exit ; yes, no need for relocation | ||
| 1491 | |||
| 1492 | ;----------------------------------------------------------------------- | ||
| 1493 | ; Relocate first portion of the Cseg_Init over Cseg_Seek segment. The size | ||
| 1494 | ; this portion should be same as the current size of Drive cache headers | ||
| 1495 | ; Anything more will overlay on Cseg_Init code which is currently active. | ||
| 1496 | ;----------------------------------------------------------------------- | ||
| 1497 | mov ax, size Drive_Cache_Header ; size of one drive cache hdr | ||
| 1498 | mov cx,Max_Drives ; CX = maximum number of drives | ||
| 1499 | mul cx ; AX = size of Cseg_Init portion | ||
| 1500 | mov cl,1 | ||
| 1501 | shr ax,cl ; AX = size of portion in words | ||
| 1502 | mov cx,ax ; CX = number of WORDS to transfer ;AN000; | ||
| 1503 | mov si,0 ; offset of the source ;AN000; | ||
| 1504 | mov di,0 ; offset of the destination ;AN000;;AN000; | ||
| 1505 | mov ax,Cseg_Init ; set source segID ;AN000; | ||
| 1506 | mov ds,ax ; DS:SI-->Cseg_Seek ;AN000; | ||
| 1507 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1508 | mov ax,Cseg_Seek ; set destination seg id ;AN000; | ||
| 1509 | mov es,ax ; ES:DI--> Cseg_Open ;AN000; | ||
| 1510 | ASSUME es:Cseg_Seek ;AN000; | ||
| 1511 | ;AN000; | ||
| 1512 | REP MOVSW ; relocate Cseg_Init over Cseg_Seek | ||
| 1513 | mov ax,Seek_Size ; reduce Seek seg size from | ||
| 1514 | sub RES_SEGS,ax ; the resident size | ||
| 1515 | |||
| 1516 | ;----------------------------------------------------------------------- | ||
| 1517 | ; Compute the new segID after reloaction and save it | ||
| 1518 | ;----------------------------------------------------------------------- | ||
| 1519 | mov ax,Cseg_Init ; | ||
| 1520 | mov ds,ax ; DS-->Cseg_Init | ||
| 1521 | ASSUME ds:Cseg_Init | ||
| 1522 | mov ax,Cseg_Seek ; AX = seg id of Cseg_Open in ext mem | ||
| 1523 | mov Init_SegID,ax | ||
| 1524 | |||
| 1525 | Reloc_Exit: | ||
| 1526 | ; copy the latest RES_SEGS size to Cseg_Main | ||
| 1527 | mov ax,Cseg_Init ; ;AN000; | ||
| 1528 | mov ds,ax ; DS-->Cseg_Init ;AN000; | ||
| 1529 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1530 | mov ax,Cseg_Main ; set destination seg id ;AN000;;AN000; | ||
| 1531 | mov es,ax ; ES--> Cseg_Main ;AN000; ;AN000; | ||
| 1532 | ASSUME es:Cseg_Main ;AN000;;AN000; | ||
| 1533 | mov ax,Res_Segs ;AN000; | ||
| 1534 | mov es:Main_Res_Segs,ax ; save it ;AN000; | ||
| 1535 | |||
| 1536 | RET ;AN000; | ||
| 1537 | |||
| 1538 | RELOCATE_SEGMENT ENDP | ||
| 1539 | |||
| 1540 | |||
| 1541 | |||
| 1542 | |||
| 1543 | |||
| 1544 | |||
| 1545 | ;----------------------------------------------------------------------- | ||
| 1546 | ; Procedure: COPY_DATA | ||
| 1547 | ;----------------------------------------------------------------------- | ||
| 1548 | ; Copy data values from Cseg_Init to other segments. I the code is relocated, | ||
| 1549 | ; seg IDs should be updated after relocation. This is done in "Update_SegID" | ||
| 1550 | ; | ||
| 1551 | ; Input: Variables inside Cseg_Open, CsegSeek and Cseg_Main segments | ||
| 1552 | ; | ||
| 1553 | ; Output: Data values copied to the above segments | ||
| 1554 | ; | ||
| 1555 | ; | ||
| 1556 | ;----------------------------------------------------------------------- | ||
| 1557 | |||
| 1558 | COPY_DATA PROC NEAR | ||
| 1559 | |||
| 1560 | mov ax,cseg_init ;AN000; | ||
| 1561 | mov ds,ax ;DS--> Cseg_Init ;AN000; | ||
| 1562 | ASSUME ds:Cseg_init ;AN000; | ||
| 1563 | mov ax,cseg_Main ;AN000; | ||
| 1564 | mov es,ax ;ES--> CSEG_MAIN ;AN000; | ||
| 1565 | ASSUME es:Cseg_Main ;AN000; | ||
| 1566 | ;AN000; | ||
| 1567 | mov es:Main_Name_Cache_Seg, Cseg_Init ;AN000; | ||
| 1568 | mov ax,Num_Of_Drives ;AN000; | ||
| 1569 | mov es:Main_Num_Of_Drives,ax ;AN000; | ||
| 1570 | mov ax,ext_count ;AN000; | ||
| 1571 | mov es:Main_Ext_Count,ax ;AN000; | ||
| 1572 | mov ax,Extent_Drive_Buff ;AN000; | ||
| 1573 | mov es:Main_Extent_Drive_Buff,ax ;AN000; | ||
| 1574 | mov ax,Name_Cache_Buff ;AN000; | ||
| 1575 | mov es:Main_Name_Cache_Buff,ax ;AN000; | ||
| 1576 | mov ax,Name_Drive_Buff ;AN000; | ||
| 1577 | mov es:Main_Name_Drive_Buff,ax ;AN000; | ||
| 1578 | mov ax,Ems_Flag | ||
| 1579 | mov es:Main_EMS_FLAG,ax | ||
| 1580 | mov ax,EMS_PAGE_Seg ;AN000; | ||
| 1581 | mov es:Main_EMS_PAGE_Seg,ax ;AN000; | ||
| 1582 | |||
| 1583 | IF BUFFERFLAG | ||
| 1584 | mov ax, EMS_PAGE_NUM | ||
| 1585 | mov es:ems_page_number, ax ;HKN | ||
| 1586 | ENDIF | ||
| 1587 | |||
| 1588 | mov ax,EMS_PAGE_SIZE ;AN000; | ||
| 1589 | mov es:Main_EMS_PAGE_SIZE,ax ;AN000; | ||
| 1590 | mov ax,Total_Ext_Count ;AN000; | ||
| 1591 | mov es:Main_Total_Ext_Count,ax ;AN000; | ||
| 1592 | mov ax,Ext_Cache_Size ;AN000; | ||
| 1593 | mov es:Main_Ext_Cache_Size,ax ;AN000; | ||
| 1594 | mov ax,Total_Name_Count ;AN000; | ||
| 1595 | mov es:Main_Total_Name_Count,ax | ||
| 1596 | |||
| 1597 | ; Copy drive buffer to MAIN segment | ||
| 1598 | lea si,ParamBuff ;AN000; | ||
| 1599 | lea di,es:Main_ParamBuff ;AN000; | ||
| 1600 | mov cx,50 ;AN000; | ||
| 1601 | |||
| 1602 | Paramloop: | ||
| 1603 | mov al,[si] ;AN000; | ||
| 1604 | mov es:[di],al ;AN000; | ||
| 1605 | inc si ;AN000; | ||
| 1606 | inc di ;AN000; | ||
| 1607 | LOOP paramloop ;AN000; | ||
| 1608 | |||
| 1609 | ;----------------------------------------------------------------------- | ||
| 1610 | ; Copy data values to OPEN segment (Cseg_Open) | ||
| 1611 | ;----------------------------------------------------------------------- | ||
| 1612 | mov ax,cseg_Open ;AN000; | ||
| 1613 | mov es,ax ;ES--> CSEG_Open ;AN000; | ||
| 1614 | ASSUME es:Cseg_Open ;AN000; | ||
| 1615 | mov si,offset drive_cache ;AN000; | ||
| 1616 | mov es:Open_Name_Drive_Buff,si ;AN000; | ||
| 1617 | mov es:Open_Name_Cache_Seg,Cseg_Init ;AN000; | ||
| 1618 | mov ax,check_Queue | ||
| 1619 | mov es:chk_Flag,ax | ||
| 1620 | |||
| 1621 | ;----------------------------------------------------------------------- | ||
| 1622 | ; Copy data values to SEEK segment (Cseg_Seek) for Fastseek functions | ||
| 1623 | ;----------------------------------------------------------------------- | ||
| 1624 | mov ax,cseg_Seek ;AN000; | ||
| 1625 | mov es,ax ;ES--> CSEG_Seek ;AN000; | ||
| 1626 | ASSUME es:Cseg_Seek ;AN000; | ||
| 1627 | mov si,Extent_Drive_Buff ;AN000; | ||
| 1628 | mov es:Seek_Extent_Drive_Buff,si ;AN000; | ||
| 1629 | mov es:Seek_Name_Cache_Seg,Cseg_Init ;AN000; | ||
| 1630 | mov ax,Num_Of_Drives ;AN000; | ||
| 1631 | mov es:Seek_Num_Of_Drives,ax ;AN000; | ||
| 1632 | mov ax,Total_Ext_Count ;AN000; | ||
| 1633 | mov es:Seek_Total_Ext_Count,ax ;AN000; | ||
| 1634 | mov ax,Total_Name_Count ;AN000; | ||
| 1635 | mov es:Seek_Total_name_Count,ax ;AN000; | ||
| 1636 | mov ax,Name_Cache_Buff ;AN000; | ||
| 1637 | mov es:Seek_Name_Cache_Buff,ax ;AN000; | ||
| 1638 | mov ax,Name_Drive_Buff ;AN000; | ||
| 1639 | mov es:Seek_Name_Drive_Buff,ax ;AN000; | ||
| 1640 | mov ax,check_Queue | ||
| 1641 | mov es:check_Flag,ax | ||
| 1642 | ;AN000; | ||
| 1643 | mov ax,cseg_Init ;AN000; | ||
| 1644 | mov es,ax ;ES addressability to CSEG_Init ;AN000; | ||
| 1645 | ASSUME es:Cseg_Init ;AN000; | ||
| 1646 | ;AN000; | ||
| 1647 | ret | ||
| 1648 | |||
| 1649 | COPY_DATA ENDP | ||
| 1650 | |||
| 1651 | |||
| 1652 | |||
| 1653 | |||
| 1654 | ;----------------------------------------------------------------------- | ||
| 1655 | ; Procedure: ADJUST_SEGIDS | ||
| 1656 | ;----------------------------------------------------------------------- | ||
| 1657 | ; Function: Adjust segment Ids of various segments after relocation | ||
| 1658 | ; | ||
| 1659 | ; Input: SegID Vectors | ||
| 1660 | ; | ||
| 1661 | ; Output: SegIDs vectors are adjusted | ||
| 1662 | ; | ||
| 1663 | ; Note: The following segid and vectors are set previously either during | ||
| 1664 | ; link time or during initialization time. These SegIDS needs to | ||
| 1665 | ; be changed after the code and buffers are relocated. | ||
| 1666 | ;----------------------------------------------------------------------- | ||
| 1667 | |||
| 1668 | ADJUST_SEGIDS PROC NEAR | ||
| 1669 | |||
| 1670 | mov ax,Cseg_Init ;AN000; | ||
| 1671 | mov ds,ax ;DS addressability to Cseg_Init ;AN000; | ||
| 1672 | ASSUME ds:Cseg_init ;AN000;;AN000; | ||
| 1673 | mov ax,cseg_Main ;AN000; | ||
| 1674 | mov es,ax ;ES addressability to CSEG_MAIN ;AN000; | ||
| 1675 | ASSUME es:Cseg_Main ;AN000; | ||
| 1676 | |||
| 1677 | mov bx, Init_segID ; copy seg ID of Init_Seg to ;AN000; | ||
| 1678 | mov es:Main_Name_Cache_Seg, bx ; Main seg ;AN000; | ||
| 1679 | |||
| 1680 | cmp Total_Name_Count,0 ; Fastopen function enabled ?? | ||
| 1681 | je Adjust_Seek ; yes, Adjust Cseg_Seek ID | ||
| 1682 | |||
| 1683 | mov ax,Open_SegID ;AN000; | ||
| 1684 | mov es,ax ; ES addressability to CSEG_Open ;AN000; | ||
| 1685 | ASSUME es:Cseg_Open ; copy segid of init_seg to ;AN000; | ||
| 1686 | mov es:Open_Name_Cache_Seg, bx ; Open segment | ||
| 1687 | |||
| 1688 | Adjust_Seek: | ||
| 1689 | cmp Total_Ext_Count,0 ;Fastopen function enabled ?? | ||
| 1690 | je Adjust_Vectors ;yes, check Fastseek function | ||
| 1691 | |||
| 1692 | mov ax,Seek_SegID ;AN000; | ||
| 1693 | mov es,ax ; ES addressability to CSEG_Seek ;AN000; | ||
| 1694 | ASSUME es:Cseg_Seek ;AN000; | ||
| 1695 | mov es:Seek_Name_Cache_Seg, bx ;AN000; | ||
| 1696 | |||
| 1697 | |||
| 1698 | ; Adjust seg ids of jump vectors to Fastopen and Fastseek functions ;AN000; | ||
| 1699 | Adjust_Vectors: | ||
| 1700 | mov ax,cseg_Main ;AN000; | ||
| 1701 | mov es,ax ;ES addressability to CSEG_MAIN ;AN000; | ||
| 1702 | ASSUME es:Cseg_Main ;AN000; | ||
| 1703 | ;DS addressability to Cseg_Init | ||
| 1704 | mov ax, Open_SegID ;AN000; | ||
| 1705 | mov word ptr es:FOPEN_Insert + word, ax ;AN000; | ||
| 1706 | mov word ptr es:FOPEN_Update + word, ax ;AN000; | ||
| 1707 | mov word ptr es:FOPEN_Delete + word, ax ;AN000; | ||
| 1708 | mov word ptr es:FOPEN_Lookup + word, ax ;AN000; | ||
| 1709 | IF BUFFERFLAG | ||
| 1710 | mov word ptr es:FOPEN_Purge + word, ax ;TEL 9/29 | ||
| 1711 | ENDIF | ||
| 1712 | |||
| 1713 | |||
| 1714 | mov ax, Seek_SegID ;AN000; | ||
| 1715 | mov word ptr es:FSEEK_Open + word, ax ;AN000; | ||
| 1716 | mov word ptr es:FSEEK_Close + word, ax ;AN000; | ||
| 1717 | mov word ptr es:FSEEK_Insert + word, ax ;AN000; | ||
| 1718 | mov word ptr es:FSEEK_Delete + word, ax ;AN000; | ||
| 1719 | mov word ptr es:FSEEK_Lookup + word, ax ;AN000; | ||
| 1720 | mov word ptr es:FSEEK_Truncate + word, ax ;AN000; | ||
| 1721 | mov word ptr es:FSEEK_Purge + word, ax ;AN000; | ||
| 1722 | |||
| 1723 | cmp Total_Name_Count,0 ; Fastopen function enabled ?? | ||
| 1724 | je Adjust_Delete ; no , exit | ||
| 1725 | |||
| 1726 | ; Change the segID of single Jump Vector inside Cseg_Main | ||
| 1727 | mov ax,cseg_Main ;AN000;;AN000; | ||
| 1728 | mov es,ax ;ES addressability to CSEG_MAIN ;AN000;;AN000; | ||
| 1729 | ASSUME es:Cseg_Main ;AN000;;AN000; | ||
| 1730 | mov ax,Open_SegID ;AN000; | ||
| 1731 | mov word ptr es:Vector_LookUp + word, ax ;;AN000;AN000; | ||
| 1732 | |||
| 1733 | Adjust_Delete: | ||
| 1734 | cmp Total_Ext_Count,0 ; Fastseek function enabled ?? | ||
| 1735 | je Adjust_Exit ; no , exit | ||
| 1736 | |||
| 1737 | ; Change the segID of single Jump Vector inside Cseg_Main | ||
| 1738 | mov ax,cseg_Main ;AN000;;AN000; | ||
| 1739 | mov es,ax ;ES addressability to CSEG_MAIN ;AN000;;AN000; | ||
| 1740 | ASSUME es:Cseg_Main ;AN000;;AN000; | ||
| 1741 | mov ax,Seek_SegID ;AN000; | ||
| 1742 | mov word ptr es:Vector_Delete + word, ax ;;AN000;AN000; | ||
| 1743 | |||
| 1744 | Adjust_Exit: | ||
| 1745 | ret ;AN000; | ||
| 1746 | ;return | ||
| 1747 | ADJUST_SEGIDS ENDP | ||
| 1748 | |||
| 1749 | |||
| 1750 | |||
| 1751 | |||
| 1752 | |||
| 1753 | |||
| 1754 | |||
| 1755 | |||
| 1756 | ;****************************************************************************** | ||
| 1757 | ; * | ||
| 1758 | ; * MODULE: PARSE | ||
| 1759 | ; * | ||
| 1760 | ; * FUNCTION: Parse command line | ||
| 1761 | ; * | ||
| 1762 | ; * INPUT: FASTOPEN d: {=n | (n,m) } ... /x à | ||
| 1763 | ; * where à activates queue analyser for debugging | ||
| 1764 | ; * | ||
| 1765 | ; * OUTPUT: Command line is parsed | ||
| 1766 | ; * | ||
| 1767 | ; * RETURN SEQUENCE: | ||
| 1768 | ; * | ||
| 1769 | ; * If CY = 0 No error | ||
| 1770 | ; * | ||
| 1771 | ; * If CY = 1 Error | ||
| 1772 | ; * | ||
| 1773 | ; * EXTERNAL REFERENCES: SYSPARSE | ||
| 1774 | ; * | ||
| 1775 | ; ************************************************************************* | ||
| 1776 | |||
| 1777 | EOL EQU -1 ; Indicator for End-Of-Line | ||
| 1778 | NOERROR EQU 0 ; Return Indicator for No Errors | ||
| 1779 | |||
| 1780 | |||
| 1781 | PARSE PROC NEAR | ||
| 1782 | |||
| 1783 | mov num_of_drives,0 ; initialize drive count | ||
| 1784 | mov name_count,0 | ||
| 1785 | mov ext_count,0 | ||
| 1786 | mov Total_name_count,0 ;AN000; | ||
| 1787 | mov Total_ext_count,0 ;AN000; | ||
| 1788 | mov Prev_Type,0 ;AN000; | ||
| 1789 | mov Ext_Mem,0 ;AN000; | ||
| 1790 | mov Check_Queue,0 ;AN000; | ||
| 1791 | lea si,parambuff ; drive ID buff address ;AN000; | ||
| 1792 | mov parmbuff_Ptr,si ; save it ;AN000; | ||
| 1793 | |||
| 1794 | ;---------------------------------------------------------------------------- | ||
| 1795 | ; Get command string address from PSP | ||
| 1796 | ;---------------------------------------------------------------------------- | ||
| 1797 | mov si,0081H | ||
| 1798 | mov ah,62H | ||
| 1799 | INT 21H ; get program PSP segment ;AN000; | ||
| 1800 | mov PSP_Seg,bx ; save PSP segment ;AN000; | ||
| 1801 | ;AN000; | ||
| 1802 | mov ds,bx ; DS = PSP segment ;AN000; | ||
| 1803 | mov si,0081h ; SI-->beginning of parameter string in PSP | ||
| 1804 | lea di,cmdline_buff ; DI-->command param buffer ;AN000; | ||
| 1805 | mov cx,127 ; copy 127 bytes from PSP ;AN000; | ||
| 1806 | |||
| 1807 | ;---------------------------------------------------------------------------- | ||
| 1808 | ; Copy command parameters from PSP to the command buffer | ||
| 1809 | ;---------------------------------------------------------------------------- | ||
| 1810 | Cmdloop: | ||
| 1811 | mov al,ds:[si] ; DS:SI-->Command line ;AN000; | ||
| 1812 | mov es:[di],al ; ES:DI-->program command buffer ;AN000; | ||
| 1813 | inc si ;AN000; | ||
| 1814 | inc di ;AN000; | ||
| 1815 | LOOP cmdloop ; copy command line | ||
| 1816 | push cs ;AN000; | ||
| 1817 | pop ds ;AN000; | ||
| 1818 | |||
| 1819 | ;---------------------------------------------------------------------------- | ||
| 1820 | ; set parametrs for SysParse call | ||
| 1821 | ;---------------------------------------------------------------------------- | ||
| 1822 | xor cx,cx ; no params processed so far ;AN000; | ||
| 1823 | MOV ORDINAL,CX ; SAVE initial ordinal value ;AN000; | ||
| 1824 | lea si,cmdline_buff ; ES:SI-->command line ;AN000; | ||
| 1825 | lea di,parms ; ES:DI-->parameter | ||
| 1826 | MOV CURRENT_PARM,SI ; pointer to next positional ;AN000; | ||
| 1827 | |||
| 1828 | mov ax,0100h ; Drive only | ||
| 1829 | mov pos1type,ax ; set positional control block 1 ;AN000; | ||
| 1830 | mov ax,08502h ; Numeric/Complex/Drive/Repeat | ||
| 1831 | mov pos2type,ax ; set positional control block 2 ;AN000; | ||
| 1832 | mov al,1 ; minimum 1 positional ;AN000; | ||
| 1833 | mov Par_Min,al ; | ||
| 1834 | mov al,2 ;AN000; | ||
| 1835 | mov Par_Max,al ; maximum 1 positional ;AN000; | ||
| 1836 | jmp short set_param | ||
| 1837 | |||
| 1838 | ;---------------------------------------------------------------------------- | ||
| 1839 | ; MAIN PARSE LOOP | ||
| 1840 | ;---------------------------------------------------------------------------- | ||
| 1841 | PARSE_LOOP: ; MAIN PARSE LOOP | ||
| 1842 | mov ax,08502h ; number/drive ID/comlex/repeat | ||
| 1843 | mov pos1type,ax ; set positional control block ;AN000; | ||
| 1844 | mov ax,08502h ; | ||
| 1845 | mov pos2type,ax ; | ||
| 1846 | mov al,1 ; minimum 1 positional ;AN000; | ||
| 1847 | mov Par_Min,al ; set min | ||
| 1848 | mov al,2 ; maximum 2 positionals ;AN000; | ||
| 1849 | mov Par_Max,al ; set max ;AN000; | ||
| 1850 | |||
| 1851 | Set_Param: | ||
| 1852 | mov Par_sw,1 ; set switch flag in PARSMX | ||
| 1853 | xor dx,dx | ||
| 1854 | push cs ;AN000; | ||
| 1855 | pop es ; ES=DS=CS ;AN000; | ||
| 1856 | LEA DI,PARMS ; ES:DI = PARSE CONTROL DEFINITON ;AN000; | ||
| 1857 | MOV SI,CURRENT_PARM ; DS:SI = next positional ;AN000; | ||
| 1858 | XOR DX,DX ; RESERVED, INIT TO ZERO ;AN000; | ||
| 1859 | MOV CX,ORDINAL ; OPERAND ORDINAL, INITIALLY ;AN000; | ||
| 1860 | |||
| 1861 | CALL SYSPARSE ; Parse current positional | ||
| 1862 | |||
| 1863 | mov Next_Parm,si ; save pointer to next positional ;AN000; | ||
| 1864 | mov ORDINAL,CX ; save current ordinal ;AN000; | ||
| 1865 | cmp ax,EOL ; END-OF-COMMAND string ?? ;AN000; | ||
| 1866 | jne Parse_chk_Error ; no - check error | ||
| 1867 | |||
| 1868 | |||
| 1869 | ;---------------------------------------------------------------------------- | ||
| 1870 | ; If previous positional is a drive ID without Name or Extent count then assign | ||
| 1871 | ; default counts . | ||
| 1872 | ;---------------------------------------------------------------------------- | ||
| 1873 | cmp Prev_Type,6 ; previous param = drive ID ;AN000; | ||
| 1874 | jne Take_Exit ; no - exit ;AN000; | ||
| 1875 | ;AN000; | ||
| 1876 | CALL PROC_DEFAULT ; yes - setup default counts for previous drive ;AN000; | ||
| 1877 | jnc Take_Exit ; exit ;AN000; | ||
| 1878 | jmp parse_Error ; error exit ;AN000; | ||
| 1879 | |||
| 1880 | Take_Exit: | ||
| 1881 | CALL Verify_Counts ; verify the Total counts | ||
| 1882 | jnc Counts_OK ; exit if count ok | ||
| 1883 | jmp parse_error ; else error exit | ||
| 1884 | |||
| 1885 | Counts_Ok: | ||
| 1886 | jmp parse_exit ; normal - exit | ||
| 1887 | |||
| 1888 | |||
| 1889 | ;---------------------------------------------------------------------------- | ||
| 1890 | ; CHECK ERROR CONDITIONS | ||
| 1891 | ;---------------------------------------------------------------------------- | ||
| 1892 | Parse_Chk_Error: ; check for error conditions | ||
| 1893 | cmp ax,NOERROR ; any parse error ?? | ||
| 1894 | jne verify_missing_oper ; yes - check missing operand | ||
| 1895 | jmp Chk_Result ; no - check result buffer ;AN000; | ||
| 1896 | |||
| 1897 | Verify_Missing_Oper: | ||
| 1898 | cmp ax,2 ; yes - missing operand error?? | ||
| 1899 | jne disp_error ; no - jump ;AN000; | ||
| 1900 | |||
| 1901 | cmp Prev_Type,0 ; yes - any previous parameters ?? | ||
| 1902 | jne Chk_Prev_Drive ; yes, previous drive id ;AN000; | ||
| 1903 | mov MSG_CLASS,2 | ||
| 1904 | MOV MSG_NUM,AX ; set message number ;AN000; | ||
| 1905 | MOV SUBST_COUNT,0 ; no message substitution ;AN000; | ||
| 1906 | MOV INPUT_FLAG,0 ; no input ;AN000; | ||
| 1907 | CALL PRINT_STDOUT ; show message ;AN000; | ||
| 1908 | stc ; set error flag ;AN000; | ||
| 1909 | jmp Parse_Exit ; exit | ||
| 1910 | |||
| 1911 | ;---------------------------------------------------------------------------- | ||
| 1912 | ; If previous positional is drive ID without counts then assign default counts | ||
| 1913 | ;---------------------------------------------------------------------------- | ||
| 1914 | Chk_prev_drive: | ||
| 1915 | cmp Prev_Type,6 ; previous param = drive ID ?? ;AN000; | ||
| 1916 | jne Take_Exit1 ; no - exit ;AN000; | ||
| 1917 | |||
| 1918 | CALL PROC_DEFAULT ; yes - assign default ID | ||
| 1919 | jnc Take_Exit1 ; no error, verify counts ;AN000; | ||
| 1920 | jmp parse_Error ; error exit ;AN000; | ||
| 1921 | |||
| 1922 | Take_Exit1: | ||
| 1923 | CALL Verify_Counts ; verify the Total counts | ||
| 1924 | jnc Counts_right ; count ok - check special case | ||
| 1925 | jmp parse_error ; error - exit | ||
| 1926 | |||
| 1927 | Counts_right: | ||
| 1928 | cmp Prev_Type,0 ; no previous param ? (Special case) ;AN000; | ||
| 1929 | je invalid_operand ; no, exit ( FASTOPEN >TEMP ) case ;AN000; | ||
| 1930 | clc ;AN000; | ||
| 1931 | jmp parse_exit ; exit | ||
| 1932 | |||
| 1933 | Invalid_Operand: ; else error | ||
| 1934 | jmp bad_param | ||
| 1935 | |||
| 1936 | Disp_Error: | ||
| 1937 | cmp ax, 3 ; invalid switch type ?? | ||
| 1938 | jne bad_param ; no - | ||
| 1939 | jmp Bad_Switch | ||
| 1940 | |||
| 1941 | ;---------------------------------------------------------------------------- | ||
| 1942 | ; If user entered à to activate the analyser, than verify the previous | ||
| 1943 | ; drive case. If true, assign default name extent entries, set activation | ||
| 1944 | ; flag and take normal exit. | ||
| 1945 | ;---------------------------------------------------------------------------- | ||
| 1946 | Bad_Param: | ||
| 1947 | mov si,Current_Parm ; SI-->current parameter (analyser hook) | ||
| 1948 | mov al,0e0h ; à (hidden character to activate analyser) | ||
| 1949 | cmp [si],al ; activate analyser ?? | ||
| 1950 | jne set_disp_param ; no - normal error | ||
| 1951 | mov Check_Queue,1 ; yes - set flag to activate analyser | ||
| 1952 | clc | ||
| 1953 | jmp Chk_Prev_Drive ; exit | ||
| 1954 | |||
| 1955 | Set_Disp_Param: | ||
| 1956 | mov di,Next_Parm ; ending address of bad param (1/6/88) | ||
| 1957 | mov al,0 | ||
| 1958 | mov ds:[di],al ; set termination character | ||
| 1959 | LEA SI,SUBLIST1 ; DS:SI-->Substitution list ;AN000; | ||
| 1960 | MOV AX,CURRENT_PARM ; starting address of bad parameter ;AN000; | ||
| 1961 | MOV [SI].DATA_OFF,AX ; SI-->File name ;AN000; | ||
| 1962 | MOV [SI].DATA_SEG,DS ; DS-->Segment ;AN000; | ||
| 1963 | MOV [SI].MSG_ID,0 ; message ID ;AN000; | ||
| 1964 | MOV [SI].FLAGS,010H ; ASCIIZ string, left align ;AN000; | ||
| 1965 | MOV [SI].MAX_WIDTH,0 ; MAXIMUM FIELD WITH ;AN000; | ||
| 1966 | MOV [SI].MIN_WIDTH,0 ; MINIMUM FIELD WITH ;AN000; | ||
| 1967 | mov ax,incorrect_param ; Error Code ;AN000; | ||
| 1968 | MOV MSG_NUM,AX ; set message number ;AN000; | ||
| 1969 | MOV SUBST_COUNT,1 ; substitution count ;AN000; | ||
| 1970 | MOV MSG_CLASS,-1 ; message class ;AN000; | ||
| 1971 | MOV INPUT_FLAG,0 ; no input ;AN000; | ||
| 1972 | CALL PRINT_STDOUT ; display message ;AN000; | ||
| 1973 | stc ; error flag | ||
| 1974 | jmp Parse_Exit ; exit (1/6/88 P2670) | ||
| 1975 | |||
| 1976 | |||
| 1977 | ;---------------------------------------------------------------------------- | ||
| 1978 | ; CHECK POSITIONAL PARAMETER TYPE | ||
| 1979 | ;---------------------------------------------------------------------------- | ||
| 1980 | Chk_Result: | ||
| 1981 | push es ; get DS back to Program data segment ;AN000; | ||
| 1982 | pop ds ;AN000; | ||
| 1983 | cmp postype,1 ; number ?? ;AN000; | ||
| 1984 | jne chk_switch ;AN000; | ||
| 1985 | jmp short Proc_Name ; yes, process name entry ;AN000; | ||
| 1986 | |||
| 1987 | chk_switch: | ||
| 1988 | cmp postype,3 ; switch ?? ;AN000; | ||
| 1989 | je Proc_sw ; yes, process switch ;AN000; | ||
| 1990 | cmp postype,6 ; drive id ?? ;AN000; | ||
| 1991 | je Proc_driveid ; yes, Process Drive ID ;AN000; | ||
| 1992 | cmp postype,4 ; complex item ?? ;AN000; | ||
| 1993 | jne disp_msg ;AN000; | ||
| 1994 | jmp Proc_complex ; yes, process Complex item ;AN000; | ||
| 1995 | |||
| 1996 | disp_msg: | ||
| 1997 | mov ax,incorrect_param ; no, check reult buffer ;AN000; | ||
| 1998 | jmp bad_param ; else error ;AN000; | ||
| 1999 | |||
| 2000 | Proc_Sw: jmp Proc_Switch ; process switch ;AN000; | ||
| 2001 | |||
| 2002 | |||
| 2003 | |||
| 2004 | ;---------------------------------------------------------------------------- | ||
| 2005 | ; PROCESS DRIVE ID | ||
| 2006 | ;---------------------------------------------------------------------------- | ||
| 2007 | PROC_DRIVEID: ; PROCESS DRIVE ID | ||
| 2008 | cmp Prev_Type,6 ; previous param = drive ID ;AN000; | ||
| 2009 | jne check_drive_id ; no, jump ;AN000; | ||
| 2010 | ;AN000; | ||
| 2011 | ; if not set default name and extent entry count for previous drive | ||
| 2012 | CALL PROC_DEFAULT ; setup default counts ;AN000; | ||
| 2013 | jnc Check_Drive_id ; ;AN000; | ||
| 2014 | jmp parse_Error ;AN000; | ||
| 2015 | |||
| 2016 | Check_Drive_Id: ; process current drive ID | ||
| 2017 | mov ax,ValueLo ; get drive letter number from result buff ;AN000; | ||
| 2018 | ; C:=3 D:=4 etc, Parser drive id convention ;AN000; | ||
| 2019 | add al,040H ; convert to drive letter ;AN000; | ||
| 2020 | |||
| 2021 | CALL CHECK_DRIVE ; validate drive ID ?? ;AN000; | ||
| 2022 | jnc set_drive_id ; yes, jump ;AN000; | ||
| 2023 | jmp Parse_Exit ; no, invalid drive id , exit ;AN000; | ||
| 2024 | |||
| 2025 | Set_Drive_Id: | ||
| 2026 | inc num_of_drives ; update the drive count ;AN000; | ||
| 2027 | xor ax,ax ;AN000; | ||
| 2028 | mov ax,valuelo ; get drive number ;AN000; | ||
| 2029 | xor ah,ah ; only low byte is valid ;AN000;;AN000; | ||
| 2030 | mov di,ParmBuff_Ptr ; DS:DI-->driveID buffer ;AN000; | ||
| 2031 | dec ax ; C:=2 D:=3 E:=4 etc Fastopen drive id ;AN000; | ||
| 2032 | mov [di],ax ; save drive in Drive ID table ;AN000; | ||
| 2033 | add parmbuff_ptr,2 ; points to next extent count area ;AN000; | ||
| 2034 | mov al,PosTYpe ; set previous type before look for next ;AN000; | ||
| 2035 | mov Prev_Type,al ; positional parameter ;AN000; | ||
| 2036 | mov si,Next_Parm ; get pointer to next param (switch) ;AN000; | ||
| 2037 | mov Current_Parm,si ; ;AN000; | ||
| 2038 | jmp Parse_Loop ; look for next posistional parameter ;AN000; | ||
| 2039 | |||
| 2040 | |||
| 2041 | ;---------------------------------------------------------------------------- | ||
| 2042 | ; PROCESS INTEGER ( C:=n ) followed by drive ID | ||
| 2043 | ;---------------------------------------------------------------------------- | ||
| 2044 | PROC_NAME: | ||
| 2045 | cmp Prev_Type, 6 ; previous type = drive ID | ||
| 2046 | je Get_Name_Value ; yes - jump | ||
| 2047 | mov ax,incorrect_param ; error code ;AN000; | ||
| 2048 | jmp bad_param | ||
| 2049 | |||
| 2050 | Get_Name_Value: | ||
| 2051 | xor ax,ax ;AN000; | ||
| 2052 | mov ax,valuelo ; get name value ;AN000; | ||
| 2053 | cmp ax,10 ; check validity of the count ;AN000; | ||
| 2054 | jl Bad_Name_Count | ||
| 2055 | cmp ax,999 ;AN000; | ||
| 2056 | jle save_name_count ; count OK, save it ;AN000; | ||
| 2057 | |||
| 2058 | Bad_Name_Count: ; bad name count | ||
| 2059 | mov ax,Invalid_Name ; error code ;AN000; | ||
| 2060 | jmp parse_error ; error - exit ;AN000; | ||
| 2061 | |||
| 2062 | Save_Name_Count: | ||
| 2063 | mov name_count,ax ; save it (name count) | ||
| 2064 | add Total_Name_Count,ax ; update total name count | ||
| 2065 | mov di,ParmBuff_Ptr ; DS:DI-->driveID buffer ;AN000; | ||
| 2066 | mov ax,-1 ;AN000; | ||
| 2067 | mov [di],ax ; MARK this drive has no extent entry ;AN000; | ||
| 2068 | add parmbuff_ptr,2 ; points to extent count area ;AN000; | ||
| 2069 | |||
| 2070 | Set_Drive_Hdr: | ||
| 2071 | mov ax,Name_Count ; get name count entry ;AN000; | ||
| 2072 | CALL SET_DRIVE_CACHE_HEADER ; Set Name cache header ;AN000; | ||
| 2073 | jnc set_min_max ; no error set min and max ;AN000; | ||
| 2074 | jmp parse_Error ; display error ;AN000; | ||
| 2075 | |||
| 2076 | Set_Min_Max: | ||
| 2077 | mov al,1 ;AN000; | ||
| 2078 | mov Par_Min,al ; change min-max ;AN000; | ||
| 2079 | mov al,2 ;AN000;;AN000; | ||
| 2080 | mov Par_Max,al ;AN000; | ||
| 2081 | mov al,PosTYpe ; set previous type before look for next ;AN000; | ||
| 2082 | mov Prev_Type,al ;AN000; | ||
| 2083 | mov si,Next_Parm ; get pointer to next param (switch) ;AN000; | ||
| 2084 | mov Current_Parm,si ; ;AN000; | ||
| 2085 | mov ordinal,0 ;AN000; | ||
| 2086 | Jmp Parse_Loop ; parse nexy positional ;AN000; | ||
| 2087 | |||
| 2088 | |||
| 2089 | ;---------------------------------------------------------------------------- | ||
| 2090 | ; PROCESS COMPLEX (n,m) followed by a drive id | ||
| 2091 | ;---------------------------------------------------------------------------- | ||
| 2092 | PROC_COMPLEX: | ||
| 2093 | cmp Prev_Type, 6 ; previous type = drive ID ?? | ||
| 2094 | je Get_Cmplx_Item ; yes - ok | ||
| 2095 | mov ax,incorrect_param ; no - error, previous must be drive id ;AN000; | ||
| 2096 | jmp bad_param ; display error | ||
| 2097 | |||
| 2098 | Get_Cmplx_Item: | ||
| 2099 | mov al, PosType ; | ||
| 2100 | mov Prev_Type,al ; save current type as previous | ||
| 2101 | lea di,valuelo ; DI-->result buffer ;AN000; | ||
| 2102 | mov si,[di] ; get next positional param address ;AN000; | ||
| 2103 | mov current_parm,si ; SI-->first complex item ;AN000; | ||
| 2104 | mov ax,08001h ; Control ( Numeric/Optional ) ;AN000; | ||
| 2105 | mov Pos1Type,ax ; change pos-param control block flag ;AN000; | ||
| 2106 | mov Pos2Type,ax ;AN000; | ||
| 2107 | mov al,1 ; atleast 1 or maximun two positionals in complex item ;AN000; | ||
| 2108 | mov Par_Min,al ; set minimum = 1 | ||
| 2109 | mov al,2 ;AN000; | ||
| 2110 | mov Par_Max,al ; set maximum = 2 ;AN000; | ||
| 2111 | mov ordinal1,0 ; initialize ordinal for complex item loop ;AN000; | ||
| 2112 | mov par_sw,0 ; reset switch flag in PARMSX | ||
| 2113 | |||
| 2114 | COMPLX_LOOP: | ||
| 2115 | xor dx,dx | ||
| 2116 | LEA DI,PARMS ;ES:DI = PARSE CONTROL DEFINITON ;AN000; | ||
| 2117 | MOV SI,CURRENT_PARM ;SI = COMMAND STRING, NEXT PARM ;AN000; | ||
| 2118 | XOR DX,DX ;RESERVED, INIT TO ZERO ;AN000; | ||
| 2119 | MOV CX,ORDINAL1 ;OPERAND ORDINAL, INITIALLY ZERO ;AN000; | ||
| 2120 | |||
| 2121 | CALL SYSPARSE ; parse positional param in complex item | ||
| 2122 | |||
| 2123 | cmp ax,NOERROR ; parse error ?? | ||
| 2124 | je Chk_Complex_Result ; no, check result buffer ;AN000; | ||
| 2125 | cmp ax,EOL ; END-OF-COMMAND string ?? ;AN000; | ||
| 2126 | jne Complex_Error ; no, check error | ||
| 2127 | mov si,Next_Parm ; Set pointer to next param (4/3/88) | ||
| 2128 | mov Current_Parm,si ; set next param address before parsing ;AN000; | ||
| 2129 | jmp Parse_Loop ; go to main parse loop | ||
| 2130 | |||
| 2131 | Complex_Error: | ||
| 2132 | mov ax,Incorrect_Param ; no, check reult buffer ;AN000; | ||
| 2133 | jmp bad_param ; display error | ||
| 2134 | |||
| 2135 | ;------------------------------------------------------------------------------- | ||
| 2136 | ; Ckeck The Result Buffer | ||
| 2137 | ;------------------------------------------------------------------------------- | ||
| 2138 | Chk_Complex_Result: | ||
| 2139 | mov ordinal1,cx ; save current ordinal ;AN000; ;AN000; | ||
| 2140 | cmp postype,1 ; positional type = number ?? | ||
| 2141 | je Proc_Complex_Name ; yes, process name entry ;AN000; | ||
| 2142 | cmp postype,3 ; positional type = String ?? | ||
| 2143 | je Miss_param ; yes, process missing parameter | ||
| 2144 | mov ax,incorrect_param ; no, check reult buffer ;AN000; | ||
| 2145 | jmp bad_param | ||
| 2146 | |||
| 2147 | Miss_Param: | ||
| 2148 | mov current_parm,si ; save current chara pointer ;AN000; | ||
| 2149 | jmp complx_loop ; get extent count | ||
| 2150 | |||
| 2151 | |||
| 2152 | ;------------------------------------------------------------------------------- | ||
| 2153 | ; PROCESS NAME ENTRY (n) | ||
| 2154 | ;------------------------------------------------------------------------------- | ||
| 2155 | Proc_Complex_Name: ; PROCESS COMPLEX ITEM | ||
| 2156 | mov current_parm,si ; save current chara pointer ;AN000; | ||
| 2157 | cmp cx,2 ; second positional in the complex ;AN000; | ||
| 2158 | je proc_extent_entry ; yes, process Extent count ;AN000; | ||
| 2159 | xor ax,ax ; eles process Name Count ;AN000; | ||
| 2160 | mov ax,valuelo ; get name value from result buffer ;AN000; | ||
| 2161 | cmp ax,10 ; validate the name value for higher ;AN000; | ||
| 2162 | jl Name_Error ; and lower boundries ;AN000; | ||
| 2163 | cmp ax,Max_Entry_Num ; name entry count ok ?? | ||
| 2164 | jg Name_Error ; no - error | ||
| 2165 | jmp short Store_Name_Count ; yes - store it | ||
| 2166 | |||
| 2167 | Name_Error: ; invalid name count | ||
| 2168 | mov ax,invalid_name ; error code ;AN000; | ||
| 2169 | jmp parse_error ; display error | ||
| 2170 | |||
| 2171 | Store_Name_Count: | ||
| 2172 | mov Name_Count,ax ; save it (name count) ;AN000; ;AN000; | ||
| 2173 | add Total_name_count,ax ; update total name count ;AN000; ;AN000; | ||
| 2174 | |||
| 2175 | CALL SET_DRIVE_CACHE_HEADER ; Set Name cache header ;AN000; | ||
| 2176 | jc Cant_Set_Header ; jump if error ;AN000; | ||
| 2177 | jmp Complx_loop ; look for extent count ;AN000; | ||
| 2178 | |||
| 2179 | Cant_Set_Header: | ||
| 2180 | jmp Parse_Error ; error exit | ||
| 2181 | |||
| 2182 | |||
| 2183 | ;------------------------------------------------------------------------------- | ||
| 2184 | ; PROCESS EXTENT ENTRY (m) | ||
| 2185 | ;------------------------------------------------------------------------------- | ||
| 2186 | Proc_Extent_Entry: | ||
| 2187 | mov ax,valuelo ; get extent count entry | ||
| 2188 | cmp ax,1 ; validate entry between 1 an 10 ;AN000; | ||
| 2189 | jl Extent_Error ;AN000; | ||
| 2190 | cmp ax,10 | ||
| 2191 | jl set_default_ext ; if <10 set default entry 12 | ||
| 2192 | cmp ax,Max_Entry_Num ; >999 ?? | ||
| 2193 | jg Extent_Error ; yes - error | ||
| 2194 | jmp short Store_Extent_Count ; value OK, save it | ||
| 2195 | |||
| 2196 | Set_Default_Ext: ; for count 1 throug 9 set default count 12 | ||
| 2197 | mov ax,12 | ||
| 2198 | jmp short Store_Extent_Count | ||
| 2199 | |||
| 2200 | Extent_Error: ; invalid entry error | ||
| 2201 | mov ax,invalid_extent ; error code | ||
| 2202 | jmp parse_error ; display error ;AN000; | ||
| 2203 | |||
| 2204 | Store_Extent_Count: | ||
| 2205 | mov ext_count,ax ; save the count | ||
| 2206 | add Total_Ext_count,ax ; update total extent count | ||
| 2207 | mov di,parmbuff_ptr ; DI-->drive/extent buffer ;AN000; | ||
| 2208 | mov [di],ax ; save in buffer ;AN000; | ||
| 2209 | add parmbuff_ptr,2 ; move pointer to next extent in buffer ;AN000; | ||
| 2210 | mov si,Next_Parm ; get pointer to next param | ||
| 2211 | mov Current_Parm,si ; set next param address before parsing ;AN000; | ||
| 2212 | mov Par_Sw,1 ; set switch flag in PARMSX | ||
| 2213 | Jmp Parse_Loop ; parse next positional parameter ;AN000; | ||
| 2214 | |||
| 2215 | |||
| 2216 | ;---------------------------------------------------------------------------- | ||
| 2217 | ; PROCESS SWITCH (/X) OPTION | ||
| 2218 | ;---------------------------------------------------------------------------- | ||
| 2219 | Proc_Switch: | ||
| 2220 | cmp Prev_Type,0 ; any previous type ?? | ||
| 2221 | je Switch_Error ; no - error | ||
| 2222 | cmp Ext_Mem,0 ; switch previously specified ?? ;AN000; | ||
| 2223 | je set_sw_flag ; no, set flag ;AN000; | ||
| 2224 | |||
| 2225 | Switch_Error: | ||
| 2226 | mov ax,incorrect_param ; error code ;AN000; | ||
| 2227 | jmp bad_param ; error - /x could be specified only once | ||
| 2228 | |||
| 2229 | Set_Sw_flag: | ||
| 2230 | cmp Prev_Type,6 ; previous param = drive ID 12/15 P2939 ;AN000; | ||
| 2231 | jne sw_save_Ptr ; no - continue 12/15 p2939 ;AN000; | ||
| 2232 | ;AN000; | ||
| 2233 | CALL PROC_DEFAULT ; yes setup default counts for previous drive ;AN000; | ||
| 2234 | jnc sw_save_ptr ; no error - continue 12/15 p2939 ;AN000; | ||
| 2235 | jmp short parse_Error ; error - exit 12/15 P2939 ;AN000; | ||
| 2236 | |||
| 2237 | Sw_save_ptr: | ||
| 2238 | mov current_parm,si ; save current chara pointer ;AN000; | ||
| 2239 | mov bx,synonym ; get synonym (/x) ;AN000; ;AN000; | ||
| 2240 | cmp bx,offset e_switch ; /X ?? ;AN000; | ||
| 2241 | je set_extflag ; yes - check result buffer ;AN000; | ||
| 2242 | jmp Bad_Switch ; error exit | ||
| 2243 | |||
| 2244 | Set_ExtFlag: ; no, check reult buffer | ||
| 2245 | mov Ext_Mem,1 ; yes, set Hi Memory flag ;AN000; | ||
| 2246 | mov si,Current_parm ; -->next parameter ;AN000; | ||
| 2247 | mov al,PosTYpe ; set prevvious type before look for next ;AN000; | ||
| 2248 | mov Prev_Type,al ;AN000; | ||
| 2249 | jmp parse_loop ;AN000; | ||
| 2250 | |||
| 2251 | Bad_Switch: | ||
| 2252 | mov di,Next_Parm ; ending address of bad param 1/6/88 | ||
| 2253 | mov al,0 | ||
| 2254 | mov ds:[di],al ; set termination character | ||
| 2255 | LEA SI,SUBLIST1 ; DS:SI-->Substitution list ;AN000; | ||
| 2256 | MOV AX,CURRENT_PARM ; starting address of bad parameter ;AN000; | ||
| 2257 | MOV [SI].DATA_OFF,AX ; SI-->File name ;AN000; | ||
| 2258 | MOV [SI].DATA_SEG,DS ; DS-->Segment ;AN000; | ||
| 2259 | MOV [SI].MSG_ID,0 ; message ID ;AN000; | ||
| 2260 | MOV [SI].FLAGS,010H ; ASCIIZ string, left align ;AN000; | ||
| 2261 | MOV [SI].MAX_WIDTH,0 ; MAXIMUM FIELD WITH ;AN000; | ||
| 2262 | MOV [SI].MIN_WIDTH,0 ; MINIMUM FIELD WITH ;AN000; | ||
| 2263 | MOV BX,Invalid_Switch ; get message number | ||
| 2264 | MOV MSG_NUM,BX ; set message number ;AN000; | ||
| 2265 | MOV SUBST_COUNT,1 ; substitution count ;AN000; | ||
| 2266 | MOV MSG_CLASS,-1 ; message class ;AN000; | ||
| 2267 | MOV INPUT_FLAG,0 ; no input ;AN000; | ||
| 2268 | CALL PRINT_STDOUT ; display message ;AN000; | ||
| 2269 | stc ; error flag | ||
| 2270 | jmp Parse_Exit ; exit (1/6/88 P2670) | ||
| 2271 | |||
| 2272 | |||
| 2273 | |||
| 2274 | ;---------------------------------------------------------------------------- | ||
| 2275 | ; PROCESS PARSE ERROR | ||
| 2276 | ;---------------------------------------------------------------------------- | ||
| 2277 | PARSE_ERROR: ; AX = meassage number | ||
| 2278 | MOV MSG_CLASS,-1 ; message class ;AN000; | ||
| 2279 | MOV MSG_NUM,AX ; set message number ;AN000; | ||
| 2280 | MOV SUBST_COUNT,0 ; no message substitution ;AN000; | ||
| 2281 | MOV INPUT_FLAG,0 ; no input ;AN000; | ||
| 2282 | CALL PRINT_STDOUT ; show message ;AN000; | ||
| 2283 | stc ; set error flag ;AN000; | ||
| 2284 | |||
| 2285 | Parse_Exit: ; EXIT | ||
| 2286 | push cs ;AN000; | ||
| 2287 | pop ds ; DS - Program data area seg ;AN000; | ||
| 2288 | ret ;AN000; ;AN000; | ||
| 2289 | PARSE ENDP ; end of parser | ||
| 2290 | |||
| 2291 | |||
| 2292 | |||
| 2293 | |||
| 2294 | ;---------------------------------------------------------------------------- | ||
| 2295 | ; | ||
| 2296 | ; Procedure: PROC_DEFAULT | ||
| 2297 | ; | ||
| 2298 | ; Function: Process default parameters if name and extend counts | ||
| 2299 | ; are not specified with the drive id. | ||
| 2300 | ; | ||
| 2301 | ;---------------------------------------------------------------------------- | ||
| 2302 | |||
| 2303 | PROC_DEFAULT PROC ; PROCESS DEFAULT | ||
| 2304 | push si ; makesure to save next chara pointer ;AN000; | ||
| 2305 | mov ax,30h ; get default name count ;AN000; | ||
| 2306 | mov name_count,ax ; save it ;AN000; | ||
| 2307 | add Total_name_count,ax ; update total name count ;AN000; | ||
| 2308 | mov ext_count,ax ; save it ;AN000; ;AN000; | ||
| 2309 | add Total_Ext_count,ax ; save it ;AN000; ;AN000; | ||
| 2310 | mov di,ParmBuff_Ptr ; DS:DI-->parameter buffer ;AN000; | ||
| 2311 | mov [di],ax ; save in buffer ;AN000; | ||
| 2312 | add Parmbuff_ptr,2 ; points to next drive id position | ||
| 2313 | mov ax,Name_Count ;AN000; | ||
| 2314 | CALL Set_drive_Cache_Header ; Set Name cache header ;AN000; | ||
| 2315 | |||
| 2316 | Default_Exit: | ||
| 2317 | pop si ;AN000; | ||
| 2318 | ret ; return ;AN000; | ||
| 2319 | |||
| 2320 | PROC_DEFAULT ENDP | ||
| 2321 | |||
| 2322 | |||
| 2323 | |||
| 2324 | |||
| 2325 | ;---------------------------------------------------------------------------- | ||
| 2326 | ; Procedure: VERIFY_COUNTS | ||
| 2327 | ; | ||
| 2328 | ; Function: Verify the validity of the name and extent counts | ||
| 2329 | |||
| 2330 | ;---------------------------------------------------------------------------- | ||
| 2331 | VERIFY_COUNTS PROC NEAR | ||
| 2332 | |||
| 2333 | ; Check the validity of NAME and EXTENT count entries | ||
| 2334 | cmp Total_ext_count,0 ; any extent param ?? ;AN000; | ||
| 2335 | je Chk_Name_Count ; no, dont check extent count ;AN000; | ||
| 2336 | cmp Total_ext_count, Max_Entry_Num ; check lower boundry ;AN000; | ||
| 2337 | jg invalid_ext ; error if not within ;AN000; | ||
| 2338 | clc ; Extent Count is valid | ||
| 2339 | |||
| 2340 | ; Extent count is OK, check Name count | ||
| 2341 | Chk_Name_Count: | ||
| 2342 | cmp Total_Name_Count,0 ; any name param ?? ;AN000; | ||
| 2343 | je Verify_Exit ; no, dont check extent count ;AN000; | ||
| 2344 | |||
| 2345 | cmp Total_name_count, Max_Entry_Num ;AN000; | ||
| 2346 | jg invalid_name_entry ;AN000; | ||
| 2347 | clc ; Name count is OK ;AN000; | ||
| 2348 | jmp short verify_exit ; exit ;AN000; | ||
| 2349 | |||
| 2350 | Invalid_ext: | ||
| 2351 | mov ax,many_ext_entries ; AX = error code ;AN000; | ||
| 2352 | stc | ||
| 2353 | jmp short verify_exit ;AN000; | ||
| 2354 | |||
| 2355 | Invalid_name_entry: | ||
| 2356 | mov ax,many_name_entries ; AX = error code ;AN000; | ||
| 2357 | stc ;AN000; | ||
| 2358 | |||
| 2359 | Verify_Exit: ; | ||
| 2360 | |||
| 2361 | RET ;AN000; | ||
| 2362 | |||
| 2363 | VERIFY_COUNTS ENDP | ||
| 2364 | |||
| 2365 | |||
| 2366 | |||
| 2367 | |||
| 2368 | |||
| 2369 | |||
| 2370 | |||
| 2371 | |||
| 2372 | |||
| 2373 | |||
| 2374 | |||
| 2375 | ;========================================================================= | ||
| 2376 | ; CHECK_DRIVE | ||
| 2377 | ;----------------------------------------------------------------------- | ||
| 2378 | ; | ||
| 2379 | ; INPUT: AL - Drive letter | ||
| 2380 | ; | ||
| 2381 | ; OUTPUT: | ||
| 2382 | ; If Carry = 0 | ||
| 2383 | ; user_drive set to current entered drive letter | ||
| 2384 | ; num_Of_drives incremented | ||
| 2385 | ; If Carry = 1 error | ||
| 2386 | ;----------------------------------------------------------------------- | ||
| 2387 | ; 1) see if drive is valid and removable using int 21h IOCTL | ||
| 2388 | ; | ||
| 2389 | ; 2) use int 21h name translate to make sure that the drive is not | ||
| 2390 | ; redirected, substed, on another machine, or in any other way shape | ||
| 2391 | ; or form hosed. | ||
| 2392 | ;========================================================================= | ||
| 2393 | |||
| 2394 | CHECK_DRIVE PROC NEAR | ||
| 2395 | |||
| 2396 | CALL Convert_To_Caps ; make sure it is a capital letter | ||
| 2397 | mov byte ptr user_drive,al ; save it in user drive | ||
| 2398 | mov byte ptr source_xname,al ; put in source string for call | ||
| 2399 | |||
| 2400 | mov bl,al ;put drive letter in bl | ||
| 2401 | sub bl,"A"-1 ;convert to 1 based number | ||
| 2402 | |||
| 2403 | mov ah,ioctl ;set up for removable call | ||
| 2404 | mov al,8 ;function code | ||
| 2405 | INT int_command | ||
| 2406 | |||
| 2407 | cmp ax,1 ;is drive fixed? | ||
| 2408 | jz okay_drive ;yes - see if it's subst | ||
| 2409 | cmp ax,0fh ;is drive valid? | ||
| 2410 | jnz hosed_drive ;yes - but hosed | ||
| 2411 | |||
| 2412 | mov ax,invalid_drive ; set bad drive message | ||
| 2413 | jmp short drive_Error ; display error message | ||
| 2414 | |||
| 2415 | Okay_Drive: | ||
| 2416 | lea si,source_xname ; set up for name translate | ||
| 2417 | lea di,target_xname | ||
| 2418 | mov ax,xNameTrans SHL 8 | ||
| 2419 | INT int_command ;do the translation | ||
| 2420 | |||
| 2421 | lea si,source_xname ;compare source and target drive | ||
| 2422 | lea di,target_xname | ||
| 2423 | |||
| 2424 | mov cx,Len_source_xname ;get count of invalid chars | ||
| 2425 | repz cmpsb ;compare until mismatch found | ||
| 2426 | jz check_drive_end ;no mismatch - exit | ||
| 2427 | |||
| 2428 | Hosed_Drive: | ||
| 2429 | MOV AX,BAD_USE_MESSAGE ; message number | ||
| 2430 | |||
| 2431 | Drive_Error: | ||
| 2432 | push ax ; save message number | ||
| 2433 | mov ax,Valuelo ; get drive letter number from result buff | ||
| 2434 | ; C:=3 D:=4 etc, Parser drive id convention | ||
| 2435 | add al,040H ; convert to drive letter | ||
| 2436 | lea si,Drive_Id ; DS:SI-->drive letter save area | ||
| 2437 | mov [si],al ; save drive letter in buffer | ||
| 2438 | |||
| 2439 | LEA SI,SUBLIST1 ; DS:SI-->Substitution list ;AN000; | ||
| 2440 | MOV AX,OFFSET DRIVE_ID ;AN000; | ||
| 2441 | MOV [SI].DATA_OFF,AX ; SI-->File name ;AN000; | ||
| 2442 | MOV [SI].DATA_SEG,DS ; DS-->Segment ;AN000; | ||
| 2443 | MOV [SI].MSG_ID,1 ; message ID ;AN000; | ||
| 2444 | MOV [SI].FLAGS,010H ; ASCIIZ string, left align ;AN000; | ||
| 2445 | MOV [SI].MAX_WIDTH,0 ; MAXIMUM FIELD WITH ;AN000; | ||
| 2446 | MOV [SI].MIN_WIDTH,0 ; MINIMUM FIELD WITH ;AN000; | ||
| 2447 | POP AX ; restore message number ;AN000; | ||
| 2448 | MOV MSG_NUM,AX ; set message number ;AN000; | ||
| 2449 | MOV SUBST_COUNT,1 ; substitution count ;AN000; | ||
| 2450 | MOV MSG_CLASS,-1 ; message class ;AN000; | ||
| 2451 | MOV INPUT_FLAG,0 ; no input ;AN000; | ||
| 2452 | CALL PRINT_STDOUT ; display message ;AN000; | ||
| 2453 | stc ; error flag | ||
| 2454 | |||
| 2455 | Check_Drive_End: | ||
| 2456 | ret ; return | ||
| 2457 | |||
| 2458 | CHECK_DRIVE endp | ||
| 2459 | |||
| 2460 | |||
| 2461 | |||
| 2462 | |||
| 2463 | |||
| 2464 | ;========================================================================= | ||
| 2465 | ; Procedure: SET_DRIVE_CACHE_HEADER | ||
| 2466 | ; | ||
| 2467 | ; Function: Set name cache drive header | ||
| 2468 | ; | ||
| 2469 | ; Input: ax contains number of entries for num_entries | ||
| 2470 | ; user_drive contains user drive for drive_letter | ||
| 2471 | ; num_Of_drives contains number of caches set up so far | ||
| 2472 | ; drive_cache offset of drive cache headers start | ||
| 2473 | ; Output: | ||
| 2474 | ; If successful: | ||
| 2475 | ; drive cache header set up | ||
| 2476 | ; user_drive reset to blank | ||
| 2477 | ; num_Of_drives incremented | ||
| 2478 | ; else | ||
| 2479 | ; bx set to error flag | ||
| 2480 | ; dx points to error message | ||
| 2481 | ;----------------------------------------------------------------------- | ||
| 2482 | ; 1) see if drive too many drives have been entered. | ||
| 2483 | ; 2) Walk through drive cache headers to make sure that the drive | ||
| 2484 | ; letter was not previously entered. | ||
| 2485 | ; 3) Set up drive cache header | ||
| 2486 | ;========================================================================= | ||
| 2487 | |||
| 2488 | SET_DRIVE_CACHE_HEADER PROC NEAR | ||
| 2489 | |||
| 2490 | mov cx,num_of_drives ;get current count of drives | ||
| 2491 | mov bx,offset drive_cache ;get start of name drive cache | ||
| 2492 | mov dl,user_drive ;get user entered drive | ||
| 2493 | dec cx ;is this the 1st drive entered ? | ||
| 2494 | jcxz set_it_up ;yes - don't check | ||
| 2495 | |||
| 2496 | cmp num_Of_drives,max_drives ;no - check for maximum num of drives | ||
| 2497 | jng we_have_room ;yes - go check for dup drives | ||
| 2498 | mov ax,too_many_entries ;set up for error message | ||
| 2499 | stc ;set up error flag | ||
| 2500 | jmp short set_dheader_exit ;and exit | ||
| 2501 | |||
| 2502 | ;----------------------------------------------------------------------- | ||
| 2503 | ; Search through the drive headers to see the duplicate drive exist. | ||
| 2504 | ; If a new drive header at the bottom of the chain for the new drive. | ||
| 2505 | ; If no drives exist, then create the new header as the first drive header. | ||
| 2506 | ;----------------------------------------------------------------------- | ||
| 2507 | We_Have_Room: ;BX-->current drive header | ||
| 2508 | cmp dl,[bx].dch_drive_letter ;drive header exist for this drive?? | ||
| 2509 | jnz not_dup_drive ;no - continue | ||
| 2510 | mov ax,dup_drive ;yes - set up for error message | ||
| 2511 | stc | ||
| 2512 | jmp short set_dheader_exit ;exit | ||
| 2513 | |||
| 2514 | Not_Dup_Drive: | ||
| 2515 | cmp [bx].dch_sibling_ptr,no_siblings ;any more header to search ?? | ||
| 2516 | jz set_drive_sibling ;no - go create the new drive header | ||
| 2517 | add bx,size drive_cache_header ;yes - get pointer to next drive header | ||
| 2518 | jmp short we_have_room ;check it | ||
| 2519 | |||
| 2520 | Set_drive_sibling: | ||
| 2521 | mov cx,bx ;save current header address | ||
| 2522 | add cx,size drive_cache_header ;pointer to next header | ||
| 2523 | mov [bx].dch_sibling_ptr,cx ;set pointer to new header from current hdr | ||
| 2524 | mov bx,cx ;BX-->new header | ||
| 2525 | |||
| 2526 | Set_it_up: | ||
| 2527 | mov [bx].dch_drive_letter,dl ;save drive letter in new header | ||
| 2528 | mov [bx].dch_sibling_ptr,no_siblings ;mark new header as last header in chain | ||
| 2529 | mov [bx].dch_num_entries,ax ;save name count in new header | ||
| 2530 | |||
| 2531 | Set_dheader_Exit: ; Exit | ||
| 2532 | ret | ||
| 2533 | |||
| 2534 | SET_DRIVE_CACHE_HEADER ENDP | ||
| 2535 | |||
| 2536 | |||
| 2537 | |||
| 2538 | |||
| 2539 | |||
| 2540 | subttl Convert to caps | ||
| 2541 | page | ||
| 2542 | ;========================================================================= | ||
| 2543 | ; Procedure: Convert_to_caps | ||
| 2544 | ; | ||
| 2545 | ; CONVERT LOWER CASE CHARACTERS TO UPPER CASE | ||
| 2546 | ; Convert character in al to a capital letter. | ||
| 2547 | |||
| 2548 | ;========================================================================= | ||
| 2549 | |||
| 2550 | CONVERT_TO_CAPS PROC NEAR | ||
| 2551 | |||
| 2552 | cmp al,"a" | ||
| 2553 | JNAE no_convert | ||
| 2554 | cmp al,"z" | ||
| 2555 | JNBE no_convert | ||
| 2556 | sub al,32 | ||
| 2557 | |||
| 2558 | No_Convert: | ||
| 2559 | ret ;and return | ||
| 2560 | |||
| 2561 | CONVERT_TO_CAPS ENDP | ||
| 2562 | |||
| 2563 | |||
| 2564 | |||
| 2565 | |||
| 2566 | |||
| 2567 | |||
| 2568 | |||
| 2569 | ;========================================================================= | ||
| 2570 | ; SET_EMS : THIS MODULE SETS EMS FOR FASTOPEN CODE AND DATA | ||
| 2571 | ; PAGE 0 IN HIGH MEMORY IS MAPPED FOR CODE USING | ||
| 2572 | ; THE PHYSICAL PAGE FRAME AND PAGE 1 IS | ||
| 2573 | ; MAPPED FOR DATA USING PHYSICAL PAGE FRAME NUMBER | ||
| 2574 | ; TWO PHYSICAL PAGE FRAME SEG IDs ARE SAVED AND | ||
| 2575 | ; THEY WILL BE USED BY THE (MAIN) ROUTINE. | ||
| 2576 | ; | ||
| 2577 | ; INPUTS : NONE | ||
| 2578 | ; | ||
| 2579 | ; OUTPUTS : CY - ERROR | ||
| 2580 | ; | ||
| 2581 | ; NC - EMS_PAGE_SEG - SEG ID OF SINGLE PAGE FRAME | ||
| 2582 | ;========================================================================= | ||
| 2583 | |||
| 2584 | SET_EMS PROC NEAR | ||
| 2585 | CALL EMS_CHECK1 ;SEE IF EMS INSTALLED ;AN000; | ||
| 2586 | JNC EMS_GET_PAGE ; yes, get page ;AN000; | ||
| 2587 | |||
| 2588 | MOV EMS_FLAG,0 ; Flag EMS not installed ;AN000; | ||
| 2589 | STC ; Make sure carry is Clear ;AN000; | ||
| 2590 | JMP EMS_EXIT ; Leave check routine ;AN000; | ||
| 2591 | |||
| 2592 | EMS_GET_PAGE: | ||
| 2593 | PUSH ES ; save ES,DI they may destroy by 2F | ||
| 2594 | PUSH DI | ||
| 2595 | |||
| 2596 | IF NOT BUFFERFLAG | ||
| 2597 | |||
| 2598 | MOV AH,EMS_2F_HANDLER | ||
| 2599 | XOR AL,AL | ||
| 2600 | INT 2FH ; see 2F is there | ||
| 2601 | CMP AL,0FFH | ||
| 2602 | JNE EMS_PAGE_ERR ; error, if not | ||
| 2603 | |||
| 2604 | MOV AH,EMS_2F_HANDLER | ||
| 2605 | MOV AL,0FFH | ||
| 2606 | MOV DI,0FEH | ||
| 2607 | INT 2FH ; get EMS page | ||
| 2608 | OR AH,AH | ||
| 2609 | JNZ EMS_PAGE_ERR | ||
| 2610 | MOV EMS_PAGE_SEG,ES ; SAVE PAGE SEG ID | ||
| 2611 | MOV EMS_PAGE_NUM,DI ; SAVE PHYSICAL PAGE NUMBER | ||
| 2612 | |||
| 2613 | ELSE | ||
| 2614 | |||
| 2615 | ;---------------------------------------------------------------HKN 8/25/88 | ||
| 2616 | ; Fastopen must get an EMS page like a well behaved program and | ||
| 2617 | ; should not grab a reserved page from the BIOS. | ||
| 2618 | ; | ||
| 2619 | mov cx, FRAME_COUNT | ||
| 2620 | xor ax, ax | ||
| 2621 | mov bx, ax | ||
| 2622 | mov dx, ax | ||
| 2623 | |||
| 2624 | get_page: | ||
| 2625 | cmp es:[di], 0a000h ; is the page in ax above 640K | ||
| 2626 | jb next_page ; if no get next_page | ||
| 2627 | |||
| 2628 | mov bx, di ; we have a valid page | ||
| 2629 | |||
| 2630 | inc dx ; count the # of pages above 640K | ||
| 2631 | |||
| 2632 | cmp dx, 1 | ||
| 2633 | je next_page | ||
| 2634 | sub di, 4 | ||
| 2635 | mov ax, es:[di] | ||
| 2636 | mov [FST_PAGE], ax | ||
| 2637 | mov ax, es:[di+2] | ||
| 2638 | mov [FST_PAGE+2], ax | ||
| 2639 | mov di, bx ; restore di | ||
| 2640 | |||
| 2641 | next_page: | ||
| 2642 | add di, 4 | ||
| 2643 | loop get_page | ||
| 2644 | jne found_page | ||
| 2645 | jmp ems_page_err | ||
| 2646 | |||
| 2647 | found_page: | ||
| 2648 | ; int 3 | ||
| 2649 | cmp dx, 1 | ||
| 2650 | jne second_last_page | ||
| 2651 | mov di, bx | ||
| 2652 | mov ax, es:[di] | ||
| 2653 | mov ems_page_seg, ax | ||
| 2654 | mov ax, es:[di+2] | ||
| 2655 | mov ems_page_num, ax | ||
| 2656 | jmp save_state | ||
| 2657 | |||
| 2658 | second_last_page: | ||
| 2659 | mov ax, [FST_PAGE] | ||
| 2660 | mov ems_page_seg, ax | ||
| 2661 | mov ax, [FST_PAGE+2] | ||
| 2662 | mov ems_page_num, ax | ||
| 2663 | |||
| 2664 | save_state: | ||
| 2665 | push es | ||
| 2666 | mov ax, Cseg_Main | ||
| 2667 | mov es, ax | ||
| 2668 | assume es:Cseg_Main | ||
| 2669 | |||
| 2670 | mov word ptr save_map_addr, offset es:save_ems_page_state | ||
| 2671 | mov word ptr save_map_addr + 2, ax | ||
| 2672 | |||
| 2673 | mov ax, ems_page_seg | ||
| 2674 | mov es:Main_EMS_PAGE_SEG, ax | ||
| 2675 | pop es | ||
| 2676 | assume es:Cseg_Init | ||
| 2677 | call [save_map_addr] | ||
| 2678 | jc ems_page_err | ||
| 2679 | |||
| 2680 | ;-------------------------------------------------------------------------- | ||
| 2681 | |||
| 2682 | ENDIF | ||
| 2683 | |||
| 2684 | POP DI | ||
| 2685 | POP ES | ||
| 2686 | JMP SHORT EMS_ALLOCATE_PAGE | ||
| 2687 | |||
| 2688 | EMS_PAGE_ERR: | ||
| 2689 | POP DI | ||
| 2690 | POP ES | ||
| 2691 | STC ;yes, page not found ;AN000; | ||
| 2692 | JMP SHORT EMS_ERROR ;error exit ;AN000; | ||
| 2693 | |||
| 2694 | ;----------------------------------------------------------------------- | ||
| 2695 | ; Allocate one page | ||
| 2696 | ;----------------------------------------------------------------------- | ||
| 2697 | EMS_ALLOCATE_PAGE: | ||
| 2698 | MOV BX,1 ;one page ;AN000; | ||
| 2699 | MOV AH,EMS_ALLOC_PAGES ;set op code ;AN000; | ||
| 2700 | INT EMS_INT ;allocate page ;AN000; | ||
| 2701 | OR AH,AH ;Was there an error allocating? ;AN000; | ||
| 2702 | JNZ EMS_ERROR ;yes - display error ;AN000; | ||
| 2703 | MOV EXT_HANDLE,DX ;no -Save EMS handle | ||
| 2704 | |||
| 2705 | IF BUFFERFLAG | ||
| 2706 | |||
| 2707 | ;------------------------------------------------------HKN 8/25/88 | ||
| 2708 | ; Must save ems handle in Cseg_Main also. | ||
| 2709 | |||
| 2710 | push es | ||
| 2711 | push ax | ||
| 2712 | mov ax, Cseg_Main | ||
| 2713 | mov es, ax | ||
| 2714 | assume es:Cseg_Main | ||
| 2715 | mov es:ems_save_handle1, dx | ||
| 2716 | pop ax | ||
| 2717 | pop es | ||
| 2718 | assume es:Cseg_Init | ||
| 2719 | |||
| 2720 | ENDIF | ||
| 2721 | |||
| 2722 | ;----------------------------------------------------------------------- | ||
| 2723 | ; SET HANDLE NAME TO THE PAGE HANDLE | ||
| 2724 | ;----------------------------------------------------------------------- | ||
| 2725 | PUSH DS ;AN000; | ||
| 2726 | POP ES ;AN000; | ||
| 2727 | ASSUME ES:CSEG_INIT ;AN000; | ||
| 2728 | LEA SI,HANDLE_NAME ; DS:SI-->Handle name string ;AN000; | ||
| 2729 | MOV DX,EXT_HANDLE ; handle number ;AN000; | ||
| 2730 | MOV AH,EMS_HANDLE_NAME ;AN000; | ||
| 2731 | MOV AL,1 ; set op code code ;AN000; | ||
| 2732 | INT 67H ; set handle ;AN000; | ||
| 2733 | OR AH,AH ;AN000; | ||
| 2734 | JNZ EMS_ERROR ; jump if error ;AN000; | ||
| 2735 | |||
| 2736 | ;----------------------------------------------------------------------- | ||
| 2737 | ; Map logical page 0 in physical page frame FE (P254) | ||
| 2738 | ;----------------------------------------------------------------------- | ||
| 2739 | CALL MAP_FRAME ;map two pages ;AN000; | ||
| 2740 | JNC EMS_GET_SIZE ;no error, normal exit ;AN000; | ||
| 2741 | |||
| 2742 | ;----------------------------------------------------------------------- | ||
| 2743 | ; Get partial page map size | ||
| 2744 | ;----------------------------------------------------------------------- | ||
| 2745 | EMS_GET_SIZE: | ||
| 2746 | MOV AH,EMS_PAGE_SIZE ;Allocate requested pages ;AN000; | ||
| 2747 | MOV AL,2 | ||
| 2748 | INT EMS_INT ; ;AN000; | ||
| 2749 | OR AH,AH | ||
| 2750 | JNZ EMS_ERROR | ||
| 2751 | XOR AH,AH | ||
| 2752 | MOV EMS_PAGESIZE,AX ;save EMS page size | ||
| 2753 | CLC | ||
| 2754 | JMP SHORT EMS_EXIT | ||
| 2755 | |||
| 2756 | EMS_ERROR: | ||
| 2757 | MOV AX,EMS_FAILED ;error message ;AN000; | ||
| 2758 | MOV MSG_NUM,AX ;save message number | ||
| 2759 | MOV SUBST_COUNT,0 ;no message substitution ;AN000; | ||
| 2760 | MOV MSG_CLASS,-1 ;message class ;AN000; | ||
| 2761 | MOV INPUT_FLAG,0 ;no input ;AN000; | ||
| 2762 | CALL PRINT_STDOUT ;show message "Incorrect Parameter" ;AN000; | ||
| 2763 | STC ; set error flag ;AN000; | ||
| 2764 | |||
| 2765 | EMS_EXIT: | ||
| 2766 | RET ; Return ;AN000; | ||
| 2767 | |||
| 2768 | SET_EMS ENDP | ||
| 2769 | |||
| 2770 | |||
| 2771 | |||
| 2772 | |||
| 2773 | |||
| 2774 | |||
| 2775 | ;========================================================================= | ||
| 2776 | ; EMS_CHECK1 : THIS MODULE DETERMINES WHETHER OR NOT EMS IS | ||
| 2777 | ; INSTALLED FOR THIS SESSION. | ||
| 2778 | ; | ||
| 2779 | ; INPUTS : NONE | ||
| 2780 | ; | ||
| 2781 | ; OUTPUTS : ES:BX - FRAME ARRAY | ||
| 2782 | ; CY - EMS NOT AVAILABLE | ||
| 2783 | ; NC - EMS AVAILABLE | ||
| 2784 | ;========================================================================= | ||
| 2785 | |||
| 2786 | EMS_CHECK1 PROC NEAR ;EMS INSTALL CHECK | ||
| 2787 | |||
| 2788 | PUSH DS ;save ds ;AN000; | ||
| 2789 | XOR AX,AX ;set ax to 0 ;AN000; | ||
| 2790 | MOV DS,AX ;set ds to 0 ;AN000; | ||
| 2791 | CMP DS:WORD PTR[067h*4+0],0 ;see if int 67h is there ;AN000; | ||
| 2792 | POP DS ;restore ds ;AN000; | ||
| 2793 | JE EMS_NOT_INST1 ;no, EMS not installed ;AN000; | ||
| 2794 | |||
| 2795 | MOV AH,EMS_GET_STATUS ;YES, GET STATUS ;AN000; | ||
| 2796 | INT EMS_INT ;INT 67H ;AN000; | ||
| 2797 | CMP AH,0 ;EMS MANAGER PRESENT ?? | ||
| 2798 | JNE EMS_NOT_INST1 ;NO, EMS NOT INSTALLED | ||
| 2799 | |||
| 2800 | MOV AH,EMS_GET_VERSION ;YES, GET STATUS ;AN000; ;AN000; | ||
| 2801 | INT EMS_INT ;INT 67H ;AN000;;AN000; | ||
| 2802 | CMP AH,0 ;EMS MANAGER PRESENT ?? ;AN000; | ||
| 2803 | JNE EMS_NOT_INST1 ;NO, EMS NOT INSTALLED ;AN000; | ||
| 2804 | |||
| 2805 | CMP AL,40H ;VERSION 4.0 ?? ;AN000; | ||
| 2806 | JNE EMS_NOT_INST1 ;NO, EMS NOT INSTALLED ;AN000; | ||
| 2807 | |||
| 2808 | MOV AX,EMS_GET_COUNT | ||
| 2809 | INT EMS_INT ;GET ARRAY COUNT | ||
| 2810 | CMP AH,0 | ||
| 2811 | JNE EMS_NOT_INST1 | ||
| 2812 | |||
| 2813 | MOV FRAME_COUNT,CX | ||
| 2814 | MOV AX, BUFFER_ENTRY_SIZE | ||
| 2815 | MUL CX ; CALCULATE THE ARRAY SIZE BE RESERVED | ||
| 2816 | |||
| 2817 | IF NOT IBMCOPYRIGHT | ||
| 2818 | CMP AX, 100h | ||
| 2819 | ELSE | ||
| 2820 | CMP AX, 30H | ||
| 2821 | ENDIF | ||
| 2822 | |||
| 2823 | JG EMS_NOT_INST1 | ||
| 2824 | |||
| 2825 | MOV AX,EMS_GET_FRAME_ADDR ;YES, GET FRAME ADDRESS ;AN000; | ||
| 2826 | PUSH DS ;SWAP DS & ES ;AN000; | ||
| 2827 | POP ES ; ;AN000; | ||
| 2828 | LEA DI,FRAME_BUFFER ;ES:DI--> RESULT BUFFER ;AN000; | ||
| 2829 | INT EMS_INT ;GET FRAME ADDRESSES ;AN000; | ||
| 2830 | CMP AH,0 ;IS EMS INSTALLED ;AN000; | ||
| 2831 | JNE EMS_NOT_INST1 ;NO,exit | ||
| 2832 | CMP CX,FRAME_COUNT ; ;AN000; | ||
| 2833 | JNE SHORT EMS_NOT_INST1 | ||
| 2834 | |||
| 2835 | CLC | ||
| 2836 | MOV EMS_FLAG,1 ; EMS IS ACTIVE, SET FLAG | ||
| 2837 | JMP EMS_CHECK1_EXIT | ||
| 2838 | |||
| 2839 | EMS_NOT_INST1: ;EMS NOT INSTALLED | ||
| 2840 | MOV AX,EMS_NOT_INSTALL ;error message ;AN000; | ||
| 2841 | MOV MSG_NUM,AX ;set message number ;AN000; | ||
| 2842 | MOV SUBST_COUNT,0 ;no message substitution ;AN000; | ||
| 2843 | MOV MSG_CLASS,-1 ;message class ;AN000; | ||
| 2844 | MOV INPUT_FLAG,0 ;no input ;AN000; | ||
| 2845 | CALL PRINT_STDOUT ;show message | ||
| 2846 | STC ;FLAG EMS NOT INSTALLED ;AN000; | ||
| 2847 | ;AN000; | ||
| 2848 | EMS_CHECK1_EXIT: ;EXIT ROUTINE | ||
| 2849 | RET ;RETURN TO CALLER ;AN000; | ||
| 2850 | |||
| 2851 | EMS_CHECK1 ENDP | ||
| 2852 | |||
| 2853 | |||
| 2854 | |||
| 2855 | |||
| 2856 | ;========================================================================= | ||
| 2857 | ; MAP_FRAME : THIS MODULE MAPS TWO LOGICAL PAGES IN THE HIGH | ||
| 2858 | ; MEMORY TO TWO PHYSICAL PAGE FEAMES IN THE LOW | ||
| 2859 | ; MEMORY. | ||
| 2860 | ; | ||
| 2861 | ; INPUTS : EXT_HANDLE - HANDLE | ||
| 2862 | ; | ||
| 2863 | ; OUTPUTD CY - ERROR | ||
| 2864 | ; NC - PAGE IS MAPPED | ||
| 2865 | ;========================================================================= | ||
| 2866 | |||
| 2867 | MAP_FRAME PROC NEAR ; MAP physical page frames | ||
| 2868 | PUSH BX ; DMS; | ||
| 2869 | XOR BX,BX ; Logical page 0 ;AN000; | ||
| 2870 | MOV AX,EMS_PAGE_NUM ; AL=Physical Page frame number ;AN000; | ||
| 2871 | MOV AH,EMS_MAP_HANDLE ; AH=EMS function to map page ;AN000; | ||
| 2872 | MOV DX,EXT_HANDLE ; EMS handle ;AN000; | ||
| 2873 | INT EMS_INT ;AN000; | ||
| 2874 | OR AH,AH ; Was there an error allocating? ;AN000; | ||
| 2875 | JNZ MAP_ERROR ; yes - set flag ;AN000; | ||
| 2876 | CLC | ||
| 2877 | JMP SHORT MAP_EXIT ; no - exit ;AN000; | ||
| 2878 | |||
| 2879 | MAP_ERROR: | ||
| 2880 | STC ; set error flag ;AN000; | ||
| 2881 | |||
| 2882 | MAP_EXIT: | ||
| 2883 | POP BX ;AN000; | ||
| 2884 | RET ; return ;AN000; | ||
| 2885 | |||
| 2886 | |||
| 2887 | MAP_FRAME ENDP | ||
| 2888 | |||
| 2889 | |||
| 2890 | |||
| 2891 | |||
| 2892 | |||
| 2893 | |||
| 2894 | |||
| 2895 | |||
| 2896 | ;************************************************************ | ||
| 2897 | ;* | ||
| 2898 | ;* SUBROUTINE NAME: PRINT_STDOUT | ||
| 2899 | ;* | ||
| 2900 | ;* SUBROUTINE FUNCTION: | ||
| 2901 | ;* Display the requested message to the specified handle | ||
| 2902 | ;* | ||
| 2903 | ;* INPUT: | ||
| 2904 | ;* Paramters in parater storage area | ||
| 2905 | ;* DS:SI-->Substitution List | ||
| 2906 | ;* ES:DI-->PTR to input buffer if buffered keyboard | ||
| 2907 | ;* input is specified (DL = 0A) | ||
| 2908 | ;* OUTPUT: | ||
| 2909 | ;* AX = Single character entered if DL=01 | ||
| 2910 | ;* OR | ||
| 2911 | ;* ES:DI-->input buffer where string is returned if DL=0A | ||
| 2912 | ;* | ||
| 2913 | ;* The message corresponding to the requested msg number will | ||
| 2914 | ;* be written to Standard Out. Message substitution will | ||
| 2915 | ;* be performed if specified | ||
| 2916 | ;* | ||
| 2917 | ;* NORMAL EXIT: | ||
| 2918 | ;* Message will be successfully written to requested handle. | ||
| 2919 | ;* | ||
| 2920 | ;* ERROR EXIT: | ||
| 2921 | ;* None. Note that theoretically an error can be returned from | ||
| 2922 | ;* SYSDISPMSG, but there is nothing that the application can do. | ||
| 2923 | ;* | ||
| 2924 | ;* INTERNAL REFERENCES: SysDispMsg | ||
| 2925 | ;* | ||
| 2926 | ;* EXTERNAL REFERENCES: | ||
| 2927 | ;* None | ||
| 2928 | ;* | ||
| 2929 | ;************************************************************ | ||
| 2930 | PRINT_STDOUT PROC NEAR | ||
| 2931 | PUSH BX ;AN000; | ||
| 2932 | PUSH CX ;AN000; | ||
| 2933 | PUSH DX ;AN000; | ||
| 2934 | |||
| 2935 | MOV AX,MSG_NUM ; Message ID ;AN000; | ||
| 2936 | MOV BX,STDOUT ; standard input message handle ;AN000; | ||
| 2937 | MOV CX,SUBST_COUNT ; message substitution count ;AN000; | ||
| 2938 | MOV DH,MSG_CLASS ; message class ;AN000; | ||
| 2939 | MOV DL,INPUT_FLAG ; Type of INT 10 for KBD input ;AN000; | ||
| 2940 | |||
| 2941 | CALL SYSDISPMSG ; AX=Extended key value if wait ;AN000; | ||
| 2942 | ;for key ;AN000; | ||
| 2943 | JNC DISP_DONE ; If CARRY SET then registers | ||
| 2944 | ;will contain extended error info ;AN000; | ||
| 2945 | ; AX - Extended error Number | ||
| 2946 | ; BH - Error Class | ||
| 2947 | ; BL - Suggested action | ||
| 2948 | DISP_DONE: ; CH - Locus | ||
| 2949 | POP DX ;AN000; | ||
| 2950 | POP CX ;AN000; | ||
| 2951 | POP BX ;AN000; | ||
| 2952 | ;AN000; | ||
| 2953 | RET | ||
| 2954 | PRINT_STDOUT ENDP | ||
| 2955 | |||
| 2956 | |||
| 2957 | CSEG_INIT ENDS | ||
| 2958 | |||
| 2959 | |||
| 2960 | ;=========================================================================== | ||
| 2961 | ;;; STACK SEGMENT SIZE = 20 PARAGRAPHS | ||
| 2962 | ;=========================================================================== | ||
| 2963 | |||
| 2964 | STACK SEGMENT PARA STACK 'STACK' | ||
| 2965 | DB 64 dup("STACK ") ; 512 WORD STACK AREA ;AN000; | ||
| 2966 | STACK ENDS | ||
| 2967 | |||
| 2968 | |||
| 2969 | END START | ||
| 2970 | |||
diff --git a/v4.0/src/CMD/FASTOPEN/FASTOPEN.ASM b/v4.0/src/CMD/FASTOPEN/FASTOPEN.ASM new file mode 100644 index 0000000..5594abd --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTOPEN.ASM | |||
| @@ -0,0 +1,2052 @@ | |||
| 1 | Page 84,132 ; | ||
| 2 | Title FASTOPEN | ||
| 3 | ;Date: May 13,1988 | ||
| 4 | ;============================================================================== | ||
| 5 | ; EQUATES | ||
| 6 | ;============================================================================== | ||
| 7 | Is_drive_head EQU 00000001b ;AN000; | ||
| 8 | Is_delete EQU 00000010b ;AN000; | ||
| 9 | Is_insert EQU 00000100b ;AN000; | ||
| 10 | Not_drive_head EQU 11111110b ;AN000; | ||
| 11 | Not_delete EQU 11111101b ;AN000; | ||
| 12 | Not_insert EQU 11111011b | ||
| 13 | |||
| 14 | EMS_SAVE_STATE EQU 4FH ;AN000; | ||
| 15 | EMS_RESTORE_STATE EQU 4FH ;AN000; | ||
| 16 | EMS_INT EQU 67H ;AN000; | ||
| 17 | DOS_PAGE1 EQU 0FEH ;AN000; | ||
| 18 | |||
| 19 | |||
| 20 | ;============================================================================== | ||
| 21 | ; INCLUDE FILES | ||
| 22 | ;============================================================================== | ||
| 23 | .xcref | ||
| 24 | .xlist | ||
| 25 | debug=0 ; an equate only for DOSMAC.inc ;AN000; | ||
| 26 | INCLUDE DOSMAC.inc ;AN000; | ||
| 27 | .list | ||
| 28 | .cref | ||
| 29 | INCLUDE dirent.inc ;AN000; | ||
| 30 | INCLUDE fastsegs.inc ; this cannot include in Fastopen.inc | ||
| 31 | INCLUDE fastopen.inc ; this include file also contains DOS equates ;AN000; | ||
| 32 | include version.inc | ||
| 33 | |||
| 34 | ;============================================================================== | ||
| 35 | |||
| 36 | |||
| 37 | |||
| 38 | EXTRN FK_OPEN:FAR ;AN000; | ||
| 39 | EXTRN FK_CLOSE:FAR ;AN000; | ||
| 40 | EXTRN FK_INSERT:FAR ;AN000; | ||
| 41 | EXTRN FK_DELETE:FAR ;AN000; | ||
| 42 | EXTRN FK_LOOKUP:FAR ;AN000; | ||
| 43 | EXTRN FK_TRUNCATE:FAR ;AN000; | ||
| 44 | EXTRN FK_PURGE:FAR ;AN000; | ||
| 45 | |||
| 46 | |||
| 47 | ;============================================================================ | ||
| 48 | |||
| 49 | CSEG_MAIN SEGMENT PARA PUBLIC 'code' | ||
| 50 | ASSUME cs:cseg_main, ds:nothing,es:nothing,ss:nothing | ||
| 51 | ;============================================================================ | ||
| 52 | |||
| 53 | PUBLIC MAIN ;AN000; | ||
| 54 | |||
| 55 | IF BUFFERFLAG | ||
| 56 | PUBLIC SAVE_EMS_PAGE_STATE | ||
| 57 | PUBLIC EMS_PAGE_NUMBER | ||
| 58 | ENDIF | ||
| 59 | |||
| 60 | PUBLIC RESTORE_PAGE_STATE | ||
| 61 | PUBLIC EMS_SAVE_HANDLE1 | ||
| 62 | |||
| 63 | PUBLIC Main_name_cache_seg ;AN000; | ||
| 64 | PUBLIC Main_Num_Of_drives ;AN000; | ||
| 65 | PUBLIC Main_Ext_Count ;AN000; | ||
| 66 | PUBLIC Main_extent_drive_Buff ;AN000; | ||
| 67 | PUBLIC Main_ext_cache_size ;AN000; | ||
| 68 | PUBLIC Main_name_cache_Buff ;AN000; | ||
| 69 | PUBLIC Main_EMS_FLAG ;AN000; | ||
| 70 | PUBLIC Main_Res_Segs ;AN000; | ||
| 71 | PUBLIC Main_EMS_PAGE_SIZE ;AN000; | ||
| 72 | PUBLIC Main_EMS_PAGE_SEG ;AN000; | ||
| 73 | PUBLIC Main_Total_Ext_Count ;AN000; | ||
| 74 | PUBLIC Main_Total_Name_Count ;AN000; | ||
| 75 | PUBLIC Main_Name_Drive_Buff ;AN000; | ||
| 76 | PUBLIC Main_ParamBuff ;AN000; | ||
| 77 | |||
| 78 | PUBLIC FOPEN_Insert ;AN000; | ||
| 79 | PUBLIC FOPEN_Update ;AN000; | ||
| 80 | PUBLIC FOPEN_Delete ;AN000; | ||
| 81 | PUBLIC FOPEN_Lookup ;AN000; | ||
| 82 | PUBLIC FOPEN_PURGE ;AN000; | ||
| 83 | |||
| 84 | PUBLIC FSEEK_Open ;AN000; | ||
| 85 | PUBLIC FSEEK_Close ;AN000; | ||
| 86 | PUBLIC FSEEK_Insert ;AN000; | ||
| 87 | PUBLIC FSEEK_Delete ;AN000; | ||
| 88 | PUBLIC FSEEK_Lookup ;AN000; | ||
| 89 | PUBLIC FSEEK_Truncate ;AN000; | ||
| 90 | PUBLIC FSEEK_Purge ;AN000; | ||
| 91 | |||
| 92 | PUBLIC VECTOR_LookUp ;AN000; | ||
| 93 | PUBLIC VECTOR_Delete ;AN000; | ||
| 94 | |||
| 95 | |||
| 96 | ; Following data variables are accessed by all other segments | ||
| 97 | call_cnt DW 0 ;AN000; | ||
| 98 | Purge_Flag DW 0 ; =1 if last call is PURGE function | ||
| 99 | Prev_drv_id DB -1 ; previous request drive id | ||
| 100 | Main_name_cache_seg DW Cseg_Init ; default to Init1 seg ;AN000; | ||
| 101 | Main_Num_Of_drives DW 0 ; number of drives ;AN000; | ||
| 102 | Main_Ext_Count DW 0 ; total name extent entries ;AN000; | ||
| 103 | Main_extent_drive_Buff DW 0 ; addrs to extent drive ;AN000; | ||
| 104 | Main_name_cache_Buff DW 0 ; address of Name cache buffer ;AN000; | ||
| 105 | Main_ext_cache_size DW 0 ; extent cache size | ||
| 106 | Main_EMS_FLAG DW 0 ; EMI flag 1= if EMI is enabled ;AN000; | ||
| 107 | Main_Res_Segs DW 0 ; number of segs to be stay resident ;AN000; | ||
| 108 | Main_Total_Ext_Count DW 0 ; Total extent count entries ;AN000; | ||
| 109 | Main_Total_Name_Count DW 0 ; Total name count entries ;AN000; | ||
| 110 | Main_Name_Drive_Buff DW 0 ; EMS data page segment ID ;AN000; | ||
| 111 | Main_ParamBuff DW 50 dup (0) ; Drive ID/extent count buffer ;AN000; | ||
| 112 | |||
| 113 | ; The following structure is for saving and restoring EMS page state | ||
| 114 | EMS_PAGE_MAP LABEL WORD | ||
| 115 | Main_EMS_SEG_COUNT DW 1 ; EMS segment count | ||
| 116 | Main_EMS_PAGE_SEG DW 0 ; EMS page segment ID ;AN000; | ||
| 117 | |||
| 118 | |||
| 119 | Main_EMS_PAGE_SIZE DW 0 ; EMS page size ;AN000; | ||
| 120 | EMS_PAGE_ARRAY DW 30 dup (0) ; EMS state save array | ||
| 121 | |||
| 122 | ; The following data values are used by MAIN segment | ||
| 123 | EMS_SAVE_LOG_PAGE1 DW ? ;HOLDS PREVIOUS PAGE1 ;AN000; | ||
| 124 | EMS_SAVE_HANDLE1 DW ? ;HOLDS PREVIOUS handle1 ;AN000; | ||
| 125 | |||
| 126 | IF BUFFERFLAG | ||
| 127 | ;----------------------------------------------------------HKN 8/26/88 | ||
| 128 | |||
| 129 | EMS_PAGE_NUMBER DW ? ; holds the ems | ||
| 130 | ; physical page no. | ||
| 131 | |||
| 132 | ENDIF | ||
| 133 | ; | ||
| 134 | ;----------------------------------------------------------------------------- | ||
| 135 | ; Fastopen/Fastseek function jump vectors | ||
| 136 | ; Inititally the jump vectors have default offset and segment values. | ||
| 137 | ; If the modules are relocated, the offset and the segID in the jump vectors | ||
| 138 | ; may be changed to the new segID of the new location. | ||
| 139 | ;----------------------------------------------------------------------------- | ||
| 140 | FOPEN_Insert DD Insert ;AN000; | ||
| 141 | FOPEN_Update DD Update ;AN000; | ||
| 142 | FOPEN_Delete DD delete ;AN000; | ||
| 143 | FOPEN_Lookup DD lookup ;AN000; | ||
| 144 | FOPEN_Purge DD FP_purge ;AN000; | ||
| 145 | |||
| 146 | FSEEK_Open DD Fk_Open ;AN000; | ||
| 147 | FSEEK_Close DD Fk_Close ;AN000; | ||
| 148 | FSEEK_Insert DD Fk_Insert ;AN000; | ||
| 149 | FSEEK_Delete DD Fk_Delete ;AN000; | ||
| 150 | FSEEK_Lookup DD Fk_Lookup ;AN000; | ||
| 151 | FSEEK_Truncate DD Fk_Truncate ;AN000; | ||
| 152 | FSEEK_Purge DD Fk_Purge ;AN000; | ||
| 153 | |||
| 154 | VECTOR_LookUp DD LookUp ; jump vector to LookUp used by Insert call | ||
| 155 | VECTOR_Delete DD Fk_Delete ; jump vector to Delete used by Free_buffer routine | ||
| 156 | |||
| 157 | |||
| 158 | |||
| 159 | |||
| 160 | |||
| 161 | ;============================================================================== | ||
| 162 | |||
| 163 | MAIN PROC FAR ; FAR procedure for FAR call from DOS | ||
| 164 | push cx ; save DOS registers ;AN000; | ||
| 165 | push dx ; makesure to restore the necessary ;AN000; | ||
| 166 | push ds ; ones on return ;AN000; | ||
| 167 | push es ;AN000; | ||
| 168 | push bp ;AN000; | ||
| 169 | push di ;AN000; | ||
| 170 | push bx ;AN000; | ||
| 171 | |||
| 172 | ;----------------------------------------------------------------------------- | ||
| 173 | ; The cache buffers are maintained in a seperate segement whose segment ID is | ||
| 174 | ; in Name_Cache_Seg. The ES will be used as the seg register during the access | ||
| 175 | ; of data in the cache buffers, while DS will be used to access the Fastopen | ||
| 176 | ; resident and non-resident data area. | ||
| 177 | ;----------------------------------------------------------------------------- | ||
| 178 | cmp cs:Main_EMS_flag,1 ; EMS enabled ?? ;AN000; | ||
| 179 | jne dispatch_funcs ; no - dispatch functions ;AN000; | ||
| 180 | ; yes - save EMS page state | ||
| 181 | IF NOT BUFFERFLAG | ||
| 182 | |||
| 183 | ;----------------------------------------------------------------------------- | ||
| 184 | ; SAVE EMS PAGE STATE | ||
| 185 | ;----------------------------------------------------------------------------- | ||
| 186 | PUSH AX ; save registers | ||
| 187 | PUSH CX | ||
| 188 | PUSH DX ;AN000; | ||
| 189 | PUSH DS ;AN000; | ||
| 190 | PUSH ES ;AN000; | ||
| 191 | PUSH BP ;AN000; | ||
| 192 | PUSH SI ;AN000; | ||
| 193 | PUSH DI ;AN000; | ||
| 194 | PUSH BX ;AN000; | ||
| 195 | MOV AX, SEG EMS_PAGE_MAP ; get segid | ||
| 196 | MOV DS,AX | ||
| 197 | LEA SI,EMS_PAGE_MAP ; DS:SI-->page map struc | ||
| 198 | MOV AX, SEG EMS_PAGE_ARRAY ; get segid | ||
| 199 | MOV ES,AX | ||
| 200 | LEA DI,EMS_PAGE_ARRAY ; ES:DI-->Page ARRAY | ||
| 201 | MOV AH,EMS_SAVE_STATE ; | ||
| 202 | MOV AL,0 ; subfunction code | ||
| 203 | INT EMS_INT ; save page state ;AN000; | ||
| 204 | |||
| 205 | POP BX ;AN000; | ||
| 206 | POP DI ;AN000; | ||
| 207 | POP SI ;AN000; | ||
| 208 | POP BP ;AN000; | ||
| 209 | POP ES ;AN000; | ||
| 210 | POP DS ;AN000; | ||
| 211 | POP DX ;AN000; | ||
| 212 | POP CX ;AN000; | ||
| 213 | |||
| 214 | CMP AH,0 ; save ok?? | ||
| 215 | JNE SAVE_FAILED ; no, error | ||
| 216 | POP AX ; clear stack | ||
| 217 | |||
| 218 | ELSE | ||
| 219 | |||
| 220 | |||
| 221 | ;------------------------------------------------------------HKN 8/26/88-- | ||
| 222 | ; Before dispatching off the fastopen functions we must do the | ||
| 223 | ; following: | ||
| 224 | ; 1. save the map for this page | ||
| 225 | ; 2. map this page to log. page 0 with the fastopen handle in | ||
| 226 | ; ems_save_handle1. | ||
| 227 | ; 3. dispatch | ||
| 228 | ; | ||
| 229 | |||
| 230 | ; int 3 | ||
| 231 | |||
| 232 | push ax | ||
| 233 | push cx | ||
| 234 | push dx | ||
| 235 | push ds | ||
| 236 | push es | ||
| 237 | push bp | ||
| 238 | push si | ||
| 239 | push di | ||
| 240 | push bx | ||
| 241 | |||
| 242 | call far ptr save_ems_page_state | ||
| 243 | jc ems_failed | ||
| 244 | |||
| 245 | call map_page | ||
| 246 | jc ems_failed | ||
| 247 | |||
| 248 | pop bx | ||
| 249 | pop di | ||
| 250 | pop si | ||
| 251 | pop bp | ||
| 252 | pop es | ||
| 253 | pop ds | ||
| 254 | pop dx | ||
| 255 | pop cx | ||
| 256 | POP AX ; restore registers | ||
| 257 | |||
| 258 | JMP DISPATCH_FUNCS ; yes, dispatch functions | ||
| 259 | |||
| 260 | EMS_FAILED: | ||
| 261 | pop bx | ||
| 262 | pop di | ||
| 263 | pop si | ||
| 264 | pop bp | ||
| 265 | pop es | ||
| 266 | pop ds | ||
| 267 | pop dx | ||
| 268 | pop cx | ||
| 269 | |||
| 270 | ENDIF | ||
| 271 | |||
| 272 | IF NOT BUFFERFLAG | ||
| 273 | SAVE_FAILED: | ||
| 274 | ENDIF | ||
| 275 | |||
| 276 | POP AX ; restore registers | ||
| 277 | |||
| 278 | POP BX ; no, restore DOS registers ;AN000; | ||
| 279 | POP DI ;AN000; | ||
| 280 | POP BP ;AN000; | ||
| 281 | POP ES ;AN000; | ||
| 282 | POP DS ;AN000; | ||
| 283 | POP DX ;AN000; | ||
| 284 | POP CX ;AN000; | ||
| 285 | STC | ||
| 286 | JMP ERROR_RET ; error return | ||
| 287 | |||
| 288 | |||
| 289 | ;----------------------------------------------------------------------------- | ||
| 290 | ; FASTOPEN/FASTSEEK DISPATCHER | ||
| 291 | ;----------------------------------------------------------------------------- | ||
| 292 | DISPATCH_FUNCS: | ||
| 293 | cmp al,5 ; buffer purge ?? | ||
| 294 | je Check_Drive_id ; yes - check drive id | ||
| 295 | cmp al,11 ; Fastopen function call ?? ;AN000; | ||
| 296 | jge Check_drive_id ; no - dispatch Fastseek functions | ||
| 297 | jmp Dispatch_fopen ; yes - dispatch Fastopen functions ;AN000; | ||
| 298 | |||
| 299 | |||
| 300 | ;----------------------------------------------------------------------------- | ||
| 301 | ; Check to see the Drive ID in DL is the valid. If not error and return DI=1 | ||
| 302 | ; if Fastseek LookUp function. Makesure to preserve AL, DS, SI and DI | ||
| 303 | ;----------------------------------------------------------------------------- | ||
| 304 | CHECK_DRIVE_ID: | ||
| 305 | cmp cs:Prev_drv_id, dl ; current id same as previous valid | ||
| 306 | je Dispatch_Fseek ; yes - dont check drive ID | ||
| 307 | |||
| 308 | push si ;AN000; | ||
| 309 | push bx ;DS=addressability to Cseg_Main ;AN000; | ||
| 310 | push cx ;AN000; | ||
| 311 | lea si,cs:Main_ParamBuff ; DS:SI-->drive ID buffer ;AN000; | ||
| 312 | mov cx,cs:Main_Num_Of_Drives ; number of drives ;AN000; | ||
| 313 | |||
| 314 | Get_Drive_Id: ;AN000; | ||
| 315 | mov bx,cs:[si] ;AN000; | ||
| 316 | cmp bl,dl ; drive ID match ?? ;AN000; | ||
| 317 | je drive_found ; yes, drive ID found ;AN000; | ||
| 318 | add si,4 ; (2/11) no, move pointer to next ID ;AN000; | ||
| 319 | LOOP get_drive_id ; check next drive id ;AN000; | ||
| 320 | |||
| 321 | Drive_Not_Found: ; drive id not found | ||
| 322 | pop cx ; restore registers ;AN000; | ||
| 323 | pop bx ;AN000; | ||
| 324 | pop si ;AN000; | ||
| 325 | jmp Error_Exit ; return | ||
| 326 | |||
| 327 | Drive_Found: ; drive ID found | ||
| 328 | mov cs:Prev_drv_id,dl ; save drive id as prev drive id | ||
| 329 | pop cx ; restore registers ;AN000; | ||
| 330 | pop bx ; and do the specified function ;AN000; | ||
| 331 | pop si ;AN000; | ||
| 332 | |||
| 333 | ;----------------------------------------------------------------------------- | ||
| 334 | ; FASTSEEK FUNCTION DISPATCHER | ||
| 335 | ;----------------------------------------------------------------------------- | ||
| 336 | DISPATCH_FSEEK: | ||
| 337 | cmp al,010H | ||
| 338 | jle Fsk_Cont | ||
| 339 | inc cs:call_cnt ;AN000; | ||
| 340 | ; cmp cs:call_cnt,0efffH ; for debugging | ||
| 341 | ; jne fsk_cont ; for debugging | ||
| 342 | |||
| 343 | |||
| 344 | Fsk_Cont: | ||
| 345 | push cs ; set addressability | ||
| 346 | pop ds ; CS = DS = Cseg_Main segment | ||
| 347 | ASSUME ds:Cseg_Main | ||
| 348 | cmp al,FONC_Purge ; PURGE call ?? ;AN000; | ||
| 349 | je chk_05 ; yes - continue ;AN000; | ||
| 350 | |||
| 351 | mov cs:Purge_Flag, 0 ; reset purge flag | ||
| 352 | cmp al,FSK_Open ; OPEN call ;AN000; | ||
| 353 | jne chk_12 ; jump if not ;AN000; | ||
| 354 | CALL FSEEK_OPEN ;AN000; | ||
| 355 | jmp exit ;AN000; | ||
| 356 | Chk_12: | ||
| 357 | cmp al,FSK_Close ; CLOSE ?? ;AN000; | ||
| 358 | jne chk_14 ;AN000; | ||
| 359 | CALL FSEEK_CLOSE ; process close function ;AN000; | ||
| 360 | jmp exit ;AN000; | ||
| 361 | Chk_14: | ||
| 362 | cmp al,FSK_Lookup ; LOOKUP ?? ;AN000; | ||
| 363 | jne chk_15 ;AN000; | ||
| 364 | CALL FSEEK_LOOKUP ; process lookup ;AN000; | ||
| 365 | CALL RESTORE_PAGE_STATE ; restore EMS page ;AN000; | ||
| 366 | pop dx ; dont restore original BX and DI ;AN000; | ||
| 367 | pop dx ; from DOS since BX and DI contins return values ;AN000; | ||
| 368 | jmp exit_1 ; exit | ||
| 369 | |||
| 370 | Chk_15: | ||
| 371 | cmp al,FSK_Insert ; INSERT ?? ;AN000; | ||
| 372 | jne chk_13 ;AN000; | ||
| 373 | CALL FSEEK_INSERT ; Process insert ;AN000; | ||
| 374 | jmp exit ;AN000; | ||
| 375 | Chk_13: | ||
| 376 | cmp al,FSK_DELETE ; DELETE ?? ;AN000; | ||
| 377 | jne chk_16 ;AN000; | ||
| 378 | CALL FSEEK_DELETE ; process delete ;AN000; | ||
| 379 | jmp short exit ;AN000; | ||
| 380 | Chk_16: | ||
| 381 | cmp al,FSK_Trunc ; TRUNCATE ?? ;AN000; | ||
| 382 | jne Chk_05 ; | ||
| 383 | CALL FSEEK_TRUNCATE ; process truncate ;AN000; | ||
| 384 | jmp short exit ;AN000; | ||
| 385 | |||
| 386 | Chk_05: | ||
| 387 | cmp cs:Purge_Flag, 1 ; previous call is purge ?? ;AN000; | ||
| 388 | jne Purge_buffs ; no - purge the buffers | ||
| 389 | clc ; yes - exit | ||
| 390 | jmp short exit ;AN000; | ||
| 391 | |||
| 392 | Purge_Buffs: | ||
| 393 | mov cs:Purge_Flag,1 ; set purge flag | ||
| 394 | cmp CS:Main_Total_Ext_Count,0 ; reset fseek buffs?? | ||
| 395 | je reset_fopen ; no - reset fopen | ||
| 396 | CALL FSEEK_PURGE ; reset extent cache ;AN000; | ||
| 397 | |||
| 398 | Reset_Fopen: | ||
| 399 | cmp CS:Main_Total_Name_Count,0 ; reset fopen buffs?? | ||
| 400 | je Reset_Exit ; no - reset f | ||
| 401 | CALL CS:FOPEN_PURGE ; reset extent cache ;AN000; | ||
| 402 | |||
| 403 | Reset_Exit: | ||
| 404 | clc | ||
| 405 | jmp short exit ;AN000; | ||
| 406 | |||
| 407 | |||
| 408 | ; NOTE: Carry Flag state from Function calls must be correctly returned | ||
| 409 | ; to the DOS, especially from Fastseek Lookup function | ||
| 410 | |||
| 411 | |||
| 412 | ;----------------------------------------------------------------------------- | ||
| 413 | ; FASTOPEN FUNCTION DISPATCHER | ||
| 414 | ;----------------------------------------------------------------------------- | ||
| 415 | DISPATCH_FOPEN: ; dispatch FOPEN functions | ||
| 416 | cld ;AN000; | ||
| 417 | mov cs:Purge_Flag, 0 ; reset purge flag | ||
| 418 | cmp al, FONC_update ;AN000; | ||
| 419 | jne Chk_02 ;AN000; | ||
| 420 | CALL CS:Fopen_Update ; UPDATE ;AN000; | ||
| 421 | jmp short exit ;AN000; | ||
| 422 | |||
| 423 | Chk_02: | ||
| 424 | cmp al, FONC_insert ;AN000; | ||
| 425 | jne Chk_01 ;AN000; | ||
| 426 | CALL CS:Fopen_Insert ; INSERT ;AN000; | ||
| 427 | jmp short exit ;AN000; | ||
| 428 | Chk_01: | ||
| 429 | cmp al, FONC_look_up ;AN000; | ||
| 430 | jne chk_03 ;AN000; | ||
| 431 | CALL CS:Fopen_lookup ; LOOKUP ;AN000; | ||
| 432 | jmp short exit ;AN000; | ||
| 433 | Chk_03: | ||
| 434 | cmp al, FONC_delete ;AN000; | ||
| 435 | jne Error_Exit ;AN000; | ||
| 436 | CALL CS:Fopen_delete ; DELETE ;AN000; | ||
| 437 | jmp short exit ;AN000; | ||
| 438 | |||
| 439 | |||
| 440 | |||
| 441 | ;----------------------------------------------------------------------------- | ||
| 442 | ; EXIT TO DOS FROM FUNCTIONS | ||
| 443 | ;----------------------------------------------------------------------------- | ||
| 444 | |||
| 445 | ERROR_EXIT: ; EXIT from invalid drive id search loop | ||
| 446 | CALL RESTORE_PAGE_STATE ; restore frame buff status ;AN000; | ||
| 447 | ; on return AX should have function code | ||
| 448 | pop bx ; restore first two regs of DOS | ||
| 449 | pop di ;AN000; | ||
| 450 | cmp al,FSK_Lookup ;AN000; | ||
| 451 | jne exit_2 ;AN000; | ||
| 452 | mov di,1 ; set error flag - invalid drive id ;AN000; | ||
| 453 | stc ;AN000; | ||
| 454 | jmp short Exit_1 ;AN000; | ||
| 455 | |||
| 456 | EXIT_2: | ||
| 457 | clc ;AN000; | ||
| 458 | jmp short Exit_1 ;AN000; | ||
| 459 | |||
| 460 | |||
| 461 | ; Normal Exit from Fastopen Functions except Fastseek Lookup function | ||
| 462 | EXIT: | ||
| 463 | CALL RESTORE_PAGE_STATE ; restore EMS page state ;AN000;;AN000; | ||
| 464 | pop bx ; restore BX ;AN000; | ||
| 465 | pop di ; restore DI ;AN000; | ||
| 466 | |||
| 467 | |||
| 468 | ; Exit from FastSeek Lookup function. Dont restore BX and DI | ||
| 469 | EXIT_1: | ||
| 470 | pop bp ; restore remaining DOS registers | ||
| 471 | pop es ; except BX and DI since they contain ;AN000; | ||
| 472 | pop ds ; return values. ;AN000; | ||
| 473 | pop dx ;AN000; | ||
| 474 | pop cx ;AN000; | ||
| 475 | |||
| 476 | ERROR_RET: | ||
| 477 | ret ;AN000; | ||
| 478 | |||
| 479 | MAIN ENDP | ||
| 480 | |||
| 481 | IF BUFFERFLAG | ||
| 482 | ;--------------------------------------------------------------------------- | ||
| 483 | ; Procedure name : save_ems_page_state | ||
| 484 | ; | ||
| 485 | ; Description: | ||
| 486 | ; Saves the state of the page whose physical segment value is | ||
| 487 | ; specified in Main_EMS_PAGE_SEG. | ||
| 488 | ;--------------------------------------------------------------------------- | ||
| 489 | |||
| 490 | SAVE_EMS_PAGE_STATE PROC FAR | ||
| 491 | |||
| 492 | PUSH AX ; save registers | ||
| 493 | PUSH CX | ||
| 494 | PUSH DX ;AN000; | ||
| 495 | PUSH DS ;AN000; | ||
| 496 | PUSH ES ;AN000; | ||
| 497 | PUSH BP ;AN000; | ||
| 498 | PUSH SI ;AN000; | ||
| 499 | PUSH DI ;AN000; | ||
| 500 | PUSH BX ;AN000; | ||
| 501 | |||
| 502 | MOV AX, SEG EMS_PAGE_MAP ; get segid | ||
| 503 | MOV DS,AX | ||
| 504 | LEA SI,EMS_PAGE_MAP ; DS:SI-->page map struc | ||
| 505 | MOV AX, SEG EMS_PAGE_ARRAY ; get segid | ||
| 506 | MOV ES,AX | ||
| 507 | LEA DI,EMS_PAGE_ARRAY ; ES:DI-->Page ARRAY | ||
| 508 | MOV AH,EMS_SAVE_STATE ; | ||
| 509 | MOV AL,0 ; subfunction code | ||
| 510 | INT EMS_INT ; save page state ;AN000; | ||
| 511 | |||
| 512 | POP BX ;AN000; | ||
| 513 | POP DI ;AN000; | ||
| 514 | POP SI ;AN000; | ||
| 515 | POP BP ;AN000; | ||
| 516 | POP ES ;AN000; | ||
| 517 | POP DS ;AN000; | ||
| 518 | POP DX ;AN000; | ||
| 519 | POP CX ;AN000; | ||
| 520 | |||
| 521 | CMP AH,0 ; save ok?? | ||
| 522 | JE SAVE_OK ; | ||
| 523 | STC | ||
| 524 | JMP SHORT DONE | ||
| 525 | SAVE_OK: | ||
| 526 | CLC | ||
| 527 | DONE: | ||
| 528 | POP AX | ||
| 529 | RET | ||
| 530 | |||
| 531 | SAVE_EMS_PAGE_STATE ENDP | ||
| 532 | |||
| 533 | ENDIF | ||
| 534 | |||
| 535 | |||
| 536 | ;----------------------------------------------------------------------------- | ||
| 537 | ; PROCERDURE: RESTORE_PAGE_STATE | ||
| 538 | ; | ||
| 539 | ; Function: Restore state of EMS page | ||
| 540 | ; | ||
| 541 | ; Input: None | ||
| 542 | ; Output: Page is restored | ||
| 543 | ; | ||
| 544 | ;----------------------------------------------------------------------------- | ||
| 545 | |||
| 546 | RESTORE_PAGE_STATE PROC NEAR ;RESTORE EMS PAGE STATE | ||
| 547 | PUSHF ;save flag ;AN000; | ||
| 548 | CMP CS:MAIN_EMS_FLAG, 0 ;EMS enabled ?? ;AN000; | ||
| 549 | JNE REST_PUSH_REGS ;yes, restore registers | ||
| 550 | JMP SHORT RESTORE_EXIT ;no, exit ;AN000; | ||
| 551 | ;yes, restore page registers | ||
| 552 | REST_PUSH_REGS: | ||
| 553 | PUSH AX ; save function code | ||
| 554 | PUSH CX ; save caller registers ;AN000; | ||
| 555 | PUSH DX ;AN000; | ||
| 556 | PUSH DS ;AN000; | ||
| 557 | PUSH ES ;AN000; | ||
| 558 | PUSH BP ;AN000; | ||
| 559 | PUSH SI ;AN000; | ||
| 560 | PUSH DI ;AN000; | ||
| 561 | PUSH BX ;AN000; | ||
| 562 | |||
| 563 | MOV AX, SEG EMS_PAGE_ARRAY | ||
| 564 | MOV DS,AX | ||
| 565 | LEA SI,EMS_PAGE_ARRAY ; DS:SI-->Page array | ||
| 566 | MOV AH,EMS_RESTORE_STATE ; | ||
| 567 | MOV AL,1 ; | ||
| 568 | INT EMS_INT ; restre page state ;AN000; | ||
| 569 | CMP AH,0 ; restore OK ?? | ||
| 570 | JE REST_POP_REGS ; yes | ||
| 571 | STC ; set carry | ||
| 572 | |||
| 573 | REST_POP_REGS: | ||
| 574 | POP BX ; RESTORE REGISTERS ;AN000; | ||
| 575 | POP DI ;AN000; | ||
| 576 | POP SI ;AN000; | ||
| 577 | POP BP ;AN000; | ||
| 578 | POP ES ;AN000; | ||
| 579 | POP DS ;AN000; | ||
| 580 | POP DX ;AN000; | ||
| 581 | POP CX ;AN000; | ||
| 582 | POP AX ; restore function code | ||
| 583 | |||
| 584 | RESTORE_EXIT: | ||
| 585 | POPF | ||
| 586 | RET ;AN000; | ||
| 587 | |||
| 588 | RESTORE_PAGE_STATE ENDP | ||
| 589 | |||
| 590 | |||
| 591 | IF BUFFERFLAG | ||
| 592 | |||
| 593 | ;---------------------------------------------------------HKN 8/26/88------- | ||
| 594 | ; procedure name : map_page | ||
| 595 | ; Inputs : ems_page_number = physical page frame | ||
| 596 | ; number. | ||
| 597 | ; ems_save_handle1 = emm_handle. | ||
| 598 | ; Output : CY - error | ||
| 599 | ; NC - page is mapped to logical page 0 | ||
| 600 | ;---------------------------------------------------------------------------- | ||
| 601 | map_page proc near | ||
| 602 | |||
| 603 | push ax | ||
| 604 | push bx | ||
| 605 | push dx | ||
| 606 | |||
| 607 | xor bx, bx | ||
| 608 | mov ax, cs:ems_page_number ; contains the page number obtained | ||
| 609 | ; during fastopen intialization. | ||
| 610 | mov ah, 44h | ||
| 611 | mov dx, cs:ems_save_handle1 ; contains the emm handle that was | ||
| 612 | ; obtained during fast init. | ||
| 613 | int ems_int | ||
| 614 | or ah, ah | ||
| 615 | jnz err_map_page | ||
| 616 | clc | ||
| 617 | jmp short map_page_done | ||
| 618 | |||
| 619 | err_map_page: | ||
| 620 | stc | ||
| 621 | |||
| 622 | map_page_done: | ||
| 623 | pop dx | ||
| 624 | pop bx | ||
| 625 | pop ax | ||
| 626 | ret | ||
| 627 | |||
| 628 | map_page endp | ||
| 629 | |||
| 630 | ENDIF | ||
| 631 | |||
| 632 | |||
| 633 | ; NOTE: | ||
| 634 | CSEG_MAIN ENDS ; End of the first portion of the | ||
| 635 | ; Cseg_Main segment. Remaining | ||
| 636 | ; portion is in Fastinit.asm | ||
| 637 | |||
| 638 | ;----------------------------------------------------------------------------- | ||
| 639 | |||
| 640 | |||
| 641 | |||
| 642 | |||
| 643 | |||
| 644 | ;============================================================================== | ||
| 645 | ; All Fastopen functions are kept in a seperate segment. These are accessed | ||
| 646 | ; by a FAR indirect call from the MAIN routine. | ||
| 647 | ; ADDRESSABILTY: CS is used for accessing local data in Cseg_Open segment | ||
| 648 | ; DS is used for accessing data in the drive cache buffer | ||
| 649 | ; in the Cseg_Init segment | ||
| 650 | ; ES is used for accessing data in the name cache buffer | ||
| 651 | ; in the Cseg_Init segment | ||
| 652 | ; | ||
| 653 | ;***************************************************************************** | ||
| 654 | CSEG_OPEN SEGMENT PARA PUBLIC 'code' | ||
| 655 | ASSUME cs:cseg_open,ds:nothing,es:nothing,ss:nothing | ||
| 656 | ;***************************************************************************** | ||
| 657 | |||
| 658 | PUBLIC Open_name_cache_seg ;AN000; | ||
| 659 | PUBLIC Open_name_Drive_Buff ;AN000; | ||
| 660 | PUBLIC End_Open ;AN000; | ||
| 661 | PUBLIC Chk_Flag ;AN000; | ||
| 662 | |||
| 663 | ;---- FastOpen Functions Local Variables -------------- | ||
| 664 | |||
| 665 | Current_Node DW ? ;address of current node entry buffer ;AN000; | ||
| 666 | Current_Sibling DW ? ;address of current sibling node entry buffer ;AN000; | ||
| 667 | Current_Drive DW ? ;address of current drive header ;AN000; | ||
| 668 | Matching_Node DW -1 ;flag ;AN000; | ||
| 669 | From_Delete DW 0 ;= 1 if call is from DELETE function ;AN000; | ||
| 670 | Old_SI DW 0 ;SI save area ;AN000; | ||
| 671 | Flag DB 0 ;AN000; | ||
| 672 | Level DB 0 ;depth level of the path ;AN000; | ||
| 673 | Dir_Info_Buffer DD ? ;Dir_Info buffer inside DOS ;AN000; | ||
| 674 | Extended_Info_Buffer DD ? ;Extended Info buffer inside DOS ;AN000; | ||
| 675 | New_FEI_clusnum DW 0 ;AN000; | ||
| 676 | Packed_Name DB 11 dup (0) ;Space for packed dir name ;AN000; | ||
| 677 | Top DW 0 ;AN000; | ||
| 678 | Temp DW 0 ;AN000; | ||
| 679 | Bottom DW 0 ;AN000; | ||
| 680 | Depth DB 0 ;AN000; | ||
| 681 | |||
| 682 | Chk_Flag dw 0 ; flag used by the analyser | ||
| 683 | func_cod db 0 ; function code for analyser | ||
| 684 | |||
| 685 | ;Following data area is filled during initialization | ||
| 686 | Open_name_cache_seg DW Cseg_Init ; address of name cache buffer | ||
| 687 | Open_name_Drive_Buff DW 0 ; address of first drive buffer | ||
| 688 | |||
| 689 | |||
| 690 | |||
| 691 | |||
| 692 | ; | ||
| 693 | ;============================================================================== | ||
| 694 | ; Pathname Tree Search | ||
| 695 | ; | ||
| 696 | ; Element of each path name is represented by a node in the tree. First | ||
| 697 | ; node is connected to the the Drive header through first child pointer | ||
| 698 | ; (DCH_Child_Ptr). The first node may have one or more nodes underneath. | ||
| 699 | ; The first one is called the Child of this node and the others are the siblings | ||
| 700 | ; of the child node. Previous node is connected to the first node through | ||
| 701 | ; the child pointer (nChild_Ptr) and the siblings are connected through the | ||
| 702 | ; sibling pointer (nSibling_Ptr). Each node is connected to the previous | ||
| 703 | ; node through a backward pointer (nBackward_Ptr). For example, to go to the | ||
| 704 | ; previous node from any of the siblings. It is necessary to go to the | ||
| 705 | ; child through previous siblings (if any) and then to the previous from the | ||
| 706 | ; child. All this backward movement is using nBackward_Ptr. | ||
| 707 | ; Similarly to go to a child or sibling, nChild_ptr or nSibling_Ptr should be | ||
| 708 | ; used. The strucure of drive header and the node are defined in Fastopen.inc | ||
| 709 | ; | ||
| 710 | |||
| 711 | ;============================================================================== | ||
| 712 | ;Subroutine: LOOKUP | ||
| 713 | ; | ||
| 714 | ;INPUT: | ||
| 715 | ; DS:SI -> path (drive letter D: will be validated by Find_Drive_Cache_hdr) | ||
| 716 | ; ES:DI -> DIR_INFO buffer to be returned inside DOS | ||
| 717 | ; ES:CX -> FASTOPEN_Extended_Info buffer inside DOS | ||
| 718 | ; ES:BP -> Drive_Cache_Heade | ||
| 719 | ; | ||
| 720 | ; | ||
| 721 | ;OUTPUT: | ||
| 722 | ; If the whole path is found, | ||
| 723 | ; DS:SI--> 0 | ||
| 724 | ; ES:DI--> DIR_INFO buffer is filled with directory info | ||
| 725 | ; ES:CX--> EXT_INFO buffer is filled with extended info | ||
| 726 | ; | ||
| 727 | ; If partially found the path, | ||
| 728 | ; DS:SI--> '\' after the matching directory name | ||
| 729 | ; ES:DI--> DIR_INFO buffer is filled with directory info | ||
| 730 | ; ES:CX--> EXT_INFO buffer is filled with extended info | ||
| 731 | ; | ||
| 732 | ; If the Name_cache tree is empty, i.e.,no root directory name, | ||
| 733 | ; DS:SI--> '\' after ':' | ||
| 734 | ; ES:DI--> DIR_INFO buffer is undetermined | ||
| 735 | ; ES:CX--> EXT_INFO buffer is undetermined | ||
| 736 | ; | ||
| 737 | ;============================================================================== | ||
| 738 | |||
| 739 | LOOKUP PROC FAR | ||
| 740 | |||
| 741 | mov cs:func_cod,al ; save function code | ||
| 742 | cmp From_Delete, 0 ;call from DELETE function ?? | ||
| 743 | je Look_Pack_Dir ;no, dont restore DS | ||
| 744 | mov DS,bx ;yes, restore DS | ||
| 745 | ASSUME DS:Cseg_Init | ||
| 746 | jmp short Look_save_regs ;save registers | ||
| 747 | |||
| 748 | Look_Pack_Dir: | ||
| 749 | CALL PACK_DIR_NAME ;on return drive letter => DL, | ||
| 750 | |||
| 751 | CALL FIND_DRIVE_CACHE_HEADER ;find drive header address | ||
| 752 | ;on return ES:BP-->drive header | ||
| 753 | jnc look_save_regs ;drive buffer found | ||
| 754 | jmp lookup_error ;drive buffer not found | ||
| 755 | |||
| 756 | Look_Save_Regs: | ||
| 757 | push es | ||
| 758 | push di | ||
| 759 | push cx | ||
| 760 | mov ax, cs:Open_Name_Cache_Seg ;AN000; | ||
| 761 | mov es, ax ;ES = Name_Cache_Seg ;AN000; | ||
| 762 | ASSUME es:Cseg_Init ;AN000; | ||
| 763 | CALL SET_LRU ;set the Real LRU, if any. | ||
| 764 | |||
| 765 | or cs:Flag,Is_drive_head ;level of the tree. Drive header | ||
| 766 | mov cs:Matching_Node, -1 ;Nothing found yet. | ||
| 767 | mov cs:Current_Drive, BP ;drive header | ||
| 768 | mov cs:Level, 0 ;path level is 0 | ||
| 769 | |||
| 770 | Lookup_Path: | ||
| 771 | mov cs:Current_Node, BP ;save current node address | ||
| 772 | mov cs:Current_Sibling,0fffeh ;set no sibligs yet. | ||
| 773 | mov cs:Old_SI, si ;save current path address | ||
| 774 | |||
| 775 | CALL PACK_DIR_NAME ;get the next dir name from the path | ||
| 776 | jc Lookup_Done ;yes, found the whole path. | ||
| 777 | |||
| 778 | test cs:Flag, Is_drive_head ;dir name = drive header ? | ||
| 779 | jz Lp_Path1 ;no- | ||
| 780 | |||
| 781 | push ds ;yes-drive header | ||
| 782 | mov ds,cs:Open_Name_Cache_Seg | ||
| 783 | ASSUME ds:Cseg_Init | ||
| 784 | mov BP, DS:[BP.DCH_Child_ptr] ;BP-->first child node under drive hdr | ||
| 785 | pop ds | ||
| 786 | ASSUME ds:nothing | ||
| 787 | jmp short Lp_Path2 | ||
| 788 | |||
| 789 | Lp_Path1: | ||
| 790 | mov BP, ES:[BP.nChild_ptr] ;BP--> child of current node | ||
| 791 | |||
| 792 | Lp_Path2: | ||
| 793 | cmp BP, -1 ;no child? | ||
| 794 | je Lookup_Done ;Not found or partially found | ||
| 795 | mov cs:Current_Node, BP ;current_node = found node | ||
| 796 | and cs:Flag, Not_drive_head ;reset the flag. | ||
| 797 | |||
| 798 | Lp_Cmpare: | ||
| 799 | CALL CMPARE ;look for path in current node | ||
| 800 | je Lookup_Found ;Yes, found a match. Next level for | ||
| 801 | ;possible remianing path | ||
| 802 | |||
| 803 | mov BP, ES:[BP.nSibling_ptr] ;not found. Any siblings? | ||
| 804 | mov cs:Current_Sibling,BP | ||
| 805 | cmp BP, -1 ;any more sibling? | ||
| 806 | je Lookup_Done ;no - done | ||
| 807 | |||
| 808 | mov cs:Current_Node, BP ;yes- make the found sibling as a current | ||
| 809 | jmp short Lp_Cmpare ;node and search path in this node | ||
| 810 | |||
| 811 | Lookup_Found: | ||
| 812 | inc cs:Level | ||
| 813 | mov cs:Matching_Node,BP ;Used by Unfold_Name_Record | ||
| 814 | |||
| 815 | CALL PRE_LRU_STACK ;set the TEMP_LRU_Stack | ||
| 816 | jmp Lookup_Path ;continue to the next dir | ||
| 817 | |||
| 818 | Lookup_Done: | ||
| 819 | mov si, cs:Old_SI | ||
| 820 | pop cx ;restore Extended_Info buffer | ||
| 821 | pop di ;restore Dir_Info buffer | ||
| 822 | pop es ;the segment for the above buffers | ||
| 823 | |||
| 824 | cmp ax, -1 | ||
| 825 | je Lookup_ERR ;error occured in Pack_Dir_Name. | ||
| 826 | clc ;clear carry. | ||
| 827 | jmp short Lookup_Done1 | ||
| 828 | |||
| 829 | Lookup_ERR: ;error exit | ||
| 830 | stc | ||
| 831 | |||
| 832 | Lookup_Done1: | ||
| 833 | test cs:Flag, is_delete ;called by delete? | ||
| 834 | jnz Lookup_Return | ||
| 835 | jc Lookup_Exit ;If it was an error, don't change the carry flag | ||
| 836 | |||
| 837 | CALL UNFOLD_NAME_RECORD ;unfold the current node's record | ||
| 838 | Lookup_Exit: | ||
| 839 | jmp short Lookup_Return ;return to DOS. | ||
| 840 | |||
| 841 | Lookup_Error: ;error exit | ||
| 842 | stc | ||
| 843 | mov ax,-1 | ||
| 844 | |||
| 845 | Lookup_Return: ;return to Delete routine. | ||
| 846 | CALL Check_It ;check tree structure | ||
| 847 | ret | ||
| 848 | |||
| 849 | LOOKUP ENDP | ||
| 850 | |||
| 851 | |||
| 852 | |||
| 853 | |||
| 854 | |||
| 855 | ;============================================================================== | ||
| 856 | ;SUBROUTINE: INSERT | ||
| 857 | ; | ||
| 858 | ;INPUT: DS:DI -> Dir_Info in DOS | ||
| 859 | ; ES:BX -> Fastopen_Extended_Info in DOS | ||
| 860 | ; Current_Node, Current_Sibling, Current_Drive, Flag | ||
| 861 | ; | ||
| 862 | ;OUTPUT: Information inserted into Name_cache_tree. | ||
| 863 | ; | ||
| 864 | ; Any Sequential Insert operation should be preceded by a Look_up | ||
| 865 | ; operation. For ex., if the DOS wants to insert C:\DIR1\DIR2\File1 | ||
| 866 | ; and suppose there is no matching name cache record for DIR1 in the tree. | ||
| 867 | ; Firstly DOS will try to look up C:\DIR1\DIR2\File1. FASTOPEN will | ||
| 868 | ; return to DOS with DS:SI points to "\" after the drive letter. | ||
| 869 | ; Then, DOS will simply ask an insert operation with DS:DI, ES:BX | ||
| 870 | ; points to the information on "DIR1". FASTOPEN will insert DIR1 | ||
| 871 | ; onto the tree. After that DOS will ask another insert | ||
| 872 | ; operation for DIR2. FASTOPEN will insert DIR2. Finally DOS will | ||
| 873 | ; ask to insert File1. | ||
| 874 | ; | ||
| 875 | ; Suppose when DOS try to look up C:\DIR1\DIR2\File2 at this moment. | ||
| 876 | ; FASTOPEN will return to DOS with DS:SI points to "\" after DIR2 (since | ||
| 877 | ; DIR2 information is already in the name cache tree). Then DOS will ask | ||
| 878 | ; to insert File2. | ||
| 879 | ; | ||
| 880 | ; Any Insert operation of subdirectory name which is deeper than (Number_ | ||
| 881 | ; of_Entries - 1) will not be inserted but will just return. | ||
| 882 | ; Also, for the safety reason, if the would be freed node (=LRU node) is | ||
| 883 | ; the same as the Current_Node, there will be no insertion. (This is a simple | ||
| 884 | ; safety valve. A more smart logic can look for the next **legitimately | ||
| 885 | ; available** LRU node to use, or sometimes, simply replace the contents of the | ||
| 886 | ; entry if adequate. But this will increase the complexity greatly, and I | ||
| 887 | ; think the current logic is still practical enough to use despite of the | ||
| 888 | ; possible small window of performance degradation in a very special cases. J.K.) | ||
| 889 | ; | ||
| 890 | ;============================================================================== | ||
| 891 | |||
| 892 | INSERT PROC FAR | ||
| 893 | mov cs:func_cod,al ; save function code | ||
| 894 | inc cs:Level ;increment directory level | ||
| 895 | xor ax,ax | ||
| 896 | mov al, cs:Level | ||
| 897 | inc al | ||
| 898 | mov bp, cs:Current_Drive ;BP-->address of current drive header | ||
| 899 | push ds | ||
| 900 | mov ds,cs:Open_Name_Cache_Seg ;DS=name cache segment | ||
| 901 | |||
| 902 | ASSUME ds:Cseg_Init ;AN000; | ||
| 903 | cmp ax, ds:[bp.DCH_Num_Entries] ;Level > (Num_Entries - 1) ? | ||
| 904 | pop ds | ||
| 905 | ASSUME ds:nothing | ||
| 906 | jbe Insert_it ;no- insert it | ||
| 907 | jmp short Insert_return ;yes return | ||
| 908 | |||
| 909 | Insert_it: | ||
| 910 | or cs:Flag, is_insert | ||
| 911 | |||
| 912 | CALL GET_FREE_NODE ;AX = offset value of the available | ||
| 913 | ;name_record in Name_Cache_Seg. | ||
| 914 | jc I_Exit ;Current node = would-be freed node. | ||
| 915 | |||
| 916 | CALL MAKE_NAME_RECORD ;Fill the above name record entry. | ||
| 917 | ;ES was changed to Name_Cache_Seg. | ||
| 918 | |||
| 919 | mov bp, cs:Current_Node ;set BP to current_node | ||
| 920 | mov bx, bp ;save it into bx | ||
| 921 | cmp cs:Current_Sibling,0fffeh ;current node sibling node ?? | ||
| 922 | je I_Child ;no-child of preceding node | ||
| 923 | mov es:[bp.nSibling_ptr], ax ;yes-make new node sibling of | ||
| 924 | jmp short I_Done ;current node | ||
| 925 | |||
| 926 | I_Child: ;set nChild_ptr | ||
| 927 | test cs:Flag,Is_drive_head ;drive level? | ||
| 928 | jnz I_Child_first ;Yes, must be the first child | ||
| 929 | mov es:[bp.nChild_ptr], ax ;no-make ndew node child of | ||
| 930 | jmp short I_Done ;current node | ||
| 931 | |||
| 932 | I_Child_first: ;this is the first child in this drive. | ||
| 933 | push ds | ||
| 934 | mov ds,cs:Open_Name_Cache_Seg ;AN000; | ||
| 935 | ASSUME ds:Cseg_Init ;AN000; | ||
| 936 | mov ds:[bp.DCH_Child_ptr],ax ;make new node 1st child current drive | ||
| 937 | pop ds | ||
| 938 | ASSUME ds:nothing | ||
| 939 | mov bx, cs:Current_Drive ;change bx to Current_Drive | ||
| 940 | and cs:Flag, Not_drive_head ;reset the flag | ||
| 941 | |||
| 942 | I_Done: | ||
| 943 | mov bp, ax | ||
| 944 | mov es:[bp.nBackward_ptr],bx ;set the backward ptr of the inserted node. | ||
| 945 | |||
| 946 | CALL PRE_LRU_STACK ;save this inserted record temporarily. | ||
| 947 | |||
| 948 | mov cs:Current_Node,bp ;make new node current node | ||
| 949 | ;any subsequent insert operation | ||
| 950 | mov cs:Current_Sibling,0fffeh ;should be installed as a child | ||
| 951 | |||
| 952 | I_Exit: | ||
| 953 | and cs:Flag, not_insert ;set not insert flag | ||
| 954 | |||
| 955 | Insert_return: | ||
| 956 | CALL Check_It ;check tree structure | ||
| 957 | ret ;return | ||
| 958 | |||
| 959 | INSERT ENDP | ||
| 960 | |||
| 961 | |||
| 962 | |||
| 963 | |||
| 964 | |||
| 965 | |||
| 966 | ;============================================================================== | ||
| 967 | ;Subroutine: DELETE | ||
| 968 | ; | ||
| 969 | ;INPUT: DS:SI -> path | ||
| 970 | ; ES:BP -> drive_cache_header (for Look_Up operation) | ||
| 971 | ; | ||
| 972 | ;OUTPUT: if found, then remove the matching Name_Record will be removed from | ||
| 973 | ; the tree and from the LRU chain. The freed entry will be placed | ||
| 974 | ; on top of the LRU chain. | ||
| 975 | ; | ||
| 976 | ;============================================================================== | ||
| 977 | |||
| 978 | DELETE PROC FAR | ||
| 979 | |||
| 980 | mov cs:func_cod,al ; save function code | ||
| 981 | CALL PACK_DIR_NAME ;drive letter => DL, ;AN000; | ||
| 982 | |||
| 983 | CALL FIND_DRIVE_CACHE_HEADER ;find drive header address | ||
| 984 | ;on return ES:BP-->drive header | ||
| 985 | jc d_err_exit ;error exit | ||
| 986 | |||
| 987 | or cs:Flag, is_delete ;set the flag for Look_up. | ||
| 988 | push ds ;save DS in BX since it is going to be | ||
| 989 | pop bx ;changed for jumping to other segment | ||
| 990 | push ds | ||
| 991 | mov ax,cseg_Main | ||
| 992 | mov ds,ax ;DS=Main segment ID | ||
| 993 | assume ds:Cseg_Main | ||
| 994 | mov cs:From_Delete, 1 ;set flag indicate that the call | ||
| 995 | ;is from DELETE function | ||
| 996 | CALL VECTOR_LOOKUP ;FAR call to Lookup function | ||
| 997 | |||
| 998 | mov cs:From_Delete, 0 ;reset from delete flag | ||
| 999 | pop ds | ||
| 1000 | ASSUME ds:nothing | ||
| 1001 | jc D_err_Exit ;indirectly in the same segment | ||
| 1002 | |||
| 1003 | cmp byte ptr ds:[si], 0 ;found the whole path? | ||
| 1004 | jne D_err_Exit ;No. | ||
| 1005 | |||
| 1006 | ;At this point, Current_Node = BP. | ||
| 1007 | mov bx, cs:Open_Name_Cache_Seg | ||
| 1008 | mov es, bx ;set ES to name_cache_seg. | ||
| 1009 | ASSUME es:Cseg_Init | ||
| 1010 | |||
| 1011 | Delete_Node: | ||
| 1012 | cmp es:[bp.nChild_ptr], -1 ;No children? | ||
| 1013 | jne D_err_Exit | ||
| 1014 | CALL REMOVEFROMTREE ;remove the node while maintaing the | ||
| 1015 | ;integrity of the tree. | ||
| 1016 | |||
| 1017 | mov es:[bp.nCmpct_Dir_Info], ' ' ;mark that this entry is free!!! | ||
| 1018 | |||
| 1019 | D_LRU_MRU: | ||
| 1020 | CALL REMOVEFROMLRUCHAIN ;Remove BP from the LRU,MRU chain | ||
| 1021 | |||
| 1022 | mov si, cs:Current_Drive ;Now let the deleted node to be the | ||
| 1023 | push ds ; LRU node | ||
| 1024 | mov ds,cs:Open_Name_Cache_Seg | ||
| 1025 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1026 | |||
| 1027 | mov bx, ds:[si.DCH_LRU_ROOT] ;es:bx -> first node | ||
| 1028 | mov es:[bp.nLRU_ptr],bx ;Target.nLRU_ptr -> first node | ||
| 1029 | mov es:[bx.nMRU_ptr],bp ;First_node.nMRU_ptr -> target | ||
| 1030 | mov ds:[si.DCH_LRU_ROOT],bp ;LRU_ROOT -> target | ||
| 1031 | mov es:[bp.nMRU_ptr],-1 | ||
| 1032 | pop ds | ||
| 1033 | ASSUME ds:nothing | ||
| 1034 | jmp short D_Exit ;exit | ||
| 1035 | |||
| 1036 | D_err_Exit: ;error exit | ||
| 1037 | stc | ||
| 1038 | mov ax, -1 | ||
| 1039 | |||
| 1040 | D_Exit: | ||
| 1041 | and cs:Flag, not_delete ;reset the flag | ||
| 1042 | CALL Check_It ;check tree structure | ||
| 1043 | ret ;return | ||
| 1044 | |||
| 1045 | DELETE ENDP | ||
| 1046 | |||
| 1047 | |||
| 1048 | |||
| 1049 | |||
| 1050 | |||
| 1051 | ;============================================================================== | ||
| 1052 | ;Subroutine: UPDATE | ||
| 1053 | ; | ||
| 1054 | ;INPUT: If AH = 0, then update Dir_Entry area. | ||
| 1055 | ; ES:DI -> Dir_entry ("dir_first" is the key to search). | ||
| 1056 | ; DL = Logical Drive number (0 = A, 1 = B, ...). | ||
| 1057 | ; | ||
| 1058 | ; If AH = 1, then update "Fastopen_extended_info.FEI_clusnum". | ||
| 1059 | ; DL = Logical Drive number (0 = A, 1 = B, ...) | ||
| 1060 | ; CX = The value of "dir_first" to search. | ||
| 1061 | ; BP = new value of FEI_clusnum in the extended_info area. | ||
| 1062 | ; | ||
| 1063 | ; If AH = 2, then delete the entry. Same effect as Delete function | ||
| 1064 | ; except this time the keys used to delete are; | ||
| 1065 | ; DL = logical drive number | ||
| 1066 | ; CX = the value of "dir_first" to search. | ||
| 1067 | ; | ||
| 1068 | ; If AH = 3, then delete the entry. Same effect as Delete function | ||
| 1069 | ; except this time the keys used to delete are; | ||
| 1070 | ; DL = logical drive number | ||
| 1071 | ; DH = directory position | ||
| 1072 | ; DI = directory sector (low value) | ||
| 1073 | ; CX = directory sector (high value) | ||
| 1074 | ; | ||
| 1075 | ; | ||
| 1076 | ;OUT: if found, then data is updated | ||
| 1077 | ; else CY and AX = -1. | ||
| 1078 | ; | ||
| 1079 | ; This routine use "starting cluster number" and "drive letter" | ||
| 1080 | ; as a key to find the name record. Usually the reason is DOS | ||
| 1081 | ; does not have any "full path" information about the file when | ||
| 1082 | ; it has to call this routine to update the information. | ||
| 1083 | ; It follows the MRU chain until it finds the name record or | ||
| 1084 | ; until it reaches the free name record (identified by the | ||
| 1085 | ; Directory name starting with ' '), or until the end of | ||
| 1086 | ; the MRU chain. | ||
| 1087 | ; | ||
| 1088 | ;============================================================================== | ||
| 1089 | |||
| 1090 | UPDATE PROC FAR | ||
| 1091 | |||
| 1092 | mov cs:func_cod,al ; save function code | ||
| 1093 | cmp ah, 0 ;update directory entry ? | ||
| 1094 | je Update_Dir_Entry ;yes- | ||
| 1095 | cmp ah, 1 ;update extended info ? | ||
| 1096 | je Update_Extended_clusnum ;yes- | ||
| 1097 | cmp ah, 2 ;delete based on first clus num ? | ||
| 1098 | je Update_Delete ;yes- | ||
| 1099 | cmp ah, 3 ;delete based directory sector ? | ||
| 1100 | je Update_Delete1 ;yes- | ||
| 1101 | |||
| 1102 | U_ERROR: ;no - error exit | ||
| 1103 | stc | ||
| 1104 | jmp short Update_Exit | ||
| 1105 | |||
| 1106 | Update_Delete: ; same as delete | ||
| 1107 | CALL FIND_CLUSTER_NUMBER ; find name entry using first cluster | ||
| 1108 | jc U_ERROR | ||
| 1109 | jmp Delete_Node ; if found, delete entry | ||
| 1110 | |||
| 1111 | Update_Delete1: ; same as delete (PTR P3718 3/10/88) | ||
| 1112 | CALL FIND_DIR_SECTOR ; find name entry using directory | ||
| 1113 | jc U_ERROR ; sector and directory position | ||
| 1114 | jmp Delete_Node ; if found, delete node | ||
| 1115 | |||
| 1116 | Update_Dir_Entry: | ||
| 1117 | mov cx, es:[di.dir_first] | ||
| 1118 | push es ;save Dir_Info pointer ES:DI | ||
| 1119 | push di | ||
| 1120 | CALL FIND_CLUSTER_NUMBER | ||
| 1121 | pop si ;restore Dir_Info pointer in DS:SI | ||
| 1122 | pop ds | ||
| 1123 | jc U_ERROR ;error-if not found | ||
| 1124 | |||
| 1125 | push bp ;found the entry | ||
| 1126 | pop di | ||
| 1127 | add di, nCmpct_Dir_Info ;ES:DI->Name_Record.nCmpct_Dir_Info | ||
| 1128 | mov cx, ODI_head_leng | ||
| 1129 | REP MOVSB ;update Cmpct_dir_info head section | ||
| 1130 | add si, ODI_skip_leng | ||
| 1131 | mov cx, ODI_tail_leng | ||
| 1132 | REP MOVSB ;update tail section | ||
| 1133 | jmp short Update_Exit ;exit | ||
| 1134 | |||
| 1135 | Update_Extended_clusnum: ;update extended info field | ||
| 1136 | mov cs:New_FEI_clusnum,bp | ||
| 1137 | CALL FIND_CLUSTER_NUMBER ;Find entry based first cluster number | ||
| 1138 | jc U_ERROR | ||
| 1139 | |||
| 1140 | add bp, nExtended_Info ;es:bp -> Name_record.nExtended_Info | ||
| 1141 | mov bx, cs:New_FEI_clusnum | ||
| 1142 | mov es:[bp.FEI_clusnum],bx | ||
| 1143 | |||
| 1144 | Update_Exit: | ||
| 1145 | CALL Check_It ;check tree structure | ||
| 1146 | ret ;return | ||
| 1147 | |||
| 1148 | UPDATE ENDP | ||
| 1149 | |||
| 1150 | |||
| 1151 | |||
| 1152 | |||
| 1153 | |||
| 1154 | |||
| 1155 | ;============================================================================== | ||
| 1156 | ;Subroutine: FP_PURGE Rest Name Cache Buffers | ||
| 1157 | ; | ||
| 1158 | ;INPUT: Main_Name_Drive_Buff - Offset to Name cache buffer | ||
| 1159 | ; Main_Name_Cache_Seg - Name cache seg id | ||
| 1160 | ; DL = Drive ID | ||
| 1161 | ; | ||
| 1162 | ;OUT: Buffer is purged | ||
| 1163 | ; | ||
| 1164 | ;============================================================================== | ||
| 1165 | |||
| 1166 | FP_PURGE PROC FAR | ||
| 1167 | |||
| 1168 | mov si,Open_Name_Drive_Buff ; SI-->first Name drive cache buff | ||
| 1169 | mov es,Open_Name_Cache_Seg ; ES = name cache seg ID | ||
| 1170 | mov bx,es:[si].DCH_Name_Buff ; BX-->Name cache buffer | ||
| 1171 | inc dl ; DL=drive number | ||
| 1172 | add dl,040H ; convert drive num to drive letter | ||
| 1173 | |||
| 1174 | ; Search for the name drive header corresponds to the drive letter | ||
| 1175 | Purge_Drv_Loop: | ||
| 1176 | cmp es:[si].DCH_Drive_Letter,dl ; drive letter match ?? | ||
| 1177 | je Purge_drive_cache ; yes - set drive cache | ||
| 1178 | add si, size Drive_Cache_Header ; no - get address of next drive cache | ||
| 1179 | jmp purge_drv_loop ; try next name drive header | ||
| 1180 | |||
| 1181 | Purge_Drive_Cache: ; SI-->drive header | ||
| 1182 | mov bx,es:[si].DCH_Name_Buff ; BX-->Name cache buffer | ||
| 1183 | mov cx,es:[si].DCH_num_entries ; get number of name records | ||
| 1184 | mov ax,bx ; save last name record address | ||
| 1185 | mov es:[bx].nMRU_ptr, -1 ; make first MRU -1 | ||
| 1186 | jmp short set_start | ||
| 1187 | |||
| 1188 | Set_Up_Names: | ||
| 1189 | mov es:[bx].nMRU_ptr,ax ;save last name record as MRU entry | ||
| 1190 | add ax, size Name_Record ;AX = last name record = current name record | ||
| 1191 | |||
| 1192 | Set_Start: | ||
| 1193 | mov es:[bx].nChild_ptr, -1 ;no children or siblings | ||
| 1194 | mov es:[bx].nsibling_ptr, -1 ;right now | ||
| 1195 | mov es:[bx].nBackward_ptr, -1 | ||
| 1196 | |||
| 1197 | push di | ||
| 1198 | push ax | ||
| 1199 | mov ax, ' ' ;AX = ' ' | ||
| 1200 | mov di, bx ;DI-->current name record | ||
| 1201 | add di, nCmpct_Dir_Info ;blank out the Dir name area | ||
| 1202 | stosb ;in the name record | ||
| 1203 | stosw | ||
| 1204 | stosw | ||
| 1205 | stosw | ||
| 1206 | stosw | ||
| 1207 | stosw | ||
| 1208 | pop ax ; AX = last name record address | ||
| 1209 | pop di | ||
| 1210 | |||
| 1211 | dec cx ;update record count | ||
| 1212 | jcxz purge_exit ;exit if last name record is done | ||
| 1213 | mov dx,bx | ||
| 1214 | add dx, size Name_Record ;DX-->next name record | ||
| 1215 | mov es:[bx].nLRU_ptr,dx ;set LRU pointer - next name record | ||
| 1216 | add bx, size Name_Record | ||
| 1217 | jmp set_up_names ;set next name record | ||
| 1218 | |||
| 1219 | Purge_exit: | ||
| 1220 | clc | ||
| 1221 | ret | ||
| 1222 | |||
| 1223 | FP_PURGE ENDP | ||
| 1224 | |||
| 1225 | |||
| 1226 | |||
| 1227 | ;---------------------------------------------------------------------------- | ||
| 1228 | ; FASTOPEN SUPPORT ROUTINES | ||
| 1229 | ;---------------------------------------------------------------------------- | ||
| 1230 | ; | ||
| 1231 | ; PROCEDURE: Find_Drive_Cache_Header | ||
| 1232 | ; | ||
| 1233 | ; Function: Validate drive ID and find address of drive cache header | ||
| 1234 | ; | ||
| 1235 | ;IN: DL - drive letter | ||
| 1236 | ; Drive_Header_Start ;label | ||
| 1237 | ; Flag. | ||
| 1238 | ; | ||
| 1239 | ;OUT: If CY = 0 Drive Header found | ||
| 1240 | ; ES:BP -> Drive_Cache_Header, | ||
| 1241 | ; | ||
| 1242 | ; If CY = 1 Drive Header not found | ||
| 1243 | ; | ||
| 1244 | ;---------------------------------------------------------------------------- | ||
| 1245 | |||
| 1246 | FIND_DRIVE_CACHE_HEADER PROC NEAR | ||
| 1247 | |||
| 1248 | mov bp, cs:Open_name_drive_buff | ||
| 1249 | push ds | ||
| 1250 | mov ds,cs:Open_Name_Cache_Seg ;AN000; | ||
| 1251 | ASSUME ds:Cseg_Init ;DS:BP-->first drive header ;AN000; | ||
| 1252 | |||
| 1253 | FDCH_while: | ||
| 1254 | cmp byte ptr ds:[bp.DCH_Drive_Letter], dl ; drive letter match | ||
| 1255 | jne fdch_chk_end ; no - check next header | ||
| 1256 | clc ; yes - exit | ||
| 1257 | jmp short FDCH_Exit | ||
| 1258 | |||
| 1259 | FDCH_Chk_End: | ||
| 1260 | cmp byte ptr ds:[bp.DCH_Sibling_ptr], -1 ; is this last header ? | ||
| 1261 | je FDCH_Not_Found ; yes - header not found | ||
| 1262 | add bp, size Drive_Cache_Header ; no - get next header | ||
| 1263 | jmp short FDCH_while ; look for match | ||
| 1264 | |||
| 1265 | FDCH_Not_Found: | ||
| 1266 | stc ;not found | ||
| 1267 | |||
| 1268 | FDCH_Exit: ;ES:BP-->header if found | ||
| 1269 | pop ds | ||
| 1270 | ASSUME ds:nothing ;return | ||
| 1271 | ret | ||
| 1272 | |||
| 1273 | FIND_DRIVE_CACHE_HEADER endp | ||
| 1274 | |||
| 1275 | |||
| 1276 | |||
| 1277 | |||
| 1278 | ;---------------------------------------------------------------------- | ||
| 1279 | ; PROCEDURE: GET_FREE_NODE | ||
| 1280 | ; | ||
| 1281 | ; called by Insert. The LRU node pointed DCH_LRU_ROOT is returned in AX | ||
| 1282 | ; and DCH_LRU_ROOT points to the following node in LRU chain. | ||
| 1283 | ; If the node is not an empty node, then it will be removed from the | ||
| 1284 | ; tree. | ||
| 1285 | ; | ||
| 1286 | ; IN: Current_Drive, Current_Node | ||
| 1287 | ; | ||
| 1288 | ; OUT: AX = offset of the free node in Name_Cache_Seg | ||
| 1289 | ; Other registers saved. | ||
| 1290 | ;---------------------------------------------------------------------- | ||
| 1291 | |||
| 1292 | GET_FREE_NODE PROC NEAR | ||
| 1293 | |||
| 1294 | push es ;save registers | ||
| 1295 | push di | ||
| 1296 | push si | ||
| 1297 | push bp | ||
| 1298 | |||
| 1299 | mov ax, cs:Open_Name_Cache_Seg ;AN000; | ||
| 1300 | mov es, ax ;ES=Name cache segment ;AN000; | ||
| 1301 | ASSUME es:Cseg_Init ;AN000; | ||
| 1302 | mov si, cs:Current_Drive ;SI-->drive_cache_header | ||
| 1303 | push ds | ||
| 1304 | mov ds,cs:Open_Name_Cache_Seg | ||
| 1305 | ASSUME ds:Cseg_Init | ||
| 1306 | mov ax, ds:[si.DCH_LRU_ROOT] ;get the LRU node | ||
| 1307 | pop ds | ||
| 1308 | ASSUME ds:nothing | ||
| 1309 | |||
| 1310 | cmp ax, cs:current_Node ;LRU node=Current Node ?? | ||
| 1311 | je GFN_skip ;yes- | ||
| 1312 | |||
| 1313 | mov bp, ax ;BP=Current node | ||
| 1314 | mov di, es:[bp.nLRU_ptr] ;DI= current LRU node's following node | ||
| 1315 | mov es:[di.nMRU_ptr],-1 ;set that node's MRU ptr | ||
| 1316 | push ds | ||
| 1317 | mov ds,cs:Open_Name_Cache_Seg ;DS=Name cache segment | ||
| 1318 | ASSUME ds:Cseg_Init | ||
| 1319 | mov ds:[si.DCH_LRU_ROOT],di ;connect previous node to | ||
| 1320 | pop ds ;next node | ||
| 1321 | ASSUME ds:nothing | ||
| 1322 | |||
| 1323 | cmp byte ptr es:[bp.nCmpct_Dir_Info],' ';an empty node? | ||
| 1324 | je GFN_OK ;then no problem. | ||
| 1325 | |||
| 1326 | CALL RemoveFromTree ;otherwise, it should be removed | ||
| 1327 | ;from the tree. | ||
| 1328 | GFN_OK: | ||
| 1329 | clc | ||
| 1330 | jmp short GFN_ret | ||
| 1331 | |||
| 1332 | GFN_Skip: | ||
| 1333 | stc | ||
| 1334 | |||
| 1335 | GFN_ret: | ||
| 1336 | pop bp | ||
| 1337 | pop si | ||
| 1338 | pop di | ||
| 1339 | pop es | ||
| 1340 | ret ;return | ||
| 1341 | |||
| 1342 | GET_FREE_NODE endp | ||
| 1343 | |||
| 1344 | |||
| 1345 | |||
| 1346 | |||
| 1347 | ; | ||
| 1348 | ;---------------------------------------------------------------------- | ||
| 1349 | ; PROCEDURE: PRE_LRU_STACK | ||
| 1350 | ; | ||
| 1351 | ; When called by Look_up, Insert routine, the requested target node (BP) | ||
| 1352 | ; will be temporarily removed from LRU,MRU chain (until SET_LRU routine | ||
| 1353 | ; call), and will be pushed into a logical stack. Actually, this routine | ||
| 1354 | ; will not use a stack, but try to get the effect of the use of stack | ||
| 1355 | ; to keep the history of target nodes in "REVERSE" LRU order as follows; | ||
| 1356 | ; { inc Depth; | ||
| 1357 | ; if Depth == 1 then Bottom = BP; | ||
| 1358 | ; Bottom.LRU_ptr = -1; | ||
| 1359 | ; Bottom.MRU_ptr = -1; | ||
| 1360 | ; else if Depth == 2 then Top = BP; | ||
| 1361 | ; Top.LRU_ptr = Bottom; | ||
| 1362 | ; Bottom.MRU_ptr = Top; | ||
| 1363 | ; Top.MRU_ptr = -1; | ||
| 1364 | ; else if Depth >= 3 then Temp = Top; | ||
| 1365 | ; Top = BP; | ||
| 1366 | ; Top.LRU_ptr = Temp; | ||
| 1367 | ; Temp.MRU_ptr = Top; | ||
| 1368 | ; Top.MRU_ptr = -1; | ||
| 1369 | ; } | ||
| 1370 | ; | ||
| 1371 | ;IN: Depth, Top, Bottom, Temp, | ||
| 1372 | ; Requested target node (BP) | ||
| 1373 | ; ES = Name_Cache_Seg | ||
| 1374 | ; | ||
| 1375 | ;OUT: Target node removed from LRU,MRU chain. | ||
| 1376 | ; Target node's history saved in reverse LRU order. | ||
| 1377 | ; If called by "Delete" routine, then will just exit. | ||
| 1378 | ; If called by "Insert" routine, then will not attempt | ||
| 1379 | ; to remove the target node. | ||
| 1380 | ;---------------------------------------------------------------------- | ||
| 1381 | |||
| 1382 | PRE_LRU_STACK PROC NEAR | ||
| 1383 | |||
| 1384 | test cs:Flag, is_delete ;invoked by Delete routine | ||
| 1385 | jnz PLS_Exit | ||
| 1386 | test cs:Flag, is_insert ;called by Insert routine | ||
| 1387 | jnz PLS_Push | ||
| 1388 | |||
| 1389 | CALL RemoveFromLRUChain ;remove BP from the chain. | ||
| 1390 | |||
| 1391 | PLS_Push: | ||
| 1392 | push di | ||
| 1393 | |||
| 1394 | inc cs:Depth | ||
| 1395 | cmp cs:Depth, 1 | ||
| 1396 | jne PLS_Top | ||
| 1397 | mov cs:Bottom, bp ;bottom = bp | ||
| 1398 | mov es:[bp.nLRU_ptr], -1 | ||
| 1399 | jmp short PLS_Done | ||
| 1400 | |||
| 1401 | PLS_Top: | ||
| 1402 | cmp cs:Depth, 2 | ||
| 1403 | jne PLS_Temp | ||
| 1404 | mov cs:Top, bp ;Top = bp | ||
| 1405 | mov di, cs:bottom ;di = bottom | ||
| 1406 | |||
| 1407 | PLS_com: | ||
| 1408 | mov es:[bp.nLRU_ptr],di ;Top.LRU_ptr = bottom | ||
| 1409 | mov es:[di.nMRU_ptr],bp ;Bottom.MRU_ptr = top | ||
| 1410 | jmp short PLS_Done | ||
| 1411 | |||
| 1412 | PLS_Temp: | ||
| 1413 | mov di, cs:Top ;di = Top | ||
| 1414 | mov cs:Temp, di ;Temp = di | ||
| 1415 | mov cs:Top, bp ;Top = bp | ||
| 1416 | jmp short PLS_com | ||
| 1417 | |||
| 1418 | PLS_Done: | ||
| 1419 | mov es:[bp.nMRU_ptr],-1 | ||
| 1420 | pop di | ||
| 1421 | |||
| 1422 | PLS_Exit: | ||
| 1423 | ret | ||
| 1424 | |||
| 1425 | PRE_LRU_STACK endp | ||
| 1426 | ; | ||
| 1427 | |||
| 1428 | |||
| 1429 | |||
| 1430 | |||
| 1431 | |||
| 1432 | ;---------------------------------------------------------------------- | ||
| 1433 | ;PROCEDURE: SET_LRU | ||
| 1434 | ; | ||
| 1435 | ;INPUT: Depth, Top, Bottom, Current_Drive, ES = Name_Cache_Seg | ||
| 1436 | ; | ||
| 1437 | ;OUT: If Depth == 0 then exit | ||
| 1438 | ; Pre_LRU_Stack procedure already maintained a reverse order LRU | ||
| 1439 | ; mini chain. Set_LRU will just put the top after the last node | ||
| 1440 | ; of the current LRU chain; | ||
| 1441 | ; { Get the last node of LRU chain. | ||
| 1442 | ; if Depth == 0 then exit; | ||
| 1443 | ; if Depth == 1 then Last_Node.LRU_ptr = Bottom; | ||
| 1444 | ; Bottom.MRU_ptr = Last_Node; | ||
| 1445 | ; MRU_ROOT = Bottom; | ||
| 1446 | ; if Depth >= 2 then Last_Node.LRU_ptr = Top; | ||
| 1447 | ; Top.MRU_ptr = Last_Node; | ||
| 1448 | ; MRU_ROOT = Bottom; | ||
| 1449 | ; Depth = 0; | ||
| 1450 | ; } | ||
| 1451 | ;---------------------------------------------------------------------- | ||
| 1452 | |||
| 1453 | SET_LRU PROC NEAR | ||
| 1454 | |||
| 1455 | cmp cs:Depth, 0 ;nothing in the stack? | ||
| 1456 | je SL_Exit | ||
| 1457 | |||
| 1458 | push si | ||
| 1459 | push di | ||
| 1460 | push bx | ||
| 1461 | mov si, cs:Current_Drive ;cs:si -> Drive_Cache_Header | ||
| 1462 | push ds | ||
| 1463 | mov ds,cs:Open_Name_Cache_Seg ;AN000; | ||
| 1464 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1465 | mov di, ds:[si.DCH_MRU_ROOT] ;es:di -> Last node in LRU chain | ||
| 1466 | |||
| 1467 | cmp cs:Depth, 1 | ||
| 1468 | jne SL_Other | ||
| 1469 | |||
| 1470 | mov bx, cs:Bottom | ||
| 1471 | mov es:[di.nLRU_ptr],bx ;Last_Node.LRU_ptr = Bottom | ||
| 1472 | mov es:[bx.nMRU_ptr],di ;Bottom.MRU_ptr = Last_Node | ||
| 1473 | mov ds:[si.DCH_MRU_ROOT],bx ;MRU_ROOT = Bottom | ||
| 1474 | jmp short SL_Done | ||
| 1475 | |||
| 1476 | SL_Other: ;Depth >= 2 | ||
| 1477 | mov bx, cs:Top | ||
| 1478 | mov es:[di.nLRU_ptr],bx | ||
| 1479 | mov es:[bx.nMRU_ptr],di | ||
| 1480 | mov bx, cs:Bottom | ||
| 1481 | mov ds:[si.DCH_MRU_ROOT],bx | ||
| 1482 | |||
| 1483 | SL_Done: | ||
| 1484 | pop ds | ||
| 1485 | ASSUME ds:nothing | ||
| 1486 | mov cs:Depth, 0 ;reset the Depth | ||
| 1487 | pop bx | ||
| 1488 | pop di | ||
| 1489 | pop si | ||
| 1490 | |||
| 1491 | SL_Exit: | ||
| 1492 | ret | ||
| 1493 | |||
| 1494 | Set_LRU endp | ||
| 1495 | |||
| 1496 | |||
| 1497 | |||
| 1498 | |||
| 1499 | |||
| 1500 | ;---------------------------------------------------------------------- | ||
| 1501 | ; Procedure RemoveFromLRUChain | ||
| 1502 | ; | ||
| 1503 | ;IN: Target node (BP) to be removed | ||
| 1504 | ; Current_drive | ||
| 1505 | ; ES - Name_Cache_Seg | ||
| 1506 | ; | ||
| 1507 | ;OUT: Target node removed from the LRU,MRU chain. LRU,MRU chain | ||
| 1508 | ; updated. | ||
| 1509 | ; | ||
| 1510 | ;---------------------------------------------------------------------- | ||
| 1511 | |||
| 1512 | RemoveFromLRUChain PROC near | ||
| 1513 | |||
| 1514 | push bx | ||
| 1515 | push di | ||
| 1516 | push si | ||
| 1517 | |||
| 1518 | mov si, cs:Current_drive ;cs:si-> Drive_cache_header | ||
| 1519 | mov bx, es:[bp.nMRU_ptr] ;es:bx-> Preceding node | ||
| 1520 | mov di, es:[bp.nLRU_ptr] ;es:di-> Following node | ||
| 1521 | cmp bx, -1 ;Is target the first node? | ||
| 1522 | je RFLC_first_node | ||
| 1523 | cmp di, -1 ;Is target the last node of LRU chain? | ||
| 1524 | je RFLC_last_node | ||
| 1525 | mov es:[bx.nLRU_ptr],di ;Preceding.LRU_ptr->following node | ||
| 1526 | mov es:[di.nMRU_ptr],bx ;Following.MRU_ptr->preceding node | ||
| 1527 | jmp short RFLC_done | ||
| 1528 | |||
| 1529 | RFLC_first_node: | ||
| 1530 | push ds | ||
| 1531 | mov ds,cs:Open_Name_Cache_Seg ;AN000; | ||
| 1532 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1533 | mov ds:[si.DCH_LRU_ROOT],di ;LRU_ROOT-> following node | ||
| 1534 | pop ds | ||
| 1535 | ASSUME ds:nothing | ||
| 1536 | mov es:[di.nMRU_ptr], -1 ;Following node's MRU_ptr | ||
| 1537 | jmp short RFLC_done | ||
| 1538 | |||
| 1539 | RFLC_last_node: | ||
| 1540 | push ds | ||
| 1541 | mov ds,cs:Open_Name_Cache_Seg | ||
| 1542 | ASSUME ds:Cseg_Init | ||
| 1543 | mov ds:[si.DCH_MRU_ROOT],bx ;MRU_ROOT-> preceding node | ||
| 1544 | mov es:[bx.nLRU_ptr], -1 ;Preceding node's LRU_ptr | ||
| 1545 | pop ds | ||
| 1546 | ASSUME ds:nothing | ||
| 1547 | |||
| 1548 | RFLC_done: | ||
| 1549 | pop si | ||
| 1550 | pop di | ||
| 1551 | pop bx | ||
| 1552 | ret | ||
| 1553 | |||
| 1554 | RemoveFromLRUChain endp | ||
| 1555 | ; | ||
| 1556 | |||
| 1557 | |||
| 1558 | |||
| 1559 | ;---------------------------------------------------------------------- | ||
| 1560 | ; Proceure RemoveFromTree | ||
| 1561 | ; | ||
| 1562 | ;IN: BP - offset of node to be removed from the tree | ||
| 1563 | ; This node shoud not be a subdirectory that is not empty!!! | ||
| 1564 | ; ES - Name_Cache_Seg | ||
| 1565 | ; Current_Drive | ||
| 1566 | ; | ||
| 1567 | ;OUT: The node will be freed from the tree. | ||
| 1568 | ; The neighbor's Child_ptr, Sibling_ptr, Backward_ptr are adjusted | ||
| 1569 | ; accordingly. | ||
| 1570 | ; The freed node's child_ptr, sibling_ptr, backward_ptr are reset to -1. | ||
| 1571 | ;---------------------------------------------------------------------- | ||
| 1572 | |||
| 1573 | REMOVEFROMTREE PROC NEAR | ||
| 1574 | |||
| 1575 | push bx | ||
| 1576 | push dx | ||
| 1577 | |||
| 1578 | mov bx, es:[bp.nBackward_ptr] ;get the preceding node | ||
| 1579 | mov dx, es:[bp.nSibling_ptr] ;get the sibling node | ||
| 1580 | cmp bx, cs:Current_Drive | ||
| 1581 | je RFT_First_Child ;bp is the first child | ||
| 1582 | cmp es:[bx.nChild_ptr],bp | ||
| 1583 | je RFT_Child ;bp is the child of the preceding node | ||
| 1584 | mov es:[bx.nSibling_ptr],dx ;bp is the Sibling of the preceding node | ||
| 1585 | ;Update the preceding node's Sibling ptr | ||
| 1586 | jmp short RFT_Reset | ||
| 1587 | |||
| 1588 | RFT_First_Child: | ||
| 1589 | push ds | ||
| 1590 | mov ds,cs:Open_Name_Cache_Seg ;AN000; | ||
| 1591 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1592 | mov ds:[bx.DCH_Child_ptr],dx | ||
| 1593 | pop ds | ||
| 1594 | ASSUME ds:nothing | ||
| 1595 | jmp short RFT_Reset | ||
| 1596 | |||
| 1597 | RFT_Child: | ||
| 1598 | mov es:[bx.nChild_ptr],dx | ||
| 1599 | |||
| 1600 | RFT_Reset: ;reset the deleted node's tree pointers | ||
| 1601 | mov es:[bp.nChild_ptr],-1 | ||
| 1602 | mov es:[bp.nSibling_ptr],-1 | ||
| 1603 | mov es:[bp.nBackward_ptr],-1 | ||
| 1604 | |||
| 1605 | xchg dx,bx ;now, dx=preceding node, bx=following node | ||
| 1606 | cmp bx,-1 ;end of sibling? | ||
| 1607 | je RFT_ret | ||
| 1608 | mov es:[bx.nBackward_ptr],dx;modify backward_ptr of the sibling node | ||
| 1609 | |||
| 1610 | RFT_ret: | ||
| 1611 | pop dx | ||
| 1612 | pop bx | ||
| 1613 | ret ;return | ||
| 1614 | |||
| 1615 | REMOVEFROMTREE endp | ||
| 1616 | ; | ||
| 1617 | |||
| 1618 | |||
| 1619 | |||
| 1620 | |||
| 1621 | ;---------------------------------------------------------------------- | ||
| 1622 | ; Procedure CMPARE | ||
| 1623 | ; | ||
| 1624 | ;IN: Packed name | ||
| 1625 | ; BP = target node | ||
| 1626 | ; | ||
| 1627 | ;OUT: ZERO flag set when compare O.K. | ||
| 1628 | ; DI destroyed. | ||
| 1629 | ;---------------------------------------------------------------------- | ||
| 1630 | |||
| 1631 | CMPARE PROC near | ||
| 1632 | |||
| 1633 | push ds | ||
| 1634 | push si | ||
| 1635 | mov cx, 11 | ||
| 1636 | push cs | ||
| 1637 | pop ds | ||
| 1638 | mov si, offset cs:Packed_Name ;ds:si -> Packed_Name | ||
| 1639 | mov di,bp | ||
| 1640 | add di,nCmpct_Dir_Info ;es:di -> bp.nCmpact_Dir_Info | ||
| 1641 | REPE CMPSB | ||
| 1642 | pop si | ||
| 1643 | pop ds | ||
| 1644 | ret | ||
| 1645 | CMPARE endp | ||
| 1646 | |||
| 1647 | |||
| 1648 | |||
| 1649 | |||
| 1650 | ; | ||
| 1651 | ;---------------------------------------------------------------------- | ||
| 1652 | ; Procedure: MAKE_NAME_RECORD | ||
| 1653 | ; | ||
| 1654 | ;IN: DS:DI -> Dir_Info, ES:BX -> Extended_Info | ||
| 1655 | ; AX = offset of the Name_Record entry in Name_Cache_Seg. | ||
| 1656 | ; | ||
| 1657 | ;OUT: Name_Record in Name_Cache_Seg filled. | ||
| 1658 | ; nLRU_ptr, nChild_ptr, nSibling_ptr and nMRU_ptr are set to -1 for now. | ||
| 1659 | ; ES, SI, DI destroyed. ES will be Name_Cache_Seg. | ||
| 1660 | ;---------------------------------------------------------------------- | ||
| 1661 | |||
| 1662 | MAKE_NAME_RECORD PROC NEAR | ||
| 1663 | |||
| 1664 | push ds ;save DS | ||
| 1665 | push ax | ||
| 1666 | |||
| 1667 | push es ;save Extended_Info seg in DOS | ||
| 1668 | push di | ||
| 1669 | pop si ;DS:SI -> Dir_Info | ||
| 1670 | mov di, cs:Open_Name_Cache_Seg ;AN000; | ||
| 1671 | mov es, di ;AN000; | ||
| 1672 | ASSUME es:Cseg_Init ;AN000; | ||
| 1673 | mov di, ax ;ES:DI -> Name_Record | ||
| 1674 | mov ax, -1 | ||
| 1675 | mov es:[di.nLRU_ptr],ax ;initialize pointers | ||
| 1676 | mov es:[di.nChild_ptr],ax | ||
| 1677 | mov es:[di.nSibling_ptr],ax | ||
| 1678 | mov es:[di.nMRU_ptr],ax | ||
| 1679 | add di, nCmpct_Dir_Info ;ES:DI -> Name_Record.nCmpct_Dir_Info | ||
| 1680 | mov cx, ODI_head_leng ;currently 10. | ||
| 1681 | rep movsb ;Move header part | ||
| 1682 | add si, ODI_skip_leng ;DS:SI -> tail part of Dir_Info | ||
| 1683 | mov cx, ODI_tail_leng | ||
| 1684 | REP MOVSB ;move tail part. | ||
| 1685 | |||
| 1686 | pop ds ;restore Extended_Info seg in DS!!! | ||
| 1687 | mov si, bx ;DS:SI -> Extended_Info | ||
| 1688 | mov cx, size Fastopen_Extended_Info | ||
| 1689 | rep movsb ;Move Extended_Info | ||
| 1690 | pop ax | ||
| 1691 | pop ds ;Restore DS | ||
| 1692 | |||
| 1693 | ret ;return | ||
| 1694 | |||
| 1695 | MAKE_NAME_RECORD ENDP | ||
| 1696 | ; | ||
| 1697 | |||
| 1698 | |||
| 1699 | |||
| 1700 | |||
| 1701 | ;---------------------------------------------------------------------- | ||
| 1702 | ; Procedure Unfold_Name_Record | ||
| 1703 | ; | ||
| 1704 | ;IN: Matching_Node, ES:DI -> Dir_Info buffer, ES:CX -> Extended_Info buffer | ||
| 1705 | ; | ||
| 1706 | ;OUT: if no matching node is found, then just return | ||
| 1707 | ; else Dir_Info, Extended_Info buffer are filled. | ||
| 1708 | ;---------------------------------------------------------------------- | ||
| 1709 | |||
| 1710 | Unfold_Name_Record PROC near | ||
| 1711 | |||
| 1712 | cmp cs:Matching_Node, -1 | ||
| 1713 | je UNR_Exit ;just exit | ||
| 1714 | push ds | ||
| 1715 | push si | ||
| 1716 | push di | ||
| 1717 | push cx ;save extended_info addr | ||
| 1718 | |||
| 1719 | mov si, cs:Open_Name_Cache_Seg ;AN000; | ||
| 1720 | mov ds, si ;AN000; | ||
| 1721 | ASSUME ds:Cseg_Init ;AN000; | ||
| 1722 | mov si, cs:Matching_Node | ||
| 1723 | add si, nCmpct_Dir_Info ;DS:SI -> Cmpct_Dir_Info | ||
| 1724 | |||
| 1725 | mov cx, ODI_head_leng ;Dir_Info header length | ||
| 1726 | REP MOVSB ;Cmpct_Dir_Info.CDI_file_name -> ODI_head | ||
| 1727 | |||
| 1728 | add di, ODI_skip_leng ;length of Skiped part of Dir_Info | ||
| 1729 | mov cx, ODI_tail_leng ;Dir_Info tail length | ||
| 1730 | REP movsb ;Cmpct_Dir_Info.CDI_Time -> ODI_tail | ||
| 1731 | ;At this moment, SI -> nExtended_Info | ||
| 1732 | |||
| 1733 | pop di ;ES:DI -> Extended_info | ||
| 1734 | push di ;save di again for cx. | ||
| 1735 | mov cx, size Fastopen_Extended_Info | ||
| 1736 | REP movsb | ||
| 1737 | |||
| 1738 | pop cx ;restore extended_info addr | ||
| 1739 | pop di | ||
| 1740 | pop si | ||
| 1741 | pop ds | ||
| 1742 | ASSUME ds:nothing | ||
| 1743 | UNR_Exit: | ||
| 1744 | ret ;return | ||
| 1745 | |||
| 1746 | Unfold_Name_Record endp | ||
| 1747 | ; | ||
| 1748 | |||
| 1749 | |||
| 1750 | |||
| 1751 | |||
| 1752 | ;---------------------------------------------------------------------- | ||
| 1753 | ; PROCEDURE: PACK DIR_NAME | ||
| 1754 | ; | ||
| 1755 | ; Parse the name off of DS:SI into Packed_Name. If called first time and | ||
| 1756 | ; DS:[SI+1] = ':' then it is ASSUMEd to be a drive letter and it will be | ||
| 1757 | ; returned in DL and SI will points to '\' after ':'. If it was a directory | ||
| 1758 | ; name then Packed_Name will be set and SI points to '\' or 0 after the | ||
| 1759 | ; parsed directory name or filename. This routine will check DS:[SI] when | ||
| 1760 | ; called to see if it points to '\' or 0. If it points to '\' then | ||
| 1761 | ; it is ASSUMEd that the user want to skip the delimiter. If it was 0, | ||
| 1762 | ; then this routine will set carry. So, with a given drive,path string, | ||
| 1763 | ; the user is going to keep calling this routine until it returns | ||
| 1764 | ; with carry set that tells the end. | ||
| 1765 | ;---------------------------------------------------------------------- | ||
| 1766 | |||
| 1767 | PACK_DIR_NAME PROC NEAR | ||
| 1768 | |||
| 1769 | cmp byte ptr ds:[si], 0 ;end of path ?? | ||
| 1770 | jne PDN_Drive ;no-check for drive letter | ||
| 1771 | stc | ||
| 1772 | jmp short PDN_Exit ;yes-exit | ||
| 1773 | |||
| 1774 | PDN_Drive: | ||
| 1775 | cmp byte ptr ds:[si+1], ':' ;drive letter terminater? | ||
| 1776 | jnz PDN_chk_skip ;no - | ||
| 1777 | mov dl, byte ptr ds:[si] ;yes-set DL to the drive letter | ||
| 1778 | inc si | ||
| 1779 | inc si ;set SI -> '\' after ':' | ||
| 1780 | jmp short PDN_Exit ;then exit | ||
| 1781 | |||
| 1782 | PDN_chk_skip: | ||
| 1783 | cmp byte ptr ds:[si], '\' ;delimeter? | ||
| 1784 | jne PDN_Path ;no- | ||
| 1785 | inc si ;yes-skip delimiter | ||
| 1786 | cmp byte ptr ds:[si], 0 ;end of path ?? | ||
| 1787 | jne PDN_Path ;no-pack path name | ||
| 1788 | stc ;yes-In fact, the input from DOS was | ||
| 1789 | mov ax, -1 ;D:\,0. FASTOPEN will treate | ||
| 1790 | jmp short PDN_Exit ;this as an error. | ||
| 1791 | |||
| 1792 | PDN_Path: ;pack path name | ||
| 1793 | push es | ||
| 1794 | push di | ||
| 1795 | push ax | ||
| 1796 | |||
| 1797 | push cs | ||
| 1798 | pop es | ||
| 1799 | mov di, offset cs:Packed_Name ;ES:DI-->pack buffer | ||
| 1800 | |||
| 1801 | mov ax,' ' | ||
| 1802 | STOSB ;blank out the Packed_Name | ||
| 1803 | STOSW | ||
| 1804 | STOSW | ||
| 1805 | STOSW | ||
| 1806 | STOSW | ||
| 1807 | STOSW | ||
| 1808 | mov di, offset cs:Packed_Name | ||
| 1809 | |||
| 1810 | PDN_GetName: | ||
| 1811 | LODSB ;DS:SI => AL, SI++ | ||
| 1812 | cmp al,'.' | ||
| 1813 | jz PDN_SetExt | ||
| 1814 | or al,al | ||
| 1815 | jz PDN_GetDone | ||
| 1816 | cmp al,'\' | ||
| 1817 | jz PDN_GetDone | ||
| 1818 | STOSB | ||
| 1819 | jmp short PDN_GetName | ||
| 1820 | |||
| 1821 | PDN_SetExt: | ||
| 1822 | mov di, offset cs:Packed_Name+8 | ||
| 1823 | |||
| 1824 | PDN_GetExt: | ||
| 1825 | LODSB | ||
| 1826 | or al,al | ||
| 1827 | jz PDN_GetDone | ||
| 1828 | cmp al,'\' | ||
| 1829 | jz PDN_GetDone | ||
| 1830 | |||
| 1831 | PDN_StoExt: | ||
| 1832 | STOSB | ||
| 1833 | jmp PDN_GetExt | ||
| 1834 | |||
| 1835 | PDN_GetDone: | ||
| 1836 | dec si ;set SI back to the delimeter or 0. | ||
| 1837 | pop ax | ||
| 1838 | pop di | ||
| 1839 | pop es | ||
| 1840 | |||
| 1841 | PDN_Exit: | ||
| 1842 | ret | ||
| 1843 | |||
| 1844 | PACK_DIR_NAME endp | ||
| 1845 | |||
| 1846 | |||
| 1847 | |||
| 1848 | |||
| 1849 | |||
| 1850 | ;---------------------------------------------------------------------- | ||
| 1851 | ; PROCEDURE: FIND_CLUSTER_NUMBER | ||
| 1852 | ; | ||
| 1853 | ;IN: DL = driver # (0 = A, 1 = B,...) | ||
| 1854 | ; CX = The value of Dir_First in Name_Record to search. | ||
| 1855 | ; Search Name_Record entries to find the matching starting cluster number. | ||
| 1856 | ; The search uses MRU chain for efficiency. | ||
| 1857 | ; | ||
| 1858 | ;OUT: ES = Name_Cache_Seg | ||
| 1859 | ; BP = Name_Record | ||
| 1860 | ; if not found, carry bit. | ||
| 1861 | ; ES, BP register changed. | ||
| 1862 | ;---------------------------------------------------------------------- | ||
| 1863 | |||
| 1864 | FIND_CLUSTER_NUMBER PROC NEAR | ||
| 1865 | |||
| 1866 | push ax | ||
| 1867 | push cx | ||
| 1868 | push dx | ||
| 1869 | add dl, 'A' ;convert to a drive letter | ||
| 1870 | |||
| 1871 | CALL FIND_DRIVE_CACHE_HEADER ;ES:BP -> driver header if found | ||
| 1872 | jc FCN_exit ;exit if not found | ||
| 1873 | |||
| 1874 | mov dx, cx ;save the key in DX ;AN000; | ||
| 1875 | mov ax, cs:Open_Name_Cache_Seg ;AN000; | ||
| 1876 | mov es, ax ;AN000; | ||
| 1877 | ASSUME es:Cseg_Init | ||
| 1878 | |||
| 1879 | CALL SET_LRU ;clean up the LRU stack | ||
| 1880 | |||
| 1881 | mov cs:Current_Drive,bp ;set Current_Drive (You should not set | ||
| 1882 | ;Current_Drive before SET_LRU at any time!!! | ||
| 1883 | push ds | ||
| 1884 | mov ds,cs:Open_Name_Cache_Seg | ||
| 1885 | ASSUME ds:Cseg_Init | ||
| 1886 | mov cx, ds:[bp.DCH_Num_Entries] ;Max number to try | ||
| 1887 | mov bp, ds:[bp.DCH_MRU_ROOT] ;get the start of MRU chaing | ||
| 1888 | pop ds | ||
| 1889 | ASSUME ds:nothing | ||
| 1890 | |||
| 1891 | FCN_while: | ||
| 1892 | cmp es:[bp.nCmpct_Dir_Info], ' ' ;Is it a free node ? | ||
| 1893 | je FCN_not_found ;then no reason to continue search. | ||
| 1894 | |||
| 1895 | cmp dx, es:[bp.nCmpct_Dir_Info.CDI_cluster] ;matching starting cluster # ? | ||
| 1896 | je FCN_exit ;found it!!! | ||
| 1897 | |||
| 1898 | mov bp, es:[bp.nMRU_ptr] ;next MRU entry address | ||
| 1899 | cmp bp, -1 ;It was the end of MRU chain? | ||
| 1900 | je FCN_not_found ;not found. End of search | ||
| 1901 | LOOP FCN_while ;else compare cluster and contine... | ||
| 1902 | |||
| 1903 | FCN_Not_found: | ||
| 1904 | stc | ||
| 1905 | |||
| 1906 | FCN_exit: | ||
| 1907 | pop dx | ||
| 1908 | pop cx | ||
| 1909 | pop ax | ||
| 1910 | ret | ||
| 1911 | |||
| 1912 | FIND_CLUSTER_NUMBER ENDP | ||
| 1913 | |||
| 1914 | |||
| 1915 | |||
| 1916 | |||
| 1917 | ;---------------------------------------------------------------------- | ||
| 1918 | ; PROCEDURE: FIND_DIR_SECTOR (PTR 3718 3/10/88) | ||
| 1919 | ; | ||
| 1920 | ; Search Name_Record using directory sector and directory position | ||
| 1921 | ; for the name entry. | ||
| 1922 | ; | ||
| 1923 | ;IN: DL = driver # (0 = A, 1 = B,...) | ||
| 1924 | ; DI = Dirctory sector Low value | ||
| 1925 | ; CX = Dirctory sector high value | ||
| 1926 | ; DH = Dirctory position | ||
| 1927 | ; | ||
| 1928 | ;OUT: ES = Name_Cache_Seg | ||
| 1929 | ; BP = Name_Record | ||
| 1930 | ; if not found, carry bit. | ||
| 1931 | ; ES, BP register changed. | ||
| 1932 | ;---------------------------------------------------------------------- | ||
| 1933 | |||
| 1934 | FIND_DIR_SECTOR PROC NEAR | ||
| 1935 | |||
| 1936 | push ax | ||
| 1937 | push cx | ||
| 1938 | push dx | ||
| 1939 | add dl, 'A' ;convert to a drive letter | ||
| 1940 | |||
| 1941 | CALL FIND_DRIVE_CACHE_HEADER ;ES:BP -> driver header if found | ||
| 1942 | jc FDIR_exit ; error if not found | ||
| 1943 | |||
| 1944 | mov ax, cs:Open_Name_Cache_Seg ;AN000; | ||
| 1945 | mov es, ax ;AN000; | ||
| 1946 | ASSUME es:Cseg_Init | ||
| 1947 | |||
| 1948 | CALL SET_LRU ;clean up the LRU stack | ||
| 1949 | |||
| 1950 | mov ax,cx ; save directory sector high value | ||
| 1951 | mov cs:Current_Drive,bp ;set Current_Drive (You should not set | ||
| 1952 | ;Current_Drive before SET_LRU at any time!!! | ||
| 1953 | push ds | ||
| 1954 | mov ds,cs:Open_Name_Cache_Seg | ||
| 1955 | ASSUME ds:Cseg_Init | ||
| 1956 | mov cx, ds:[bp.DCH_Num_Entries] ;Max number to try | ||
| 1957 | mov bp, ds:[bp.DCH_MRU_ROOT] ;get the start of MRU chaing | ||
| 1958 | pop ds | ||
| 1959 | ASSUME ds:nothing | ||
| 1960 | |||
| 1961 | FDIR_while: | ||
| 1962 | cmp es:[bp.nCmpct_Dir_Info], ' ' ;Is it a free node ? | ||
| 1963 | je FDIR_NOT_FOUND ;then no reason to continue search. | ||
| 1964 | |||
| 1965 | cmp di, word ptr es:[bp.nExtended_Info.FEI_dirsec] ;matching directory sector hi? | ||
| 1966 | jne FDIR_Next ;check next entry | ||
| 1967 | |||
| 1968 | cmp ax, word ptr es:[bp.nExtended_Info.FEI_dirsec+2] ;matching directory sector low ? | ||
| 1969 | jne FDIR_Next ;check next entry | ||
| 1970 | |||
| 1971 | cmp dh, es:[bp.nExtended_Info.FEI_dirpos] ;matching directory postion ? | ||
| 1972 | je FDIR_Exit ;check next entry | ||
| 1973 | |||
| 1974 | FDIR_Next: | ||
| 1975 | mov bp, es:[bp.nMRU_ptr] ;next MRU entry address | ||
| 1976 | cmp bp, -1 ;It was the end of MRU chain? | ||
| 1977 | je FDIR_not_found ;not found. End of search | ||
| 1978 | loop FDIR_while ;else compare cluster and contine... | ||
| 1979 | |||
| 1980 | FDIR_Not_found: ; no found | ||
| 1981 | stc | ||
| 1982 | |||
| 1983 | FDIR_exit: | ||
| 1984 | pop dx | ||
| 1985 | pop cx | ||
| 1986 | pop ax | ||
| 1987 | ret | ||
| 1988 | |||
| 1989 | FIND_DIR_SECTOR ENDP | ||
| 1990 | |||
| 1991 | |||
| 1992 | |||
| 1993 | |||
| 1994 | |||
| 1995 | ;-------------------------------------------------------------------------- | ||
| 1996 | ; Procedure: CHECK_IT Call Fastopen Tree Analyser to check the | ||
| 1997 | ; consistency of the Directory/File Tree strucutre. | ||
| 1998 | ;-------------------------------------------------------------------------- | ||
| 1999 | CHECK_IT PROC NEAR | ||
| 2000 | |||
| 2001 | pushf ; save all registers | ||
| 2002 | push ax | ||
| 2003 | push bx | ||
| 2004 | push cx | ||
| 2005 | push dx | ||
| 2006 | push si | ||
| 2007 | push di | ||
| 2008 | push ds | ||
| 2009 | push es | ||
| 2010 | cmp cs:Chk_flag,0 ;Fastopen analyser enabled ?? | ||
| 2011 | je Check_Exit ;no - exit | ||
| 2012 | |||
| 2013 | mov ax,cs:Open_Name_Cache_Seg ;yes-set multiplex function call | ||
| 2014 | mov es,ax | ||
| 2015 | mov ah,091h ;load Multiplex ID | ||
| 2016 | xor al,al | ||
| 2017 | xor cx,cx | ||
| 2018 | mov cl,cs:func_cod ;CL=Fastopen Function code | ||
| 2019 | mov di,cs:Current_Drive ;ES:DI-->current drive header | ||
| 2020 | INT 2FH ;call the analyser | ||
| 2021 | |||
| 2022 | Check_Exit: | ||
| 2023 | pop es ;restore all registers | ||
| 2024 | pop ds | ||
| 2025 | pop di | ||
| 2026 | pop si | ||
| 2027 | pop dx | ||
| 2028 | pop cx | ||
| 2029 | pop bx | ||
| 2030 | pop ax | ||
| 2031 | popf ;return | ||
| 2032 | ret | ||
| 2033 | |||
| 2034 | CHECK_IT ENDP | ||
| 2035 | |||
| 2036 | |||
| 2037 | |||
| 2038 | |||
| 2039 | |||
| 2040 | ; Calculate the size of the CSEG_OPEN Module in bytes | ||
| 2041 | IF ($-Cseg_Open) MOD 16 ;AN000; | ||
| 2042 | ORG ($-Cseg_Open)+16-(($-Cseg_Open) MOD 16) ;AN000; | ||
| 2043 | ENDIF ;AN000; | ||
| 2044 | |||
| 2045 | END_OPEN label word | ||
| 2046 | |||
| 2047 | |||
| 2048 | |||
| 2049 | |||
| 2050 | CSEG_OPEN ends | ||
| 2051 | end | ||
| 2052 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/FASTOPEN/FASTOPEN.LNK b/v4.0/src/CMD/FASTOPEN/FASTOPEN.LNK new file mode 100644 index 0000000..eb37c6e --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTOPEN.LNK | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | FASTOPEN.OBJ+ | ||
| 2 | FASTSEEK.OBJ+ | ||
| 3 | FASTINIT.OBJ+ | ||
| 4 | FASTP.OBJ+ | ||
| 5 | FASTSM.OBJ | ||
| 6 | FASTOPEN.EXE,/m; | ||
| 7 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/FASTOPEN/FASTOPEN.SKL b/v4.0/src/CMD/FASTOPEN/FASTOPEN.SKL new file mode 100644 index 0000000..25c7c5e --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTOPEN.SKL | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | ;========================================================== | ||
| 2 | ; FASTOPEN MESSAGE SKELETON FILE | ||
| 3 | ;========================================================== | ||
| 4 | |||
| 5 | :util FASTOPEN ;AN000; | ||
| 6 | :class A ;System message class ;AN000; | ||
| 7 | :use 1 COMMON1 ;MSG 1 is always "Incorrect DOS Version" ;AN000; | ||
| 8 | :use 6 PARSE10 ;Invalid parameter message ;AN000; | ||
| 9 | :use 3 PARSE3 ;Invalid Switch | ||
| 10 | |||
| 11 | :def 4 CR,LF,"FASTOPEN installed",CR,LF ;AN000; | ||
| 12 | :def 5 CR,LF,"FASTOPEN already installed",CR,LF ;AN000; | ||
| 13 | :def 7 CR,LF,"Too many drive entries",CR,LF ;AN000; | ||
| 14 | :def 8 CR,LF,"Same drive specified more than once",CR,LF ;AN000; | ||
| 15 | :def 9 CR,LF,"Invalid parameter",CR,LF ;AN000; | ||
| 16 | :def 11 CR,LF,"Invalid extent entry",CR,LF ;AN000; | ||
| 17 | :def 12 CR,LF,"Invalid number of file/directory entries",CR,LF ;AN000;;AN000; | ||
| 18 | :def 13 CR,LF,"Cannot setup expanded memory",CR,LF ;AN000;;AN000; | ||
| 19 | :def 14 CR,LF,"Expanded memory not available",CR,LF ;AN000;;AN000; | ||
| 20 | :def 15 CR,LF,"Invalid drive specification %1",CR,LF ;AN000;;AN000; | ||
| 21 | :def 16 CR,LF,"Not enough space in EMS. Low memory is used",CR,LF ;AN000; | ||
| 22 | :def 17 CR,LF,"Cannot use FASTOPEN for drive %1",CR,LF | ||
| 23 | :def 18 CR,LF,"Too many extent entries",CR,LF ;AN000; | ||
| 24 | :def 19 CR,LF,"Too many file/directory entries",CR,LF ;AN000; | ||
| 25 | |||
| 26 | :end | ||
| 27 | |||
| 28 | ;========================================================== | ||
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 | |||
diff --git a/v4.0/src/CMD/FASTOPEN/FASTP.ASM b/v4.0/src/CMD/FASTOPEN/FASTP.ASM new file mode 100644 index 0000000..561417c --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTP.ASM | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | PAGE 90,132 ;A2 | ||
| 2 | TITLE fastp.asm - fastopen SYSTEM COMMAND LINE PARSER | ||
| 3 | ;****************** START OF SPECIFICATIONS ***************************** | ||
| 4 | ; MODULE NAME: fastp.asm | ||
| 5 | ; | ||
| 6 | ; DESCRIPTIVE NAME: Include the DOS system PARSER in the SEGMENT | ||
| 7 | ; configuration expected by the modules of fastopen. | ||
| 8 | ; | ||
| 9 | ;FUNCTION: The common code of the DOS command line PARSER is optimized by | ||
| 10 | ; the setting of certain switches that cause the conditional | ||
| 11 | ; assembly of only the required portions of the common PARSER. | ||
| 12 | ; | ||
| 13 | ; ENTRY POINT: SYSPARSE, near | ||
| 14 | ; | ||
| 15 | ; INPUT: | ||
| 16 | ; ES - has seg id of the SEGMENT | ||
| 17 | ; that contains the input control blocks, | ||
| 18 | ; defined below. | ||
| 19 | ; | ||
| 20 | ; DI - offset into ES of the PARMS INPUT BLOCK | ||
| 21 | ; | ||
| 22 | ; DS - has seg id of the SEGMENT | ||
| 23 | ; that contains the DOS input COMMAND | ||
| 24 | ; string, which is originally presented at 81h | ||
| 25 | ; in the PSP. | ||
| 26 | ; | ||
| 27 | ; SI - offset into DS of the text of the DOS input COMMAND string | ||
| 28 | ; as originally presented at 81H in the PSP. | ||
| 29 | ; | ||
| 30 | ; DX - zero | ||
| 31 | ; | ||
| 32 | ; CX - ordinal value, intially zero, updated on each subsequent call | ||
| 33 | ; to the value returned in CX on the previous call. | ||
| 34 | ; | ||
| 35 | ; CS - points to the segment containing the | ||
| 36 | ; INCLUDE PARSE.ASM statement | ||
| 37 | ; | ||
| 38 | ; DS - also points to the segment containing the INCLUDE | ||
| 39 | ; PARSE.ASM statement. | ||
| 40 | ; | ||
| 41 | ; EXIT-NORMAL: Output registers: | ||
| 42 | ; AX - return code: | ||
| 43 | ; RC_No_Error equ 0 ; No error | ||
| 44 | ; RC_EOL equ -1 ; End of command line | ||
| 45 | ; | ||
| 46 | ; DX - Offset into ES of the selected RESULT BLOCK. | ||
| 47 | ; BL - terminated delimiter code | ||
| 48 | ; CX - new operand ordinal | ||
| 49 | ; SI - set past scanned operand | ||
| 50 | ; | ||
| 51 | ; EXIT-ERROR: Output registers: | ||
| 52 | ; AX - return code: | ||
| 53 | ; RC_Too_Many equ 1 ; Too many operands | ||
| 54 | ; RC_Op_Missing equ 2 ; Required operand missing | ||
| 55 | ; RC_Not_In_SW equ 3 ; Not in switch list provided | ||
| 56 | ; RC_Not_In_Key equ 4 ; Not in keyword list provided | ||
| 57 | ; RC_Out_Of_Range equ 6 ; Out of range specified | ||
| 58 | ; RC_Not_In_Val equ 7 ; Not in value list provided | ||
| 59 | ; RC_Not_In_Str equ 8 ; Not in string list provided | ||
| 60 | ; RC_Syntax equ 9 ; Syntax error | ||
| 61 | ; | ||
| 62 | ; INTERNAL REFERENCES: | ||
| 63 | ; ROUTINES: SYSPARSE:near (INCLUDEd in PARSE.ASM) | ||
| 64 | ; | ||
| 65 | ; DATA AREAS: none | ||
| 66 | ; | ||
| 67 | ; EXTERNAL REFERENCES: | ||
| 68 | ; ROUTINES: none | ||
| 69 | ; | ||
| 70 | ; DATA AREAS: control blocks pointed to by input registers. | ||
| 71 | ; | ||
| 72 | ; NOTES: | ||
| 73 | ; | ||
| 74 | ; For LINK instructions, refer to the PROLOG of the main module, | ||
| 75 | ; fastopen.asm. | ||
| 76 | ; | ||
| 77 | ; REVISION HISTORY: A000 Version 4.00: add PARSER, System Message Handler, | ||
| 78 | ; | ||
| 79 | ; COPYRIGHT: "MS DOS FASTOPEN Utility" | ||
| 80 | ; "Version 4.00 (C)Copyright 1988 Microsoft " | ||
| 81 | ; "Licensed Material - Property of Microsoft " | ||
| 82 | ; | ||
| 83 | ;PROGRAM AUTHOR: DOS 4.00 P L | ||
| 84 | ; | ||
| 85 | ;****************** END OF SPECIFICATIONS ***************************** | ||
| 86 | IF1 ; ;AN000; | ||
| 87 | %OUT COMPONENT=fastopen, MODULE=fastp.asm... | ||
| 88 | ENDIF ; ;AN000; | ||
| 89 | ; = = = = = = = = = = = = | ||
| 90 | HEADER <MACRO DEFINITION> ; ;AN000; | ||
| 91 | ; = = = = = = = = = = = = | ||
| 92 | |||
| 93 | HEADER MACRO TEXT ;; ;AN000; | ||
| 94 | .XLIST | ||
| 95 | SUBTTL TEXT | ||
| 96 | .LIST | ||
| 97 | PAGE ;; ;AN000; | ||
| 98 | ENDM ;; ;AN000; | ||
| 99 | |||
| 100 | ; = = = = = = = = = = = = | ||
| 101 | HEADER <SYSPARSE - SYSTEM COMMAND LINE PARSER> ; ;AN000; | ||
| 102 | CSEG_INIT SEGMENT PARA PUBLIC 'CODE' ; | ||
| 103 | ASSUME CS:CSEG_INIT,DS:CSEG_INIT,ES:CSEG_INIT | ||
| 104 | |||
| 105 | PUBLIC SYSPARSE ;SUBROUTINE ENTRY POINT ;AN000; | ||
| 106 | |||
| 107 | |||
| 108 | INCSW EQU 1 ;INCLUDE PSDATA.INC ;AN000; | ||
| 109 | FARSW EQU 0 ;CALL THE PARSER BY NEAR CALL | ||
| 110 | DATESW EQU 0 ;SUPPRESS DATE CHECKING ;AN000; | ||
| 111 | TIMESW EQU 0 ;SUPPRESS TIME CHECKING ;AN000; | ||
| 112 | FILESW EQU 0 ;SUPPRESS CHECKING FILE SPECIFICATION ;AN000; | ||
| 113 | CAPSW EQU 0 ;SUPPRESS FILE TABLE CAPS ;AN000; | ||
| 114 | CMPXSW EQU 1 ;SUPPRESS CHECKING COMPLEX LIST | ||
| 115 | DRVSW EQU 1 ;SUPPRESS SUPPORT OF DRIVE ONLY FORMAT | ||
| 116 | QUSSW EQU 0 ;SUPPRESS SUPPORT OF QUOTED STRING FORMAT ;AN000; | ||
| 117 | NUMSW EQU 1 ;SUPPRESS CHECKING NUMERIC VALUE | ||
| 118 | KEYSW EQU 0 ;SUPPRESS KEYWORD SUPPORT ;AN000; | ||
| 119 | SWSW EQU 1 ;DO SUPPORT SWITCHES ;AN000; | ||
| 120 | VAL1SW EQU 0 ;SUPPRESS SUPPORT OF VALUE DEFINITION 1 ;AN000; | ||
| 121 | VAL2SW EQU 0 ;SUPPRESS SUPPORT OF VALUE DEFINITION 2 ;AN000; | ||
| 122 | VAL3SW EQU 0 ;DO SUPPORT VALUE DEFINITION 3 | ||
| 123 | |||
| 124 | |||
| 125 | IF1 ; ;AN000; | ||
| 126 | %OUT COMPONENT=fastopen, SUBCOMPONENT=PARSE, MODULE=PARSE.ASM... | ||
| 127 | %OUT COMPONENT=fastopen, SUBCOMPONENT=PARSE, MODULE=PSDATA.INC... | ||
| 128 | ENDIF ; ;AN000; | ||
| 129 | INCLUDE PARSE.ASM ; ;AN000; | ||
| 130 | CSEG_INIT ENDS ; | ||
| 131 | END ; ;AN000; | ||
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 | ||
diff --git a/v4.0/src/CMD/FASTOPEN/FASTSEGS.INC b/v4.0/src/CMD/FASTOPEN/FASTSEGS.INC new file mode 100644 index 0000000..fd6c46d --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTSEGS.INC | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | .seq | ||
| 5 | stack segment Stack 'STACK' ; represents STACK ;AN000; | ||
| 6 | stack ends ;AN000; | ||
| 7 | |||
| 8 | cseg_main segment Public 'CODE'; represents MAIN | ||
| 9 | cseg_main ends | ||
| 10 | |||
| 11 | cseg_open segment Public 'CODE'; represents FASTOPEN ;AN000; | ||
| 12 | cseg_open ends ;AN000; | ||
| 13 | |||
| 14 | cseg_seek segment Public 'CODE'; represents FASTSEEK ;AN000; | ||
| 15 | cseg_seek ends ;AN000; | ||
| 16 | |||
| 17 | cseg_init segment Public 'CODE' ; represents INIT | ||
| 18 | cseg_init ends | ||
| 19 | |||
| 20 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/FASTOPEN/FASTSM.ASM b/v4.0/src/CMD/FASTOPEN/FASTSM.ASM new file mode 100644 index 0000000..b2dad14 --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/FASTSM.ASM | |||
| @@ -0,0 +1,145 @@ | |||
| 1 | PAGE 90,132 ;A2 | ||
| 2 | TITLE fastsm.SAL - fastopen SYSTEM MESSAGES | ||
| 3 | ;****************** START OF SPECIFICATIONS ***************************** | ||
| 4 | ; MODULE NAME: fastsm.SAL | ||
| 5 | |||
| 6 | ; DESCRIPTIVE NAME: Include the DOS system MESSAGE HANDLER in the SEGMENT | ||
| 7 | ; configuration expected by the modules of fastopen. | ||
| 8 | |||
| 9 | ;FUNCTION: The common code of the DOS SYSTEM MESSAGE HANDLER is made a | ||
| 10 | ; part of the fastopen module by using INCLUDE to bring in the | ||
| 11 | ; common portion, in SYSMSG.INC. This included code contains | ||
| 12 | ; the routines to initialize for message services, to find | ||
| 13 | ; where a particular message is, and to display a message. | ||
| 14 | |||
| 15 | ; ENTRY POINT: SYSDISPMSG:near | ||
| 16 | ; SYSGETMSG:near | ||
| 17 | ; SYSLOADMSG:near | ||
| 18 | |||
| 19 | ; INPUT: | ||
| 20 | ; AX = MESSAGE NUMBER | ||
| 21 | ; BX = HANDLE TO DISPLAY TO (-1 means use DOS functions 1-12) | ||
| 22 | ; SI = OFFSET IN ES: OF SUBLIST, OR 0 IF NONE | ||
| 23 | ; CX = NUMBER OF %PARMS, 0 IF NONE | ||
| 24 | ; DX = CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW | ||
| 25 | ; CALL SYSDISPMSG ;DISPLAY THE MESSAGE | ||
| 26 | |||
| 27 | ; If carry set, extended error already called: | ||
| 28 | ; AX = EXTENDED MESSAGE NUMBER | ||
| 29 | ; BH = ERROR CLASS | ||
| 30 | ; BL = SUGGESTED ACTION | ||
| 31 | ; CH = LOCUS | ||
| 32 | ; _ _ _ _ _ _ _ _ _ _ _ _ | ||
| 33 | |||
| 34 | ; AX = MESSAGE NUMBER | ||
| 35 | ; DH = MESSAGE CLASS (1=DOS EXTENDED ERROR, 2=PARSE ERROR, -1=UTILITY MSG) | ||
| 36 | ; CALL SYSGETMSG ;FIND WHERE A MSG IS | ||
| 37 | |||
| 38 | ; If carry set, error | ||
| 39 | ; CX = 0, MESSAGE NOT FOUND | ||
| 40 | ; If carry not set, ok, and resulting regs are: | ||
| 41 | ; CX = MESSAGE SIZE | ||
| 42 | ; DS:SI = MESSAGE TEXT | ||
| 43 | ; _ _ _ _ _ _ _ _ _ _ _ _ | ||
| 44 | |||
| 45 | ; CALL SYSLOADMSG ;SET ADDRESSABILITY TO MSGS, CHECK DOS VERSION | ||
| 46 | ; If carry not set: | ||
| 47 | ; CX = SIZE OF MSGS LOADED | ||
| 48 | |||
| 49 | ; If carry is set, regs preset up for SYSDISPMSG, as: | ||
| 50 | ; AX = ERROR CODE IF CARRY SET | ||
| 51 | ; AX = 1, INCORRECT DOS VERSION | ||
| 52 | ; DH =-1, (Utility msg) | ||
| 53 | ; OR, | ||
| 54 | ; AX = 1, Error loading messages | ||
| 55 | ; DH = 0, (Message manager error) | ||
| 56 | ; BX = STDERR | ||
| 57 | ; CX = NO_REPLACE | ||
| 58 | ; DL = NO_INPUT | ||
| 59 | |||
| 60 | ; EXIT-NORMAL: CARRY is not set | ||
| 61 | |||
| 62 | ; EXIT-ERROR: CARRY is set | ||
| 63 | ; Call Get Extended Error for reason code, for SYSDISPMSG and | ||
| 64 | ; SYSGETMSG. | ||
| 65 | |||
| 66 | ; INTERNAL REFERENCES: | ||
| 67 | ; ROUTINES: (Generated by the MSG_SERVICES macro) | ||
| 68 | ; SYSLOADMSG | ||
| 69 | ; SYSDISPMSG | ||
| 70 | ; SYSGETMSG | ||
| 71 | |||
| 72 | ; DATA AREAS: | ||
| 73 | |||
| 74 | ; INCLUDE SYSMSG.INC ;Permit System Message handler definition | ||
| 75 | ; | ||
| 76 | ; EXTERNAL REFERENCES: | ||
| 77 | ; ROUTINES: none | ||
| 78 | |||
| 79 | ; DATA AREAS: control blocks pointed to by input registers. | ||
| 80 | |||
| 81 | ; NOTES: | ||
| 82 | |||
| 83 | ; To assemble these modules, the alphabetical or sequential | ||
| 84 | ; ordering of segments may be used. | ||
| 85 | |||
| 86 | ; For LINK instructions, refer to the PROLOG of the main module, | ||
| 87 | ; fastopen.asm. | ||
| 88 | |||
| 89 | ; REVISION HISTORY: A000 Version 4.00: add PARSER, System Message Handler, | ||
| 90 | ; | ||
| 91 | ; COPYRIGHT: "MS DOS FASTOPEN Utility" | ||
| 92 | ; "Version 4.00 (C)Copyright 1988 Microsoft " | ||
| 93 | ; "Licensed Material - Property of Microsoft " | ||
| 94 | ; | ||
| 95 | ;****************** END OF SPECIFICATIONS ***************************** | ||
| 96 | IF1 ; ;AN000; | ||
| 97 | %OUT COMPONENT=fastopen, MODULE=fastsm.asm... | ||
| 98 | ENDIF ; ;AN000; | ||
| 99 | ; = = = = = = = = = = = = | ||
| 100 | |||
| 101 | HEADER MACRO TEXT ;; ;AN000; | ||
| 102 | .XLIST ;; | ||
| 103 | SUBTTL TEXT | ||
| 104 | .LIST ;; | ||
| 105 | PAGE ;; ;AN000; | ||
| 106 | ENDM ;; ;AN000; | ||
| 107 | ; = = = = = = = = = = = = | ||
| 108 | INCLUDE SYSMSG.INC ;PERMIT SYSTEM MESSAGE HANDLER DEFINITION ;AN000; | ||
| 109 | MSG_UTILNAME <fastopen> ;IDENTIFY THE COMPONENT ;AN000; | ||
| 110 | ; = = = = = = = = = = = = | ||
| 111 | HEADER <DEFINITION OF MESSAGES> ; ;AN000; | ||
| 112 | CSEG_INIT SEGMENT PARA PUBLIC 'CODE' ; | ||
| 113 | ASSUME CS:CSEG_INIT ;ESTABLISHED BY CALLER | ||
| 114 | ASSUME DS:CSEG_INIT ;ESTABLISHED BY CALLER | ||
| 115 | ASSUME ES:CSEG_INIT ;ESTABLISHED BY CALLER | ||
| 116 | |||
| 117 | PUBLIC COPYRIGHT ; ;AN000; | ||
| 118 | COPYRIGHT DB "MS DOS FASTOPEN Utility " ; ;AN000; | ||
| 119 | INCLUDE COPYRIGH.INC ; ;AN000; | ||
| 120 | HEADER <MESSAGE DATA AREAS> ; ;AN000; | ||
| 121 | MSG_SERVICES <MSGDATA> ;WORKAREAS FOR SYSTEM MESSAGE HANDLER ;AN000; | ||
| 122 | ; = = = = = = = = = = = = | ||
| 123 | HEADER <SYSTEM MESSAGE HANDLER> ; ;AN000; | ||
| 124 | PUBLIC SYSLOADMSG ; ;AN000; | ||
| 125 | PUBLIC SYSDISPMSG ; ;AN000; | ||
| 126 | |||
| 127 | |||
| 128 | MSG_SERVICES <FASTOPEN.CLA,FASTOPEN.CL1,FASTOPEN.CL2> ; | ||
| 129 | |||
| 130 | ;DEFAULT=CHECK DOS VERSION | ||
| 131 | ;DEFAULT=NEARmsg | ||
| 132 | ;DEFAULT=INPUTmsg | ||
| 133 | ;DEFAULT=NUMmsg | ||
| 134 | ;DEFAULT=NO TIMEmsg | ||
| 135 | ;DEFAULT=NO DATEmsg | ||
| 136 | |||
| 137 | .xlist | ||
| 138 | .xcref | ||
| 139 | MSG_SERVICES <LOADmsg,GETmsg,DISPLAYmsg,INPUTmsg,CHARmsg,NUMmsg> ;AN000; | ||
| 140 | include msgdcl.inc | ||
| 141 | .cref | ||
| 142 | .list | ||
| 143 | ; = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = | ||
| 144 | CSEG_INIT ENDS ; | ||
| 145 | END ; ;AN000; | ||
diff --git a/v4.0/src/CMD/FASTOPEN/MAKEFILE b/v4.0/src/CMD/FASTOPEN/MAKEFILE new file mode 100644 index 0000000..8911afe --- /dev/null +++ b/v4.0/src/CMD/FASTOPEN/MAKEFILE | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #************************** makefile for cmd\... *************************** | ||
| 2 | |||
| 3 | msg =..\..\messages | ||
| 4 | dos =..\..\dos | ||
| 5 | inc =..\..\inc | ||
| 6 | hinc =..\..\h | ||
| 7 | |||
| 8 | # | ||
| 9 | ####################### dependencies begin here. ######################### | ||
| 10 | # | ||
| 11 | |||
| 12 | all: fastopen.exe | ||
| 13 | |||
| 14 | fastopen.ctl: fastopen.skl makefile $(msg)\$(COUNTRY).msg | ||
| 15 | |||
| 16 | fastopen.obj: fastopen.asm $(inc)\fastopen.inc \ | ||
| 17 | makefile | ||
| 18 | |||
| 19 | fastseek.obj: fastseek.asm $(inc)\fastopen.inc \ | ||
| 20 | makefile | ||
| 21 | |||
| 22 | fastinit.obj: fastinit.asm $(inc)\dossym.inc $(inc)\fastopen.inc \ | ||
| 23 | makefile | ||
| 24 | |||
| 25 | fastp.obj: fastp.asm \ | ||
| 26 | makefile \ | ||
| 27 | $(inc)\psdata.inc \ | ||
| 28 | $(inc)\parse.asm | ||
| 29 | |||
| 30 | fastsm.obj: fastsm.asm \ | ||
| 31 | makefile \ | ||
| 32 | $(inc)\versiona.inc \ | ||
| 33 | $(inc)\copyrigh.inc \ | ||
| 34 | $(inc)\sysmsg.inc \ | ||
| 35 | $(inc)\msgserv.asm \ | ||
| 36 | fastopen.ctl \ | ||
| 37 | fastopen.cl1 \ | ||
| 38 | fastopen.cl2 \ | ||
| 39 | fastopen.cla \ | ||
| 40 | |||
| 41 | fastopen.exe: fastopen.obj \ | ||
| 42 | fastopen.lnk \ | ||
| 43 | fastseek.obj \ | ||
| 44 | fastinit.obj \ | ||
| 45 | fastp.obj \ | ||
| 46 | fastsm.obj | ||
| 47 | link @fastopen.lnk | ||