 lib environment
 sttl System Interrupt Handlers
 pag
 name inthan.system
 global swihan,timout,nmihan,swi2han,clkint

*
* clkint
*
* Process a clock interrupt
*

clkint ldy tmhead any timeouts?
 beq clkto6
 dec tmtime,y dec the time count
 bne clkto6 did it timeout?
 bra clkto4 yes it did!
clkto2 ldy tmhead any more timeouts here?
 beq clkto6
 tst tmtime,y check for 0 time left
 bne clkto6
clkto4 ldd tmlink,y get forward link
 std tmhead make new list head
 ldx tmlst point to last entry
 bne clkt45 is it null?
 sty tmlst set new last
 sty tmavl set new first too
 bra clkt47
clkt45 sty tmlink,x set new link
 sty tmlst set last entry ptr
clkt47 ldd #0 set null link
 std tmlink,y save it
clkto5 ldx tmparm,y get parameter
 jsr [tmrout,y] execute routine
 bra clkto2
clkto6 tst kernal in kernal?
 bne clkin2 if != 0, in kernal
 lda uprfsc+1 check if profiling?
 beq clkin1 if 0, no profile
 jsr doprof do profile
clkin1 ldd utimu+1 get user time
 addd #1 bump by one tick
 std utimu+1 save new value
 bne clkin3 overflow?
 inc utimu bump m.s.b.
 bra clkin3
clkin2 ldd utims+1 get system time
 addd #1 bump by one tick
 std utims+1 save new value
 bne clkin3 overflow?
 inc utims bump msb
clkin3 inc lbolt bump lbolt timer
 ldb lbolt get value
 cmpb #10 one second yet?
 bhs clkin4
 ldx utask get task pointer
 cmpx tsktab task 0 ?
 beq clki35
 inc restim bump residence time
 lda restim get the res time
 cmpa #RESTM over limit?
 bls clki35
 inc chproc if so, change tasks
 inc tsact,x bump activity counter
 bne clki33 overflow?
 dec tsact,x yes, so fix it
clki33 jmp fixpri fix priority
clki35 rts return


 pag
*
* Process one second interval stuff
*

clkin4 clr lbolt clear out lbolt
 tst stlm time limit active?
 beq clki45
 ldd utims calculate total course time
 addd utimu (ignore low 8 bits ... 25.6 seconds)
 tsta too hi?
 bne clki43
 cmpb stlm time limit?
 blo clki45
clki43 ldx utask point to task entry
 ldd tsuid,x check if super user
 beq clki45
 ldd #TIMES set interrupt
 jsr xmtint transmit the interrupt
clki45 ldd stiml get system time clock
 addd #1 bump by one second
 std stiml save new
 bne clkin6 overflow?
 ldd stimh get hi part of time
 addd #1 bump by one
 std stimh save new
clkin6 ldx tsktab point to tasks
 leax TSKSIZ,x skip system task
clki65 ldd tsalrm,x get alarm counter
 beq clkin7 is it active?
 subd #1 if so, dec it by 1 second
 std tsalrm,x save new count
 bne clkin7 did it hit 0?
 pshs x
 ldd #ALARMS set alarm interrupt
 jsr xmtint send the interrupt
 puls x reset task pointer
clkin7 leax TSKSIZ,x bump to next task entry
 cmpx tskend end of list?
 bne clki65
 ldb stiml+1 get low byte of time
 andb #3 4 seconds yet?
 bne clkin8
* tst tmtuct check for update time
* beq clki75
* dec tmtuct dec the count
* bne clki75 zero yet?
* lda stup reset counter
* sta tmtuct
* inc tmtupf set update flag for scheduler
* tst rdytci swapper sleeping?
* beq clki75
* ldy #rdytci point to event
* clr 0,y reset flag
* jsr wakeup wakeup swapper
clki75 ldy #lbolt if so, its time to
 jsr wakeup wakeup lbolt
 ldx tsktab point to task table
 leax TSKSIZ,x skip system task
clki74 tst tsstat,x look for active tasks
 beq clki76
 inc tsage,x bump the age byte
 bne clki76 overflow?
 dec tsage,x fix it
clki76 leax TSKSIZ,x bump to next task entry
 cmpx tskend end of list?
 bne clki74
clkin8 tst rdytgo swapper waiting?
 beq clki82
 ldy #rdytgo point to event
 clr 0,y zero flag
 jsr wakeup wakeup swapper
clki82 tst kernal were we in user mode?
 bne clki85 if not, go ahead
 jsr tstint test for an interrupt
 beq clkin9
 jsr doint process the interrupt
clki85 ldx utask point to task
 cmpx tsktab system task?
 beq clkin9
 jsr fixpri fix up his priority
 stb jobpri set current priority
clkin9 rts return from clock

 pag
*
* swihan
*
* Handle an swi type interrupt.  This is treated
* as an EMT type trap.  An EMT signal is generated.
*

swihan ldd #EMTS setup type
swiha2 ldx utask get task entry
 jsr xmtint transmit interrupt
 jsr tstint check for interrupt
 beq swiha4
 jsr doint process interrupt
swiha4 ldx utask point to task
 jsr fixpri update priorities
 stb jobpri set the current mode
 rts return


*
* nmi handler
*

nmihan clra
 ldx utask get task entry
 jsr xmtint send int
 jsr tstint test for int
 beq nmiha2
 jsr doint do interrupt
nmiha2 rts return

*
* swi2 handler
*

swi2han ldd #EMT2S set int
 bra swiha2

*
* timout
*
* Do an interrupt timeout.  X has the passed
* parameter, Y has the routine address to be called,
* and b has the time in 10ths of seconds.
*

timout pshs b,x,u save stuff
 pshs cc save condition codes
 seti mask interrupts
 ldu tmavl get a timeout slot
 beq timou6 it better never be null !!!!
 ldd 2,s get parameter
 std tmparm,u save in slot
 sty tmrout,u save routine address
 ldd tmlink,u get link to next slot
 std tmavl save as new list head
 bne timou2 is it null?
 std tmlst set tail to null
timou2 ldb 1,s get count
 ldy #tmhead point to head of list
timou3 ldx tmlink,y follow links
 beq timou4 end of the line?
 cmpb tmtime,x check times
 blo timou4 if lower, we go here!
 subb tmtime,x remove time bias
 leay 0,x update past pointer
 bra timou3 repeat
timou4 stb tmtime,u save this guys time
 stu tmlink,y set forward link
 stx tmlink,u this one too
 beq timou6 end of a list?
 ldb tmtime,x get next guys time
 subb tmtime,u remove the added bias
 stb tmtime,x save result
timou6 puls cc reset status
 puls b,x,u,pc return
