-
Notifications
You must be signed in to change notification settings - Fork 0
Example Macros
TODO: Similar to MR Table example, add example invocations and show generated code for all examples
This example shows how the $_eval() function can be used to create a table in a series of memory registers (MRx) starting at an arbitrary base address. This can be useful when a macro is used in different programs that need to locate the table at different MR locations, or to create a series of tables in a single program at different MR locations.
This macro produces a table with 4 entries that divide the given value by 3, 6, 9, and 12.
$macro DIVIDER_TABLE(baseMRNum, value) ++
.mreg mr$_eval(${baseMRNum}+0) ${value}/3
.mreg mr$_eval(${baseMRNum}+1) ${value}/6
.mreg mr$_eval(${baseMRNum}+2) ${value}/9
.mreg mr$_eval(${baseMRNum}+3) ${value}/12
$endmacro
For example, the following use of the macro:
.equ DIV8_TABLE_BASE 40 ; MR of first entry of 8/x table
$DIVIDER_TABLE(DIV8_TABLE_BASE, 8)
.equ DIV32_TABLE_BASE 50 ; MR of first entry of 32/x table
$DIVIDER_TABLE(DIV32_TABLE_BASE, 32)
Would produce the following assembler code:
.equ DIV8_TABLE_BASE 40 ; MR of first entry of /8 table
.mreg mr40 8/3
.mreg mr41 8/6
.mreg mr42 8/9
.mreg mr43 8/12
.equ DIV32_TABLE_BASE 50 ; MR of first entry of /32 table
.mreg mr50 32/3
.mreg mr51 32/6
.mreg mr52 32/9
.mreg mr53 32/12
; Set an MR to a 32 bit value from (2) 16 bit constants
; Uses ACC32
<!-- TOC --><a name="branch-on-switch-state-low"></a>
## Branch on Switch State LOW
; Branch to a target label if the given (debounced) SWITCH is LOW
; Uses ACC32
<!-- TOC --><a name="branch-on-switch-state-high"></a>
## Branch on Switch State HIGH
; Branch to a target label if the given (debounced) SWITCH is HIGH.
; The first arg should be one of the SWxDB assembler constants.
; Uses ACC32
<!-- TOC --><a name="macro-synonym"></a>
## Macro Synonym
This is an example of providing an alternate name (synonym) for a macro
; Short hand for IF_SWITCH_HIGH()
$macro IF_SWITCH(a,b) ++
<!-- TOC --><a name="invert-a-core-register-10-cr"></a>
## Invert a Core Register (1.0-CR)
; Invert a positive value in "cr" and leave result in acc32.
; The invert is defined as 1 minus the original value for any
; value between 0 and max pos (0x7FFFFFFF).
; Uses ACC32
<!-- TOC --><a name="multiply-two-16-bit-numbers"></a>
## Multiply Two 16 Bit Numbers
Multiplying two 16 bit integers in FXCore takes several instructions, this macro simplifies this common operation.
; ACC32 = Multiply the lower 16 bits of two core registers
<!-- TOC --><a name="convert-msec-to-number-of-samples-at-48k"></a>
## Convert Msec to Number of Samples (At 48k)
Convert msec to number (integral) number of delay samples, assuming 48kHz sample rate.
<!-- TOC --><a name="convert-msec-to-number-of-samples-at-current-sample-rate"></a>
## Convert Msec to Number of Samples (At Current Sample Rate)
Convert (fixed constant) msec to samples based on current sampling rate. Unlike MS_TO_SAMPLES_48K
this macro expands to executable code that accounts for the current sampling rate.
The results are left in ACC32.
The msec arg must be a fixed constant (or constant expression) that evaluates to
less than 2048.
$macro MS_TO_SAMPLES(msec) ++
r0.u =
acc32 = BOOTSTAT acc32 = acc32 andi 3 ; Mask all but PLL (sampling rate) bits [1:0] acc32 = acc32 add -2 ; If PLL=2 then rate is 32k if acc32 =0 goto _mts_k32 ; Special case, 32k is not a multiple of 12k
acc32 = acc32 add 3 ; Get original PLL value plus 1, now a multiplier for 12k rate acc32 = acc32 sl 15 ; Do multiply in upper 16 bits acc32 = acc32 mult r0 goto _mts_end
_mts_k32:
acc32.u =
_mts_end: $endmacro
<!-- TOC --><a name="encode-4-bytes-into-32-bit-word"></a>
## Encode 4 Bytes Into 32-Bit Word
; Encode 4 bytes into a 32-bit word
<!-- TOC --><a name="4-way-switch-statement"></a>
## 4-Way Switch Statement
; Multi-target branch based on value of a CR. A value of 0 will
; branch to label target0, a value of 1 will branch to target1,
; etc. Any value is >=3 will branch to the last (default) label.
; Uses ACC32.
cpy_cc acc32,
cpy_cc acc32,
jmp ${default} $endmacro
<!-- TOC --><a name="3-way-switch-statement"></a>
## 3-Way Switch Statement
; Multi-target branch based on value of a CR. A value of 0 will
; branch to label target0, a value of 1 will branch to target1,
; etc. If the value is >=2 will branch to the last (default) label.
; Uses ACC32.
<!-- TOC --><a name="mr-symbolic-name-and-initial-value"></a>
## MR Symbolic Name and Initial Value
This macro is shorthand for the common practice of defining a symbolic name
for a MR location, and initializing that location to a specific value. This example
demonstrates the use of string expressions in the _eval() predefined macro.
The "mr" argument
can either be a simple integer number 0-127, or "mr" followed by 0-127. E.g. these generate the same code:
$defMR(myreg, 110, 0) $defMR(myreg, mr110, 0)
The above macros would both produce the same 2 statements:
.rn myreg mr110 .mreg myreg 0
Note a math expression cannot be used for the "mr" argument, e.g. "100+10" will cause an error. If an expression
is needed, evaluate it with $_eval() e.g. `$defMR(myreg, $_eval(100+10), 0)`
<!-- TOC --><a name="copy-sfr-to-mr"></a>
## Copy SFR to MR
; Copy a Special Function Register (SFR) to a Memory Register (MR)
; Uses ACC32
<!-- TOC --><a name="copy-mr-to-sfr"></a>
## Copy MR to SFR
; Copy a Memory Register (MR) to a Special Function Register (SFR)
; Uses ACC32
<!-- TOC --><a name="copy-mr-to-mr-uses-acc32"></a>
## Copy MR to MR (uses ACC32)
; Copy a MR to another MR (uses ACC32)
<!-- TOC --><a name="copy-mr-to-mr"></a>
## Copy MR to MR
; Copy MR to MR with a temp register (does not use acc32)
<!-- TOC --><a name="set-mr-from-two-16-bit-constants"></a>
## Set MR from Two 16-Bit Constants
Copyright © Cabintech Global LLC