Category : Assembly Language Source Code
Archive   : DRIVEKIT.ZIP
Filename : PRNMOD.ASM

 
Output of file : PRNMOD.ASM contained in archive : DRIVEKIT.ZIP

PAGE
PAGE 62,132
TITLE RS232 Printer Device Driver Module
NAME prnmod
;
INCLUDE REQHDR.MAC
;
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CSEG, DS:CSEG
;
;Defined elsewhere...
EXTRN DONE:near, DONE2:near, ERROUT:near, XFER:near
EXTRN REQHDR:dword
;
;Defined here...
PUBLIC PRNOUT, PRNSTAT, PRNIT
PUBLIC PRNCTL_IN, PRNCTL_OUT
;
;
; RS232 Communications channels
COMM0 EQU 0
COMM1 EQU 1
;
; Interrupt 14H functions
SETCOMM EQU 0 ;set channel baud,parity,stopbits,databits
WRITE EQU 1 ;write AL to port
READ EQU 2 ;read AL from port
STAT EQU 3 ;read channel status
;
; Returned status bits
TXEMPTY EQU 20H ;transmitter register empty
DSRBIT EQU 20H ;data set ready bit
CTSBIT EQU 10H ;clear to send bit
TX_OK EQU 80H ;transmission successful
;
; Channel initialization byte
; Bit field definitions
B110 EQU 00000000B ;110 BAUD
B150 EQU 00100000B ;150 BAUD
B300 EQU 01000000B ;300 BAUD
B600 EQU 01100000B ;600 BAUD
B1200 EQU 10000000B ;1200 BAUD
B2400 EQU 10100000B ;2400 BAUD
B4800 EQU 11000000B ;4800 BAUD
B9600 EQU 11100000B ;9600 BAUD
;
NOPAR EQU 00000000B ;no parity
ODD EQU 00001000B ;odd parity
EVENP EQU 00011000B ;even parity
;
STOP1 EQU 00000000B ;1 stop bit
STOP2 EQU 00000100B ;2 stop bits
;
DATA7 EQU 00000010B ;7 bits data
DATA8 EQU 00000011B ;8 bits data
;
DEFAULT EQU B9600+EVENP+STOP1+DATA7
page
;--------------------------------------------------------------------------
;
; .OUTPUT: Printer Output via ROM BIOS INT 14H
;
; On entry DS=CS, CX=byte count, ES:DI transfer buffer
;
PRNOUT PROC NEAR
;
JCXZ OEX ;if 0 bytes to xfer, return
NXBYTE: MOV AL,ES:[DI] ;get byte from transfer buffer
INC DI ; advance buffer ptr
MOV BYTE PTR RCNT,2
;
RETRY: MOV AH,WRITE ;send AL to COMM0 port
MOV DX,COMM1 ;
INT 14H ;
TEST AH,TX_OK ;transmission successful?
JZ CONTINUE ; then continue
;
DEC BYTE PTR RCNT ;decrement retry count
JNZ RETRY ;
MOV AL,WRFLT ;write fault error code
JMP ERROUT ; exit
;
CONTINUE:
LOOP NXBYTE ;exhaust byte count
OEX: JMP DONE ;successful return
;
PRNOUT ENDP
;
RCNT DB ? ;error retry count
;
page
;--------------------------------------------------------------------------
;
; .IOCTL_IN: Read printer channel initialization parameter
;
; On entry DS=CS, CX=byte count, ES:DI transfer buffer
;
PRNCTL_IN PROC NEAR
;
JCXZ OEX ;leave if 0 bytes requested
MOV SI,OFFSET DEST ;
;
RDPARM: MOV AL,[SI] ;move parameters to transfer buffer
MOV ES:[DI],AL ; with 0 termination
OR AL,AL ;
JZ MOVFIN ;
INC SI ;
INC DI ;
LOOP RDPARM ;
INC CX ;
;
MOVFIN: DEC CX ;
JMP XFER ;on return set DONE and bytes transferred
;
PRNCTL_IN ENDP
page
;--------------------------------------------------------------------------
;
; .IOCTL_OUT: Write printer channel initialization parameter
;
; On entry DS=CS, CX=byte count, ES:DI transfer buffer
;
PRNCTL_OUT PROC NEAR
;
JCXZ OEX ;leave if 0 bytes requested
MOV SI,OFFSET DEST ;
CMP CX,20 ;if request is to send more than
JBE WRPARM ; 20 bytes, set limit at 20
MOV CX,20 ;
;
WRPARM: MOV AL,ES:[DI] ;move parameters from transfer buffer
MOV [SI],AL ;
INC SI ;
INC DI ;
LOOP WRPARM ;
;
PUSH CX ;
CALL CH_BYTE ;convert first 2 characters to byte
MOV AH,SETCOMM ;initialize channel
MOV DX,COMM1 ; to requested baud rate, parity, etc.
INT 14H ;
POP CX ;
;
JMP XFER ;on return set DONE and bytes transferred
;
PRNCTL_OUT ENDP
;
; Channel initialization byte
OLDPARM DB DEFAULT ;default 9600,even parity, 7 data, 1 stop bit
page
;--------------------------------------------------------------------------
;
; .OUTSTAT: Printer channel status from ROM BIOS INT 14H
;
; On entry DS=CS, CX=byte count, ES:DI transfer buffer
;
PRNSTAT PROC NEAR
;
MOV AH,STAT ;get channel status in AX
MOV DX,COMM1 ;
INT 14H ;
;
;check that clear to send and data set ready are asserted
TEST AL,CTSBIT+DSRBIT
JZ BSY ;
TEST AH,TXEMPTY ;transmitter register empty?
JZ BSY ;
EXIT: JMP DONE ;NOT busy return
BSY: JMP DONE2 ;busy return
;
PRNSTAT ENDP
;
;
; Convert ASCII HEX comm port initialization byte to binary
;
CH_BYTE PROC NEAR
;
PUSH CS ;
POP DS ;
MOV BX,OFFSET DEST ;point to parameter string
MOV AL,[BX+0] ; get most significant HEX digit
CALL TOHEX ; convert to binary nibble
XCHG AL,AH ; save in AH
MOV AL,[BX+1] ; get least significant HEX digit
CALL TOHEX ; convert to binary nibble in AL
MOV CL,4 ;
SHL AH,CL ; shift most significant digit into upper nibble
ADD AL,AH ; combine with lower nibble and save
MOV BYTE PTR OLDPARM,AL
RET ;
CH_BYTE ENDP
;
; Convert ASCII HEX byte to binary byte
;
TOHEX PROC NEAR
;
SUB AL,30H ;
CMP AL,0AH ;
JC HEXRET ;
SUB AL,07H ;
HEXRET: RET ;
;
TOHEX ENDP
;
;--------------------------------------------------------------------------
;
; .INIT: PRN device driver INIT code
;
; On entry DS=CS, CX=byte count, ES:DI transfer buffer
;
CR EQU 0DH
LF EQU 0AH
DESTLNG EQU 20
;
; Parameters passed in device= command line
DEST DB DESTLNG DUP (?)
;
;
PRNIT PROC NEAR
;
ENDPRN EQU $
;
LEA AX,CS:ENDPRN ;offset to end of resident driver
MOV DX,CS ;segment address
LDS BX,CS:REQHDR ;DS:BX pts to request header
MOV [BX+BRKSEG],DX ; save ending code segment address
MOV [BX+BRKOFF],AX ; save ending code offset address
;
;get ptr to filename portion of command line in CONFIG.SYS file
LDS SI,DWORD PTR[BX+PARMS]
PUSH CS ;
POP ES ;
MOV DI,OFFSET DEST ;destination address for parms
;
TOP1: MOV AL,[SI] ; check for termination char's
;
; command line has the form: device=filename /parms
; or device=filename
;
CMP AL,CR ;parms are present
JZ GETPARMS ;
CMP AL,LF ;no parm field
JZ NOPARMS ;
;
INC SI ;
JMP SHORT TOP1 ;
;
GETPARMS:
MOV CX,0 ;character count
NXTCHR: DEC SI ;back up ptr
INC CX ;
MOV AL,[SI] ;
CMP AL,'/' ;scan for start character
JNZ NXTCHR ;
DEC CX ;
INC SI ;ready to move parms to DEST
REP MOVSB ;
MOV AL,0 ;terminate with 0
MOV ES:[DI],AL ;
CALL CH_BYTE ;convert parm to binary byte in OLDPARM
NOPARMS:
MOV AL,BYTE PTR OLDPARM
MOV AH,SETCOMM ;initialize channel
MOV DX,COMM1 ; to requested baud rate, parity, etc.
INT 14H ;
;
MOV DX,OFFSET SIGN_ON
MOV AH,9 ;boot message
INT 21H ;
JMP DONE ;
;
PRNIT ENDP
;
SIGN_ON DB 'Serial printer channel 1 initialized'
DB 0AH,0DH,'$'
;
CSEG ENDS
END