\ -*- forth -*- \ This file contains bare bones task switching code, in the form of \ the following words. It switches the 3 stacks and the a and f \ registers. \ \ suspend \ -- task | copy state to data stack, return task pointer \ resume \ task -- | ignore current context, resume old task \ swaptask \ ta var -- tb | swap task ta with task stored in var \ \ For example, using only two tasks, a single variable is used to \ store the task pointer of the other state. \ \ variable other \ \ Which enables the definition of a simple yield word \ \ : yield suspend other swaptask resume ; \ \ In general, one would call a 'schedule' word which transforms one \ task id into another one. For example by placing one task in a \ queue, and reading the next one from the queue. \ \ : yield suspend schedule resume ; \ \ \ Booting a task is very simple. It requires the initialization of the \ 3 stack pointers to an available location in memory. This depends on \ the particual memory model an is left to the user. \ \ : spawn \ suspend other ! \ suspend current task \ #x10 rp ! \ move return stack pointer to half of stack \ #x50 xp ! \ similar for the other 2 \ #x60 dp ! \ init-task ; \ \ IMPLEMENTATION macro : dp FSR0L ; : xp FSR1L ; : rp STKPTR ; forth \ A task is represented by a data stack pointer. The tricky bits are \ dp@ and dp! which must not interfere with the WREG = TOP \ optimization we have going on. It turns out this is easy: \ \ dp@ is just dp @, which is implemented as 'dup', followed by w <- FSR0L \ dp! is also just dp !, implemented as 'w -> FSR0L' followed by 'drop' \ \ Note that saving of a / f registers and TABLAT is only necessary if \ you use them in all tasks. the first 2-task app i did indeed used \ both a and f reg in both tasks, so here's the safest version. \ Note: this saves only the low byte of the FSR address, so task \ stacks need to be in the same bank. macro : dp@ dp @ ; : dp! dp ! ; forth macro : suspend \ -- task TABLAT @ fl @ fh @ al @ ah @ rp @ xp @ dp@ ; : resume \ task -- dp! xp ! rp ! ah ! al ! fh ! fl ! TABLAT ! ; : swaptask \ task var -- swap! ; forth \ YIELD: M.W 3b: to surrender or relinquish to the physical control of another