From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/DEV.ASM | 439 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 439 insertions(+) create mode 100644 v2.0/source/DEV.ASM (limited to 'v2.0/source/DEV.ASM') 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 @@ +; +; 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 + \ No newline at end of file -- cgit v1.2.3