Opbasm PicoBlaze macro library reference¶
- abs(Arg1)¶
Absolute value.
- Parameters:
Arg1 – Register to make positive
- Returns:
Result is in the same register
Example:
load s0, evalh(-10) abs(s0) ; Result is 10
- abs16(Arg1, Arg2)¶
16-bit absolute value.
- Parameters:
Arg1 – MSB register to make positive
Arg2 – LSB register to make positive
Result is in Arg1, Arg2
Example:
load16(s1,s0, -1000) abs16(s1, s0) ; s1, s0 contain +1000 load16(s1,s0, 1000) abs16(s1, s0) ; s1, s0 contain +1000
- add16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit addition.
- Parameters:
Arg1 – MSB1 register
Arg2 – LSB1 register
Arg3 – Decimal constant or expression or MSB2 when Arg4 is present
Arg4 – Optional register for LSB2
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a constant literal. When four arguments are passed, Arg3 and Arg4 are a 16-bit pair to add to the result.
Example:
add16(s1,s0, 0x1234) ; s1,s0 += 0x1234 add16(s1,s0, s3,s2) ; s1,s0 += s3,s2
- addstack(Arg1)¶
Allocate local space on the stack.
- Parameters:
Arg1 – Number of values to add to the stack or a register
You can use the added space for a local variable storage on the stack. This avoids the need to have static stratchpad memory allocations. Use
dropstack()
to restore the stack pointer.Example:
addstack(2) ; Add 2 values addstack(s1) ; Add number of values from s1
- and16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit logical AND.
- Parameters:
Arg1 – MSB1
Arg2 – LSB1
Arg3 – Decimal constant or expression or MSB2 when Arg4 is present
Arg4 – Optional register for LSB2
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a constant literal. When four arguments are passed, Arg3 and Arg4 are a 16-bit pair to AND to the result.
Example:
load16(s1,s0, 0x787F) and16(s1,s0, 0x0FC0) ; Result is 0x0840 and16(s1,s0, s3,s2) ; (s1,s0) AND (s3,s2)
- ansi_black([Arg1])¶
ANSI escape codes for generating color text.
The resulting string contains backslash escapes that must be processed by
cstr()
orestr()
.- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
Example:
ansi_red`foobar'ansi_reset ; red text ansi_red(bold)`foobar'ansi_reset ; bold/bright red text
- ansi_blue([Arg1])¶
ANSI escape codes for generating blue text.
- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
See also
ansi_black()
for more information.
- ansi_cyan([Arg1])¶
ANSI escape codes for generating cyan text.
- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
See also
ansi_black()
for more information.
- ansi_green([Arg1])¶
ANSI escape codes for generating green text.
- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
See also
ansi_black()
for more information.
- ansi_magenta([Arg1])¶
ANSI escape codes for generating magenta text.
- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
See also
ansi_black()
for more information.
- ansi_red([Arg1])¶
ANSI escape codes for generating red text.
- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
See also
ansi_black()
for more information.
- ansi_reset()¶
ANSI escape code for clearing pervious colors.
See also
ansi_black()
for more information.
- ansi_white([Arg1])¶
ANSI escape codes for generating white text.
- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
See also
ansi_black()
for more information.
- ansi_yellow([Arg1])¶
ANSI escape codes for generating yellow text.
- Parameters:
Arg1 – Optional argument of “bold” will activate bold/bright text
See also
ansi_black()
for more information.
- argc(Arg1-ArgN)¶
Count the number of args.
- Parameters:
Arg1-ArgN – Argument list to count
Example:
argc(a,b,c,d) ; Expands to 4
- asciiord(Arg1)¶
Convert a string to a list of decimal ASCII codes.
- Parameters:
Arg1 – String to convert
Example:
asciiord(`My string') ; Expands to 77, 121, 32, 115, 116, 114, 105, 110, 103
Note
You must use m4 quotes on the string argument to avoid unwanted substitutions.
- break()¶
Break statement to exit from for(), while(), and dowhile() loops.
- calleq(Arg1)¶
Call if equal.
- Parameters:
Arg1 – Label to call
- callge(Arg1)¶
Call if greater or equal.
- Parameters:
Arg1 – Label to call
Example:
compare s3, 24 callge(greater) ; call if s3 >= 24
- calllt(Arg1)¶
Call if less than.
- Parameters:
Arg1 – Label to call
- callne(Arg1)¶
Call if not equal.
- Parameters:
Arg1 – Label to call
Example:
compare s3, 24 callne(not_equal) ; call if s3 != 24
- callstring(Arg1, Arg2, Arg3)¶
Repeated string function call operation (useful for PicoBlaze-3).
- Parameters:
Arg1 – Subroutine to call for each character
Arg2 – Register used to hold characters (typically an argument to the subroutine)
Arg3 – String to split into characters
Example:
callstring(write_char, s1, `My string') Expands to: load s1, "M" call write_char load s1, "y" call write_char ...
- calltable(Arg1, Arg2, Arg3-ArgN)¶
Repeated function call on a table of constants.
- Parameters:
Arg1 – Subroutine to call for each byte
Arg2 – Temporary register for each constant
Arg3-ArgN – Decimal values representing table bytes
Example:
calltable(my_subroutine, sF, pbhex(DE,AD,BE,EF)) ; Pass DE,AD,BE,EF in repeated calls to my_subroutine
- clearcy([Arg1])¶
Clear the carry flag.
- Parameters:
Arg1 – Optional temp register
Example:
clearcy clearcy(s0)
- clearmask(Arg1, Arg2)¶
Clear mask bits in a register.
- Parameters:
Arg1 – Register to modify
Arg2 – Mask value
Example:
clearmask(s5, mask(0,1,2)) clearmask(s4, 0xF1)
- colorize(Arg1, Arg2[, Arg3])¶
Wrap a string in ANSI color codes.
The resulting string contains backslash escapes that must be processed by
cstr()
orestr()
.- Parameters:
Arg1 – String to modify
Arg2 – ANSI color name (black, red, green, yellow, blue, magenta, cyan, and white)
Arg3 – Optional argument “bold” will select bold text
Example:
colorize(`foobar', blue) ; Equivalent to ansi_blue`foobar'ansi_reset colorize(`foobar', red, bold) ; Equivalent to ansi_red(bold)`foobar'ansi_reset
- compares(Arg1, Arg2)¶
Signed compare.
- Parameters:
Arg1 – Register for left side of comparison
Arg2 – Register or constant for right side of comparison. Constant is a number in m4 syntax and cannot be a named constant
Carry flag is set in accordance with signed relation.
Zero flag is indeterminate. Use normal compare instruction for == and !=
Note
This calls the
setcy()
macro and depends on the tempregExample:
load s0, evalh(-20) load s1, 42 compares(s0, s1) ; C flag is set because -20 < 0x42
- constlower(Arg1)¶
Split a 16-bit constant and return its lower byte.
- Parameters:
Arg1 – Constant to split
Example:
constlower(0x1234) ; Expands to 0x34
- constupper(Arg1)¶
Split a 16-bit constant and return its upper byte.
- Parameters:
Arg1 – Constant to split
Example:
constupper(0x1234) ; Expands to 0x12
- continue()¶
Continue statement to restart a for(), while(), or dowhile() loop.
- cstr(Arg1)¶
Convert a string to a list of decimal ASCII codes with a NUL terminator.
- Parameters:
Arg1 – String to convert
See also
estr()
for more information.
- dec2pbhex(Arg1-ArgN)¶
Convert a list of decimal values to PicoBlaze hex format.
- Parameters:
Arg1-ArgN – Decimal values to convert
Example:
dec2pbhex(1, 2, 100, 200) ; Expands to 01, 02, 64, C8
- delay_cycles(Arg1)¶
Delay for a number of instruction cycles.
- Parameters:
Arg1 – Number of instructions to delay
This can generate two types of delay loops. The default is a recursive delay implemented without any registers. For delays of 511 cycles or less a more efficient loop can be generated if a loop count register is defined first by calling the
use_delay_reg()
macro.Example:
delay_cycles(10) ; Delay for 10 instructions (20 clock cycles)
- delay_ms(Arg1, Arg2, Arg3[, Arg4])¶
Delay by milliseconds.
- Parameters:
Arg1 – Milliseconds to delay
Arg2 – MSB register of delay counter
Arg3 – LSB register of delay counter
Arg4 – Optional number of instructions to deduct from the delay (default is 0)
This delay will be cycle accurate if the requested delay is an integer multiple of the clock period. At 100 MHz, the max delay is 214 ms. It increases with lower clock frequencies.
Example:
use_clock(50) ; 50 MHz clock delay_5ms: delay_ms(5, s4,s5, 2) ; Deduct 2 additional instructions to account for call and return return ... call delay_5ms
- delay_us(Arg1, Arg2, Arg3[, Arg4])¶
Delay by microseconds.
- Parameters:
Arg1 – Microseconds to delay
Arg2 – MSB register of delay counter
Arg3 – LSB register of delay counter
Arg4 – Optional number of instructions to deduct from the delay (default is 0)
This delay will be cycle accurate if the requested delay is an integer multiple of the clock period.
Example:
use_clock(50) ; 50 MHz clock delay_40us: delay_us(40, s4,s5) return ... call delay_40us
- dowhile(Arg1, Arg2)¶
Do-while loop.
- Parameters:
Arg1 – Boolean comparison expression
Arg2 – Code block for loop body
The Boolean expression must be of the form:
reg op reg|expression
where op is <, >=, ==, !=, &, or ~&Example:
load s0, 15'd dowhile(s0 != 10, `output s3, P_foo sub s0, 01')
- dropstack(Arg1)¶
Drop values stored on the stack.
- Parameters:
Arg1 – Number of values to drop from the stack or a register
Example:
dropstack(2) ; Remove 2 values dropstack(s1) ; Remove number of values specified in s1 register
- errmsg(Arg1)¶
Print an error message and terminate m4.
- Parameters:
Arg1 – message string
This prints a message with the file and line number where the macro was invoked for debugging.
Example:
errmsg(`Bad arguments to foo macro')
- estr(Arg1)¶
Convert a string to a list of decimal ASCII codes without a NUL terminator.
- Parameters:
Arg1 – String to convert
The following C escape codes are translated to their ASCII value:
\\ \
\n NL\LF
\r CR
\t HT
\b BS
\a BEL
\e ESC
\s semicolon ;
Example:
estr(`My string\r\n') ; Expands to 77, 121, 32, 115, 116, 114, 105, 110, 103, 13, 10 cstr(`My string\r\n') ; Expands to 77, 121, 32, 115, 116, 114, 105, 110, 103, 13, 10, 0
- evala(Arg1)¶
Evaluate m4 expression as a 12-bit PicoBlaze address.
- Parameters:
Arg1 – Expression
- Returns:
Expands to a PicoBlaze address literal with a comment listing the original expression
- evalb(Arg1)¶
Evaluate m4 expression as a PicoBlaze binary number.
- Parameters:
Arg1 – Expression or constant name
- Returns:
Expands to a PicoBlaze binary literal with a comment listing the original expression
- evalc(Arg1[, Arg2, Arg3])¶
Evaluate m4 expression with expansion of constants.
- Parameters:
Arg1 – Expression or constant name
Arg2 – Optional numeric base to convert to (default is 10)
Arg3 – Optional minimum number of digits in result (default is 0)
- Returns:
Expands to a literal for the expression or constant
- evald(Arg1)¶
Evaluate m4 expression as a PicoBlaze decimal number.
- Parameters:
Arg1 – Expression or constant name
- Returns:
Expands to a PicoBlaze decimal literal with a comment listing the original expression
Example:
constant cname, evald(20 * 4 - 1) --> constant cname, 79'd
- evalh(Arg1)¶
Evaluate m4 expression as an 8-bit PicoBlaze hex number.
- Parameters:
Arg1 – Expression or constant name
- Returns:
Expands to a PicoBlaze hex literal with a comment listing the original expression
Example:
constant cname, evalh(20 + 6) --> constant cname, 1a constant cname2, evalh(250 + 6) --> constant cname2, 01
- evalx(Arg1[, Arg2, Arg3])¶
Only evaluate valid expressions, otherwise reproduce the original text in the first argument.
- Parameters:
Arg1 – Expression or string literal
Arg2 – Optional numeric base to convert to (default is 10)
Arg3 – Optional minimum number of digits in result (default is 0)
Example:
evalx(some_name) --> some_name evalx(1+3) --> 4
- expr(Arg1)¶
Expression evaluators This is a family of macros that provide implementation of arithmetic expressions from compact input notation
- Parameters:
Arg1 – Register assignment expression of the form: sN := <val> op <val> [op <val>]*
val is one of:
register
literal expression (with no internal spaces)
sp[addr] scratchpad adddress
spi[reg] indirect scratchpad address in register
op is one of:
- + - * /
add, subtract, multiply, divide
- & | ^
and, or, xor
- << >>
shift left, shift right (0-filled MSB)
- =:
reverse assignment to register or scratchpad
Note
Operations are evaluated left to right with no precedence
Example:
expr(s0 := s1 + s2 - s3 >> 4 =: sp[M_value]) Arithmetic is performed on s0 and the result is stored in scratchpad at M_value s0 <= s1, s0 <= s0 + s2, s0 <= s0 - s3, s0 <= s0 >> 4, sp[M_value] <= s0 expr(s1 := s4 + (28*4-1)) s1 <= s4, s1 <= s1 + 111 Constant expressions must have no spaces
Summary of expression macros:
Macro
Target x operand
Supported operators
Notes
expr
8x8
+, -, *, /, &, |, ^, <<, >>, =:
exprs
8x8
+, -, *, /, &, |, ^, <<, >>, =:
(signed *, /, and >>)
expr2
16x8 (see note)
+, -, *, /, <<, >>, =:
expr2s
16x8 (see note)
+, -, *, /, <<, >>, =:
(signed for all except <<)
expr16
16x16
+, -, &, |, ^, <<, >>, =:
expr16s
16x16
+, -, &, |, ^, <<, >>, =:
(signed >>)
Note
The expr2 macros support 16-bit literals as operands of + and -
For multiplication and division support you must initialize the internal functions with one of the following:
Macro
Multiply
Divide
expr
use_expr_mul
use_expr_div
exprs
use_expr_muls
use_expr_divs
expr2
use_expr_mul
use_expr_div16
expr2s
use_expr_muls and use_expr_mulsu
use_expr_div16s
As an expedient you can invoke
use_expr_all()
to include all of them and then eliminate any unused mul or div routines with the--remove-dead-code
option to opbasm.These macros need to be called before any call to expr*() that uses multiplication or division. It is best to place them at the start of the program and jump over them to reach the startup code. The stack must be configured with
use_stack()
before calling these macros because additional modified registers must be saved and restored.By default these macros configure the mul and div functions to use the s8,s9 or s7,s8, and s9 registers for input and output. You can modify the register allocation by passing arguments to the use_* macros. The MSB of multiplication is ignored by subsequent operations. Division by 0 is not detected.
- expr16(Arg1)¶
16x16 unsigned expression evaluator. All terms are 16-bit register pairs or 16-bit literals.
- Parameters:
Arg1 – Register assignment expression of the form: sN := <val> op <val> [op <val>]*
See also
expr()
for more information.Example:
reg16(rx, s4,s5) reg16(ry, s6,s7) load16(ry, 400) expr2(rx := 2000 + ry * 3) ; (2000 + 400) * 3 => 12600
- expr16s(Arg1)¶
16x16 signed expression evaluator. All terms are 16-bit register pairs or 16-bit literals.
- Parameters:
Arg1 – Register assignment expression of the form: sN := <val> op <val> [op <val>]*
See also
expr()
for more information.Example:
reg16(rx, s4,s5) reg16(ry, s6,s7) load16(ry, -400) expr2(rx := 2000 + ry * -3) ; (2000 + -400) * -3 => -4800
- expr2(Arg1)¶
16x8 unsigned expression evaluator. The target register is a 16-bit pair and the first term can be a 16-bit pair or a 16-bit literal.
- Parameters:
Arg1 – Register assignment expression of the form: sN := <val> op <val> [op <val>]*
See also
expr()
for more information.Example:
reg16(rx, s4,s5) reg16(ry, s6,s7) load16(ry, 400) expr2(rx := ry + 200 * 3) ; (400 + 200) * 3 => 1800
- expr2s(Arg1)¶
16x8 signed expression evaluator. The target register is a 16-bit pair and the first term can be a 16-bit pair or a 16-bit literal.
- Parameters:
Arg1 – Register assignment expression of the form: sN := <val> op <val> [op <val>]*
See also
expr()
for more information.Example:
reg16(rx, s4,s5) reg16(ry, s6,s7) load16(ry, -400) expr2(rx := ry + 200 * -3) ; (-400 + 200) * -3 => 600
- exprs(Arg1)¶
Signed 8-bit expression evaluator.
- Parameters:
Arg1 – Register assignment expression of the form: sN := <val> op <val> [op <val>]*
See also
expr()
for more information.
- fetch16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit fetch.
- Parameters:
Arg1 – MSB register of target
Arg2 – LSB register of target
Arg3 – Register pointing to low byte or MSB of source address when Arg4 is present
Arg4 – Optional register for LSB of source address
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a register pointing to the low byte to fetch. It is incremented twice to permit sequential use of fetch16(). When four arguments are passed, Arg3 and Arg4 are a 16-bit pair of address constants to fetch from.
Example:
constant M_ACCUM_L, 1a constant M_ACCUM_H, 1b reg16(M_ACCUM, M_ACCUM_H, M_ACCUM_L) reg16(rx, s4, s3) fetch16(rx, M_ACCUM) ; Fetch direct from address load s0, M_ACCUM_L fetch16(rx, s0) ; Fetch from indirect pointer fetch16(rx, s0) ; Fetch next word
- floor_log(Arg1, Arg2)¶
Compute floor(log(n,b)) for Base-b.
- Parameters:
Arg1 – Number to compute floor-log on
Arg2 – Logarithm base
Example:
floor_log(20, 2) ; Expands to 4 (2**4 = 16, 2**5 = 32) floor_log(1000, 10) ; Expands to 3 (10**3 = 1000)
- floor_log2(Arg1)¶
Compute floor(log(n)) for Base-2.
- Parameters:
Arg1 – Number to compute floor-log on
Example:
floor_log2(64) ; Expands to 6
- for(Arg1, Arg2, Arg3, Arg4)¶
For loop.
- Parameters:
Arg1 – Initialization expression (passed to expr()). This can be empty.
Arg2 – Boolean comparison expression
Arg3 – Update expression (passed to expr()). This can be empty.
Arg4 – Code block for loop body
Example:
for(s0 := 0, s0 < 5, s0 := s0 + 1, `output s0, 00')
Note: The
continue()
macro will behave as in C by jumping to the update code before restarting the loop.
- func(Arg1, Arg2, Arg3, Arg4)¶
Function definition.
This creates a function that receives its arguments on the stack. A macro is generated to prepare the stack arguments and call the function. The function will save registers automatically and load the stack arguments. The saved registers and call frame are cleaned up at the end. Do not use return instructions in the code body. Instead call the leave_func() macro. Use the retvalue() macro to store return values on the stack.
- Parameters:
Arg1 – Label for function
Arg2 – Variable definitions (same format as passed to the vars() macro)
Arg3 – Number of bytes returned on stack (0 for no return values)
Arg4 – Code block for func body
Example:
func(mul, `s0 is m1, s1 is m2, s2 is result', 0, `expr(result := m1 * m2)')
- getstack(Arg1-ArgN)¶
Retrieve multiple contiguous values from the stack without changing the stack pointer.
- Parameters:
Arg1-ArgN – Registers to save values in The first register corresponds to the highest address
Example:
getstack(s3, s4, s5) ; Get stack offset SP+3, SP+2, and SP+1 into s3, s4, s5
- getstackat(Arg1, Arg2)¶
Retrieve values from the stack without changing the stack pointer.
- Parameters:
Arg1 – Register to save value in
Arg2 – Offset from stack pointer (offset 1 is the first value) or a register
Example:
getstackat(s3, 2) ; Get the second value relative to the stack pointer getstackat(s3, s0) ; Get stack value pointed at by s0
- if(Arg1, Arg2, [Arg3, ]Arg4-ArgN)¶
Generic if macro.
- Parameters:
Arg1 – Boolean comparison expression.
Arg2 – True clause
Arg3 – Optional else clause or next else-if comparison expression
Arg4-ArgN – Additional else-if clauses
The Boolean expression must be of the form:
reg op reg|expression
where op is <, >, <=, >=, ==, !=, &, or ~& or of the formreg
which is treated asreg != 0
.Signed comparison is invoked with
signed(comparison expr.)
With signed comparison the right operand cannot be a named constant.With the & operator, a test instruction is used in place of compare. The true clause is executed when the result is non-zero (mask matches). The ~& operator executes the true clause when the test result is zero (no match).
This macro performs a comparison of the left and right operands and then inserts the if* macro selected by the operation.
Example:
if(s0 < s1, `load s0, 01', `load s0, 02') if(s0 != 0xa5, `load s0, 01') if(signed(s0 < -10), `load s0, 01') ; Signed comparison with signed()
- ifeq(Arg1[, Arg2])¶
Low level if-equals
- Parameters:
Arg1 – True clause
Arg2 – Optional else clause
These macros insert labels and jump instructions to implement the behavior of an if-then or if-then-else statement testing for equality, inequality, greater-or-equal, or less-than.
Example:
compare s0, s1 ifeq(`load s3, 20 output s3, MY_PORT', ; else `load s3, 30 output s3, MY_OTHER_PORT')
- ifge(Arg1[, Arg2])¶
Low level if-greater-or-equal.
- Parameters:
Arg1 – True clause
Arg2 – Optional else clause
See also
ifeq()
for more information.
- iflt(Arg1[, Arg2])¶
Low level if-less-than.
- Parameters:
Arg1 – True clause
Arg2 – Optional else clause
See also
ifeq()
for more information.
- ifne(Arg1[, Arg2])¶
Low level if-not-equal.
- Parameters:
Arg1 – True clause
Arg2 – Optional else clause
See also
ifeq()
for more information.
- input16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit input.
- Parameters:
Arg1 – MSB register of target
Arg2 – LSB register of target
Arg3 – Register pointing to low byte or MSB of source address when Arg4 is present
Arg4 – Optional register for LSB of source address
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a register pointing to the low port byte to read from. It is incremented twice to permit sequential use of input16(). When four arguments are passed, Arg3 and Arg4 are a 16-bit pair of port constants to input from.
Example:
constant P_ACCUM_L, 1a constant P_ACCUM_H, 1b reg16(P_ACCUM, P_ACCUM_H, P_ACCUM_L) reg16(rx, s4, s3) input16(rx, P_ACCUM) ; Input direct from address load s0, P_ACCUM_L input16(rx, s0) ; Input from indirect pointer input16(rx, s0) ; Input next word
- instdata(Arg1, Arg2)¶
Generate an INST directive from a pair of decimal values.
- Parameters:
Arg1 – High 10-bits
Arg2 – Low byte
Example:
instdata(pbhex(0A, 0B)) ; Expands to inst 00A0B
- insttable_be(Arg1-ArgN)¶
Convert a list of data into a series of INST directives in big-endian byte order.
- Parameters:
Arg1-ArgN – Data to convert in decimal format
Example:
insttable_be(pbhex(0a, 0b, 0c)) Expands to: inst 00a0b inst 00c00
- insttable_le(Arg1-ArgN)¶
Convert a list of data into a series of INST directives in little-endian byte order.
- Parameters:
Arg1-ArgN – Data to convert in decimal format
Example:
insttable_le(pbhex(0a, 0b, 0c)) Expands to: inst 00b0a inst 0000c insttable_le(asciiord(`Pack strings into ROM')) inst 06150 inst 06b63 inst 07320 ... inst 0206f inst 04f52 inst 0004d
- iodefs(Arg1, Arg2-ArgN)¶
Define a series of contiguous port or scratchpad memory constants.
- Parameters:
Arg1 – Starting address for port or memory
Arg2-ArgN – Constant names
Example:
iodefs(0, P_uart_out, P_uart_in, P_control) Expands to: constant P_uart_out, 00 constant P_uart_in, 01 constant P_control, 02
- isnum(Arg1)¶
Determine if argument is a number in m4 syntax.
Note
There must be no leading or trailing whitespace.
- Parameters:
Arg1 – String to check
- Returns:
1 for true 0 for false
Example:
isnum(foo) ; Expands to 0 isnum(0x42) ; Expands to 1
- isr(Arg1, Arg2, [Arg3, ]Arg4)¶
ISR definition.
This creates an ISR that takes care of saving registers on the stack. Do not use returni instructions in the code body. Instead call the leave_func() macro. By default the ISR returns with interrupts enabled. You can leave them disabled by passing “disable” as Arg3.
- Parameters:
Arg1 – Address for ISR
Arg2 – Variable definitions (same format as passed to the vars() macro)
Arg3 – Optional return interrupt state “enable” | “disable” | empty
Arg4 – Code block for ISR body
Example:
isr(0x3FF, `s0, s1, s2', `load s0, 42 output s0, ff')
- jeq(Arg1)¶
Jump if equal.
- Parameters:
Arg1 – Label to jump to
Example:
compare s0, s1 jeq(is_equal) ; jumps if s0 == s1
- jge(Arg1)¶
Jump if greater or equal.
- Parameters:
Arg1 – Label to jump to
- jlt(Arg1)¶
Jump if less than.
- Parameters:
Arg1 – Label to jump to
Example:
compare s0, s1 jlt(less_than) ; jumps if s0 < s1
- jne(Arg1)¶
Jump if not equal.
- Parameters:
Arg1 – Label to jump to
- leave_func([Arg1])¶
Return from func() macro code bodies.
- Parameters:
Arg1 – Optional condition code (Z, NZ, C, or NC)
Example:
leave_func leave_func(Z)
- leave_isr([Arg1])¶
Return from isr() macro code bodies.
- Parameters:
Arg1 – Optional condition code (Z, NZ, C, or NC)
Example:
leave_isr(Z)
- load16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit load.
- Parameters:
Arg1 – MSB destination register
Arg2 – LSB destination register
Arg3 – Decimal constant or expression or source MSB when Arg4 is present
Arg4 – Optional register for source LSB
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a constant literal. When four arguments are passed, Arg3 and Arg4 are a 16-bit register pair copied to the destination.
Example:
load16(s1, s0, 2014) ; Load 16-bit literal load16(s1, s0, 200 * 11 + 5) ; Load 16-bit constant expresson load16(s1, s0, s3, s2) ; Load 16-bits from a register pair load16(rx, ry) ; Assuming rx and ry are reg16 definitions
- load_out(Arg1, Arg2[, Arg3])¶
Load a register with a value and output to a port.
- Parameters:
Arg1 – Value to load (constant or other register)
Arg2 – Port to output to
Arg3 – Optional register to load with value, uses _tempreg if omitted
Example:
load_out(0x5A, 0x10) ; Write 0x5A to port 0x10 using _tempreg load_out(0x5A, 0x10, sA) ; Write 0x5A to port 0x10 using sA
- load_store(Arg1, Arg2[, Arg3])¶
Load a register with a value and store to scratchpad.
- Parameters:
Arg1 – Value to load (constant or other register)
Arg2 – Scratchpad address to output to (constant or a register)
Arg3 – Optional Register to load with value, uses _tempreg if omitted
Example:
load_store(0x42, 0x20) ; Store 0x42 at scratchpad address 0x20 using _tempreg load_store(0x42, 0x20, sA) ; Store 0x42 at scratchpad address 0x20 using sA
- loadaddr(Arg1, Arg2, Arg3)¶
Load a 16-bit address from a label.
- Parameters:
Arg1 – MSB destination register
Arg2 – LSB destination register
Arg3 – Address label
- Returns:
Result in Arg1, Arg2
Example:
my_func: return loadaddr(s1,s0, my_func)
- mask(Arg1-ArgN)¶
Define a mask with specific bits set.
- Parameters:
Arg1-ArgN – Bit numbers to set in mask (0-7)
Example:
mask(0, 1, 2, 7) ; Expands to 135 = 0x87
- maskh(Arg1)¶
Alternate mask that can be used as a direct argument to a PicoBlaze instruction.
- Parameters:
Arg1 – Bit numbers to set in mask (0-7)
- Returns:
A mask in PicoBlaze hex format
Example:
test s0, maskh(3,4,5) ; Test if bits 3, 4, and 5 are clear jump z, is_clear
- mem16(Arg1, Arg2, Arg3)¶
Create a constant for 16-bit memory and port addresses. This is similar to
reg16()
but it also generates named constants with “_H” and “_L” suffixes for byte access.- Parameters:
Arg1 – Name of constant
Arg2 – MSB address
Arg3 – LSB address
Example:
mem16(M_DATA, 0x05, 0x04) ; Allocate scratchpad 05, 04 for use as M_DATA load s0, M_DATA_L ; load address 0x04 load s1, M_DATA_H ; load address 0x05
- negate(Arg1)¶
2s complement negation.
- Parameters:
Arg1 – Register to negate
- Returns:
Result is in the same register
Example:
load s0, 10'd negate(s0) ; Result is -10
- negate16(Arg1, Arg2)¶
16-bit 2s-complement negation.
- Parameters:
Arg1 – MSB register to negate
Arg2 – LSB register to negate
Result in Arg1, Arg2
Example:
load16(s1,s0, -2600) negate16(s1, s0) ; s1,s0 pair now contain +2600
- nop()¶
No-op macro. Delay by one instruction without affecting processor state.
- not(Arg1)¶
Logical not.
- Parameters:
Arg1 – Register to invert
- Returns:
Result is in the same register
Example:
load s0, 5A not(s0) ; Result is 0xA5
- not16(Arg1, Arg2)¶
16-bit logical not.
- Parameters:
Arg1 – MSB register to invert
Arg2 – LSB register to invert
Result in Arg1, Arg2
Example:
load16(s1,s0, 0x8F5A) not16(s1, s0) ; s1,s0 pair now contain 0x70A5
- or16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit logical OR.
- Parameters:
Arg1 – MSB1
Arg2 – LSB1
Arg3 – Decimal constant or expression or MSB2 when Arg4 is present
Arg4 – Optional register for LSB2
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a constant literal. When four arguments are passed, Arg3 and Arg4 are a 16-bit pair to OR to the result.
Example:
load16(s1,s0, 0x10F0) or16(s1,s0, 0x008F) ; Result is 0x10FF or16(s1,s0, s3,s2) ; (s1,s0) OR (s3,s2)
- output16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit output.
- Parameters:
Arg1 – MSB register of source
Arg2 – LSB register of source
Arg3 – Register pointing to low byte or MSB of output address when Arg4 is present
Arg4 – Optional register for LSB of output address
When three arguments are passed, Arg3 is a register pointing to the low byte to output to. It is incremented twice to permit sequential use of output16(). When four arguments are passed, Arg3 and Arg4 are a 16-bit pair of port address constants to output to.
Example:
load16(rx, 2014) output16(rx, P_ACCUM) ; Output direct to port address load s0, P_ACCUM_L output16(rx, s0) ; Output to indirect pointer output16(rx, s0) ; Output next word
- outputstring(Arg1, Arg2, Arg3)¶
Repeated string output operation.
- Parameters:
Arg1 – Output port in m4 integer format or a constant name
Arg2 – Register used to hold characters
Arg3 – String to split into characters
Example:
constant UART_PORT, 0a outputstring(UART_PORT, s1, `My string') Expands to: load s1, "M" output s1, UART_PORT load s1, "y" output s1, UART_PORT ... outputstring(0x0A, s1, `My string') ; Without using a constant
- outputtable(Arg1, Arg2, Arg3-ArgN)¶
Output a table of constants.
- Parameters:
Arg1 – Output port in m4 integer format or a constant name
Arg2 – Temporary register for each constant
Arg3-ArgN – Decimal values to output to port
Example:
constant UART_PORT, 0a outputtable(UART_PORT, sF, pbhex(DE,AD,BE,EF)) ; Output DE,AD,BE,EF to port
- pb2m4(Arg1)¶
Convert PicoBlaze literals into m4 syntax. Performs the following conversions:
Character literal to ASCII ordinal:
"c" -> 99
Decimal to integer:
20'd -> 20
Hex to integer:
5A -> 90
Binary to integer:
1100'b -> 12
- Parameters:
Arg1 – String to convert
- Returns:
An integer in m4 syntax.
Example:
pb2m4(10'd) expands to 10, pb2m4("0") expands to 48
- pbhex(Arg1-ArgN)¶
Convert a list of values in PicoBlaze hex format to decimal.
- Parameters:
Arg1-ArgN – Hex values to convert
Example:
pbhex(01, 02, 03, 0a, ff) ; Expands to 1, 2, 3, 10, 255
- pop(Arg1-ArgN)¶
Pop register values from a simulated stack in scratchpad RAM.
Arguments should be passed in the same order as push() to restore register contents.
- Parameters:
Arg1-ArgN – Registers with values to pop
See also
push()
for more information.
- popvars()¶
Remove definitions from previous call to vars().
- proc(Arg1, Arg2, Arg3)¶
Procedure definition.
- Parameters:
Arg1 – Label for procedure
Arg2 – Variable definitions (same format as passed to the vars() macro)
Arg3 – Code block for proc body
Example:
proc(add2, `s0 is result', `add result, 02') ... load s0, 42 call add2
- push(Arg1-ArgN)¶
Push register values onto a simulated stack in scratchpad RAM.
The stack pointer grows from the end of the scratchpad to the start.
- Parameters:
Arg1-ArgN – Registers with values to push
Example:
use_stack(sa, 0x3F) push(s0) pop(s1) push(s3, s4, s5) ; Push and pop multiple registers at once pop(s3, s4, s5) ; Pop is performed in reverse order from push
- putstack(Arg1-ArgN)¶
Store multiple contiguous values on the stack without changing the stack pointer.
- Parameters:
Arg1-ArgN – Registers to store values from The first register corresponds to the highest address
Example:
putstack(s3, s4, s5) ; Put s3, s4, s5 into stack offset SP+3, SP+2, and SP+1
- putstackat(Arg1, Arg2)¶
Store values to the stack without changing the stack pointer.
- Parameters:
Arg1 – Register with value to store
Arg2 – Offset from stack pointer (offset 1 is the first value) or a register
Example:
putstackat(s3, 2) ; Put the second value relative to the stack pointer putstackat(s3, s0) ; Put stack value pointed at by s0
- qstr(Arg1)¶
Add double quotes around a string. This is allows the use of macros to generate strings where substitution within “” would normally be suppressed.
- Parameters:
Arg1 – String to quote
Example:
define(DATE_STAMP, `1 Jan 2015') string mystr$, qstr(DATE_STAMP) ; Expands to string mystr$, "1 Jan 2015"
- randlabel([Arg1])¶
Generate a random name for a label.
- Parameters:
Arg1 – Optional prefix to name
Example:
randlabel(PREFIX_) ; Expands to "__PREFIX_?????"
- reg16(Arg1, Arg2, Arg3)¶
Create a virtual 16-bit register. The defined name can be used in place of the MSB, LSB pairs used in other 16-bit macros.
- Parameters:
Arg1 – Name of virtual register
Arg2 – MSB register
Arg3 – LSB register
Example:
reg16(rx, s1, s0) ; rx = (s1, s0) reg16(ry, s5, s4) ; ry = (s5, s4) add16(rx, ry) ; rx = rx + ry add16(rx, s3, s2) ; rx = rx + (s3, s2)
- reglower(Arg1, Arg2)¶
Get the lower register from a
reg16()
ormem16()
definition.- Parameters:
Arg1 – MSB of 16-bit register pair
Arg2 – LSB of 16-bit register pair
See also
regupper()
for more information.
- regupper(Arg1, Arg2)¶
Get the upper register from a
reg16()
ormem16()
definition.- Parameters:
Arg1 – MSB of 16-bit register pair
Arg2 – LSB of 16-bit register pair
Example:
reg16(rx, s5, s4) load s1, regupper(rx) ; load upper byte from s5 (rx expands to "s5,s4") load s1, reglower(rx) ; load lower byte from s4
- repeat(Arg1, Arg2)¶
Repeat an instruction or macro.
- Parameters:
Arg1 – Instruction or macro string to repeat
Arg2 – Numper of repetitions
Example:
repeat(`output s0, 00', 3)
- repeatstr(Arg1, Arg2)¶
Repeat a string.
- Parameters:
Arg1 – Instruction or macro string to repeat
Arg2 – Numper of repetitions
Example:
repeat(`A', 3) ; Expands to "AAA"
- reteq()¶
Return if equal.
Example:
compare s0, s1 reteq ; return if s0 == s1
- retge()¶
Return if greater or equal.
- retlt()¶
Return if less than.
- retne()¶
Return if not equal.
- retvalue(Arg1, Arg2)¶
Place func return value onto the stack.
Only call this macro inside a func code body
- Parameters:
Arg1 – Register with value to save
Arg2 – Offset from end of return frame (starting at 1)
Example:
retvalue(s0, 1) ; First return value to be popped off after return retvalue(s1, 2) ; Second value to return from func
- reverse(Arg1-ArgN)¶
Reverse arguments.
- Parameters:
Arg1-ArgN – List of arguments to reverse
Example:
reverse(1,2,3) ; Expands to 3,2,1
- rl(Arg1, Arg2)¶
Multi-bit rotate left.
- Parameters:
Arg1 – Register to rotate
Arg2 – Number of shifts
Example:
rl(s2, 4) ; Rotate left by 4
- rl16(Arg1, Arg2, Arg3)¶
16-bit rotate left.
- Parameters:
Arg1 – MSB register to rotate
Arg2 – LSB register to rotate
Arg3 – Number of bits to rotate (0-16)
- rr(Arg1, Arg2)¶
Multi-bit rotate right.
- Parameters:
Arg1 – Register to rotate
Arg2 – Number of shifts
Example:
rr(s2, 4) ; Rotate right by 4
- rr16(Arg1, Arg2, Arg3)¶
16-bit rotate right.
- Parameters:
Arg1 – MSB register to rotate
Arg2 – LSB register to rotate
Arg3 – Number of bits to rotate (0-16)
- setbit(Arg1, Arg2)¶
Set and clear bits in a register.
- Parameters:
Arg1 – Register to modify
Arg2 – Bit number (0-7) to set or clear
Example:
setbit(s0, 2)
- setcy([Arg1])¶
Set the carry flag.
- Parameters:
Arg1 – Optional temporary register to modify. Uses temp register by default.
Example:
setcy setcy(sF)
- setmask(Arg1, Arg2)¶
Set mask bits in a register.
- Parameters:
Arg1 – Register to modify
Arg2 – Mask value
Example:
setmask(s5, mask(0,1,2)) setmask(s4, 0xF1)
- signed(Arg1)¶
Convert a Boolean expression to use signed comparison.
- Parameters:
Arg1 – Expression to convert
This is used in the expression passed to the if(), for(), while(), and dowhile() macros to invoke signed comparison.
Example:
signed(s0 < 4) ; Expands to "s0 s< 4"
- signex(Arg1, Arg2)¶
Sign extension.
This extends the sign from an 8-bit number into a new register producing a 16-bit result. The argument order allows you to use this with virtual registers created with
reg16()
.- Parameters:
Arg1 – Register to extend sign into (MSB)
Arg2 – Register to test for sign bit (LSB)
Example:
load s0, 81 ; Sign bit is set signex(s1, s0) ; s1 now contains 0xFF reg16(rx, s4,s5) load reglower(rx), 82 signex(rx)
- sl0(Arg1, Arg2)¶
Multi-bit shift left with ‘0’ insert.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
sl0(s2, 4) ; Shift left by 4
- sl0_16(Arg1, Arg2, Arg3)¶
16-bit shift left, inserting ‘0’.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- sl1(Arg1, Arg2)¶
Multi-bit shift left with ‘1’ insert.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
sl1(s2, 4) ; Shift left by 4
- sl1_16(Arg1, Arg2, Arg3)¶
16-bit shift left, inserting ‘1’.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- sla(Arg1, Arg2)¶
Multi-bit shift left with C insert.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
sla(s2, 4) ; Shift left by 4
- sla_16(Arg1, Arg2, Arg3)¶
16-bit arithmetic shift left, inserting C flag.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- slx(Arg1, Arg2)¶
Multi-bit shift left with LSB sign extension.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
slx(s2, 4) ; Shift left by 4
- slx_16(Arg1, Arg2, Arg3)¶
16-bit sign extending shift left, duplicating LSB.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- sr0(Arg1, Arg2)¶
Multi-bit shift right with ‘0’ insert.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
sr0(s2, 4) ; Shift right by 4
- sr0_16(Arg1, Arg2, Arg3)¶
16-bit shift right, inserting ‘0’.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- sr1(Arg1, Arg2)¶
Multi-bit shift right with ‘1’ insert.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
sr1(s2, 4) ; Shift right by 4
- sr1_16(Arg1, Arg2, Arg3)¶
16-bit shift right, inserting ‘1’.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- sra(Arg1, Arg2)¶
Multi-bit shift right with C insert.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
sra(s2, 4) ; Shift right by 4
- sra_16(Arg1, Arg2, Arg3)¶
16-bit arithmetic shift right, inserting C flag.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- srx(Arg1, Arg2)¶
Multi-bit shift right with MSB sign extension.
- Parameters:
Arg1 – Register to shift
Arg2 – Number of shifts
Example:
srx(s2, 4) ; Shift right by 4
- srx_16(Arg1, Arg2, Arg3)¶
16-bit sign extending shift right, duplicating MSB.
- Parameters:
Arg1 – MSB register to shift
Arg2 – LSB register to shift
Arg3 – Number of bits to shift (0-16)
- store16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit store.
- Parameters:
Arg1 – MSB register of source
Arg2 – LSB register of source
Arg3 – Register pointing to low byte or MSB of target address when Arg4 is present
Arg4 – Optional register for LSB of target address
When three arguments are passed, Arg3 is a register pointing to the low byte to store to. It is incremented twice to permit sequential use of store16(). When four arguments are passed, Arg3 and Arg4 are a 16-bit pair of address constants to store to.
Example:
load16(rx, 2014) store16(rx, M_ACCUM) ; Store direct to address load s0, M_ACCUM_L store16(rx, s0) ; Store to indirect pointer store16(rx, s0) ; Store next word
- storestring(Arg1, Arg2[, Arg3])¶
Store a string to scratchpad RAM.
- Parameters:
Arg1 – Address of first byte
Arg2 – String to store
Arg3 – Optional register to load each character, uses _tempreg if omitted
Example:
storestring(0x10, `Hello')
- storestringat(Arg1, Arg2[, Arg3])¶
Store a string to scratchpad RAM using a register address.
- Parameters:
Arg1 – Pointer register to scratchpad address
Arg2 – String to store
Arg3 – Optional register to load each character, uses _tempreg if omitted
The pointer register will finish with the address of the last character in the string.
Example:
load s0, M_BUFFER storestringat(s0, `Hello')
- storetable(Arg1, Arg2, Arg3-ArgN)¶
Store a table of constants in scratchpad RAM.
- Parameters:
Arg1 – Address of first byte
Arg2 – Temporary register for each constant
Arg3-ArgN – Decimal values to load in scratchpad
Example:
load s1, my_array storetable(0x10, sF, pbhex(DE,AD,BE,EF)) ; Load DE,AD,BE,EF into memory storetable(0x10, sF, 10, 11, 12) ; Load decimals
- storetableat(Arg1, Arg2, Arg3-ArgN)¶
Store a table of constants in scratchpad RAM.
- Parameters:
Arg1 – Pointer register to scratchpad address
Arg2 – Temporary register for each constant
Arg3-ArgN – Decimal values to load in scratchpad
The pointer register will finish with the address of the last byte in the table.
Example:
load s1, my_array storetableat(s1, sF, pbhex(DE,AD,BE,EF)) ; Load DE,AD,BE,EF into memory storetableat(s1, sF, 10, 11, 12) ; Load decimals
- strhash(Arg1)¶
Generate a 16-bit checksum constant from a string using the BSD algorithm. This does not dynamically compute a hash from variable data. It can be used to seed a PRNG from a build time string like a timestamp.
- Parameters:
Arg1 – String to compute hash over
Example:
strhash(`Hello world') ; Expands to 27566 reg16(RS, s0, s1) load16(RS, strhash(DATE_STAMP TIME_STAMP)) ; Seed the PRNG with the build time call random16
- strlenc(Arg1)¶
Return the length of a string constant, a portable string or a packed string. The argument is passed through the
estr()
macro to collapse escaped characters before counting them.- Parameters:
Arg1 – String to count length from. This is either a constant or the label to a string defined with string() or packed_string()
Example:
load s0, strlenc(`foobar\r\n') ; Expands to 8 packed_string(xyzzy, `This is a string') load s0, strlenc(xyzzy) ; Expands to 16
- sub16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit subtraction.
- Parameters:
Arg1 – MSB1 register
Arg2 – LSB1 register
Arg3 – Decimal constant or expression or MSB2 when Arg4 is present
Arg4 – Optional register for LSB2
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a constant literal. When four arguments are passed, Arg3 and Arg4 are a 16-bit pair to add to the result.
Example:
sub16(s1,s0, 0x1234) ; s1,s0 -= 0x1234 sub16(s1,s0, s3,s2) ; s1,s0 -= s3,s2 sub16(rx, ry) ; rx -= ry
- swap(Arg1, Arg2)¶
Swap registers.
- Parameters:
Arg1 – Register 1
Arg2 – Register 2
Example:
swap(s0, s1) ; s1 -> s0 and s0 -> s1
- test16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit test.
- Parameters:
Arg1 – MSB1
Arg2 – LSB1
Arg3 – Decimal constant or expression or MSB2 when Arg4 is present
Arg4 – Optional register for LSB2
When three arguments are passed, Arg3 is a constant literal. When four arguments are passed, Arg3 and Arg4 are a 16-bit pair to use with the TEST comparison. .. note:
On PicoBlaze-3, only the Z flag is set properly. On PicoBlaze-6 the C flag contains the XOR (odd parity) of all bits.
Example:
load16(s1,s0, 0x10F0) test16(s1,s0, 0x0080) ; Z flag is clear test16(s1,s0, 0x0800) ; Z flag is set
- testbit(Arg1, Arg2)¶
Test if a bit is set or clear.
- Parameters:
Arg1 – Register to test
Arg2 – Bit number (0-7) to test
Z is set if bit is clear, Z is clear if bit is set
Example:
testbit(s1, 3) jump z, bit_cleared
- uniqlabel([Arg1])¶
Generate a unique name for a label. The labels will be unique to each included file.
- Parameters:
Arg1 – Optional prefix to name
Example:
uniqlabel(PREFIX_) ; Expands to "__PREFIX_f0_0001"
- use_ascii2bcd(Arg1, Arg2, Arg3)¶
Generate a function to convert an ASCII number to BCD. Invalid characters are converted to “0” digits.
- Parameters:
Arg1 – Name of function to generate
Arg2 – Register for first function argument, the scratchpad address of the ASCII data
Arg3 – Register for length of the data
- Returns:
The generated function has no return value. All registers are preserved on the stack.
Example:
use_ascii2bcd(ascii2bcd, s0, s1) load s0, 20 ; Array address load s1, 05 ; Length call ascii2bcd ; The array now contains all BCD digits
- use_bcd2int(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)¶
Generate a function to convert an unpacked BCD coded bytes to a variable size integer.
The BCD input is stored in a buffer in scratchpad memory. The buffer address and length are passed as arguments. The converted result is overwritten to the leftmost portion of the buffer. The length register returns with the number of bytes in the result. This function handles conversion to any size integer as the result is guaranteed to be smaller than the initial buffer. Internal temp registers must be allocated for use by the macro. They must not include the _tempreg register.
- Parameters:
Arg1 – Name of function to generate
Arg2 – First argument of generated function. Register with scratchpad BCD address
Arg3 – Register with number of bytes for scratchpad buffer
Arg4 – Internal temp register
Arg5 – Internal temp register
Arg6 – Internal temp register
Arg7 – Internal temp register
Arg8 – Internal temp register
- Returns:
The converted integer value is located at the start of the buffer with the LSB first, opposite to the order of the BCD digits. The number of bytes in the converted integer is returned in the second argument to the function (Arg3 of this generator macro). All other registers are preserved on the stack.
Example:
use_bcd2int(bcd2int, s0, s1, s2,s3,s4,s5,s6) load s0, 20 ; BCD buffer load s1, 03 ; 3 BCD digits long call bcd2int ; s1 contains the number of converted bytes ; scratchpad 20 (and possibly 21) contain the binary result
- use_bcdwrite(Arg1, Arg2, Arg3, Arg4)¶
Generate a function to write an array of BCD coded bytes to an output port.
- Parameters:
Arg1 – Name of function to generate
Arg2 – Register for first function argument, the scratchpad address of the source BCD data
Arg3 – Register for number of bytes to write
Arg4 – Port address to write. This is a fixed value that can’t be changed at runtime
- Returns:
The generated function has no return value. All registers are preserved on the stack.
Example:
constant ConsolePort, FE use_bcdwrite(bcdwrite, s0, s1, ConsolePort) load s0, 20 ; Source address load s1, 05 ; Write 5 bytes call bcdwrite
- use_clock(Arg1)¶
Define system clock frequency.
Only invoke once. Must be executed before any delay macros.
- Parameters:
Arg1 – Clock frequency in MHz. Limited to integer values.
Example:
use_clock(50) ; 50 MHz clock
- use_delay_reg(Arg1)¶
Define delay loop register.
Only invoke once. Must be executed before any delay macros. This register must be different from the registers used in the delay_us() and delay_ms() macros.
- Parameters:
Arg1 – Register to use for inner loop counter
Example:
use_delay_reg(sA)
- use_divide16x8(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7[, Arg8])¶
Divide 16 / 8 subroutine. Implements truncating division.
- Parameters:
Arg1 – Subroutine name
Arg2 – Dividend MSB
Arg3 – Dividend LSB
Arg4 – Divisor
Arg5 – Quotient MSB
Arg6 – Quotient LSB
Arg7 – Remainder
Arg8 – Optional preamble code block. Also supresses return statement if present.
The temp register is overwritten. It is sE by default. Call use_tempreg(reg_name) before invoking this macro to change it. The MSB of the dividend is destroyed.
Example:
use_divide16x8(div16, s0,s1, s2, s3,s4, s5) ; (s3,s4) (rem s5) <= (s0,s1) / s2 load16(s0,s1, 400) load s2, 5'd call div16
- use_divide16x8s(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7[, Arg8])¶
Signed Divide 16 / 8 subroutine. Implements truncating division.
- Parameters:
Arg1 – Subroutine name
Arg2 – Dividend MSB (signed)
Arg3 – Dividend LSB
Arg4 – Divisor (signed)
Arg5 – Quotient MSB (signed)
Arg6 – Quotient LSB
Arg7 – Remainder
Arg8 – Optional preamble code block. Also supresses return statement if present.
The temp register is overwritten. It is sE by default. Call use_tempreg(reg_name) before invoking this macro to change it. The MSB of the dividend is destroyed.
Example:
use_divide16x8s(div16, s0,s1, s2, s3,s4, s5) ; (s3,s4) (rem s5) <= (s0,s1) / s2 load16(s0,s1, -400) load s2, 5'd call div16
- use_divide8x8(Arg1, Arg2, Arg3, Arg4, Arg5[, Arg6])¶
Divide 8 / 8 subroutine. Implements truncating division.
- Parameters:
Arg1 – Subroutine name
Arg2 – Dividend
Arg3 – Divisor
Arg4 – Quotient
Arg5 – Remainder
Arg6 – Optional preamble code block. Also supresses return statement if present.
The temp register is overwritten. It is sE by default. Call use_tempreg(reg_name) before invoking this macro to change it.
Example:
use_divide8x8(div8, s0, s1, s2, s3) ; s2 (rem s3) <= s0 / s1 load s0, 20'd load s1, 4'd call div8
- use_divide8x8s(Arg1, Arg2, Arg3, Arg4, Arg5[, Arg6])¶
Signed Divide 8 / 8 subroutine. Implements truncating division.
- Parameters:
Arg1 – Subroutine name
Arg2 – Dividend (signed)
Arg3 – Divisor (signed)
Arg4 – Quotient
Arg5 – Remainder
Arg6 – Optional preamble code block. Also supresses return statement if present.
Same arguments as unsigned 8 / 8 divide. .. seealso::
use_divide8x8()
for more information.
- use_divide8xk(Arg1, Arg2, Arg3, Arg4)¶
Divide 8 / constant subroutine with 8-bit result.
- Parameters:
Arg1 – Subroutine name
Arg2 – Dividend
Arg3 – Constant divisor (can be wider than 8-bits)
Arg4 – Result quotient
Example:
use_divide8xk(div8k5, s0, 5, s4) ; s4 = s0 / 5 load s0, 30'd call div8k5 ; 30 / 5 => 6
- use_expr_all()¶
Configure all multiplication and divide subroutines. Use this in conjunction with Opbasm’s dead code removal to guarantee that only the arithmetic subroutines in use will be assembled. This is equivalent to calling the following macros with no arguments:
- use_expr_div([Arg1, Arg2, Arg3, Arg4])¶
Configure unsigned division for expressions. All arguments are optional.
- Parameters:
Arg1 – Optional Dividend (default is s8)
Arg2 – Optional Divisor (default is s9)
Arg3 – Optional Internal result Quotient (default is sA) preserved on stack
Arg4 – Optional Internal result Remainder (default is sB) preserved on stack
- Returns:
The result is copied to Arg1, Arg2
- use_expr_div16([Arg1, Arg2, Arg3, Arg4, Arg5, Arg6])¶
Configure unsigned 16x8 division for expressions. This creates a new function “expr_div16” used by the expr2() macro.
- Parameters:
Arg1 – Optional MSB of Dividend (default is s7)
Arg2 – Optional LSB of Dividend (default is s8)
Arg3 – Optional Divisor (default is s9)
Arg4 – Optional MSB of Quotient (default is sA)
Arg5 – Optional LSB of Quotient (default is sB)
Arg6 – Optional Remainder (default is sC)
- Returns:
The generated function places the quotient in Arg1,Arg2 and the remainder in Arg3.
Arg4-6 act as temp registers and are restored from the stack.
- use_expr_div16s([Arg1, Arg2, Arg3, Arg4, Arg5, Arg6])¶
Configure signed 16x8 division for expressions. This creates a new function “expr_div16s” used by the expr2s() macro.
- Parameters:
Arg1 – Optional MSB of Dividend (default is s7)
Arg2 – Optional LSB of Dividend (default is s8)
Arg3 – Optional Divisor (default is s9)
Arg4 – Optional MSB of Quotient (default is sA)
Arg5 – Optional LSB of Quotient (default is sB)
Arg6 – Optional Remainder (default is sC)
- Returns:
The generated function places the quotient in Arg1,Arg2 and the remainder in Arg3.
Arg4-6 act as temp registers and are restored from the stack.
- use_expr_divs([Arg1, Arg2, Arg3, Arg4])¶
Configure signed division for expressions. All arguments are optional.
- Parameters:
Arg1 – Optional Dividend (default is s8)
Arg2 – Optional Divisor (default is s9)
Arg3 – Optional Internal result Quotient (default is sA) preserved on stack
Arg4 – Optional Internal result Remainder (default is sB) preserved on stack
- Returns:
The result is copied to Arg1, Arg2
- use_expr_mul([Arg1, Arg2, Arg3, Arg4])¶
Configure unsigned multiplication for expressions. All arguments are optional.
- Parameters:
Arg1 – Optional Multiplicand (default is s8)
Arg2 – Optional Multiplier (default is s9)
Arg3 – Optional Internal result MSB (default is sA) preserved on stack
Arg4 – Optional Internal result LSB (default is sB) preserved on stack
- Returns:
The result is copied to Arg1, Arg2
- use_expr_muls([Arg1, Arg2, Arg3, Arg4])¶
Configure signed multiplication for expressions. All arguments are optional.
- Parameters:
Arg1 – Optional Multiplicand (default is s8)
Arg2 – Optional Multiplier (default is s9)
Arg3 – Optional Internal result MSB (default is sA) preserved on stack
Arg4 – Optional Internal result LSB (default is sB) preserved on stack
- Returns:
The result is copied to Arg1, Arg2
- use_expr_mulsu([Arg1, Arg2, Arg3, Arg4])¶
Configure signedxunsigned (16x8) multiplication for expressions. All arguments are optional.
- Parameters:
Arg1 – Optional Multiplicand (default is s8)
Arg2 – Optional Multiplier (default is s9)
Arg3 – Optional Internal result MSB (default is sA) preserved on stack
Arg4 – Optional Internal result LSB (default is sB) preserved on stack
- Returns:
The result is copied to Arg1, Arg2
- use_hexwrite(Arg1, Arg2, Arg3, Arg4)¶
Generate a function to write an array to an output port as ASCII hex.
- Parameters:
Arg1 – Name of function to generate
Arg2 – Register for first function argument, the scratchpad address of the source data
Arg3 – Register for number of bytes to write
Arg4 – Port address to write. This is a fixed value that can’t be changed at runtime
- Returns:
The generated function has no return value. All registers are preserved on the stack.
Example:
constant ConsolePort, FE use_hexwrite(hexwrite, s0, s1, ConsolePort) load s0, 20 ; Source address load s1, 05 ; Write 5 bytes call hexwrite
- use_int2bcd(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)¶
Generate a function to convert an integer to unpacked BCD coded bytes stored in a scratchpad buffer.
The number to convert is passed on the stack as one or more bytes with the MSB pushed last. The buffer size is fixed after generating the function. You must ensure it is large enough to contain the largest integer you expect to convert. Each buffer byte corresponds to one decimal digit. The converted BCD number is right justified within the buffer with leading 0’s for padding. The least significant digit is always at the end of the buffer.
- Parameters:
Arg1 – Name of function to generate
Arg2 – Number of bytes for scratchpad buffer (fixed constant)
Arg3 – First argument of generated function. Register with destination scratchpad address
Arg4 – Register containing number of bytes of data to convert on the stack
Arg5 – Internal temp register
Arg6 – Internal temp register
Arg7 – Internal temp register
Arg8 – Internal temp register
- Returns:
The generated function has no return value. All registers are preserved on the stack.
Example:
use_int2bcd(int2bcd, 5, s0, s1, s2, s3, s4, s5) ; Support up to 5 decimal digits load s0, 20 ; Dest address load s1, 02 ; Convert 16-bit number (2-bytes) load16(s4,s3, 31337) push(s3,s4) ; Put number to convert on stack; LSB then MSB call int2bcd
- use_memcopy(Arg1, Arg2, Arg3, Arg4)¶
Generate a function to copy an array in scratchpad memory.
- Parameters:
Arg1 – Name of function to generate
Arg2 – Register for first function argument, the scratchpad address of the source array
Arg3 – Register for destination address
Arg4 – Register for number of bytes to copy
- Returns:
The generated function has no return value. All registers are preserved on the stack.
Example:
use_memcopy(memcopy, s0, s1, s2) load s0, 20 ; Source address load s1, 30 ; Dest address load s2, 05 ; Copy 5 bytes call memcopy
- use_memset(Arg1, Arg2, Arg3, Arg4)¶
Generate a function to set an array in scratchpad memory.
- Parameters:
Arg1 – Name of function to generate
Arg2 – Register for first function argument, the scratchpad address of the destination array
Arg3 – Register for number of bytes to copy
Arg4 – Register for value to set array bytes to
- Returns:
The generated function has no return value. All registers are preserved on the stack.
Example:
use_memset(memset, s0, s1, s2) load s0, 20 ; Destination address load s1, 05 ; Copy 5 bytes load s2, 00 ; Set all bytes to 0 call memset
- use_memwrite(Arg1, Arg2, Arg3, Arg4)¶
Generate a function to write an array of bytes to an output port.
- Parameters:
Arg1 – Name of function to generate
Arg2 – Register for first function argument, the scratchpad address of the source array
Arg3 – Register for number of bytes to write
Arg4 – Port address to write. This is a fixed value that can’t be changed at runtime
- Returns:
The generated function has no return value. All registers are preserved on the stack.
Example:
constant ConsolePort, FE use_memwrite(memwrite, s0, s1, ConsolePort) load s0, 20 ; Source address load s1, 05 ; Write 5 bytes call memwrite
- use_multiply8x8(Arg1, Arg2, Arg3, Arg4, Arg5[, Arg6])¶
Multiply 8 x 8 subroutine.
- Parameters:
Arg1 – Subroutine name
Arg2 – Multiplicand
Arg3 – Multiplier
Arg4 – Result MSB
Arg5 – Result LSB
Arg6 – Optional preamble code block. Also supresses return statement if present.
The temp register is overwritten. It is sE by default. Call use_tempreg(reg_name) before invoking this macro to change it. The optional code block can be used to insert initialization code at the beginning of the generated subroutine. The final
return
is omitted so that you can also append finalization code. You must provide an explicitreturn
when the preamble block is in use.Example:
use_multiply8x8(mul8, s0, s1, s3, s2) ; (s3, s2) = s0 * s1 load s0, 04 load s1, 05 call mul8
- use_multiply8x8s(Arg1, Arg2, Arg3, Arg4, Arg5[, Arg6])¶
Signed Multiply 8 x 8 subroutine.
- Parameters:
Arg1 – Subroutine name
Arg2 – Multiplicand (signed)
Arg3 – Multiplier (signed)
Arg4 – Result MSB
Arg5 – Result LSB
Arg6 – Optional preamble code block. Also supresses return statement if present.
Same arguments as unsigned multiply. Both arguments are treated as signed numbers. .. seealso::
use_multiply8x8()
for more information.
- use_multiply8x8su(Arg1, Arg2, Arg3, Arg4, Arg5[, Arg6])¶
SignedxUnsigned Multiply 8 x 8 subroutine.
- Parameters:
Arg1 – Subroutine name
Arg2 – Multiplicand (signed)
Arg3 – Multiplier (unsigned)
Arg4 – Result MSB
Arg5 – Result LSB
Arg6 – Optional preamble code block. Also supresses return statement if present.
Same arguments as unsigned multiply. Only the multiplicand is treated as signed. .. seealso::
use_multiply8x8()
for more information.
- use_multiply8xk(Arg1, Arg2, Arg3, Arg4, Arg5)¶
Multiply 8 x constant subroutine with 16-bit result.
- Parameters:
Arg1 – Subroutine name
Arg2 – Multiplicand
Arg3 – Constant multiplier (can be wider than 8-bits)
Arg4 – Result MSB
Arg5 – Result LSB
Example:
use_multiply8xk(mul8k5, s0, 5, s5, s4) ; (s5, s4) = s0 * 5 load s0, 7'd call mul8k5 ; 7 * 5 => 35
- use_multiply8xk_small(Arg1, Arg2, Arg3, Arg4)¶
Multiply 8 x constant subroutine with 8-bit result.
- Parameters:
Arg1 – Subroutine name
Arg2 – Multiplicand
Arg3 – Constant multiplier
Arg4 – Result byte
It is your responsibility to ensure that the result doesn’t overflow the size of a byte.
Example:
use_multiply8xk_small(mul8k5, s0, 5, s4) ; s4 = s0 * 5 load s0, 7'd call mul8k5 ; 7 * 5 => 35
- use_packed_strings(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6[, Arg7])¶
Configure packed string handling.
This uses string data packed into INST statements stored in big-endian order. You must provide a routine to read pairs of characters from a dual-ported memory. The packed_string() macro calls into a generic handler routine that scans for a NUL terminator on data read from an external ROM.
- Parameters:
Arg1 – Register to store even characters
Arg2 – Register to store odd characters
Arg3 – Register for MSB of address to string
Arg4 – Register for LSB of address to string
Arg5 – Label of user provided function to process each character (Only needs to handle the even char register)
Arg6 – Label of user provided function to read pairs of characters from memory
Arg7 – Optional name of macro to generate strings (default is “packed_string”)
Example:
use_packed_strings(s0, s1, s5,s4, write_char, read_next_chars) ; read_next_chars is called until a NUL is found ; write_char is called for each character stored in s0
This generates a new macro with the name used for Arg7. You must take steps to ensure that the normal execution path skips the instructions generated by this macro. It takes the following arguments:
- Parameters:
Arg1 – Label used to identify string
Arg2 – String value. This can contain all of the escape chars supported by estr/cstr
Example:
jump main packed_string(my_string, `Hello, World!\r\n') main: ... call my_string ; Output the string
- use_random16(Arg1, Arg2, Arg3, Arg4, Arg5)¶
16-bit pseudo-random number generator. Based on George Marsaglia’s xorshift algorithm. This generates a full cycle of 65535 values. Expands to 23 instructions.
- Parameters:
Arg1 – Label to use for random function
Arg2 – MSB of 16-bit random state variable (Initialize this with a non-zero seed)
Arg3 – LSB of 16-bit random state variable (Initialize this with a non-zero seed)
Arg4 – MSB of a 16-bit internal temp register
Arg5 – LSB of a 16-bit internal temp register
Example:
reg16(RS, s0,s1) use_random16(random, RS, sA, sB) ... load16(RS, 0x1234) ; Seed the PRNG (Use an external entropy source like an ADC in real life) call random
- use_random8(Arg1, Arg2)¶
8-bit pseudo-random number generator. Based on George Marsaglia’s xorshift algorithm. Generates a full cycle of 255 values. Expands to 11 instructions.
- Parameters:
Arg1 – label to use for random function
Arg2 – Random state variable (Initialize this with a non-zero seed)
The common temp register is destructively modified.
Example:
namereg s8, RS use_random8(random, RS) ... load RS, 5A ; Seed the PRNG (Use an external entropy source like an ADC in real life) call random
- use_stack(Arg1, Arg2)¶
Initialize and define stack pointer register.
Only invoke once. Must be executed before any push() or pop() macros
- Parameters:
Arg1 – Stack pointer register
Arg2 – Scratchpad address for top of stack
Example:
namereg sA, SP ; Reserve stack pointer register use_stack(SP, 0x3F) ; Start stack at end of 64-byte scratchpad
- use_strings(Arg1, Arg2, Arg3, Arg4[, Arg5])¶
Configure string handling for either PB3 or PB6.
This will set up a string output function for either platform On PB6, the string() macro calls into a generic handler routine that scans for a NUL terminator.
- Parameters:
Arg1 – Register to store each character
Arg2 – Register for MSB of address to string (Only used on PB6)
Arg3 – Register for LSB of address to string (Only used on PB6)
Arg4 – Label of user provided function to process each character
Arg5 – Optional name of macro to generate strings (default is “string”)
Example:
use_strings(s0, s5,s4, write_char) ; write_char is called for each character stored in s0 using the "string()" macro use_strings(s1, s5, s4, write_char_to_console, console_str) ; write_char_to_console is called for each character stored in s1 using the "console_str()" macro
This generates a new macro with the name used for Arg5. You must take steps to ensure that the normal execution path skips the instructions generated by this macro. It takes the following arguments:
- Parameters:
Arg1 – Label used to identify string
Arg2 – String value. This can contain all of the escape chars supported by estr/cstr
Example:
jump main string(my_string, `Hello, World!\r\n') main: ... call my_string ; Output the string
- use_tempreg(Arg1)¶
Define a common temporary register used by other macros. This allows you to change the temp register from its default of
sE
.- Parameters:
Arg1 – Register to use for temp register
Example:
use_tempreg(sA) load _tempreg, 01 ; Puts 0x01 into sA
- var_count_ms(Arg1, Arg2)¶
Generate 16-bit millisecond count for variable delay macro var_delay_ms().
- Parameters:
Arg1 – Milliseconds to delay
Arg2 – Max milliseconds for the delay loop (from definition using var_delay_ms())
- var_count_us(Arg1, Arg2)¶
Generate 16-bit microsecond count for variable delay macro var_delay_us().
- Parameters:
Arg1 – Microseconds to delay
Arg2 – Max microseconds for the delay loop (from definition using var_delay_us())
- var_delay_ms(Arg1, Arg2, Arg3)¶
Variable delay by milliseconds
- Parameters:
Arg1 – Maximum milliseconds to delay
Arg2 – MSB of delay counter
Arg3 – LSB of delay counter
The var_count_ms() macro generates a 16-bit count value that is loaded into the counter registers before calling the delay function.
Example:
use_clock(50) ; 50 MHz clock define(MAXDELAY, 10) ; 10ms max delay reg16(dly_count, s4,s5) delay: var_delay_ms(MAXDELAY, dly_count) return ... load16(dly_count, var_count_ms(1, MAXDELAY)) call delay ; Delay for 1 ms ... load16(dly_count, var_count_ms(8, MAXDELAY)) call delay ; Delay for 8 ms
- var_delay_us(Arg1, Arg2, Arg3)¶
Variable delay by microseconds.
- Parameters:
Arg1 – Maximum microseconds to delay
Arg2 – MSB of delay counter
Arg3 – LSB of delay counter
The var_count_us() macro generates a 16-bit count value that is loaded into the counter registers before calling the delay function.
Example:
use_clock(50) ; 50 MHz clock define(MAXDELAY, 900) ; 900 us max delay reg16(dly_count, s4,s5) delay: var_delay_us(MAXDELAY, dly_count) return ... load16(dly_count, var_count_us(100, MAXDELAY)) call delay ; Delay for 100 us ... load16(dly_count, var_count_us(800, MAXDELAY)) call delay ; Delay for 800 us
- vars(Arg1-ArgN)¶
Define variables.
- Parameters:
Arg1-ArgN – Series of variable alias expressions where an alias expression is: <reg> is <alias> [:= value]
The alias becomes an alternate name for the register. It is loaded with a value if the optional initializer is included. The value can be any constant expression or register. Use the popvars() macro to remove the variable definitions.
Example:
vars(s0 is counter := 0, s1 is sum, s2 is max := 20*3) ; s0 is loaded with 0 ; s2 is loaded with 60 ; Three macros "counter", "sum", and "max" will expand into their registers
- warnmsg(Arg1)¶
Print a warning message and continue.
- Parameters:
Arg1 – message string
This prints a message with the file and line number where the macro was invoked for debugging.
Example:
warnmsg(`Bad arguments to foo macro')
- while(Arg1, Arg2)¶
While loop.
- Parameters:
Arg1 – Boolean comparison expression
Arg2 – Code block for loop body
The Boolean expression must be of the form:
reg op reg|expression
where op is <, >=, ==, !=, &, or ~&Example:
load s0, 00 while(s0 < 10, `output s3, P_foo add s0, 01')
- words_be(Arg1-ArgN)¶
Convert 16-bit words into bytes with big-endian order.
- Parameters:
Arg1-ArgN – Numbers to split into bytes
Example:
words_be(0xff01, 0xff02) ; Expands to 1, 255, 2, 255
- words_le(Arg1-ArgN)¶
Convert 16-bit words into bytes with little-endian order.
- Parameters:
Arg1-ArgN – Numbers to split into bytes
Example:
words_le(0xff01, 0xff02) ; Expands to 255, 1, 255, 2
- xor16(Arg1, Arg2, Arg3[, Arg4])¶
16-bit logical XOR.
- Parameters:
Arg1 – MSB1
Arg2 – LSB1
Arg3 – Decimal constant or expression or MSB2 when Arg4 is present
Arg4 – Optional register for LSB2
- Returns:
Result in Arg1, Arg2
When three arguments are passed, Arg3 is a constant literal. When four arguments are passed, Arg3 and Arg4 are a 16-bit pair to XOR to the result.
Example:
load16(s1,s0, 0x5A01) xor16(s1,s0, 0xF0FF) ; Result is 0xAAFE xor16(s1,s0, s3,s2) ; (s1,s0) XOR (s3,s2)