mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-14 10:47:14 -07:00
MS-DOS v2.0 Release
This commit is contained in:
parent
fce0f75959
commit
80ab2fddfd
156 changed files with 56403 additions and 0 deletions
439
v2.0/source/DEV.ASM
Normal file
439
v2.0/source/DEV.ASM
Normal file
|
@ -0,0 +1,439 @@
|
|||
;
|
||||
; Device call routines for MSDOS
|
||||
;
|
||||
|
||||
INCLUDE DOSSEG.ASM
|
||||
|
||||
IFNDEF KANJI
|
||||
KANJI EQU 0 ;FALSE
|
||||
ENDIF
|
||||
|
||||
CODE SEGMENT BYTE PUBLIC 'CODE'
|
||||
ASSUME SS:DOSGROUP,CS:DOSGROUP
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.ASM
|
||||
INCLUDE DEVSYM.ASM
|
||||
.cref
|
||||
.list
|
||||
|
||||
TITLE DEV - Device call routines
|
||||
NAME Dev
|
||||
|
||||
i_need IOXAD,DWORD
|
||||
i_need IOSCNT,WORD
|
||||
i_need DEVIOBUF,4
|
||||
i_need IOCALL,BYTE
|
||||
i_need IOMED,BYTE
|
||||
i_need IORCHR,BYTE
|
||||
i_need CALLSCNT,WORD
|
||||
i_need DMAAdd,DWORD
|
||||
i_need NullDevPt,DWORD
|
||||
i_need CallDevAd,DWORD
|
||||
i_need Attrib,BYTE
|
||||
i_need NULDEV,DWORD
|
||||
i_need Name1,BYTE
|
||||
i_need DevPt,DWORD
|
||||
i_need DPBHead,DWORD
|
||||
i_need NumIO,BYTE
|
||||
i_need ThisDPB,DWORD
|
||||
i_need DevCall,DWORD
|
||||
i_need VerFlg,BYTE
|
||||
|
||||
SUBTTL IOFUNC -- DO FUNCTION 1-12 I/O
|
||||
PAGE
|
||||
IOFUNC_RETRY:
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
invoke restore_world
|
||||
|
||||
procedure IOFUNC,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:SI Points to FCB
|
||||
; AH is function code
|
||||
; = 0 Input
|
||||
; = 1 Input Status
|
||||
; = 2 Output
|
||||
; = 3 Output Status
|
||||
; = 4 Flush
|
||||
; AL = character if output
|
||||
; Function:
|
||||
; Perform indicated I/O to device or file
|
||||
; Outputs:
|
||||
; AL is character if input
|
||||
; If a status call
|
||||
; zero set if not ready
|
||||
; zero reset if ready (character in AL for input status)
|
||||
; For regular files:
|
||||
; Input Status
|
||||
; Gets character but restores fcb_RR field
|
||||
; Zero set on EOF
|
||||
; Input
|
||||
; Gets character advances fcb_RR field
|
||||
; Returns ^Z on EOF
|
||||
; Output Status
|
||||
; Always ready
|
||||
; AX altered, all other registers preserved
|
||||
|
||||
MOV WORD PTR [IOXAD+2],SS
|
||||
MOV WORD PTR [IOXAD],OFFSET DOSGROUP:DEVIOBUF
|
||||
MOV WORD PTR [IOSCNT],1
|
||||
MOV WORD PTR [DEVIOBUF],AX
|
||||
|
||||
IOFUNC2:
|
||||
TEST [SI.fcb_DEVID],080H
|
||||
JNZ IOTODEV
|
||||
JMP IOTOFILE
|
||||
|
||||
IOTODEV:
|
||||
invoke save_world
|
||||
PUSH DS
|
||||
PUSH SS
|
||||
POP ES
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
XOR BX,BX
|
||||
MOV [IOCALL.REQSTAT],BX
|
||||
MOV BYTE PTR [IOMED],BL
|
||||
|
||||
MOV BX,OFFSET DOSGROUP:IOCALL
|
||||
|
||||
MOV CX,(DEVRD SHL 8) OR DRDWRHL
|
||||
OR AH,AH
|
||||
JZ DCALLR
|
||||
MOV CX,(DEVRDND SHL 8) OR DRDNDHL
|
||||
DEC AH
|
||||
JZ DCALLR
|
||||
MOV CX,(DEVWRT SHL 8) OR DRDWRHL
|
||||
DEC AH
|
||||
JZ DCALLO
|
||||
MOV CX,(DEVOST SHL 8) OR DSTATHL
|
||||
DEC AH
|
||||
JZ DCALLO
|
||||
DFLUSH:
|
||||
MOV CX,(DEVIFL SHL 8) OR DFLSHL
|
||||
DCALLR:
|
||||
MOV AH,86H
|
||||
DCALL:
|
||||
MOV [IOCALL.REQLEN],CL
|
||||
MOV [IOCALL.REQFUNC],CH
|
||||
MOV CL,AH
|
||||
POP DS
|
||||
ASSUME DS:NOTHING
|
||||
CALL DEVIOCALL
|
||||
MOV DI,[IOCALL.REQSTAT]
|
||||
TEST DI,STERR
|
||||
JZ OKDEVIO
|
||||
MOV AH,CL
|
||||
invoke CHARHARD
|
||||
CMP AL,1
|
||||
JZ IOFUNC_RETRY
|
||||
;Know user must have wanted ignore. Make sure device shows ready so
|
||||
;that DOS doesn't get caught in a status loop when user simply wants
|
||||
;to ignore the error.
|
||||
AND BYTE PTR [IOCALL.REQSTAT+1], NOT (STBUI SHR 8)
|
||||
OKDEVIO:
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
CMP CH,DEVRDND
|
||||
JNZ DNODRD
|
||||
MOV AL,BYTE PTR [IORCHR]
|
||||
MOV [DEVIOBUF],AL
|
||||
|
||||
DNODRD: MOV AH,BYTE PTR [IOCALL.REQSTAT+1]
|
||||
NOT AH ; Zero = busy, not zero = ready
|
||||
AND AH,STBUI SHR 8
|
||||
|
||||
invoke restore_world
|
||||
ASSUME DS:NOTHING
|
||||
MOV AX,WORD PTR [DEVIOBUF]
|
||||
return
|
||||
|
||||
DCALLO:
|
||||
MOV AH,87H
|
||||
JMP SHORT DCALL
|
||||
|
||||
IOTOFILE:
|
||||
ASSUME DS:NOTHING
|
||||
OR AH,AH
|
||||
JZ IOIN
|
||||
DEC AH
|
||||
JZ IOIST
|
||||
DEC AH
|
||||
JZ IOUT
|
||||
return ; NON ZERO FLAG FOR OUTPUT STATUS
|
||||
|
||||
IOIST:
|
||||
PUSH WORD PTR [SI.fcb_RR] ; Save position
|
||||
PUSH WORD PTR [SI.fcb_RR+2]
|
||||
CALL IOIN
|
||||
POP WORD PTR [SI.fcb_RR+2] ; Restore position
|
||||
POP WORD PTR [SI.fcb_RR]
|
||||
return
|
||||
|
||||
IOUT:
|
||||
CALL SETXADDR
|
||||
invoke STORE
|
||||
invoke FINNOSAV
|
||||
CALL RESTXADDR ; If you change this into a jmp don't come
|
||||
return ; crying to me when things don't work ARR
|
||||
|
||||
IOIN:
|
||||
CALL SETXADDR
|
||||
invoke LOAD
|
||||
PUSH CX
|
||||
invoke FINNOSAV
|
||||
POP CX
|
||||
OR CX,CX ; Check EOF
|
||||
CALL RESTXADDR
|
||||
MOV AL,[DEVIOBUF] ; Get byte from trans addr
|
||||
retnz
|
||||
MOV AL,1AH ; ^Z if EOF
|
||||
return
|
||||
|
||||
SETXADDR:
|
||||
POP WORD PTR [CALLSCNT] ; Return address
|
||||
invoke save_world
|
||||
PUSH WORD PTR [DMAADD] ; Save Disk trans addr
|
||||
PUSH WORD PTR [DMAADD+2]
|
||||
PUSH DS
|
||||
PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
MOV CX,WORD PTR [IOXAD+2]
|
||||
MOV WORD PTR [DMAADD+2],CX
|
||||
MOV CX,WORD PTR [IOXAD]
|
||||
MOV WORD PTR [DMAADD],CX ; Set byte trans addr
|
||||
MOV CX,[IOSCNT] ; ioscnt specifies length of buffer
|
||||
POP DS
|
||||
ASSUME DS:NOTHING
|
||||
MOV [SI.fcb_RECSIZ],1 ; One byte per record
|
||||
MOV DX,SI ; FCB to DS:DX
|
||||
invoke GETRRPOS
|
||||
JMP SHORT RESTRET ; RETURN ADDRESS
|
||||
|
||||
RESTXADDR:
|
||||
POP WORD PTR [CALLSCNT] ; Return address
|
||||
POP WORD PTR [DMAADD+2] ; Restore Disk trans addr
|
||||
POP WORD PTR [DMAADD]
|
||||
invoke restore_world
|
||||
RESTRET:JMP WORD PTR [CALLSCNT] ; Return address
|
||||
IOFUNC ENDP
|
||||
|
||||
SUBTTL DEVIOCALL, DEVIOCALL2 - CALL A DEVICE
|
||||
PAGE
|
||||
procedure DEVIOCALL,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:SI Points to device FCB
|
||||
; ES:BX Points to request data
|
||||
; Function:
|
||||
; Call the device
|
||||
; Outputs:
|
||||
; None
|
||||
; DS:SI,AX destroyed, others preserved
|
||||
|
||||
LDS SI,DWORD PTR [SI.fcb_FIRCLUS]
|
||||
|
||||
entry DEVIOCALL2
|
||||
; As above only DS:SI points to device header on entry, and DS:SI is preserved
|
||||
MOV AX,[SI.SDEVSTRAT]
|
||||
MOV WORD PTR [CALLDEVAD],AX
|
||||
MOV WORD PTR [CALLDEVAD+2],DS
|
||||
CALL DWORD PTR [CALLDEVAD]
|
||||
MOV AX,[SI.SDEVINT]
|
||||
MOV WORD PTR [CALLDEVAD],AX
|
||||
CALL DWORD PTR [CALLDEVAD]
|
||||
return
|
||||
DEVIOCALL ENDP
|
||||
|
||||
SUBTTL DEVNAME - LOOK FOR NAME OF DEVICE
|
||||
PAGE
|
||||
procedure DEVNAME,NEAR
|
||||
ASSUME DS:DOSGROUP,ES:DOSGROUP
|
||||
|
||||
; Inputs:
|
||||
; DS,ES:DOSGROUP
|
||||
; Filename in NAME1
|
||||
; Function:
|
||||
; Determine if file is in list of I/O drivers
|
||||
; Outputs:
|
||||
; Carry set if name not found
|
||||
; ELSE
|
||||
; Zero flag set
|
||||
; BH = Bit 7,6 = 1, bit 5 = 0 (cooked mode)
|
||||
; bits 0-4 set from low byte of attribute word
|
||||
; DEVPT = DWORD pointer to Device header of device
|
||||
; Registers BX destroyed
|
||||
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
PUSH CX
|
||||
|
||||
IF KANJI
|
||||
PUSH WORD PTR [NAME1]
|
||||
CMP [NAME1],5
|
||||
JNZ NOKTR
|
||||
MOV [NAME1],0E5H
|
||||
NOKTR:
|
||||
ENDIF
|
||||
|
||||
TEST BYTE PTR [ATTRIB],attr_volume_id ; If looking for VOL id don't find devs
|
||||
JNZ RET31
|
||||
MOV SI,OFFSET DOSGROUP:NULDEV
|
||||
LOOKIO:
|
||||
ASSUME DS:NOTHING
|
||||
TEST [SI.SDEVATT],DEVTYP
|
||||
JZ SKIPDEV ; Skip block devices
|
||||
PUSH SI
|
||||
ADD SI,SDEVNAME
|
||||
MOV DI,OFFSET DOSGROUP:NAME1
|
||||
MOV CX,4 ; All devices are 8 letters
|
||||
REPE CMPSW ; Check for name in list
|
||||
POP SI
|
||||
JZ IOCHK ; Found it?
|
||||
SKIPDEV:
|
||||
LDS SI,DWORD PTR [SI] ; Get address of next device
|
||||
CMP SI,-1 ; At end of list?
|
||||
JNZ LOOKIO
|
||||
RET31: STC ; Not found
|
||||
RETNV: PUSH SS
|
||||
POP DS
|
||||
ASSUME DS:DOSGROUP
|
||||
|
||||
IF KANJI
|
||||
POP WORD PTR [NAME1]
|
||||
ENDIF
|
||||
|
||||
POP CX
|
||||
POP DI
|
||||
POP SI
|
||||
RET
|
||||
|
||||
IOCHK:
|
||||
ASSUME DS:NOTHING
|
||||
MOV WORD PTR [DEVPT+2],DS ; Save pointer to device
|
||||
MOV BH,BYTE PTR [SI.SDEVATT]
|
||||
OR BH,0C0H
|
||||
AND BH,NOT 020H ;Clears Carry
|
||||
MOV WORD PTR [DEVPT],SI
|
||||
JMP RETNV
|
||||
DevName ENDP
|
||||
|
||||
procedure GetBP,NEAR
|
||||
ASSUME DS:DOSGROUP,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; AL = Logical unit number (A = 0)
|
||||
; Function:
|
||||
; Find Drive Parameter Block
|
||||
; Outputs:
|
||||
; ES:BP points to DPB
|
||||
; [THISDPB] = ES:BP
|
||||
; Carry set if unit number bad
|
||||
; No other registers altered
|
||||
|
||||
LES BP,[DPBHEAD] ; Just in case drive isn't valid
|
||||
AND AL,3FH ; Mask out dirty and device bits
|
||||
CMP AL,BYTE PTR [NUMIO]
|
||||
CMC
|
||||
JC GOTDPB ; Get drive A
|
||||
FNDDPB:
|
||||
CMP AL,ES:[BP.dpb_drive]
|
||||
JZ GOTDPB ; Carry is clear if jump executed
|
||||
LES BP,ES:[BP.dpb_next_dpb]
|
||||
JMP SHORT FNDDPB
|
||||
GOTDPB:
|
||||
MOV WORD PTR [THISDPB],BP
|
||||
MOV WORD PTR [THISDPB+2],ES
|
||||
RET
|
||||
GetBP ENDP
|
||||
|
||||
SUBTTL SETREAD, SETWRITE -- SET UP HEADER BLOCK
|
||||
PAGE
|
||||
procedure SETREAD,NEAR
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:BX = Transfer Address
|
||||
; CX = Record Count
|
||||
; DX = Starting Record
|
||||
; AH = Media Byte
|
||||
; AL = Unit Code
|
||||
; Function:
|
||||
; Set up the device call header at DEVCALL
|
||||
; Output:
|
||||
; ES:BX Points to DEVCALL
|
||||
; No other registers effected
|
||||
|
||||
PUSH DI
|
||||
PUSH CX
|
||||
PUSH AX
|
||||
MOV CL,DEVRD
|
||||
SETCALLHEAD:
|
||||
MOV AL,DRDWRHL
|
||||
PUSH SS
|
||||
POP ES
|
||||
MOV DI,OFFSET DOSGROUP:DEVCALL
|
||||
STOSB ; length
|
||||
POP AX
|
||||
STOSB ; Unit
|
||||
PUSH AX
|
||||
MOV AL,CL
|
||||
STOSB ; Command code
|
||||
XOR AX,AX
|
||||
STOSW ; Status
|
||||
ADD DI,8 ; Skip link fields
|
||||
POP AX
|
||||
XCHG AH,AL
|
||||
STOSB ; Media byte
|
||||
XCHG AL,AH
|
||||
PUSH AX
|
||||
MOV AX,BX
|
||||
STOSW
|
||||
MOV AX,DS
|
||||
STOSW ; Transfer addr
|
||||
POP CX ; Real AX
|
||||
POP AX ; Real CX
|
||||
STOSW ; Count
|
||||
XCHG AX,DX ; AX=Real DX, DX=real CX, CX=real AX
|
||||
STOSW ; Start
|
||||
XCHG AX,CX
|
||||
XCHG DX,CX
|
||||
POP DI
|
||||
MOV BX,OFFSET DOSGROUP:DEVCALL
|
||||
RET
|
||||
|
||||
entry SETWRITE
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
; Inputs:
|
||||
; DS:BX = Transfer Address
|
||||
; CX = Record Count
|
||||
; DX = Starting Record
|
||||
; AH = Media Byte
|
||||
; AL = Unit Code
|
||||
; Function:
|
||||
; Set up the device call header at DEVCALL
|
||||
; Output:
|
||||
; ES:BX Points to DEVCALL
|
||||
; No other registers effected
|
||||
|
||||
PUSH DI
|
||||
PUSH CX
|
||||
PUSH AX
|
||||
MOV CL,DEVWRT
|
||||
ADD CL,[VERFLG]
|
||||
JMP SHORT SETCALLHEAD
|
||||
SETREAD ENDP
|
||||
|
||||
do_ext
|
||||
|
||||
CODE ENDS
|
||||
END
|
||||
|