Skip to content

Example Macros

Cabintech edited this page Jan 19, 2025 · 51 revisions

FXCoreMP Sample Macros

TODO: Add example invocations for all examples

Example 1 - MR Table Generation With $_eval() Function

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

Example 2 - Copy SFR to MR

; Copy a Special Function Register (SFR) to a Memory Register (MR)
; Uses ACC32
$macro COPY_SFR_TO_MR(mr, sfr) ++
cpy_cs	acc32, ${sfr} 
cpy_mc	${mr}, acc32 
$endmacro

Example 3 - Copy MR to SFR

; Copy a Memory Register (MR) to a Special Function Register (SFR)
; Uses ACC32
$macro COPY_MR_TO_SFR(sfr, mr) ++
cpy_cm	acc32, ${mr} 
cpy_sc	${sfr}, acc32 
$endmacro

Example 4 - Copy MR to MR (uses ACC32)

; Copy a MR to another MR (uses ACC32)
$macro COPY_MR_TO_MR(mrTo, mrFrom) ++
cpy_cm	acc32, ${mrFrom}
cpy_mc	${mrTo}, acc32 
$endmacro

Example 5 - Copy MR to MR

; Copy MR to MR with a temp register (does not use acc32)
$macro COPY_MR_TO_MR_TEMP(mrTarget, mrSource, crTemp) ++
cpy_cm		${crTemp}, ${mrSource} 	
cpy_mc		${mrTarget}, ${crTemp}
$endmacro

Example 6 - Set MR from Two 16-Bit Constants

; Set an MR to a 32 bit value from (2) 16 bit constants
; Uses ACC32
$macro COPY_CONST_TO_MR(mrTo, constHi, constLo) ++
wrdld	acc32, ${constHi} 
ori		acc32, ${constLo}
cpy_mc	${mrTo}, acc32
$endmacro

Example 7 - Branch on Switch State LOW

; Branch to a target label if the given (debounced) SWITCH is LOW
; Uses ACC32
$macro IF_SWITCH_LOW(switch, label) ++
cpy_cs		acc32, SWITCH 
andi		acc32, ${switch}
jz			acc32, ${label}
$endmacro

Example 8 - 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
$macro IF_SWITCH_HIGH(switch, label) ++
cpy_cs		acc32, SWITCH 
andi		acc32, ${switch}
jnz			acc32, ${label}
$endmacro

Example 9

; Short hand for IF_SWITCH_HIGH()
$macro IF_SWITCH(a,b) ++
$IF_SWITCH_HIGH(${a},${b})
$endmacro

Example 10 - Invert a Core Register

; 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
$macro INVERT(cr) ++
wrdld	acc32, 0x7FFF 	; Load max pos value 
ori		acc32, 0xFFFF	
subs	acc32, ${cr}	; Leaves result in acc32
$endmacro

Example 11 - Multiply Two 16 Bit Numbers

; ACC32 = Multiply the lower 16 bits of two core registers
$macro MULT_16(cr1, cr2, crTemp) ++
sl			${cr1}, 16			; Move arg1 to upper 32 bits 
cpy_cc		${crTemp}, acc32	; Save in temp 
sl			${cr2}, 15			; Move arg 2, not sure why 15 instead of 16 bits 
multrr		acc32, ${crTemp}	; acc32 = upper 32 bits of 64 bit result
$endmacro

Example 12 - Convert Msec to Number of Samples

; Convert msec to number (integral) number of delay samples, assuming 48kHz sample rate.
$macro MS_TO_SAMPLES_48K(msec) ((${msec}/1000)/(1/48000))

Example 13 - Encode 4 Bytes Into 32-Bit Word

; Encode 4 bytes into a 32-bit word
$macro WORD32_BYTES(msb, b2, b1, lsb) (${msb}<<24)|(${b2}<<16)|(${b1}<<8)|${lsb}

Example 14 - 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.
$macro SWITCH4(crValue, target0, target1, target2, default) ++
jz			${crValue}, ${target0}

cpy_cc		acc32, ${crValue}
addi		acc32, -1			
jz			acc32, ${target1}

cpy_cc		acc32, ${crValue}		
addi		acc32, -2			
jz			acc32, ${target2}

jmp			${default}
$endmacro

Example 15 - 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.
$macro SWITCH3(crValue, target0, target1, default) ++
jz			${crValue}, ${target0}
cpy_cc		acc32, ${crValue}		
addi		acc32, -1			
jz			acc32, ${target1}
jmp			${default}
$endmacro

Clone this wiki locally