diff options
Diffstat (limited to 'v2.0/source/DEV.ASM')
| -rw-r--r-- | v2.0/source/DEV.ASM | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/v2.0/source/DEV.ASM b/v2.0/source/DEV.ASM new file mode 100644 index 0000000..b640d55 --- /dev/null +++ b/v2.0/source/DEV.ASM | |||
| @@ -0,0 +1,439 @@ | |||
| 1 | ; | ||
| 2 | ; Device call routines for MSDOS | ||
| 3 | ; | ||
| 4 | |||
| 5 | INCLUDE DOSSEG.ASM | ||
| 6 | |||
| 7 | IFNDEF KANJI | ||
| 8 | KANJI EQU 0 ;FALSE | ||
| 9 | ENDIF | ||
| 10 | |||
| 11 | CODE SEGMENT BYTE PUBLIC 'CODE' | ||
| 12 | ASSUME SS:DOSGROUP,CS:DOSGROUP | ||
| 13 | |||
| 14 | .xlist | ||
| 15 | .xcref | ||
| 16 | INCLUDE DOSSYM.ASM | ||
| 17 | INCLUDE DEVSYM.ASM | ||
| 18 | .cref | ||
| 19 | .list | ||
| 20 | |||
| 21 | TITLE DEV - Device call routines | ||
| 22 | NAME Dev | ||
| 23 | |||
| 24 | i_need IOXAD,DWORD | ||
| 25 | i_need IOSCNT,WORD | ||
| 26 | i_need DEVIOBUF,4 | ||
| 27 | i_need IOCALL,BYTE | ||
| 28 | i_need IOMED,BYTE | ||
| 29 | i_need IORCHR,BYTE | ||
| 30 | i_need CALLSCNT,WORD | ||
| 31 | i_need DMAAdd,DWORD | ||
| 32 | i_need NullDevPt,DWORD | ||
| 33 | i_need CallDevAd,DWORD | ||
| 34 | i_need Attrib,BYTE | ||
| 35 | i_need NULDEV,DWORD | ||
| 36 | i_need Name1,BYTE | ||
| 37 | i_need DevPt,DWORD | ||
| 38 | i_need DPBHead,DWORD | ||
| 39 | i_need NumIO,BYTE | ||
| 40 | i_need ThisDPB,DWORD | ||
| 41 | i_need DevCall,DWORD | ||
| 42 | i_need VerFlg,BYTE | ||
| 43 | |||
| 44 | SUBTTL IOFUNC -- DO FUNCTION 1-12 I/O | ||
| 45 | PAGE | ||
| 46 | IOFUNC_RETRY: | ||
| 47 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 48 | invoke restore_world | ||
| 49 | |||
| 50 | procedure IOFUNC,NEAR | ||
| 51 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 52 | |||
| 53 | ; Inputs: | ||
| 54 | ; DS:SI Points to FCB | ||
| 55 | ; AH is function code | ||
| 56 | ; = 0 Input | ||
| 57 | ; = 1 Input Status | ||
| 58 | ; = 2 Output | ||
| 59 | ; = 3 Output Status | ||
| 60 | ; = 4 Flush | ||
| 61 | ; AL = character if output | ||
| 62 | ; Function: | ||
| 63 | ; Perform indicated I/O to device or file | ||
| 64 | ; Outputs: | ||
| 65 | ; AL is character if input | ||
| 66 | ; If a status call | ||
| 67 | ; zero set if not ready | ||
| 68 | ; zero reset if ready (character in AL for input status) | ||
| 69 | ; For regular files: | ||
| 70 | ; Input Status | ||
| 71 | ; Gets character but restores fcb_RR field | ||
| 72 | ; Zero set on EOF | ||
| 73 | ; Input | ||
| 74 | ; Gets character advances fcb_RR field | ||
| 75 | ; Returns ^Z on EOF | ||
| 76 | ; Output Status | ||
| 77 | ; Always ready | ||
| 78 | ; AX altered, all other registers preserved | ||
| 79 | |||
| 80 | MOV WORD PTR [IOXAD+2],SS | ||
| 81 | MOV WORD PTR [IOXAD],OFFSET DOSGROUP:DEVIOBUF | ||
| 82 | MOV WORD PTR [IOSCNT],1 | ||
| 83 | MOV WORD PTR [DEVIOBUF],AX | ||
| 84 | |||
| 85 | IOFUNC2: | ||
| 86 | TEST [SI.fcb_DEVID],080H | ||
| 87 | JNZ IOTODEV | ||
| 88 | JMP IOTOFILE | ||
| 89 | |||
| 90 | IOTODEV: | ||
| 91 | invoke save_world | ||
| 92 | PUSH DS | ||
| 93 | PUSH SS | ||
| 94 | POP ES | ||
| 95 | PUSH SS | ||
| 96 | POP DS | ||
| 97 | ASSUME DS:DOSGROUP | ||
| 98 | XOR BX,BX | ||
| 99 | MOV [IOCALL.REQSTAT],BX | ||
| 100 | MOV BYTE PTR [IOMED],BL | ||
| 101 | |||
| 102 | MOV BX,OFFSET DOSGROUP:IOCALL | ||
| 103 | |||
| 104 | MOV CX,(DEVRD SHL 8) OR DRDWRHL | ||
| 105 | OR AH,AH | ||
| 106 | JZ DCALLR | ||
| 107 | MOV CX,(DEVRDND SHL 8) OR DRDNDHL | ||
| 108 | DEC AH | ||
| 109 | JZ DCALLR | ||
| 110 | MOV CX,(DEVWRT SHL 8) OR DRDWRHL | ||
| 111 | DEC AH | ||
| 112 | JZ DCALLO | ||
| 113 | MOV CX,(DEVOST SHL 8) OR DSTATHL | ||
| 114 | DEC AH | ||
| 115 | JZ DCALLO | ||
| 116 | DFLUSH: | ||
| 117 | MOV CX,(DEVIFL SHL 8) OR DFLSHL | ||
| 118 | DCALLR: | ||
| 119 | MOV AH,86H | ||
| 120 | DCALL: | ||
| 121 | MOV [IOCALL.REQLEN],CL | ||
| 122 | MOV [IOCALL.REQFUNC],CH | ||
| 123 | MOV CL,AH | ||
| 124 | POP DS | ||
| 125 | ASSUME DS:NOTHING | ||
| 126 | CALL DEVIOCALL | ||
| 127 | MOV DI,[IOCALL.REQSTAT] | ||
| 128 | TEST DI,STERR | ||
| 129 | JZ OKDEVIO | ||
| 130 | MOV AH,CL | ||
| 131 | invoke CHARHARD | ||
| 132 | CMP AL,1 | ||
| 133 | JZ IOFUNC_RETRY | ||
| 134 | ;Know user must have wanted ignore. Make sure device shows ready so | ||
| 135 | ;that DOS doesn't get caught in a status loop when user simply wants | ||
| 136 | ;to ignore the error. | ||
| 137 | AND BYTE PTR [IOCALL.REQSTAT+1], NOT (STBUI SHR 8) | ||
| 138 | OKDEVIO: | ||
| 139 | PUSH SS | ||
| 140 | POP DS | ||
| 141 | ASSUME DS:DOSGROUP | ||
| 142 | CMP CH,DEVRDND | ||
| 143 | JNZ DNODRD | ||
| 144 | MOV AL,BYTE PTR [IORCHR] | ||
| 145 | MOV [DEVIOBUF],AL | ||
| 146 | |||
| 147 | DNODRD: MOV AH,BYTE PTR [IOCALL.REQSTAT+1] | ||
| 148 | NOT AH ; Zero = busy, not zero = ready | ||
| 149 | AND AH,STBUI SHR 8 | ||
| 150 | |||
| 151 | invoke restore_world | ||
| 152 | ASSUME DS:NOTHING | ||
| 153 | MOV AX,WORD PTR [DEVIOBUF] | ||
| 154 | return | ||
| 155 | |||
| 156 | DCALLO: | ||
| 157 | MOV AH,87H | ||
| 158 | JMP SHORT DCALL | ||
| 159 | |||
| 160 | IOTOFILE: | ||
| 161 | ASSUME DS:NOTHING | ||
| 162 | OR AH,AH | ||
| 163 | JZ IOIN | ||
| 164 | DEC AH | ||
| 165 | JZ IOIST | ||
| 166 | DEC AH | ||
| 167 | JZ IOUT | ||
| 168 | return ; NON ZERO FLAG FOR OUTPUT STATUS | ||
| 169 | |||
| 170 | IOIST: | ||
| 171 | PUSH WORD PTR [SI.fcb_RR] ; Save position | ||
| 172 | PUSH WORD PTR [SI.fcb_RR+2] | ||
| 173 | CALL IOIN | ||
| 174 | POP WORD PTR [SI.fcb_RR+2] ; Restore position | ||
| 175 | POP WORD PTR [SI.fcb_RR] | ||
| 176 | return | ||
| 177 | |||
| 178 | IOUT: | ||
| 179 | CALL SETXADDR | ||
| 180 | invoke STORE | ||
| 181 | invoke FINNOSAV | ||
| 182 | CALL RESTXADDR ; If you change this into a jmp don't come | ||
| 183 | return ; crying to me when things don't work ARR | ||
| 184 | |||
| 185 | IOIN: | ||
| 186 | CALL SETXADDR | ||
| 187 | invoke LOAD | ||
| 188 | PUSH CX | ||
| 189 | invoke FINNOSAV | ||
| 190 | POP CX | ||
| 191 | OR CX,CX ; Check EOF | ||
| 192 | CALL RESTXADDR | ||
| 193 | MOV AL,[DEVIOBUF] ; Get byte from trans addr | ||
| 194 | retnz | ||
| 195 | MOV AL,1AH ; ^Z if EOF | ||
| 196 | return | ||
| 197 | |||
| 198 | SETXADDR: | ||
| 199 | POP WORD PTR [CALLSCNT] ; Return address | ||
| 200 | invoke save_world | ||
| 201 | PUSH WORD PTR [DMAADD] ; Save Disk trans addr | ||
| 202 | PUSH WORD PTR [DMAADD+2] | ||
| 203 | PUSH DS | ||
| 204 | PUSH SS | ||
| 205 | POP DS | ||
| 206 | ASSUME DS:DOSGROUP | ||
| 207 | MOV CX,WORD PTR [IOXAD+2] | ||
| 208 | MOV WORD PTR [DMAADD+2],CX | ||
| 209 | MOV CX,WORD PTR [IOXAD] | ||
| 210 | MOV WORD PTR [DMAADD],CX ; Set byte trans addr | ||
| 211 | MOV CX,[IOSCNT] ; ioscnt specifies length of buffer | ||
| 212 | POP DS | ||
| 213 | ASSUME DS:NOTHING | ||
| 214 | MOV [SI.fcb_RECSIZ],1 ; One byte per record | ||
| 215 | MOV DX,SI ; FCB to DS:DX | ||
| 216 | invoke GETRRPOS | ||
| 217 | JMP SHORT RESTRET ; RETURN ADDRESS | ||
| 218 | |||
| 219 | RESTXADDR: | ||
| 220 | POP WORD PTR [CALLSCNT] ; Return address | ||
| 221 | POP WORD PTR [DMAADD+2] ; Restore Disk trans addr | ||
| 222 | POP WORD PTR [DMAADD] | ||
| 223 | invoke restore_world | ||
| 224 | RESTRET:JMP WORD PTR [CALLSCNT] ; Return address | ||
| 225 | IOFUNC ENDP | ||
| 226 | |||
| 227 | SUBTTL DEVIOCALL, DEVIOCALL2 - CALL A DEVICE | ||
| 228 | PAGE | ||
| 229 | procedure DEVIOCALL,NEAR | ||
| 230 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 231 | |||
| 232 | ; Inputs: | ||
| 233 | ; DS:SI Points to device FCB | ||
| 234 | ; ES:BX Points to request data | ||
| 235 | ; Function: | ||
| 236 | ; Call the device | ||
| 237 | ; Outputs: | ||
| 238 | ; None | ||
| 239 | ; DS:SI,AX destroyed, others preserved | ||
| 240 | |||
| 241 | LDS SI,DWORD PTR [SI.fcb_FIRCLUS] | ||
| 242 | |||
| 243 | entry DEVIOCALL2 | ||
| 244 | ; As above only DS:SI points to device header on entry, and DS:SI is preserved | ||
| 245 | MOV AX,[SI.SDEVSTRAT] | ||
| 246 | MOV WORD PTR [CALLDEVAD],AX | ||
| 247 | MOV WORD PTR [CALLDEVAD+2],DS | ||
| 248 | CALL DWORD PTR [CALLDEVAD] | ||
| 249 | MOV AX,[SI.SDEVINT] | ||
| 250 | MOV WORD PTR [CALLDEVAD],AX | ||
| 251 | CALL DWORD PTR [CALLDEVAD] | ||
| 252 | return | ||
| 253 | DEVIOCALL ENDP | ||
| 254 | |||
| 255 | SUBTTL DEVNAME - LOOK FOR NAME OF DEVICE | ||
| 256 | PAGE | ||
| 257 | procedure DEVNAME,NEAR | ||
| 258 | ASSUME DS:DOSGROUP,ES:DOSGROUP | ||
| 259 | |||
| 260 | ; Inputs: | ||
| 261 | ; DS,ES:DOSGROUP | ||
| 262 | ; Filename in NAME1 | ||
| 263 | ; Function: | ||
| 264 | ; Determine if file is in list of I/O drivers | ||
| 265 | ; Outputs: | ||
| 266 | ; Carry set if name not found | ||
| 267 | ; ELSE | ||
| 268 | ; Zero flag set | ||
| 269 | ; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode) | ||
| 270 | ; bits 0-4 set from low byte of attribute word | ||
| 271 | ; DEVPT = DWORD pointer to Device header of device | ||
| 272 | ; Registers BX destroyed | ||
| 273 | |||
| 274 | PUSH SI | ||
| 275 | PUSH DI | ||
| 276 | PUSH CX | ||
| 277 | |||
| 278 | IF KANJI | ||
| 279 | PUSH WORD PTR [NAME1] | ||
| 280 | CMP [NAME1],5 | ||
| 281 | JNZ NOKTR | ||
| 282 | MOV [NAME1],0E5H | ||
| 283 | NOKTR: | ||
| 284 | ENDIF | ||
| 285 | |||
| 286 | TEST BYTE PTR [ATTRIB],attr_volume_id ; If looking for VOL id don't find devs | ||
| 287 | JNZ RET31 | ||
| 288 | MOV SI,OFFSET DOSGROUP:NULDEV | ||
| 289 | LOOKIO: | ||
| 290 | ASSUME DS:NOTHING | ||
| 291 | TEST [SI.SDEVATT],DEVTYP | ||
| 292 | JZ SKIPDEV ; Skip block devices | ||
| 293 | PUSH SI | ||
| 294 | ADD SI,SDEVNAME | ||
| 295 | MOV DI,OFFSET DOSGROUP:NAME1 | ||
| 296 | MOV CX,4 ; All devices are 8 letters | ||
| 297 | REPE CMPSW ; Check for name in list | ||
| 298 | POP SI | ||
| 299 | JZ IOCHK ; Found it? | ||
| 300 | SKIPDEV: | ||
| 301 | LDS SI,DWORD PTR [SI] ; Get address of next device | ||
| 302 | CMP SI,-1 ; At end of list? | ||
| 303 | JNZ LOOKIO | ||
| 304 | RET31: STC ; Not found | ||
| 305 | RETNV: PUSH SS | ||
| 306 | POP DS | ||
| 307 | ASSUME DS:DOSGROUP | ||
| 308 | |||
| 309 | IF KANJI | ||
| 310 | POP WORD PTR [NAME1] | ||
| 311 | ENDIF | ||
| 312 | |||
| 313 | POP CX | ||
| 314 | POP DI | ||
| 315 | POP SI | ||
| 316 | RET | ||
| 317 | |||
| 318 | IOCHK: | ||
| 319 | ASSUME DS:NOTHING | ||
| 320 | MOV WORD PTR [DEVPT+2],DS ; Save pointer to device | ||
| 321 | MOV BH,BYTE PTR [SI.SDEVATT] | ||
| 322 | OR BH,0C0H | ||
| 323 | AND BH,NOT 020H ;Clears Carry | ||
| 324 | MOV WORD PTR [DEVPT],SI | ||
| 325 | JMP RETNV | ||
| 326 | DevName ENDP | ||
| 327 | |||
| 328 | procedure GetBP,NEAR | ||
| 329 | ASSUME DS:DOSGROUP,ES:NOTHING | ||
| 330 | |||
| 331 | ; Inputs: | ||
| 332 | ; AL = Logical unit number (A = 0) | ||
| 333 | ; Function: | ||
| 334 | ; Find Drive Parameter Block | ||
| 335 | ; Outputs: | ||
| 336 | ; ES:BP points to DPB | ||
| 337 | ; [THISDPB] = ES:BP | ||
| 338 | ; Carry set if unit number bad | ||
| 339 | ; No other registers altered | ||
| 340 | |||
| 341 | LES BP,[DPBHEAD] ; Just in case drive isn't valid | ||
| 342 | AND AL,3FH ; Mask out dirty and device bits | ||
| 343 | CMP AL,BYTE PTR [NUMIO] | ||
| 344 | CMC | ||
| 345 | JC GOTDPB ; Get drive A | ||
| 346 | FNDDPB: | ||
| 347 | CMP AL,ES:[BP.dpb_drive] | ||
| 348 | JZ GOTDPB ; Carry is clear if jump executed | ||
| 349 | LES BP,ES:[BP.dpb_next_dpb] | ||
| 350 | JMP SHORT FNDDPB | ||
| 351 | GOTDPB: | ||
| 352 | MOV WORD PTR [THISDPB],BP | ||
| 353 | MOV WORD PTR [THISDPB+2],ES | ||
| 354 | RET | ||
| 355 | GetBP ENDP | ||
| 356 | |||
| 357 | SUBTTL SETREAD, SETWRITE -- SET UP HEADER BLOCK | ||
| 358 | PAGE | ||
| 359 | procedure SETREAD,NEAR | ||
| 360 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 361 | |||
| 362 | ; Inputs: | ||
| 363 | ; DS:BX = Transfer Address | ||
| 364 | ; CX = Record Count | ||
| 365 | ; DX = Starting Record | ||
| 366 | ; AH = Media Byte | ||
| 367 | ; AL = Unit Code | ||
| 368 | ; Function: | ||
| 369 | ; Set up the device call header at DEVCALL | ||
| 370 | ; Output: | ||
| 371 | ; ES:BX Points to DEVCALL | ||
| 372 | ; No other registers effected | ||
| 373 | |||
| 374 | PUSH DI | ||
| 375 | PUSH CX | ||
| 376 | PUSH AX | ||
| 377 | MOV CL,DEVRD | ||
| 378 | SETCALLHEAD: | ||
| 379 | MOV AL,DRDWRHL | ||
| 380 | PUSH SS | ||
| 381 | POP ES | ||
| 382 | MOV DI,OFFSET DOSGROUP:DEVCALL | ||
| 383 | STOSB ; length | ||
| 384 | POP AX | ||
| 385 | STOSB ; Unit | ||
| 386 | PUSH AX | ||
| 387 | MOV AL,CL | ||
| 388 | STOSB ; Command code | ||
| 389 | XOR AX,AX | ||
| 390 | STOSW ; Status | ||
| 391 | ADD DI,8 ; Skip link fields | ||
| 392 | POP AX | ||
| 393 | XCHG AH,AL | ||
| 394 | STOSB ; Media byte | ||
| 395 | XCHG AL,AH | ||
| 396 | PUSH AX | ||
| 397 | MOV AX,BX | ||
| 398 | STOSW | ||
| 399 | MOV AX,DS | ||
| 400 | STOSW ; Transfer addr | ||
| 401 | POP CX ; Real AX | ||
| 402 | POP AX ; Real CX | ||
| 403 | STOSW ; Count | ||
| 404 | XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX | ||
| 405 | STOSW ; Start | ||
| 406 | XCHG AX,CX | ||
| 407 | XCHG DX,CX | ||
| 408 | POP DI | ||
| 409 | MOV BX,OFFSET DOSGROUP:DEVCALL | ||
| 410 | RET | ||
| 411 | |||
| 412 | entry SETWRITE | ||
| 413 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 414 | |||
| 415 | ; Inputs: | ||
| 416 | ; DS:BX = Transfer Address | ||
| 417 | ; CX = Record Count | ||
| 418 | ; DX = Starting Record | ||
| 419 | ; AH = Media Byte | ||
| 420 | ; AL = Unit Code | ||
| 421 | ; Function: | ||
| 422 | ; Set up the device call header at DEVCALL | ||
| 423 | ; Output: | ||
| 424 | ; ES:BX Points to DEVCALL | ||
| 425 | ; No other registers effected | ||
| 426 | |||
| 427 | PUSH DI | ||
| 428 | PUSH CX | ||
| 429 | PUSH AX | ||
| 430 | MOV CL,DEVWRT | ||
| 431 | ADD CL,[VERFLG] | ||
| 432 | JMP SHORT SETCALLHEAD | ||
| 433 | SETREAD ENDP | ||
| 434 | |||
| 435 | do_ext | ||
| 436 | |||
| 437 | CODE ENDS | ||
| 438 | END | ||
| 439 | |||