			SUBTITLE    "< Maskable interrupt routines & interrupt handler dispatch >"
			NEWPAGE
			scope

; Maskable interrupt has happened, we land here rst38.s.
; Save PC for TRACE routine. TRACE will point where execution was happening when interrupt occured.
; Save flags & return address.
; Mark system NETWORK flag as being in tasker/interupt response.
; Recover hardware MEMORY configuration & save so it can later be restored.
; Switch hardware to standard 64k configuration.
; Recover interrupt latch & strip out bits not enabled.
; Execute handlers for devices enabled in MASK & hardware is interrupting.
; Loop & test all 8 slots.
; Test BREAK.
; Restore memory.
; Mark NETWORK flags we are no longer in tasker.
; Restore registers.
; Enable maskable interrupts.
; Return from interrupt.

		ORG	zspace.RST38$

RST38z		equ	$
		EX	(SP),HL
		LD	(PCSAVE$),HL		; Save for TRACE
		EX	(SP),HL
		PUSH	HL			; Save HL for now
		PUSH	AF			; Save AF for now
		LD	HL,NFLAG$		; Show the system we
		SET	6,(HL)			; are in the TASKER
		LD	HL,LBANK$		; P/U & save the current
		LD	A,(HL)			; logical bank #
		LD	(HL),0
		PUSH	AF
		LD	HL,OPREG$		; Get current memory
		LD	A,(HL)
		PUSH	AF			; config & save
		AND	8Ch			; Strip bits 0, 1, 4-6
		OR	3			; Bring up regular 64K
		LD	(HL),A
		nop
		nop			; 	OUT	(084H),A
		ld	a,00h		;	IN	A,(INTLAT)
		cpl				; After CPL A is 0.
		ld	hl,INTIM$		; Address of interrupt latch. 
		LD	a,(hl)			; Get who doin dis interrupin?
		INC	L			; Advance to int mask
		AND	(HL)			; Mask the latch bits
		JR	Z,TSTBRK		; Go if nothing interrupted.
NXTVCT		INC	L			; Ck on INTVC$.
		RRA				; Ck if device interrupted.
		JR	C,ACTVTSK
NXTMSK		INC	L			; Ck all 8 bits of mask.
		OR	A			; When fin, ck overhead
		JR	NZ,NXTVCT		; task routine.

TSTBRK		CALL	KCKz			; Test <BREAK>, <SHIFT>
		JR	NZ,BREAKz		; Go if break
TSKEXIT		POP	AF			; Get previous mem config
		LD	(OPREG$),A		; & restore to it.
		nop
		nop;	OUT	(084H),A	
		POP	AF
		LD	(LBANK$),A
		LD	HL,NFLAG$		; Now leaving the TASKER
		RES	6,(HL)			; show the system.			
		POP	AF			; Restore previous regs
		POP	HL
		ei
RETINST		ret

;		Found active INTVC$


ACTVTSK		PUSH	AF			; Save the regs
		PUSH	BC
		PUSH	DE
		PUSH	HL
		PUSH	IX
		LD	DE,POPREGS		; Stack return vector
		PUSH	DE
		LD	E,(HL)			; P/u INTVC pointer vector
		INC	L
		LD	D,(HL)
		EX	DE,HL			; Shift it to HL
		JP	(HL)			; Go to service routine

; Restore registers after service routine & loop to check next slot.

POPREGS		POP	IX
		POP	HL
		POP	DE
		POP	BC
		POP	AF
		JR	NXTMSK			; Loop to next mask bit

; BREAK key detected

BREAKz		JR	NC,GOTBRK		; Go if <BREAK> only
		PUSH	BC			; Was <SHIFT-BREAK>
		DI
		CALL	TAPDRV			; Reselect drive
		POP	BC
		JR	TSKEXIT

; BREAK during tasking - enter DEBUG? - user BREAK?

GOTBRK		LD	A,(SFLAG$)		; Check if BREAK key is
		AND	10h			; disabled to inhibit
		JR	NZ,TSKEXIT		; DEBUG or BREAK vector
		LD	HL,zDBGHK		; Merge DEBUG flag &
		OR	(HL)			; hook (X"00' or X"C9')
		LD	(HL),0C9h		; Turn off DEBUG
		INC	HL			; Point to zDEBUG vector &
		JR	Z,EXITBRK		; go if DEBUG is active
		LD	A,(PCSAVE$+1)		; Don"t allow vectored break
		CP	COREMAX$>>8		; if old PC is in SYSRES
		JR	C,TSKEXIT
		LD	HL,PHIGH$+1		; or if old PC is
		CP	(HL)			; above HIGH$
		JR	NC,TSKEXIT
		LD	HL,0			; else ck if BREAK is
BRKVEC$		EQU	$-2
		LD	A,H			; to be trapped by user
		OR	L
		JR	Z,TSKEXIT
EXITBRK		POP	AF			; Discard old mem config
		POP	AF			; Restore reg AF
		POP	AF
		EX	(SP),HL			; P/u HL & stack vector.
		EI
		ret				; To DEBUG or BREAK vector.