Built-in Functions
This page documents all built-in functions available in basm expressions.
Mathematical Functions
Trigonometric Functions
sin(x)- Sine of x (x in radians)cos(x)- Cosine of x (x in radians)asin(x)- Arc sine of x (returns radians)acos(x)- Arc cosine of x (returns radians)atan2(y, x)- Arc tangent of y/x (returns radians)
Exponential and Logarithmic Functions
exp(x)- Exponential function (e^x)ln(x)- Natural logarithm (base e)log10(x)- Logarithm base 10pow(base, exponent)- Power function (base^exponent)sqrt(x)- Square root
Rounding and Modulo Functions
floor(x)- Largest integer ≤ xceil(x)- Smallest integer ≥ xint(x)- Integer part (truncate towards zero)frac(x)- Fractional partabs(x)- Absolute valuefmod(x, y)- Floating point remainder of x/yfremain(x, y)- IEEE remainder function
Comparison and Utility Functions
min(a, b, ...)- Minimum value (variadic)max(a, b, ...)- Maximum value (variadic)clamp(value, min, max)- Clamp value between min and maxfmin(a, b)- Minimum of two floatsfmax(a, b)- Maximum of two floatsfdim(x, y)- Positive difference (max(x-y, 0))fstep(edge, x)- Step function (0 if x<edge, 1 if x≥edge)isgreater(x, y)- Test if x > y (returns 0 or 1)isless(x, y)- Test if x < y (returns 0 or 1)hypot(x, y)- Euclidean distance sqrt(x²+y²)ldexp(x, exp)- x * 2^exp
Bit Manipulation Functions
high(value)/hi(value)- High byte of 16-bit valuelow(value)/lo(value)- Low byte of 16-bit value
Memory Access Functions
peek(address)/memory(address)- Read byte from memory at address during assembly
String Functions
char(value)- Convert integer to single character stringstring_new(length, filler)- Create string of given length filled with fillerstring_push(string, char_or_string)- Append character or stringstring_concat(s1, s2, ...)- Concatenate strings (variadic)string_from_list(list)- Convert list of integers to stringstring_get(string, index)- Get character at index (same aslist_get)string_map(string, transform)- Applytransform(a function name, or an inline lambda) to each character (same aslist_map)string_filter(string, predicate)- Keep only the characters for whichpredicatereturns true (same aslist_filter)string_uppercase(s)string_format(template, arg0, arg1, ...)- Rust/Python-str.format-style positional substitution:{0},{1}, ... intemplateare replaced byarg0,arg1, ... (0-based); use{{/}}for a literal{/}. A placeholder can be reused, and an argument that's itself a string is substituted verbatim (no added quotes). A placeholder index with no matching argument, or malformed{...}content, is an assembling error.
A placeholder can also carry a width/base format spec after a :, e.g. {0:hex4}, reusing the
same hex/hex2/hex4/hex8/bin/bin8/bin16/bin32/int specs the PRINT statement's
{hex4}-style interpolation already supports. The argument must resolve to an integer, or it's an
assembling error.
MSG equ string_format("Score: {0}/{1}", 10, 100) ; "Score: 10/100"
ADDR equ string_format("Address: {0:hex4}", 0xAB) ; "Address: 0x00ab"
BOTH equ string_format("{0:int} = {0:hex2}", 10) ; "10 = 0x0a"
string_len(string)- Length of string (same aslist_len)
Pixels
mode0_byte_to_pen_at(byte, position)- Extract pen number at position (0 or 1) from mode 0 bytemode1_byte_to_pen_at(byte, position)- Extract pen number at position (0-3) from mode 1 bytemode2_byte_to_pen_at(byte, position)- Extract pen number at position (0-7) from mode 2 bytepen_at_mode0_byte(byte, position)- Get pen at position in mode 0 bytepen_at_mode1_byte(byte, position)- Get pen at position in mode 1 bytepen_at_mode2_byte(byte, position)- Get pen at position in mode 2 bytepens_to_mode0_byte(pen0, pen1)- Convert 2 pens to mode 0 bytepens_to_mode1_byte(pen0, pen1, pen2, pen3)- Convert 4 pens to mode 1 bytepens_to_mode2_byte(pen0, ..., pen7)- Convert 8 pens to mode 2 byte
List Functions
list_new(length, filler)- Create list of given length filled with filler valuelist_get(list, index)- Get element at indexlist_set(list, index, value)- Set element at index (returns new list)list_len(list)- Length of listlist_sublist(list, start, end)- Extract sublist (end is not included)list_sublist(list_or_string, a_range)- Extract the elements (or characters) at the positions the range selects - the same thingtarget[a_range]does via bracketslist_sort(list)- Sort list in ascending order (returns new list)list_argsort(list)- Return indices that would sort the listlist_reverse(list)- Reverse the list (returns new list)list_push(list, element)- Append element to list (returns new list)list_extend(list1, list2)- Concatenate two lists (returns new list)list_filter(list, predicate)- Return a list containing the elements for whichpredicate(a function name, or an inline lambda) returns truelist_map(list, transform)list_fold(list, initial, folder)- Reduce the list to a single value:folder(accumulator, element)is called for each element in order, starting frominitiallist_position_predicate(list, predicate)- Index of the first element for whichpredicatereturns true (-1 if none does):
; list_position_predicate example - also locks in a fix: this used to
; (incorrectly) compare item == predicate(item) instead of checking
; whether predicate(item) is true.
org $4000
numbers = [5, 6, 7, 8]
; found: index of the first element greater than 6
first_over_6 = list_position_predicate(numbers, (x) => x > 6)
assert first_over_6 == 2
; not found: -1 when no element matches
none_over_100 = list_position_predicate(numbers, (x) => x > 100)
assert none_over_100 == -1
; a predicate that ignores its argument and always returns a truthy,
; non-boolean value is still a valid (always-true) predicate, so this
; matches the FIRST element (index 0). The old, buggy implementation
; instead compared each item to the literal value 7 and would have
; wrongly answered 2 (the index of the value 7) here.
always_true = list_position_predicate(numbers, (x) => 7)
assert always_true == 0
ret
list_position_value(list, value)(-1 if not found, value)list_split_by_value(list, value)
Range Functions
list_len() and list_get() above also accept a range directly (see
Ranges) - a range is not itself materialized into a list, so both
compute in constant time even for a very large range.
range_step_by(a_range, step)- Returns a new range that steps bystepinstead of 1. There is no dedicateda..step..bsyntax - this function, or broadcasting (base + (0..n) * stride), are how a strided sequence is built instead.
Matrix Functions
To be called on a matrix object or a list of list object (WIP).
matrix_new(width, height, filler)- Create matrix filled with value, ormatrix_new(list_of_lists)to create from nested listsmatrix_set(matrix, y, x, value)- Set element at position (returns new matrix) - note the argument order is row (y) then column (x), notx, ymatrix_get(matrix, y, x)- Get element at position - samey, xorder asmatrix_set. Thematrix[x, y]bracket form uses the more naturalx, yorder instead and swaps internally, if that reads better in your own codematrix_col(matrix, x)- Get column as listmatrix_row(matrix, y)- Get row as listmatrix_set_col(matrix, x, list)- Set column from list (returns new matrix)matrix_set_row(matrix, y, list)- Set row from list (returns new matrix)matrix_width(matrix)- Get matrix widthmatrix_height(matrix)- Get matrix height
File Functions
load("filename")- Load file content as list of bytes
Code Assembly Function
assemble("z80_code")- Assemble Z80 code string and return bytes as list
Example:
Binary Transformation Function
binary_transform(data, "crunch_type")- Compress data using specified cruncher
Supported crunch types:
"LZEXO","LZ4","LZ48","LZ49""LZSHRINKLER","LZX7","LZX0","LZAPU""LZSA1","LZSA2","LZUPKR""BackwardZx0"(backward variant)
Example:
Section Functions
section_start("section_name")- Get start address of named sectionsection_stop("section_name")- Get stop address of named sectionsection_length("section_name")- Get length of named sectionsection_used("section_name")- Get number of bytes actually used in sectionsection_mmr("section_name")- Get memory mapper register value for section
Timing Functions
countnops(start_label, stop_label)- Number of NOPs (the CPC time unit) taken by the code between two labels (stop_labelexcluded). The assembled bytes are disassembled and the duration of each instruction is summed. As for every duration estimation, the result may be wrong for instructions having several durations (conditional jumps...). Equivalent of rasm'scountnops.
Example: