mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
update docs
This commit is contained in:
parent
d6444bba66
commit
44b8291540
@ -38,6 +38,7 @@ What does Prog8 provide?
|
|||||||
- convenience abstractions for low level aspects such as ZeroPage handling, program startup, explicit memory addresses
|
- 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
|
- fast execution speed due to compilation to native assembly code
|
||||||
- inline assembly allows you to have full control when every cycle or byte matters
|
- 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:*
|
*Rapid edit-compile-run-debug cycle:*
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ Language features
|
|||||||
- Variable data types include signed and unsigned bytes and words, arrays, strings and floats.
|
- 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.
|
- 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)
|
- 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)!
|
- 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.
|
`64tass <https://sourceforge.net/projects/tass64/>`_ - cross assembler. Install this on your shell path.
|
||||||
It's very easy to compile yourself.
|
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.*
|
*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.
|
It's possible to use older versions, but it is very likely that the automatic Vice breakpoints won't work with them.
|
||||||
|
|
||||||
|
@ -888,9 +888,11 @@ rsave()
|
|||||||
Note: it's not needed to rsave() before an asm subroutine that clobbers the X register
|
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).
|
(which is used as the internal evaluation stack pointer).
|
||||||
The compiler will take care of this situation automatically.
|
The compiler will take care of this situation automatically.
|
||||||
|
Note: the 16 bit 'virtual' registers of the Commander X16 are not saved.
|
||||||
|
|
||||||
rrestore()
|
rrestore()
|
||||||
Restores the CPU registers and the status flags from previously saved values.
|
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()
|
read_flags()
|
||||||
Returns the current value of the CPU status register.
|
Returns the current value of the CPU status register.
|
||||||
@ -914,6 +916,8 @@ swap(x, y)
|
|||||||
|
|
||||||
target()
|
target()
|
||||||
Returns byte value designating the target machine that the program was compiled for.
|
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:
|
The following return values are currently defined:
|
||||||
|
|
||||||
- 16 = compiled for CommanderX16 with 65C02 CPU
|
- 16 = compiled for CommanderX16 with 65C02 CPU
|
||||||
|
@ -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
|
**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.
|
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
|
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 use a conditional branch statement for that.
|
after the call* so you can often use a conditional branch statement for that. But the latter is tricky,
|
||||||
Note that this makes no sense inside an expression, so the compiler will still give an error for that.
|
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
|
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.
|
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
|
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.
|
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.
|
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::
|
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 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
|
Expressions
|
||||||
-----------
|
-----------
|
||||||
|
@ -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()``),
|
builtin functions (``set_carry()``, ``clear_carry()``, ``set_irqd()``, ``clear_irqd()``),
|
||||||
and read via the ``read_flags()`` function.
|
and read via the ``read_flags()`` function.
|
||||||
|
|
||||||
|
The 16 'virtual' 16-bit registers that are defined on the Commander X16 machine are not real hardware
|
||||||
Subroutine Calling Conventions
|
registers and are just 16 memory-mapped word values that you *can* access directly.
|
||||||
------------------------------
|
|
||||||
|
|
||||||
**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.
|
|
||||||
|
|
||||||
|
|
||||||
IRQ Handling
|
IRQ Handling
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import diskio
|
%import diskio
|
||||||
;%import floats
|
%import floats
|
||||||
;%import graphics
|
%import graphics
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%import test_stack
|
%import test_stack
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
@ -9,11 +9,6 @@
|
|||||||
main {
|
main {
|
||||||
|
|
||||||
sub start () {
|
sub start () {
|
||||||
ubyte qq
|
txt.print("hello\n")
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user