;********************************************************
;*							*
;*	INTERRUPT SERVICE ROUTINES FOR KEYBOARD		*
;*	INPUT AND REAL-TIME CLOCK FUNCTIONS		*
;*				3-Aug-80		*
;*							*
;********************************************************
;
;
;
;
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	HL,LOCK		;POINT TO SHIFT LOCK VARIABLES
	CP	(HL)		;TEST IF A=SHIFT LOCK CHARACTER
	INC	HL		; THEN POINT TO LOCK FLAG
	JR	NZ,STASH2-$	;JUMP IF NOT THE SHIFT CHARACTER
	INC	(HL)		; ELSE COMPLIMENT THE SHIFT LOCK
	RET			; AND EXIT NOW

STASH2:	BIT	0,(HL)		;TEST THE SHIFT LOCK FLAG
	JR	Z,STASH3-$	;JUMP IF SHIFT LOCK NOT SET
	CP	40H		;ELSE CHECK FOR SHIFABLE CHARACTER
	JR	C,STASH3-$	; AND JUMP IF NOT EQUAL OR GREATER
	CP	7FH		; THAN '@' AND LESS THAN RUBOUT
	JR	NC,STASH3-$
	XOR	00100000B	;ELSE TOGGLE BIT 5 OF THE CHARACTER
STASH3:	LD	C,A
	LD	HL,FIFCNT	;BUMP INPUT FIFO CHARACTER COUNT
	LD	A,(HL)
	INC	A
	CP	16
	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	00001111B	;INCREMENT FIFO POINTER
	LD	(HL),A		; MODULO 16 AND REPLACE
	LD	HL,FIFO
	ADD	A,L		;INDEX INTO FIFO BY OFFSET IN A
	LD	L,A
	LD	A,(HL)
	RET
;
;
;	SOFTWARE DISK MOTOR TURN-OFF TIMER ROUTINE
;
DSKTMR:	LD	HL,MOTOR	;DECREMENT DISK TURN-OFF TIMER
	DEC	(HL)
	RET	NZ		;EXIT IF NOT TIMED OUT YET
	IN	A,(BITDAT)
	OR	01000100B	;DISABLE ALL DRIVE SELECTS AND
	OUT	(BITDAT),A	; TURN OFF THE SPINDLE MOTORS
	RET
;
;
;	-- INTERRUPT SERVICE ROUTINE FOR PARALLEL KEYBOARD --
;
KEYSRV:	LD	(SPSAVE),SP	;SAVE USER STACK POINTER AND
	LD	SP,TMPSTK+32	; SWITCH TO LOCAL STACK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF		;SAVE MACHINE STATE
	IN	A,(KBDDAT)	;READ KEYBOARD INPUT PORT
	CPL
	LD	HL,(PINVEC)	;GET KBD INTERRUPT ROUTINE VECTOR
	JR	DSPTCH-$	; AND JUMP TO DISPATCH POINT
;
;
;
;	-- INTERRUPT SERVICE ROUTINE FOR ONE SECOND TIMER --
;
TIMER:	LD	(SPSAVE),SP	;SAVE USER STACK POINTER AND
	LD	SP,TMPSTK+32	; SWITCH TO LOCAL STACK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF
	LD	HL,(TIKVEC)	;GET CLOCK INTERRUPT ROUTINE VECTOR
	JR	DSPTCH-$	; AND JUMP TO DISPATCH POINT
;
;
;
;	-- SERIAL INPUT INTERRUPT SERVICE ROUTINE FOR SIO --
;
SIOINT:	LD	(SPSAVE),SP	;SAVE USER STACK POINTER AND
	LD	SP,TMPSTK+32	; SWITCH TO LOCAL STACK
	PUSH	HL
	PUSH	DE
	PUSH	BC
	PUSH	AF		;SAVE MACHINE STATE
	IN	A,(SIODPB)	;READ SIO DATA INPUT PORT
	AND	01111111B
	LD	HL,(SINVEC)	;GET SERIAL INPUT ROUTINE VECTOR
DSPTCH:	CALL	CALLHL		;CALL SUBROUTINE ADDRESSED BY H
	POP	AF
	POP	BC
	POP	DE
	POP	HL
	LD	SP,(SPSAVE)
	EI			;RE-ENABLE INTERRUPTS AND RETURN
	RETI
;
;
;	-- RX ERROR INTERRUPT SERVICE ROUTINE FOR SIO --
;
;	ARRIVE HERE IF RECIEVE INTERRUPT FROM FRAMING, OVERRUN
;	AND PARITY ERRORS. (PARITY CAN BE DISABLED)
;
SIOERR:	LD	(SPSAVE),SP	;SAVE USER STACK POINTER AND
	LD	SP,TMPSTK+32	; SWITCH TO LOCAL STACK
	PUSH	AF
	CALL	SIOIN2		;CLEAR BAD CHARACTER FROM SIO
	LD	A,'G'-64
	CALL	SIOXMT		;OUTPUT A CTL-G AS A WARNING
	POP	AF
	LD	SP,(SPSAVE)
	EI
	RETI
;
;
CALLHL:	JP	(HL)
;
;
;
;	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 RECIEVED
SIOIN2:	LD	A,00110000B	;RESET STATUS BITS IN SIO FOR
	OUT	(SIOCPB),A	; PARITY/OVERRUN/FRAMING ERRORS,
	IN	A,(SIODPB)	; THEN GET THE INPUT CHARACTER 
	AND	01111111B
	RET
;
;
SIOOUT:	CP	' '		;TEST FOR CONTROL CHARACTERS
	JR	NC,SIOXMT-$	;JUMP IF PRINTABLE CHARACTER
	CALL	SIOXMT		; ELSE SEND CONTROL CHARACTER
	LD	A,(NULLS)	; AND THEN SEND NULLS AS PADDING
	INC	A		;GET NULL PAD COUNT AND FIX SO
	JR	PAD1-$		; THAT COUNT=0 SENDS NO NULLS

PAD:	PUSH	AF
	XOR	A
	CALL	SIOXMT		;OUTPUT A NULL TO THE SIO
	POP	AF
PAD1:	DEC	A
	JR	NZ,PAD-$	;LOOP SENDING NULLS TO SIO
	RET
;
;
SIOXMT:	PUSH	AF
SIOX1:	IN	A,(SIOCPB)
	AND	00000100B	;TEST TBE STATUS BIT
	JR	Z,SIOX1-$
	POP	AF
	OUT	(SIODPB),A	;OUTPUT DATA TO SIO
	RET
;
;
;
;
