aboutsummaryrefslogtreecommitdiff
path: root/forth/forth/avr/task.fs
diff options
context:
space:
mode:
Diffstat (limited to 'forth/forth/avr/task.fs')
-rw-r--r--forth/forth/avr/task.fs160
1 files changed, 160 insertions, 0 deletions
diff --git a/forth/forth/avr/task.fs b/forth/forth/avr/task.fs
new file mode 100644
index 0000000..1a96928
--- /dev/null
+++ b/forth/forth/avr/task.fs
@@ -0,0 +1,160 @@
+\ *******************************************************************
+\ *
+\ 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!
+;
+