-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtask.txt
159 lines (150 loc) · 4.85 KB
/
task.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
\ *******************************************************************
\ *
\ Filename: task.txt *
\ Date: 07.06.2015 *
\ FF Version: 5.0 *
\ MCU: Atmega *
\ Copyright: Mikael Nordman *
\ Author: Mikael Nordman *
\ *******************************************************************
\ FlashForth is licensed according to the GNU General Public License*
\ *******************************************************************
\ TASK leaves the userarea address on the stack.
\ The basic size of a task is decimal 32 bytes.
\ The return stack, the parameter stack and the tib buffer areas
\ are in addition to that.
\ These are allocated at the end (high address) of the user area.
\ Own user varibles can be allocated from offset 2 upwards,
\ below the return stack. Addsize must reflect any additonal
\ user variables that are used.
\ uareasize = 32 + rsize + tibsize + ssize + addsize
\
\ The operator task is predefined.
\ flash decimal 72 72 72 0 task: operator
\
\ A background task with a 12 cell return stack and a
\ 12 cell parameter stack and no tib.
\ flash decimal 0 24 24 0 task: bg1
\
\ A background task with also one extra user variable.
\ flash decimal 0 24 24 2 task: bg2
\ ram decimal 2 user bg2_cnt
\ Do not use user variables as task specific variables
\ User variables are needed by _words_common_to_several_tasks_
\ which need some task specific data storage.
-task
marker -task
hex ram
\ Near definition saves memory !
: up! up ! ;
: up@ up @ ;
: op@ operator @ ;
: ul@ ulink @ ;
: ul! ulink ! ;
: op! op@ up! ;
\ access user variables of other task
: his ( task-addr var-addr -- addr )
up@ - swap @ +
;
\ Define a new task
\ A new task must be defined in the flash memory space
: task: ( tibsize stacksize rsize addsize -- )
flash create
up@ s0 - dup \ Basic size ts ss rs as bs bs
ram here + flash , \ User pointer ts ss rs as bs
4 for
over , +
next
cell+ \ Task size
ram allot
;
\ Initialise a user area and link it to the task loop
\ May only be executed from the operator task
: tinit ( taskloop-addr task-addr -- )
\ use task user area
@+ up! \ a addsize-addr
ul@ if \ ? Already running
2drop
else
\ Pointer to task area
dup 2- task !
\ r0 = uarea+addsize+rsize
@+ swap @+ rot + up@ + \ a ssize-addr r0
\ Save r0
r0 ! \ a ssize-addr
\ s0 = r0 + ssize
@ r0 @ + s0 ! \ a
\ Store task-loop address to the return stack
r0 @ x>r \ rsp
\ Store SP to return stack
1- dup s0 @ swap ! \ rsp
\ Store current rsp and space for saving TOS and P PAUSE
5 - rsave ! \
\ tiu = s0 + 2
s0 @ 2+ tiu !
0 ul!
0 task 2+ ! \ clear status and cr flag
decimal \ Set the base to decimal
then
op! \ run the operator task again
;
\ Insert a new task after operator in the linked list.
\ May only be executed from the operator task
: run ( task-addr -- )
@ up! ul@ 0= if \ ? Already running
up@ \ task-uarea
op! ul@ \ task-uarea operator-ulink
over ul!
swap up! ul!
then
op! \ run operator task
;
\ End a task by linking it out from the linked list
\ May only be executed from the operator task
: end ( task-addr -- )
@ up! ul@ if
up@
op!
begin \ find the uarea in the linked list
dup ul@ <> \ uarea flag
while
ul@ up! \ uarea
repeat
up@ \ uarea prev-uarea
swap up! \ prev-uarea
ul@ \ prev-uarea next-uarea
0 ul! \ ulink of a ended task is zero
swap up! \ next-uarea
ul! \
then
op!
;
\ End all tasks except the operator task
\ May only be executed from the operator task
: single ( -- )
ul@ op@ <> if \ Are there any running tasks
ul@ op@ ul! \ link operator to himself
up! \ move to next user area
begin
ul@ op@ <> \ is this the last linked user area
while
ul@ 0 ul! \ write zero to ulink
up! \ and move to next user area
repeat
0 ul!
op!
then
;
\ List all running tasks
: tasks ( -- )
up@ op!
begin
up@
task @ 6 - op! c>n .id space
up!
ul@ op@ -
while
ul@ up!
repeat
up!
;