diff --git a/compiler/res/prog8lib/c128/syslib.p8 b/compiler/res/prog8lib/c128/syslib.p8 index 19eee028e..3fd00edac 100644 --- a/compiler/res/prog8lib/c128/syslib.p8 +++ b/compiler/res/prog8lib/c128/syslib.p8 @@ -97,7 +97,7 @@ extsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C extsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock extsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! extsub $FFED = SCRORG() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! -extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. +extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ Y, ubyte @ X ; read/set position of cursor on screen (Y=column, X=row). Also see txt.plot extsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices ; ---- end of C64 compatible ROM kernal routines ---- diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index 25ec6ee87..bfc934b5e 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -99,7 +99,7 @@ extsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A extsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files extsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock extsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) -extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. +extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ Y, ubyte @ X ; read/set position of cursor on screen (Y=column, X=row). Also see txt.plot extsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index a7c405855..839428787 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -81,7 +81,7 @@ extsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A extsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files extsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock extsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) -extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Also see txt.plot +extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ Y, ubyte @ X ; read/set position of cursor on screen (Y=column, X=row). Also see txt.plot extsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices ; ---- utility diff --git a/docs/source/comparing.rst b/docs/source/comparing.rst index 6340b36c2..19bd5491e 100644 --- a/docs/source/comparing.rst +++ b/docs/source/comparing.rst @@ -73,8 +73,8 @@ Subroutines variables declared in their parent subroutine(s). - Everything in prog8 is publicly accessible from everywhere else (via fully scoped names) - there is no notion of private or public symbol accessibility. - Because there is no callstack for subroutine arguments, it becomes very easy to manipulate the return address that *does* get pushed on the stack by the cpu. - With only a little bit of code it is possible to implement a simple cooperative multitasking system that runs multiple tasks simultaneously. See the "multitasking" example. - Each task is a subroutine and it simply has its state stored in its statically allocated variables so it can resume after a yield, without doing anything special. + With only a little bit of code it is possible to implement a simple cooperative multitasking system that runs multiple tasks simultaneously. See the "multitasking" example, + which uses the "coroutines" library. Each task is a subroutine and it simply has its state stored in the statically allocated variables so it can resume after yielding, without doing anything special. Pointers -------- diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 9387aa115..33d1c58d1 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -373,6 +373,25 @@ API is experimental and may change or disappear in a future version. Read the `coroutines source code `_ to see what's in there. And look at the ``multitasking`` example to see how it can be used. +Here is a minimal example (if the library gets more stable, better docs will be written here):: + + %import coroutine + + main { + sub start() { + coroutines.killall() + coroutines.add(&some_task, 1111) + ; ... add more tasks here or later + coroutines.run(0) + } + + sub some_task() { + repeat 100 { + uword userdata = coroutines.yield() + ; ... do something... + } + } + } cx16 diff --git a/docs/source/targetsystem.rst b/docs/source/targetsystem.rst index 39642f30e..8f538b8f9 100644 --- a/docs/source/targetsystem.rst +++ b/docs/source/targetsystem.rst @@ -127,18 +127,23 @@ So the normal IRQ vector can still run and will be when the program is started! CPU === -Directly Usable Registers -------------------------- +Directly Accessible Registers +----------------------------- -The hardware CPU registers are not directly accessible from regular Prog8 code. -If you need to mess with them, you'll have to use inline assembly. +The hardware CPU registers (A, X, Y) are not directly accessible from regular Prog8 code. +If you need to work with them, you'll have to use some inline assembly with ``%asm``. +Or, if they are required to have a value as arguments to some external kernal or library assembly routine, +just use a normal subroutine call to an ``extsub`` that correctly specifies what registers go where. +The compiler will then take care of loading the arguments into the required registers and returning +any response value(s) back to the prog8 code. -The status register (P) carry flag and interrupt disable flag can be written via a couple of special +The status register (P) carry flag and interrupt disable flag *can* be written via a couple of special builtin functions (``set_carry()``, ``clear_carry()``, ``set_irqd()``, ``clear_irqd()``), -and read via the ``read_flags()`` function. +and read via the ``read_flags()`` function. With the special status branch statements like ``if_cc``, +``if_cs`` etc you can branch directly on the status of the flags. The 16 'virtual' 16-bit registers that are defined on the Commander X16 machine are not real hardware -registers and are just 16 memory-mapped word values that you *can* access directly. +registers and are just 16 memory-mapped word values that you *can* access directly from everywhere. IRQ Handling