;********************************************************
;*							*
;*	INTERRUPT SERVICE ROUTINES FOR KEYBOARD		*
;*	INPUT AND REAL-TIME CLOCK FUNCTIONS		*
;*							*
;********************************************************
;
;
;
;
KBDST:	LD	A,(FIFCNT)	;GET INPUT FIFO BYTECOUNT
	OR	A		;TEST IF EQUAL ZERO
	RET	Z		;EXIT WITH A=0 IF QUEUE IS EMPTY
	LD	A,255
	RET			;ELSE SET A=255 TO INDICATE DATA READY
;
;
;
KBDIN:	CALL	KBDST
	JR	Z,KBDIN		;LOOP UNTIL KEYBOARD INPUT READY
	PUSH	HL
	CALL	REMOVE		;GET CHARACTER FROM INPUT QUEUE
	POP	HL
	RET
;
;
;
;
;
STASH:	LD	C,A		;PUT CHARACTER IN C
	LD	A,(FIFSIZ)
	AND	00111111B
	LD	B,A		;PUT MAX FIFO SIZE IN B
	LD	HL,FIFCNT	;BUMP FIFO CHARACTER COUNT
	LD	A,(HL)
	INC	A
	CP	B
	RET	NC		;EXIT NOW IF FIFO IS FULL
	LD	(HL),A		; ELSE INCREMENT FIFO COUNT
	LD	HL,FIFIN	;POINT HL TO FIFO INPUT OFFSET
	CALL	INDEX
	LD	(HL),C		;STORE CHARACTER IN FIFO @ HL
	RET
;
;
;
;
REMOVE:	LD	HL,FIFCNT
	DEC	(HL)
	LD	HL,FIFOUT	;POINT HL TO FIFO OUTPUT OFFSET
INDEX:	LD	A,(HL)
	INC	A
	AND	00111111B	;INCREMENT FIFO POINTER
	LD	(HL),A		; MODULO 64 AND REPLACE
	LD	HL,FIFO
	ADD	A,L		;INDEX INTO FIFO BY OFFSET IN A
	LD	L,A
	LD	A,H
	ADC	A,0		;CARRY ADD OUT TO 16 BITS
	LD	H,A
	LD	A,(HL)
	RET
;
;
;
;
;
;
;	-- INTERRUPT SERVICE ROUTINE FOR PARALLEL KEYBOARD --
;
KEYSRV:	LD	(IRQSAV),SP	;SAVE USER STACK POINTER AND
	LD	SP,IRQSTK	; SWITCH TO LOCAL STACK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF		;SAVE MACHINE STATE
	IN	A,(KBD)		;READ KEYBOARD INPUT PORT
	LD	HL,(KBDVEC)
	CALL	DISPATCH
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	LD	SP,(IRQSAV)
RETI:	EI			;RE-ENABLE INTERRUPTS AND RETURN
	RETI
;
;
;
;	-- INTERRUPT SERVICE ROUTINE FOR ONE MILLISECOND TIMER --
;
MILLISEC:
	LD	(IRQSAV),SP	;SAVE USER STACK POINTER AND
	LD	SP,IRQSTK	; SWITCH TO LOCAL STACK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	LD	HL,(STPVEC)
	CALL	DISPATCH	;CALL MILLISECOND INTERRUPT ROUTINE
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	LD	SP,(IRQSAV)
	EI
	RETI
;
;
;
DISPATCH:
	JP	(HL)
;
;
;
;	-- INTERRUPT SERVICE ROUTINE FOR CLOCK TICK INTERRUPT --
;
TIMER:
	LD	(IRQSAV),SP	;SAVE USER STACK POINTER AND
	LD	SP,IRQSTK	; SWITCH TO LOCAL STACK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	LD	HL,(TICKS)
	INC	HL		;BUMP FREE RUNNING CLOCK TICK COUNTER
	LD	(TICKS),HL
	LD	HL,(TIKVEC)
	CALL	DISPATCH	;DO EXTRA CLOCK TICK ACTIVITY
	LD	HL,TIKCNT
	DEC	(HL)		;DECREMENT CLOCK TICK PRE-SCALER
	JR	NZ,TIMER2	;JUMP IF CURRENT SECOND NOT PASSED

	LD	A,(NTICKS)	;ELSE RELOAD TICK COUNT AND DO
	LD	(HL),A		; VARIOUS ONCE-A-SECOND THINGS
	CALL	CLOCK		;UPDATE TIME-OF-DAY CLOCK
	CALL	DISKTEST	;DO BACKGROUND DISK ACTIVITY MONITOR

TIMER2:	POP	AF
	POP	BC
	POP	DE
	POP	HL
	LD	SP,(IRQSAV)
	EI			;RE-ENABLE INTERRUPTS AND RETURN
	RETI
;
;
;	-- INTERRUPT SERVICE ROUTINE FOR CRTC VSYNC INTERRUPT --
;
VSYNC:	LD	(IRQSAV),SP	;SAVE USER STACK POINTER AND
	LD	SP,IRQSTK	; SWITCH TO LOCAL STACK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	LD	A,(DSCOPY)
	PUSH	AF		;SAVE D/S CONTROL BYTE ON STACK
	LD	A,DYSTAT+OFF
	OUT	(PORT0),A	;SWITCH-ON STATIC MEMORY BANK

	LD	A,(SCROLL)
	OR	A
	JR	Z,VSYNC2	;JUMP IF NO SCROLL REQUESTED THIS TIME
	LD	HL,(START)
	LD	A,12
	OUT	(CRTADD),A	;SELECT 6845 REGSITER #12
	LD	A,H
	OUT	(CRTDAT),A	;OUTPUT MSB OF START ADDRESS
	LD	A,13
	OUT	(CRTADD),A	;SELECT 6845 REGISTER #13
	LD	A,L
	OUT	(CRTDAT),A	;OUTPUT LSB OF START ADDRESS
	LD	DE,(NEWLIN)
	ADD	HL,DE		;GET RELATIVE ADDRESS OF NEW BLANK LINE
	LD	A,H
	AND	00000111B	;MAKE SURE TO ROLL-AROUND MOD 2048
	LD	H,A
	LD	BC,80
	CALL	CLRLINE		;CLEAR NEW BOTTOM LINE ON SCREN

VSYNC2:	LD	HL,(OLDCSR)	;POINT TO LAST CURSOR ATTRIBUTE BYTE
	LD	A,(HL)
	BIT	7,A		;TEST MSB (INDICATES CURSOR ACTIVE)
	JR	Z,VSYNC3	;JUMP IF CURSOR HAS BEEN WRITTEN OVER
	XOR	10010000B	;ELSE CLEAR MSB AND COMPLIMENT REVERSE
	LD	(HL),A		; VIDEO BIT TO REMOVE CURSOR
VSYNC3:	LD	HL,(CURSOR)
	LD	DE,ATTMEM
	ADD	HL,DE		;POINT TO ATTRIBUTE FOR NEW CURSOR
	LD	A,(HL)
	XOR	10010000B	;SET MSB AND COMPLIMENT REVERSE VIDEO
	LD	(HL),A		; TO CREATE NEW CURSOR ATTRIBUTE BYTE
	LD	(OLDCSR),HL	;STORE POINTER FOR NEXT CURSOR UPDATE

	LD	A,00000011B
	OUT	(CTCA3),A	;TURN OFF VSYNC INTERRUPT
	XOR	A
	LD	(SCROLL),A	;RESET SCROLL-REQUEST FLAG
	LD	(MOVECS),A	;RESET CURSOR-MOVE-REQUEST FLAG

	POP	AF		;POP MEMORY CONTROL BYTE OFF STACK
	OUT	(PORT0),A	;SWITCH BACK TO PRE-INTERRUPT CONFIG
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	LD	SP,(IRQSAV)
	EI			;RE-ENABLE INTERRUPTS AND RETURN
	RETI
;
;
;
;	POLLED MODE I/O ROUTINES FOR SIO CHANEL B
;
SIOST:	IN	A,(SIOCPB)	;GET SIO STATUS REGISTER
	AND	00000001B
	RET	Z		;ACC=0 IF NO DATA AVAILABLE
	LD	A,255
	RET
;
;
SIOIN:	CALL	SIOST		;TEST CONSOLE STATUS
	JR	Z,SIOIN		;LOOP UNTIL DATA IS
	IN	A,(SIODPB)	; READY AT SIO DATA PORT
	AND	01111111B
	RET
;
;
;
;	-- RX INTERRUPT SERVICE ROUTINE FOR SIO CONSOLE --
;

SIOINT:
	LD	(IRQSAV),SP
	LD	SP,IRQSTK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	LD	HL,SIOADR+1
	LD	C,(HL)		;LOAD C WITH SIO DATA PORT#
	IN	A,(C)
	AND	01111111B
	LD	HL,(RDAVEC)
	CALL	DISPATCH	;GO PROCESS SIO INPUT CHARACTER
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	LD	SP,(IRQSAV)
	EI
	RETI
;
;
;	-- RX ERROR INTERRUPT SERVICE ROUTINE FOR SIO CONSOLE --
;
SIOERR:
	LD	(IRQSAV),SP
	LD	SP,IRQSTK
	PUSH	AF
	PUSH	BC
	LD	A,(SIOADR)
	LD	C,A		;LOAD C WITH SIO CONTROL PORT#
	LD	A,00110000B
	OUT	(C),A		;RESET SIO EXTERNAL STATUS/INTERRUPTS
	LD	A,(SIOADR+1)
	LD	C,A		;NOW LOAD C WITH DATA PORT#
	IN	A,(C)		;INPUT AND DISCARD BAD CHARACTER
	POP	BC
	POP	AF
	EI
	RETI
;
;
;
;
;
SIOOUT:
	PUSH	BC
	PUSH	AF
	LD	A,(SIOADR)
	LD	C,A		;LOAD C WITH SIO STATUS PORT#
SIOUT1:	IN	A,(C)
	AND	00000100B	;TEST TBE STATUS BIT
	JR	Z,SIOUT1
	LD	A,(SIOADR+1)
	LD	C,A		;LOAD C WITH SIO DATA PORT# NOW
	POP	AF
	OUT	(C),A		;OUTPUT DATA TO SIO
	POP	BC
	RET
;
;
;
;
;
;
CLOCK:	LD	DE,TOD		;POINT DE TO START OF TIME-OF-DAY
	LD	HL,TODTAB	;POINT HL TO HH:MM:SS TABLE
	LD	B,4
CLOCK2:	LD	A,(DE)
	ADD	A,1		;INCREMENT TIME WITH ADD INSTRUCTION
	DAA			; SO DECIMAL ADJUST WILL WORK RIGHT
	CP	(HL)		;COMPARE IF HH/MM/SS ROLLED OVER
	JR	C,CLOCK3
	XOR	A		;RESET TO ZERO IF ROLL OVER
CLOCK3:	LD	(DE),A		;STORE UPDATED TIME DATA
	RET	C		;EXIT IF NO MORE NEEDS TO BE DONE
	INC	HL
	INC	DE		;ELSE POINT TO NEXT DATA & CONSTANT
	DJNZ	CLOCK2
CLOCK4:	RET

TODTAB:	DEFB	60H		;60 SECONDS/MINUTE
	DEFB	60H		;60 MINUTES/HOUR
	DEFB	24H		;24 HOURS/DAY
	DEFB	99H		;OVERFLOW TO DAYS
;
;
;
