[3ae31e9] | 1 | * ------------------------------------------------------------------------------
|
---|
| 2 | * mtswap.s -- Multi-tasker -- swapper
|
---|
| 3 | * Version 24 -- 1988-04-16 -- D.N. Lynx Crowe
|
---|
| 4 | * (c) Copyright 1988 -- D.N. Lynx Crowe
|
---|
| 5 | * Machine cycles are given as the first number in the comments for timing.
|
---|
| 6 | * ------------------------------------------------------------------------------
|
---|
| 7 | .text
|
---|
| 8 | *
|
---|
| 9 | .xdef __MT_Swp
|
---|
| 10 | .xdef __MT_Nxt
|
---|
| 11 | *
|
---|
| 12 | .xdef MT_Enq
|
---|
| 13 | *
|
---|
| 14 | .xref _MT_STpc
|
---|
| 15 | .xref _MT_NTpc
|
---|
| 16 | .xref _MT_LTCB
|
---|
| 17 | *
|
---|
| 18 | .xref _MT_TCBs * to force loading
|
---|
| 19 | .xref _MT_CurP
|
---|
| 20 | .xref _MT_RdyQ
|
---|
| 21 | *
|
---|
| 22 | .page
|
---|
| 23 | *
|
---|
| 24 | * TCB offsets
|
---|
| 25 | * -----------
|
---|
| 26 | NEXT .equ 0 * LONG - next TCB in queue
|
---|
| 27 | FWD .equ NEXT+4 * LONG - next TCB in chain
|
---|
| 28 | TID .equ FWD+4 * WORD - task ID
|
---|
| 29 | PRI .equ TID+2 * WORD - task priority
|
---|
| 30 | SLICE .equ PRI+2 * LONG - slice time limit
|
---|
| 31 | REGS .equ SLICE+4 * LONG[16] - registers
|
---|
| 32 | TCB_SP .equ REGS+64 * LONG - stack pointer
|
---|
| 33 | TCB_PC .equ TCB_SP+4 * LONG - program counter
|
---|
| 34 | TCB_SR .equ TCB_PC+4 * WORD - status register
|
---|
| 35 | FLAGS .equ TCB_SR+2 * WORD - task flags
|
---|
| 36 | TOS .equ FLAGS+2 * LONG - top of stack pointer
|
---|
| 37 | *
|
---|
| 38 | TCB_A6 .equ REGS+56 * LONG - task a6 image
|
---|
| 39 | TCB_A7 .equ REGS+60 * LONG - task a7 image
|
---|
| 40 | *
|
---|
| 41 | MTF_RDY .equ $0001 * 'ready' bit
|
---|
| 42 | NOT_RDY .equ $FFFE * 'ready' bit complement
|
---|
| 43 | MTF_SWT .equ $0002 * 'wait' bit
|
---|
| 44 | NOT_SWT .equ $FFFD * 'wait' bit complement
|
---|
| 45 | MTF_RUN .equ $0004 * 'run' bit
|
---|
| 46 | NOT_RUN .equ $FFFB * 'run' bit complement
|
---|
| 47 | MTF_STP .equ $0008 * 'stop' bit
|
---|
| 48 | NOT_STP .equ $FFF7 * 'stop' bit complement
|
---|
| 49 | *
|
---|
| 50 | IPL7 .equ $0700 * processor IPL 7 mask
|
---|
| 51 | *
|
---|
| 52 | RPRV .equ a1 * previous TCB pointer
|
---|
| 53 | RCUR .equ a2 * current TCB pointer
|
---|
| 54 | RNXT .equ a3 * next TCB pointer
|
---|
| 55 | RTCP .equ a6 * general TCB pointer
|
---|
| 56 | *
|
---|
| 57 | RPRI .equ d0 * task priority
|
---|
| 58 | RTST .equ d1 * test register
|
---|
| 59 | *
|
---|
| 60 | TRAP_SWP .equ 8 * swapper TRAP number 1
|
---|
| 61 | TRAP_NXT .equ 9 * swapper TRAP number 2
|
---|
| 62 | *
|
---|
| 63 | .page
|
---|
| 64 | *
|
---|
| 65 | * _MT_Swp -- swap tasks
|
---|
| 66 | * ------- ----------
|
---|
| 67 | __MT_Swp: ori.w #IPL7,sr * 8 disable interrupts
|
---|
| 68 | tst.l _MT_RdyQ * 20 see if anything is queued
|
---|
| 69 | beq MT_runit * 8/10 re-run current task if not
|
---|
| 70 | *
|
---|
| 71 | movem.l a6-a7,-(a7) * 28 save a6,a7 on stack
|
---|
| 72 | movea.l _MT_CurP,RTCP * 20 get current TCB pointer
|
---|
| 73 | movem.l d0-d7/a0-a5,REGS(RTCP) * 152 put task d0-d7/a0-a5 in TCB
|
---|
| 74 | move.l (a7)+,TCB_A6(RTCP) * 26 put task a6 in TCB
|
---|
| 75 | move.l (a7)+,TCB_A7(RTCP) * 26 put task a7 in TCB
|
---|
| 76 | move.w (a7)+,TCB_SR(RTCP) * 17 put task sr in TCB
|
---|
| 77 | move.l (a7)+,TCB_PC(RTCP) * 26 put task pc in TCB
|
---|
| 78 | move.l a7,TCB_SP(RTCP) * 18 put task sp in TCB
|
---|
| 79 | andi.w #NOT_RUN,FLAGS(RTCP) * 21 turn off' run' bit
|
---|
| 80 | move.w PRI(RTCP),RPRI * 12 get task priority
|
---|
| 81 | lea _MT_RdyQ,RCUR * 8 point at ready queue
|
---|
| 82 | movea.l (RCUR),RNXT * 12 get highest priority TCB
|
---|
| 83 | move.l (RNXT),(RCUR) * 13 dequeue the TCB
|
---|
| 84 | andi.w #NOT_RDY,FLAGS(RNXT) * 21 turn off 'ready' bit
|
---|
| 85 | *
|
---|
| 86 | MT_Enq: movea.l RCUR,RPRV * 4 point at previous TCB
|
---|
| 87 | movea.l (RPRV),RCUR * 10 get pointer to next TCB
|
---|
| 88 | move.l RCUR,RTST * 4 test pointer
|
---|
| 89 | beq enq1 * 8/10 enqueue now if pointer is NIL
|
---|
| 90 | *
|
---|
| 91 | cmp.w PRI(RCUR),RPRI * 12 compare priorities
|
---|
| 92 | bls MT_Enq * 8/10 jump if RPRI LE table TCB
|
---|
| 93 | *
|
---|
| 94 | enq1: move.l RTCP,(RPRV) * 9 set NEXT of previous TCB
|
---|
| 95 | move.l RTCP,_MT_LTCB * 22 log last TCB swapped out
|
---|
| 96 | move.l RCUR,(RTCP) * 9 set NEXT of rescheduled TCB
|
---|
| 97 | ori.w #MTF_RDY,FLAGS(RTCP) * 21 turn on 'ready' bit
|
---|
| 98 | movea.l RNXT,RTCP * 4 get new TCB pointer
|
---|
| 99 | move.l RTCP,_MT_CurP * 22 make it the current TCB
|
---|
| 100 | clr.l (RTCP) * 22 clear NEXT of current TCB
|
---|
| 101 | ori.w #MTF_RUN,FLAGS(RTCP) * 21 turn on 'run' bit
|
---|
| 102 | move.l TCB_PC(RTCP),_MT_STpc * 25 log dispatch address
|
---|
| 103 | movea.l TCB_SP(RTCP),a7 * 16 get task sp
|
---|
| 104 | move.l TCB_PC(RTCP),-(a7) * 26 put task pc on the stack
|
---|
| 105 | move.w TCB_SR(RTCP),-(a7) * 26 put task sr on the stack
|
---|
| 106 | movem.l REGS(RTCP),d0-d7/a0-a5 * 128 restore task d0-d7/a0-a5
|
---|
| 107 | movea.l TCB_A6(RTCP),a6 * 26 restore task a6
|
---|
| 108 | *
|
---|
| 109 | MT_runit: rte * 20 (re)start the task
|
---|
| 110 | *
|
---|
| 111 | .page
|
---|
| 112 | *
|
---|
| 113 | * __MT_Nxt -- start the first task in the ready queue
|
---|
| 114 | * -------- ---------------------------------------
|
---|
| 115 | __MT_Nxt: ori.w #IPL7,sr * 8 disable interrupts
|
---|
| 116 | movem.l a6-a7,-(a7) * 28 save a6,a7 on stack
|
---|
| 117 | movea.l _MT_CurP,RTCP * 20 get current TCB pointer
|
---|
| 118 | move.l RTCP,_MT_LTCB * 22 log last TCB swapped out
|
---|
| 119 | movem.l d0-d7/a0-a5,REGS(RTCP) * 152 put task d0-d7/a0-a5 in TCB
|
---|
| 120 | move.l (a7)+,TCB_A6(RTCP) * 26 put task a6 in TCB
|
---|
| 121 | move.l (a7)+,TCB_A7(RTCP) * 26 put task a7 in TCB
|
---|
| 122 | move.w (a7)+,TCB_SR(RTCP) * 17 put task sr in TCB
|
---|
| 123 | move.l (a7)+,TCB_PC(RTCP) * 26 put task pc in TCB
|
---|
| 124 | move.l a7,TCB_SP(RTCP) * 18 put task sp in TCB
|
---|
| 125 | andi.w #NOT_RUN,FLAGS(RTCP) * 21 turn off' run' bit
|
---|
| 126 | lea _MT_RdyQ,RCUR * 8 point at ready queue
|
---|
| 127 | movea.l (RCUR),RNXT * 12 get highest priority TCB
|
---|
| 128 | move.l (RNXT),(RCUR) * 13 dequeue the TCB
|
---|
| 129 | andi.w #NOT_RDY,FLAGS(RNXT) * 21 turn off 'ready' bit
|
---|
| 130 | movea.l RNXT,RTCP * 4 get new TCB pointer
|
---|
| 131 | move.l RTCP,_MT_CurP * 22 make it the current TCB
|
---|
| 132 | clr.l (RTCP) * 22 clear NEXT of current TCB
|
---|
| 133 | ori.w #MTF_RUN,FLAGS(RTCP) * 21 turn on 'run' bit
|
---|
| 134 | move.l TCB_PC(RTCP),_MT_NTpc * 25 log dispatch address
|
---|
| 135 | movea.l TCB_SP(RTCP),a7 * 16 get task sp
|
---|
| 136 | move.l TCB_PC(RTCP),-(a7) * 26 put task pc on the stack
|
---|
| 137 | move.w TCB_SR(RTCP),-(a7) * 26 put task sr on the stack
|
---|
| 138 | movem.l REGS(RTCP),d0-d7/a0-a5 * 128 restore task d0-d7/a0-a5
|
---|
| 139 | movea.l TCB_A6(RTCP),a6 * 26 restore task a6
|
---|
| 140 | rte * 20 start the task
|
---|
| 141 | *
|
---|
| 142 | .end
|
---|