;TASKER/ASM - LS-DOS 6.2 ; ; Interrupt task table, IM 1 ; CORE$ DEFL $ ORG TCB$ DW NOTASK,NOTASK,NOTASK,NOTASK DW NOTASK,NOTASK,NOTASK,NOTASK DW NOTASK,NOTASK,TYPTSK$,NOTASK ORG CORE$ ; ; Model IV task processor ; RST38@ 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 OUT (@OPREG),A INTLAT EQU 0E0H IN A,(INTLAT) ;Get interrupt latch CPL ;Mod IV is reverse LD HL,INTIM$ ;Store state of int LD (HL),A INC L ;Advance to int mask AND (HL) ;Mask the latch bits JR Z,TSTBRK ;Go if nothing interptd 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 KCK@ ;Test , JR NZ,BREAK? ;Go if break TSKEXIT POP AF ;Get previous mem config LD (OPREG$),A ; & restore to it OUT (@OPREG),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 ; ; Register restoral after service routine ; POPREGS POP IX POP HL POP DE POP BC POP AF JR NXTMSK ;Loop to next mask bit ; ; BREAK key detected ; BREAK? JR NC,GOTBRK ;Go if only PUSH BC ;Was 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,@DBGHK ;Merge DEBUG flag & OR (HL) ; hook (X'00' or X'C9') LD (HL),0C9H ;Turn off DEBUG INC HL ;Point to @DEBUG vector & JR Z,EXITBRK ; go if DEBUG is active ; LD A,(PCSAVE$+1) ;Don't allow vectored break CP MAXCOR$<-8 ; if old PC is in SYSRES JR C,TSKEXIT LD HL,HIGH$+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 ; ; Real Time Clock interrupt processor ; RTCPROC EQU $ IN A,(0ECH) ;Clear the RTC interrupt 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 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) 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 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) ;Go to task ; @KLTSK POP DE ;Remove ret LD A,(@RPTSK+1) ;Pt to task tbl entry SUB TCB$&0FFH RRCA ; of last task ; @RMTSK LD DE,NOTASK ;Remove entry ; @ADTSK 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 LD (HL),E ;Vector adr to ptr tbl INC L LD (HL),D EI RET ; 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 CHGTASK ; ; Routine to check if task slot active ; @CKTSK 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 CP (HL) ; order only RET ; Z or NZ result