diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 000000000..51f6d408e
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/source/index.rst b/docs/source/index.rst
index bca4071cd..aacd6e529 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -166,12 +166,12 @@ Detailed instructions on how to obtain a version of the compiler are in :ref:`bu
Required additional tools
-------------------------
-`64tass `_ - cross assembler. Install this on your shell path.
-It's very easy to compile yourself.
-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.*
-If you are on a Debian based Linux, there's a "64tass" package in the repositories. It's a bit old but seems to work.
-It's possible to use these older versions of 64tass, but it is likely that the automatic VICE breakpoints won't work with them though.
+`64tass `_ - cross assembler. Install this program somewhere on your shell's search path.
+It's easy to compile yourself, but a recent precompiled .exe (only for Windows) can be obtained from
+`the files section `_ in the official project on sourceforge.
+*You need at least version 1.56 of this assembler.*
+If you are on a Debian based Linux, there's a "64tass" package in the repositories, which is a bit old, but it seems to work.
+It's possible to use old versions of 64tass, but it is likely that certain things will break.
A **Java runtime (jre or jdk), version 11 or newer** is required to run the prog8 compiler itself.
If you're scared of Oracle's licensing terms, most Linux distributions ship OpenJDK or similar in their packages repository instead.
diff --git a/docs/source/memorymap.odg b/docs/source/memorymap.odg
index fe9fe7af2..a2c778555 100644
Binary files a/docs/source/memorymap.odg and b/docs/source/memorymap.odg differ
diff --git a/docs/source/memorymap.svg b/docs/source/memorymap.svg
index bfa5992d6..0b602dba3 100644
--- a/docs/source/memorymap.svg
+++ b/docs/source/memorymap.svg
@@ -1,12 +1,12 @@
-
+
-
+
-
+
@@ -42,11 +42,9 @@
-
-
@@ -54,7 +52,6 @@
-
@@ -71,24 +68,17 @@
-
-
-
-
-
-
-
@@ -96,38 +86,14 @@
-
-
-
-
+
+
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -135,29 +101,40 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -204,292 +181,245 @@
-
-
- Prog8 defaults on C64
-
- Commodore 64
-
- Memory
-
- Commander X16
-
- Prog8 defaults on X16
-
-
- Kernal ROM
-
- $F000
-
- -
-
- $FFFF
-
- Kernal ROM (banked, max 32)
-
-
-
-
- $E000
-
- -
-
- $EFFF
-
-
-
-
- I/O area
-
- $D000
-
- -
-
- $DFFF
-
-
-
- $CF00-$CFFF: expression eval. stack $CF00-$CF20: CX16 “registers” R0-R15 $C000-$CEFF: free to use
-
- RAM
-
- $C000
-
- -
-
- $CFFF
-
-
-
-
- Basic ROM
-
- $B000
-
- -
-
- $BFFF
-
- Hi RAM (banked, max 256)
-
-
-
-
- $A000
-
- -
-
- $AFFF
-
-
-
-
- RAM
-
- $9F00
-
- -
-
- $9FFF
-
- I/O area
-
-
-
-
- $9000
-
- -
-
- $9EFF
-
- RAM
-
-
-
-
- $8000
-
- -
-
- $8FFF
-
-
-
-
-
- $7000
-
- -
-
- $7FFF
-
-
-
-
-
- $6000
-
- -
-
- $6FFF
-
-
-
-
-
- $5000
-
- -
-
- $5FFF
-
-
-
-
-
- $4000
-
- -
-
- $4FFF
-
-
-
-
-
- $3000
-
- -
-
- $3FFF
-
-
-
-
-
- $2000
-
- -
-
- $2FFF
-
-
-
-
-
- $1000
-
- -
-
- $1FFF
-
-
-
- start of free Basic program memory
-
-
- $0800
-
- -
-
- $0FFF
-
-
- start of free Basic program memory
-
-
- Text screen
-
- $0400
-
- -
-
- $07FF
-
- “ Golden” RAM
-
- $0700-$07FF: expression eval. stack $0400-$06FF: free to use
-
-
- Kernal variables
-
- $0300
-
- -
-
- $03FF
-
- Kernal variables
-
-
-
-
- $0200
-
- -
-
- $02FF
-
-
-
-
- CPU stack
-
- $0100
-
- -
-
- $01FF
-
- CPU stack
-
-
- *special
-
- Zero Page
-
- $0000
-
- -
-
- $00FF
-
- Zero Page
-
- *special
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ Memory
+
+ Commander X16
+
+ Commodore 64
+
+ $F000
+
+ -
+
+ $FFFF
+
+ Kernal ROM (banked, max 32)
+
+ Kernal ROM
+
+ $E000
+
+ -
+
+ $EFFF
+
+
+
+ $D000
+
+ -
+
+ $DFFF
+
+
+ I/O area
+
+ $C000
+
+ -
+
+ $CFFF
+
+
+ RAM « see footnotes »
+
+ $B000
+
+ -
+
+ $BFFF
+
+ Hi RAM (banked, max 256)
+
+ Basic ROM
+
+ $A000
+
+ -
+
+ $AFFF
+
+
+
+ $9F00
+
+ -
+
+ $9FFF
+
+ I/O area
+
+ Basic RAM
+
+ $9000
+
+ -
+
+ $9EFF
+
+ Basic RAM
+
+
+ $8000
+
+ -
+
+ $8FFF
+
+
+
+ $7000
+
+ -
+
+ $7FFF
+
+
+
+ $6000
+
+ -
+
+ $6FFF
+
+
+
+ $5000
+
+ -
+
+ $5FFF
+
+
+
+ $4000
+
+ -
+
+ $4FFF
+
+
+
+ $3000
+
+ -
+
+ $3FFF
+
+
+
+ $2000
+
+ -
+
+ $2FFF
+
+
+
+ $1000
+
+ -
+
+ $1FFF
+
+
+
+ $0800
+
+ -
+
+ $0FFF
+
+ start of Basic program
+
+ start of Basic program
+
+ $0400
+
+ -
+
+ $07FF
+
+ “ Golden” RAM « see footnotes »
+
+ Text screen
+
+ $0300
+
+ -
+
+ $03FF
+
+ Kernal variables
+
+ Kernal variables
+
+ $0200
+
+ -
+
+ $02FF
+
+
+
+ $0100
+
+ -
+
+ $01FF
+
+ CPU stack
+
+ CPU stack
+
+ $0000
+
+ -
+
+ $00FF
+
+ Zero Page « see footnotes »
+
+ Zero Page « see footnotes »
+
+ Memory
+
+ Commander X16
+
+ Commodore 64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/source/programming.rst b/docs/source/programming.rst
index de68512dd..3f3a7a746 100644
--- a/docs/source/programming.rst
+++ b/docs/source/programming.rst
@@ -763,35 +763,35 @@ You can use them in expressions and the compiler will evaluate them at compile-t
Math
^^^^
-abs(x)
+abs (x)
Absolute value of an integer. Value returned is an unsigned word.
For floating point numbers, use ``floats.fabs()`` instead.
-sgn(x)
+sgn (x)
Get the sign of the value. Result is -1, 0 or 1 (negative, zero, positive).
-sqrt16(w)
+sqrt16 (w)
16 bit unsigned integer Square root. Result is unsigned byte.
To do the reverse, squaring an integer, just write ``x*x``.
-divmod(number, divident, division, remainder)
+divmod (number, divident, division, remainder)
Performs division and remainder calculation in a single call. This is faster than using separate '/' and '%' calculations.
All values are ubytes. The last two arguments must be ubyte variables to receive the division and remainder results, respectively.
-divmodw(number, divident, division, remainder)
+divmodw (number, divident, division, remainder)
Same as divmod, but for uwords.
Array operations
^^^^^^^^^^^^^^^^
-any(x)
+any (x)
1 ('true') if any of the values in the array value x is 'true' (not zero), else 0 ('false')
-all(x)
+all (x)
1 ('true') if all of the values in the array value x are 'true' (not zero), else 0 ('false')
-len(x)
+len (x)
Number of values in the array value x, or the number of characters in a string (excluding the 0-byte).
Note: this can be different from the number of *bytes* in memory if the datatype isn't a byte. See sizeof().
Note: lengths of strings and arrays are determined at compile-time! If your program modifies the actual
@@ -799,11 +799,11 @@ len(x)
(use the ``string.length`` routine if you want to dynamically determine the length by counting to the
first 0-byte)
-reverse(array)
+reverse (array)
Reverse the values in the array (in-place).
Can be used after sort() to sort an array in descending order.
-sort(array)
+sort (array)
Sort the array in ascending order (in-place)
Supported are arrays of bytes or word values.
Sorting a floating-point array is not supported right now, as a general sorting routine for this will
@@ -816,18 +816,18 @@ sort(array)
Miscellaneous
^^^^^^^^^^^^^
-cmp(x,y)
+cmp (x,y)
Compare the integer value x to integer value y. Doesn't return a value or boolean result, only sets the processor's status bits!
You can use a conditional jumps (``if_cc`` etcetera) to act on this.
Normally you should just use a comparison expression (``x < y``)
-lsb(x)
+lsb (x)
Get the least significant byte of the word x. Equivalent to the cast "x as ubyte".
-msb(x)
+msb (x)
Get the most significant byte of the word x.
-mkword(msb, lsb)
+mkword (msb, lsb)
Efficiently create a word value from two bytes (the msb and the lsb). Avoids multiplication and shifting.
So mkword($80, $22) results in $8022.
@@ -836,36 +836,36 @@ mkword(msb, lsb)
Don't get confused by how the system actually stores this 16-bit word value in memory (which is
in little-endian format, so lsb first then msb)
-peek(address)
+peek (address)
same as @(address) - reads the byte at the given address in memory.
-peekw(address)
+peekw (address)
reads the word value at the given address in memory. Word is read as usual little-endian lsb/msb byte order.
-poke(address, value)
+poke (address, value)
same as @(address)=value - writes the byte value at the given address in memory.
-pokew(address, value)
+pokew (address, value)
writes the word value at the given address in memory, in usual little-endian lsb/msb byte order.
-pokemon(address, value)
+pokemon (address, value)
Doesn't do anything useful. Also doesn't have anything to do with a certain video game.
-push(value)
+push (value)
pushes a byte value on the CPU hardware stack. Low-level function that should normally not be used.
-pushw(value)
+pushw (value)
pushes a 16-bit word value on the CPU hardware stack. Low-level function that should normally not be used.
-pop(variable)
+pop (variable)
pops a byte value off the CPU hardware stack into the given variable. Only variables can be used.
Low-level function that should normally not be used.
-popw(value)
+popw (value)
pops a 16-bit word value off the CPU hardware stack into the given variable. Only variables can be used.
Low-level function that should normally not be used.
-rol(x)
+rol (x)
Rotate the bits in x (byte or word) one position to the left.
This uses the CPU's rotate semantics: bit 0 will be set to the current value of the Carry flag,
while the highest bit will become the new Carry flag value.
@@ -873,13 +873,13 @@ rol(x)
Modifies in-place, doesn't return a value (so can't be used in an expression).
You can rol a memory location directly by using the direct memory access syntax, so like ``rol(@($5000))``
-rol2(x)
+rol2 (x)
Like ``rol`` but now as 8-bit or 16-bit rotation.
It uses some extra logic to not consider the carry flag as extra rotation bit.
Modifies in-place, doesn't return a value (so can't be used in an expression).
You can rol a memory location directly by using the direct memory access syntax, so like ``rol2(@($5000))``
-ror(x)
+ror (x)
Rotate the bits in x (byte or word) one position to the right.
This uses the CPU's rotate semantics: the highest bit will be set to the current value of the Carry flag,
while bit 0 will become the new Carry flag value.
@@ -887,19 +887,19 @@ ror(x)
Modifies in-place, doesn't return a value (so can't be used in an expression).
You can ror a memory location directly by using the direct memory access syntax, so like ``ror(@($5000))``
-ror2(x)
+ror2 (x)
Like ``ror`` but now as 8-bit or 16-bit rotation.
It uses some extra logic to not consider the carry flag as extra rotation bit.
Modifies in-place, doesn't return a value (so can't be used in an expression).
You can ror a memory location directly by using the direct memory access syntax, so like ``ror2(@($5000))``
-sizeof(name)
+sizeof (name)
Number of bytes that the object 'name' occupies in memory. This is a constant determined by the data type of
the object. For instance, for a variable of type uword, the sizeof is 2.
For an 10 element array of floats, it is 50 (on the C64, where a float is 5 bytes).
Note: usually you will be interested in the number of elements in an array, use len() for that.
-memory(name, size, alignment)
+memory (name, size, alignment)
Returns the address of the first location of a statically "reserved" block of memory of the given size in bytes,
with the given name. The block is uninitialized memory, it is *not* set to zero!
If you specify an alignment value >1, it means the block of memory will
@@ -914,7 +914,7 @@ memory(name, size, alignment)
The return value is just a simple uword address so it cannot be used as an array in your program.
You can only treat it as a pointer or use it in inline assembly.
-callfar(bank, address, argumentword) -> uword ; NOTE: specific to cx16 target for now
+callfar (bank, address, argumentword) -> uword ; NOTE: specific to cx16 target for now
Calls an assembly routine in another bank on the Commander X16 (using its ``jsrfar`` routine)
Be aware that ram OR rom bank may be changed depending on the address it jumps to!
The argumentword will be loaded into the A+Y registers before calling the routine.
@@ -922,7 +922,7 @@ callfar(bank, address, argumentword) -> uword ; NOTE: specific to cx16 targe
NOTE: this routine is very inefficient, so don't use it to call often. Set the bank yourself
or even write a custom tailored trampoline routine if you need to.
-syscall(callnr), syscall1(callnr, arg), syscall2(callnr, arg1, arg2), syscall3(callnr, arg1, arg2, arg3)
+syscall (callnr), syscall1 (callnr, arg), syscall2 (callnr, arg1, arg2), syscall3 (callnr, arg1, arg2, arg3)
Functions for doing a system call on targets that support this. Currently no actual target
uses this though except, possibly, the experimental code generation target!
The regular 6502 based compiler targets just use a subroutine call to asmsub Kernal routines at
diff --git a/docs/source/targetsystem.rst b/docs/source/targetsystem.rst
index 31a5bd365..050e411e0 100644
--- a/docs/source/targetsystem.rst
+++ b/docs/source/targetsystem.rst
@@ -28,18 +28,12 @@ This chapter explains some relevant system details of the c64 and cx16 machines.
Memory Model
============
-(Work in Progress) Memory Map Diagram for C64 and X16
-
-.. image:: memorymap.svg
-
-
-Physical address space layout
------------------------------
+Generic 6502 Physical address space layout
+------------------------------------------
The 6502 CPU can address 64 kilobyte of memory.
Most of the 64 kilobyte address space can be used by Prog8 programs.
-This is a hard limit: there is no built-in support for RAM expansions or bank switching.
-
+This is a hard limit: there is no support for RAM expansions or bank switching built natively into the language.
====================== ================== ========
memory area type note
@@ -47,54 +41,54 @@ memory area type note
``$00``--``$ff`` zeropage contains many sensitive system variables
``$100``--``$1ff`` Hardware stack used by the CPU, normally not accessed directly
``$0200``--``$ffff`` Free RAM or ROM free to use memory area, often a mix of RAM and ROM
+ depending on the specific computer system
====================== ================== ========
-A few of these memory addresses are reserved and cannot be used for arbitrary data.
-They have a special hardware function, or are reserved for internal use in the
-code generated by the compiler:
+Memory map for the C64 and the X16
+----------------------------------
-================== =======================
-reserved address in use for
-================== =======================
-``$00`` data direction (CPU hw)
-``$01`` bank select (CPU hw)
-``$02`` internal scratch variable
-``$03`` internal scratch variable
-``$fb - $fc`` internal scratch variable
-``$fd - $fe`` internal scratch variable
-``$fffa - $fffb`` NMI vector (CPU hw)
-``$fffc - $fffd`` RESET vector (CPU hw)
-``$fffe - $ffff`` IRQ vector (CPU hw)
-================== =======================
+This is the default memory map of the 64 Kb addressable memory for those two systems.
+Both systems have ways to alter the memory map and/or to switch memory banks, but that is not shown here.
-The actual machine will often have many other special addresses as well,
-For example, the Commodore 64 has:
+.. image:: memorymap.svg
-- ROMs installed in the machine: BASIC, Kernal and character roms. Occupying ``$a000``--``$bfff`` and ``$e000``--``$ffff``.
-- memory-mapped I/O registers, for the video and sound chips, and the CIA's. Occupying ``$d000``--``$dfff``.
-- RAM areas that are used for screen graphics and sprite data: usually at ``$0400``--``$07ff``.
+Footnotes for the Commander X16
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+*Golden Ram $0400 - $07FF*
+ *reserved:* $0700 - $07FF (expression evaluation stack)
-Prog8 programs can access all of those special memory locations but it will have a special meaning.
+ *free to use:* $0400 - $06FF
+
+*Zero Page $0000 - $00FF*
+ $00 and $01 are hardwired as Rom and Ram banking registers.
+
+ $02 - $21 are the 16 virtual cx16 registers R0-R15.
+
+ $22 - $7F are free to use, and Prog8 utilizes this to put variables in automatically.
+
+ The top half of the ZP ($80-$FF) is reserved for use by the Kernal and Basic in normal operation.
+ Zero page use by Prog8 can be manipulated with the ``%zeropage`` directive, various options
+ may free up more locations for use by Prog8.
-.. _zeropage:
+Footnotes for the Commodore 64
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Zeropage ("ZP")
----------------
+*RAM $C000-$CFFF*
+ *reserved:* $CF00 - $CFFF (expression evaluation stack)
+ *this includes:* $CF00 - $CF20 for the 16 virtual cx16 registers R0-R15
-The zeropage memory block ``$02``--``$ff`` can be regarded as 254 CPU 'registers', because
-they take less clock cycles to access and need fewer instruction bytes than accessing other memory locations outside of the ZP.
-Theoretically they can all be used in a program, with the following limitations:
+ *free to use:* $C000 - $CEFF
-- several addresses (``$02``, ``$03``, ``$fb - $fc``, ``$fd - $fe``) are reserved for internal use
-- most other addresses will already be in use by the machine's operating system or Kernal,
- and overwriting them will probably crash the machine. It is possible to use all of these
- yourself, but only if the program takes over the entire system (and seizes control from the regular Kernal).
- This means it can no longer use (most) BASIC and Kernal routines from ROM.
-- it's more convenient and safe to let the compiler allocate these addresses for you and just
- use symbolic names in the program code.
+*Zero Page $0000 - $00FF*
+ Consider the full zero page to be reserved for use by the Kernal and Basic in normal operation.
+ Zero page use by Prog8 can be manipulated with the ``%zeropage`` directive, various options
+ may free up more locations for use by Prog8.
+
+Zero page usage by the Prog8 compiler
+-------------------------------------
Prog8 knows what addresses are safe to use in the various ZP handling configurations.
It will use the free ZP addresses to place its ZP variables in,
until they're all used up. If instructed to output a program that takes over the entire
diff --git a/gradle.properties b/gradle.properties
index 7c76c34d4..9fbf0d876 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -4,4 +4,4 @@ org.gradle.parallel=true
org.gradle.daemon=true
kotlin.code.style=official
javaVersion=11
-kotlinVersion=1.8.10
+kotlinVersion=1.8.20