From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/BIOS/MSLPT.ASM | 270 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 v4.0/src/BIOS/MSLPT.ASM (limited to 'v4.0/src/BIOS/MSLPT.ASM') diff --git a/v4.0/src/BIOS/MSLPT.ASM b/v4.0/src/BIOS/MSLPT.ASM new file mode 100644 index 0000000..ad858a0 --- /dev/null +++ b/v4.0/src/BIOS/MSLPT.ASM @@ -0,0 +1,270 @@ + PAGE ,132 ; + TITLE MSLPT - BIOS + %OUT ...MSLPT.ASM + +;============================================================================== +;REVISION HISTORY: +;AN000 - New for DOS Version 4.00 - J.K. +;AC000 - Changed for DOS Version 4.00 - J.K. +;AN00x - PTM number for DOS Version 4.00 - J.K. +;============================================================================== +;AN001 - P156 KBMLPT device driver's retry logic. 8/18/87 J.K. +;============================================================================== + itest=0 + INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT + INCLUDE MSEQU.INC + INCLUDE MSMACRO.INC + INCLUDE DEVSYM.INC + INCLUDE IOCTL.INC + + EXTRN BUS$EXIT:NEAR ;MSBIO1 + EXTRN ERR$CNT:NEAR ;MSBIO1 + EXTRN CMDERR:NEAR ;MSBIO1 + EXTRN GETDX:NEAR ;MSBIO1 + EXTRN EXIT:NEAR ;MSBIO1 + EXTRN ERR$EXIT:NEAR ;MSBIO1 +;DATA + EXTRN PTRSAV:DWORD ;MSBIO1 + EXTRN TIMDEV:WORD ;MSCLOCK + EXTRN LPT2DEV:WORD ;MSBIO2 + EXTRN WAIT_COUNT:WORD ;MSDATA + EXTRN PRINTDEV:BYTE ;MSDATA +; IBM ROM STATUS BITS (I DON'T TRUST THEM, NEITHER SHOULD YOU) + +NOTBUSYSTATUS = 10000000B ; NOT BUSY +ACKSTATUS = 01000000B ; ACKNOWLEDGE (FOR WHAT?) +NOPAPERSTATUS = 00100000B ; NO MORE PAPER +SELECTEDSTATUS = 00010000B ; THE PRINTER SAID IT WAS SELECTED +IOERRSTATUS = 00001000B ; SOME KINDA ERROR +RESERVED = 00000110B ; NOPS +TIMEOUTSTATUS = 00000001B ; TIME OUT. + + +; WARNING!!! THE IBM ROM DOES NOT RETURN JUST ONE BIT. IT RETURNS A +; WHOLE SLEW OF BITS, ONLY ONE OF WHICH IS CORRECT. + +;---------------------------------------------------------- +;J.K. AN001; PRN$WRIT will retry only if error code is TIMEOUT. + +; WRITE TO PRINTER DEVICE + +; CX HAS COUNT OF BYTES +; ES:DI POINT TO DESTINATION +; AUXNUM HAS PRINTER NUMBER + + PUBLIC PRN$WRIT +PRN$WRIT PROC NEAR + ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY + + jcxz Prn$Done ;No char to output +Prn$Loop: + mov bx, 2 ;Initialize retry count +Prn$Out: +;SB34LPT000**************************************************************** +;SB Print the character at ES:[DI] +;SB Call the function PrnOP to do this +;SB The character to be printed goes in AL and the function code +;SB for 'Output character' goes in AH +;SB Check for error in printing. +;SB If there is no error go to print the next character. +;SB If there is an error indicated see if it is due to TIMEOUT. If the +;SB error is not TIMEOUT then we can do nothing about it. Just go to +;SB print the next character. If it is due to timeout we can execute +;SB the code to retry the print which follows this piece of code +;SB LOCS: 6 + + mov al,es:[di] ; assume AX disposible since enter + xor ah,ah ; via int 21h + call PrnOp ; print to printer + jz Prn$Con ; no error - continue + test ah,TIMEOUTSTATUS + jz Prn$Con ; NOT time out - continue + +;SB34LPT000**************************************************************** + dec bx ;Retry until count is exhausted. + jnz Prn$Out ;Retry it. + jmp short Pmessg ;Return with error. + ; + ; next character + ; +Prn$Con: + inc di ;point to next char and continue + loop Prn$Loop +Prn$Done: + jmp Exit +Pmessg: + jmp Err$Cnt +PRN$WRIT endp + +; JCXZ EXVEC3 ; NO CHARS TO OUTPUT.. +;PRN$LOOP: +; MOV BX,2 ; INITIALIZE RETRY FLAG +;PRN$OUT: +; MOV AL,ES:[DI] ; GET CHAR INTO AL +; INC DI ; POINT TO NEXT CHAR +; XOR AH,AH ; AH=0 => OUTPUT CHAR IN DL +; CALL PRNOP ; TO INDICATE PRINT CHAR IN AL +; JNZ PRRETRY +; LOOP PRN$LOOP +;EXVEC3: +; JMP EXIT +;PRRETRY: +; DEC DI ; UNDO THE INC ABOVE... +; DEC BX +; JNZ PRN$OUT +;PMESSG: +; JMP ERR$CNT ;RETURN WITH THE ERROR +;PRN$WRIT ENDP + +;-------------------------------------------------------- + +; PRINTER STATUS ROUTINE + + PUBLIC PRN$STAT +PRN$STAT PROC NEAR + ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY + + CALL PRNSTAT ;DEVICE IN DX + JNZ PMESSG ; OTHER ERRORS WERE FOUND +;J.K. The next three lines are commented out, since it is a dead code. +; MOV AL,9 ; AGAIN, ASSUME OUT OF PAPER... +; TEST AH,NOPAPERSTATUS +; JNZ PMESSG + TEST AH,NOTBUSYSTATUS + jnz Prn$Done ;No error. Exit + JMP BUS$EXIT +PRN$STAT ENDP + +; TAKE THE APPROPRIATE PRINTER AND DO THE OPERATION. TRIAGE THE STATUS +; RETURNED IN AH INTO SOME MEANINGFUL ERROR. + +PRNSTAT PROC NEAR +;SB33037********************************************************************** + mov AH, 2 ; set command for get status ;SB ;3.30* +PRNOP: ;SB ;3.30* + call GETDX ; determine which printer ;SB ;3.30* + int 17h ; call ROM-BIOS printer routine ;SB;3.30* + +;SB33037********************************************************************** + +; EXAMINE THE STATUS BITS TO SEE IF AN ERROR OCCURRED. UNFORTUNATELY, SEVERAL +; OF THE BITS ARE SET SO WE HAVE TO PICK AND CHOOSE. WE MUST BE EXTREMELY +; CAREFUL ABOUT BREAKING BASIC. + + TEST AH,IOERRSTATUS ; I/O ERROR? + JZ CHECKNOTREADY ; NO, TRY NOT READY + +; AT THIS POINT, WE KNOW WE HAVE AN ERROR. THE CONVERSE IS NOT TRUE. + + MOV AL,9 ; FIRST, ASSUME OUT OF PAPER + TEST AH,NOPAPERSTATUS ; OUT OF PAPER SET? + JNZ RET1 ; YES, ERROR IS SET + INC AL ; INDICATE I/O ERROR +RET1: + +; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT) + + RET ; RETURN WITH ERROR + +; THE BITS SAID NO ERROR. UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WORK +; HERE. + +CHECKNOTREADY: + MOV AL,2 ; ASSUME NOT-READY + TEST AH,TIMEOUTSTATUS ; IS TIME-OUT SET? + ; IF NZ THEN ERROR, ELSE OK??? +PRNOP2: + RET +PRNSTAT ENDP + +; OUTPUT UNTIL BUSY. THIS ENTRY POINT IS USED EXCLUSIVELY BY THE PRINT +; SPOOLERS. UNDER NO CURCUMSTANCES SHOULD THE DEVICE DRIVER BLOCK WAITING FOR +; THE DEVICE TO BECOME READY. + +; INPUTS: CX HAS COUNT OF BYTES TO OUTPUT. +; ES:DI POINTS TO SOURCE BUFFER +; OUTPUTS: SET THE NUMBER OF BYTES TRANSFERRED APPROPRIATELY + PUBLIC PRN$TILBUSY +PRN$TILBUSY PROC NEAR + ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY + + PUSH DS + PUSH ES + POP DS ; NOW ES AND DS BOTH POINT TO SOURCE BUFFER + ASSUME DS:NOTHING + + MOV SI,DI ; EVERYTHING IS SET FOR LODSB +PRN$TILBLOOP: + PUSH CX + PUSH BX + XOR BX,BX + MOV BL,CS:[PRINTDEV] + SHL BX,1 + MOV CX,CS:WAIT_COUNT[BX] ; WAIT COUNT TIMES TO COME READY + POP BX +PRN$GETSTAT: + CALL PRNSTAT ; GET STATUS + JNZ PRN$BPERR ; ERROR + TEST AH,10000000B ; READY YET? + LOOPZ PRN$GETSTAT ; NO, GO FOR MORE + POP CX ; GET ORIGINAL COUNT + JZ PRN$BERR ; STILL NOT READY => DONE + LODSB + XOR AH,AH + CALL PRNOP + JNZ PRN$BERR ; ERROR + LOOP PRN$TILBLOOP ; GO FOR MORE +PRN$B: + POP DS + LDS BX,CS:[PTRSAV] + ASSUME DS:NOTHING + SUB WORD PTR [BX].COUNT,CX ;# OF SUCCESSFUL I/O'S + JMP EXIT +PRN$TILBUSY ENDP + +PRN$BPERR PROC NEAR + ASSUME DS:CODE + POP CX +PRN$BERR: + POP DS + LDS BX,CS:[PTRSAV] + ASSUME DS:NOTHING + + SUB WORD PTR [BX].COUNT,CX ;# OF SUCCESSFUL I/O'S + JMP ERR$EXIT +PRN$BPERR ENDP +; +; MANIPULATES THE VALUE IN WAIT_COUNT DEPENDING ON THE VALUE PASSED IN THE +; GENERIC IOCTL PACKET. +; IT EITHER SETS OR RETURNS THE CURRENT VALUE FOR THE RETRY COUNT FOR THE +; DEVICE. +; + PUBLIC PRN$GENIOCTL +PRN$GENIOCTL PROC NEAR + ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY + + LES DI,[PTRSAV] + CMP ES:[DI].MAJORFUNCTION,IOC_PC + JE PRNFUNC_OK +PRNFUNCERR: + JMP CMDERR + +PRNFUNC_OK: + MOV AL,ES:[DI].MINORFUNCTION + LES DI,ES:[DI].GENERICIOCTL_PACKET + XOR BX,BX + MOV BL,[PRINTDEV] ; GET INDEX INTO RETRY COUNTS + SHL BX,1 + MOV CX,WAIT_COUNT[BX] ; PULL OUT RETRY COUNT FOR DEVICE + CMP AL,GET_RETRY_COUNT + JZ PRNGETCOUNT + CMP AL,SET_RETRY_COUNT + JNZ PRNFUNCERR + MOV CX,ES:[DI].RC_COUNT +PRNGETCOUNT: + MOV WAIT_COUNT[BX],CX ; PLACE "NEW" RETRY COUNT + MOV ES:[DI].RC_COUNT,CX ; RETURN CURRENT RETRY COUNT + JMP EXIT +PRN$GENIOCTL ENDP +CODE ENDS + END -- cgit v1.2.3