		SUBTITLE    "< TASKER interrupt processor >"
		NEWPAGE
		scope

		ORG	zspace.TASKER$

TASKER		nop			; TASKER interrupt processor.
		nop			; IN A,(0ECh).

		LD	A,11		; Task 11 executes every tick.
		CALL	RTCTASK		; RTC interrupt
		LD	HL,TIMSL$
		RLC	(HL)		; Ck on time slice
		ret	NC		; Ignore if nothing
		LD	DE,TIMTSK$	; on this interrupt
		PUSH	DE		; else init for clocker
		LD	A,8		; Task 8 at INT/2 if fast
		CALL	RTCTASK
		LD	A,9		; Task 9 at INT/2 if fast
		CALL	RTCTASK
		LD	A,10		; Task 10 at INT/2 if fast
		CALL	RTCTASK
		LD	HL,TIMER$	; Bump the timer at INT/2
		INC	(HL)		; Beat the heart!
		LD	A,(HL)		; P/u the heart beat
		AND	7		; For this interrupt.
RTCTASK		RLCA			; consider 0-7 only
		ADD	A,TCB$&0FFh	; Add offset to table.
		LD	L,A
		LD	H,TCB$>>8
		LD	(zRPTSK+1),HL
		LD	E,(HL)		; P/u task vector addr
		INC	L
		LD	D,(HL)
		PUSH	DE
		POP	IX		; Also to IX
		EX	DE,HL
		LD	E,(HL)		; P/u task entry point
		INC	HL
		LD	D,(HL)
		EX	DE,HL
		jp	(hl)		; Transfer control to task.

zKLTSK		POP	DE		; Remove ret
		LD	A,(zRPTSK+1)	; Pt to task tbl entry
		SUB	TCB$&0FFh
		RRCA			; of last task.

zRMTSK		LD	DE,NOTASK	; Remove entry.

zADTSK		CP	12		; Too large a task?
		RET	NC		; Ret if too big else.
		RLCA			; add to task table
		ADD	A,TCB$&0FFh	; Add the offset
		LD	L,A		; Estab ptr to vector
		LD	H,TCB$>>8
CHGTASK		di			; Originally DI.
		LD	(HL),E		; Vector adr to ptr tbl.
		INC	L
		LD	(HL),D
		ei			; Marker holding EI originally.
		ret
NOTASK		DW	$-1		; Current task vector

zRPTSK		; P/u last task done.

		LD	HL,0
		LD	E,(HL)		; P/u task vector addr
		INC	HL
		LD	D,(HL)
		EX	DE,HL
		POP	DE		;Pop ret addr
		JR	CHGTASK

zCKTSK		; Routine to check if task slot active.

		RLCA			;Task number * 2
		ADD	A,TCB$&0FFh+1	;Index into task table
		LD	L,A
		LD	H,TCB$>>8
		LD	A,NOTASK>>8	;Check match of high order only.
		CP	(HL)
		RET			; Z or NZ result.