	.IF	LISTC
	.LIST
	.PAGE
	.ELSE
	.NOLIST
	.ENDC
;****************************************************************************
;
;	Printer I/O Handler
;
;	File:	SAGE.BIOSC.TEXT
;	Date:	 2-Aug-83
;	Issue:	2A
;
;
;	COPYRIGHT (c) 1982, 1983 SAGE Computer Technology
;	All Rights Reserved
;
;****************************************************************************
;
;	History:
;
;	1     13-Jun-82 Initial release.
;	1A    20-Jul-82 Installed BRKOUT check in PRTOUT.
;	1B    15-Aug-82 Installed call to IOCONFA in INCHAN6 & WCFCH6.
;	1C    23-Aug-82 Added event handling.  Had size and address reversed
;			in WTCHAN6.
;	1D    24-Aug-82 Fixed Status read on redirect to Remote.
;	1E     2-Oct-82 Fixed status read of byte 50.
;	1F    15-Dec-82 Disabled 8259 interrupt in INCHAN6 and when all
;			characters output in PRTINT.
;	2     23-Mar-83 Initial SAGE IV release.
;	2A     1-Aug-83 Disable foreground when calling PRTPOLL from
;			background.
;
;****************************************************************************




.PAGE
;****************************************************************************
;
;	Printer output routine (background)
;
;	Outputs character from D0 (low byte).
;
;	All registers are preserved.
;
;****************************************************************************

PRTOUTX MOVE	SR,-(A7)	;Local BIOS entry point
				;Simulate TRAP entry

;	Normal TRAP entry point
PRTOUT	MOVE.W	D1,-(A7)	;Save a working register
$10	MOVE	#2100H,SR	;Disable printer channel interrupts
	CLR.W	D1
	MOVE.B	PRTPUT,D1
	ADDQ.B	#1,D1		;Advance Put pointer
	CMP.B	PRTGET,D1
	BEQ.S	$30		;Output buffer is full
	SUBQ.B	#1,D1		;Store in original Put pointer position
	MOVE.B	#0DH,C8255+6	;Enable interrupt on 8255
	MOVE.L	A0,-(A7)	;Save address register
	LEA	PRTBUF,A0
	MOVE.B	D0,0(A0,D1.W)	;Store character in printer out buffer
	ADDQ.B	#1,PRTPUT	;Update put pointer
	MOVEA.L (A7)+,A0	;Restore address register
	CMPI.B	#2,PRTMODE	;Check if interrupt driven
	BNE.S	$100		;Not interrupt driven
	BSET	#0,PRTCMD	;Check if printer interrupt enabled
	BNE.S	$20		;Was already enabled
	MOVE.B	D0,C8255	;Output to printer port
	MOVE.B	#08H,C8255+6	;Set up strobe signal
	ADDQ.B	#1,PRTGET	;Advance Get pointer
	BCLR	#5,P8259+2	;Enable interrupt on 8259
	MOVE.B	#09H,C8255+6	;Remove strobe signal
	
$20	MOVE	#2000H,SR	;Enable interrupts
$22	MOVE.W	(A7)+,D1	;Restore working register
	CLR.B	1(A7)		;Condition code to NE on return
	RTE

;	Hang and wait for a change
$30	CLR.B	BRKOUT		;Make sure Break Out flag is clear
	STOP	#2000H		;Enable interrupts and stop
	TST.B	BRKOUT		;Check if Break occured
	BEQ	$10		;No Break, Look again
	BRA	$22		;Throw away character and return


;	Process polled printer output
$100	TST.B	PRTTIM		;Check for Scheduled Printer Poll
	BNE	$20		;Had poll already scheduled
	BSET	#7,P8259+2	;Disable foreground
	MOVE	#2000H,SR	;Enable interrupts
	BSR.S	PRTPOLL		;Poll for printer output
	BCLR	#7,P8259+2	;Enable foreground
	BRA	$20


;	Poll for printer output
PRTPOLL MOVE.W	PRTPLC,D1	;Set up poll loop count
$10	BTST	#4,C8255+2	;Check if still busy
	DBEQ	D1,$10
	BNE	$30		;Poll timed out
	CLR.B	PRTTIM		;Clear schedule flag
	CLR.W	D1
	MOVE.B	PRTGET,D1
	CMP.B	PRTPUT,D1	;Check if any characters
	BEQ.S	$20		;Queue is empty
	MOVE.L	A0,-(A7)	;Save an address register
	LEA	PRTBUF,A0
	MOVE.B	0(A0,D1.W),C8255 ;Output to printer port
	MOVE.B	#08H,C8255+6	;Set up strobe signal
	MOVEA.L (A7)+,A0	;Restore address register
	ADDQ.B	#1,PRTGET	;Advance Get pointer
	MOVE.B	#09H,C8255+6	;Remove strobe signal
	MOVE.B	PRTGET,D1
	CMP.B	PRTPUT,D1	;Check if any characters
	BNE.S	PRTPOLL		;Queue is not empty
$20	MOVE.B	ATCHTBL+35.,D1	;Check if attached
	BEQ.S	$25		;Not attached
	MOVE.W	D0,-(A7)
	MOVE.W	#35.,D0
	JSR	SIGEVENT	;Signal the event
	MOVE.W	(A7)+,D0
$25	RTS			;Nothing more to do
	
;	Poll timed out, set up schedule to check again later
$30	MOVE.B	#1,PRTTIM	;Set flag that schedule is in progress
	MOVE.L	A0,-(A7)
	LEA	PRTSCHD,A0
	CLR.W	8(A0)		;No seconds
	MOVE.W	PRTDTM,10.(A0)	;Set up delay before next poll check
	PEA	PRTPOLL
	MOVE.L	(A7)+,4(A0)	;Set up poll check address
	BSR	ESCHED		;Enter the schedule
	MOVEA.L (A7)+,A0
	RTS


;	Write to Printer Channel
WTCHAN6
	MOVEM.L D1/A1,-(A7)	;Save registers D1 & A1
	MOVEA.L 8(A0),A1	;Get memory address
	MOVE.L	4(A0),D1	;Get size
	BEQ.S	$100		;No characters requested
$10	MOVE.B	(A1)+,D0	;Get output character
	BSR	PRTOUTX		;Output character
	SUBQ.L	#1,D1		;Check size
	BNE.S	$10		;Back for more
$100	MOVEM.L (A7)+,D1/A1	;Restore registers D1 & A1
	RTS


.PAGE
;****************************************************************************
;
;	Printer output interrupt
;
;****************************************************************************

PRTINT	
	MOVE.B	#0CH,C8255+6	;Strobe the interrupt reset
	MOVE.B	#0DH,C8255+6
$10	CLR.W	D0
	MOVE.B	PRTGET,D0
	CMP.B	PRTPUT,D0	;Check if any characters
	BEQ.S	$30		;Queue is empty
	MOVE.L	A0,-(A7)	;Save an address register
	LEA	PRTBUF,A0
	MOVE.B	0(A0,D0.W),C8255 ;Output to printer port
	MOVE.B	#08H,C8255+6	;Set up strobe signal
	MOVEA.L (A7)+,A0	;Restore address register
	ADDQ.B	#1,PRTGET	;Advance Get pointer
	MOVE.B	#09H,C8255+6	;Remove strobe signal
$20	MOVE.W	(A7)+,D0	;Restore working register
	RTE

;	Turn off printer out interrupt
$30	CLR.B	PRTCMD
	MOVE.B	#0CH,C8255+6
	BSET	#5,P8259+2	;Disable interrupt
	MOVE.B	ATCHTBL+35.,D0	;Check if attached
	BEQ	$20		;Not attached
	MOVE.W	#35.,D0
	JSR	SIGEVENT	;Signal the event
	BRA	$20

.PAGE
;****************************************************************************
;
;	Printer Initialization
;
;****************************************************************************

INCHAN6
	MOVE	#2100H,SR	;Disable printer interrupts
	MOVE.B	#0CH,C8255+6	;Disable interrupt
	BSET	#5,P8259+2
	CLR.B	PRTCMD		;Clear interrupts active flag
	MOVE.B	PRTPUT,PRTGET	;Clear output buffer
	TST.B	PRTTIM		;Check if Scheduled Poll in progress
	BEQ	$10		;No scheduled poll
	MOVEM.L A0,-(A7)
	LEA	PRTSCHD,A0
	BSR	CSCHED		;Cancel the schedule
	MOVEM.L (A7)+,A0
	CLR.B	PRTTIM
$10	MOVE	#2000H,SR	;Enable interrupts
	RTS



;	Set up inhibit of LF after CR in Interpreter
PIOCONF MOVEM.L A0-A1,-(A7)
	MOVEA.L IOCONFA,A1
	MOVE.B	PRTOPT,-(A7)	;Set up option byte on stack
	CLR.W	-(A7)		;Set up type of data
	MOVEA.L A7,A0
	JSR	(A1)		;Call IOCONFIG in Interpreter
	ADDQ.L	#4,A7		;Pop the stack
	MOVEM.L (A7)+,A0-A1
	RTS



;****************************************************************************
;
;	Printer Status request
;
;****************************************************************************

STCHAN6
	CLR.W	D0
	MOVE.B	PRTPUT,D0	;Calculate number of buffered output chars
	SUB.B	PRTGET,D0
	MOVE.W	D0,(A1)
	MOVE.B	C8255+2,D0	;Get status port
	ANDI.W	#0F0H,D0	;Mask off all but printer bits
	MOVE.B	D0,50.(A1)	;Save result in status table
	RTS



;	Write printer configuration
WCFCH6
	MOVE.L	(A1)+,PRTPLC
	MOVE.W	(A1)+,PRTMODE
	BSR	PIOCONF
	BSET	#5,P8259+2	;Disable parallel interrupt on 8259
	RTS
	
	
;	Read printer configuration
RCFCH6
	MOVE.L	PRTPLC,(A1)+
	MOVE.W	PRTMODE,(A1)+
	RTS

                                                                                                                                                                                                                                                                                                                                                                                