 sttl Scheduler routines
 pag

*
* All routines in this file pertain to scheduling
* operations.
*

*
* change & rsched
*
* Change will change tasks.  The current task is put
* back on the linked list of running tasks.
* Rsched will reschedule the cpu giving control to
* another ready task.  If no tasks are ready, idle
* looping is done until one becomes ready.  Rsched
* does not put the current task back on the ready list!
* This routine returns one to the caller.  All registers
* are destroyed.
*

change ldx utask point to task table entry
 bsr putrun put on ready list
*
rsched seti mask interrupts
 ldx utask point to current task
 sts umark0,x save stack pointers
 ldx #tsktab point to task table
 bsr swtchu switch users
 clr idle reset idle/running flag
rsche2 clr chproc reset change flag
 bsr getjob get a new task
 bne rsche3 find one?
 if DEBUG&DBG_TASK
 tst idle any changes?
 bne 00f no - don't print
 jsr prt_tasks
00 lda #1 set idle switch
 sta idle
 endif
 lda #127 set higheset priority
 sta jobpri set as current
 clri clear interrupts
* idle work could go on here
 ldy #SWITCH2 Turn on LED #2
 ldu 0,y -- One flicker for each access
 ldu 0,y
 ldu 0,y
 ldu 0,y
 seti
 bra rsche2 loop til find a ready one
rsche3 stb jobpri set new priority
 bsr swtchu switch users top page
 ldx utask point to task
 ldd #1 return 1 to new task
 rts return

*
* Switch users
*   X - Task entry for new task
*
swtchu puls y get return address
 stx utask set up new running task
 lds umark0,x reset stack
 if DEBUG&DBG_SYS
 pshs d,x,y
 ldx #00f
 jsr DB_pdata
 ldd utask
 jsr DB_phex2
 ldx #01f
 jsr DB_pdata
 leax 6,s
 tfr x,d
 jsr DB_phex2
 ldx #02f
 jsr DB_pdata
 ldd 6,s
 jsr DB_phex2
 puls d,x,y
 endif
 jmp 0,y return to caller
 if DEBUG&DBG_SYS
*
00 fcc $d,'SWTCHU, Task = $',0
01 fcc ', (S) = $',0
02 fcc ', PC = $',0
 endif

 if DEBUG&DBG_TASK
*
* prt_tasks - Print task tables
*
prt_tasks pshs d,x,y,u
 ldx #00f
 jsr DB_pdata
 ldy #tsktab
 jsr DB_pcrlf
10 lda tsstat,y only print non-free tasks
 cmpa #TFREE
 beq 20f
 tfr y,d
 jsr DB_phex2
 ldx #01f
 jsr DB_pdata
 ldd tsstat,y
 jsr DB_phex2
 ldx #01f
 jsr DB_pdata
 ldu umark0,y
 lda tsstat,y task sleeping?
 cmpa #TSLEEP
 bne 12f no
 ldd 0+7,u PC - in sleep
 bra 15f
12 ldd 0,u PC - from interrupt
15 jsr DB_phex2
 jsr DB_outsp
 ldd tsevnt,y
 jsr DB_phex2 event
 jsr DB_outsp
 jsr DB_pcrlf
20 leay TSKSIZ,y
 cmpy #end_vars
 bne 10b
99 puls d,x,y,u,pc
00 fcc $d,'Task  State  PC   Event',0
01 fcc '  ',0
 endif

 pag

*
* getjob
*
* Search ready list for ready task.  If none found,
* return 'EQ' status.  Otherwise return task table
* entry address in x.
*

getjob clrb clear flag
 ldx runlst point to head of list
 beq getjo6 empty list?
getjo1 lda tsstat,x get status byte
 cmpa #TRUN is it in run state?
 bne getjo8
 tstb first in list?
 beq getjo2
 ldd tslink,x remove from list
 std tslink,y
 bra getjo4
getjo2 ldy tslink,x remove from list head
 sty runlst set new head
getjo4 ldb tsprir,x get priority
 clr tslink,x zero out link
 clr tslink+1,x so not run list
 lda #$ff set ne status
 rts return
getjo6 clra set eq status
 rts
getjo8 tfr x,y save old pos
 ldx tslink,x follow link
 beq getjo6
 ldb #1 set flag
 bra getjo1 repeat loop

 pag

*
* putrun
*
* Put current task on ready list.  The list is
* arranged with higher priority tasks at the top.
* If equal priorities are found, the new one is
* put at the end of the block.  On entry, x points
* to the task table entry.  All registers are
* destroyed except x.
*

putrun pshs cc save status
 seti mask interrupts
 ldy runlst point to head
 bne putru2
 stx runlst set new head
putru1 ldd #0 set last link
 std tslink,x
 puls cc,pc return
putru2 ldb tsprir,x get priority
 cmpb tsprir,y look for correct prior slot
 ble putru4
 ldd runlst
 stx runlst set new head
 bra putru5 link in rest
putru4 tfr y,u save last look
 ldy tslink,y follow link
 beq putru6
 cmpb tsprir,y check priority
 ble putru4
 ldd tslink,u link into list here
 stx tslink,u
putru5 std tslink,x
 puls cc,pc return
putru6 stx tslink,u
 bra putru1 go zero last link

 pag

*
* makrdy
*
* Make a task ready to run.  Enter with x
* pointing to task table entry.  If new tasks
* priority is higher than current, set the
* 'chproc' flag so the system can change tasks.
*

makrdy lda #TRUN set status
 sta tsstat,x
 ldd #0 clear events flag
 std tsevnt,x
 bsr putrun put on ready list
 ldb tsprir,x get priority
 cmpb jobpri higher than current?
 ble makrd6
 inc chproc set change flag
makrd6 rts return
