XXIIVV

A collection of commonly used macros in uxn projects.

Generics

Shorthands for logic and arithmetic opcodes.

%+  { ADD }  %-  { SUB } 
%<  { LTH }  %>  { GTH }  %=  { EQU }  %!  { NEQ }
%++ { ADD2 } %-- { SUB2 } 
%<< { LTH2 } %>> { GTH2 } %== { EQU2 } %!! { NEQ2 }

Fast Arithmetic

%2*  { #10 SFT } %2/  { #01 SFT }
%4*  { #20 SFT } %4/  { #02 SFT }
%8*  { #30 SFT } %8/  { #03 SFT }
%10* { #40 SFT } %10/ { #04 SFT }
%20* { #50 SFT } %20/ { #05 SFT }

%2**  { #10 SFT2 } %2//  { #01 SFT2 }
%4**  { #20 SFT2 } %4//  { #02 SFT2 }
%8**  { #30 SFT2 } %8//  { #03 SFT2 }
%10** { #40 SFT2 } %10// { #04 SFT2 }
%20** { #50 SFT2 } %20// { #05 SFT2 }

%2MOD    { #01 AND }
%4MOD    { #03 AND }
%8MOD    { #07 AND }
%8MOD2   { #0007 AND2 }
%100MOD2 { #00ff AND2 }

Buttons

%B_UP { #10 } %B_DOWN { #20 } %B_LEFT   { #40 } %B_RIGHT { #80 }
%B_A  { #01 } %B_B    { #02 } %B_SELECT { #04 } %B_START { #08 }

Binary Opcodes

%ROL { DUP #07 SFT SWP #10 SFT + }
%ROR { DUP #70 SFT SWP #01 SFT + }

Signed Opcodes

%LTS2 { #8000 ++ SWP2 #8000 ++ >> }
%GTS2 { #8000 ++ SWP2 #8000 ++ << }
%ABS2 { DUP2 #0f SFT2 = #05 JCN #0000 SWP2 -- }

Modulo

%MOD  { DIVk MUL SUB }
%MOD2 { DIV2k MUL2 SUB2 }

Geometry

%SIZE-TO-RECT {
    STH2 STH2 OVR2 STH2r ++ OVR2 STH2r ++
} ( x y w h -- x1 y1 x2 y2 )

ASCII

To test for character types.

%IS-SPACER   { #21 < } ( char -- flag )
%IS-LABEL    { STHk #40 = STHr #26 = #0000 !! } ( char -- flag )
%IS-ALPHA-LC { STHk #60 > STHr #7b < #0101 == } ( char -- flag )
%IS-ALPHA-UC { STHk #40 > STHr #5b < #0101 == } ( char -- flag )
%IS-ALPHA    { DUP IS-ALPHA-UC SWP IS-ALPHA-LC #0000 !! } ( char -- flag )
%IS-NUMBER   { STHk #2f > STHr #3a < #0101 == } ( char -- flag )
%IS-ALPHANUM { DUP IS-ALPHA SWP IS-NUMBER #0000 !! } ( char -- flag )

Debugger

To print the hex values of data.

%DEBUG  { ;print-hex JSR2 #0a .Console/write DEO }
%DEBUG2 { SWP ;print-hex JSR2 ;print-hex JSR2 #0a .Console/write DEO }
%BREAKPOINT { #0101 #0e DEO2 }
@print-hex ( value -- )
	
	STHk #04 SFT ,&parse JSR .Console/write DEO
	STHr #0f AND ,&parse JSR .Console/write DEO
	RTN
	&parse ( value -- char )
		DUP #09 GTH ,&above JCN #30 ADD RTN &above #09 SUB #60 ADD RTN

RTN

Multiplication

By Alderwick

(
    multiplying by different methods
    each routine is tested with all possible inputs
    00 00 ... ff ff
    and the number of while(u->ram.ptr){} loops is counted
    to obtain the average number of cycles per calculation
)

@multiply_by_lookup
    ( all inputs -> outputs correct )
    ( average cycles 26 )
    SUBk ( a b a-b )
    LIT2r :&table LITr 00 ( a b a-b / table* 00 )
    STH ADD2kr LDAr ( a b / table* 00 a-b (a-b)^2/2 )
    ANDk #01 AND ( a b sum / table* 00 a-b (a-b)^2/2 )
    STHr SUB POPr ( a b sum / table* 00 )
    SWP STH ADD2kr LDAr ( a sum / table* 00 b b^2/2 )
    STHr ADD POPr ( a sum / table* 00 )
    SWP STH ADD2r LDAr ( sum / a^2/2 )
    STHr ADD
RTN

    &table
    0000 0204 080c 1218 2028 323c 4854 6270 8090 a2b4 c8dc f208 2038 526c 88a4 c2e0
    0020 4264 88ac d2f8 2048 729c c8f4 2250 80b0 e214 487c b2e8 2058 92cc 0844 82c0
    0040 82c4 084c 92d8 2068 b2fc 4894 e230 80d0 2274 c81c 72c8 2078 d22c 88e4 42a0
    0060 c224 88ec 52b8 2088 f25c c834 a210 80f0 62d4 48bc 32a8 2098 128c 0884 0280
    0080 0284 088c 1298 20a8 32bc 48d4 62f0 8010 a234 c85c f288 20b8 52ec 8824 c260
    00a0 42e4 882c d278 20c8 721c c874 22d0 8030 e294 48fc b268 20d8 924c 08c4 8240
    00c0 8244 08cc 9258 20e8 b27c 4814 e2b0 8050 22f4 c89c 7248 20f8 d2ac 8864 4220
    00e0 c2a4 886c 5238 2008 f2dc c8b4 a290 8070 6254 483c 3228 2018 120c 0804 0200

@multiply_by_shifting
    ( all inputs -> outputs correct )
    ( average cycles 102.199 )
    LTHk JMP SWP
    LITr 00
    STH ( a / sum b )
    &loop
    DUP #01 AND ,&accumulate JCN
    &rest
    #01 SFT LITr 10 SFTr ( a>>1 / sum b<<1 )
    DUP ,&loop JCN
    POP POPr STHr ( sum )
RTN
    &accumulate
    STHkr ADDr STH ( a / sum+b b )
    ,&rest JMP

@mul2_by_shifting
    LTH2k JMP SWP2
    LIT2r 0000
    STH2 ( a* / sum* b* )
    &loop
    DUP2 #0001 AND2 ORA ,&accumulate JCN
    &rest
    #01 SFT2 LITr 10 SFT2r ( a>>1* / sum* b<<1* )
    ORAk ,&loop JCN
    POP2 POP2r STH2r ( sum* )
RTN
    &accumulate
    STH2kr ADD2r STH2 ( a* / sum+b* b* )
    ,&rest JMP

@multiply_by_adding
    ( fails on N * 0 and N * 1 )
    ( average cycles on working results 1146.47 )
    SWP DUP STH2
    #01
    &loopz
        STH2r ADDk NIP STH2
        #01 ADD GTHk ,&loopz JCN
    POP2 STHr POPr
RTN

@native_multiply
    ( all inputs -> outputs correct )
    ( average cycles 2 )
    MUL
RTN