XXIIVV

A collection of commonly used macros in uxn projects.

Generics

Shorthands for logic and arithmetic opcodes.

%+  { ADD }  %-  { SUB }  %*  { MUL }  %/  { DIV }
%<  { LTH }  %>  { GTH }  %=  { EQU }  %!  { NEQ }
%++ { ADD2 } %-- { SUB2 } %** { MUL2 } %// { DIV2 }
%<< { LTH2 } %>> { GTH2 } %== { EQU2 } %!! { NEQ2 }

Fast Arithmetic

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

%2MOD  { #01 AND } %2MOD2  { #0001 AND2 }
%4MOD  { #03 AND } %4MOD2  { #0003 AND2 }
%8MOD  { #07 AND } %8MOD2  { #0007 AND2 }
%10MOD { #0f AND } %10MOD2 { #000f 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 + }
%ROL2 { DUP2 #0f SFT2 SWP2 #10 SFT2 ++ }
%ROR2 { DUP2 #f0 SFT2 SWP2 #01 SFT2 ++ }

Signed Opcodes

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

Modulo/MinMax

%MOD  { DIVk MUL SUB }
%MOD2 { DIV2k MUL2 SUB2 }
%MIN2 { LTH2k JMP SWP2 POP2 }
%MAX2 { GTH2k JMP SWP2 POP2 }

ASCII

To test for character types.

%IS-UC { DUP #40 > SWP #5b < AND }
%IS-LC { DUP #60 > SWP #7b < AND }
%IS-NUM { DUP #2f > SWP #3a < AND }

Debugger

To print the hex values of data.

%HALT   { #010f DEO }
%EMIT   { #18 DEO }
%PRINT  { ;print-str JSR2 #0a EMIT }
%DEBUG  { ;print-hex/byte JSR2 #0a EMIT }
%DEBUG2 { ;print-hex JSR2 #0a EMIT }
@print-hex ( value* -- )

	SWP ,&byte JSR 
	&byte ( byte -- )
		STHk #04 SFT ,&parse JSR #18 DEO
		STHr #0f AND ,&parse JSR #18 DEO
	JMP2r
	&parse ( byte -- char ) DUP #09 GTH ,&above JCN #30 ADD JMP2r 
	&above #57 ADD JMP2r

JMP2r
@print-dec ( value* -- )

	#2710 DIV2k DUP #30 ADD #18 DEO MUL2 SUB2
	#03e8 DIV2k DUP #30 ADD #18 DEO MUL2 SUB2
	#0064 DIV2k DUP #30 ADD #18 DEO MUL2 SUB2
	#000a DIV2k DUP #30 ADD #18 DEO MUL2 SUB2
	#30 ADD #18 DEO POP

JMP2r
@print-str ( string* -- )

	#0001 SUB2 
	&while
		INC2 LDAk DUP #18 DEO ,&while JCN 
	POP2

JMP2r
@print-zeropage ( -- )

	#0a #18 DEO
	#0000
	&loop
		LDZk ;print-hex/byte JSR2
		DUP #01 AND #00 = ,&no-space JCN
			#2018 DEO
			&no-space
		DUP #0f AND #0f ! ,&no-break JCN
			#0a18 DEO
			&no-break
		INC NEQk ,&loop JCN
	POP2
	#0a #18 DEO

JMP2r
@print-arvelie ( -- )

	.DateTime/year DEI2 #07d6 -- NIP 
		( digit1 ) DUP #0a DIV #30 + #18 DEO
		( digit2 ) #0a MOD #30 + #18 DEO
	.DateTime/doty DEI2
		( month ) DUP2 #000e DIV2 NIP #41 + #18 DEO
		( digit3 ) #000e MOD2 DUP2 #000a DIV2 NIP #30 + #18 DEO
		( digit4 ) #000a MOD2 NIP #30 + #18 DEO
	#0a #18 DEO

JMP2r

Strings

string primitives

@scat ( src* dst* -- )

	DUP2 ,slen JSR ++ ,scpy JSR

JMP2r

@slen ( str* -- len* )

	DUP2 ,scap JSR SWP2 --

JMP2r

@scap ( str* -- end* )

	LDAk #00 ! JMP JMP2r
	&while 
		INC2 LDAk ,&while JCN

JMP2r

@scpy ( src* dst* -- )
	
	STH2
	&while
		LDAk STH2kr STA INC2r
		INC2 LDAk ,&while JCN
	POP2
	#00 STH2r STA

JMP2r

@sput ( str* char -- )

	ROT ROT ,scap JSR STA

JMP2r

@spop ( str* -- )

	( clamp ) LDAk #00 ! JMP JMP2r
	#00 ROT ROT ,scap JSR #0001 -- STA

JMP2r

Memory

@mclr ( addr* len* -- )

	OVR2 ++ SWP2
	&loop
		STH2k #00 STH2r STA
		INC2 GTH2k ,&loop JCN
	POP2 POP2

JMP2r

@mcpy ( src* dst* len* -- )

	SWP2 STH2
	OVR2 ++ SWP2
	&loop
		LDAk STH2kr STA INC2r
		INC2 GTH2k ,&loop JCN
	POP2 POP2
	POP2r

JMP2r

Random

@prng-init ( -- )

	( seed )
	#00 .DateTime/second DEI
	#00 .DateTime/minute DEI #60 SFT2 EOR2
	#00 .DateTime/hour   DEI #c0 SFT2 EOR2 ,prng/x STR2
	#00 .DateTime/hour   DEI #04 SFT2
	#00 .DateTime/day    DEI #10 SFT2 EOR2
	#00 .DateTime/month  DEI #60 SFT2 EOR2
		.DateTime/year  DEI2 #a0 SFT2 EOR2 ,prng/y STR2

JMP2r

@prng ( -- number* )

	LIT2 &x $2
	DUP2 #50 SFT2 EOR2
	DUP2 #03 SFT2 EOR2
	LIT2 &y $2 DUP2 ,&x STR2
	DUP2 #01 SFT2 EOR2 EOR2
	,&y STR2k POP

JMP2r

decimal string to hex number

@sdec ( addr* -- hex* )

	( res ) LIT2r 0000
	&while
		LDAk #30 - #00 SWP
		STH2r #000a ** ++ STH2
		INC2 LDAk ,&while JCN
	POP2
	( res ) STH2r

JMP2r

Presets

%AUTO-NONE   { #00 .Screen/auto DEO }
%AUTO-X      { #01 .Screen/auto DEO }
%AUTO-Y      { #02 .Screen/auto DEO }
%AUTO-XY     { #03 .Screen/auto DEO }
%AUTO-ADDR   { #04 .Screen/auto DEO }
%AUTO-XADDR  { #05 .Screen/auto DEO }
%AUTO-YADDR  { #06 .Screen/auto DEO }
%AUTO-XYADDR { #07 .Screen/auto DEO }
%RELEASE-MOUSE { #0096 DEO }

Geometry

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