⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iolpt.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	JMP	word ptr lperrt[BX] ; asmter this way



;Raw Line Printer Output routine
; Entry - [AL]=byte to be sent to current line printer
;	  [AH]=device id (0..n)
; Exit	- Flags used, All other registers preserved.

LPROUT:
	PUSH	AX
	PUSH	BX
	MOV	BX,FileDB.FD_HANDLE ; get handle for routine
	CALL	B$SNDLPT	; Call OEM routine to output to printer
	OR	AH,AH
	JNE	LPERR		;branch if OEM routine detected error
	POP	BX
	POP	AX
	RET



;*** 
; LPT_SOUT -- Sequential output.
;
;Purpose:
;	This routine keeps track of column position, expands tabs, and forces
;	a carriage return when line width is exceeded.
;
;Entry:
;	(ES:)[SI] = *FDB
;	DI = -2*device id
;	[AL] = byte to be output.
;
;Exit:
;	None
;
;Uses:
;	SI, DI can be changed.
;
;Preserves:
;	All other registers.
;
;Exceptions:
;
;******************************************************************************
cProc	LPT_SOUT,<NEAR>,<DX>	
cBegin				

;	First check if LPRINT is being performed.  If so, then check
;	if it is the first character since it was last closed and do
;	an open operation on LPT1.

	CMP	SI,OFFSET DGROUP:b$LPTFDB ; test if LPRINT
	JNE	NO_LPRINT_OPEN	;if not, then jump
	TEST	b$LPTFDB.FD_FLAGS,FL_LPT_OPN ; test if device is open
	JNE	NO_LPRINT_OPEN	;if so, then jump
	PUSH	AX		;save registers...
	PUSH	BX
	XOR	AH,AH		;will select LPT1
	CALL	B$OPNLPT	; open the device
	OR	AH,AH		;test for any errors
	JNZ	LPERR		;if so, then jump
	MOV	WORD PTR b$LPTFDB.FD_HANDLE,BX ; get handle in FDB
	OR	b$LPTFDB.FD_FLAGS,FL_LPT_OPN ; set the open flag
	POP	BX		;restore registers...
	POP	AX
NO_LPRINT_OPEN:

	PUSH	BX		;save caller's BX
	PUSH	AX		;save char to be output
	CALL	GLPDCB		;DI points to line printer DCB, unit in AH
				; Note interpreter returns unit in AX!
	MOV	BL,AH		;[BL] = device id
	POP	AX		;[AL] = byte to be output
	MOV	AH,BL		;[AH] = device id
	POP	BX		;restore caller's BX

	MOV	DX,WORD PTR _LPWID[DI] ;[DL]=device width, [DH]=current column
	CMP	SI,OFFSET DGROUP:b$LPTFDB	; Test if LPRINT FDB
	JZ	NOTBIN		;branch if so -- not binary mode
	MOV	DL,FileDB.FD_WIDTH	;Get width from FDB

	TEST	FileDB.FD_FLAGS,FL_BIN	; binary mode?
	JZ	NOTBIN		; brif not
	CALL	LPROUT		; Raw output of character
	CALL	$UPDPOS		; DH = new position
	JMP	SHORT SAVPOS	; save new position
	
NOTBIN:
	CALL	$CRIFEL 	;force CR if End-Of-Line
SAVPOS:
	MOV	BYTE PTR _LPPOS[DI],DH ;save new column position
cEnd				


;*** 
; LPOUT1 -- low-level line printer output
;
;Purpose:
;	For IBM Compatibility, the filter performs the following translations
; 		x x x CR x x x    === x x x CR LF x x x
;		x x x CR LF x x x === x x x CR LF x x x
;	If LPT was opened for RANDOM mode, and WIDTH=255, then suppress LF which
;	follow carriage returns for IBM compatibility.
;
;	Eat all LineFeeds which follow CarriageReturns with following algorithm:
;	if (Char <> LF) or (LastWasCR = 0) then output (Char)
;	if (Char = CR) then
;	    LastWasCR = 1
;	    if FDB.MODE<>RANDOM or FDB.WIDTH<>255 then
;		output(LF)
;	else
;	    LastWasCR = 0
;
;	The only case where this is not compatible with IBM is when the user
;	executes:
;		PRINT CHR$(13);CHR$(10);...
;
;	The best way this could have been done was by setting CRONLY=1 in the
;	switch files and letting the device drivers append Line-Feeds if
;	necessary.  It was considered too late to make a change this drastic.
;
;Entry:
;	AL = char to output
;	(ES:)[SI] = *FDB
;
;Exit:
;	DH = new column position
;
;Uses:
;	None
;
;Exceptions:
;
;******************************************************************************
cProc	LPOUT1,<NEAR>		
cBegin				

	CALL	$UPDPOS 	;[DH]=new column position(AL, DH)
	CMP	AL,ASCLF
	JNE	LPOUT2		;branch if not attempting to output LF
	CMP	b$EOL,1	; end-of-line processing ?
	JNE	LPOUT2		; brif not end-of-line processing, the
				; user might be doing something like
				; print chr$(13)+chr$(10)
	TEST	BYTE PTR _LPFLG[DI],_LPCRF
	JNE	LPOUT3		;brif last byte out was CR (eat LF)
LPOUT2:
	CALL	LPROUT		;output the character
LPOUT3:
	AND	BYTE PTR _LPFLG[DI],255-_LPCRF ;reset last byte out was CR flag
	CMP	AL,ASCCR
	JNE	LPOUTX		;return if wasn't carriage return
	OR	BYTE PTR _LPFLG[DI],_LPCRF ;set last byte out CR flag

	CMP	SI,OFFSET DGROUP:b$LPTFDB	; Test if LPRINT FDB
	JZ	OUTLF		;branch if Pseudo FDB (LPRINT)

	CMP	FileDB.FD_MODE,MD_RND	;MODE = RANDOM?
	JNE	OUTLF		; brif not -- print LF after a CR
	CMP	FileDB.FD_WIDTH,255	;WIDTH = 255?
	JE	LPOUTX		; brif so -- suppress LF following CRs
OUTLF:
	PUSH	AX
	MOV	AL,ASCLF
	CALL	LPROUT
	POP	AX
LPOUTX:
cEnd				


$CRIFEL:
	CALL	LPOUT1		; output character
	CMP	DH,DL		; compare column with width
	JB	NOCR		; Brif still room on current line
	CMP	AL,32		; printable character ?
	JB	NOCR		; brif non-printable
	CMP	DL,255		; infinite width ?
	JZ	NOCR		; Brif so (width = 255)
				; else output <CR><LF>

WRICR:				; output <CR>
	PUSH	AX		; save char
	MOV	AL,ASCCR
	CALL	LPOUT1		
	POP	AX		; restore char
NOCR:				
	RET

;$UPDPOS - update column position (called by device out routines)
; Entry - [DH] = current 0-relative column position
;	  [AL] = byte to be output
; Exit	- [DH] = new column position.  All other registers preserved

$UPDPOS: CMP	AL,32
	JB	NPRINT		;branch if not printable (CTL CHR)
	INC	DH		;bump column position
	RET
NPRINT: CMP	AL,ASCCR
	JNE	NOTCR		;branch if not carriage return
ZERPOS: MOV	DH,0		;reset to left margin
	RET
NOTCR:	CMP	AL,ASCBS
	JNE	UPPOSX		;branch if not backspace
	OR	DH,DH
	JE	UPPOSX		;don't decrement below 0
	DEC	DH		;decrement position
UPPOSX: RET



;	GPOS - Get position

;	EXIT	(AH) = device position

LPT_GPOS:
	MOV	AH,POSITION	;Get position (device)
	RET


;	GWID - Get width

;	EXIT	(AH) = file width

LPT_GWID:
	MOV	AH,FileDB.FD_WIDTH  ;Get printer (file) width
	RET


fileio	ENDP

;***
; B$LPOS - Line printer position
;
; Purpose:
;	Get line printer position
; Input:
;	lptID = printer # (map 1 into 0, etc.)
; Output:
;	(AX) = printer position
; Modifies:
;	per convention
; Exceptions:
;	Control may be transfered to B$ERR_FC
;****
cProc	B$LPOS,<PUBLIC,FAR>	
parmW	lptID			
cBegin				
	MOV	BX,lptID	
	CMP	BX,NUM_LPT	;Check for too high
	JA	ercfc
	OR	BX,BX		;Test for 0 - same as 1
	JZ	lpos1
	DEC	BX		;Map 1 to 0
lpos1:	SHL	BX,1		;BX=0,2,4... offset into B$LPTWID
	MOV	AL,LPTPOS[BX]	;Get position for printer #n
	XOR	AH,AH		
	INC	AX		
cEnd				

ercfc:	JMP	B$ERR_FC

;***
; B$LWID - WIDTH LPRINT Statement
;
; Purpose:
;	Sets the LPRINT file width and device width
; Input:
;	newWidth = desired LPRINT file width
; Output:
;	NONE
; Modifies:
;	Per convention
; Exceptions:
;	NONE
;****
cProc	B$LWID,<PUBLIC,FAR>	
parmW	newWidth		
cBegin				
	MOV	DX,newWidth		;  Get New Width for Printer
	or	dh,dh			;  If new widht is >255 Error
	jnz	ercfc			;  and
	or	dl,dl			;  If new width is zero Error
	jz	ercfc			

	MOV	B$LPTWID,DL		;Set printer 1 width
	MOV	b$LPTFDB.FD_WIDTH,DL	;Set LPRINT file width
cEnd				

;GLPDCB - get pointer to LPT Device Control Block
; Entry - [DI] = -2*device id (2,4,..n)
; Exit	- DI points to the device control block for device DI.
;	  [AH] = 0..n for LPT1, LPT2, ...
;		 Note: interpreter returns unit number in AX!

GLPDCB: CALL	B$GLPUID 	; [AH]=unit id (0..n)
	PUSH	AX		;save unit id
	xchg	ah,al
	xor	ah,ah
	SHL	AX,1		;2 fields in DCB
	ADD	AX,OFFSET DGROUP:B$LPTWID
	MOV	DI,AX		;DI points to LPTx device ctl block
	POP	AX		;[AX]=unit id
	RET

;***
;B$LPTECHO
;Purpose:
;	Echo to the line printer.		[13]
;Entry:
;	[AX] = character code
;Exit:
;	none
;Modifies:
;	none ([AX] is preserved)
;****
cProc	B$LPTECHO,<PUBLIC,NEAR>,<DI,SI,AX>
cBegin
	MOV	SI,OFFSET DGROUP:b$LPTFDB	
	MOV	DI,DN_LPT1*-2	; lpt1:
	OR	AH,AH		;  Test for two byte character
	JZ	ONEBYT
	PUSH	AX
	XCHG	AH,AL
	CALL	LPT_SOUT	; Write the high byte first
	POP	AX
ONEBYT:
	CALL	LPT_SOUT	; Then the low byte
cEnd

; Entry - [DI] = -2*device id (2,4,..n)
; Exit	- [AH] = 0..n for LPT1, LPT2, ...
; Uses AH

cProc	B$GLPUID,<NEAR>,<BX>	
cBegin

	MOV	BX,DI
	ADD	BX,2*DN_LPT1
	SHR	BX,1		;[BX]=0, 1. for LPT1, LPT2, ...
	MOV	AH,BL		; return (printer # - 1) * 2 in AH

cEnd


;	File close routines
;	Deallocate file block

cProc	LPT_CLOSE,<NEAR>	
cBegin

	PUSH	BX		;save register
	MOV	BX,FileDB.FD_HANDLE ; get handle of printer
	CALL	B$CLSLPT	; close the device
	POP	BX		;restore the register
	CMP	SI,OFFSET DGROUP:b$LPTFDB ; is this LPRINT?
	JE	LPRINT_CLOSE	;if so, then branch
	CALL	B$LHDALC_CPCT	; deallocate FDB and compact local heap
LPRINT_CLOSE:

cEnd				; return to caller

	SUBTTL	interface for LPRINT preamble
	page
;***
;B$LPRT -- LPRINT preamble
;void B$LPRT(void)
;
;Purpose:
;	This is the only interface for LPRINT preamble.  BASCOM 2.0 uses two
;	preambles, $PR0E for LPRINT and $PR0F for LPRINT USING.  This routine
;	sets up flag, b$PRFG, to 8 (LPSTM) to indicate LPRINT is on going.
;	If there is LPRINT USING, B$USNG will OR the flag, b$PRFG, with
;	USING (=2) to indicate USING is on going.
;Entry:
;	none
;Exit:
;	b$PTRFIL = LPRINT FDB pointer/handle
;	b$PRFG is set to LPSTM (=8)
;Uses:
;	none
;Exceptions:
;	none
;*******************************************************************************

cProc	B$LPRT,<PUBLIC,FAR>,<SI> ; don't set up frame (can't get an error)
cBegin

	OR	[b$PRFG],LPSTM ;set the flag to indicate a LPRINT is on going

	MOV	[b$PTRFIL],OFFSET DGROUP:b$LPTFDB ;set up b$PTRFIL

	MOV	SI,OFFSET DGROUP:b$FILVEC
	cCall	B$WCHSET	;set the dispatch vector for print items

cEnd				; exit to caller



sEnd	OI_TEXT 		

	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -