diff options
Diffstat (limited to 'v4.0/src/DOS/BUF.ASM')
| -rw-r--r-- | v4.0/src/DOS/BUF.ASM | 982 |
1 files changed, 982 insertions, 0 deletions
diff --git a/v4.0/src/DOS/BUF.ASM b/v4.0/src/DOS/BUF.ASM new file mode 100644 index 0000000..f6a6b7d --- /dev/null +++ b/v4.0/src/DOS/BUF.ASM | |||
| @@ -0,0 +1,982 @@ | |||
| 1 | ; SCCSID = @(#)buf.asm 1.1 85/04/09 | ||
| 2 | TITLE BUF - MSDOS buffer management | ||
| 3 | NAME BUF | ||
| 4 | ; Low level routines for buffer cache management | ||
| 5 | ; | ||
| 6 | ; GETCURHEAD | ||
| 7 | ; SET_MAP_PAGE | ||
| 8 | ; SAVE_MAP | ||
| 9 | ; RESTORE_MAP | ||
| 10 | ; SETVISIT | ||
| 11 | ; ScanPlace | ||
| 12 | ; PLACEBUF | ||
| 13 | ; PLACEHEAD | ||
| 14 | ; PointComp | ||
| 15 | ; GETBUFFR | ||
| 16 | ; GETBUFFRB | ||
| 17 | ; FlushBuf | ||
| 18 | ; BufWrite | ||
| 19 | ; SKIPVISIT | ||
| 20 | ; SET_RQ_SC_PARMS | ||
| 21 | ; | ||
| 22 | ; Revision history: | ||
| 23 | ; | ||
| 24 | ; AN000 version 4.00 Jan. 1988 | ||
| 25 | ; A004 PTM 3765 -- Disk reset failed | ||
| 26 | |||
| 27 | ; NEW PROCS FOR BUFFERS FIX: | ||
| 28 | |||
| 29 | ; SAVE_USER_MAP | ||
| 30 | ; RESTORE_USER_MAP | ||
| 31 | ; DETECT_COLLISION | ||
| 32 | ; SETUP_EMS_BUFFERS | ||
| 33 | ; | ||
| 34 | |||
| 35 | |||
| 36 | ; | ||
| 37 | ; get the appropriate segment definitions | ||
| 38 | ; | ||
| 39 | .xlist | ||
| 40 | INCLUDE dosseg.asm | ||
| 41 | |||
| 42 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 43 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 44 | |||
| 45 | .xcref | ||
| 46 | INCLUDE DOSSYM.INC | ||
| 47 | INCLUDE DEVSYM.INC | ||
| 48 | include version.inc | ||
| 49 | .cref | ||
| 50 | .list | ||
| 51 | |||
| 52 | Installed = TRUE | ||
| 53 | |||
| 54 | i_need BuffHead,DWORD | ||
| 55 | i_need PreRead,WORD | ||
| 56 | i_need LastBuffer,DWORD | ||
| 57 | i_need CurBuf,DWORD | ||
| 58 | i_need WPErr,BYTE | ||
| 59 | i_need ALLOWED,BYTE | ||
| 60 | i_need FAILERR,BYTE | ||
| 61 | i_need HIGH_SECTOR,WORD ; DOS 4.00 >32mb ;AN000; | ||
| 62 | i_need CurHashEntry,DWORD ; DOS 4.00 current Hash entry ;AN000; | ||
| 63 | i_need BUF_HASH_PTR,DWORD ; DOS 4.00 Hash table pointer ;AN000; | ||
| 64 | i_need BUF_HASH_COUNT,WORD ; DOS 4.00 Hash table entries ;AN000; | ||
| 65 | i_need SC_CACHE_PTR,DWORD ; DOS 4.00 seconadary cache table ;AN000; | ||
| 66 | i_need SC_CACHE_COUNT,WORD ; DOS 4.00 secondary cache entries ;AN000; | ||
| 67 | i_need BUF_EMS_MODE,BYTE ; DOS 4.00 EMS mode ;AN000; | ||
| 68 | i_need BUF_EMS_HANDLE,WORD ; DOS 4.00 buffer EMS handle ;AN000; | ||
| 69 | i_need SC_SECTOR_SIZE,WORD ; DOS 4.00 sector size ;AN000; | ||
| 70 | i_need SC_DRIVE,BYTE ; DOS 4.00 drive ;AN000; | ||
| 71 | i_need ACT_PAGE,WORD ; DOS 4.00 active logical EMS page ;AN000; | ||
| 72 | i_need DOS34_FLAG,WORD ; DOS 4.00 common flag ;AN000; | ||
| 73 | i_need BUF_EMS_SEG_CNT,WORD ; DOS 4.00 EMS seg count ;AN000; | ||
| 74 | i_need BUF_EMS_MAP_BUFF,BYTE ; DOS 4.00 EMS map buffer ;AN000; | ||
| 75 | i_need FIRST_BUFF_ADDR,WORD ; DOS 4.00 beginning of the chain ;AN000; | ||
| 76 | i_need BUF_EMS_PAGE_FRAME,WORD ; DOS 4.00 EMS page frame ;AN000; | ||
| 77 | |||
| 78 | IF BUFFERFLAG | ||
| 79 | i_need BUF_EMS_PFRAME,WORD | ||
| 80 | i_need BUF_EMS_LAST_PAGE,WORD | ||
| 81 | i_need BUF_EMS_FIRST_PAGE,WORD | ||
| 82 | i_need BUF_EMS_SAFE_FLAG,byte | ||
| 83 | i_need BUF_EMS_NPA640,WORD | ||
| 84 | i_need NEXTADD,WORD | ||
| 85 | i_need DMAADD,DWORD | ||
| 86 | i_need BYTCNT1,WORD | ||
| 87 | i_am BUF_EMS_MAP_BUF,12,<0,0,0,0,0,0,0,0,0,0,0,0> | ||
| 88 | i_am CURADD,WORD | ||
| 89 | i_am low_ems_buf,512 | ||
| 90 | extrn SAVE_USER_MAP:near | ||
| 91 | extrn RESTORE_USER_MAP:near | ||
| 92 | ENDIF | ||
| 93 | |||
| 94 | |||
| 95 | Break <GETCURHEAD -- Get current buffer header> | ||
| 96 | |||
| 97 | ; Inputs: | ||
| 98 | ; DX= sector number (LOW) | ||
| 99 | ; [HIGH_SECTOR]= sector number (HIGH) | ||
| 100 | ; Function: | ||
| 101 | ; Hash into a buffer group and activate the extended memory if | ||
| 102 | ; necessary | ||
| 103 | ; Outputs: | ||
| 104 | ; [CurHashEntry] = current Hash entry addr | ||
| 105 | ; DS:DI = 1st buffer addr of the current Hash entry | ||
| 106 | ; No other registers altered | ||
| 107 | |||
| 108 | procedure GETCURHEAD,NEAR | ||
| 109 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 110 | |||
| 111 | PUSH DX ;LB. save regs ;AN000; | ||
| 112 | PUSH AX ;LB. ;AN000; | ||
| 113 | PUSH BX ;LB. ;AN000; | ||
| 114 | MOV AX,DX ;LB. ;AN000; | ||
| 115 | ; MOV DX,[HIGH_SECTOR] ;LB. HASH(sector#) and get entry # ;AN000; | ||
| 116 | XOR DX,DX ;LB. to avoid divide overflow ;AN000; | ||
| 117 | DIV [BUF_HASH_COUNT] ;LB. get remainder ;AN000; | ||
| 118 | ADD DX,DX ;LB. 8 bytes per entry ;AN000; | ||
| 119 | ADD DX,DX ;LB. ;AN000; | ||
| 120 | ADD DX,DX ;LB. times 8 ;AN000; | ||
| 121 | |||
| 122 | LDS DI,[BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; | ||
| 123 | ADD DI,DX ;LB position to entry ;AN000; | ||
| 124 | Map_Entry2: | ||
| 125 | MOV WORD PTR [CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000; | ||
| 126 | MOV WORD PTR [CurHashEntry],DI ;LB. ;AN000; | ||
| 127 | MOV WORD PTR [LASTBUFFER],-1 ;LB. invalidate last buffer ;AN000; | ||
| 128 | MOV BX,[DI.EMS_PAGE_NUM] ;LB. logical page ;AN000; | ||
| 129 | |||
| 130 | IF NOT BUFFERFLAG | ||
| 131 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 132 | MOV [FIRST_BUFF_ADDR],DI ;LB. 1/19/88 save first buffer addr ;AN000; | ||
| 133 | CALL SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 134 | ELSE | ||
| 135 | push ax | ||
| 136 | mov ax, [NEXTADD] | ||
| 137 | mov [CURADD], ax | ||
| 138 | pop ax | ||
| 139 | CALL SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 140 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 141 | MOV [FIRST_BUFF_ADDR],DI ;LB. 1/19/88 save first buffer addr ;AN000; | ||
| 142 | ENDIF | ||
| 143 | |||
| 144 | ;AN000; | ||
| 145 | POP BX ;LB. ;AN000; | ||
| 146 | POP AX ;LB. ;AN000; | ||
| 147 | POP DX ;LB. ;AN000; | ||
| 148 | return ;LB. ;AN000; | ||
| 149 | EndProc GETCURHEAD ;AN000; | ||
| 150 | |||
| 151 | ;AN000; | ||
| 152 | Break <SET_MAP_PAGE - map handle and page > ;AN000; | ||
| 153 | ; Inputs: ;AN000; | ||
| 154 | ; BX= logical page ;AN000; | ||
| 155 | ; Function: ;AN000; | ||
| 156 | ; Map handle and logical page to frame 0 page 0 ;AN000; | ||
| 157 | ; Outputs: ;AN000; | ||
| 158 | ; AH=0 success ;AN000; | ||
| 159 | ; No other registers altered ;AN000; | ||
| 160 | ;AN000; | ||
| 161 | Procedure SET_MAP_PAGE,NEAR ;AN000; | ||
| 162 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 163 | |||
| 164 | ; int 3 | ||
| 165 | ;AN000; | ||
| 166 | CMP [BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 167 | JZ No_map ;LB. no ;AN000; | ||
| 168 | |||
| 169 | IF NOT BUFFERFLAG | ||
| 170 | CMP [ACT_PAGE],BX ;LB. already mapped ? ;AN000; | ||
| 171 | JZ No_map ;LB. yes ;AN000; | ||
| 172 | ENDIF | ||
| 173 | MOV [ACT_PAGE],BX ;LB. save active page mapped ;AN000; | ||
| 174 | |||
| 175 | IF BUFFERFLAG | ||
| 176 | cmp [BUF_EMS_SAFE_FLAG], 1 | ||
| 177 | je no_coll | ||
| 178 | ; int 3 | ||
| 179 | call detect_collision | ||
| 180 | no_coll: | ||
| 181 | ENDIF | ||
| 182 | |||
| 183 | MOV DX,[BUF_EMS_HANDLE] ;LB. ;AN000; | ||
| 184 | MOV AH,44H ;LB. activate current handle ;AN000; | ||
| 185 | MOV AL,BYTE PTR [BUF_EMS_PAGE_FRAME] ;LB. page frame number ;AN000; | ||
| 186 | INT 67H ;LB. ;AN000; | ||
| 187 | No_map: ;AN000; | ||
| 188 | return ;AN000; | ||
| 189 | EndProc SET_MAP_PAGE ;AN000; | ||
| 190 | ;AN000; | ||
| 191 | |||
| 192 | IF BUFFERFLAG | ||
| 193 | |||
| 194 | Break <SAVE_MAP - save map > ;AN000; | ||
| 195 | ; Inputs: ;AN000; | ||
| 196 | ; none ;AN000; | ||
| 197 | ; Function: ;AN000; | ||
| 198 | ; save map ;AN000; | ||
| 199 | ; Outputs: ;AN000; | ||
| 200 | ; none ;AN000; | ||
| 201 | ; No other registers altered ;AN000; | ||
| 202 | ;AN000; | ||
| 203 | Procedure SAVE_MAP,NEAR ;AN000; | ||
| 204 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 205 | ;AN000; | ||
| 206 | CMP [BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 207 | JZ No_save ;LB. no ;AN000; | ||
| 208 | MOV [ACT_PAGE],-1 ;LB. invalidate active page ;AN000; | ||
| 209 | MOV WORD PTR [LASTBUFFER],-1 ;LB. and last buffer pointer ;AN000; | ||
| 210 | PUSH AX ;LB. save regs ;AN000; | ||
| 211 | PUSH DS ;LB. save regs ;AN000; | ||
| 212 | PUSH ES ;LB. ;AN000; | ||
| 213 | PUSH SI ;LB. ;AN000; | ||
| 214 | PUSH DI ;LB. ;AN000; | ||
| 215 | MOV SI,OFFSET DOSGROUP:BUF_EMS_SEG_CNT ;LB. ;AN000; | ||
| 216 | MOV DI,OFFSET DOSGROUP:BUF_EMS_MAP_BUF ;LB. ;AN000; | ||
| 217 | |||
| 218 | PUSH CS | ||
| 219 | POP ES | ||
| 220 | PUSH CS ;LB. ;AN000; | ||
| 221 | POP DS ;LB. ds:si -> ems seg count ;AN000; | ||
| 222 | |||
| 223 | MOV AX,4F00H ;LB. save map ;AN000; | ||
| 224 | EnterCrit critDisk ;LB. enter critical section ;AN000; | ||
| 225 | INT 67H ;LB. ;AN000; | ||
| 226 | LeaveCrit critDisk ;LB. leave critical section ;AN000; | ||
| 227 | POP DI ;LB. ;AN000; | ||
| 228 | POP SI ;LB. restore regs ;AN000; | ||
| 229 | POP ES ;LB. ;AN000; | ||
| 230 | POP DS ;LB. ;AN000; | ||
| 231 | POP AX ;LB. restore ;AN000; | ||
| 232 | No_save: ;AN000; | ||
| 233 | return ;AN000; | ||
| 234 | EndProc SAVE_MAP ;AN000; | ||
| 235 | ;AN000; | ||
| 236 | |||
| 237 | Break <RESTORE_MAP- retore map > ;AN000; | ||
| 238 | ; Inputs: ;AN000; | ||
| 239 | ; none ;AN000; | ||
| 240 | ; Function: ;AN000; | ||
| 241 | ; restore_map ;AN000; | ||
| 242 | ; Outputs: ;AN000; | ||
| 243 | ; none ;AN000; | ||
| 244 | ; No other registers altered ;AN000; | ||
| 245 | ;AN000; | ||
| 246 | Procedure RESTORE_MAP,NEAR ;AN000; | ||
| 247 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 248 | ;AN000; | ||
| 249 | CMP [BUF_EMS_MODE],-1 ;LB. EMS support ;AN000; | ||
| 250 | JZ No_restore ;LB. no ;AN000; | ||
| 251 | PUSH AX ;LB. save regs ;AN000; | ||
| 252 | PUSH DS ;LB. save regs ;AN000; | ||
| 253 | PUSH SI ;LB. ;AN000; | ||
| 254 | MOV SI,OFFSET DOSGROUP:BUF_EMS_MAP_BUF ;LB. ;AN000; | ||
| 255 | |||
| 256 | PUSH CS | ||
| 257 | POP DS | ||
| 258 | MOV AX,4F01H ;LB. restore map ;AN000; | ||
| 259 | EnterCrit critDisk ;LB. enter critical section ;AN000; | ||
| 260 | INT 67H ;LB. ;AN000; | ||
| 261 | LeaveCrit critDisk ;LB. leave critical section ;AN000; | ||
| 262 | POP SI ;LB. restore regs ;AN000; | ||
| 263 | POP DS ;LB. ;AN000; | ||
| 264 | POP AX ;LB. ;AN000; | ||
| 265 | No_restore: ;AN000; | ||
| 266 | return ;AN000; | ||
| 267 | EndProc RESTORE_MAP ;AN000; | ||
| 268 | |||
| 269 | ENDIF | ||
| 270 | ;AN000; | ||
| 271 | ;AN000; | ||
| 272 | |||
| 273 | Break <SCANPLACE, PLACEBUF -- PUT A BUFFER BACK IN THE POOL> | ||
| 274 | |||
| 275 | ; Inputs: | ||
| 276 | ; Same as PLACEBUF | ||
| 277 | ; Function: | ||
| 278 | ; Save scan location and call PLACEBUF | ||
| 279 | ; Outputs: | ||
| 280 | ; DS:DI Points to saved scan location | ||
| 281 | ; SI destroyed, other registers unchanged | ||
| 282 | |||
| 283 | procedure ScanPlace,near | ||
| 284 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 285 | |||
| 286 | ;; PUSH ES | ||
| 287 | ;; LES SI,[DI.buf_link] ; Save scan location | ||
| 288 | MOV SI,[DI.buf_next] ; Save scan location | ||
| 289 | CALL PLACEBUF | ||
| 290 | ;; PUSH ES | ||
| 291 | ;; POP DS ; Restore scan location | ||
| 292 | MOV DI,SI | ||
| 293 | ;; POP ES | ||
| 294 | return | ||
| 295 | EndProc ScanPlace | ||
| 296 | |||
| 297 | ; Rewritten PLACEBUF (LKR), eliminates loops | ||
| 298 | ; | ||
| 299 | ; Input: | ||
| 300 | ; DS:DI points to buffer (DS->BUFFINFO array, DI=offset in array) | ||
| 301 | ; Function: | ||
| 302 | ; Remove buffer from queue and re-insert it in proper place. | ||
| 303 | ; NO registers altered | ||
| 304 | |||
| 305 | procedure PLACEBUF,NEAR | ||
| 306 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 307 | |||
| 308 | ; invoke save_world | ||
| 309 | push AX ;Save only regs we modify ;AN000; | ||
| 310 | push BX ;AN000; | ||
| 311 | push SI ;AN000; | ||
| 312 | push ES ;AN000; | ||
| 313 | |||
| 314 | les SI,[CurHashEntry] ;ES:SI -> Current Hash entry ;AN000; | ||
| 315 | mov BX,word ptr ES:[SI.BUFFER_BUCKET] ;BX = offset of head of list ;AN000; | ||
| 316 | |||
| 317 | cmp [DI.buf_next],BX ;Buf = last? ;AN000; | ||
| 318 | je nret ;Yes, special case ;AN000; | ||
| 319 | cmp DI,BX ;Buf = first? ;AN000; | ||
| 320 | je bufloop ;Yes, special case ;AN000; | ||
| 321 | mov SI,[DI.buf_prev] ;No, SI = prior Buf ;AN000; | ||
| 322 | mov AX,[DI.buf_next] ;Now delete Buf from list ;AN000; | ||
| 323 | mov [SI.buf_next],AX ;AN000; | ||
| 324 | push SI ;Save si ;AN000; | ||
| 325 | mov SI,[DI.buf_next] ;Update backward pointer ;AN000; | ||
| 326 | mov AX,[DI.buf_prev] ; ;AN000; | ||
| 327 | mov [SI.buf_prev],AX ; ;AN000; | ||
| 328 | pop si ;Restore si ;AN000; | ||
| 329 | lookend: ;(label is now a misnomer) ;AN000; | ||
| 330 | mov SI,[BX.buf_prev] ;SI-> last buffer ;AN000; | ||
| 331 | mov [SI.buf_next],DI ;Add Buf to end of list ;AN000; | ||
| 332 | mov [BX.buf_prev],DI ;AN000; | ||
| 333 | mov [DI.buf_prev],SI ;Update linkage in Buf too ;AN000; | ||
| 334 | mov [DI.buf_next],BX ;AN000; | ||
| 335 | nret: ;AN000; | ||
| 336 | ;AN000; | ||
| 337 | ; invoke restore_world ;AN000; | ||
| 338 | pop ES ;Restore regs we modified ;AN000; | ||
| 339 | pop SI ;AN000; | ||
| 340 | pop BX ;AN000; | ||
| 341 | pop AX ;AN000; | ||
| 342 | ;AN000; | ||
| 343 | cmp [DI.buf_ID],-1 ; Buffer FREE? ;AN000; | ||
| 344 | retnz ; No ;AN000; | ||
| 345 | invoke PLACEHEAD ; Buffer is free, belongs at hea;AN000; | ||
| 346 | return ;AN000; | ||
| 347 | bufloop: ;(label is now a misnomer) ;AN000; | ||
| 348 | mov BX,[DI.buf_next] ;Set new head position ;AN000; | ||
| 349 | mov word ptr ES:[SI.BUFFER_BUCKET],BX ;AN000; | ||
| 350 | jmp nret ;Continue with repositioning ;AN000; | ||
| 351 | |||
| 352 | EndProc PLACEBUF | ||
| 353 | |||
| 354 | ; SAME AS PLACEBUF except places buffer at head | ||
| 355 | ; NOTE:::::: ASSUMES THAT BUFFER IS CURRENTLY THE LAST | ||
| 356 | ; ONE IN THE LIST!!!!!!! | ||
| 357 | ; Rewritten PLACEBUF, takes buffer from end of list to head of list | ||
| 358 | |||
| 359 | procedure PLACEHEAD,NEAR ;AN000; | ||
| 360 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 361 | push ES ;AN000; | ||
| 362 | push SI ;AN000; | ||
| 363 | les SI,[CurHashEntry] ;AN000; | ||
| 364 | mov word ptr ES:[SI.BUFFER_BUCKET],DI ;AN000; | ||
| 365 | pop SI ;AN000; | ||
| 366 | pop ES ;AN000; | ||
| 367 | return ;AN000; | ||
| 368 | EndProc PLACEHEAD ;AN000; | ||
| 369 | |||
| 370 | |||
| 371 | Break <POINTCOMP -- 20 BIT POINTER COMPARE> | ||
| 372 | |||
| 373 | ; Compare DS:SI to ES:DI (or DS:DI to ES:SI) for equality | ||
| 374 | ; DO NOT USE FOR < or > | ||
| 375 | ; No Registers altered | ||
| 376 | |||
| 377 | procedure PointComp,NEAR | ||
| 378 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 379 | |||
| 380 | CMP SI,DI | ||
| 381 | retnz | ||
| 382 | PUSH CX | ||
| 383 | PUSH DX | ||
| 384 | MOV CX,DS | ||
| 385 | MOV DX,ES | ||
| 386 | CMP CX,DX | ||
| 387 | POP DX | ||
| 388 | POP CX | ||
| 389 | return | ||
| 390 | EndProc PointComp | ||
| 391 | |||
| 392 | Break <GETBUFFR -- GET A SECTOR INTO A BUFFER> | ||
| 393 | |||
| 394 | ; Input: | ||
| 395 | ; AL = 0 means sector must be pre-read | ||
| 396 | ; ELSE no pre-read | ||
| 397 | ; DX = Desired physical sector number (LOW) | ||
| 398 | ; [HIGH_SECTOR]= Desired physical sector number (HIGH) | ||
| 399 | ; ES:BP = Pointer to drive parameters | ||
| 400 | ; [ALLOWED] set in case of INT 24 | ||
| 401 | ; Function: | ||
| 402 | ; Get the specified local sector into one of the I/O buffers | ||
| 403 | ; And shuffle the queue | ||
| 404 | ; Output: | ||
| 405 | ; [CURBUF] Points to the Buffer for the sector | ||
| 406 | ; THE BUFFER TYPE FIELD OF buf_flags = 0, caller must set it | ||
| 407 | ; Carry set if error (currently user FAILed to INT 24) | ||
| 408 | ; DS,DX,ES:BP unchanged, all other registers destroyed | ||
| 409 | |||
| 410 | procedure GETBUFFR,NEAR | ||
| 411 | DOSAssume CS,<DS>,"GetBuffr" | ||
| 412 | ASSUME ES:NOTHING | ||
| 413 | |||
| 414 | XOR SI,SI | ||
| 415 | |||
| 416 | entry GETBUFFRB | ||
| 417 | |||
| 418 | Assert ISDPB,<ES,BP>,"GetBuffr" | ||
| 419 | MOV [PREREAD],AX | ||
| 420 | MOV AL,ES:[BP.dpb_drive] | ||
| 421 | LDS DI,[LASTBUFFER] | ||
| 422 | ASSUME DS:NOTHING | ||
| 423 | MOV CX,[HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 424 | CMP DI,-1 ; Recency pointer valid? | ||
| 425 | JZ SKBUF ; No | ||
| 426 | |||
| 427 | CMP DX,WORD PTR [DI.buf_sector] | ||
| 428 | JNZ SKBUF ; Wrong sector | ||
| 429 | CMP CX,WORD PTR [DI.buf_sector+2] ; F.C. >32mb ;AN000; | ||
| 430 | JNZ SKBUF ; F.C. >32mb ;AN000; | ||
| 431 | CMP AL,[DI.buf_ID] | ||
| 432 | JNZ SKBUF ; Wrong Drive | ||
| 433 | |||
| 434 | JMP JUSTBUF ; Just asked for same buffer | ||
| 435 | SKBUF: | ||
| 436 | CALL GETCURHEAD ;LB. get cuurent Hash entry ;AN000; | ||
| 437 | ; LDS DI,[BUFFHEAD] | ||
| 438 | NXTBFF: | ||
| 439 | CMP DX,WORD PTR [DI.buf_sector] ; F.C. >32mb ;AN000; | ||
| 440 | JNZ BUMP | ||
| 441 | CMP CX,WORD PTR [DI.buf_sector+2] ; F.C. >32mb ;AN000; | ||
| 442 | JNZ BUMP ; F.C. >32mb ;AN000; | ||
| 443 | CMP AL,[DI.buf_ID] | ||
| 444 | if not bufferflag | ||
| 445 | JZ SETINF | ||
| 446 | else | ||
| 447 | jnz bump | ||
| 448 | jmp setinf | ||
| 449 | endif | ||
| 450 | BUMP: | ||
| 451 | mov DI,[DI.buf_next] ;;;;;;1/19/88 ;AN000; | ||
| 452 | cmp DI,[FIRST_BUFF_ADDR] ;;;;;;1/19/88 ;AN000; | ||
| 453 | JNZ NXTBFF | ||
| 454 | ;;;; LDS DI,[CurHashEntry] ;LB. secondary cache's use ;AN000; | ||
| 455 | ;;;; LDS DI,[DI.BUFFER_BUCKET] ;LB. ;AN000; | ||
| 456 | ; LDS DI,[BUFFHEAD] | ||
| 457 | PUSH [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 458 | PUSH SI | ||
| 459 | PUSH DX | ||
| 460 | PUSH BP | ||
| 461 | PUSH ES | ||
| 462 | CALL BUFWRITE ; Write out the dirty buffer | ||
| 463 | POP ES | ||
| 464 | POP BP | ||
| 465 | POP DX | ||
| 466 | POP SI | ||
| 467 | POP [HIGH_SECTOR] ;F.C. >32mb ;AN000; | ||
| 468 | if not bufferflag | ||
| 469 | JC GETBERR | ||
| 470 | else | ||
| 471 | jnc skip_getberr | ||
| 472 | jmp getberr | ||
| 473 | skip_getberr: | ||
| 474 | endif | ||
| 475 | CALL SET_RQ_SC_PARMS ;LB. set parms ;AN000; | ||
| 476 | XOR AH,AH ; initial flags | ||
| 477 | TEST BYTE PTR [PREREAD],-1 ; Read in the new sector | ||
| 478 | JNZ SETBUF | ||
| 479 | LEA BX,[DI.BufInSiz] ; Point at buffer | ||
| 480 | MOV CX,1 | ||
| 481 | PUSH SI | ||
| 482 | PUSH DI | ||
| 483 | PUSH DX | ||
| 484 | ; Note: As far as I can tell, all disk reads into buffers go through this point. -mrw 10/88 | ||
| 485 | if bufferflag | ||
| 486 | ; int 3 | ||
| 487 | cmp [buf_ems_mode], -1 | ||
| 488 | jz normread | ||
| 489 | push bx | ||
| 490 | push ds ; save ds:bx --> ems_buffer | ||
| 491 | push cs | ||
| 492 | pop ds | ||
| 493 | mov bx, offset dosgroup:low_ems_buf ; ds:bx --> low_ems_buffer | ||
| 494 | normread: | ||
| 495 | endif | ||
| 496 | OR SI,SI | ||
| 497 | JZ NORMSEC | ||
| 498 | invoke FATSECRD | ||
| 499 | MOV AH,buf_isFAT ; Set buf_flags | ||
| 500 | JMP SHORT GOTTHESEC ; Buffer is marked free if read barfs | ||
| 501 | NORMSEC: | ||
| 502 | invoke DREAD ; Buffer is marked free if read barfs | ||
| 503 | MOV AH,0 ; Set buf_flags to no type, DO NOT XOR! | ||
| 504 | GOTTHESEC: ; Carry set by either FATSECRD or DREAD | ||
| 505 | if bufferflag | ||
| 506 | pushf | ||
| 507 | jc skipreadtrans | ||
| 508 | cmp [buf_ems_mode], -1 | ||
| 509 | je skipreadtrans | ||
| 510 | |||
| 511 | popf | ||
| 512 | pop ds | ||
| 513 | pop bx ; restore ems_buffer pointer | ||
| 514 | pushf | ||
| 515 | |||
| 516 | push cx ; save regs to be used by rep mov | ||
| 517 | push ds | ||
| 518 | push es | ||
| 519 | |||
| 520 | mov di, bx | ||
| 521 | push ds | ||
| 522 | pop es ; es:di --> ems_buf | ||
| 523 | mov si, offset dosgroup:low_ems_buf | ||
| 524 | push cs | ||
| 525 | pop ds ; ds:si --> low_ems_buf | ||
| 526 | mov cx, 512/2 | ||
| 527 | rep movsw | ||
| 528 | |||
| 529 | pop es ; restore regs. | ||
| 530 | pop ds | ||
| 531 | pop cx | ||
| 532 | skipreadtrans: | ||
| 533 | popf | ||
| 534 | endif | ||
| 535 | POP DX | ||
| 536 | POP DI | ||
| 537 | POP SI | ||
| 538 | JC GETBERR | ||
| 539 | SETBUF: | ||
| 540 | MOV CX,[HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 541 | MOV WORD PTR [DI.buf_sector+2],CX ; F.C. >32mb ;AN000; | ||
| 542 | MOV WORD PTR [DI.buf_sector],DX ; F.C. >32mb ;AN000; | ||
| 543 | MOV WORD PTR [DI.buf_DPB],BP | ||
| 544 | MOV WORD PTR [DI.buf_DPB+2],ES | ||
| 545 | MOV AL,ES:[BP.dpb_drive] | ||
| 546 | MOV WORD PTR [DI.buf_ID],AX ; Sets buf_flags too, to AH | ||
| 547 | SETINF: | ||
| 548 | MOV [DI.buf_wrtcnt],1 ; Default to not a FAT sector ;AC000; | ||
| 549 | XOR AX,AX ;>32mb ;AN000; | ||
| 550 | OR SI,SI | ||
| 551 | JZ SETSTUFFOK | ||
| 552 | MOV AL,ES:[BP.dpb_FAT_count] | ||
| 553 | MOV [DI.buf_wrtcnt],AL ;>32mb ;AN000; | ||
| 554 | MOV AX,ES:[BP.dpb_FAT_size] | ||
| 555 | SETSTUFFOK: | ||
| 556 | MOV [DI.buf_wrtcntinc],AX ;>32mb ;AC000; | ||
| 557 | CALL PLACEBUF | ||
| 558 | JUSTBUF: | ||
| 559 | MOV WORD PTR [CURBUF+2],DS | ||
| 560 | MOV WORD PTR [LASTBUFFER+2],DS | ||
| 561 | MOV WORD PTR [CURBUF],DI | ||
| 562 | MOV WORD PTR [LASTBUFFER],DI | ||
| 563 | CLC | ||
| 564 | GETBERR: | ||
| 565 | Context DS | ||
| 566 | return | ||
| 567 | EndProc GETBUFFR | ||
| 568 | |||
| 569 | Break <FLUSHBUF -- WRITE OUT DIRTY BUFFERS> | ||
| 570 | |||
| 571 | ; Input: | ||
| 572 | ; DS = DOSGROUP | ||
| 573 | ; AL = Physical unit number local buffers only | ||
| 574 | ; = -1 for all units and all remote buffers | ||
| 575 | ; Function: | ||
| 576 | ; Write out all dirty buffers for unit, and flag them as clean | ||
| 577 | ; Carry set if error (user FAILed to I 24) | ||
| 578 | ; Flush operation completed. | ||
| 579 | ; DS Preserved, all others destroyed (ES too) | ||
| 580 | |||
| 581 | procedure FlushBuf,NEAR | ||
| 582 | DOSAssume CS,<DS>,"FlushBuf" | ||
| 583 | ASSUME ES:NOTHING | ||
| 584 | |||
| 585 | MOV AH,-1 | ||
| 586 | ; LDS DI,[BUFFHEAD] | ||
| 587 | ASSUME DS:NOTHING | ||
| 588 | |||
| 589 | LDS DI,[BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; | ||
| 590 | MOV CX,[BUF_HASH_COUNT] ;LB. get Hash entry count ;AN000; | ||
| 591 | XOR DX,DX ;LB. set initial index to 0 ;AN000; | ||
| 592 | |||
| 593 | NXTBUFF2: | ||
| 594 | PUSH CX ;LB. save Hash entry count ;AN000; | ||
| 595 | TEST [DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ;AN004; | ||
| 596 | JNZ Zapzap ;MS. yes ;AN004; | ||
| 597 | CMP [DI.Dirty_Count],0 ;LB. dirty entry ? ;AN000; | ||
| 598 | JZ getnext ;LB. no ;AN000; | ||
| 599 | Zapzap: ;AN004; | ||
| 600 | PUSH DS ;LB. save regs ;AN000; | ||
| 601 | PUSH DI ;LB. ;AN000; | ||
| 602 | invoke Map_Entry ;LB. ds:di -> first buffer addr ;AN000; | ||
| 603 | NXTBUFF: | ||
| 604 | CALL CHECKFLUSH ; Ignore Carry return from CHECKFLUSH. | ||
| 605 | ; FAILERR is set if user FAILed. | ||
| 606 | PUSH AX | ||
| 607 | MOV AL,[DI.buf_ID] | ||
| 608 | CMP AL,BYTE PTR [WPERR] | ||
| 609 | JZ ZAP | ||
| 610 | TEST [DOS34_FLAG],FROM_DISK_RESET ;MS. from disk reset ;AN000; | ||
| 611 | JNZ Zap ;MS. yes ;AN000; | ||
| 612 | |||
| 613 | NOZAP: | ||
| 614 | POP AX | ||
| 615 | mov DI,[DI.buf_next] ;;;;1/19/88 ;AN000; | ||
| 616 | CMP DI,[FIRST_BUFF_ADDR] ;;;;1/19/88 ;AN000; | ||
| 617 | JNZ NXTBUFF | ||
| 618 | |||
| 619 | POP DI ;LB. ;AN000; | ||
| 620 | POP DS ;LB. ;AN000; | ||
| 621 | getnext: | ||
| 622 | ADD DI,size BUFFER_HASH_ENTRY ;LB. position to next entry ;AN000; | ||
| 623 | POP CX ;LB. restore entry count ;AN000; | ||
| 624 | LOOP NXTBUFF2 ;LB. get next entry buffer ;AN000; | ||
| 625 | Context DS | ||
| 626 | CMP [FAILERR],0 | ||
| 627 | JNZ FLSHBad ; Carry clear if JMP | ||
| 628 | return | ||
| 629 | FlshBad: | ||
| 630 | STC ; Return error if user FAILed | ||
| 631 | return | ||
| 632 | Zap: | ||
| 633 | MOV WORD PTR [DI.buf_ID],00FFH ; Invalidate buffer, it is inconsistent | ||
| 634 | JMP NoZap | ||
| 635 | |||
| 636 | EndProc FlushBuf | ||
| 637 | |||
| 638 | procedure CHECKFLUSH,NEAR | ||
| 639 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 640 | ; Carry set if problem (currently user FAILed to I 24) | ||
| 641 | |||
| 642 | Assert ISBUF,<DS,DI>,"CheckFlush" | ||
| 643 | CMP [DI.buf_ID],AH | ||
| 644 | retz ; Skip free buffers, carry clear | ||
| 645 | CMP AH,AL | ||
| 646 | JZ DOBUFFER ; Do all dirty buffers | ||
| 647 | CMP AL,[DI.buf_ID] | ||
| 648 | CLC | ||
| 649 | retnz ; Buffer not for this unit or SFT | ||
| 650 | DOBUFFER: | ||
| 651 | TEST [DI.buf_flags],buf_dirty | ||
| 652 | retz ; Buffer not dirty, carry clear by TEST | ||
| 653 | PUSH AX | ||
| 654 | PUSH WORD PTR [DI.buf_ID] | ||
| 655 | CALL BUFWRITE | ||
| 656 | POP AX | ||
| 657 | JC LEAVE_BUF ; Leave buffer marked free (lost). | ||
| 658 | AND AH,NOT buf_dirty ; Buffer is clean, clears carry | ||
| 659 | MOV WORD PTR [DI.buf_ID],AX | ||
| 660 | LEAVE_BUF: | ||
| 661 | POP AX ; Search info | ||
| 662 | return | ||
| 663 | EndProc CHECKFLUSH | ||
| 664 | |||
| 665 | Break <BUFWRITE -- WRITE OUT A BUFFER IF DIRTY> | ||
| 666 | |||
| 667 | ; Input: | ||
| 668 | ; DS:DI Points to the buffer | ||
| 669 | ; Function: | ||
| 670 | ; Write out all the buffer if dirty. | ||
| 671 | ; Output: | ||
| 672 | ; Buffer marked free | ||
| 673 | ; Carry set if error (currently user FAILed to I 24) | ||
| 674 | ; DS:DI Preserved, ALL others destroyed (ES too) | ||
| 675 | |||
| 676 | procedure BufWrite,NEAR | ||
| 677 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 678 | |||
| 679 | Assert ISBUF,<DS,DI>,"BufWrite" | ||
| 680 | MOV AX,00FFH | ||
| 681 | XCHG AX,WORD PTR [DI.buf_ID] ; Free, in case write barfs | ||
| 682 | CMP AL,0FFH | ||
| 683 | retz ; Buffer is free, carry clear. | ||
| 684 | TEST AH,buf_dirty | ||
| 685 | retz ; Buffer is clean, carry clear. | ||
| 686 | invoke DEC_DIRTY_COUNT ; LB. decrement dirty count | ||
| 687 | CMP AL,BYTE PTR [WPERR] | ||
| 688 | retz ; If in WP error zap buffer | ||
| 689 | MOV [SC_DRIVE],AL ;LB. set it for invalidation ;AN000; | ||
| 690 | LES BP,[DI.buf_DPB] | ||
| 691 | LEA BX,[DI.BufInSiz] ; Point at buffer | ||
| 692 | MOV DX,WORD PTR [DI.buf_sector] ;F.C. >32mb ;AN000; | ||
| 693 | MOV CX,WORD PTR [DI.buf_sector+2] ;F.C. >32mb ;AN000; | ||
| 694 | MOV [HIGH_SECTOR],CX ;F.C. >32mb ;AN000; | ||
| 695 | MOV CL,[DI.buf_wrtcnt] ;>32mb ;AC000; | ||
| 696 | ; MOV AL,CH ; [DI.buf_wrtcntinc] | ||
| 697 | XOR CH,CH | ||
| 698 | MOV AX,[DI.buf_wrtcntinc] ;>32mb ;AC000; | ||
| 699 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL | ||
| 700 | TEST [DI.buf_flags],buf_isDATA | ||
| 701 | JZ NO_IGNORE | ||
| 702 | OR [ALLOWED],allowed_IGNORE | ||
| 703 | NO_IGNORE: | ||
| 704 | PUSH DI ; Save buffer pointer | ||
| 705 | XOR DI,DI ; Indicate failure | ||
| 706 | WRTAGAIN: | ||
| 707 | SaveReg <DI,CX,AX> | ||
| 708 | MOV CX,1 | ||
| 709 | SaveReg <BX,DX,DS> | ||
| 710 | ; Note: As far as I can tell, all disk reads into buffers go through this point. -mrw 10/88 | ||
| 711 | |||
| 712 | if bufferflag | ||
| 713 | ; int 3 | ||
| 714 | cmp [buf_ems_mode], -1 | ||
| 715 | jz skipwritetrans | ||
| 716 | |||
| 717 | push es | ||
| 718 | push di | ||
| 719 | push si | ||
| 720 | push cx | ||
| 721 | |||
| 722 | mov si, bx ; ds:si --> ems_buffer | ||
| 723 | mov di, offset dosgroup:low_ems_buf | ||
| 724 | push cs | ||
| 725 | pop es ; es:di --> low_ems_buffer | ||
| 726 | mov cx, 512/2 | ||
| 727 | rep movsw | ||
| 728 | |||
| 729 | pop cx | ||
| 730 | pop si | ||
| 731 | pop di | ||
| 732 | pop es | ||
| 733 | |||
| 734 | push ds | ||
| 735 | push bx | ||
| 736 | mov bx, offset dosgroup:low_ems_buf | ||
| 737 | push cs | ||
| 738 | pop ds ; ds:bx --> low_ems_buffer | ||
| 739 | skipwritetrans: | ||
| 740 | endif | ||
| 741 | |||
| 742 | invoke DWRITE ; Write out the dirty buffer | ||
| 743 | |||
| 744 | if bufferflag | ||
| 745 | pushf ; save carry flag from DWRITE | ||
| 746 | cmp [buf_ems_mode], -1 | ||
| 747 | jz normwrite | ||
| 748 | popf ; need to get at stack | ||
| 749 | pop bx ; ds:bx --> ems_buffer | ||
| 750 | pop ds | ||
| 751 | pushf ; put it back, so we can pop it | ||
| 752 | normwrite: | ||
| 753 | popf ; restore carry flag | ||
| 754 | endif | ||
| 755 | |||
| 756 | RestoreReg <DS,DX,BX> | ||
| 757 | RestoreReg <AX,CX,DI> | ||
| 758 | JC NOSET | ||
| 759 | INC DI ; If at least ONE write succeedes, the operation | ||
| 760 | NOSET: ; succeedes. | ||
| 761 | ADD DX,AX | ||
| 762 | LOOP WRTAGAIN | ||
| 763 | OR DI,DI ; Clears carry | ||
| 764 | JNZ BWROK ; At least one write worked | ||
| 765 | STC ; DI never got INCed, all writes failed. | ||
| 766 | BWROK: | ||
| 767 | POP DI | ||
| 768 | return | ||
| 769 | EndProc BufWrite | ||
| 770 | |||
| 771 | Break <SET_RQ_SC_PARMS-set requesting drive for SC> | ||
| 772 | |||
| 773 | ; Input: | ||
| 774 | ; ES:BP = drive parameter block | ||
| 775 | ; Function: | ||
| 776 | ; Set requesting drive, and sector size | ||
| 777 | ; Output: | ||
| 778 | ; [SC_SECTOR_SIZE]= drive sector size | ||
| 779 | ; [SC_DRIVE]= drive # | ||
| 780 | ; | ||
| 781 | ; All registers preserved | ||
| 782 | |||
| 783 | procedure SET_RQ_SC_PARMS,NEAR | ||
| 784 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 785 | |||
| 786 | CMP [SC_CACHE_COUNT],0 ;LB. do it only secondary cache exists ;AN000; | ||
| 787 | JZ nosec ;LB. ;AN000; | ||
| 788 | PUSH DX ;LB. save dx ;AN000; | ||
| 789 | MOV DX,ES:[BP.dpb_sector_size] ;LB. save sector size ;AN000; | ||
| 790 | MOV [SC_SECTOR_SIZE],DX ;LB. ;AN000; | ||
| 791 | MOV DL,ES:[BP.dpb_drive] ;LB. save drive # ;AN000; | ||
| 792 | MOV [SC_DRIVE],DL ;LB. ;AN000; | ||
| 793 | ;AN000; | ||
| 794 | POP DX ;LB. restore dx ;AN000; | ||
| 795 | |||
| 796 | nosec: | ||
| 797 | return | ||
| 798 | EndProc SET_RQ_SC_PARMS ;LB. return ;AN000; | ||
| 799 | |||
| 800 | Break <INC_DIRTY_COUNT-increment dirty count> | ||
| 801 | |||
| 802 | ; Input: | ||
| 803 | ; none | ||
| 804 | ; Function: | ||
| 805 | ; increment dirty buffers count | ||
| 806 | ; Output: | ||
| 807 | ; dirty buffers count in the current hash entry is incremented | ||
| 808 | ; | ||
| 809 | ; All registers preserved | ||
| 810 | |||
| 811 | procedure INC_DIRTY_COUNT,NEAR | ||
| 812 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 813 | |||
| 814 | PUSH DS ;LB. save regs ;AN000; | ||
| 815 | PUSH SI ;LB. ;AN000; | ||
| 816 | LDS SI,[CurHashEntry] ;LB. get current hash entry ;AN000; | ||
| 817 | INC [SI.Dirty_Count] ;LB. add 1 ;AN000; | ||
| 818 | POP SI ;LB. restore regs ;AN000; | ||
| 819 | POP DS ;LB. ;AN000; | ||
| 820 | return | ||
| 821 | EndProc INC_DIRTY_COUNT ;LB. return ;AN000; | ||
| 822 | |||
| 823 | Break <DEC_DIRTY_COUNT-decrement dirty count> | ||
| 824 | |||
| 825 | ; Input: | ||
| 826 | ; none | ||
| 827 | ; Function: | ||
| 828 | ; decrement dirty buffers count | ||
| 829 | ; Output: | ||
| 830 | ; dirty buffers count in the current hash entry is decremented | ||
| 831 | ; | ||
| 832 | ; All registers preserved | ||
| 833 | |||
| 834 | procedure DEC_DIRTY_COUNT,NEAR | ||
| 835 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 836 | |||
| 837 | PUSH DS ;LB. save regs ;AN000; | ||
| 838 | PUSH SI ;LB. ;AN000; | ||
| 839 | LDS SI,[CurHashEntry] ;LB. get current hash entry ;AN000; | ||
| 840 | CMP [SI.Dirty_Count],0 ;LB. in case if 0 ;AN000; | ||
| 841 | JZ nodec ;LB. do nothing ;AN000; | ||
| 842 | DEC [SI.Dirty_Count] ;LB. sub 1 ;AN000; | ||
| 843 | nodec: | ||
| 844 | POP SI ;LB. restore regs ;AN000; | ||
| 845 | POP DS ;LB. ;AN000; | ||
| 846 | return | ||
| 847 | EndProc DEC_DIRTY_COUNT ;LB. return ;AN000; | ||
| 848 | |||
| 849 | |||
| 850 | Break <MAP_ENTRY- map the buffers of this entry> | ||
| 851 | |||
| 852 | ; Input: | ||
| 853 | ; DS:DI ponits to hash entry | ||
| 854 | ; Function: | ||
| 855 | ; map the buferrs of this entry | ||
| 856 | ; Output: | ||
| 857 | ; the buffers are mapped | ||
| 858 | ; | ||
| 859 | ; All registers preserved | ||
| 860 | |||
| 861 | procedure Map_Entry,NEAR | ||
| 862 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 863 | |||
| 864 | PUSH DX ;LB. save regs ;AN000; | ||
| 865 | PUSH AX ;LB. ;AN000; | ||
| 866 | PUSH BX ;LB. ;AN000; | ||
| 867 | JMP Map_Entry2 ;LB. ;AN000; | ||
| 868 | EndProc Map_Entry ;LB. ;AN000; | ||
| 869 | |||
| 870 | |||
| 871 | IF BUFFERFLAG | ||
| 872 | |||
| 873 | ;------------------------------------------------------------------------- | ||
| 874 | ; Procedure name : detect collision | ||
| 875 | ; Inputs : [DMAADD] - user Xaddr | ||
| 876 | ; [CURADD] - current offset | ||
| 877 | ; [BYTCNT1] - for partial sector read | ||
| 878 | ; SAFE_FLAG - cleared - indicating that the | ||
| 879 | ; current page is unsafe. | ||
| 880 | ; | ||
| 881 | ; Outputs : es - physical page segment to use | ||
| 882 | ; di - corresponding page number | ||
| 883 | ; SAFE_FLAG is set is a collision is detected | ||
| 884 | ; and the current page is switched form | ||
| 885 | ; LAST_PAGE to FIRST_PAGE. | ||
| 886 | ;--------------------------------------------------------------------------- | ||
| 887 | ; | ||
| 888 | |||
| 889 | Procedure detect_collision, near | ||
| 890 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 891 | |||
| 892 | push ax | ||
| 893 | push bx | ||
| 894 | push cx | ||
| 895 | |||
| 896 | cmp [BUF_EMS_MODE], -1 | ||
| 897 | jz fin_detect_coll | ||
| 898 | |||
| 899 | mov ax, [CURADD] ; current offset | ||
| 900 | |||
| 901 | cmp [BYTCNT1], 0 | ||
| 902 | je no_partial_sector | ||
| 903 | add ax, [BYTCNT1] | ||
| 904 | |||
| 905 | no_partial_sector: | ||
| 906 | mov cl, 4 | ||
| 907 | shr ax, cl ; convert to paragraphs | ||
| 908 | mov bx, word ptr [DMAADD+2] ; get original segment | ||
| 909 | add ax, bx ; get current segment | ||
| 910 | |||
| 911 | and ax, 0fc00h ; get ems page of current segment | ||
| 912 | cmp ax, [BUF_EMS_LAST_PAGE] ; is the current segment = last segment | ||
| 913 | jne fin_detect_coll ; page is still safe | ||
| 914 | |||
| 915 | ; int 3 | ||
| 916 | push ax | ||
| 917 | mov ax, word ptr [DMAADD] | ||
| 918 | mov ax, [NEXTADD] | ||
| 919 | mov ax, [CURADD] | ||
| 920 | mov ax, [BYTCNT1] | ||
| 921 | pop ax | ||
| 922 | |||
| 923 | call restore_user_map | ||
| 924 | mov word ptr [LASTBUFFER], -1 | ||
| 925 | mov ax, [BUF_EMS_FIRST_PAGE] | ||
| 926 | mov [BUF_EMS_PFRAME], ax | ||
| 927 | mov ax, [BUF_EMS_FIRST_PAGE+2] | ||
| 928 | mov [BUF_EMS_PAGE_FRAME], ax | ||
| 929 | mov [BUF_EMS_SAFE_FLAG], 1 | ||
| 930 | call Setup_EMS_buffers | ||
| 931 | call save_user_map | ||
| 932 | |||
| 933 | fin_detect_coll: | ||
| 934 | pop cx | ||
| 935 | pop bx | ||
| 936 | pop ax | ||
| 937 | ret | ||
| 938 | |||
| 939 | EndProc detect_collision | ||
| 940 | |||
| 941 | Procedure Setup_EMS_Buffers,Near | ||
| 942 | ASSUME DS:NOTHING,ES:NOTHING ;AN000; | ||
| 943 | |||
| 944 | cmp [BUF_EMS_MODE], -1 | ||
| 945 | jz setup_ems_ret | ||
| 946 | |||
| 947 | push bx | ||
| 948 | push cx | ||
| 949 | push ax | ||
| 950 | push ds | ||
| 951 | push di | ||
| 952 | |||
| 953 | mov bx, [BUF_HASH_COUNT] ; # of hash table entries | ||
| 954 | lds di, [BUF_HASH_PTR] ; ds:di -> hash table | ||
| 955 | |||
| 956 | xor cx, cx | ||
| 957 | |||
| 958 | next_bucket: | ||
| 959 | mov ax, [BUF_EMS_PFRAME] | ||
| 960 | mov word ptr ds:[di.BUFFER_BUCKET+2], ax | ||
| 961 | add di, 8 ; next has entry. | ||
| 962 | inc cx | ||
| 963 | cmp cx, bx | ||
| 964 | jne next_bucket | ||
| 965 | |||
| 966 | pop di | ||
| 967 | pop ds | ||
| 968 | pop ax | ||
| 969 | pop cx | ||
| 970 | pop bx | ||
| 971 | |||
| 972 | setup_ems_ret: | ||
| 973 | ret | ||
| 974 | |||
| 975 | EndProc Setup_EMS_Buffers | ||
| 976 | |||
| 977 | ENDIF | ||
| 978 | |||
| 979 | |||
| 980 | CODE ENDS | ||
| 981 | END | ||
| 982 | \ No newline at end of file | ||