Well, this is a bit random, but I came up with this ca65 macro for converting a nibble (number $0..$F) to its corresponding ASCII character code, when said nibble isn't a compile time constant, and thought I would share it. The main use case would be some sort of debugging. One could, for example, generate a textual log file similar to using .out, but without the limitations of .out.
This macro can then be used to output a 16-bit number as a hex ASCII string:
Usage example:
I'd love to hear about other ca65 tips, tricks and workarounds like this.
Code:
.macro nibbleToHexAscii nibble
.local x0, x1, x2, x3
.local y0, y1, y2, y3, y4
x3 = ( nibble >> 3 ) & 1
x2 = ( nibble >> 2 ) & 1
x1 = ( nibble >> 1 ) & 1
x0 = ( nibble >> 0 ) & 1
y4 = ( x3 & x1 ) | ( x3 & x2 )
y3 = ( x3 & ~x2 & ~x1 )
y2 = ( ~x3 & x2 ) | ( x2 & x0 ) | ( x2 & x1 )
y1 = ( ~x3 & x1 ) | ( x1 & x0 ) | ( x3 & x2 & ~x1 & ~x0 )
y0 = ( ~x3 & x0 ) | ( ~x2 & ~x1 & x0 ) | ( x3 & x1 & ~x0 ) | ( x3 & x2 & ~x0 )
.byte <( ( y4 << 4 | y3 << 3 | y2 << 2 | y1 << 1 | y0 << 0 ) + '0' )
.endmacro
.local x0, x1, x2, x3
.local y0, y1, y2, y3, y4
x3 = ( nibble >> 3 ) & 1
x2 = ( nibble >> 2 ) & 1
x1 = ( nibble >> 1 ) & 1
x0 = ( nibble >> 0 ) & 1
y4 = ( x3 & x1 ) | ( x3 & x2 )
y3 = ( x3 & ~x2 & ~x1 )
y2 = ( ~x3 & x2 ) | ( x2 & x0 ) | ( x2 & x1 )
y1 = ( ~x3 & x1 ) | ( x1 & x0 ) | ( x3 & x2 & ~x1 & ~x0 )
y0 = ( ~x3 & x0 ) | ( ~x2 & ~x1 & x0 ) | ( x3 & x1 & ~x0 ) | ( x3 & x2 & ~x0 )
.byte <( ( y4 << 4 | y3 << 3 | y2 << 2 | y1 << 1 | y0 << 0 ) + '0' )
.endmacro
This macro can then be used to output a 16-bit number as a hex ASCII string:
Code:
.macro wordToHexAscii addr
.repeat 4, i
nibbleToHexAscii { (addr >> ( 4 * ( 3 - i ) ) ) & $F }
.endrepeat
.endmacro
.repeat 4, i
nibbleToHexAscii { (addr >> ( 4 * ( 3 - i ) ) ) & $F }
.endrepeat
.endmacro
Usage example:
Code:
.byte "Current address is: "
wordToHexAscii *
wordToHexAscii *
I'd love to hear about other ca65 tips, tricks and workarounds like this.