diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DOS/DISK2.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/DOS/DISK2.ASM')
| -rw-r--r-- | v4.0/src/DOS/DISK2.ASM | 784 |
1 files changed, 784 insertions, 0 deletions
diff --git a/v4.0/src/DOS/DISK2.ASM b/v4.0/src/DOS/DISK2.ASM new file mode 100644 index 0000000..bb76e89 --- /dev/null +++ b/v4.0/src/DOS/DISK2.ASM | |||
| @@ -0,0 +1,784 @@ | |||
| 1 | ; SCCSID = @(#)disk2.asm 1.3 85/06/19 | ||
| 2 | ; SCCSID = @(#)disk2.asm 1.3 85/06/19 | ||
| 3 | TITLE DISK2 - Disk utility routines | ||
| 4 | NAME Disk2 | ||
| 5 | ; Low level Read and write routines for local SFT I/O on files and devs | ||
| 6 | ; | ||
| 7 | ; DskRead | ||
| 8 | ; DWRITE | ||
| 9 | ; DSKWRITE | ||
| 10 | ; HarderrRW | ||
| 11 | ; SETUP | ||
| 12 | ; BREAKDOWN | ||
| 13 | ; READ_LOCK_VIOLATION | ||
| 14 | ; WRITE_LOCK_VIOLATION | ||
| 15 | ; DISKREAD | ||
| 16 | ; SET_ACC_ERR_DS | ||
| 17 | ; SET_ACC_ERR | ||
| 18 | ; SETSFT | ||
| 19 | ; SETCLUS | ||
| 20 | ; AddRec | ||
| 21 | ; | ||
| 22 | ; Revision history: | ||
| 23 | ; | ||
| 24 | ; AN000 version 4.00 Jan. 1988 | ||
| 25 | ; | ||
| 26 | |||
| 27 | ; | ||
| 28 | ; get the appropriate segment definitions | ||
| 29 | ; | ||
| 30 | .xlist | ||
| 31 | include dosseg.asm | ||
| 32 | |||
| 33 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 34 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 35 | |||
| 36 | .xcref | ||
| 37 | INCLUDE DOSSYM.INC | ||
| 38 | INCLUDE DEVSYM.INC | ||
| 39 | include version.inc | ||
| 40 | .cref | ||
| 41 | .list | ||
| 42 | |||
| 43 | Installed = TRUE | ||
| 44 | |||
| 45 | i_need THISSFT,DWORD | ||
| 46 | i_need DMAADD,DWORD | ||
| 47 | i_need NEXTADD,WORD | ||
| 48 | i_need ThisDrv,BYTE | ||
| 49 | i_need SecClusPos,BYTE | ||
| 50 | i_need ClusNum,WORD | ||
| 51 | i_need ReadOp,BYTE | ||
| 52 | i_need Trans,BYTE | ||
| 53 | i_need BytPos,4 | ||
| 54 | i_need SecPos,DWORD ; DOS 4.00 >32mb ;AN000; | ||
| 55 | i_need BytSecPos,WORD | ||
| 56 | i_need BytCnt1,WORD | ||
| 57 | i_need BytCnt2,WORD | ||
| 58 | i_need SecCnt,WORD | ||
| 59 | i_need ThisDPB,DWORD | ||
| 60 | i_need LastPos,WORD | ||
| 61 | i_need EXTERRPT,DWORD | ||
| 62 | i_need CALLVIDRW,DWORD | ||
| 63 | i_need ALLOWED,BYTE | ||
| 64 | i_need DEVCALL,BYTE | ||
| 65 | i_need CALLSCNT,WORD | ||
| 66 | i_need DISK_FULL,BYTE ; disk full flag for ran blk wrt | ||
| 67 | i_need FSeek_drive,BYTE ; DOS 4.00 ;AN000; | ||
| 68 | i_need FSeek_firclus,WORD ; DOS 4.00 ;AN000; | ||
| 69 | i_need HIGH_SECTOR,WORD ; F.C. >32mb ;AN000; | ||
| 70 | i_need TEMP_VAR2,WORD ; LB. ;AN000; | ||
| 71 | i_need TEMP_VAR,WORD ; LB. ;AN000; | ||
| 72 | i_need IFS_DRIVER_ERR,WORD ; LB. ;AN000; | ||
| 73 | i_need CurHashEntry,DWORD ; DOS 4.00 current Hash entry ;AN000; | ||
| 74 | i_need BUF_HASH_PTR,DWORD ; DOS 4.00 Hash table pointer ;AN000; | ||
| 75 | i_need BUF_HASH_COUNT,WORD ; DOS 4.00 Hash table entries ;AN000; | ||
| 76 | i_need LastBuffer,DWORD | ||
| 77 | i_need FIRST_BUFF_ADDR,WORD ; first buffer address ;AN000; | ||
| 78 | |||
| 79 | IF BUFFERFLAG | ||
| 80 | EXTRN SAVE_MAP:NEAR | ||
| 81 | EXTRN RESTORE_MAP:NEAR | ||
| 82 | EXTRN SAVE_USER_MAP:NEAR | ||
| 83 | EXTRN RESTORE_USER_MAP:NEAR | ||
| 84 | i_need BUF_EMS_SAFE_FLAG,BYTE | ||
| 85 | i_need BUF_EMS_MODE,BYTE | ||
| 86 | i_need CURADD,WORD | ||
| 87 | ENDIF | ||
| 88 | |||
| 89 | |||
| 90 | Break <DSKREAD -- PHYSICAL DISK READ> | ||
| 91 | |||
| 92 | ; Inputs: | ||
| 93 | ; DS:BX = Transfer addr | ||
| 94 | ; CX = Number of sectors | ||
| 95 | ; [HIGH_SECTOR] = Absolute record number (HIGH) | ||
| 96 | ; DX = Absolute record number (LOW) | ||
| 97 | ; ES:BP = Base of drive parameters | ||
| 98 | ; Function: | ||
| 99 | ; Call BIOS to perform disk read | ||
| 100 | ; Outputs: | ||
| 101 | ; DI = CX on entry | ||
| 102 | ; CX = Number of sectors unsuccessfully transfered | ||
| 103 | ; AX = Status word as returned by BIOS (error code in AL if error) | ||
| 104 | ; Zero set if OK (from BIOS) (carry clear) | ||
| 105 | ; Zero clear if error (carry clear) | ||
| 106 | ; SI Destroyed, others preserved | ||
| 107 | |||
| 108 | procedure DskRead,NEAR | ||
| 109 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 110 | |||
| 111 | Assert ISDPB,<ES,BP>,"DskRead" | ||
| 112 | PUSH CX | ||
| 113 | MOV AH,ES:[BP.dpb_media] | ||
| 114 | MOV AL,ES:[BP.dpb_UNIT] | ||
| 115 | PUSH BX | ||
| 116 | PUSH ES | ||
| 117 | invoke SETREAD | ||
| 118 | JMP DODSKOP | ||
| 119 | |||
| 120 | Break <DWRITE -- SEE ABOUT WRITING> | ||
| 121 | |||
| 122 | ; Inputs: | ||
| 123 | ; DS:BX = Transfer address | ||
| 124 | ; CX = Number of sectors | ||
| 125 | ; [HIGH_SECTOR] = Absolute record number (HIGH) | ||
| 126 | ; DX = Absolute record number (LOW) | ||
| 127 | ; ES:BP = Base of drive parameters | ||
| 128 | ; [ALLOWED] must be set in case HARDERR called | ||
| 129 | ; Function: | ||
| 130 | ; Calls BIOS to perform disk write. If BIOS reports | ||
| 131 | ; errors, will call HARDERRRW for further action. | ||
| 132 | ; Output: | ||
| 133 | ; Carry set if error (currently, user FAILed to I 24) | ||
| 134 | ; BP preserved. All other registers destroyed. | ||
| 135 | |||
| 136 | entry DWRITE | ||
| 137 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 138 | |||
| 139 | Assert ISDPB,<ES,BP>,"DWrite" | ||
| 140 | CALL DSKWRITE | ||
| 141 | retz ; Carry clear | ||
| 142 | MOV BYTE PTR [READOP],1 | ||
| 143 | invoke HARDERRRW | ||
| 144 | CMP AL,1 ; Check for retry | ||
| 145 | JZ DWRITE | ||
| 146 | CMP AL,3 ; Check for FAIL | ||
| 147 | CLC | ||
| 148 | JNZ NO_CAR2 ; Ignore | ||
| 149 | STC | ||
| 150 | NO_CAR2: | ||
| 151 | return | ||
| 152 | |||
| 153 | Break <DSKWRITE -- PHYSICAL DISK WRITE> | ||
| 154 | |||
| 155 | ; Inputs: | ||
| 156 | ; DS:BX = Transfer addr | ||
| 157 | ; CX = Number of sectors | ||
| 158 | ; DX = Absolute record number (LOW) | ||
| 159 | ; [HIGH_SECTOR] = Absolute record number (HIGH) | ||
| 160 | ; ES:BP = Base of drive parameters | ||
| 161 | ; Function: | ||
| 162 | ; Call BIOS to perform disk read | ||
| 163 | ; Outputs: | ||
| 164 | ; DI = CX on entry | ||
| 165 | ; CX = Number of sectors unsuccessfully transfered | ||
| 166 | ; AX = Status word as returned by BIOS (error code in AL if error) | ||
| 167 | ; Zero set if OK (from BIOS) (carry clear) | ||
| 168 | ; Zero clear if error (carry clear) | ||
| 169 | ; SI Destroyed, others preserved | ||
| 170 | |||
| 171 | entry DSKWRITE | ||
| 172 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 173 | |||
| 174 | Assert ISDPB,<ES,BP>,"DskWrite" | ||
| 175 | PUSH CX | ||
| 176 | MOV AH,ES:[BP.dpb_media] | ||
| 177 | MOV AL,ES:[BP.dpb_UNIT] | ||
| 178 | PUSH BX | ||
| 179 | PUSH ES | ||
| 180 | invoke SETWRITE | ||
| 181 | DODSKOP: | ||
| 182 | MOV CX,DS ; Save DS | ||
| 183 | POP DS ; DS:BP points to DPB | ||
| 184 | PUSH DS | ||
| 185 | LDS SI,DS:[BP.dpb_driver_addr] | ||
| 186 | invoke DEVIOCALL2 | ||
| 187 | MOV DS,CX ; Restore DS | ||
| 188 | POP ES ; Restore ES | ||
| 189 | POP BX | ||
| 190 | MOV CX,[CALLSCNT] ; Number of sectors transferred | ||
| 191 | POP DI | ||
| 192 | SUB CX,DI | ||
| 193 | NEG CX ; Number of sectors not transferred | ||
| 194 | MOV AX,[DEVCALL.REQSTAT] | ||
| 195 | MOV [IFS_DRIVER_ERR],AX ;IFS. save it for IFS ;AN000; | ||
| 196 | TEST AX,STERR | ||
| 197 | return | ||
| 198 | EndProc DskRead | ||
| 199 | |||
| 200 | |||
| 201 | |||
| 202 | Break <HardErrRW - map extended errors and call harderr> | ||
| 203 | |||
| 204 | ; Inputs: | ||
| 205 | ; AX is error code from read or write | ||
| 206 | ; Other registers set as per HARDERR | ||
| 207 | ; Function: | ||
| 208 | ; Checks the error code for special extended | ||
| 209 | ; errors and maps them if needed. Then invokes | ||
| 210 | ; Harderr | ||
| 211 | ; Outputs: | ||
| 212 | ; Of HARDERR | ||
| 213 | ; AX may be modified prior to call to HARDERR. | ||
| 214 | ; No other registers altered. | ||
| 215 | |||
| 216 | procedure HARDERRRW,near | ||
| 217 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 218 | |||
| 219 | CMP AL,error_I24_wrong_disk | ||
| 220 | JNZ DO_ERR ; Nothing to do | ||
| 221 | PUSH DS | ||
| 222 | PUSH SI | ||
| 223 | LDS SI,[CALLVIDRW] ; Get pointer from dev | ||
| 224 | MOV WORD PTR [EXTERRPT+2],DS ; Set ext err pointer | ||
| 225 | MOV WORD PTR [EXTERRPT],SI | ||
| 226 | POP SI | ||
| 227 | POP DS | ||
| 228 | DO_ERR: | ||
| 229 | invoke HARDERR | ||
| 230 | return | ||
| 231 | |||
| 232 | EndProc HARDERRRW | ||
| 233 | |||
| 234 | Break <SETUP -- SETUP A DISK READ OR WRITE FROM USER> | ||
| 235 | |||
| 236 | ; Inputs: | ||
| 237 | ; ES:DI point to SFT (value also in THISSFT) | ||
| 238 | ; [DMAADD] contains transfer address | ||
| 239 | ; CX = Byte count | ||
| 240 | ; WARNING Stack must be clean, two ret addrs on stack, 1st of caller, | ||
| 241 | ; 2nd of caller of caller. | ||
| 242 | ; Outputs: | ||
| 243 | ; CX = byte count | ||
| 244 | ; [THISDPB] = Base of drive parameters if file | ||
| 245 | ; = Pointer to device header if device or NET | ||
| 246 | ; ES:DI Points to SFT | ||
| 247 | ; [NEXTADD] = Displacement of disk transfer within segment | ||
| 248 | ; [TRANS] = 0 (No transfers yet) | ||
| 249 | ; [BYTPOS] = Byte position in file | ||
| 250 | ; | ||
| 251 | ; The following fields are relevant to local files (not devices) only: | ||
| 252 | ; | ||
| 253 | ; [SECPOS] = Position of first sector (local files only) | ||
| 254 | ; [BYTSECPOS] = Byte position in first sector (local files only) | ||
| 255 | ; [CLUSNUM] = First cluster (local files only) | ||
| 256 | ; [SECCLUSPOS] = Sector within first cluster (local files only) | ||
| 257 | ; [THISDRV] = Physical unit number (local files only) | ||
| 258 | ; | ||
| 259 | ; RETURNS ONE LEVEL UP WITH: | ||
| 260 | ; CX = 0 | ||
| 261 | ; CARRY = Clear | ||
| 262 | ; IF AN ERROR IS DETECTED | ||
| 263 | ; All other registers destroyed | ||
| 264 | |||
| 265 | procedure SETUP,NEAR | ||
| 266 | DOSAssume CS,<DS>,"SetUp" | ||
| 267 | ASSUME ES:NOTHING | ||
| 268 | |||
| 269 | Assert ISSFT,<ES,DI>,"SetUp" | ||
| 270 | LDS SI,ES:[DI.sf_devptr] | ||
| 271 | ASSUME DS:NOTHING | ||
| 272 | MOV WORD PTR [THISDPB+2],DS | ||
| 273 | context DS | ||
| 274 | MOV WORD PTR [THISDPB],SI | ||
| 275 | MOV BX,WORD PTR [DMAADD] | ||
| 276 | MOV [NEXTADD],BX ;Set NEXTADD to start of Xaddr | ||
| 277 | MOV BYTE PTR [TRANS],0 ;No transferes | ||
| 278 | MOV AX,WORD PTR ES:[DI.sf_Position] | ||
| 279 | MOV DX,WORD PTR ES:[DI.sf_Position+2] | ||
| 280 | MOV WORD PTR [BYTPOS+2],DX ;Set it | ||
| 281 | MOV WORD PTR [BYTPOS],AX | ||
| 282 | TEST ES:[DI.sf_flags],sf_isnet + devid_device | ||
| 283 | JNZ NOSETSTUFF ;Following not done on devs or NET | ||
| 284 | PUSH ES | ||
| 285 | LES BP,[THISDPB] ;Point at the DPB | ||
| 286 | Assert ISDPB,<ES,BP>,"Setup" | ||
| 287 | MOV BL,ES:[BP.dpb_drive] | ||
| 288 | MOV [THISDRV],BL ;Set THISDRV | ||
| 289 | MOV BX,ES:[BP.dpb_sector_size] | ||
| 290 | ; CMP DX,BX ; See if divide will overflow | ||
| 291 | ; JNC EOFERR ; for 16 bit sector | ||
| 292 | ;; 32 bit divide | ||
| 293 | invoke DIV32 ; F.C. >32mb ;AN000; | ||
| 294 | MOV WORD PTR [SECPOS],AX ; F.C. >32mb ;AN000; | ||
| 295 | MOV BX,[HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 296 | MOV WORD PTR [SECPOS+2],BX ; F.C. >32mb ;AN000; | ||
| 297 | |||
| 298 | MOV [BYTSECPOS],DX | ||
| 299 | MOV DX,AX | ||
| 300 | AND AL,ES:[BP.dpb_cluster_mask] | ||
| 301 | MOV [SECCLUSPOS],AL | ||
| 302 | MOV AX,CX ; Save byte count | ||
| 303 | ; MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 304 | PUSH WORD PTR [SECPOS+2] ; F.C. >32mb ;AN000; | ||
| 305 | POP [HIGH_SECTOR] ; F.C. >32mb ;AN000; | ||
| 306 | PUSH AX ; F.C. >32mb save ax ;AN000; | ||
| 307 | MOV AX,DX ; F.C. >32mb ax=dx ;AN000; | ||
| 308 | invoke SHR32 ; F.C. >32mb shift ax ;AN000; | ||
| 309 | MOV DX,AX ; F.C. >32mb dx=ax ;AN000; | ||
| 310 | POP AX ; F.C. >32mb restore dx ;AN000; | ||
| 311 | |||
| 312 | ; SHR DX,CL | ||
| 313 | CMP DX,ES:[BP.dpb_max_cluster] ;>32mb if > disk size ;AN000; ;AN000; | ||
| 314 | JA EOFERR ;>32mb then EOF ;AN000; ;AN000; | ||
| 315 | |||
| 316 | MOV [CLUSNUM],DX | ||
| 317 | POP ES ; ES:DI point to SFT | ||
| 318 | MOV CX,AX ; Put byte count back in CX | ||
| 319 | NOSETSTUFF: | ||
| 320 | MOV AX,CX ; Need it in AX too | ||
| 321 | ADD AX,WORD PTR [DMAADD] ; See if it will fit in one segment | ||
| 322 | JNC OK ; Must be less than 64K | ||
| 323 | MOV AX,WORD PTR [DMAADD] | ||
| 324 | NEG AX ; Amount of room left in segment (know | ||
| 325 | ; less than 64K since max value of CX | ||
| 326 | ; is FFFF). | ||
| 327 | JNZ NoDec | ||
| 328 | DEC AX | ||
| 329 | NoDec: | ||
| 330 | MOV CX,AX ; Can do this much | ||
| 331 | JCXZ NOROOM ; Silly user gave Xaddr of FFFF in segment | ||
| 332 | OK: | ||
| 333 | return | ||
| 334 | |||
| 335 | EOFERR: | ||
| 336 | POP ES ; ES:DI point to SFT | ||
| 337 | XOR CX,CX ; No bytes read | ||
| 338 | ;;;;;;;;;;; 7/18/86 | ||
| 339 | ; MOV BYTE PTR [DISK_FULL],1 ; set disk full flag | ||
| 340 | ;;;;;;;;;;; | ||
| 341 | NOROOM: | ||
| 342 | POP BX ; Kill return address | ||
| 343 | CLC | ||
| 344 | return ; RETURN TO CALLER OF CALLER | ||
| 345 | EndProc SETUP | ||
| 346 | |||
| 347 | Break <BREAKDOWN -- CUT A USER READ OR WRITE INTO PIECES> | ||
| 348 | |||
| 349 | ; Inputs: | ||
| 350 | ; CX = Length of disk transfer in bytes | ||
| 351 | ; ES:BP = Base of drive parameters | ||
| 352 | ; [BYTSECPOS] = Byte position witin first sector | ||
| 353 | ; Outputs: | ||
| 354 | ; [BYTCNT1] = Bytes to transfer in first sector | ||
| 355 | ; [SECCNT] = No. of whole sectors to transfer | ||
| 356 | ; [BYTCNT2] = Bytes to transfer in last sector | ||
| 357 | ; AX, BX, DX destroyed. No other registers affected. | ||
| 358 | |||
| 359 | procedure BREAKDOWN,near | ||
| 360 | DOSAssume CS,<DS>,"BreakDown" | ||
| 361 | ASSUME ES:NOTHING | ||
| 362 | |||
| 363 | Assert ISDPB,<ES,BP>,"BreakDown" | ||
| 364 | MOV AX,[BYTSECPOS] | ||
| 365 | MOV BX,CX | ||
| 366 | OR AX,AX | ||
| 367 | JZ SAVFIR ; Partial first sector? | ||
| 368 | SUB AX,ES:[BP.dpb_sector_size] | ||
| 369 | NEG AX ; Max number of bytes left in first sector | ||
| 370 | SUB BX,AX ; Subtract from total length | ||
| 371 | JAE SAVFIR | ||
| 372 | ADD AX,BX ; Don't use all of the rest of the sector | ||
| 373 | XOR BX,BX ; And no bytes are left | ||
| 374 | SAVFIR: | ||
| 375 | MOV [BYTCNT1],AX | ||
| 376 | MOV AX,BX | ||
| 377 | XOR DX,DX | ||
| 378 | DIV ES:[BP.dpb_sector_size] ; How many whole sectors? | ||
| 379 | MOV [SECCNT],AX | ||
| 380 | MOV [BYTCNT2],DX ; Bytes remaining for last sector | ||
| 381 | OR DX,[BYTCNT1] | ||
| 382 | retnz ; NOT (BYTCNT1 = BYTCNT2 = 0) | ||
| 383 | CMP AX,1 | ||
| 384 | retnz | ||
| 385 | MOV AX,ES:[BP.dpb_sector_size] ; Buffer EXACT one sector I/O | ||
| 386 | MOV [BYTCNT2],AX | ||
| 387 | MOV [SECCNT],DX ; DX = 0 | ||
| 388 | RET45: | ||
| 389 | return | ||
| 390 | EndProc BreakDown | ||
| 391 | |||
| 392 | ; ES:DI points to SFT. This entry used by NET_READ | ||
| 393 | ; Carry set if to return error (CX=0,AX=error_sharing_violation). | ||
| 394 | ; Else do retrys. | ||
| 395 | ; ES:DI,DS,CX preserved | ||
| 396 | |||
| 397 | procedure READ_LOCK_VIOLATION,NEAR | ||
| 398 | DOSAssume CS,<DS>,"Read_Lock_Violation" | ||
| 399 | ASSUME ES:NOTHING | ||
| 400 | |||
| 401 | Assert ISSFT,<ES,DI>,"ReadLockViolation" | ||
| 402 | |||
| 403 | MOV [READOP],0 | ||
| 404 | ERR_ON_CHECK: | ||
| 405 | TEST ES:[DI.sf_mode],sf_isfcb | ||
| 406 | JNZ HARD_ERR | ||
| 407 | PUSH CX | ||
| 408 | MOV CL,BYTE PTR ES:[DI.sf_mode] | ||
| 409 | AND CL,sharing_mask | ||
| 410 | CMP CL,sharing_compat | ||
| 411 | POP CX | ||
| 412 | JNE NO_HARD_ERR | ||
| 413 | HARD_ERR: | ||
| 414 | invoke LOCK_VIOLATION | ||
| 415 | retnc ; User wants Retrys | ||
| 416 | NO_HARD_ERR: | ||
| 417 | XOR CX,CX ;No bytes transferred | ||
| 418 | MOV AX,error_lock_violation | ||
| 419 | STC | ||
| 420 | return | ||
| 421 | |||
| 422 | EndProc READ_LOCK_VIOLATION | ||
| 423 | |||
| 424 | ; Same as READ_LOCK_VIOLATION except for READOP. | ||
| 425 | ; This entry used by NET_WRITE | ||
| 426 | procedure WRITE_LOCK_VIOLATION,NEAR | ||
| 427 | DOSAssume CS,<DS>,"Write_Lock_Violation" | ||
| 428 | ASSUME ES:NOTHING | ||
| 429 | Assert ISSFT,<ES,DI>,"WriteLockViolation" | ||
| 430 | |||
| 431 | MOV [READOP],1 | ||
| 432 | JMP ERR_ON_CHECK | ||
| 433 | |||
| 434 | EndProc WRITE_LOCK_VIOLATION | ||
| 435 | |||
| 436 | |||
| 437 | Break <DISKREAD -- PERFORM USER DISK READ> | ||
| 438 | |||
| 439 | ; Inputs: | ||
| 440 | ; Outputs of SETUP | ||
| 441 | ; Function: | ||
| 442 | ; Perform disk read | ||
| 443 | ; Outputs: | ||
| 444 | ; Carry clear | ||
| 445 | ; CX = No. of bytes read | ||
| 446 | ; ES:DI point to SFT | ||
| 447 | ; SFT offset and cluster pointers updated | ||
| 448 | ; Carry set | ||
| 449 | ; CX = 0 | ||
| 450 | ; ES:DI point to SFT | ||
| 451 | ; AX has error code | ||
| 452 | |||
| 453 | procedure DISKREAD,NEAR | ||
| 454 | DOSAssume CS,<DS>,"DiskRead" | ||
| 455 | ASSUME ES:NOTHING | ||
| 456 | |||
| 457 | Assert ISSFT,<ES,DI>,"DISKREAD" | ||
| 458 | PUSH ES:[DI.sf_firclus] ; set up 1st cluster # for FastSeek | ||
| 459 | POP [FSeek_firclus] ; 11/5/86 | ||
| 460 | |||
| 461 | MOV AX,WORD PTR ES:[DI.sf_size] | ||
| 462 | MOV BX,WORD PTR ES:[DI.sf_size+2] | ||
| 463 | SUB AX,WORD PTR [BYTPOS] | ||
| 464 | SBB BX,WORD PTR [BYTPOS+2] | ||
| 465 | JB RDERR ;Read starts past EOF | ||
| 466 | JNZ ENUF ;More than 64k to EOF | ||
| 467 | OR AX,AX | ||
| 468 | JZ RDERR ;Read starts at EOF | ||
| 469 | CMP AX,CX | ||
| 470 | JAE ENUF ;I/O fits | ||
| 471 | MOV CX,AX ;Limit read to up til EOF | ||
| 472 | ENUF: | ||
| 473 | invoke CHECK_READ_LOCK ;IFS. check read lock ;AN000; | ||
| 474 | JNC Read_Ok ; There are no locks | ||
| 475 | return | ||
| 476 | |||
| 477 | READ_OK: | ||
| 478 | LES BP,[THISDPB] | ||
| 479 | Assert ISDPB,<ES,BP>,"DISKREAD/ReadOK" | ||
| 480 | MOV AL,ES:[BP.dpb_drive] ; set up drive # for FastSeek | ||
| 481 | MOV [FSeek_drive],AL ; 11/5/86 ;AN000; | ||
| 482 | |||
| 483 | CALL BREAKDOWN | ||
| 484 | MOV CX,[CLUSNUM] | ||
| 485 | invoke FNDCLUS | ||
| 486 | ;------------------------------------------------------------------------ | ||
| 487 | IF NOT IBMCOPYRIGHT | ||
| 488 | JC SET_ACC_ERR_DS ; fix to take care of I24 fail | ||
| 489 | ; migrated from 330a - HKN | ||
| 490 | ENDIF | ||
| 491 | ;------------------------------------------------------------------------ | ||
| 492 | OR CX,CX | ||
| 493 | JZ SKIPERR | ||
| 494 | RDERR: | ||
| 495 | MOV [DISK_FULL],1 ;MS. EOF detection ;AN000; | ||
| 496 | MOV AH,0EH ;MS. read/data/fail ;AN000; | ||
| 497 | transfer WRTERR22 | ||
| 498 | RDLASTJ:JMP RDLAST | ||
| 499 | SETSFTJ2: JMP SETSFT | ||
| 500 | |||
| 501 | CANOT_READ: | ||
| 502 | POP CX ; Clean stack | ||
| 503 | POP CX | ||
| 504 | POP BX | ||
| 505 | |||
| 506 | entry SET_ACC_ERR_DS | ||
| 507 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 508 | Context DS | ||
| 509 | |||
| 510 | entry SET_ACC_ERR | ||
| 511 | DOSAssume CS,<DS>,"SET_ACC_ERR" | ||
| 512 | |||
| 513 | XOR CX,CX | ||
| 514 | MOV AX,error_access_denied | ||
| 515 | STC | ||
| 516 | return | ||
| 517 | |||
| 518 | SKIPERR: | ||
| 519 | MOV [LASTPOS],DX | ||
| 520 | MOV [CLUSNUM],BX | ||
| 521 | CMP [BYTCNT1],0 | ||
| 522 | JZ RDMID | ||
| 523 | invoke BUFRD | ||
| 524 | JC SET_ACC_ERR_DS | ||
| 525 | RDMID: | ||
| 526 | CMP [SECCNT],0 | ||
| 527 | JZ RDLASTJ | ||
| 528 | invoke NEXTSEC | ||
| 529 | JC SETSFTJ2 | ||
| 530 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 531 | ONSEC: | ||
| 532 | MOV DL,[SECCLUSPOS] | ||
| 533 | MOV CX,[SECCNT] | ||
| 534 | MOV BX,[CLUSNUM] | ||
| 535 | RDLP: | ||
| 536 | invoke OPTIMIZE | ||
| 537 | JC SET_ACC_ERR_DS | ||
| 538 | PUSH DI | ||
| 539 | PUSH AX | ||
| 540 | PUSH BX | ||
| 541 | MOV [ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE | ||
| 542 | MOV DS,WORD PTR [DMAADD+2] | ||
| 543 | ASSUME DS:NOTHING | ||
| 544 | PUSH DX | ||
| 545 | PUSH CX | ||
| 546 | invoke SET_RQ_SC_PARMS ;LB. do this for SC ;AN000; | ||
| 547 | |||
| 548 | IF BUFFERFLAG | ||
| 549 | pushf | ||
| 550 | cmp [BUF_EMS_SAFE_FLAG], 1 | ||
| 551 | je safe_read | ||
| 552 | call save_map | ||
| 553 | call restore_user_map | ||
| 554 | safe_read: | ||
| 555 | popf | ||
| 556 | ENDIF | ||
| 557 | |||
| 558 | invoke DREAD | ||
| 559 | |||
| 560 | IF BUFFERFLAG | ||
| 561 | pushf | ||
| 562 | cmp [BUF_EMS_SAFE_FLAG], 1 | ||
| 563 | je safe_mapping | ||
| 564 | call save_user_map | ||
| 565 | call restore_map | ||
| 566 | safe_mapping: | ||
| 567 | popf | ||
| 568 | ENDIF | ||
| 569 | |||
| 570 | POP BX | ||
| 571 | POP DX | ||
| 572 | JNC SKP_CANOT_READ | ||
| 573 | JMP CANOT_READ | ||
| 574 | SKP_CANOT_READ: | ||
| 575 | MOV [TEMP_VAR],BX ;LB. save sector count ;AN000; | ||
| 576 | MOV [TEMP_VAR2],DX ;LB. 1st sector ;AN000; | ||
| 577 | SCAN_NEXT: | ||
| 578 | ;;;;;;; invoke GETCURHEAD ;LB. get buffer header ;AN000; | ||
| 579 | PUSH DX ;LB. save regs ;AN000; | ||
| 580 | PUSH AX ;LB. ;AN000; | ||
| 581 | PUSH BX ;LB. ;AN000; | ||
| 582 | MOV AX,DX ;LB. | ||
| 583 | ; MOV DX,[HIGH_SECTOR] ;LB. HASH(sector#) and get entry # ;AN000; | ||
| 584 | XOR DX,DX ;LB. to avoid divide overflow ;AN000; | ||
| 585 | DIV [BUF_HASH_COUNT] ;LB. get remainder ;AN000; | ||
| 586 | ADD DX,DX ;LB. 8 bytes per entry ;AN000; | ||
| 587 | ADD DX,DX ;LB. ;AN000; | ||
| 588 | ADD DX,DX ;LB. times 8 ;AN000; | ||
| 589 | |||
| 590 | LDS DI,[BUF_HASH_PTR] ;LB. get Hash Table addr ;AN000; | ||
| 591 | ADD DI,DX ;LB position to entry ;AN000; | ||
| 592 | CMP [DI.Dirty_Count],0 ;LB dirty hash entry ? ;AN000; | ||
| 593 | JNZ yesdirty ;LB yes and map it ;AN000; | ||
| 594 | POP BX ;LB. ;AN000; | ||
| 595 | POP AX ;LB. ;AN000; | ||
| 596 | POP DX ;LB. ;AN000; | ||
| 597 | |||
| 598 | IF NOT BUFFERFLAG | ||
| 599 | JMP SHORT end_scan ;LB. ;AN000; | ||
| 600 | ELSE | ||
| 601 | JMP END_SCAN | ||
| 602 | ENDIF | ||
| 603 | |||
| 604 | yesdirty: | ||
| 605 | MOV WORD PTR [CurHashEntry+2],DS ;LB. update current Hash entry ptr ;AN000; | ||
| 606 | MOV WORD PTR [CurHashEntry],DI ;LB. ;AN000; | ||
| 607 | MOV WORD PTR [LASTBUFFER],-1 ;LB. invalidate last buffer ;AN000; | ||
| 608 | MOV BX,[DI.EMS_PAGE_NUM] ;LB. logical page ;AN000; | ||
| 609 | |||
| 610 | IF NOT BUFFERFLAG | ||
| 611 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 612 | MOV [FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000; | ||
| 613 | invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 614 | ELSE | ||
| 615 | ; int 3 | ||
| 616 | push ds | ||
| 617 | push di ; save hash ptr | ||
| 618 | |||
| 619 | LDS DI,[DI.BUFFER_BUCKET] ;ds:di is 1st buffer addr | ||
| 620 | POP AX ; Recall transfer address | ||
| 621 | PUSH AX | ||
| 622 | PUSH DI ; Save search environment | ||
| 623 | PUSH DX ; F.C. no need for high sector, <64K | ||
| 624 | push cx | ||
| 625 | |||
| 626 | MOV DX,[TEMP_VAR2] ;LB. get 1st sector # | ||
| 627 | SUB DX,WORD PTR [DI.buf_sector] ; How far into transfer? | ||
| 628 | NEG DX | ||
| 629 | MOV DI,AX | ||
| 630 | MOV AX,DX | ||
| 631 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 632 | MUL CX | ||
| 633 | ADD DI,AX ; Put the buffer here | ||
| 634 | mov [CURADD], di | ||
| 635 | |||
| 636 | pop cx | ||
| 637 | pop dx | ||
| 638 | pop di | ||
| 639 | |||
| 640 | invoke SET_MAP_PAGE ;LB. activate handle if EMS there ;AN000; | ||
| 641 | pop di ; restore hash ptr. | ||
| 642 | pop ds | ||
| 643 | LDS DI,[DI.BUFFER_BUCKET] ;LB. ds:di is 1st buffer addr ;AN000; | ||
| 644 | MOV [FIRST_BUFF_ADDR],DI ;LB. save first buff addr 1/19/88 ;AN000; | ||
| 645 | ENDIF | ||
| 646 | ;AN000; | ||
| 647 | POP BX ;LB. ;AN000; | ||
| 648 | POP AX ;LB. ;AN000; | ||
| 649 | POP DX ;LB. ;AN000; | ||
| 650 | |||
| 651 | |||
| 652 | Assert ISDPB,<ES,BP>,"DISKREAD/RdLp" | ||
| 653 | MOV AL,ES:[BP.dpb_drive] | ||
| 654 | NXTBUF: ; Must see if one of these sectors is buffered | ||
| 655 | invoke BUFF_RANGE_CHECK ;F.C. >32mb | ||
| 656 | JNC inrange ;LB. ;AN000; | ||
| 657 | mov DI,[DI.buf_next] ;LB. get next buffer 1/19/88 ;AN000; | ||
| 658 | JMP DONXTBUF ;LB. ;AN000; | ||
| 659 | inrange: | ||
| 660 | TEST [DI.buf_flags],buf_dirty | ||
| 661 | JZ CLBUFF ; Buffer is clean, so OK | ||
| 662 | ; A sector has been read in when a dirty copy of it is in a buffer | ||
| 663 | ; The buffered sector must now be read into the right place | ||
| 664 | POP AX ; Recall transfer address | ||
| 665 | PUSH AX | ||
| 666 | PUSH DI ; Save search environment | ||
| 667 | PUSH DX ; F.C. no need for high sector, <64K | ||
| 668 | |||
| 669 | MOV DX,[TEMP_VAR2] ;LB. get 1st sector # | ||
| 670 | SUB DX,WORD PTR [DI.buf_sector] ; How far into transfer? | ||
| 671 | NEG DX | ||
| 672 | MOV SI,DI | ||
| 673 | MOV DI,AX | ||
| 674 | MOV AX,DX | ||
| 675 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 676 | MUL CX | ||
| 677 | ADD DI,AX ; Put the buffer here | ||
| 678 | LEA SI,[SI].BUFINSIZ | ||
| 679 | SHR CX,1 | ||
| 680 | PUSH ES | ||
| 681 | MOV ES,WORD PTR [DMAADD+2] | ||
| 682 | REP MOVSW | ||
| 683 | JNC EVENMOV | ||
| 684 | MOVSB | ||
| 685 | EVENMOV: | ||
| 686 | POP ES | ||
| 687 | POP DX | ||
| 688 | POP DI | ||
| 689 | MOV AL,ES:[BP.dpb_drive] | ||
| 690 | invoke SCANPLACE ;LB. done with this chain ;AN000; | ||
| 691 | JMP SHORT end_scan ;LB. ;AN000; | ||
| 692 | CLBUFF: | ||
| 693 | invoke SCANPLACE | ||
| 694 | DONXTBUF: | ||
| 695 | CMP DI,[FIRST_BUFF_ADDR] ;LB. end of buffers ;AN000; | ||
| 696 | JNZ NXTBUF | ||
| 697 | end_scan: | ||
| 698 | ADD DX,1 ;LB. next sector # ;AN000; | ||
| 699 | ADC [HIGH_SECTOR],0 ;LB. ;AN000; | ||
| 700 | DEC [TEMP_VAR] ;LB. decrement count ;AN000; | ||
| 701 | JZ SCAN_DONE ;LB. scan next sector ;AN000; | ||
| 702 | JMP SCAN_NEXT ;LB. scan next sector ;AN000; | ||
| 703 | SCAN_DONE: | ||
| 704 | Context DS | ||
| 705 | POP CX | ||
| 706 | POP CX | ||
| 707 | POP BX | ||
| 708 | JCXZ RDLAST | ||
| 709 | invoke IsEOF ; test for eof on fat size | ||
| 710 | JAE SETSFT | ||
| 711 | MOV DL,0 | ||
| 712 | INC [LASTPOS] ; We'll be using next cluster | ||
| 713 | JMP RDLP | ||
| 714 | |||
| 715 | RDLAST: | ||
| 716 | MOV AX,[BYTCNT2] | ||
| 717 | OR AX,AX | ||
| 718 | JZ SETSFT | ||
| 719 | MOV [BYTCNT1],AX | ||
| 720 | invoke NEXTSEC | ||
| 721 | JC SETSFT | ||
| 722 | MOV [BYTSECPOS],0 | ||
| 723 | invoke BUFRD | ||
| 724 | JNC SETSFT | ||
| 725 | JMP SET_ACC_ERR_DS | ||
| 726 | |||
| 727 | ; Inputs: | ||
| 728 | ; [NEXTADD],[CLUSNUM],[LASTPOS] set to determine transfer size | ||
| 729 | ; and set cluster fields | ||
| 730 | ; Function: | ||
| 731 | ; Update [THISSFT] based on the transfer | ||
| 732 | ; Outputs: | ||
| 733 | ; sf_position, sf_lstclus, and sf_cluspos updated | ||
| 734 | ; ES:DI points to [THISSFT] | ||
| 735 | ; CX No. of bytes transferred | ||
| 736 | ; Carry clear | ||
| 737 | |||
| 738 | entry SETSFT | ||
| 739 | DOSAssume CS,<DS>,"SetSFT" | ||
| 740 | ASSUME ES:NOTHING | ||
| 741 | |||
| 742 | LES DI,[THISSFT] | ||
| 743 | |||
| 744 | ; Same as SETSFT except ES:DI already points to SFT | ||
| 745 | entry SETCLUS | ||
| 746 | DOSAssume CS,<DS>,"SetClus" | ||
| 747 | ASSUME ES:NOTHING | ||
| 748 | |||
| 749 | Assert ISSFT,<ES,DI>,"SetClus" | ||
| 750 | MOV CX,[NEXTADD] | ||
| 751 | SUB CX,WORD PTR [DMAADD] ; Number of bytes transfered | ||
| 752 | TEST ES:[DI.sf_flags],devid_device | ||
| 753 | JNZ ADDREC ; don't set clusters if device | ||
| 754 | MOV AX,[CLUSNUM] | ||
| 755 | MOV ES:[DI.sf_lstclus],AX | ||
| 756 | MOV AX,[LASTPOS] | ||
| 757 | MOV ES:[DI.sf_cluspos],AX | ||
| 758 | |||
| 759 | ; Inputs: | ||
| 760 | ; ES:DI points to SFT | ||
| 761 | ; CX is No. Bytes transferred | ||
| 762 | ; Function: | ||
| 763 | ; Update the SFT offset based on the transfer | ||
| 764 | ; Outputs: | ||
| 765 | ; sf_position updated to point to first byte after transfer | ||
| 766 | ; ES:DI points to SFT | ||
| 767 | ; CX No. of bytes transferred | ||
| 768 | ; Carry clear | ||
| 769 | |||
| 770 | entry AddRec | ||
| 771 | DOSAssume CS,<DS>,"AddRec" | ||
| 772 | ASSUME ES:NOTHING | ||
| 773 | |||
| 774 | Assert ISSFT,<ES,DI>,"AddRec" | ||
| 775 | JCXZ RET28 ; If no records read, don't change position | ||
| 776 | ADD WORD PTR ES:[DI.sf_position],CX ; Update current position | ||
| 777 | ADC WORD PTR ES:[DI.sf_position+2],0 | ||
| 778 | RET28: CLC | ||
| 779 | return | ||
| 780 | EndProc DISKREAD | ||
| 781 | |||
| 782 | CODE ENDS | ||
| 783 | END | ||
| 784 | \ No newline at end of file | ||