XXIIVV

A collection of commonly used routines in Uxntal projects.

The following snippets are in the standard format. If you discover faster and smaller helpers, please get in touch with me.

Numbers

To print hexadecimal numbers:

@print ( short* -- )

	SWP ,&byte JSR
	&byte ( byte -- ) DUP #04 SFT ,&char JSR
	&char ( char -- ) #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO

JMP2r

To print a hexadecimal number from a short, without leading zeroes:

@phex ( short* -- )

	#00 ,&z STR
	,&parse JSR
	,&parse JSR
	,&parse JSR
	,&parse JSR POP2

JMP2r
	&parse
		OVR #04 SFT DUP [ LIT &z $1 ] EQU ,&skip JCN
			#ff ,&z STR DUP #0f AND DUP #09 GTH #27 MUL ADD #30 ADD #18 DEO
			&skip
		POP #40 SFT2
	JMP2r

To print a decimal number from a short, without leading zeroes:

@pdec ( short* -- )

	#00 ,&z STR
	#2710 ,&parse JSR
	#03e8 ,&parse JSR
	#0064 ,&parse JSR
	#000a ,&parse JSR
	NIP
	&emit
		DUP [ LIT &z $1 ] EQU ,&skip JCN
			#ff ,&z STR DUP #30 ADD #18 DEO
			&skip
	POP

JMP2r
	&parse
		DIV2k DUP ,&emit JSR MUL2 SUB2
	JMP2r

To convert a decimal string to a hexadecimal value.

@sdec ( str* -- val* )

	LIT2r 0000
	&w
		LIT2r 000a MUL2r
		LITr 00
		LDAk #30 SUB STH ADD2r
		INC2 LDAk ,&w JCN
	POP2
	STH2r

JMP2r

To convert a hexadecimal string to a hexadecimal value.

@shex ( str* -- val* )

	LIT2r 0000
	&w
		LITr 40 SFT2r
		LITr 00
		LDAk ,chex JSR STH ADD2r
		INC2 LDAk ,&w JCN
	POP2
	STH2r

JMP2r

To convert a hexadecimal character to a nibble.

@chex ( char -- value/ff )

	DUP #2f GTH OVR #3a LTH AND ,&n JCN
	DUP #40 GTH OVR #47 LTH AND ,&u JCN
	DUP #60 GTH OVR #67 LTH AND ,&l JCN
	POP #ff

JMP2r
	&l #20 SUB &u #07 SUB &n #30 SUB JMP2r

Strings

To print a string.

@pstr ( str* -- )

	&w
		LDAk #18 DEO
		INC2 LDAk ,&w JCN
	POP2

JMP2r

Helpers for strings.

@scap ( str* -- end* ) LDAk #00 NEQ JMP JMP2r &w INC2 LDAk ,&w JCN JMP2r
@spop ( str* -- ) LDAk ,&n JCN POP2 JMP2r &n ,scap JSR #0001 SUB2 #00 ROT ROT STA JMP2r
@sput ( chr str* -- ) ,scap JSR INC2k #00 ROT ROT STA STA JMP2r
@slen ( str* -- len* ) DUP2 ,scap JSR SWP2 SUB2 JMP2r
@scat ( src* dst* -- ) ,scap JSR
@scpy ( src* dst* -- ) STH2 &w LDAk STH2kr STA INC2r INC2 LDAk ,&w JCN POP2 #00 STH2r STA JMP2r
@scmp ( a* b* -- f ) STH2 &l LDAk LDAkr STHr ANDk #00 EQU ,&e JCN NEQk ,&e JCN POP2 INC2 INC2r ,&l JMP &e NIP2 POP2r EQU JMP2r

Memory

To print an entire page of memory:

@pmem ( addr* -- )

	STH2
	#0000
	&l
		#00 OVR STH2kr ADD2 LDA ,print/byte JSR
		DUP #0f AND #0f NEQ #16 MUL #0a ADD #18 DEO
		INC NEQk ,&l JCN
	POP2
	POP2r

JMP2r

Helpers for memory.

@mclr ( src* len* -- ) OVR2 ADD2 SWP2 &l STH2k #00 STH2r STA INC2 GTH2k ,&l JCN POP2 POP2 JMP2r
@mcpy ( src* dst* len* -- ) SWP2 STH2 OVR2 ADD2 SWP2 &l LDAk STH2kr STA INC2r INC2 GTH2k ,&l JCN POP2 POP2 POP2r JMP2r
@msfl ( a* b* len* -- ) STH2 SWP2 EQU2k ,&e JCN &l DUP2k STH2kr ADD2 LDA ROT ROT STA INC2 GTH2k ,&l JCN POP2 POP2 &e POP2r JMP2r
@msfr ( a* b* len* -- ) STH2 EQU2k ,&e JCN &l DUP2 LDAk ROT ROT STH2kr ADD2 STA #0001 SUB2 LTH2k ,&l JCN POP2 POP2 &e POP2r JMP2r

To shift part of a string using a signed short.

@ssft ( str* len* -- )

	STH2 DUP2k ;slen JSR2 ADD2 STH2r
	DUP2 #8000 GTH2 ,&l JCN
	ORAk ,&r JCN
	POP2 POP2 POP2

JMP2r
	&l #8000 SWP2 SUB2 #8000 ADD2 ;msfl JSR2 JMP2r
	&r ;msfr JSR2 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