
	TITLE	"BIOS.IRQ   HT68K BIOS:  INTERRUPT HANDLERS"
	PAGE
************** 1770 FLOPPY CONTROLLER INTERRUPT *********************
FLOPPY
	MOVEM.L	#0FFFFH,AV4REG	;SAVE REGISTERS
	TST.B	STATREG		;CLEAR INTERRUPT
	RTE			;RESUME USER
********************* 68681 DUART INTERRUPT *************************
DUART
	MOVEM.L	#0FFFFH,AV3REG	;SAVE REGISTERS
	LEA	BIOS_DATA,A6
	BTST.B	#7,ISRREG	;IF INPUT_PORT_CHANGE
	BEQ.S	DUAR10
	TST.B	IPCRREG		;  THEN CLEAR INTERRUPT
DUAR10	BTST.B	#6,ISRREG	;IF DELTA_BREAK_B
	BEQ.S	DUAR20
	MOVE.B	#RESETBR,CRBREG	;  THEN RESET BREAK B
DUAR20	BTST.B	#0,SRBREG	;IF RXRDYB
	BEQ.S	DUAR30
	LEA	RBBREG,A0
	LEA	AUXIN(A6),A1
DUAR25	BSR	RXCHAR		;  REPEAT RECEIVE CHAR
;=====	BTST.B	#0,SRBREG	;  UNTIL FIFO EMPTY
;=====	BNE.S	DUAR25
;=====	BTST.B	#4,SRBREG	;  IF OVERRUN ERROR B
;=====	BEQ.S	DUAR30
;=====	MOVE.B	#RESETER,CRBREG	;    THEN RESET ERROR B
DUAR30	BTST.B	#2,SRBREG	;IF TXRDYB
	BEQ.S	DUAR40
	LEA	TBBREG,A0
	LEA	AUXOUT(A6),A1
	BSR	TXCHAR		;  TRANSMIT CHAR
	TST.W	SIZE(A1)	;  IF QUEUE = NIL
	BNE.S	DUAR40
	MOVEQ	#TXBBIT,D0	;    THEN MASK TXRDYB
	NOT.B	D0
	AND.B	D0,MASK681(A6)
	MOVE.B	MASK681(A6),IMRREG
DUAR40	BTST.B	#3,ISRREG	;IF TIMER_READY
	BEQ.S	DUAR50
	TST.B	STOPREG		;  CLEAR TIMER INTERRUPT
	BSR	CLOCK		;  UPDATE CLOCK
DUAR50	BTST.B	#2,ISRREG	;IF DELTA_BREAK_A
	BEQ.S	DUAR60
	MOVE.B	#RESETBR,CRAREG	;  THEN RESET BREAK A
DUAR60	BTST.B	#0,SRAREG	;IF RXRDYA
	BEQ.S	DUAR70
	LEA	RBAREG,A0
	LEA	CONIN(A6),A1
DUAR65	BSR	RXCHAR		;  REPEAT RECEIVE CHAR
;=====	BTST.B	#0,SRAREG	;  UNTIL FIFO EMPTY
;=====	BNE.S	DUAR65
;=====	BTST.B	#4,SRAREG	;  IF OVERRUN ERROR A
;=====	BEQ.S	DUAR70
;=====	MOVE.B	#RESETER,CRAREG	;    THEN RESET ERROR A
DUAR70	BTST.B	#2,SRAREG	;IF TXRDYA
	BEQ.S	DUAR80
	LEA	TBAREG,A0
	LEA	CONOUT(A6),A1
	BSR	TXCHAR		;  TRANSMIT CHAR
	TST.W	SIZE(A1)	;  IF QUEUE = NIL
	BNE.S	DUAR80
	MOVEQ	#TXABIT,D0	;    THEN MASK TXRDYA
	NOT.B	D0
	AND.B	D0,MASK681(A6)
	MOVE.B	MASK681(A6),IMRREG
DUAR80	MOVEM.L	AV3REG,#0FFFFH
	RTE			;RESUME USER
;------------------------------- INPUT ONE CHARACTER FROM SERIAL PORT
RXCHAR
;=====	TST.B	SIZE(A1)	;IF QUEUE IF FULL (SIZE>=256)
;=====	BEQ.S	RXCH10
;=====	SUBQ.W	#1,SIZE(A1)	;  THEN THROW AWAY OLDEST CHAR
;=====	ADDQ.B	#1,TAIL(A1)
RXCH10	MOVE.B	(A0),D0		;REMOVE CHAR FROM RX BUFFER
	MOVEQ	#0,D1		;PUT CHAR IN QUEUE
	MOVE.B	HEAD(A1),D1
	MOVE.B	D0,QUEUE(A1,D1)
	ADDQ.W	#1,SIZE(A1)	;UPDATE QUEUE
	ADDQ.B	#1,HEAD(A1)
	RTS
;------------------------------- OUTPUT ONE CHARACTER TO SERIAL PORT
TXCHAR
	TST.W	SIZE(A1)	;IF QUEUE EMPTY
	BNE.S	TXCH10
;=====	MOVE.B	#DEL,(A0)	;THEN SEND DEL TO CLEAR IRQ
	RTS			;ELSE
TXCH10	MOVEQ	#0,D1		;REMOVE CHARACTER FROM QUEUE
	MOVE.B	TAIL(A1),D1
	MOVE.B	QUEUE(A1,D1),D0
	SUBQ.W	#1,SIZE(A1)	;UPDATE QUEUE
	ADDQ.B	#1,TAIL(A1)
	MOVE.B	D0,(A0)		;PUT CHAR IN TX BUFFER
	RTS
********************** PRINTER INTERRUPT ****************************
PRINTER
	MOVEM.L	#0FFFFH,AV2REG	;SAVE REGISTERS
	LEA	BIOS_DATA,A6
	TST.B	STB1REG		;RESET ACK LINE, SET /STROBE
	ST	PRNACK(A6)	;SET ACK FLAG
	LEA	PRNOUT(A6),A1	;IF QUEUE NOT EMPTY
	TST.W	SIZE(A1)
	BEQ.S	PRN80
	BSR	PRNCHAR		;  THEN SEND ANOTHER CHAR
PRN80	MOVEM.L	AV2REG,#0FFFFH
	RTE			;RESUME USER
;------------------------------- OUTPUT ONE CHARACTER ON PRINTER PORT
PRNCHAR
	LEA	PRNOUT+VARS,A1
	MOVEQ	#0,D1		;REMOVE CHARACTER FROM QUEUE
	MOVE.B	TAIL(A1),D1
	MOVE.B	QUEUE(A1,D1),D0
	SUBQ.B	#1,SIZE(A1)	;UPDATE QUEUE
	ADDQ.B	#1,TAIL(A1)
	SF	PRNACK+VARS	;RESET ACKNOWLEDGE FLAG
	MOVE.B	D0,STB1REG	;OUTPUT DATA
	MOVE.B	D0,STB0REG	;/STROBE GOES ACTIVE
	RTS
********************* NON-MASKABLE INTERRUPT ***********************
NMI	MOVE.W	#31,MISCVEC	;SAVE VECTOR NUMBER
	MOVEM.L	#0FFFFH,MISCREG	;SAVE ALL REGISTGERS
	MOVEA.L	USP,A0
	MOVE.L	A0,MISCUSP	;SAVE USP
	CLR.W	MISCFUN
	CLR.L	MISCACC
	CLR.W	MISCIR
	CMPI.W	#3,MISCVEC
	BHI.S	SHORT		;IF GROUP ZERO
	MOVE.W	(SP)+,MISCFUN	;  POP FUNCTION CODE
	MOVE.L	(SP)+,MISCACC	;  POP ACCESS ADDRESS
	MOVE.W	(SP)+,MISCIR	;  POP INSTRUCTION REGISTER
SHORT	MOVE.W	(SP)+,MISCSR	;POP STATUS REGISTER
	MOVE.L	(SP)+,MISCPC	;POP PROGRAM COUNTER
	MOVEA.L	SP,A0
	LEA	MISCSTK,A1	;SAVE SOME OF THE SUPERVISOR STACK
	MOVE.L	(A0)+,(A1)+
	MOVE.L	(A0)+,(A1)+
	MOVE.L	(A0)+,(A1)+
	LEA	0,A0		;COPY VAR SPACE TO HIGH MEMORY
	LEA	NMISAVE,A1
	MOVE.W	#BIOS_STACK,D0
NMICOPY	MOVE.L	(A0)+,(A1)+	;COPY VAR SPACE TO HIGH MEMORY
	DBRA	D0,NMICOPY
	MOVE.W	#SUPERSR,SR	;RE-ENABLE INTERRUPTS
	JMP	MONITOR		;ENTER MONITOR
********************* ALL OTHER INTERRUPTS *************************
V02	MOVE.W	#02,-(SP)
	BRA	MISC
V03	MOVE.W	#03,-(SP)
	BRA	MISC
V04	MOVE.W	#04,-(SP)
	BRA	MISC
V05	MOVE.W	#05,-(SP)
	BRA	MISC
V06	MOVE.W	#06,-(SP)
	BRA	MISC
V07	MOVE.W	#07,-(SP)
	BRA	MISC
V08	MOVE.W	#08,-(SP)
	BRA	MISC
V09	MOVE.W	#09,-(SP)
	BRA	MISC
V10	MOVE.W	#10,-(SP)
	BRA	MISC
V11	MOVE.W	#11,-(SP)
	BRA	MISC
V12	MOVE.W	#12,-(SP)
	BRA	MISC
V13	MOVE.W	#13,-(SP)
	BRA	MISC
V14	MOVE.W	#14,-(SP)
	BRA	MISC
V15	MOVE.W	#15,-(SP)
	BRA	MISC
V16	MOVE.W	#16,-(SP)
	BRA	MISC
V17	MOVE.W	#17,-(SP)
	BRA	MISC
V18	MOVE.W	#18,-(SP)
	BRA	MISC
V19	MOVE.W	#19,-(SP)
	BRA	MISC
V20	MOVE.W	#20,-(SP)
	BRA	MISC
V21	MOVE.W	#21,-(SP)
	BRA	MISC
V22	MOVE.W	#22,-(SP)
	BRA	MISC
V23	MOVE.W	#23,-(SP)
	BRA	MISC
V24	MOVE.W	#24,-(SP)
	BRA	MISC
V25	MOVE.W	#25,-(SP)
	BRA	MISC
V26	MOVE.W	#26,-(SP)
	BRA	MISC
V27	MOVE.W	#27,-(SP)
	BRA	MISC
V28	MOVE.W	#28,-(SP)
	BRA	MISC
V29	MOVE.W	#29,-(SP)
	BRA	MISC
V30	MOVE.W	#30,-(SP)
	BRA	MISC
V31	MOVE.W	#31,-(SP)
	BRA	MISC
V32	MOVE.W	#32,-(SP)
	BRA	MISC
V33	MOVE.W	#33,-(SP)
	BRA	MISC
V34	MOVE.W	#34,-(SP)
	BRA	MISC
V35	MOVE.W	#35,-(SP)
	BRA	MISC
V36	MOVE.W	#36,-(SP)
	BRA	MISC
V37	MOVE.W	#37,-(SP)
	BRA	MISC
V38	MOVE.W	#38,-(SP)
	BRA	MISC
V39	MOVE.W	#39,-(SP)
	BRA	MISC
V40	MOVE.W	#40,-(SP)
	BRA	MISC
V41	MOVE.W	#41,-(SP)
	BRA	MISC
V42	MOVE.W	#42,-(SP)
	BRA	MISC
V43	MOVE.W	#43,-(SP)
	BRA	MISC
V44	MOVE.W	#44,-(SP)
	BRA	MISC
V45	MOVE.W	#45,-(SP)
	BRA	MISC
V46	MOVE.W	#46,-(SP)
	BRA	MISC
V47	MOVE.W	#47,-(SP)
	BRA	MISC
V48	MOVE.W	#48,-(SP)
	BRA	MISC
MISC	MOVE.W	(SP)+,MISCVEC	;SAVE VECTOR NUMBER
	MOVEM.L	#0FFFFH,MISCREG	;SAVE ALL REGISTGERS
	MOVEA.L	USP,A0
	MOVE.L	A0,MISCUSP	;SAVE USP
	CLR.W	MISCFUN
	CLR.L	MISCACC
	CLR.W	MISCIR
	CMPI.W	#3,MISCVEC
	BHI.S	GROUP12		;IF GROUP ZERO
	MOVE.W	(SP)+,MISCFUN	;  POP FUNCTION CODE
	MOVE.L	(SP)+,MISCACC	;  POP ACCESS ADDRESS
	MOVE.W	(SP)+,MISCIR	;  POP INSTRUCTION REGISTER
GROUP12	MOVE.W	(SP)+,MISCSR	;POP STATUS REGISTER
	MOVE.L	(SP)+,MISCPC	;POP PROGRAM COUNTER
	MOVEA.L	SP,A0
	LEA	MISCSTK,A1	;SAVE SOME OF THE SUPERVISOR STACK
	MOVE.L	(A0)+,(A1)+
	MOVE.L	(A0)+,(A1)+
	MOVE.L	(A0)+,(A1)+
	TST.L	EXPC		;IF ALTERNATE HANDLER DEFINED THEN
	BEQ	COLDSTART
	LEA	MISCREG,A0	;  COPY REGISTERS TO INFO SPACE
	MOVEA.L	EXINFO,A1
	MOVEQ	#15,D0
COPINFO	MOVE.L	(A0)+,(A1)+
	DBRA	D0,COPINFO
	BTST.B	#5,MISCSR	;  IF USER STATE
	BNE.S	SUPER
	SUBQ.L	#4,A1
	MOVE.L	MISCUSP,(A1)+	;    COPY USP OVER SSP
SUPER	MOVE.W	MISCVEC,(A1)+	;  COPY VECTOR
	MOVE.W	MISCSR,(A1)+	;  COPY STATUS REGISTER
	MOVE.L	MISCPC,(A1)+	;  COPY PROGRAM COUNTER
	CMPI.W	#3,MISCVEC	;  IF GROUP 0  (BUS or ADDRESS ERROR)
	BHI.S	GROUP21
	MOVE.W	MISCFUN,(A1)+	;    COPY FUNCTION CODE
	MOVE.L	MISCACC,(A1)+	;    COPY ACCESS ADDRESS
	MOVE.W	MISCIR,(A1)+	;    COPY INSTRUCTION REGISTER
GROUP21	MOVEM.L	EXREG,#0FFFFH	;  LOAD EXCEPTION HANDLER STATE
	MOVE.L	EXPC,-(SP)
	MOVE.W	EXSR,SR
	RTS			;  GO TO ALTERNATIVE HANDLER
COLDSTART			;ELSE
	MOVE.W	SUPERSR,SR
	LEA	BIOS_DATA,A6
	LEA	ERRMES,A0
	BSR	WRITESTR	;  WRITE ERROR MESSAGE TO CONSOLE
	MOVE.W	MISCVEC,D0	;  VECTOR = MINIMUM( VECTOR, 48 )
	CMPI.W	#48,D0
	BLS.S	VALIDVEC
	MOVEQ	#48,D0
VALIDVEC
	LEA	MISCMES,A0	;  POINT TO PACKED ARRAY OF STRINGS
	SUBQ.W	#3,D0
	BLT.S	FOUNDSTR	;  FOR VECTOR TIMES
FINDSTR	TST.B	(A0)+		;    POINT TO NEXT STRING
	BNE.S	FINDSTR
	DBRA	D0,FINDSTR
FOUNDSTR
	BSR	WRITESTR	;  WRITE VECTOR INDENTIFIER STRING
	LEA	CRLFMES,A0
	BSR	WRITESTR
	JMP	MONITOR		;ENTER MONITOR
;------------------------------- WRITE A STRING TO THE CONSOLE
WRITESTR
WSTR10	MOVE.B	(A0)+,D0	;WHILE NOT END OF STRING
	BEQ.S	WSTR20
	MOVE.L	D0,-(A4)
	BSR	PUTCON		;  PUT CHAR (MODIFIED:A4,A2,A1,D1,D0)
	BRA.S	WSTR10		;ENDWHILE
WSTR20	RTS

	END	;BIOS.IRQ
