From 8b9da65357223716da3b47e959f51cfed52a2d8b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 28 Dec 2024 02:19:37 +0100 Subject: [PATCH] Added supervisor to coroutines.run(). update symboldumps for 11.0.1. --- compiler/res/prog8lib/coroutines.p8 | 19 +++++++++++--- docs/import-all-atari.p8 | 1 + docs/import-all-c128.p8 | 1 + docs/import-all-c64.p8 | 1 + docs/import-all-cx16.p8 | 1 + docs/import-all-neo.p8 | 1 + docs/import-all-pet32.p8 | 1 + .../_static/symboldumps/skeletons-atari.txt | 25 ++++++++++++++++-- .../_static/symboldumps/skeletons-c128.txt | 25 ++++++++++++++++-- .../_static/symboldumps/skeletons-c64.txt | 25 ++++++++++++++++-- .../_static/symboldumps/skeletons-cx16.txt | 26 +++++++++++++++++-- .../_static/symboldumps/skeletons-neo.txt | 23 +++++++++++++++- .../_static/symboldumps/skeletons-pet32.txt | 25 ++++++++++++++++-- .../_static/symboldumps/skeletons-virtual.txt | 5 ++-- examples/cx16/pcmaudio/adpcm.p8 | 6 ++--- examples/multitasking.p8 | 14 +++++++++- gradle.properties | 2 +- 17 files changed, 179 insertions(+), 22 deletions(-) diff --git a/compiler/res/prog8lib/coroutines.p8 b/compiler/res/prog8lib/coroutines.p8 index 3e87aa56b..a7eaef558 100644 --- a/compiler/res/prog8lib/coroutines.p8 +++ b/compiler/res/prog8lib/coroutines.p8 @@ -9,7 +9,8 @@ ; - you can add new tasks, while the rest is already running. Just not yet from inside IRQ handlers! ; - tasks are regular subroutines but have to call yield() to pass control to the next task (round-robin) ; - yield() returns the registered userdata value for that task, so a single subroutine could be used as multiple tasks on different userdata -; BUT!! in that case, the subroutine cannot have any variables of its own that keep state, because they're shared across the multiple tasks +; BUT!! in that case, the subroutine cannot have any variables of its own that keep state, because they're shared across the multiple tasks! +; (if a subroutine is just inserted as a task exactly ONCE, it's okay to use normal variables for state, because nobody will share them) ; - you can kill a task (if you know it's id...) ; - when all tasks are finished the run() call will also return. ; - tasks can't push anything on the cpu stack before calling yield() - that will cause chaos. @@ -23,7 +24,9 @@ ; ; USAGE: ; - call add(taskaddress) to add a new task. It returns the task id. -; - call run() to start executing all tasks until none are left. +; - call run(supervisor) to start executing all tasks until none are left. Pass 0 or a pointer to a 'supervisor' routine. +; that routine can for instance call current() (or just look at the active_task variable) to get the id of the next task to execute. +; It has then to return a boolean: true=next task is to be executed, false=skip the task this time. ; - in tasks: call yield() to pass control to the next task. Use the returned userdata value to do different things. ; - call current() to get the current task id. ; - call kill(taskid) to kill a task by id. @@ -37,6 +40,7 @@ coroutines { uword[MAX_TASKS] userdatas uword[MAX_TASKS] returnaddresses ubyte active_task + uword supervisor sub add(uword taskaddress, uword userdata) -> ubyte { ; find the next empty slot in the tasklist and stick it there @@ -63,7 +67,8 @@ coroutines { } } - sub run() { + sub run(uword supervisor_routine) { + supervisor = supervisor_routine for active_task in 0 to len(tasklist)-1 { if tasklist[active_task]!=0 { ; activate the termination handler and start the first task @@ -87,6 +92,11 @@ resume_with_next_task: return 0 ; exiting here will now actually return from the start() call back to the calling program :) } + if supervisor!=0 { + if lsb(call(supervisor))==0 + goto resume_with_next_task + } + if task_continue==0 { ; fetch start address of next task. ; address on the stack must be pushed in reverse byte order @@ -96,7 +106,8 @@ resume_with_next_task: } else sys.pushw(task_continue) - return userdatas[active_task] ; returning from yield then continues with the next coroutine + ; returning from yield then continues with the next coroutine + return userdatas[active_task] sub next_task() -> bool { ; search through the task list for the next active task diff --git a/docs/import-all-atari.p8 b/docs/import-all-atari.p8 index 38f9baa08..4db09d0f5 100644 --- a/docs/import-all-atari.p8 +++ b/docs/import-all-atari.p8 @@ -2,6 +2,7 @@ %import buffers %import compression +%import coroutines %import conv %import cx16logo %import math diff --git a/docs/import-all-c128.p8 b/docs/import-all-c128.p8 index 71fa3e263..99700a41a 100644 --- a/docs/import-all-c128.p8 +++ b/docs/import-all-c128.p8 @@ -3,6 +3,7 @@ %import buffers %import compression %import conv +%import coroutines %import cx16logo %import diskio ;;%import floats diff --git a/docs/import-all-c64.p8 b/docs/import-all-c64.p8 index f580475f9..be32d354b 100644 --- a/docs/import-all-c64.p8 +++ b/docs/import-all-c64.p8 @@ -3,6 +3,7 @@ %import buffers %import compression %import conv +%import coroutines %import cx16logo %import diskio %import floats diff --git a/docs/import-all-cx16.p8 b/docs/import-all-cx16.p8 index 115aab2b1..d036c005f 100644 --- a/docs/import-all-cx16.p8 +++ b/docs/import-all-cx16.p8 @@ -4,6 +4,7 @@ %import bmx %import compression %import conv +%import coroutines %import cx16logo %import diskio %import emudbg diff --git a/docs/import-all-neo.p8 b/docs/import-all-neo.p8 index 13248168f..74dca8809 100644 --- a/docs/import-all-neo.p8 +++ b/docs/import-all-neo.p8 @@ -3,6 +3,7 @@ %import buffers %import compression %import conv +%import coroutines %import math %import prog8_lib %import strings diff --git a/docs/import-all-pet32.p8 b/docs/import-all-pet32.p8 index cb311c4a5..d02ffcac9 100644 --- a/docs/import-all-pet32.p8 +++ b/docs/import-all-pet32.p8 @@ -3,6 +3,7 @@ %import buffers %import compression %import conv +%import coroutines %import cx16logo %import math %import prog8_lib diff --git a/docs/source/_static/symboldumps/skeletons-atari.txt b/docs/source/_static/symboldumps/skeletons-atari.txt index 24d3908b2..defcf6185 100644 --- a/docs/source/_static/symboldumps/skeletons-atari.txt +++ b/docs/source/_static/symboldumps/skeletons-atari.txt @@ -1,5 +1,5 @@ -Prog8 compiler v11.0 by Irmen de Jong (irmen@razorvine.net) +Prog8 compiler v11.0.1 by Irmen de Jong (irmen@razorvine.net) This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-atari.p8 @@ -102,11 +102,31 @@ conv { } +LIBRARY MODULE NAME: coroutines +------------------------------- + +coroutines { + const ubyte MAX_TASKS + ubyte active_task + uword[] returnaddresses + uword supervisor + uword[] tasklist + uword[] userdatas + add (uword taskaddress, uword userdata) -> ubyte + current () -> ubyte + kill (ubyte taskid) + killall () + run (uword supervisor_routine) + termination () + yield () -> uword +} + + LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - @nosplit uword[] logo_lines + uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } @@ -242,6 +262,7 @@ sys { progend () -> uword @AY progstart () -> uword @AY push (ubyte value @A) + push_returnaddress (uword address @XY) pushw (uword value @AY) read_flags () -> ubyte @A reset_system () diff --git a/docs/source/_static/symboldumps/skeletons-c128.txt b/docs/source/_static/symboldumps/skeletons-c128.txt index a7d4a4351..eeddb123d 100644 --- a/docs/source/_static/symboldumps/skeletons-c128.txt +++ b/docs/source/_static/symboldumps/skeletons-c128.txt @@ -1,5 +1,5 @@ -Prog8 compiler v11.0 by Irmen de Jong (irmen@razorvine.net) +Prog8 compiler v11.0.1 by Irmen de Jong (irmen@razorvine.net) This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-c128.p8 @@ -102,11 +102,31 @@ conv { } +LIBRARY MODULE NAME: coroutines +------------------------------- + +coroutines { + const ubyte MAX_TASKS + ubyte active_task + uword[] returnaddresses + uword supervisor + uword[] tasklist + uword[] userdatas + add (uword taskaddress, uword userdata) -> ubyte + current () -> ubyte + kill (ubyte taskid) + killall () + run (uword supervisor_routine) + termination () + yield () -> uword +} + + LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - @nosplit uword[] logo_lines + uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } @@ -507,6 +527,7 @@ sys { progend () -> uword @AY progstart () -> uword @AY push (ubyte value @A) + push_returnaddress (uword address @XY) pushw (uword value @AY) read_flags () -> ubyte @A reset_system () diff --git a/docs/source/_static/symboldumps/skeletons-c64.txt b/docs/source/_static/symboldumps/skeletons-c64.txt index 45fbd3b87..4b40d38c9 100644 --- a/docs/source/_static/symboldumps/skeletons-c64.txt +++ b/docs/source/_static/symboldumps/skeletons-c64.txt @@ -1,5 +1,5 @@ -Prog8 compiler v11.0 by Irmen de Jong (irmen@razorvine.net) +Prog8 compiler v11.0.1 by Irmen de Jong (irmen@razorvine.net) This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-c64.p8 @@ -102,11 +102,31 @@ conv { } +LIBRARY MODULE NAME: coroutines +------------------------------- + +coroutines { + const ubyte MAX_TASKS + ubyte active_task + uword[] returnaddresses + uword supervisor + uword[] tasklist + uword[] userdatas + add (uword taskaddress, uword userdata) -> ubyte + current () -> ubyte + kill (ubyte taskid) + killall () + run (uword supervisor_routine) + termination () + yield () -> uword +} + + LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - @nosplit uword[] logo_lines + uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } @@ -633,6 +653,7 @@ sys { progend () -> uword @AY progstart () -> uword @AY push (ubyte value @A) + push_returnaddress (uword address @XY) pushw (uword value @AY) read_flags () -> ubyte @A reset_system () diff --git a/docs/source/_static/symboldumps/skeletons-cx16.txt b/docs/source/_static/symboldumps/skeletons-cx16.txt index 70c1a5372..58f6d27a1 100644 --- a/docs/source/_static/symboldumps/skeletons-cx16.txt +++ b/docs/source/_static/symboldumps/skeletons-cx16.txt @@ -1,5 +1,5 @@ -Prog8 compiler v11.0 by Irmen de Jong (irmen@razorvine.net) +Prog8 compiler v11.0.1 by Irmen de Jong (irmen@razorvine.net) This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-cx16.p8 @@ -140,11 +140,31 @@ conv { } +LIBRARY MODULE NAME: coroutines +------------------------------- + +coroutines { + const ubyte MAX_TASKS + ubyte active_task + uword[] returnaddresses + uword supervisor + uword[] tasklist + uword[] userdatas + add (uword taskaddress, uword userdata) -> ubyte + current () -> ubyte + kill (ubyte taskid) + killall () + run (uword supervisor_routine) + termination () + yield () -> uword +} + + LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - @nosplit uword[] logo_lines + uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } @@ -1186,6 +1206,7 @@ sys { progend () -> uword @AY progstart () -> uword @AY push (ubyte value @A) + push_returnaddress (uword address @XY) pushw (uword value @AY) read_flags () -> ubyte @A reset_system () @@ -1277,6 +1298,7 @@ txt { setchr (ubyte col @X, ubyte row @Y, ubyte character @A) -> clobbers (A) setclr (ubyte col @X, ubyte row @Y, ubyte color @A) -> clobbers (A) spc () + t256c (bool enable) uppercase () waitkey () -> ubyte @A width () -> clobbers (X,Y) -> ubyte @A diff --git a/docs/source/_static/symboldumps/skeletons-neo.txt b/docs/source/_static/symboldumps/skeletons-neo.txt index 2b8b5fcf9..2fc6e77d4 100644 --- a/docs/source/_static/symboldumps/skeletons-neo.txt +++ b/docs/source/_static/symboldumps/skeletons-neo.txt @@ -1,5 +1,5 @@ -Prog8 compiler v11.0 by Irmen de Jong (irmen@razorvine.net) +Prog8 compiler v11.0.1 by Irmen de Jong (irmen@razorvine.net) This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-neo.p8 @@ -102,6 +102,26 @@ conv { } +LIBRARY MODULE NAME: coroutines +------------------------------- + +coroutines { + const ubyte MAX_TASKS + ubyte active_task + uword[] returnaddresses + uword supervisor + uword[] tasklist + uword[] userdatas + add (uword taskaddress, uword userdata) -> ubyte + current () -> ubyte + kill (ubyte taskid) + killall () + run (uword supervisor_routine) + termination () + yield () -> uword +} + + LIBRARY MODULE NAME: math ------------------------- @@ -226,6 +246,7 @@ sys { progend () -> uword @AY progstart () -> uword @AY push (ubyte value @A) + push_returnaddress (uword address @XY) pushw (uword value @AY) read_flags () -> ubyte @A reset_system () diff --git a/docs/source/_static/symboldumps/skeletons-pet32.txt b/docs/source/_static/symboldumps/skeletons-pet32.txt index 1b1465468..efab7681d 100644 --- a/docs/source/_static/symboldumps/skeletons-pet32.txt +++ b/docs/source/_static/symboldumps/skeletons-pet32.txt @@ -1,5 +1,5 @@ -Prog8 compiler v11.0 by Irmen de Jong (irmen@razorvine.net) +Prog8 compiler v11.0.1 by Irmen de Jong (irmen@razorvine.net) This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-pet32.p8 @@ -102,11 +102,31 @@ conv { } +LIBRARY MODULE NAME: coroutines +------------------------------- + +coroutines { + const ubyte MAX_TASKS + ubyte active_task + uword[] returnaddresses + uword supervisor + uword[] tasklist + uword[] userdatas + add (uword taskaddress, uword userdata) -> ubyte + current () -> ubyte + kill (ubyte taskid) + killall () + run (uword supervisor_routine) + termination () + yield () -> uword +} + + LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - @nosplit uword[] logo_lines + uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } @@ -260,6 +280,7 @@ sys { progend () -> uword @AY progstart () -> uword @AY push (ubyte value @A) + push_returnaddress (uword address @XY) pushw (uword value @AY) read_flags () -> ubyte @A reset_system () diff --git a/docs/source/_static/symboldumps/skeletons-virtual.txt b/docs/source/_static/symboldumps/skeletons-virtual.txt index 1dda860e6..a3243bf23 100644 --- a/docs/source/_static/symboldumps/skeletons-virtual.txt +++ b/docs/source/_static/symboldumps/skeletons-virtual.txt @@ -1,5 +1,5 @@ -Prog8 compiler v11.0 by Irmen de Jong (irmen@razorvine.net) +Prog8 compiler v11.0.1 by Irmen de Jong (irmen@razorvine.net) This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html Compiling program import-all-virtual.p8 @@ -99,7 +99,7 @@ LIBRARY MODULE NAME: cx16logo ----------------------------- cx16logo { - @nosplit uword[] logo_lines + uword[] logo_lines logo () logo_at (ubyte column, ubyte row) } @@ -344,6 +344,7 @@ sys { pop () -> ubyte popw () -> uword push (ubyte b) + push_returnaddress (uword w) pushw (uword w) read_flags () -> ubyte reset_system () diff --git a/examples/cx16/pcmaudio/adpcm.p8 b/examples/cx16/pcmaudio/adpcm.p8 index 8dee50793..02b76eb76 100644 --- a/examples/cx16/pcmaudio/adpcm.p8 +++ b/examples/cx16/pcmaudio/adpcm.p8 @@ -101,10 +101,10 @@ adpcm { } sub decode_nibble_second(ubyte @zp nibble) { - ; Decoder for nibbles for the second channel. - ; this is the hotspot of the decoder algorithm! + ; Decoder for a single nibble for the second channel. (value of 'nibble' needs to be strictly 0-15 !) + ; This is the hotspot of the decoder algorithm! ; Note that the generated assembly from this is pretty efficient, - ; rewriting it by hand in asm seems to improve it only 5-10% + ; rewriting it by hand in asm seems to improve it only ~10%. cx16.r0s = 0 ; difference if nibble & %0100 !=0 cx16.r0s += pstep_2 diff --git a/examples/multitasking.p8 b/examples/multitasking.p8 index 8846eb68a..f9dd77bcc 100644 --- a/examples/multitasking.p8 +++ b/examples/multitasking.p8 @@ -20,8 +20,12 @@ main { void coroutines.add(&task4, sc:'4') void coroutines.add(&keyhandler, 0) void coroutines.add(&delaytask, 0) - coroutines.run() + coroutines.run(&supervisor) ; can also use 0 if you don't need a supervisor routine + ; the supervisor is called every time a task switch is about to occur - and you can control that somewhat. + ; if that control is not needed you could also just add a "system" routine as a regular task, + ; much like the keyhandler and delay tasks above. + ; we will end up here if there are no more tasks to run (doesn't happen in this example) txt.print("we're all done!\n") } @@ -36,6 +40,14 @@ main { } } + sub supervisor() -> bool { + ; you can call coroutines.current() to get the id of the next task to run. + ; (or just read the active_task variable) + ; return true to execute that task, or false to skip it this time. + ; or do something else....? + return true + } + ubyte[coroutines.MAX_TASKS] counters sub countertask() { diff --git a/gradle.properties b/gradle.properties index 8a0dc9ee7..d81237133 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.console=rich org.gradle.parallel=true org.gradle.daemon=true kotlin.code.style=official -version=11.0.1-SNAPSHOT +version=11.0.1