From 44b82915408b3a218426de1ec9d49ac6eec16824 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 22 Dec 2020 13:29:16 +0100 Subject: [PATCH] update docs --- README.md | 1 + docs/source/index.rst | 3 ++- docs/source/programming.rst | 4 ++++ docs/source/syntaxreference.rst | 22 +++++++++++++++++----- docs/source/targetsystem.rst | 17 ++--------------- examples/test.p8 | 11 +++-------- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 0f59d6ce8..b59fbf989 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ What does Prog8 provide? - convenience abstractions for low level aspects such as ZeroPage handling, program startup, explicit memory addresses - fast execution speed due to compilation to native assembly code - inline assembly allows you to have full control when every cycle or byte matters +- supports the sixteen 'virtual' 16-bit registers R0 .. R15 from the Commander X16, also on the C64. *Rapid edit-compile-run-debug cycle:* diff --git a/docs/source/index.rst b/docs/source/index.rst index 1136ef3e9..c48b64acf 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -56,6 +56,7 @@ Language features - Variable data types include signed and unsigned bytes and words, arrays, strings and floats. - High-level code optimizations, such as const-folding, expression and statement simplifications/rewriting. - Many built-in functions, such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``substr``, ``sort`` and ``reverse`` (and others) +- Supports the sixteen 'virtual' 16-bit registers R0 .. R15 from the Commander X16, also on the C64. - If you only use standard kernel and prog8 library routines, it is possible to compile the *exact same program* for both machines (just change the compiler target flag)! @@ -132,7 +133,7 @@ Required tools `64tass `_ - cross assembler. Install this on your shell path. It's very easy to compile yourself. -A recent precompiled .exe for Windows can be obtained from my `clone `_ of this project. +A recent precompiled .exe (only for Windows) can be obtained from my `clone `_ of this project. *You need at least version 1.55.2257 of this assembler to correctly use the breakpoints feature.* It's possible to use older versions, but it is very likely that the automatic Vice breakpoints won't work with them. diff --git a/docs/source/programming.rst b/docs/source/programming.rst index c935d7928..76680fde0 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -888,9 +888,11 @@ rsave() Note: it's not needed to rsave() before an asm subroutine that clobbers the X register (which is used as the internal evaluation stack pointer). The compiler will take care of this situation automatically. + Note: the 16 bit 'virtual' registers of the Commander X16 are not saved. rrestore() Restores the CPU registers and the status flags from previously saved values. + Note: the 16 bit 'virtual' registers of the Commander X16 are not restored. read_flags() Returns the current value of the CPU status register. @@ -914,6 +916,8 @@ swap(x, y) target() Returns byte value designating the target machine that the program was compiled for. + Notice that this is a compile-time constant value and is not determined on the + system when the program is running. The following return values are currently defined: - 16 = compiled for CommanderX16 with 65C02 CPU diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index e04adbaa3..136f69b01 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -517,11 +517,11 @@ You can still call the subroutine and not store the results. **There is an exception:** if there's just one return value in a register, and one or more others that are returned as bits in the status register (such as the Carry bit), the compiler allows you to call the subroutine. -It will then store the result value in a variable if required, and *keep the status register untouched -after the call* so you can use a conditional branch statement for that. -Note that this makes no sense inside an expression, so the compiler will still give an error for that. +It will then store the result value in a variable if required, and *try to keep the status register untouched +after the call* so you can often use a conditional branch statement for that. But the latter is tricky, +make sure you check the generated assembly code. -If there really are multiple return values (other than a combined 16 bit return value in 2 registers), +If there really are multiple relevant return values (other than a combined 16 bit return value in 2 registers), you'll have to write a small block of custom inline assembly that does the call and stores the values appropriately. Don't forget to save/restore any registers that are modified. @@ -557,7 +557,6 @@ This defines the ``LOAD`` subroutine at ROM memory address $FFD5, taking argumen and returning stuff in several registers as well. The ``clobbers`` clause is used to signify to the compiler what CPU registers are clobbered by the call instead of being unchanged or returning a meaningful result value. - User subroutines in the program source code that are implemented purely in assembly and which have an assembly calling convention (i.e. the parameters are strictly passed via cpu registers), are defined with ``asmsub`` like this:: @@ -576,6 +575,19 @@ the parameters are strictly passed via cpu registers), are defined with ``asmsub the statement body of such a subroutine should consist of just an inline assembly block. +The ``@ `` part is required for rom and assembly-subroutines, as it specifies for the compiler +what cpu registers should take the routine's arguments. You can use the regular set of registers +(A, X, Y), the special 16-bit register pairs to take word values (AX, AY and XY) and even a processor status +flag such as Carry (Pc). + +.. note:: + The 'virtual' 16-bit registers from the Commander X16 can also be used as ``R0`` .. ``R15`` . + This means you don't have to set them up manually before calling a subroutine that takes + one or more parameters in those 'registers'. You can just list the arguments directly. + *This also works on the Commodore-64!* (however they are not as efficient there because they're not in zeropage) + In prog8 and assembly code these 'registers' are directly accessible too via + ``cx16.r0`` .. ``cx16.r15`` (they're memory mapped uword values) + Expressions ----------- diff --git a/docs/source/targetsystem.rst b/docs/source/targetsystem.rst index e01fc0e77..a541dda3a 100644 --- a/docs/source/targetsystem.rst +++ b/docs/source/targetsystem.rst @@ -131,21 +131,8 @@ The status register (P) carry flag and interrupt disable flag can be written via builtin functions (``set_carry()``, ``clear_carry()``, ``set_irqd()``, ``clear_irqd()``), and read via the ``read_flags()`` function. - -Subroutine Calling Conventions ------------------------------- - -**Kernel/assembly subroutines:** -Arguments and results are passed via registers. -Sometimes the status register's Carry flag is used as well (as a boolean flag). -Special care should be taken when the subroutine clobbers the X register. -If it does, X must be saved before and restored after the call. - -**Normal user defined subroutines:** -Arguments and result values are passed via global variables stored in memory -*These are not allocated on a stack* so it is not possible to create recursive calls! -The result value(s) of a subroutine are returned on the evaluation stack, -to make it possible to use subroutines in expressions. +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. IRQ Handling diff --git a/examples/test.p8 b/examples/test.p8 index 10d7f9ee6..376bef56e 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,7 +1,7 @@ %import textio %import diskio -;%import floats -;%import graphics +%import floats +%import graphics %zeropage basicsafe %import test_stack %option no_sysinit @@ -9,11 +9,6 @@ main { sub start () { - ubyte qq - void c64.CHKIN(3) - qq++ - qq=c64.CHKIN(3) - qq=c64.OPEN() ; TODO DO NOT REMOVE SECOND ASSIGNMENT IF ITS NOT A SIMPLE VALUE - test_stack.test() + txt.print("hello\n") } }