sort the library routines better, updated result of crc32 benchmark

This commit is contained in:
Irmen de Jong
2025-11-01 21:44:41 +01:00
parent 4d3f0ec223
commit e1ccef4e89
4 changed files with 385 additions and 312 deletions
+4 -1
View File
@@ -34,8 +34,11 @@ How to get it/build it
- you can also compile it yourself from source. [Instructions here](https://prog8.readthedocs.io/en/latest/compiling.html).
Note that if you are not using *gradle* to build it, you might have to perform some manual
tasks once to make it compile fully. These are explained in the linked instructions.
- Alternatively, you can also install the compiler as a package on some linux distros:
- Alternatively, you can also install the compiler as a package on some linux distros (which will take care of dependencies automatically):
- Arch (via AUR): [`prog8`](https://aur.archlinux.org/packages/prog8)
- Finally there's a Homebrew recipe for Mac OS (but also for Linux, and WSL2 on Windows, this also takes care of dependencies automatically):
``brew install prog8``
Community
---------
Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

+381 -308
View File
@@ -44,15 +44,21 @@ Math
abs (x)
Returns the absolute value of a number (integer or floating point).
min (x, y)
Returns the smallest of x and y. Supported for integer types only, for floats use ``floats.minf()`` instead.
clamp (value, minimum, maximum)
Returns the value restricted to the given minimum and maximum.
Supported for integer types only, for floats use ``floats.clampf()`` instead.
divmod (dividend, divisor, quotient, remainder)
Performs division only once and returns both quotient and remainder in a single call, where using '/' and '%' separately
would perform the division operation twice.
All values are ubytes or all are uwords.
The last two arguments must be variables to receive the quotient and remainder results, respectively.
max (x, y)
Returns the largest of x and y. Supported for integer types only, for floats use ``floats.maxf()`` instead.
clamp (value, minimum, maximum)
Returns the value restricted to the given minimum and maximum.
Supported for integer types only, for floats use ``floats.clampf()`` instead.
min (x, y)
Returns the smallest of x and y. Supported for integer types only, for floats use ``floats.minf()`` instead.
sgn (x)
Get the sign of the value (integer or floating point).
@@ -63,12 +69,6 @@ sqrt (x)
Accepts unsigned integer (result is ubyte), long (result is uword, but this may not be implemented on all targets), and floating point numbers.
To do the reverse - squaring a number - just write ``x*x``.
divmod (dividend, divisor, quotient, remainder)
Performs division only once and returns both quotient and remainder in a single call, where using '/' and '%' separately
would perform the division operation twice.
All values are ubytes or all are uwords.
The last two arguments must be variables to receive the quotient and remainder results, respectively.
Array operations
^^^^^^^^^^^^^^^^
@@ -280,8 +280,13 @@ Grouped per compilation target.
* `pet32 <_static/symboldumps/skeletons-pet32.txt>`_
* `virtual <_static/symboldumps/skeletons-virtual.txt>`_
Library modules
---------------
bcd
---
^^^
Decimal addition and subtraction routines, so for example $0987 + $1111 = $2098 (rather than the usual hex outcome $1a98)
Utilizes the BCD mode of the CPU (note: not all 6502 variants support this mode).
This mode is useful for example for counting decimal score in a game, to avoid costly conversion to a decimal display string:
@@ -302,7 +307,8 @@ Available routines:
bmx (cx16 only)
----------------
^^^^^^^^^^^^^^^^
Routines to load and save "BMX" files, the CommanderX16 bitmap file format:
`BMX file format specification <https://cx16forum.com/forum/viewtopic.php?t=6945>`_
Only the *uncompressed* bitmaps variant is supported in this library for now.
@@ -316,7 +322,8 @@ There's also the "showbmx" example to look at.
buffers (experimental)
----------------------
^^^^^^^^^^^^^^^^^^^^^^
A small library providing a 8 KB stack, an 8 KB ringbuffer, and a fast 256 bytes ringbuffer.
API is experimental and may change or disappear in a future version.
Stack is a LIFO container, ringbuffers are FIFO containers.
@@ -328,7 +335,8 @@ to see what's in there. Note that the init() routines have that extra bank param
compression (slightly experimental)
-----------------------------------
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Routines for data compression and decompression. Currently only the 'ByteRun1' aka 'PackBits' RLE encoding
is available. This is the compression that was also used in Amiga IFF images and in old MacPaint images.
API is slightly experimental and may change in a future version.
@@ -407,7 +415,8 @@ API is slightly experimental and may change in a future version.
conv
----
^^^^
Routines to convert strings to numbers or vice versa.
- numbers to strings, in various formats (binary, hex, decimal)
@@ -419,7 +428,8 @@ to see what's in there.
coroutines
----------
^^^^^^^^^^
Provides a system to make cooperative multitasking programs via coroutines.
A 'coroutine' is a subroutine whose execution you can pause and resume.
This library handles the voodoo for you to switch between such coroutines transparently,
@@ -449,7 +459,8 @@ Here is a minimal example (if the library gets more stable, better docs will be
cx16
----
^^^^
This is available on *all targets*, it is always imported as part of syslib.
On the Commander X16 this module contains a *whole bunch* of things specific to that machine.
It's way too much to include here, you have to study the
@@ -476,7 +487,8 @@ On the other targets, it only contains the definition of the 16 memory-mapped vi
cx16logo
--------
^^^^^^^^
Just a fun module that contains the Commander X16 logo in PETSCII graphics
and allows you to print it anywhere on the screen.
@@ -487,7 +499,8 @@ and allows you to print it anywhere on the screen.
diskio
------
^^^^^^
Provides several routines that deal with disk drive I/O, such as:
- list files on disk, optionally filtering by a simple pattern with ? and *
@@ -536,7 +549,8 @@ to see what's in there. (Note: slight variations for different compiler targets)
emudbg (cx16 only)
-------------------
^^^^^^^^^^^^^^^^^^^
X16Emu Emulator debug routines, for Cx16 only.
Allows you to interface with the emulator's debug routines/registers.
There's stuff like ``is_emulator`` to detect if running in the emulator,
@@ -558,7 +572,7 @@ Information about the exposed debug registers is in the `emulator's documentatio
floats
------
^^^^^^
.. note::
Floating point support is only available on c64, cx16 and virtual targets for now.
@@ -583,6 +597,9 @@ Provides definitions for the ROM/Kernal subroutines and utility routines dealing
``ceil (x)``
Rounds the floating point up to an integer towards positive infinity.
``clampf (value, minimum, maximum)``
returns the value restricted to the given minimum and maximum.
``cos (x)``
Cosine.
@@ -598,6 +615,17 @@ Provides definitions for the ROM/Kernal subroutines and utility routines dealing
``floor (x)``
Rounds the floating point down to an integer towards minus infinity.
``interpolate(v, inputMin, inputMax, outputMin, outputMax)``
Interpolate a value v in interval [inputMin, inputMax] to output interval [outputMin, outputMax]
``lerp(v0, v1, t)``
Linear interpolation (LERP). Precise method, which guarantees v = v1 when t = 1.
Returns an interpolation between two inputs (v0, v1) for a parameter t in the closed unit interval [0.0, 1.0]
``lerp_fast(v0, v1, t)``
Linear interpolation (LERP). Imprecise (but faster) method, which does not guarantee v = v1 when t = 1
Teturns an interpolation between two inputs (v0, v1) for a parameter t in the closed unit interval [0.0, 1.0]
``ln (x)``
Natural logarithm (base e).
@@ -610,20 +638,24 @@ Provides definitions for the ROM/Kernal subroutines and utility routines dealing
``maxf (x, y)``
returns the largest of x and y.
``clampf (value, minimum, maximum)``
returns the value restricted to the given minimum and maximum.
``parse (stringvalue)``
Parses the string value as floating point number.
Warning: this routine may stop working on the Commander X16 when a new ROM version is released,
because it uses an internal BASIC routine. Then it will require a fix.
``print (x)``
Prints the floating point number x as a string.
There's no leading whitespace (unlike cbm BASIC when printing a floating point number)
``tostr (x)``
Converts the floating point number x to a string (returns address of the string buffer)
There's no leading whitespace.
``rad (x)``
Degrees to radians.
``rnd ()``
returns the next random float between 0.0 and 1.0 from the Pseudo RNG sequence.
``rndseed (seed)``
Sets a new seed for the float pseudo-RNG sequence. Use a negative non-zero number as seed value.
``round (x)``
Rounds the floating point to the closest integer.
@@ -636,31 +668,14 @@ Provides definitions for the ROM/Kernal subroutines and utility routines dealing
``tan (x)``
Tangent.
``rnd ()``
returns the next random float between 0.0 and 1.0 from the Pseudo RNG sequence.
``rndseed (seed)``
Sets a new seed for the float pseudo-RNG sequence. Use a negative non-zero number as seed value.
``parse (stringvalue)``
Parses the string value as floating point number.
Warning: this routine may stop working on the Commander X16 when a new ROM version is released,
because it uses an internal BASIC routine. Then it will require a fix.
``lerp(v0, v1, t)``
Linear interpolation (LERP). Precise method, which guarantees v = v1 when t = 1.
Returns an interpolation between two inputs (v0, v1) for a parameter t in the closed unit interval [0.0, 1.0]
``lerp_fast(v0, v1, t)``
Linear interpolation (LERP). Imprecise (but faster) method, which does not guarantee v = v1 when t = 1
Teturns an interpolation between two inputs (v0, v1) for a parameter t in the closed unit interval [0.0, 1.0]
``interpolate(v, inputMin, inputMax, outputMin, outputMax)``
Interpolate a value v in interval [inputMin, inputMax] to output interval [outputMin, outputMax]
``tostr (x)``
Converts the floating point number x to a string (returns address of the string buffer)
There's no leading whitespace.
gfx_lores and gfx_hires (cx16 only)
-----------------------------------
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Full-screen multicolor bitmap graphics routines, available on the X16 machine only.
- gfx_lores: optimized routines for 320x240 256 color bitmap graphics mode. Compatible with X16 screen mode 128.
@@ -679,7 +694,8 @@ They share the same routines.
graphics
--------
^^^^^^^^
Bitmap graphics routines:
- clearing the screen
@@ -695,18 +711,102 @@ to see what's in there. (Note: slight variations for different compiler targets)
math
----
^^^^
Low-level integer math routines (which you usually don't have to bother with directly, but they are used by the compiler internally).
Pseudo-Random number generators (byte and word).
Various 8-bit integer trig functions that use lookup tables to quickly calculate sine and cosines.
Usually a custom lookup table is the way to go if your application needs these,
but perhaps the provided ones can be of service too.
``log2 (ubyte v)``
Returns the 2-Log of the byte value v.
checksumming
''''''''''''
``log2w (uword v)``
Returns the 2-Log of the word value v.
``crc16 (uword data, uword length) -> uword``
Returns a CRC-16 (XMODEM) checksum over the given data buffer.
Note: on the Commander X16, there is a CRC-16/IBM-3740 routine in the kernal: cx16.memory_crc().
That one is faster, but yields different results.
``crc16_start() / crc16_update(ubyte value) / crc16_end() -> uword``
"streaming" crc16 calculation routines, when the data doesn't fit in a single buffer.
Tracks the crc16 checksum in cx16.r15! If your code uses that, it must save/restore it before calling this routine!
Call the start() routine first, feed it bytes with the update() routine, finalize with calling the end() routine which returns the crc16 value.
Note: after calling the crc16_end() routine you must start over.
``crc32 (uword data, uword length) -> long``
Calculates a CRC-32 (ISO-HDLC/PKZIP) checksum over the given data buffer.
The 32 bits result is returned as a long value. The routine clobbers R0/R1 and R12 through R15.
``crc32_start() / crc32_update(ubyte value) / crc32_end() / crc32_end_result()``
"streaming" crc32 calculation routines, when the data doesn't fit in a single buffer.
Tracks the crc32 checksum in cx16.r14 and cx16.r15! If your code uses these, it must save/restore them before calling this routine!
Call the start() routine first, feed it bytes with the update() routine, finalize with calling the end() routine that returns the result value as a long.
Instead of the normal end() routine you can also call crc32_end_result() which finalizes the calculation,
and actually returns the high and low words of the 32 bits result value as two return word values.
Note: after calling the crc32_end() or crc32_end_result() routine you must start over.
interpolation
'''''''''''''
``lerp(v0, v1, t)``
Linear interpolation routine for unsigned byte values.
Returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 255]
Guarantees v = v1 when t = 255. Also works if v0 > v1.
``lerpw(v0, v1, t)``
Linear interpolation routine for unsigned word values.
Returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 65535]
Guarantees v = v1 when t = 65535. Also works if v0 > v1.
Clobbers R15.
``interpolate(v, inputMin, inputMax, outputMin, outputMax)``
Interpolate a value v in interval [inputMin, inputMax] to output interval [outputMin, outputMax]
All values are unsigned bytes. Clobbers R15
(there is no version for word values because of lack of precision in the fixed point calculation there).
large multiplications
'''''''''''''''''''''
``mul32 (woord w1, word w2) -> long``
Returns the 32 bits signed long result of w1 * w2
``mul16_last_upper () -> uword``
Fetches the upper 16 bits of the previous 16*16 bit multiplication.
To avoid corrupting the result, it is best performed immediately after the multiplication.
Note: It is only for the regular 6502 cpu multiplication routine.
It does not work for the verafx multiplication routines on the Commander X16!
These have a different way to obtain the upper 16 bits of the result: just read cx16.r0.
**NOTE:** the result is only valid if the multiplication was done with uword arguments (or two positive word arguments).
As soon as a single negative word value (or both) was used in the multiplication, these upper 16 bits are not valid!
Suggestion (if you are on the Commander X16): use ``verafx.muls()`` to get a hardware accelerated 32 bit signed multiplication.
miscellaneous
'''''''''''''
``direction (ubyte x1, ubyte y1, ubyte x2, ubyte y2)``
From a pair of positive coordinates, calculate discrete direction between 0 and 23.
This is a heavily optimized routine (small and fast).
``direction_sc (byte x1, byte y1, byte x2, byte y2)``
From a pair of signed coordinates around the origin, calculate discrete direction between 0 and 23.
This is a heavily optimized routine (small and fast).
``direction_qd (ubyte quadrant, ubyte xdelta, ubyte ydelta)``
If you already know the quadrant and x/y deltas, calculate discrete direction between 0 and 23.
This is a heavily optimized routine (small and fast).
``diff (ubyte b1, ubyte b2) -> ubyte``
Returns the absolute difference, or distance, between the two byte values.
(This routine is more efficient than doing a compare and a subtract separately, or using abs)
``diffw (uword w1, uword w2) -> uword``
Returns the absolute difference, or distance, between the two word values.
(This routine is more efficient than doing a compare and a subtract separately, or using abs)
random numbers
''''''''''''''
``rnd ()``
Returns next random byte 0-255 from the pseudo-RNG sequence.
@@ -749,6 +849,15 @@ but perhaps the provided ones can be of service too.
Sets a new seed for the pseudo-RNG sequence of the ROM version of the RNG (both rnd and rndw). The seed consists of two words.
Do not use zeros for either of the seed values!
``log2 (ubyte v)``
Returns the 2-Log of the byte value v.
``log2w (uword v)``
Returns the 2-Log of the word value v.
trigonometry
''''''''''''
.. hint::
This is a graph showing the various ranges of values mentioned in the integer sine and cosine
routines that follow below. (Note that the x input value never corresponds to an exact *degree*
@@ -757,6 +866,10 @@ but perhaps the provided ones can be of service too.
.. image:: sinegraph.svg
``atan2 (ubyte x1, ubyte y1, ubyte x2, ubyte y2)``
Fast arctan routine that uses more memory because of large lookup tables.
Calculate the angle, in a 256-degree circle, between two points in the positive quadrant.
``sin8u (x)``
Fast 8-bit ubyte sine.
x = angle 0...2π scaled as 0...255. Result is unsigned, scaled as 0...255
@@ -793,86 +906,12 @@ but perhaps the provided ones can be of service too.
x = of angle 0...2π scaled as 0...179 (so each value increment is a 2° step). Result is signed, scaled as -127...127.
Input values 180...255 lie outside of the valid input interval and will yield a garbage result!
``atan2 (ubyte x1, ubyte y1, ubyte x2, ubyte y2)``
Fast arctan routine that uses more memory because of large lookup tables.
Calculate the angle, in a 256-degree circle, between two points in the positive quadrant.
``direction (ubyte x1, ubyte y1, ubyte x2, ubyte y2)``
From a pair of positive coordinates, calculate discrete direction between 0 and 23.
This is a heavily optimized routine (small and fast).
``direction_sc (byte x1, byte y1, byte x2, byte y2)``
From a pair of signed coordinates around the origin, calculate discrete direction between 0 and 23.
This is a heavily optimized routine (small and fast).
``direction_qd (ubyte quadrant, ubyte xdelta, ubyte ydelta)``
If you already know the quadrant and x/y deltas, calculate discrete direction between 0 and 23.
This is a heavily optimized routine (small and fast).
``diff (ubyte b1, ubyte b2) -> ubyte``
Returns the absolute difference, or distance, between the two byte values.
(This routine is more efficient than doing a compare and a subtract separately, or using abs)
``diffw (uword w1, uword w2) -> uword``
Returns the absolute difference, or distance, between the two word values.
(This routine is more efficient than doing a compare and a subtract separately, or using abs)
``mul32 (woord w1, word w2) -> long``
Returns the 32 bits signed long result of w1 * w2
``mul16_last_upper () -> uword``
Fetches the upper 16 bits of the previous 16*16 bit multiplication.
To avoid corrupting the result, it is best performed immediately after the multiplication.
Note: It is only for the regular 6502 cpu multiplication routine.
It does not work for the verafx multiplication routines on the Commander X16!
These have a different way to obtain the upper 16 bits of the result: just read cx16.r0.
**NOTE:** the result is only valid if the multiplication was done with uword arguments (or two positive word arguments).
As soon as a single negative word value (or both) was used in the multiplication, these upper 16 bits are not valid!
Suggestion (if you are on the Commander X16): use ``verafx.muls()`` to get a hardware accelerated 32 bit signed multiplication.
``crc16 (uword data, uword length) -> uword``
Returns a CRC-16 (XMODEM) checksum over the given data buffer.
Note: on the Commander X16, there is a CRC-16/IBM-3740 routine in the kernal: cx16.memory_crc().
That one is faster, but yields different results.
``crc16_start() / crc16_update(ubyte value) / crc16_end() -> uword``
"streaming" crc16 calculation routines, when the data doesn't fit in a single buffer.
Tracks the crc16 checksum in cx16.r15! If your code uses that, it must save/restore it before calling this routine!
Call the start() routine first, feed it bytes with the update() routine, finalize with calling the end() routine which returns the crc16 value.
Note: after calling the crc16_end() routine you must start over.
``crc32 (uword data, uword length) -> long``
Calculates a CRC-32 (ISO-HDLC/PKZIP) checksum over the given data buffer.
The 32 bits result is returned as a long value. The routine clobbers R0/R1 and R12 through R15.
``crc32_start() / crc32_update(ubyte value) / crc32_end() / crc32_end_result()``
"streaming" crc32 calculation routines, when the data doesn't fit in a single buffer.
Tracks the crc32 checksum in cx16.r14 and cx16.r15! If your code uses these, it must save/restore them before calling this routine!
Call the start() routine first, feed it bytes with the update() routine, finalize with calling the end() routine that returns the result value as a long.
Instead of the normal end() routine you can also call crc32_end_result() which finalizes the calculation,
and actually returns the high and low words of the 32 bits result value as two return word values.
Note: after calling the crc32_end() or crc32_end_result() routine you must start over.
``lerp(v0, v1, t)``
Linear interpolation routine for unsigned byte values.
Returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 255]
Guarantees v = v1 when t = 255. Also works if v0 > v1.
``lerpw(v0, v1, t)``
Linear interpolation routine for unsigned word values.
Returns an interpolation between two inputs (v0, v1) for a parameter t in the interval [0, 65535]
Guarantees v = v1 when t = 65535. Also works if v0 > v1.
Clobbers R15.
``interpolate(v, inputMin, inputMax, outputMin, outputMax)``
Interpolate a value v in interval [inputMin, inputMax] to output interval [outputMin, outputMax]
All values are unsigned bytes. Clobbers R15
(there is no version for word values because of lack of precision in the fixed point calculation there).
There is no ``tan`` function in this library (there is a floating point ``tan`` though in the ``floats`` library).
monogfx (cx16 and virtual)
---------------------------
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Full-screen lores or hires monochrome bitmap graphics routines, available on the X16 machine only.
- two resolutions: lores 320*240 or hires 640*480 bitmap mode
@@ -890,7 +929,8 @@ and the `testmonogfx` example program, to see what's in there.
palette (cx16 only)
--------------------
^^^^^^^^^^^^^^^^^^^^
Available for the Cx16 target. Various routines to set the display color palette.
There are also a few better looking Commodore 64 color palettes available here,
because the Commander X16's default colors for this (the first 16 colors) are too saturated
@@ -904,13 +944,15 @@ to see what's in there.
prog8_lib
---------
^^^^^^^^^
Low-level language support. You should not normally have to bother with this directly.
The compiler needs it for various built-in system routines.
psg (cx16 only)
----------------
^^^^^^^^^^^^^^^^
Available for the Cx16 target.
Contains a simple abstraction for the Vera's PSG (programmable sound generator) to play simple waveforms.
It includes an interrupt routine to handle simple Attack/Release envelopes as well.
@@ -921,7 +963,8 @@ to see what's in there.
sorting (experimental)
----------------------
^^^^^^^^^^^^^^^^^^^^^^
Various sorting routines (gnome sort and shell sort variants) for byte, word and string arrays.
API is experimental and may change or disappear in a future version.
**NOTE:** all word and str arrays have to be @nosplit! Words and pointers need to be consecutive in memory for now.
@@ -931,7 +974,8 @@ to see what's in there. Also check out the `sortingbech` example.
sprites (cx16 only)
--------------------
^^^^^^^^^^^^^^^^^^^^
Available for the Cx16 target. Simple routines to manipulate sprites.
They're not written for high performance, but for simplicity.
That's why they control one sprite at a time. The exception is the ``pos_batch`` routine,
@@ -943,110 +987,12 @@ to see what's in there.
strings
-------
^^^^^^^
Provides string manipulation routines.
``length (str) -> ubyte length``
Number of bytes in the string. This value is determined during runtime and counts upto
the first terminating 0 byte in the string, regardless of the size of the string during compilation time.
Don't confuse this with ``len`` and ``sizeof``!
``left (source, length, target)``
Copies the left side of the source string of the given length to target string.
It is assumed the target string buffer is large enough to contain the result.
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
Modifies in-place, doesn't return a value (so can't be used in an expression).
``right (source, length, target)``
Copies the right side of the source string of the given length to target string.
It is assumed the target string buffer is large enough to contain the result.
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
Modifies in-place, doesn't return a value (so can't be used in an expression).
``slice (source, start, length, target)``
Copies a segment from the source string, starting at the given index,
and of the given length to target string.
It is assumed the target string buffer is large enough to contain the result.
Also, you have to make sure yourself that start and length are within bounds of the strings.
Modifies in-place, doesn't return a value (so can't be used in an expression).
``find (string, char) -> ubyte index, bool found``
Locates the first index of the given character in the string, and a boolean (in Carry flag)
to say if it was found at all. If the character is not found, index 255 (and false) is returned.
You can consider this a safer way of checking if a character occurs
in a string than using an `in` containment check - because this find routine
properly stops at the first 0-byte string terminator it encounters in case the string was modified.
``rfind (string, char) -> ubyte index, bool found``
Like ``find``, but now looking from the *right* of the string instead.
``contains (string, char) -> bool``
Just returns true if the character is in the given string, or false if it's not.
For string literals, you can use a containment check expression instead: ``char in "hello world"``.
``compare (string1, string2) -> ubyte result``
Returns -1, 0 or 1 depending on whether string1 sorts before, equal or after string2.
Note that you can also directly compare strings and string values with each other
using ``==``, ``<`` etcetera (it will use strings.compare for you under water automatically).
This even works when dealing with uword (pointer) variables when comparing them to a string type.
``ncompare (string1, string2, length) -> ubyte result``
Compares two strings up to the number of characters in the length parameter.
Returns -1, 0 or 1 depending on whether string1 sorts before, equal or after string2.
Note that lengths of 0 or 1 evaluate the same. The first character is always compared.
A length larger than either string will function identically to compare.
``copy (from, to) -> ubyte length``
Copy a string to another, overwriting that one. Make sure it was large enough to contain the new string.
Returns the length of the string that was copied.
``ncopy (from, to, maxlength) -> ubyte length``
Copy a string to another, overwriting that one, but limited to the given length.
Returns the length of the string that was copied.
``append (string, suffix) -> ubyte length``
Appends the suffix string to the other string. Make sure the memory buffer is large enough to contain the combined strings.
Returns the length of the combined string.
``nappend (string, suffix, maxlength) -> ubyte length``
Appends the suffix string to the other string, up to the given maximum length of the combined string.
Returns the length of the combined string.
``lower (string)``
Lowercases the PETSCII-string in place.
``upper (string)``
Uppercases the PETSCII-string in place.
``lowerchar (char)``
Returns lowercased PETSCII character.
``upperchar (char)``
Returns uppercased PETSCII character.
``strip (string)``
Gets rid of whitespace and other non-visible characters at the edges of the string. (destructive)
``rstrip (string)``
Gets rid of whitespace and other non-visible characters at the end of the string. (destructive)
``lstrip (string)``
Gets rid of whitespace and other non-visible characters at the start of the string. (destructive)
``lstripped (string) -> str``
Returns pointer to first non-whitespace and non-visible character at the start of the string (non-destructive lstrip)
``trim (string)``
Gets rid of whitespace characters at the edges of the string. (destructive)
``rtrim (string)``
Gets rid of whitespace characters at the end of the string. (destructive)
``ltrim (string)``
Gets rid of whitespace characters at the start of the string. (destructive)
``ltrimmed (string) -> str``
Returns pointer to first non-whitespace character at the start of the string (non-destructive ltrim)
conversion and classification
'''''''''''''''''''''''''''''
``isdigit (char)``
Returns boolean if the character is a numerical digit 0-9
@@ -1060,17 +1006,38 @@ Provides string manipulation routines.
``isprint (char)``
Returns true if the PETSCII character is a "printable" character (space or any visible symbol)
``startswith (string, prefix) -> bool``
Returns true if string starts with prefix, otherwise false
``lower (string)``
Lowercases the PETSCII-string in place.
``endswith (string, suffix) -> bool``
Returns true if string ends with suffix, otherwise false
``upper (string)``
Uppercases the PETSCII-string in place.
``pattern_match (string, pattern) -> bool`` (not on Virtual target)
Returns true if the string matches the pattern, false if not.
'?' in the pattern matches any one character. '*' in the pattern matches any substring.
An empty pattern matches nothing. If you need everything to match, use a single '*'.
Note: this routine does not work when code is in ROM.
``lowerchar (char)``
Returns lowercased PETSCII character.
``upperchar (char)``
Returns uppercased PETSCII character.
miscellaneous
'''''''''''''
``compare (string1, string2) -> ubyte result``
Returns -1, 0 or 1 depending on whether string1 sorts before, equal or after string2.
Note that you can also directly compare strings and string values with each other
using ``==``, ``<`` etcetera (it will use strings.compare for you under water automatically).
This even works when dealing with uword (pointer) variables when comparing them to a string type.
``length (str) -> ubyte length``
Number of bytes in the string. This value is determined during runtime and counts upto
the first terminating 0 byte in the string, regardless of the size of the string during compilation time.
Don't confuse this with ``len`` and ``sizeof``!
``ncompare (string1, string2, length) -> ubyte result``
Compares two strings up to the number of characters in the length parameter.
Returns -1, 0 or 1 depending on whether string1 sorts before, equal or after string2.
Note that lengths of 0 or 1 evaluate the same. The first character is always compared.
A length larger than either string will function identically to compare.
``hash (string) -> ubyte``
Returns a simple 8 bit hash value for the given string.
@@ -1079,8 +1046,102 @@ Provides string manipulation routines.
On the English word list in /usr/share/dict/words it seems to have a pretty even distribution.
manipulation
''''''''''''
``append (string, suffix) -> ubyte length``
Appends the suffix string to the other string. Make sure the memory buffer is large enough to contain the combined strings.
Returns the length of the combined string.
``copy (from, to) -> ubyte length``
Copy a string to another, overwriting that one. Make sure it was large enough to contain the new string.
Returns the length of the string that was copied.
``left (source, length, target)``
Copies the left side of the source string of the given length to target string.
It is assumed the target string buffer is large enough to contain the result.
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
Modifies in-place, doesn't return a value (so can't be used in an expression).
``lstrip (string)``
Gets rid of whitespace and other non-visible characters at the start of the string. (destructive)
``lstripped (string) -> str``
Returns pointer to first non-whitespace and non-visible character at the start of the string (non-destructive lstrip)
``ltrim (string)``
Gets rid of whitespace characters at the start of the string. (destructive)
``ltrimmed (string) -> str``
Returns pointer to first non-whitespace character at the start of the string (non-destructive ltrim)
``nappend (string, suffix, maxlength) -> ubyte length``
Appends the suffix string to the other string, up to the given maximum length of the combined string.
Returns the length of the combined string.
``ncopy (from, to, maxlength) -> ubyte length``
Copy a string to another, overwriting that one, but limited to the given length.
Returns the length of the string that was copied.
``right (source, length, target)``
Copies the right side of the source string of the given length to target string.
It is assumed the target string buffer is large enough to contain the result.
Also, you have to make sure yourself that length is smaller or equal to the length of the source string.
Modifies in-place, doesn't return a value (so can't be used in an expression).
``rstrip (string)``
Gets rid of whitespace and other non-visible characters at the end of the string. (destructive)
``rtrim (string)``
Gets rid of whitespace characters at the end of the string. (destructive)
``slice (source, start, length, target)``
Copies a segment from the source string, starting at the given index,
and of the given length to target string.
It is assumed the target string buffer is large enough to contain the result.
Also, you have to make sure yourself that start and length are within bounds of the strings.
Modifies in-place, doesn't return a value (so can't be used in an expression).
``strip (string)``
Gets rid of whitespace and other non-visible characters at the edges of the string. (destructive)
``trim (string)``
Gets rid of whitespace characters at the edges of the string. (destructive)
searching
'''''''''
``contains (string, char) -> bool``
Just returns true if the character is in the given string, or false if it's not.
For string literals, you can use a containment check expression instead: ``char in "hello world"``.
``endswith (string, suffix) -> bool``
Returns true if string ends with suffix, otherwise false
``find (string, char) -> ubyte index, bool found``
Locates the first index of the given character in the string, and a boolean (in Carry flag)
to say if it was found at all. If the character is not found, index 255 (and false) is returned.
You can consider this a safer way of checking if a character occurs
in a string than using an `in` containment check - because this find routine
properly stops at the first 0-byte string terminator it encounters in case the string was modified.
``pattern_match (string, pattern) -> bool`` (not on Virtual target)
Returns true if the string matches the pattern, false if not.
'?' in the pattern matches any one character. '*' in the pattern matches any substring.
An empty pattern matches nothing. If you need everything to match, use a single '*'.
Note: this routine does not work when code is in ROM.
``rfind (string, char) -> ubyte index, bool found``
Like ``find``, but now looking from the *right* of the string instead.
``startswith (string, prefix) -> bool``
Returns true if string starts with prefix, otherwise false
syslib
------
^^^^^^
The "system library" for your target machine. It contains many system-specific definitions such
as ROM/Kernal subroutine definitions, memory location constants, and utility subroutines.
@@ -1093,25 +1154,18 @@ depending on the chosen compilation target. Read the :source:`sys lib source cod
sys (part of syslib)
--------------------
``target``
A constant ubyte value designating the target machine that the program is 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:
^^^^^^^^^^^^^^^^^^^^
- 7 = Neo6502
- 8 = Atari 8 bits
- 16 = Commander X16
- 25 = Foenix F256 family
- 64 = Commodore 64
- 128 = Commodore 128
- 255 = Virtual machine
miscellaneous
'''''''''''''
``cpu_is_65816()``
Returns true if the CPU in the computer is a 65816, false otherwise (6502 cpu).
Note that Prog8 itself has no support yet for this CPU other than detecting its presence.
``disable_caseswitch()`` and ``enable_caseswitch()``
Disable or enable the ability to switch character set case using a keyboard combination.
``exit (returncode)``
Immediately stops the program and exits it, with the returncode in the A register.
Note: custom interrupt handlers remain active unless manually cleared first!
@@ -1146,31 +1200,6 @@ sys (part of syslib)
Compares two blocks of memory of up to 65535 bytes in size.
Returns -1 (255), 0 or 1, meaning: block 1 sorts before, equal or after block 2.
``read_flags () -> ubyte``
Returns the current value of the CPU status register.
``set_carry ()``
Sets the CPU status register Carry flag.
``clear_carry ()``
Clears the CPU status register Carry flag.
``set_irqd ()``
Sets the CPU status register Interrupt Disable flag.
``clear_irqd ()``
Clears the CPU status register Interrupt Disable flag.
``irqsafe_set_irqd ()``
Sets the CPU status register Interrupt Disable flag, in a way that is safe to be used inside a IRQ handler.
Pair with ``irqsafe_clear_irqd()``.
``irqsafe_clear_irqd ()``
Clears the CPU status register Interrupt Disable flag, in a way that is safe to be used inside a IRQ handler.
Pair with ``irqsafe_set_irqd()``. Inside an IRQ handler this makes sure it doesn't inadvertently
clear the irqd status bit, and it can still be used inside normal code as well (where it *does* clear
the irqd status bit if it was cleared before entering).
``progend ()``
Returns the last address of the program in memory + 1. This means: the memory address directly after all the program code and variables,
including the uninitialized ones ("BSS" variables) and the uninitialized memory blocks reserved by the `memory()` function.
@@ -1181,6 +1210,29 @@ sys (part of syslib)
Returns the first address of the program in memory. This usually is $0801 on the C64 and the X16, for example.
On the assembly level: it returns the address of the symbol "``prog8_program_start``".
``reset_system ()``
Soft-reset the system back to initial power-on BASIC prompt.
(called automatically by Prog8 when the main subroutine returns and the program is not using basicsafe zeropage option)
``save_prog8_internals()`` and ``restore_prog8_internals()``
Normally not used in user code, the compiler utilizes these for the internal interrupt logic.
It stores and restores the values of the internal prog8 variables.
This allows other code to run that might clobber these values temporarily.
``target``
A constant ubyte value designating the target machine that the program is 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:
- 7 = Neo6502
- 8 = Atari 8 bits
- 16 = Commander X16
- 25 = Foenix F256 family
- 64 = Commodore 64
- 128 = Commodore 128
- 255 = Virtual machine
``wait (uword jiffies)``
wait approximately the given number of jiffies (1/60th seconds)
Note: the regular system irq handler has run for this to work as it depends on the system jiffy clock.
@@ -1198,17 +1250,36 @@ sys (part of syslib)
can be used to avoid screen flicker/tearing when updating screen contents.
note: a more accurate way to do this is by using a raster irq handler instead.
``reset_system ()``
Soft-reset the system back to initial power-on BASIC prompt.
(called automatically by Prog8 when the main subroutine returns and the program is not using basicsafe zeropage option)
``disable_caseswitch()`` and ``enable_caseswitch()``
Disable or enable the ability to switch character set case using a keyboard combination.
processor status flags
''''''''''''''''''''''
``clear_carry ()``
Clears the CPU status register Carry flag.
``save_prog8_internals()`` and ``restore_prog8_internals()``
Normally not used in user code, the compiler utilizes these for the internal interrupt logic.
It stores and restores the values of the internal prog8 variables.
This allows other code to run that might clobber these values temporarily.
``clear_irqd ()``
Clears the CPU status register Interrupt Disable flag.
``irqsafe_set_irqd ()``
Sets the CPU status register Interrupt Disable flag, in a way that is safe to be used inside a IRQ handler.
Pair with ``irqsafe_clear_irqd()``.
``irqsafe_clear_irqd ()``
Clears the CPU status register Interrupt Disable flag, in a way that is safe to be used inside a IRQ handler.
Pair with ``irqsafe_set_irqd()``. Inside an IRQ handler this makes sure it doesn't inadvertently
clear the irqd status bit, and it can still be used inside normal code as well (where it *does* clear
the irqd status bit if it was cleared before entering).
``read_flags () -> ubyte``
Returns the current value of the CPU status register.
``set_carry ()``
Sets the CPU status register Carry flag.
``set_irqd ()``
Sets the CPU status register Interrupt Disable flag.
processor stack
'''''''''''''''
``push (value)``
pushes a byte value on the CPU hardware stack.
@@ -1243,7 +1314,8 @@ sys (part of syslib)
textio (txt.*)
--------------
^^^^^^^^^^^^^^
This will probably be the most used library module. It contains a whole lot of routines
dealing with text-based input and output (to the screen). Such as
@@ -1262,12 +1334,22 @@ to see what's in there. (Note: slight variations for different compiler targets)
verafx (cx16 only)
-------------------
^^^^^^^^^^^^^^^^^^^
Available for the Cx16 target. Routines that use the Vera FX logic to accelerate certain operations.
``available``
Returns true if Vera FX is available, false if not (that would be an older Vera chip)
``clear``
Very quickly clear a piece of vram to a given byte value (it writes 4 bytes at a time).
The routine is around 3 times faster as a regular unrolled loop to clear vram.
``copy``
Very quickly copy a portion of the video memory to somewhere else in vram (4 bytes at a time)
Sometimes this is also called "blitting".
This routine is about 50% faster as a regular byte-by-byte copy.
``muls``
The VeraFX signed word 16*16 to 32 multiplier is accessible via the ``muls`` routine.
It is about 4 to 5 times faster than the default 6502 cpu routine for word multiplication.
@@ -1288,15 +1370,6 @@ Available for the Cx16 target. Routines that use the Vera FX logic to accelerate
Note: there is a block level %option "verafxmuls" that automatically replaces all word multiplications in that block
by calls to verafx, but be careful with it because it may interfere with other Vera operations or IRQs.
``clear``
Very quickly clear a piece of vram to a given byte value (it writes 4 bytes at a time).
The routine is around 3 times faster as a regular unrolled loop to clear vram.
``copy``
Very quickly copy a portion of the video memory to somewhere else in vram (4 bytes at a time)
Sometimes this is also called "blitting".
This routine is about 50% faster as a regular byte-by-byte copy.
``transparency``
Set transparent write mode for VeraFX cached writes and also for normal writes to DATA0/DATA.
If enabled, pixels with value 0 do not modify VRAM when written (so they are "transparent")
-3
View File
@@ -2,9 +2,6 @@ TODO
====
- fix/check github issues.
- docs: sort the routines in the library chapter alphabetically
- redo the benchmark-c tests with final 12.0 release version.
Future Things and Ideas