update docs

This commit is contained in:
Irmen de Jong 2020-12-22 13:29:16 +01:00
parent d6444bba66
commit 44b8291540
6 changed files with 29 additions and 29 deletions

View File

@ -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:*

View File

@ -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 <https://sourceforge.net/projects/tass64/>`_ - 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 <https://github.com/irmen/64tass/releases>`_ of this project.
A recent precompiled .exe (only for Windows) can be obtained from my `clone <https://github.com/irmen/64tass/releases>`_ 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.

View File

@ -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

View File

@ -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 ``@ <register>`` 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
-----------

View File

@ -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

View File

@ -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")
}
}