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/ROM.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/ROM.ASM')
| -rw-r--r-- | v4.0/src/DOS/ROM.ASM | 938 |
1 files changed, 938 insertions, 0 deletions
diff --git a/v4.0/src/DOS/ROM.ASM b/v4.0/src/DOS/ROM.ASM new file mode 100644 index 0000000..ca34409 --- /dev/null +++ b/v4.0/src/DOS/ROM.ASM | |||
| @@ -0,0 +1,938 @@ | |||
| 1 | ; SCCSID = @(#)rom.asm 1.1 85/04/10 | ||
| 2 | TITLE ROM - Miscellaneous routines | ||
| 3 | NAME ROM | ||
| 4 | ; Misc Low level routines for doing simple FCB computations, Cache | ||
| 5 | ; reads and writes, I/O optimization, and FAT allocation/deallocation | ||
| 6 | ; | ||
| 7 | ; SKPCLP | ||
| 8 | ; FNDCLUS | ||
| 9 | ; BUFSEC | ||
| 10 | ; BUFRD | ||
| 11 | ; BUFWRT | ||
| 12 | ; NEXTSEC | ||
| 13 | ; OPTIMIZE | ||
| 14 | ; FIGREC | ||
| 15 | ; ALLOCATE | ||
| 16 | ; RESTFATBYT | ||
| 17 | ; RELEASE | ||
| 18 | ; RELBLKS | ||
| 19 | ; GETEOF | ||
| 20 | ; | ||
| 21 | ; Modification history: | ||
| 22 | ; | ||
| 23 | ; Created: ARR 30 March 1983 | ||
| 24 | ; | ||
| 25 | |||
| 26 | ; | ||
| 27 | ; get the appropriate segment definitions | ||
| 28 | ; | ||
| 29 | .xlist | ||
| 30 | include dosseg.asm | ||
| 31 | include fastseek.inc ; DOS 4.00 | ||
| 32 | include fastxxxx.inc ; DOS 4.00 | ||
| 33 | include version.inc | ||
| 34 | |||
| 35 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 36 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 37 | |||
| 38 | .xcref | ||
| 39 | INCLUDE DOSSYM.INC | ||
| 40 | INCLUDE DEVSYM.INC | ||
| 41 | include EA.inc | ||
| 42 | .cref | ||
| 43 | .list | ||
| 44 | |||
| 45 | i_need CLUSNUM,WORD | ||
| 46 | i_need NEXTADD,WORD | ||
| 47 | i_need LASTPOS,WORD | ||
| 48 | i_need SECCLUSPOS,BYTE | ||
| 49 | i_need FATBYT,WORD | ||
| 50 | i_need THISSFT,DWORD | ||
| 51 | i_need TRANS,BYTE | ||
| 52 | i_need BYTCNT1,WORD | ||
| 53 | i_need CURBUF,DWORD | ||
| 54 | i_need BYTSECPOS,WORD | ||
| 55 | i_need DMAADD,WORD | ||
| 56 | i_need SECPOS,DWORD ;F.C. >32mb | ||
| 57 | i_need VALSEC,DWORD ;F.C. >32mb | ||
| 58 | i_need ALLOWED,BYTE | ||
| 59 | i_need FSeek_drive,BYTE ; DOS 3.4 | ||
| 60 | i_need FSeek_firclus,WORD ; DOS 3.4 | ||
| 61 | i_need FSeek_logclus,WORD ; DOS 3.4 | ||
| 62 | i_need FSeek_logsave,WORD ; DOS 3.4 | ||
| 63 | i_need FastSeekFlg,BYTE ; DOS 3.4 | ||
| 64 | i_need XA_condition,BYTE ; DOS 3.4 | ||
| 65 | i_need HIGH_SECTOR,WORD ; DOS 3.4 | ||
| 66 | i_need DISK_FULL,BYTE ; DOS 3.4 | ||
| 67 | i_need Temp_VAR2,WORD ; DOS 3.4 | ||
| 68 | |||
| 69 | |||
| 70 | |||
| 71 | Break <FNDCLUS -- Skip over allocation units> | ||
| 72 | |||
| 73 | ; Inputs: | ||
| 74 | ; CX = No. of clusters to skip | ||
| 75 | ; ES:BP = Base of drive parameters | ||
| 76 | ; [THISSFT] point to SFT | ||
| 77 | ; Outputs: | ||
| 78 | ; BX = Last cluster skipped to | ||
| 79 | ; CX = No. of clusters remaining (0 unless EOF) | ||
| 80 | ; DX = Position of last cluster | ||
| 81 | ; Carry set if error (currently user FAILed to I 24) | ||
| 82 | ; DI destroyed. No other registers affected. | ||
| 83 | |||
| 84 | procedure FNDCLUS,NEAR | ||
| 85 | DOSAssume CS,<DS>,"FndClus" | ||
| 86 | ASSUME ES:NOTHING | ||
| 87 | |||
| 88 | Assert ISDPB,<ES,BP>,"FndCLus" | ||
| 89 | ;; 10/31/86 FastSeek | ||
| 90 | PUSH ES | ||
| 91 | LES DI,[THISSFT] | ||
| 92 | Assert ISSFT,<ES,DI>,"FndClus" | ||
| 93 | MOV [FSeek_logclus],CX ; presume CX is the position ;AN000; | ||
| 94 | MOV BX,ES:[DI.sf_lstclus] | ||
| 95 | MOV DX,ES:[DI.sf_cluspos] | ||
| 96 | ;; 10/31/86 FastSeek | ||
| 97 | OR BX,BX | ||
| 98 | JNZ YCLUS | ||
| 99 | JMP NOCLUS | ||
| 100 | YCLUS: | ||
| 101 | SUB CX,DX | ||
| 102 | JNB FINDIT | ||
| 103 | ADD CX,DX | ||
| 104 | XOR DX,DX | ||
| 105 | MOV BX,ES:[DI.sf_firclus] | ||
| 106 | FINDIT: | ||
| 107 | ;; 10/31/86 FastSeek | ||
| 108 | |||
| 109 | |||
| 110 | POP ES | ||
| 111 | OR CX,CX | ||
| 112 | JNZ skpclp | ||
| 113 | JMP RET10 | ||
| 114 | |||
| 115 | entry SKPCLP | ||
| 116 | TEST [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; | ||
| 117 | JZ do_norm ; no ;AN000; | ||
| 118 | TEST [FastSeekflg],FS_begin ; do fastseek ;AN000; | ||
| 119 | JZ do_norm ; no ;AN000; | ||
| 120 | TEST [FastSeekflg],FS_insert ; is in insert mode ? ;AN000; | ||
| 121 | JNZ do_norm ; yes ;AN000; | ||
| 122 | MOV [Temp_Var2],BX ; save physical cluster ;AN000; | ||
| 123 | ; PTR P005079 | ||
| 124 | SKPCLP2: | ||
| 125 | invoke FastSeek_Lookup ; ask for next cluster # ;AN000; | ||
| 126 | JNC clusfound ; yes, we got it ;AN000; | ||
| 127 | CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; | ||
| 128 | JNZ par_found ; yes, ;AN000; | ||
| 129 | AND [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; | ||
| 130 | JMP SHORT do_norm ;AN000; | ||
| 131 | ;AN000; | ||
| 132 | par_found: | ||
| 133 | CALL FS_Trunc_EOF ; check EOF and truncate ;AN000; | ||
| 134 | JNC SKPCLP2 ; redo lookup ;AN000; | ||
| 135 | noteof: | ||
| 136 | OR [FastSeekflg],FS_insert ; no, start to insert ;AN000; | ||
| 137 | CMP DX,[FSeek_logsave] ; is current better than new? ;AN000; | ||
| 138 | JBE OnCache ; no, let's use new ;AN000; | ||
| 139 | MOV [FSeek_logclus],DX ; use current ;AN000; | ||
| 140 | MOV BX,[Temp_Var2] ; retore pysical cluster ;AN000; | ||
| 141 | MOV DI,BX ; insert cureent cluster ;AN000; | ||
| 142 | invoke FastSeek_Insert ; insert cluster # to ;AN000; | ||
| 143 | INC [FSeek_logclus] ; get next inserted position ;AN000; | ||
| 144 | JMP SHORT do_norm | ||
| 145 | OnCache: | ||
| 146 | MOV CX,[FSeek_logclus] ; get the number of clusters ;AN000; | ||
| 147 | SUB CX,[FSeek_logsave] ; we need to skip ;AN000; | ||
| 148 | MOV DX,[FSeek_logsave] ; cluster position ;AN000; | ||
| 149 | dodo: | ||
| 150 | INC [FSeek_logsave] ; get next inserted position ;AN000; | ||
| 151 | PUSH [FSeek_logsave] ; logclus=logsave ;AN000; | ||
| 152 | POP [FSeek_logclus] ;AN000; | ||
| 153 | |||
| 154 | do_norm: | ||
| 155 | |||
| 156 | invoke UNPACK | ||
| 157 | retc | ||
| 158 | |||
| 159 | invoke FastSeek_Insert ; insert cluster # to ;AN000; | ||
| 160 | cluss: ;AN000; | ||
| 161 | PUSH BX ; FastSeek ;AN000; | ||
| 162 | MOV BX,DI | ||
| 163 | Invoke IsEOF | ||
| 164 | POP BX | ||
| 165 | JAE RET10 | ||
| 166 | XCHG BX,DI | ||
| 167 | INC DX | ||
| 168 | INC [FSeek_logclus] ; increment for next inserted ;AN000; | ||
| 169 | LOOP SKPCLPX | ||
| 170 | JMP short RET10 | ||
| 171 | SKPCLPX: | ||
| 172 | JMP SKPCLP | ||
| 173 | RET10: ;AN000; | ||
| 174 | AND [FastSeekflg],FS_no_insert ; clear insert mode | ||
| 175 | CLC | ||
| 176 | return | ||
| 177 | NOCLUS: | ||
| 178 | POP ES | ||
| 179 | INC CX | ||
| 180 | DEC DX | ||
| 181 | CLC | ||
| 182 | return | ||
| 183 | clusfound: | ||
| 184 | MOV DX,[FSeek_logclus] ; get cluster position ;AN000; | ||
| 185 | MOV BX,[FSeek_logsave] ; bx=previous cluster # PTM ;AN000; | ||
| 186 | DEC DX ;AN000; | ||
| 187 | MOV CX,1 ; we found it ;AN000; | ||
| 188 | JMP cluss ;AN000; | ||
| 189 | |||
| 190 | EndProc FNDCLUS | ||
| 191 | |||
| 192 | Break <BUFSEC -- BUFFER A SECTOR AND SET UP A TRANSFER> | ||
| 193 | |||
| 194 | ; Inputs: | ||
| 195 | ; AH = priority of buffer | ||
| 196 | ; AL = 0 if buffer must be read, 1 if no pre-read needed | ||
| 197 | ; ES:BP = Base of drive parameters | ||
| 198 | ; [CLUSNUM] = Physical cluster number | ||
| 199 | ; [SECCLUSPOS] = Sector position of transfer within cluster | ||
| 200 | ; [BYTCNT1] = Size of transfer | ||
| 201 | ; Function: | ||
| 202 | ; Insure specified sector is in buffer, flushing buffer before | ||
| 203 | ; read if necessary. | ||
| 204 | ; Outputs: | ||
| 205 | ; ES:DI = Pointer to buffer | ||
| 206 | ; SI = Pointer to transfer address | ||
| 207 | ; CX = Number of bytes | ||
| 208 | ; [NEXTADD] updated | ||
| 209 | ; [TRANS] set to indicate a transfer will occur | ||
| 210 | ; Carry set if error (user FAILed to I 24) | ||
| 211 | |||
| 212 | procedure BUFSEC,NEAR | ||
| 213 | DOSAssume CS,<DS>,"BufSec" | ||
| 214 | ASSUME ES:NOTHING | ||
| 215 | |||
| 216 | Assert ISDPB,<ES,BP>,"BufSec" | ||
| 217 | MOV DX,[CLUSNUM] | ||
| 218 | MOV BL,[SECCLUSPOS] | ||
| 219 | MOV [ALLOWED],allowed_FAIL + allowed_RETRY + allowed_IGNORE | ||
| 220 | CALL FIGREC | ||
| 221 | invoke GETBUFFR | ||
| 222 | retc | ||
| 223 | MOV BYTE PTR [TRANS],1 ; A transfer is taking place | ||
| 224 | MOV SI,[NEXTADD] | ||
| 225 | MOV DI,SI | ||
| 226 | MOV CX,[BYTCNT1] | ||
| 227 | ADD DI,CX | ||
| 228 | MOV [NEXTADD],DI | ||
| 229 | LES DI,[CURBUF] | ||
| 230 | Assert ISBUF,<ES,DI>,"BufSec" | ||
| 231 | OR ES:[DI.buf_flags],buf_isDATA | ||
| 232 | LEA DI,[DI].BUFINSIZ ; Point to buffer | ||
| 233 | ADD DI,[BYTSECPOS] | ||
| 234 | CLC | ||
| 235 | return | ||
| 236 | EndProc BUFSEC | ||
| 237 | |||
| 238 | Break <BUFRD, BUFWRT -- PERFORM BUFFERED READ AND WRITE> | ||
| 239 | |||
| 240 | ; Do a partial sector read via one of the system buffers | ||
| 241 | ; ES:BP Points to DPB | ||
| 242 | ; Carry set if error (currently user FAILed to I 24) | ||
| 243 | |||
| 244 | procedure BUFRD,NEAR | ||
| 245 | DOSAssume CS,<DS>,"BufRd" | ||
| 246 | ASSUME ES:NOTHING | ||
| 247 | |||
| 248 | Assert ISDPB,<ES,BP>,"BufRd" | ||
| 249 | PUSH ES | ||
| 250 | MOV AX,0 | ||
| 251 | CALL BUFSEC | ||
| 252 | JNC BUF_OK | ||
| 253 | BUF_IO_FAIL: | ||
| 254 | POP ES | ||
| 255 | JMP SHORT RBUFPLACED | ||
| 256 | |||
| 257 | BUF_OK: | ||
| 258 | MOV BX,ES | ||
| 259 | MOV ES,[DMAADD+2] | ||
| 260 | MOV DS,BX | ||
| 261 | ASSUME DS:NOTHING | ||
| 262 | XCHG DI,SI | ||
| 263 | SHR CX,1 | ||
| 264 | JNC EVENRD | ||
| 265 | MOVSB | ||
| 266 | EVENRD: | ||
| 267 | REP MOVSW | ||
| 268 | POP ES | ||
| 269 | LDS DI,[CURBUF] | ||
| 270 | Assert ISBUF,<DS,DI>,"BufRD/EvenRD" | ||
| 271 | LEA BX,[DI.BufInSiz] | ||
| 272 | SUB SI,BX ; Position in buffer | ||
| 273 | invoke PLACEBUF | ||
| 274 | Assert ISDPB,<ES,BP>,"BufRD/EvenRD" | ||
| 275 | CMP SI,ES:[BP.dpb_sector_size] ; Read Last byte? | ||
| 276 | JB RBUFPLACEDC ; No, leave buf where it is | ||
| 277 | invoke PLACEHEAD ; Make it prime candidate for chucking | ||
| 278 | ; even though it is MRU. | ||
| 279 | RBUFPLACEDC: | ||
| 280 | CLC | ||
| 281 | RBUFPLACED: | ||
| 282 | PUSH SS | ||
| 283 | POP DS | ||
| 284 | return | ||
| 285 | EndProc BUFRD | ||
| 286 | |||
| 287 | ; Do a partial sector write via one of the system buffers | ||
| 288 | ; ES:BP Points to DPB | ||
| 289 | ; Carry set if error (currently user FAILed to I 24) | ||
| 290 | |||
| 291 | procedure BUFWRT,NEAR | ||
| 292 | DOSAssume CS,<DS>,"BufWrt" | ||
| 293 | ASSUME ES:NOTHING | ||
| 294 | |||
| 295 | Assert ISDPB,<ES,BP>,"BufWrt" | ||
| 296 | MOV AX,WORD PTR [SECPOS] | ||
| 297 | ADD AX,1 ; Set for next sector | ||
| 298 | MOV WORD PTR [SECPOS],AX ;F.C. >32mb ;AN000; | ||
| 299 | ADC WORD PTR [SECPOS+2],0 ;F.C. >32mb ;AN000; | ||
| 300 | MOV AX,WORD PTR [SECPOS+2] ;F.C. >32mb ;AN000; | ||
| 301 | CMP AX,WORD PTR [VALSEC+2] ;F.C. >32mb ;AN000; | ||
| 302 | MOV AL,1 ;F.C. >32mb ;AN000; | ||
| 303 | JA NOREAD ;F.C. >32mb ;AN000; | ||
| 304 | JB doread ;F.C. >32mb ;AN000; | ||
| 305 | MOV AX,WORD PTR [SECPOS] ;F.C. >32mb ;AN000; | ||
| 306 | CMP AX,WORD PTR [VALSEC] ; Has sector been written before? | ||
| 307 | MOV AL,1 | ||
| 308 | JA NOREAD ; Skip preread if SECPOS>VALSEC | ||
| 309 | doread: | ||
| 310 | XOR AL,AL | ||
| 311 | NOREAD: | ||
| 312 | PUSH ES | ||
| 313 | CALL BUFSEC | ||
| 314 | JC BUF_IO_FAIL | ||
| 315 | MOV DS,[DMAADD+2] | ||
| 316 | ASSUME DS:NOTHING | ||
| 317 | SHR CX,1 | ||
| 318 | JNC EVENWRT | ||
| 319 | MOVSB | ||
| 320 | EVENWRT: | ||
| 321 | REP MOVSW | ||
| 322 | POP ES | ||
| 323 | LDS BX,[CURBUF] | ||
| 324 | Assert ISBUF,<DS,BX>,"BufWrt/EvenWrt" | ||
| 325 | |||
| 326 | TEST [BX.buf_flags],buf_dirty ;LB. if already dirty ;AN000; | ||
| 327 | JNZ yesdirty ;LB. don't increment dirty count ;AN000; | ||
| 328 | invoke INC_DIRTY_COUNT ;LB. ;AN000; | ||
| 329 | OR [BX.buf_flags],buf_dirty | ||
| 330 | yesdirty: | ||
| 331 | LEA SI,[BX.BufInSiz] | ||
| 332 | SUB DI,SI ; Position in buffer | ||
| 333 | MOV SI,DI | ||
| 334 | MOV DI,BX | ||
| 335 | invoke PLACEBUF | ||
| 336 | Assert ISDPB,<ES,BP>,"BufWrt/EvenWrt" | ||
| 337 | CMP SI,ES:[BP.dpb_sector_size] ; Written last byte? | ||
| 338 | JB WBUFPLACED ; No, leave buf where it is | ||
| 339 | invoke PLACEHEAD ; Make it prime candidate for chucking | ||
| 340 | ; even though it is MRU. | ||
| 341 | WBUFPLACED: | ||
| 342 | CLC | ||
| 343 | PUSH SS | ||
| 344 | POP DS | ||
| 345 | return | ||
| 346 | EndProc BUFWRT | ||
| 347 | |||
| 348 | Break <NEXTSEC -- Compute next sector to read or write> | ||
| 349 | |||
| 350 | ; Compute the next sector to read or write | ||
| 351 | ; ES:BP Points to DPB | ||
| 352 | |||
| 353 | procedure NEXTSEC,NEAR | ||
| 354 | DOSAssume CS,<DS>,"NextSec" | ||
| 355 | ASSUME ES:NOTHING | ||
| 356 | |||
| 357 | Assert ISDPB,<ES,BP>,"NextSec" | ||
| 358 | TEST BYTE PTR [TRANS],-1 | ||
| 359 | JZ CLRET | ||
| 360 | MOV AL,[SECCLUSPOS] | ||
| 361 | INC AL | ||
| 362 | CMP AL,ES:[BP.dpb_cluster_mask] | ||
| 363 | JBE SAVPOS | ||
| 364 | MOV BX,[CLUSNUM] | ||
| 365 | Invoke IsEOF | ||
| 366 | JAE NONEXT | ||
| 367 | ;; 11/5/86 FastSeek | ||
| 368 | TEST [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; | ||
| 369 | JZ do_norm2 ; no ;AN000; | ||
| 370 | PUSH [LASTPOS] ; save logical cluster # ;AN000; | ||
| 371 | POP [FSeek_logclus] ;AN000; | ||
| 372 | INC [FSeek_logclus] ; get next cluster ;AN000; | ||
| 373 | ;AN000; | ||
| 374 | TEST [FastSeekflg],FS_begin ; from R/W ;AN000; | ||
| 375 | JZ do_norm2 ; no ;AN000; | ||
| 376 | look2: ;AN000; | ||
| 377 | invoke FastSeek_Lookup ; call lookup ;AN000; | ||
| 378 | JNC clusgot ; found one ;AN000; | ||
| 379 | |||
| 380 | CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; | ||
| 381 | JNZ parfound2 ; yes, ;AN000; | ||
| 382 | AND [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; | ||
| 383 | JMP SHORT do_norm2 ;AN000; | ||
| 384 | parfound2: | ||
| 385 | CALL FS_TRUNC_EOF ; check EOF ;AN000; | ||
| 386 | MOV BX,[CLUSNUM] ; don't need partially found cluster | ||
| 387 | OR [FastSeekflg],FS_insert ; prepared for cluster insertion ;AN000; | ||
| 388 | ; use the old bx ;AN000; | ||
| 389 | ;AN000; | ||
| 390 | do_norm2: | ||
| 391 | invoke UNPACK | ||
| 392 | JC NONEXT | ||
| 393 | invoke FastSeek_Insert ; call insert ;AN000; | ||
| 394 | AND [FastSeekflg],FS_no_insert ; clear insert flag ;AN000; | ||
| 395 | ;AN000; | ||
| 396 | clusgot: | ||
| 397 | ;; 11/5/86 FastSeek | ||
| 398 | MOV [CLUSNUM],DI | ||
| 399 | INC [LASTPOS] | ||
| 400 | MOV AL,0 | ||
| 401 | SAVPOS: | ||
| 402 | MOV [SECCLUSPOS],AL | ||
| 403 | CLRET: | ||
| 404 | CLC | ||
| 405 | return | ||
| 406 | NONEXT: | ||
| 407 | STC | ||
| 408 | return | ||
| 409 | EndProc NEXTSEC | ||
| 410 | |||
| 411 | Break <OPTIMIZE -- DO A USER DISK REQUEST WELL> | ||
| 412 | |||
| 413 | ; Inputs: | ||
| 414 | ; BX = Physical cluster | ||
| 415 | ; CX = No. of records | ||
| 416 | ; DL = sector within cluster | ||
| 417 | ; ES:BP = Base of drives parameters | ||
| 418 | ; [NEXTADD] = transfer address | ||
| 419 | ; Outputs: | ||
| 420 | ; AX = No. of records remaining | ||
| 421 | ; BX = Transfer address | ||
| 422 | ; CX = No. or records to be transferred | ||
| 423 | ; DX = Physical sector address (LOW) | ||
| 424 | ; [HIGH_SECTOR] = Physical sector address (HIGH) | ||
| 425 | ; DI = Next cluster | ||
| 426 | ; [CLUSNUM] = Last cluster accessed | ||
| 427 | ; [NEXTADD] updated | ||
| 428 | ; Carry set if error (currently user FAILed to I 24) | ||
| 429 | ; ES:BP unchanged. Note that segment of transfer not set. | ||
| 430 | |||
| 431 | procedure OPTIMIZE,NEAR | ||
| 432 | DOSAssume CS,<DS>,"Optimize" | ||
| 433 | ASSUME ES:NOTHING | ||
| 434 | |||
| 435 | Assert ISDPB,<ES,BP>,"Optimize" | ||
| 436 | PUSH DX | ||
| 437 | PUSH BX | ||
| 438 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 439 | INC AL ; Number of sectors per cluster | ||
| 440 | MOV AH,AL | ||
| 441 | SUB AL,DL ; AL = Number of sectors left in first cluster | ||
| 442 | MOV DX,CX | ||
| 443 | MOV CX,0 | ||
| 444 | ;;; 11/5/86 FastSeek | ||
| 445 | PUSH [LASTPOS] ; save logical cluster # ;AN000; | ||
| 446 | POP [FSeek_logclus] ;AN000; | ||
| 447 | INC [FSeek_logclus] ; get next cluster ;AN000; | ||
| 448 | ;AN000; | ||
| 449 | OPTCLUS: | ||
| 450 | ; AL has number of sectors available in current cluster | ||
| 451 | ; AH has number of sectors available in next cluster | ||
| 452 | ; BX has current physical cluster | ||
| 453 | ; CX has number of sequential sectors found so far | ||
| 454 | ; DX has number of sectors left to transfer | ||
| 455 | ; ES:BP Points to DPB | ||
| 456 | ; ES:SI has FAT pointer | ||
| 457 | |||
| 458 | TEST [FastSeekflg],Fast_yes ; fastseek installed? ;AN000; | ||
| 459 | JZ do_norm3 ; no ;AN000; | ||
| 460 | TEST [FastSeekflg],FS_begin ; from R/W ;AN000; | ||
| 461 | JZ do_norm3 ; no ;AN000; | ||
| 462 | TEST [FastSeekflg],FS_insert ; is in insert mode ? ;AN000; | ||
| 463 | JNZ do_norm3 ; yes ;AN000; | ||
| 464 | invoke FastSeek_Lookup ; call lookup ;AN000; | ||
| 465 | JNC clusgot2 ; found one ;AN000; | ||
| 466 | |||
| 467 | CMP DI,1 ; valid drive ,e.g. C,D... ;AN000; | ||
| 468 | JNZ par_found3 ; yes, ;AN000; | ||
| 469 | AND [FastSeekflg],Fast_yes ; no more, fastseek ;AN000; | ||
| 470 | JMP SHORT do_norm3 ;AN000; | ||
| 471 | par_found3: | ||
| 472 | PUSH BX | ||
| 473 | CALL FS_TRUNC_EOF ; file entry not existing ;AN000; | ||
| 474 | POP BX ;AN000; | ||
| 475 | OR [FastSeekflg],FS_insert ; prepare for insertion ;AN000; | ||
| 476 | ; use old bx ;AN000; | ||
| 477 | do_norm3: | ||
| 478 | invoke UNPACK | ||
| 479 | JC OP_ERR | ||
| 480 | clusgot2: | ||
| 481 | invoke FastSeek_Insert ; call insert ;AN000; | ||
| 482 | INC [FSeek_logclus] ; insert to next position ;AN000; | ||
| 483 | ;;; 11/5/86 FastSeek ;AN000; | ||
| 484 | ADD CL,AL | ||
| 485 | ADC CH,0 | ||
| 486 | CMP CX,DX | ||
| 487 | JAE BLKDON | ||
| 488 | MOV AL,AH | ||
| 489 | INC BX | ||
| 490 | CMP DI,BX | ||
| 491 | JZ OPTCLUS | ||
| 492 | DEC BX | ||
| 493 | FINCLUS: | ||
| 494 | MOV [CLUSNUM],BX ; Last cluster accessed | ||
| 495 | SUB DX,CX ; Number of sectors still needed | ||
| 496 | PUSH DX | ||
| 497 | MOV AX,CX | ||
| 498 | MUL ES:[BP.dpb_sector_size] ; Number of sectors times sector size | ||
| 499 | MOV SI,[NEXTADD] | ||
| 500 | ADD AX,SI ; Adjust by size of transfer | ||
| 501 | MOV [NEXTADD],AX | ||
| 502 | POP AX ; Number of sectors still needed | ||
| 503 | POP DX ; Starting cluster | ||
| 504 | SUB BX,DX ; Number of new clusters accessed | ||
| 505 | ADD [LASTPOS],BX | ||
| 506 | POP BX ; BL = sector postion within cluster | ||
| 507 | invoke FIGREC | ||
| 508 | MOV BX,SI | ||
| 509 | AND [FastSeekflg],FS_no_insert ; clear insert flag | ||
| 510 | CLC | ||
| 511 | return | ||
| 512 | |||
| 513 | OP_ERR: | ||
| 514 | ADD SP,4 | ||
| 515 | AND [FastSeekflg],FS_no_insert ; clear insert flag | ||
| 516 | STC | ||
| 517 | return | ||
| 518 | |||
| 519 | BLKDON: | ||
| 520 | SUB CX,DX ; Number of sectors in cluster we don't want | ||
| 521 | SUB AH,CL ; Number of sectors in cluster we accepted | ||
| 522 | DEC AH ; Adjust to mean position within cluster | ||
| 523 | MOV [SECCLUSPOS],AH | ||
| 524 | MOV CX,DX ; Anyway, make the total equal to the request | ||
| 525 | JMP SHORT FINCLUS | ||
| 526 | EndProc OPTIMIZE | ||
| 527 | |||
| 528 | Break <FIGREC -- Figure sector in allocation unit> | ||
| 529 | |||
| 530 | ; Inputs: | ||
| 531 | ; DX = Physical cluster number | ||
| 532 | ; BL = Sector postion within cluster | ||
| 533 | ; ES:BP = Base of drive parameters | ||
| 534 | ; Outputs: | ||
| 535 | ; DX = physical sector number (LOW) | ||
| 536 | ; [HIGH_SECTOR] Physical sector address (HIGH) | ||
| 537 | ; No other registers affected. | ||
| 538 | |||
| 539 | procedure FIGREC,NEAR | ||
| 540 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 541 | |||
| 542 | Assert ISDPB,<ES,BP>,"FigRec" | ||
| 543 | PUSH CX | ||
| 544 | MOV CL,ES:[BP.dpb_cluster_shift] | ||
| 545 | DEC DX | ||
| 546 | DEC DX | ||
| 547 | MOV [HIGH_SECTOR],0 ;F.C. >32mb | ||
| 548 | OR CL,CL ;F.C. >32mb | ||
| 549 | JZ noshift ;F.C. >32mb | ||
| 550 | XOR CH,CH ;F.C. >32mb | ||
| 551 | rotleft: ;F.C. >32mb | ||
| 552 | CLC ;F.C. >32mb | ||
| 553 | RCL DX,1 ;F.C. >32mb | ||
| 554 | RCL [HIGH_SECTOR],1 ;F.C. >32mb | ||
| 555 | LOOP rotleft ;F.C. >32mb | ||
| 556 | noshift: | ||
| 557 | |||
| 558 | ; SHL DX,CL | ||
| 559 | OR DL,BL | ||
| 560 | ADD DX,ES:[BP.dpb_first_sector] | ||
| 561 | ADC [HIGH_SECTOR],0 ;F.C. >32mb | ||
| 562 | POP CX | ||
| 563 | return | ||
| 564 | EndProc FIGREC | ||
| 565 | |||
| 566 | Break <ALLOCATE -- Assign disk space> | ||
| 567 | |||
| 568 | ;*** ALLOCATE - Allocate Disk Space | ||
| 569 | ; | ||
| 570 | ; ALLOCATE is called to allocate disk clusters. The new clusters are | ||
| 571 | ; FAT-chained onto the end of the existing file. | ||
| 572 | ; | ||
| 573 | ; The DPB contains the cluster # of the last free cluster allocated | ||
| 574 | ; (dpb_next_free). We start at this cluster and scan towards higher | ||
| 575 | ; numbered clusters, looking for the necessary free blocks. | ||
| 576 | ; | ||
| 577 | ; Once again, fancy terminology gets in the way of corrct coding. When | ||
| 578 | ; using next_free, start scanning AT THAT POINT and not the one following it. | ||
| 579 | ; This fixes the boundary condition bug when only free = next_free = 2. | ||
| 580 | ; | ||
| 581 | ; If we get to the end of the disk without satisfaction: | ||
| 582 | ; | ||
| 583 | ; if (dpb_next_free == 2) then we've scanned the whole disk. | ||
| 584 | ; return (insufficient_disk_space) | ||
| 585 | ; ELSE | ||
| 586 | ; dpb_next_free = 2; start scan over from the beginning. | ||
| 587 | ; | ||
| 588 | ; Note that there is no multitasking interlock. There is no race when | ||
| 589 | ; examining the entrys in an in-core FAT block since there will be no | ||
| 590 | ; context switch. When UNPACK context switches while waiting for a FAT read | ||
| 591 | ; we are done with any in-core FAT blocks, so again there is no race. The | ||
| 592 | ; only special concern is that V2 and V3 MSDOS left the last allocated | ||
| 593 | ; cluster as "00"; marking it EOF only when the entire alloc request was | ||
| 594 | ; satisfied. We can't allow another activation to think this cluster is | ||
| 595 | ; free, so we give it a special temporary mark to show that it is, indeed, | ||
| 596 | ; allocated. | ||
| 597 | ; | ||
| 598 | ; Note that when we run out of space this algorithem will scan from | ||
| 599 | ; dpb_next_free to the end, then scan from cluster 2 through the end, | ||
| 600 | ; redundantly scanning the later part of the disk. This only happens when | ||
| 601 | ; we run out of space, so sue me. | ||
| 602 | ; | ||
| 603 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 604 | ; C A V E A T P A T T E R S O N ; | ||
| 605 | ; ; | ||
| 606 | ; The use of FATBYT and RESTFATBYT is somewhat mysterious. Here is the | ||
| 607 | ; explanation: | ||
| 608 | ; | ||
| 609 | ; In the NUL file case (sf_firclus currently 0) ALLOCATE is called with | ||
| 610 | ; entry BX = 0. What needs to be done in this case is to stuff the cluster | ||
| 611 | ; number of the first cluster allocated in sf_firclus when the ALLOCATE is | ||
| 612 | ; complete. THIS VALUE IS SAVED TEMPORARILY IN CLUSTER 0, HENCE THE CURRENT | ||
| 613 | ; VALUE IN CLUSTER 0 MUST BE SAVED AND RESTORED. This is a side effect of | ||
| 614 | ; the fact that PACK and UNPACK don't treat requests for clusters 0 and 1 as | ||
| 615 | ; errors. This "stuff" is done by the call to PACK which is right before | ||
| 616 | ; the | ||
| 617 | ; LOOP findfre ; alloc more if needed | ||
| 618 | ; instruction when the first cluster is allocated to the nul file. The | ||
| 619 | ; value is recalled from cluster 0 and stored at sf_firclus at ads4: | ||
| 620 | ; | ||
| 621 | ; This method is obviously useless (because it is non-reentrant) for | ||
| 622 | ; multitasking, and will have to be changed. Storing the required value on | ||
| 623 | ; the stack is recommended. Setting sf_firclus at the PACK of cluster 0 | ||
| 624 | ; (instead of actually doing the PACK) is BAD because it doesn't handle | ||
| 625 | ; problems with INT 24 well. | ||
| 626 | ; | ||
| 627 | ; C A V E A T P A T T E R S O N ; | ||
| 628 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 629 | ; ; | ||
| 630 | ; ENTRY BX = Last cluster of file (0 if null file) | ||
| 631 | ; CX = No. of clusters to allocate | ||
| 632 | ; ES:BP = Base of drive parameters | ||
| 633 | ; [THISSFT] = Points to SFT | ||
| 634 | ; | ||
| 635 | ; EXIT 'C' set if insufficient space | ||
| 636 | ; [FAILERR] can be tested to see the reason for failure | ||
| 637 | ; CX = max. no. of clusters that could be added to file | ||
| 638 | ; 'C' clear if space allocated | ||
| 639 | ; BX = First cluster allocated | ||
| 640 | ; FAT is fully updated | ||
| 641 | ; sf_FIRCLUS field of SFT set if file was null | ||
| 642 | ; | ||
| 643 | ; USES ALL but SI, BP | ||
| 644 | |||
| 645 | PROCEDURE ALLOCATE,NEAR | ||
| 646 | |||
| 647 | DOSAssume CS,<DS>,"Allocate" | ||
| 648 | ASSUME ES:NOTHING | ||
| 649 | |||
| 650 | Assert ISDPB,<ES,BP>,"Allocate" | ||
| 651 | PUSH BX ; save (bx) | ||
| 652 | XOR BX,BX | ||
| 653 | invoke UNPACK | ||
| 654 | MOV [FATBYT],DI ; save correct cluster 0 value | ||
| 655 | POP BX | ||
| 656 | retc ; abort if error [INTERR?] | ||
| 657 | |||
| 658 | PUSH CX | ||
| 659 | PUSH BX | ||
| 660 | |||
| 661 | MOV DX,BX | ||
| 662 | Assert ISDPB,<ES,BP>,"Allocate/Unpack" | ||
| 663 | mov bx,es:[bp.dpb_next_free] | ||
| 664 | cmp bx,2 | ||
| 665 | ja findfre | ||
| 666 | |||
| 667 | ; couldn't find enough free space beyond dpb_next_free, or dpb_next_free is | ||
| 668 | ; <2 or >dpb_max_clus. Reset it and restart the scan | ||
| 669 | |||
| 670 | ads1: | ||
| 671 | Assert ISDPB,<ES,BP>,"Alloc/ads1" | ||
| 672 | mov es:[bp.dpb_next_free],2 | ||
| 673 | mov bx,1 ; Counter next instruction so first | ||
| 674 | ; cluster examined is 2 | ||
| 675 | |||
| 676 | ; Scanning both forwards and backwards for a free cluster | ||
| 677 | ; | ||
| 678 | ; (BX) = forwards scan pointer | ||
| 679 | ; (CX) = clusters remaining to be allocated | ||
| 680 | ; (DX) = current last cluster in file | ||
| 681 | ; (TOS) = last cluster of file | ||
| 682 | |||
| 683 | FINDFRE: | ||
| 684 | INC BX | ||
| 685 | Assert ISDPB,<ES,BP>,"Alloc/findfre" | ||
| 686 | CMP BX,ES:[BP.dpb_max_cluster] | ||
| 687 | JBE aupk | ||
| 688 | jmp ads7 ; at end of disk | ||
| 689 | aupk: | ||
| 690 | invoke UNPACK ; check out this cluster | ||
| 691 | jc ads4 ; FAT error [INTERR?] | ||
| 692 | jnz findfre ; not free, keep on truckin | ||
| 693 | |||
| 694 | ; Have found a free cluster. Chain it to the file | ||
| 695 | ; | ||
| 696 | ; (BX) = found free cluster # | ||
| 697 | ; (DX) = current last cluster in file | ||
| 698 | |||
| 699 | mov es:[bp.dpb_next_free],bx ; next time start search here | ||
| 700 | xchg ax,dx ; save (dx) in ax | ||
| 701 | mov dx,1 ; mark this free guy as "1" | ||
| 702 | invoke PACK ; set special "temporary" mark | ||
| 703 | jc ads4 ; FAT error [INTERR?] | ||
| 704 | CMP ES:[BP.dpb_free_cnt],-1 ; Free count valid? | ||
| 705 | JZ NO_ALLOC ; No | ||
| 706 | DEC ES:[BP.dpb_free_cnt] ; Reduce free count by 1 | ||
| 707 | NO_ALLOC: | ||
| 708 | xchg ax,dx ; (dx) = current last cluster in file | ||
| 709 | XCHG BX,DX | ||
| 710 | MOV AX,DX | ||
| 711 | invoke PACK ; link free cluster onto file | ||
| 712 | ; CAVEAT.. On Nul file, first pass stuffs | ||
| 713 | ; cluster 0 with FIRCLUS value. | ||
| 714 | jc ads4 ; FAT error [INTERR?] | ||
| 715 | xchg BX,AX ; (BX) = last one we looked at | ||
| 716 | mov dx,bx ; (dx) = current end of file | ||
| 717 | LOOP findfre ; alloc more if needed | ||
| 718 | |||
| 719 | ; We've successfully extended the file. Clean up and exit | ||
| 720 | ; | ||
| 721 | ; (BX) = last cluster in file | ||
| 722 | |||
| 723 | MOV DX,0FFFFH | ||
| 724 | invoke PACK ; mark last cluster EOF | ||
| 725 | |||
| 726 | ; Note that FAT errors jump here to clean the stack and exit. this saves us | ||
| 727 | ; 2 whole bytes. Hope its worth it... | ||
| 728 | ; | ||
| 729 | ; 'C' set iff error | ||
| 730 | ; calling (BX) and (CX) pushed on stack | ||
| 731 | |||
| 732 | ads4: POP BX | ||
| 733 | POP CX ; Don't need this stuff since we're successful | ||
| 734 | retc | ||
| 735 | invoke UNPACK ; Get first cluster allocated for return | ||
| 736 | ; CAVEAT... In nul file case, UNPACKs cluster 0. | ||
| 737 | retc | ||
| 738 | invoke RESTFATBYT ; Restore correct cluster 0 value | ||
| 739 | retc | ||
| 740 | XCHG BX,DI ; (DI) = last cluster in file upon our entry | ||
| 741 | OR DI,DI ; clear 'C' | ||
| 742 | retnz ; we were extending an existing file | ||
| 743 | |||
| 744 | ; We were doing the first allocation for a new file. Update the SFT cluster | ||
| 745 | ; info | ||
| 746 | ;; Extended Attributes | ||
| 747 | ; TEST [XA_condition],XA_No_SFT ;FT. don't update SFT when from ;AN000; | ||
| 748 | ; JZ dofastk ;FT. GetSet_XA ;AN000; | ||
| 749 | ; AND [XA_condition],not XA_No_SFT ;FT. clear the bit ;AN000; | ||
| 750 | ; CLC ;FT. ;AN000; | ||
| 751 | ; ret ;FT. ;AN000; | ||
| 752 | ;; 11/6/86 FastSeek | ||
| 753 | dofastk: | ||
| 754 | PUSH DX | ||
| 755 | MOV DL,ES:[BP.dpb_drive] ; get drive # | ||
| 756 | |||
| 757 | PUSH ES | ||
| 758 | LES DI,[THISSFT] | ||
| 759 | Assert ISSFT,<ES,DI>,"Allocate/ads4" | ||
| 760 | MOV ES:[DI.sf_firclus],BX | ||
| 761 | MOV ES:[DI.sf_lstclus],BX | ||
| 762 | |||
| 763 | TEST [FastSeekflg],Fast_yes ; fastseek installed | ||
| 764 | JZ do_norm5 ; no | ||
| 765 | TEST [FastSeekflg],FS_begin ; do fastseek | ||
| 766 | JZ do_norm5 ; no | ||
| 767 | PUSH CX | ||
| 768 | MOV CX,BX ; set up firclus # | ||
| 769 | MOV [FSeek_firclus],BX ; update firclus varible | ||
| 770 | invoke FastSeek_Open ; create this file entry | ||
| 771 | POP CX | ||
| 772 | do_norm5: | ||
| 773 | POP ES | ||
| 774 | ;; 11/6/86 FastSeek | ||
| 775 | POP DX | ||
| 776 | return | ||
| 777 | |||
| 778 | |||
| 779 | ;** we're at the end of the disk, and not satisfied. See if we've scanned ALL | ||
| 780 | ; of the disk... | ||
| 781 | |||
| 782 | ads7: cmp es:[bp.dpb_next_free],2 | ||
| 783 | if not debug | ||
| 784 | jz tmplab2 ; | ||
| 785 | jmp ads1 ; start scan from front of disk | ||
| 786 | tmplab2: | ||
| 787 | else | ||
| 788 | jz tmplab | ||
| 789 | jmp ads1 | ||
| 790 | tmplab: | ||
| 791 | endif | ||
| 792 | |||
| 793 | ; Sorry, we've gone over the whole disk, with insufficient luck. Lets give | ||
| 794 | ; the space back to the free list and tell the caller how much he could have | ||
| 795 | ; had. We have to make sure we remove the "special mark" we put on the last | ||
| 796 | ; cluster we were able to allocate, so it doesn't become orphaned. | ||
| 797 | ; | ||
| 798 | ; (CX) = clusters remaining to be allocated | ||
| 799 | ; (TOS) = last cluster of file (before call to ALLOCATE) | ||
| 800 | ; (TOS+1) = # of clusters wanted to allocate | ||
| 801 | |||
| 802 | |||
| 803 | POP BX ; (BX) = last cluster of file | ||
| 804 | MOV DX,0FFFFH | ||
| 805 | invoke RELBLKS ; give back any clusters just alloced | ||
| 806 | POP AX ; No. of clusters requested | ||
| 807 | ; Don't "retc". We are setting Carry anyway, | ||
| 808 | ; Alloc failed, so proceed with return CX | ||
| 809 | ; setup. | ||
| 810 | SUB AX,CX ; AX=No. of clusters allocated | ||
| 811 | invoke RESTFATBYT ; Don't "retc". We are setting Carry anyway, | ||
| 812 | ; Alloc failed. | ||
| 813 | ; fmt <>,<>,<"$p: disk full in allocate\n"> | ||
| 814 | MOV [DISK_FULL],1 ;MS. indicating disk full | ||
| 815 | STC | ||
| 816 | return | ||
| 817 | |||
| 818 | EndProc ALLOCATE | ||
| 819 | |||
| 820 | ; SEE ALLOCATE CAVEAT | ||
| 821 | ; Carry set if error (currently user FAILed to I 24) | ||
| 822 | |||
| 823 | procedure RESTFATBYT,NEAR | ||
| 824 | DOSAssume CS,<DS>,"RestFATByt" | ||
| 825 | ASSUME ES:NOTHING | ||
| 826 | |||
| 827 | PUSH BX | ||
| 828 | PUSH DX | ||
| 829 | PUSH DI | ||
| 830 | XOR BX,BX | ||
| 831 | MOV DX,[FATBYT] | ||
| 832 | invoke PACK | ||
| 833 | POP DI | ||
| 834 | POP DX | ||
| 835 | POP BX | ||
| 836 | return | ||
| 837 | EndProc RESTFATBYT | ||
| 838 | |||
| 839 | Break <RELEASE -- DEASSIGN DISK SPACE> | ||
| 840 | |||
| 841 | ; Inputs: | ||
| 842 | ; BX = Cluster in file | ||
| 843 | ; ES:BP = Base of drive parameters | ||
| 844 | ; Function: | ||
| 845 | ; Frees cluster chain starting with [BX] | ||
| 846 | ; Carry set if error (currently user FAILed to I 24) | ||
| 847 | ; AX,BX,DX,DI all destroyed. Other registers unchanged. | ||
| 848 | |||
| 849 | procedure RELEASE,NEAR | ||
| 850 | DOSAssume CS,<DS>,"Release" | ||
| 851 | ASSUME ES:NOTHING | ||
| 852 | |||
| 853 | XOR DX,DX | ||
| 854 | entry RELBLKS | ||
| 855 | DOSAssume CS,<DS>,"RelBlks" | ||
| 856 | Assert ISDPB,<ES,BP>,"RelBlks" | ||
| 857 | |||
| 858 | ; Enter here with DX=0FFFFH to put an end-of-file mark in the first cluster | ||
| 859 | ; and free the rest in the chain. | ||
| 860 | |||
| 861 | invoke UNPACK | ||
| 862 | retc | ||
| 863 | retz | ||
| 864 | MOV AX,DI | ||
| 865 | PUSH DX | ||
| 866 | invoke PACK | ||
| 867 | POP DX | ||
| 868 | retc | ||
| 869 | OR DX,DX | ||
| 870 | JNZ NO_DEALLOC ; Was putting EOF mark | ||
| 871 | CMP ES:[BP.dpb_free_cnt],-1 ; Free count valid? | ||
| 872 | JZ NO_DEALLOC ; No | ||
| 873 | INC ES:[BP.dpb_free_cnt] ; Increase free count by 1 | ||
| 874 | NO_DEALLOC: | ||
| 875 | MOV BX,AX | ||
| 876 | dec ax ; check for "1" | ||
| 877 | retz ; is last cluster of incomplete chain | ||
| 878 | Invoke IsEOF | ||
| 879 | JB RELEASE ; Carry clear if JMP not taken | ||
| 880 | ret12: return | ||
| 881 | EndProc RELEASE | ||
| 882 | |||
| 883 | Break <GETEOF -- Find the end of a file> | ||
| 884 | |||
| 885 | ; Inputs: | ||
| 886 | ; ES:BP Points to DPB | ||
| 887 | ; BX = Cluster in a file | ||
| 888 | ; DS = CS | ||
| 889 | ; Outputs: | ||
| 890 | ; BX = Last cluster in the file | ||
| 891 | ; Carry set if error (currently user FAILed to I 24) | ||
| 892 | ; DI destroyed. No other registers affected. | ||
| 893 | |||
| 894 | procedure GETEOF,NEAR | ||
| 895 | DOSAssume CS,<DS>,"GetEOF" | ||
| 896 | ASSUME ES:NOTHING | ||
| 897 | |||
| 898 | Assert ISDPB,<ES,BP>,"GetEof" | ||
| 899 | invoke UNPACK | ||
| 900 | retc | ||
| 901 | PUSH BX | ||
| 902 | MOV BX,DI | ||
| 903 | Invoke IsEOF | ||
| 904 | POP BX | ||
| 905 | JAE RET12 ; Carry clear if jmp | ||
| 906 | MOV BX,DI | ||
| 907 | JMP GETEOF | ||
| 908 | EndProc GETEOF | ||
| 909 | |||
| 910 | Break <FS_TRUNC_EOF - truncate EOF for Fastseek> | ||
| 911 | |||
| 912 | ; Inputs: | ||
| 913 | ; ES:BP Points to DPB | ||
| 914 | ; BX = Cluster in a file | ||
| 915 | ; Functions: if BX=EOF then truncate it from Fastseek Cache | ||
| 916 | ; Outputs: | ||
| 917 | ; carry set: not EOF | ||
| 918 | ; carry clear: EOF and do truncate | ||
| 919 | |||
| 920 | procedure FS_TRUNC_EOF,NEAR | ||
| 921 | ASSUME ES:NOTHING,DS:NOTHING | ||
| 922 | |||
| 923 | MOV BX,DI ; get beginning physical# ;AN000; | ||
| 924 | invoke IsEOF ; is EOF ;AN000; | ||
| 925 | JB noteof2 ; no ;AN000; | ||
| 926 | PUSH [FSeek_logclus] ; ;AN000; | ||
| 927 | PUSH [FSeek_logsave] ; logclus=logsave ;AN000; | ||
| 928 | POP [FSeek_logclus] ; delete EOF ;AN000; | ||
| 929 | invoke FastSeek_Truncate ; ;AN000; | ||
| 930 | POP [FSeek_logclus] ; redo the look up ;AN000; | ||
| 931 | CLC ;AN000; | ||
| 932 | noteof2: ;AN000; | ||
| 933 | return ;AN000; | ||
| 934 | EndProc FS_TRUNC_EOF ;AN000; | ||
| 935 | |||
| 936 | CODE ENDS | ||
| 937 | END | ||
| 938 | \ No newline at end of file | ||