~rabbits/uxn

6eac5226e1cea602cb71c4c938a5e10520699af5 — Devine Lu Linvega 10 days ago 70e756b
(bunnymark) Ported to immediate opcodes
4 files changed, 64 insertions(+), 47 deletions(-)

M projects/examples/demos/bunnymark.tal
M src/uxn-fast.c
M src/uxncli.c
M src/uxnemu.c
M projects/examples/demos/bunnymark.tal => projects/examples/demos/bunnymark.tal +41 -41
@@ 24,10 24,10 @@
	;on-frame .Screen/vector DEO2

	( draw "FPS:" and "BUNNIES:" and instructions labels )
	.Screen/width DEI2 #0046 SUB2 #0008 ;text/fps #42 ;draw-str JSR2
	#0004 #0008 ;text/bunnies #42 ;draw-str JSR2
	.Screen/width DEI2 #01 SFT2 #0050 SUB2 #0008 ;text/instructions #43 ;draw-str JSR2
	#0028 #0008 #0000 ;draw-dec JSR2
	.Screen/width DEI2 #0046 SUB2 #0008 ;text/fps #42 draw-str
	#0004 #0008 ;text/bunnies #42 draw-str
	.Screen/width DEI2 #01 SFT2 #0050 SUB2 #0008 ;text/instructions #43 draw-str
	#0028 #0008 #0000 draw-dec

	( seed prng )
	#04 ;rand/a STA


@@ 38,29 38,29 @@ BRK

	( frames++ ) 
	.frames LDZ2k INC2 ROT STZ2
	.Date/second DEI .last LDZ EQU ,&post-fps-update JCN
	.Date/second DEI .last LDZ EQU ?&post-fps-update
	( fps update )
	( update last-secs ) .Date/second DEI .last STZ
	( update fps label ) .Screen/width DEI2 #002b SUB2 #0008 .frames LDZ2 ;draw-dec JSR2
	( update fps label ) .Screen/width DEI2 #002b SUB2 #0008 .frames LDZ2 draw-dec
	( reset frames counter ) #0000 .frames STZ2

	&post-fps-update
		( mouse input to add/remove bunnies )
		.Mouse/state DEI #01 EQU ,&add JCN
		.Mouse/state DEI #01 GTH ,&remove JCN
		,&done JMP
		.Mouse/state DEI #01 EQU ?&add
		.Mouse/state DEI #01 GTH ?&remove
		!&done
	&add
		;add-bunny JSR2 ,&done JMP
		add-bunny !&done
	&remove
		;remove-bunny JSR2 ,&done JMP
		remove-bunny !&done
	&done

	( loop from 0 to ;sprite/length to make all ;draw-bunny calls )
	[ ;sprite/length LDA2 ] #0000
	&loop
		EQU2k ,&bail JCN
		DUP2 ,draw-bunny JSR
		INC2 ,&loop JMP
		EQU2k ?&bail
		DUP2 draw-bunny
		INC2 !&loop
	&bail
	POP2 POP2



@@ 75,31 75,31 @@ BRK
		( top )
	[ LDA2k ] #05 SFT2 .Screen/x DEO2
	[ INC2k INC2 LDA2 ] #05 SFT2 .Screen/y DEO2
	#00 ;draw-sprite JSR2
	#00 draw-sprite

	( move the sprite by its velocity )
	[ LDA2k ] [ OVR2 #0004 ADD2 LDA2 ] ADD2 OVR2 STA2
	[ INC2k INC2 LDA2 ] [ OVR2 #0006 ADD2 LDA2 ] ADD2 OVR2 INC2 INC2 STA2

	( check for right wall collision + bounce x )
	[ DUP2 #0004 ADD2 LDA2 ] #0f SFT2 #0001 EQU2 ,&skip-max-x JCN
	[ LDA2k ] #05 SFT2 #0008 ADD2 [ .Screen/width DEI2 ] LTH2 ,&skip-max-x JCN
	[ DUP2 #0004 ADD2 LDA2 ] #0f SFT2 #0001 EQU2 ?&skip-max-x
	[ LDA2k ] #05 SFT2 #0008 ADD2 [ .Screen/width DEI2 ] LTH2 ?&skip-max-x
	[ DUP2 #0004 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0004 ADD2 STA2 ]
	&skip-max-x
	( check for left wall collision + bounce x )
	[ LDA2k ] #0f SFT2 #0000 EQU2 ,&skip-min-x JCN
	[ LDA2k ] #0f SFT2 #0000 EQU2 ?&skip-min-x
	[ DUP2 #0004 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0004 ADD2 STA2 ]
	&skip-min-x
	( check for bottom wall collision + bounce y )
	[ DUP2 #0006 ADD2 LDA2 ] #0f SFT2 #0001 EQU2 ,&skip-max-y JCN
	[ INC2k INC2 LDA2 ] #05 SFT2 #0008 ADD2 [ .Screen/height DEI2 ] LTH2 ,&skip-max-y JCN
	[ DUP2 #0006 ADD2 LDA2 ] #0f SFT2 #0001 EQU2 ?&skip-max-y
	[ INC2k INC2 LDA2 ] #05 SFT2 #0008 ADD2 [ .Screen/height DEI2 ] LTH2 ?&skip-max-y
	[ DUP2 #0006 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0006 ADD2 STA2 ]
	,&skip-gravity JMP
	!&skip-gravity
	&skip-max-y
	( check for top wall collision + bounce x )
	[ INC2k INC2 LDA2 ] #0f SFT2 #0000 EQU2 ,&skip-min-y JCN
	[ INC2k INC2 LDA2 ] #0f SFT2 #0000 EQU2 ?&skip-min-y
	[ DUP2 #0006 ADD2 LDA2 ] #ffff MUL2 [ OVR2 #0006 ADD2 STA2 ]
	,&skip-gravity JMP
	!&skip-gravity
	&skip-min-y

	( apply gravity )


@@ 110,16 110,16 @@ BRK
	( top )
	[ LDA2k ] #05 SFT2 .Screen/x DEO2
	[ INC2 INC2 LDA2 ] #05 SFT2 .Screen/y DEO2
	#85 ,draw-sprite ( .. )
	#85 

JMP
( >> )

@draw-sprite ( color -- )

	#15 .Screen/auto DEO
	[ LIT2 15 -Screen/auto ] DEO
	;bunny-chr .Screen/addr DEO2
	.Screen/sprite DEO
	#00 .Screen/auto DEO
	[ LIT2 00 -Screen/auto ] DEO

JMP2r



@@ 127,19 127,19 @@ JMP2r

	;sprite/length LDA2
	( cap bunny count at 65535 )
	DUP2 #ffff EQU2 ,&bail JCN
	DUP2 #ffff EQU2 ?&bail
	( compute the offset to the beginning of this new bunny's data )
	DUP2 #30 SFT2 ;sprite/array ADD2
	( populate the new bunny's x/y/xvel/yvel with random values )
	#00 [ ;rand JSR2 ] OVR2 STA2
	[ ;rand JSR2 #1f AND ] [ ;rand JSR2 ] OVR2 INC2 INC2 STA2
	#00 [ ;rand JSR2 #7f AND ] OVR2 #0004 ADD2 STA2
	#00 [ ;rand JSR2 #7f AND ] OVR2 #0006 ADD2 STA2
	#00 [ rand ] OVR2 STA2
	[ rand #1f AND ] [ rand ] OVR2 INC2 INC2 STA2
	#00 [ rand #7f AND ] OVR2 #0004 ADD2 STA2
	#00 [ rand #7f AND ] OVR2 #0006 ADD2 STA2
	( pop ptr to bunny data ) POP2
	( write new increased array length )
	INC2 DUP2 ;sprite/length STA2
	( update label )
	STH2k #0028 #0008 STH2r ;draw-dec JSR2
	STH2k #0028 #0008 STH2r draw-dec
	&bail
	( pop sprite/length ) POP2



@@ 147,23 147,23 @@ JMP2r

@draw-str ( x* y* text* color -- )

	#01 .Screen/auto DEO
	[ LIT2 01 -Screen/auto ] DEO
	STH
	SWP2 .Screen/y DEO2
	SWP2 .Screen/x DEO2
	&loop
		LDAk #20 SUB #00 SWP #30 SFT2 ;font ADD2 .Screen/addr DEO2
		STHkr .Screen/sprite DEO
		INC2 LDAk ,&loop JCN
		INC2 LDAk ?&loop
	POP2
	STHr POP
	#00 .Screen/auto DEO
	[ LIT2 00 -Screen/auto ] DEO

JMP2r

@draw-dec ( x* y* num* -- )

	#01 .Screen/auto DEO
	[ LIT2 01 -Screen/auto ] DEO
	SWP2 .Screen/y DEO2
	SWP2 .Screen/x DEO2
	#2710 DIV2k DUP2 NIP ,&digit JSR MUL2 SUB2


@@ 171,7 171,7 @@ JMP2r
	#0064 DIV2k DUP2 NIP ,&digit JSR MUL2 SUB2 NIP
	#0a DIVk DUP ,&digit JSR MUL SUB
	,&digit JSR
	#00 .Screen/auto DEO
	[ LIT2 00 -Screen/auto ] DEO

JMP2r
	&digit ( num -- )


@@ 183,18 183,18 @@ JMP2r

	;sprite/length LDA2
	( don't let length go below 0 )
	ORAk #00 EQU ,&bail JCN
	ORAk #00 EQU ?&bail
	( clear the old sprite location )
	DUP2 #0001 SUB2 #30 SFT2 ;sprite/array ADD2
	( top )
	[ LDA2k ] #05 SFT2 .Screen/x DEO2
	[ INC2k INC2 LDA2 ] #05 SFT2 .Screen/y DEO2
	( clear )
	#00 ;draw-sprite JSR2
	#00 draw-sprite
	POP2
	#0001 SUB2 DUP2 ;sprite/length STA2
	( update label )
	STH2k #0028 #0008 STH2r ;draw-dec JSR2
	STH2k #0028 #0008 STH2r draw-dec
	&bail
		POP2


M src/uxn-fast.c => src/uxn-fast.c +23 -4
@@ 1,7 1,5 @@
#include "uxn.h"

#include <stdio.h>

/*
Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards



@@ 36,6 34,27 @@ WITH REGARD TO THIS SOFTWARE.
#define PUT2(o, v) { tmp = (v); s->dat[s->ptr - o - 2] = tmp >> 8; s->dat[s->ptr - o - 1] = tmp; }
#define PUSH(stack, v) { stack->dat[stack->ptr++] = (v); }
#define PUSH2(stack, v) { tmp = (v); stack->dat[stack->ptr] = (v) >> 8; stack->dat[stack->ptr + 1] = (v); stack->ptr += 2; }
#define SEND(a, b) { u->dev[a] = b; if((callbacks[(a) >> 4] >> ((a) & 0xf)) & 0x1) u->deo(u, a, b); }

static 
Uint16 callbacks[] = {
        0xffff, /* 00 system   1011 0000 1111 1110 */
        0xffff, /* 10 console  0000 0000 1100 0000 */
        0xc028, /* 20 screen   0011 1100 0000 0011 */
        0xffff, /* 30 audio 0  0011 1000 0000 0001 */
        0xffff, /* 40 audio 1  0011 1000 0000 0001 */
        0xffff, /* 50 audio 2  0011 1000 0000 0001 */
        0xffff, /* 60 audio 3  0011 1000 0000 0001 */
        0x0000, /* 70 midi  */
        0x0000, /* 80 mouse */
        0x0000, /* 90 file  */
        0xffff, /* a0 file 0   0000 1110 1100 1111 */
        0xffff, /* b0 file 1   0000 1110 1100 1111 */
        0xffff, /* c0 datetime 1111 1111 1110 0000 */
        0x0000, /* d0 empty */
        0x0000, /* e0 empty */
        0x0000  /* f0 empty */
};

int
uxn_eval(Uxn *u, Uint16 pc)


@@ 104,8 123,8 @@ uxn_eval(Uxn *u, Uint16 pc)
			case 0x15: /* STA  */ t=T2;n=L;       DEC(3, 0) u->ram[t] = n; break; 
			case 0x36: /* DEI2 */ t=T;            INC(1, 1) PUT(1, u->dei(u, t)) PUT(0, u->dei(u, t + 1)) break;      
			case 0x16: /* DEI  */ t=T;            INC(1, 0) PUT(0, u->dei(u, t)) break;
			case 0x37: /* DEO2 */ t=T;n=N;l=L;    DEC(3, 0) u->deo(u, t, l); u->deo(u, t + 1, n); break; 
			case 0x17: /* DEO  */ t=T;n=N;        DEC(2, 0) u->deo(u, t, n); break; 
			case 0x37: /* DEO2 */ t=T;n=N;l=L;    DEC(3, 0) SEND(t, l) SEND(t + 1, n) break; 
			case 0x17: /* DEO  */ t=T;n=N;        DEC(2, 0) SEND(t, n) break; 
			case 0x38: /* ADD2 */ t=T2;n=N2;      INC(4,-2) PUT2(0, n + t) break; 
			case 0x18: /* ADD  */ t=T;n=N;        INC(2,-1) PUT(0, n + t) break;
			case 0x39: /* SUB2 */ t=T2;n=N2;      INC(4,-2) PUT2(0, n - t) break; 

M src/uxncli.c => src/uxncli.c +0 -1
@@ 63,7 63,6 @@ static void
emu_deo(Uxn *u, Uint8 addr, Uint8 v)
{
	Uint8 p = addr & 0x0f, d = addr & 0xf0;
	u->dev[addr] = v;
	switch(d) {
	case 0x00: system_deo(u, &u->dev[d], p); break;
	case 0x10: console_deo(&u->dev[d], p); break;

M src/uxnemu.c => src/uxnemu.c +0 -1
@@ 130,7 130,6 @@ static void
emu_deo(Uxn *u, Uint8 addr, Uint8 v)
{
	Uint8 p = addr & 0x0f, d = addr & 0xf0;
	u->dev[addr] = v;
	switch(d) {
	case 0x00:
		system_deo(u, &u->dev[d], p);