;TASKER2/ASM - LDOS 6.2, Model II - 11/09/83
;
;	revised 09/26/83 for Mod II	- kjw
;
;*=*=*
;	interrupt task table
;*=*=*
CORE$	DEFL	$
	ORG	TCB$
	DW	NOTASK,NOTASK,NOTASK,NOTASK
	DW	NOTASK,NOTASK,NOTASK,NOTASK
	DW	NOTASK,NOTASK,NOTASK,NOTASK
	ORG	CORE$
;*=*=*
;	Model II task processor
;*=*=*
NMISERV	EX	(SP),HL		;get PC for trace
	LD	(PCADDR),HL	;save it
	EX	(SP),HL		;reset stack
	PUSH	AF		;save all
	IN	A,($RDINT)	;clear interrupt
	PUSH	BC
	PUSH	DE
	PUSH	HL
	PUSH	IX
	LD	HL,NFLAG$	;sys flag
	SET	6,(HL)		;flag as in interrupt
	CALL	UPDTIME		;update time
	LD	A,R		;read refresh register
	JP	PO,NMIABT	;go if interrupts off!
	LD	A,(LCKFLG$)	;lockout flag
	AND	11000000B	;can execute task?
	CALL	Z,0038H		;execute if yes
NMIABT	LD	HL,TIMEOUT	;motor on time out delay
	LD	A,(HL)		;get byte
	OR	A		;any delay?
	JR	Z,NMISERX	;nope, exit
	DEC	(HL)		;less counter
	JR	NZ,NMISERX	;go if not time
	LD	A,4FH		;select code
	OUT	($FDCSEL),A	;de-select drives
NMISERX	POP	IX		;unstack 'em
	LD	HL,NFLAG$	;system flag
	RES	6,(HL)		;clear int bit
	POP	HL
	POP	DE
	POP	BC
	POP	AF		;restore stack
	RETN			;return from interrupt
;
;	actual RST38 interrupt tasker
;
RST38@	LD	HL,LBANK$	;current memory bank
	LD	A,(HL)		;get data
	PUSH	AF		;save on stack
	LD	(HL),0		;flag as in bank 0
	LD	A,(MODOUT$)	;get memory image
	PUSH	AF		;save for restore
	AND	01110000B	;no video
	OR	1		;set bank 0
	CALL	SET_MOD		;update mask/port
	CALL	RTCPROC		;real time processor
	POP	AF		;restore data
	CALL	SET_MOD		;update memory
	POP	AF		;restore original bank
	LD	(LBANK$),A	;update
	RET			;done
;*=*=*
;	Real Time Clock interrupt processor
;*=*=*
RTCPROC	EQU	$
	LD	A,11		;Task 11 executes every
	CALL	RTCTASK		;  RTC interrupt
	LD	HL,TIMSL$
	RLC	(HL)		;Ck on time slice
	RET	NC		;Ignore if nothing
	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)		;  else bump TIMER$
	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	(@RPTSK+1),HL
	LD	E,(HL)		;P/u task vector addr
	INC	HL
	LD	D,(HL)
	PUSH	DE
	POP	IX		;Also to IX
	LD	L,(IX+0)	;get lsb vector
	LD	H,(IX+1)	;get msb vector
	JP	(HL)		;Go to task
;
@KLTSK	POP	DE		;Remove ret
	LD	A,(@RPTSK+1)	;Pt to task tbl entry
	SUB	TCB$&0FFH	;remove offset
	RRCA			;  of last task
	LD	DE,NOTASK	;remove entry
	JR	$CHTASK		;check and remove
@RMTSK	LD	DE,NOTASK	;remove entry
@ADTSK	CALL	NMIOFF		;disable NMI
	CALL	$CHTASK		;check and change
	JP	NMION		;RTC back on!
;
;	check and install new vector in table
;
$CHTASK	CP	12		;too large?
	JR	C,CHTASK1	;go if OK
	LD	A,40		;'protected sys device'
	OR	A		;set NZ for error
	RET			;return NZ
CHTASK1	ADD	A,A		;double for table
	ADD	A,TCB$&0FFH	;add lsb offset
	LD	L,A		;pass to L
	LD	H,TCB$<-8	;msb table
	LD	(HL),E		;load lsb vector
	INC	HL		;bump table
	LD	(HL),D		;load msb vector
	RET			;done
;
NOTASK	DW	$-1		;Current task vector
@RPTSK	LD	HL,0		;P/u last task done
	LD	E,(HL)		;P/u task vector addr
	INC	HL
	LD	D,(HL)
	EX	DE,HL
	POP	DE		;Pop ret addr
	JR	$CHTASK		;install
;*=*=*
;	Routine to check if task slot active
;*=*=*
@CKTSK	RLCA
	ADD	A,TCB$&0FFH+1
	LD	L,A
	LD	H,TCB$<-8
	LD	A,NOTASK<-8	;Check match of high
	CP	(HL)		;  order only
	RET
;
