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
|
---|