This commit is contained in:
Irmen de Jong 2021-04-04 12:55:29 +02:00
parent 38ccbac97c
commit 49036abbaf
5 changed files with 50 additions and 91 deletions

View File

@ -24,13 +24,14 @@ What does Prog8 provide?
------------------------
- reduction of source code length over raw assembly
- fast execution speed due to compilation to native assembly code. It's possible to write certain raster interrupt 'demoscene' effects purely in Prog8.
- modularity, symbol scoping, subroutines
- various data types other than just bytes (16-bit words, floats, strings)
- automatic variable allocations, automatic string and array variables and string sharing
- automatic static variable allocations, automatic string and array variables and string sharing
- subroutines with input parameters and result values
- high-level program optimizations
- small program boilerplate/compilersupport overhead
- sane variable initialization, programs can be restarted again just fine after exiting to basic
- Programs can be run multiple times without reloading because of automatic variable (re)initializations.
- conditional branches
- floating point operations (requires the C64 Basic ROM routines for this)
- 'when' statement to provide a concise jump table alternative to if/elseif chains
@ -38,8 +39,6 @@ What does Prog8 provide?
- many built-in functions such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``sort`` and ``reverse``
- various powerful built-in libraries to do I/O, number conversions, graphics and more
- 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
- variables are allocated statically
- 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, and provides them also on the C64.
- encode strings and characters into petscii or screencodes as desired (C64/Cx16)

View File

@ -42,8 +42,9 @@ Language features
-----------------
- It is a cross-compiler running on modern machines (Linux, MacOS, Windows, ...)
The generated output is a machine code program runnable on actual 8-bit 6502 hardware.
- Provide a very convenient edit/compile/run cycle by being able to directly launch
It generates a machine code program runnable on actual 8-bit 6502 hardware.
- Fast execution speed due to compilation to native assembly code. It's possible to write certain raster interrupt 'demoscene' effects purely in Prog8.
- Provides a very convenient edit/compile/run cycle by being able to directly launch
the compiled program in an emulator and provide debugging information to this emulator.
- Based on simple and familiar imperative structured programming (it looks like a mix of C and Python)
- Modular programming and scoping via modules, code blocks, and subroutines.
@ -57,6 +58,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``, ``sort`` and ``reverse``
- Programs can be run multiple times without reloading because of automatic variable (re)initializations.
- Supports the sixteen 'virtual' 16-bit registers R0 .. R15 from the Commander X16, also on the C64.
- If you only use standard kernal and prog8 library routines, it is possible to compile the *exact same program* for both machines (just change the compiler target flag)!
@ -162,11 +164,11 @@ If you're targeting the CommanderX16 instead, there's the `x16emu <https://githu
:maxdepth: 2
:caption: Contents of this manual:
targetsystem.rst
building.rst
programming.rst
syntaxreference.rst
libraries.rst
targetsystem.rst
technical.rst
todo.rst

View File

@ -896,40 +896,3 @@ of the library modules to see what's there.
(They can be found in the compiler/res directory)
The example programs also use a small set of the library routines, you can study
their source code to see how they might be used.
The 6502 CPU's X-register: off-limits
-------------------------------------
Prog8 uses the cpu's X-register as a pointer in its internal expression evaluation stack.
When only writing code in Prog8, this is taken care of behind the scenes for you by the compiler.
However when you are including or linking with assembly routines or kernal/ROM calls that *do*
use the X register (either clobbering it internally, or using it as a parameter, or return value register),
those calls will destroy Prog8's stack pointer and this will result in invalid calculations.
You should avoid using the X register in your assembly code, or take preparations.
If you make sure that the value of the X register is preserved before calling a routine
that uses it, and restored when the routine is done, you'll be ok.
Routines that return a value in the X register can be called from Prog8 but the return value is
inaccessible unless you write a short piece of inline assembly code to deal with it yourself, such as::
ubyte returnvalue
%asm {{
stx P8ZP_SCRATCH_REG ; use 'phx/plx' if using 65c02 cpu
ldx #10
jsr routine_using_x
stx returnvalue
ldx P8ZP_SCRATCH_REG
}}
; now use 'returnvalue' variable
Prog8 also provides some help to deal with this:
- you should use a ``clobbers(X)`` specification for asmsub routines that modify the X register; the compiler will preserve it for you automatically when such a routine is called
- the ``sys.rsave()`` and ``sys.rrestore()`` routines can preserve and restore *all* registers (but this is very slow and overkill if you only need to save X)

View File

@ -1,6 +1,6 @@
===============
Technical stuff
===============
=================
Technical details
=================
All variables are static in memory
----------------------------------
@ -83,3 +83,37 @@ Some builtin functions have a fully custom implementation.
The compiler will warn about routines that are called and that return a value, if you're not
doing something with that returnvalue. This can be on purpuse if you're simply not interested in it.
Use the ``void`` keyword in front of the subroutine call to get rid of the warning in that case.
The 6502 CPU's X-register: off-limits
-------------------------------------
Prog8 uses the cpu's X-register as a pointer in its internal expression evaluation stack.
When only writing code in Prog8, this is taken care of behind the scenes for you by the compiler.
However when you are including or linking with assembly routines or kernal/ROM calls that *do*
use the X register (either clobbering it internally, or using it as a parameter, or return value register),
those calls will destroy Prog8's stack pointer and this will result in invalid calculations.
You should avoid using the X register in your assembly code, or take preparations.
If you make sure that the value of the X register is preserved before calling a routine
that uses it, and restored when the routine is done, you'll be ok.
Routines that return a value in the X register can be called from Prog8 but the return value is
inaccessible unless you write a short piece of inline assembly code to deal with it yourself, such as::
ubyte returnvalue
%asm {{
stx P8ZP_SCRATCH_REG ; use 'phx/plx' if using 65c02 cpu
ldx #10
jsr routine_using_x
stx returnvalue
ldx P8ZP_SCRATCH_REG
}}
; now use 'returnvalue' variable
Prog8 also provides some help to deal with this:
- you should use a ``clobbers(X)`` specification for asmsub routines that modify the X register; the compiler will preserve it for you automatically when such a routine is called
- the ``sys.rsave()`` and ``sys.rrestore()`` routines can preserve and restore *all* registers (but this is very slow and overkill if you only need to save X)

View File

@ -1,53 +1,14 @@
%import textio
%zeropage basicsafe
%option no_sysinit
main {
sub start() {
ubyte thing = otherblock.othersub()
thing = otherblock.othersub()
thing = otherblock.othersub()
thing = otherblock.othersub()
thing = otherblock.othersub()
thing = otherblock.othersub()
thing = otherblock.othersub()
thing = otherblock.othersub()
txt.print_ub(thing) ; should print 41!
; str filename = "titlescreen.bin"
; ubyte success = cx16.vload(filename, 8, 0, $0000)
; if success {
; txt.print("load ok")
; cx16.VERA_DC_HSCALE = 64
; cx16.VERA_DC_VSCALE = 64
; cx16.VERA_L1_CONFIG = %00011111 ; 256c bitmap mode
; cx16.VERA_L1_MAPBASE = 0
; cx16.VERA_L1_TILEBASE = 0
; } else {
; txt.print("load fail")
; }
}
}
block3 {
ubyte returnvalue=10
inline sub thing()->ubyte {
return returnvalue
}
}
otherblock {
ubyte othervar=20
ubyte calcparam=10
sub calc(ubyte zz) -> ubyte {
return zz+1+block3.thing()
}
inline sub othersub() -> ubyte {
return calc(calcparam)+othervar
ubyte[6] array = [ 1,2,3,
; Comment here
4,5,6 ]
txt.print_ub(len(array))
}
}