diff options
Diffstat (limited to 'v2.0/source/GETSET.ASM')
| -rw-r--r-- | v2.0/source/GETSET.ASM | 627 |
1 files changed, 627 insertions, 0 deletions
diff --git a/v2.0/source/GETSET.ASM b/v2.0/source/GETSET.ASM new file mode 100644 index 0000000..289f4c8 --- /dev/null +++ b/v2.0/source/GETSET.ASM | |||
| @@ -0,0 +1,627 @@ | |||
| 1 | TITLE GETSET - GETting and SETting MS-DOS system calls | ||
| 2 | NAME GETSET | ||
| 3 | ; | ||
| 4 | ; System Calls which get and set various things | ||
| 5 | ; | ||
| 6 | ; $GET_VERSION | ||
| 7 | ; $GET_VERIFY_ON_WRITE | ||
| 8 | ; $SET_VERIFY_ON_WRITE | ||
| 9 | ; $SET_CTRL_C_TRAPPING | ||
| 10 | ; $INTERNATIONAL | ||
| 11 | ; $GET_DRIVE_FREESPACE | ||
| 12 | ; $GET_DMA | ||
| 13 | ; $SET_DMA | ||
| 14 | ; $GET_DEFAULT_DRIVE | ||
| 15 | ; $SET_DEFAULT_DRIVE | ||
| 16 | ; $GET_INTERRUPT_VECTOR | ||
| 17 | ; $SET_INTERRUPT_VECTOR | ||
| 18 | ; RECSET | ||
| 19 | ; $CHAR_OPER | ||
| 20 | ; | ||
| 21 | .xlist | ||
| 22 | ; | ||
| 23 | ; get the appropriate segment definitions | ||
| 24 | ; | ||
| 25 | INCLUDE DOSSEG.ASM | ||
| 26 | |||
| 27 | IFNDEF ALTVECT | ||
| 28 | ALTVECT EQU 0 ; FALSE | ||
| 29 | ENDIF | ||
| 30 | |||
| 31 | IFNDEF IBM | ||
| 32 | IBM EQU 0 | ||
| 33 | ENDIF | ||
| 34 | |||
| 35 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 36 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 37 | |||
| 38 | .xcref | ||
| 39 | INCLUDE DOSSYM.ASM | ||
| 40 | INCLUDE DEVSYM.ASM | ||
| 41 | .cref | ||
| 42 | .list | ||
| 43 | |||
| 44 | |||
| 45 | i_need VERFLG,BYTE | ||
| 46 | i_need CNTCFLAG,BYTE | ||
| 47 | i_need DMAADD,DWORD | ||
| 48 | i_need CURDRV,BYTE | ||
| 49 | i_need Current_Country,WORD | ||
| 50 | i_need international_table,BYTE | ||
| 51 | i_need INDOS,BYTE | ||
| 52 | i_need SYSINITVAR,WORD | ||
| 53 | i_need NUMIO,BYTE | ||
| 54 | i_need SWITCH_CHARACTER,BYTE | ||
| 55 | i_need DEVICE_AVAILABILITY,BYTE | ||
| 56 | |||
| 57 | USERNUM DW ? ; 24 bit user number | ||
| 58 | DB ? | ||
| 59 | IF IBM | ||
| 60 | OEMNUM DB 0 ; 8 bit OEM number | ||
| 61 | ELSE | ||
| 62 | OEMNUM DB 0FFH ; 8 bit OEM number | ||
| 63 | ENDIF | ||
| 64 | |||
| 65 | MSVERS EQU THIS WORD ; MS-DOS version in hex for $GET_VERSION | ||
| 66 | MSMAJOR DB DOS_MAJOR_VERSION | ||
| 67 | MSMINOR DB DOS_MINOR_VERSION | ||
| 68 | |||
| 69 | |||
| 70 | BREAK <$Get_Version -- Return MSDOS version number> | ||
| 71 | procedure $GET_VERSION,NEAR | ||
| 72 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 73 | |||
| 74 | ; Inputs: | ||
| 75 | ; None | ||
| 76 | ; Function: | ||
| 77 | ; Return MS-DOS version number | ||
| 78 | ; Outputs: | ||
| 79 | ; OEM number in BH | ||
| 80 | ; User number in BL:CX (24 bits) | ||
| 81 | ; Version number as AL.AH in binary | ||
| 82 | ; NOTE: On pre 1.28 DOSs AL will be zero | ||
| 83 | |||
| 84 | PUSH SS | ||
| 85 | POP DS | ||
| 86 | ASSUME DS:DOSGROUP | ||
| 87 | MOV BX,[USERNUM + 2] | ||
| 88 | MOV CX,[USERNUM] | ||
| 89 | MOV AX,[MSVERS] | ||
| 90 | invoke get_user_stack | ||
| 91 | ASSUME DS:NOTHING | ||
| 92 | MOV [SI.user_BX],BX | ||
| 93 | MOV [SI.user_CX],CX | ||
| 94 | MOV [SI.user_AX],AX ; Really only sets AH | ||
| 95 | return | ||
| 96 | $GET_VERSION ENDP | ||
| 97 | |||
| 98 | BREAK <$International - return country-dependent information> | ||
| 99 | ; | ||
| 100 | ; Inputs: | ||
| 101 | ; DS:DX point to a block | ||
| 102 | ; Function: | ||
| 103 | ; give users an idea of what country the application is running | ||
| 104 | ; Outputs: | ||
| 105 | ; AX = number of bytes transferred | ||
| 106 | ; DS:DX ->+---------------------------------+ | ||
| 107 | ; | WORD Date/time format | | ||
| 108 | ; +---------------------------------+ | ||
| 109 | ; | BYTE ASCIZ currency symbol | | ||
| 110 | ; +---------------------------------+ | ||
| 111 | ; | BYTE ASCIZ thousands separator | | ||
| 112 | ; +---------------------------------+ | ||
| 113 | ; | BYTE ASCIZ decimal separator | | ||
| 114 | ; +---------------------------------+ | ||
| 115 | |||
| 116 | procedure $INTERNATIONAL,NEAR | ||
| 117 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 118 | MOV BL,AL | ||
| 119 | PUSH DS | ||
| 120 | POP ES | ||
| 121 | PUSH DX | ||
| 122 | POP DI | ||
| 123 | PUSH SS | ||
| 124 | POP DS | ||
| 125 | ASSUME DS:DOSGROUP | ||
| 126 | CMP DI,-1 | ||
| 127 | JZ international_set | ||
| 128 | OR BL,BL | ||
| 129 | JNZ international_find | ||
| 130 | MOV SI,[Current_Country] | ||
| 131 | MOV AX,WORD PTR [SI-2] ; Get size in AL, country code in AH | ||
| 132 | MOV BL,AH ; Set country code | ||
| 133 | JMP SHORT international_copy | ||
| 134 | |||
| 135 | international_find: | ||
| 136 | CALL international_get | ||
| 137 | JNC international_copy | ||
| 138 | error country_not_found | ||
| 139 | |||
| 140 | international_get: | ||
| 141 | MOV SI,OFFSET DOSGROUP:international_table | ||
| 142 | international_next: | ||
| 143 | LODSW ; Get size in AL, country code in AH | ||
| 144 | CMP AL,-1 | ||
| 145 | JNZ check_code | ||
| 146 | STC | ||
| 147 | RET35: | ||
| 148 | RET | ||
| 149 | |||
| 150 | check_code: | ||
| 151 | CMP BL,AH | ||
| 152 | JZ RET35 ; Carry clear | ||
| 153 | XOR AH,AH | ||
| 154 | ADD SI,AX | ||
| 155 | JMP international_next | ||
| 156 | |||
| 157 | international_copy: | ||
| 158 | MOV CL,AL | ||
| 159 | XOR CH,CH | ||
| 160 | PUSH DI | ||
| 161 | REP MOVSB | ||
| 162 | POP DI | ||
| 163 | MOV WORD PTR ES:[DI.MAP_CALL + 2],CS ; Set segment for case map call | ||
| 164 | international_ok: | ||
| 165 | XOR AX,AX | ||
| 166 | MOV AL,BL ; Return country code in AX | ||
| 167 | transfer SYS_RET_OK | ||
| 168 | |||
| 169 | international_set: | ||
| 170 | CALL international_get | ||
| 171 | JNC international_store | ||
| 172 | error country_not_found | ||
| 173 | |||
| 174 | international_store: | ||
| 175 | MOV [Current_Country],SI | ||
| 176 | JMP international_ok | ||
| 177 | |||
| 178 | $INTERNATIONAL ENDP | ||
| 179 | |||
| 180 | BREAK <$Get_Verify_on_Write - return verify-after-write flag> | ||
| 181 | procedure $GET_VERIFY_ON_WRITE,NEAR | ||
| 182 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 183 | |||
| 184 | ; Inputs: | ||
| 185 | ; none. | ||
| 186 | ; Function: | ||
| 187 | ; returns flag | ||
| 188 | ; Returns: | ||
| 189 | ; AL = value of VERIFY flag | ||
| 190 | |||
| 191 | MOV AL,[VERFLG] | ||
| 192 | return | ||
| 193 | $GET_VERIFY_ON_WRITE ENDP | ||
| 194 | |||
| 195 | BREAK <$Set_Verify_on_Write - Toggle verify-after-write flag> | ||
| 196 | procedure $SET_VERIFY_ON_WRITE,NEAR | ||
| 197 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 198 | |||
| 199 | ; Inputs: | ||
| 200 | ; AL = desired value of VERIFY flag | ||
| 201 | ; Function: | ||
| 202 | ; Sets flag | ||
| 203 | ; Returns: | ||
| 204 | ; None | ||
| 205 | |||
| 206 | AND AL,1 | ||
| 207 | MOV [VERFLG],AL | ||
| 208 | return | ||
| 209 | $SET_VERIFY_ON_WRITE ENDP | ||
| 210 | |||
| 211 | BREAK <$Set_CTRL_C_Trapping -- En/Disable ^C check in dispatcher> | ||
| 212 | procedure $SET_CTRL_C_TRAPPING,NEAR | ||
| 213 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 214 | |||
| 215 | ; Inputs: | ||
| 216 | ; AL = 0 read ^C status | ||
| 217 | ; AL = 1 Set ^C status, DL = 0/1 for ^C off/on | ||
| 218 | ; Function: | ||
| 219 | ; Enable disable ^C checking in dispatcher | ||
| 220 | ; Outputs: | ||
| 221 | ; If AL = 0 then DL = 0/1 for ^C off/on | ||
| 222 | |||
| 223 | OR AL,AL | ||
| 224 | JNZ CTRL_C_set | ||
| 225 | invoke get_user_stack | ||
| 226 | MOV AL,[CNTCFLAG] | ||
| 227 | MOV BYTE PTR [SI.user_DX],AL | ||
| 228 | return | ||
| 229 | CTRL_C_set: | ||
| 230 | DEC AL | ||
| 231 | JNZ bad_val | ||
| 232 | AND DL,01h | ||
| 233 | MOV [CNTCFLAG],DL | ||
| 234 | return | ||
| 235 | bad_val: | ||
| 236 | MOV AL,0FFH | ||
| 237 | return | ||
| 238 | $SET_CTRL_C_TRAPPING ENDP | ||
| 239 | |||
| 240 | BREAK <$Get_INDOS_Flag -- Return location of DOS critical-section flag> | ||
| 241 | procedure $GET_INDOS_FLAG,NEAR | ||
| 242 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 243 | |||
| 244 | ; Inputs: | ||
| 245 | ; None | ||
| 246 | ; Function: | ||
| 247 | ; Returns location of DOS status for interrupt routines | ||
| 248 | ; Returns: | ||
| 249 | ; Flag location in ES:BX | ||
| 250 | |||
| 251 | invoke get_user_stack | ||
| 252 | MOV [SI.user_BX],OFFSET DOSGROUP:INDOS | ||
| 253 | MOV [SI.user_ES],SS | ||
| 254 | return | ||
| 255 | $GET_INDOS_FLAG ENDP | ||
| 256 | |||
| 257 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 258 | ; C A V E A T P R O G R A M M E R ; | ||
| 259 | ; ; | ||
| 260 | procedure $GET_IN_VARS,NEAR | ||
| 261 | ; Return a pointer to interesting DOS variables This call is version | ||
| 262 | ; dependent and is subject to change without notice in future versions. | ||
| 263 | ; Use at risk. | ||
| 264 | invoke get_user_stack | ||
| 265 | MOV [SI.user_BX],OFFSET DOSGROUP:SYSINITVAR | ||
| 266 | MOV [SI.user_ES],SS | ||
| 267 | return | ||
| 268 | $GET_IN_VARS ENDP | ||
| 269 | ; ; | ||
| 270 | ; C A V E A T P R O G R A M M E R ; | ||
| 271 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 272 | |||
| 273 | BREAK <$Get_Drive_Freespace -- Return bytes of free disk space on a drive> | ||
| 274 | procedure $GET_DRIVE_FREESPACE,NEAR | ||
| 275 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 276 | |||
| 277 | ; Inputs: | ||
| 278 | ; DL = Drive number | ||
| 279 | ; Function: | ||
| 280 | ; Return number of free allocation units on drive | ||
| 281 | ; Outputs: | ||
| 282 | ; BX = Number of free allocation units | ||
| 283 | ; DX = Total Number of allocation units on disk | ||
| 284 | ; CX = Sector size | ||
| 285 | ; AX = Sectors per allocation unit | ||
| 286 | ; = -1 if bad drive specified | ||
| 287 | ; This call returns the same info in the same registers (except for FAT pointer) | ||
| 288 | ; as the old FAT pointer calls | ||
| 289 | |||
| 290 | PUSH SS | ||
| 291 | POP DS | ||
| 292 | ASSUME DS:DOSGROUP | ||
| 293 | MOV AL,DL | ||
| 294 | invoke GETTHISDRV | ||
| 295 | MOV AX,-1 | ||
| 296 | JC BADFRDRIVE | ||
| 297 | invoke FATREAD | ||
| 298 | XOR DX,DX | ||
| 299 | MOV BX,2 | ||
| 300 | MOV CX,ES:[BP.dpb_max_cluster] | ||
| 301 | DEC CX | ||
| 302 | PUSH CX ; Save Total | ||
| 303 | SCANFREE: | ||
| 304 | invoke UNPACK | ||
| 305 | JNZ NOTFREECLUS | ||
| 306 | INC DX | ||
| 307 | NOTFREECLUS: | ||
| 308 | INC BX | ||
| 309 | LOOP SCANFREE | ||
| 310 | POP BX ; Remember Total | ||
| 311 | MOV AL,ES:[BP.dpb_cluster_mask] | ||
| 312 | INC AL | ||
| 313 | XOR AH,AH | ||
| 314 | MOV CX,ES:[BP.dpb_sector_size] | ||
| 315 | BADFRDRIVE: | ||
| 316 | invoke get_user_stack | ||
| 317 | ASSUME DS:NOTHING | ||
| 318 | MOV [SI. user_CX],CX | ||
| 319 | MOV [SI.user_DX],BX | ||
| 320 | MOV [SI.user_BX],DX | ||
| 321 | MOV [SI.user_AX],AX | ||
| 322 | return | ||
| 323 | |||
| 324 | $GET_DRIVE_FREESPACE ENDP | ||
| 325 | |||
| 326 | BREAK <$Get_DMA, $Set_DMA -- Get/Set current DMA address> | ||
| 327 | procedure $GET_DMA,NEAR | ||
| 328 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 329 | |||
| 330 | ; Inputs: | ||
| 331 | ; None | ||
| 332 | ; Function: | ||
| 333 | ; Get DISK TRANSFER ADDRESS | ||
| 334 | ; Returns: | ||
| 335 | ; ES:BX is current transfer address | ||
| 336 | |||
| 337 | MOV BX,WORD PTR [DMAADD] | ||
| 338 | MOV CX,WORD PTR [DMAADD+2] | ||
| 339 | invoke get_user_stack | ||
| 340 | MOV [SI.user_BX],BX | ||
| 341 | MOV [SI.user_ES],CX | ||
| 342 | return | ||
| 343 | $GET_DMA ENDP | ||
| 344 | |||
| 345 | procedure $SET_DMA,NEAR ; System call 26 | ||
| 346 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 347 | |||
| 348 | ; Inputs: | ||
| 349 | ; DS:DX is desired new disk transfer address | ||
| 350 | ; Function: | ||
| 351 | ; Set DISK TRANSFER ADDRESS | ||
| 352 | ; Returns: | ||
| 353 | ; None | ||
| 354 | |||
| 355 | MOV WORD PTR [DMAADD],DX | ||
| 356 | MOV WORD PTR [DMAADD+2],DS | ||
| 357 | return | ||
| 358 | $SET_DMA ENDP | ||
| 359 | |||
| 360 | BREAK <$Get_Default_DPB,$Get_DPB -- Return pointer to DPB> | ||
| 361 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 362 | ; C A V E A T P R O G R A M M E R ; | ||
| 363 | ; ; | ||
| 364 | procedure $GET_DEFAULT_DPB,NEAR | ||
| 365 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 366 | |||
| 367 | ; Inputs: | ||
| 368 | ; DL = Drive number (always default drive for call 31) | ||
| 369 | ; Function: | ||
| 370 | ; Return pointer to drive parameter table for default drive | ||
| 371 | ; Returns: | ||
| 372 | ; DS:BX points to the DPB | ||
| 373 | ; AL = 0 If OK, = -1 if bad drive (call 50 only) | ||
| 374 | |||
| 375 | MOV DL,0 | ||
| 376 | entry $GET_DPB | ||
| 377 | PUSH SS | ||
| 378 | POP DS | ||
| 379 | ASSUME DS:DOSGROUP | ||
| 380 | MOV AL,DL | ||
| 381 | invoke GETTHISDRV | ||
| 382 | JC ISNODRV | ||
| 383 | invoke FATREAD | ||
| 384 | invoke get_user_stack | ||
| 385 | ASSUME DS:NOTHING | ||
| 386 | MOV [SI.user_BX],BP | ||
| 387 | MOV [SI.user_DS],ES | ||
| 388 | XOR AL,AL | ||
| 389 | return | ||
| 390 | |||
| 391 | ISNODRV: | ||
| 392 | MOV AL,-1 | ||
| 393 | return | ||
| 394 | $GET_Default_dpb ENDP | ||
| 395 | ; ; | ||
| 396 | ; C A V E A T P R O G R A M M E R ; | ||
| 397 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 398 | |||
| 399 | |||
| 400 | BREAK <$Get_Default_Drive, $Set_Default_Drive -- Set/Get default drive> | ||
| 401 | procedure $GET_DEFAULT_DRIVE,NEAR | ||
| 402 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 403 | |||
| 404 | ; Inputs: | ||
| 405 | ; None | ||
| 406 | ; Function: | ||
| 407 | ; Return current drive number | ||
| 408 | ; Returns: | ||
| 409 | ; AL = drive number | ||
| 410 | |||
| 411 | MOV AL,[CURDRV] | ||
| 412 | return | ||
| 413 | $GET_DEFAULT_DRIVE ENDP | ||
| 414 | |||
| 415 | procedure $SET_DEFAULT_DRIVE,NEAR | ||
| 416 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 417 | |||
| 418 | ; Inputs: | ||
| 419 | ; DL = Drive number for new default drive | ||
| 420 | ; Function: | ||
| 421 | ; Set the default drive | ||
| 422 | ; Returns: | ||
| 423 | ; AL = Number of drives, NO ERROR RETURN IF DRIVE NUMBER BAD | ||
| 424 | |||
| 425 | MOV AL,[NUMIO] | ||
| 426 | CMP DL,AL | ||
| 427 | JNB RET17 | ||
| 428 | MOV [CURDRV],DL | ||
| 429 | RET17: return | ||
| 430 | $SET_DEFAULT_DRIVE ENDP | ||
| 431 | |||
| 432 | |||
| 433 | BREAK <$Get_Interrupt_Vector - Get/Set interrupt vectors> | ||
| 434 | procedure $GET_INTERRUPT_VECTOR,NEAR | ||
| 435 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 436 | |||
| 437 | ; Inputs: | ||
| 438 | ; AL = interrupt number | ||
| 439 | ; Function: | ||
| 440 | ; Get the interrupt vector | ||
| 441 | ; Returns: | ||
| 442 | ; ES:BX is current interrupt vector | ||
| 443 | |||
| 444 | CALL RECSET | ||
| 445 | LES BX,DWORD PTR ES:[BX] | ||
| 446 | invoke get_user_stack | ||
| 447 | MOV [SI.user_BX],BX | ||
| 448 | MOV [SI.user_ES],ES | ||
| 449 | return | ||
| 450 | $GET_INTERRUPT_VECTOR ENDP | ||
| 451 | |||
| 452 | procedure $SET_INTERRUPT_VECTOR,NEAR ; System call 37 | ||
| 453 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 454 | |||
| 455 | ; Inputs: | ||
| 456 | ; AL = interrupt number | ||
| 457 | ; DS:DX is desired new interrupt vector | ||
| 458 | ; Function: | ||
| 459 | ; Set the interrupt vector | ||
| 460 | ; Returns: | ||
| 461 | ; None | ||
| 462 | |||
| 463 | CALL RECSET | ||
| 464 | MOV ES:[BX],DX | ||
| 465 | MOV ES:[BX+2],DS | ||
| 466 | return | ||
| 467 | $SET_INTERRUPT_VECTOR ENDP | ||
| 468 | |||
| 469 | IF ALTVECT | ||
| 470 | VECIN: ; INPUT VECTORS | ||
| 471 | DB 22H ; Terminate | ||
| 472 | DB 23H ; ^C | ||
| 473 | DB 24H ; Hard error | ||
| 474 | DB 28H ; Spooler | ||
| 475 | LSTVEC DB ? ; ALL OTHER | ||
| 476 | |||
| 477 | VECOUT: ; GET MAPPED VECTOR | ||
| 478 | DB int_terminate | ||
| 479 | DB int_ctrl_c | ||
| 480 | DB int_fatal_abort | ||
| 481 | DB int_spooler | ||
| 482 | LSTVEC2 DB ? ; Map to itself | ||
| 483 | |||
| 484 | NUMVEC = VECOUT-VECIN | ||
| 485 | ENDIF | ||
| 486 | |||
| 487 | procedure RECSET,NEAR | ||
| 488 | |||
| 489 | IF ALTVECT | ||
| 490 | PUSH SS | ||
| 491 | POP ES | ||
| 492 | MOV [LSTVEC],AL ; Terminate list with real vector | ||
| 493 | MOV [LSTVEC2],AL ; Terminate list with real vector | ||
| 494 | MOV CX,NUMVEC ; Number of possible translations | ||
| 495 | MOV DI,OFFSET DOSGROUP:VECIN ; Point to vectors | ||
| 496 | REPNE SCASB | ||
| 497 | MOV AL,ES:[DI+NUMVEC-1] ; Get translation | ||
| 498 | ENDIF | ||
| 499 | |||
| 500 | XOR BX,BX | ||
| 501 | MOV ES,BX | ||
| 502 | MOV BL,AL | ||
| 503 | SHL BX,1 | ||
| 504 | SHL BX,1 | ||
| 505 | return | ||
| 506 | recset ENDP | ||
| 507 | |||
| 508 | BREAK <$Char_Oper - hack on paths, switches so that xenix can look like PCDOS> | ||
| 509 | ; | ||
| 510 | ; input: AL = function: | ||
| 511 | ; 0 - read switch char | ||
| 512 | ; 1 - set switch char (char in DL) | ||
| 513 | ; 2 - read device availability | ||
| 514 | ; 3 - set device availability (0/FF in DL) | ||
| 515 | ; DL = 0 means /DEV/ must preceed device names | ||
| 516 | ; DL = Non0 means /DEV/ need not preeceed | ||
| 517 | ; output: (get) DL - character/flag | ||
| 518 | ; | ||
| 519 | procedure $CHAR_OPER,NEAR | ||
| 520 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 521 | PUSH SS | ||
| 522 | POP DS | ||
| 523 | ASSUME DS:DOSGROUP | ||
| 524 | OR AL,AL | ||
| 525 | JNZ char_oper_set_switch | ||
| 526 | MOV DL,[switch_character] | ||
| 527 | JMP SHORT char_oper_ret | ||
| 528 | char_oper_set_switch: | ||
| 529 | DEC AL | ||
| 530 | JNZ char_oper_read_avail | ||
| 531 | MOV [switch_character],DL | ||
| 532 | return | ||
| 533 | char_oper_read_avail: | ||
| 534 | DEC AL | ||
| 535 | JNZ char_oper_set_avail | ||
| 536 | MOV DL,[device_availability] | ||
| 537 | JMP SHORT char_oper_ret | ||
| 538 | char_oper_set_avail: | ||
| 539 | DEC AL | ||
| 540 | JNZ char_oper_bad_ret | ||
| 541 | MOV [device_availability],DL | ||
| 542 | return | ||
| 543 | char_oper_bad_ret: | ||
| 544 | MOV AL,0FFh | ||
| 545 | return | ||
| 546 | char_oper_ret: | ||
| 547 | invoke get_user_stack | ||
| 548 | MOV [SI.user_DX],DX | ||
| 549 | return | ||
| 550 | $CHAR_OPER ENDP | ||
| 551 | |||
| 552 | BREAK <$SetDPB - Create a valid DPB from a user-specified BPB> | ||
| 553 | procedure $SETDPB,NEAR | ||
| 554 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 555 | |||
| 556 | ; Inputs: | ||
| 557 | ; ES:BP Points to DPB | ||
| 558 | ; DS:SI Points to BPB | ||
| 559 | ; Function: | ||
| 560 | ; Build a correct DPB from the BPB | ||
| 561 | ; Outputs: | ||
| 562 | ; ES:BP and DS preserved all others destroyed | ||
| 563 | |||
| 564 | MOV DI,BP | ||
| 565 | ADD DI,2 ; Skip over dpb_drive and dpb_UNIT | ||
| 566 | LODSW | ||
| 567 | STOSW ; dpb_sector_size | ||
| 568 | MOV DX,AX | ||
| 569 | LODSB | ||
| 570 | DEC AL | ||
| 571 | STOSB ; dpb_cluster_mask | ||
| 572 | INC AL | ||
| 573 | XOR AH,AH | ||
| 574 | LOG2LOOP: | ||
| 575 | TEST AL,1 | ||
| 576 | JNZ SAVLOG | ||
| 577 | INC AH | ||
| 578 | SHR AL,1 | ||
| 579 | JMP SHORT LOG2LOOP | ||
| 580 | SAVLOG: | ||
| 581 | MOV AL,AH | ||
| 582 | STOSB ; dpb_cluster_shift | ||
| 583 | MOV BL,AL | ||
| 584 | MOVSW ; dpb_first_FAT Start of FAT (# of reserved sectors) | ||
| 585 | LODSB | ||
| 586 | STOSB ; dpb_FAT_count Number of FATs | ||
| 587 | MOV BH,AL | ||
| 588 | LODSW | ||
| 589 | STOSW ; dpb_root_entries Number of directory entries | ||
| 590 | MOV CL,5 | ||
| 591 | SHR DX,CL ; Directory entries per sector | ||
| 592 | DEC AX | ||
| 593 | ADD AX,DX ; Cause Round Up | ||
| 594 | MOV CX,DX | ||
| 595 | XOR DX,DX | ||
| 596 | DIV CX | ||
| 597 | MOV CX,AX ; Number of directory sectors | ||
| 598 | INC DI | ||
| 599 | INC DI ; Skip dpb_first_sector | ||
| 600 | MOVSW ; Total number of sectors in DSKSIZ (temp as dpb_max_cluster) | ||
| 601 | LODSB | ||
| 602 | MOV ES:[BP.dpb_media],AL ; Media byte | ||
| 603 | LODSW ; Number of sectors in a FAT | ||
| 604 | STOSB ; dpb_FAT_size | ||
| 605 | MUL BH ; Space occupied by all FATs | ||
| 606 | ADD AX,ES:[BP.dpb_first_FAT] | ||
| 607 | STOSW ; dpb_dir_sector | ||
| 608 | ADD AX,CX ; Add number of directory sectors | ||
| 609 | MOV ES:[BP.dpb_first_sector],AX | ||
| 610 | SUB AX,ES:[BP.DSKSIZ] | ||
| 611 | NEG AX ; Sectors in data area | ||
| 612 | MOV CL,BL ; dpb_cluster_shift | ||
| 613 | SHR AX,CL ; Div by sectors/cluster | ||
| 614 | INC AX | ||
| 615 | MOV ES:[BP.dpb_max_cluster],AX | ||
| 616 | MOV ES:[BP.dpb_current_dir],0 ; Current directory is root | ||
| 617 | return | ||
| 618 | $SETDPB ENDP | ||
| 619 | ; ; | ||
| 620 | ; C A V E A T P R O G R A M M E R ; | ||
| 621 | ;----+----+----+----+----+----+----+----+----+----+----+----+----+----+----; | ||
| 622 | |||
| 623 | do_ext | ||
| 624 | |||
| 625 | CODE ENDS | ||
| 626 | END | ||
| 627 | |||