commit 4be5c22

Devine Lu Linvega  ·  2025-09-26 21:19:50 +0000 UTC
parent ba08598
Optimized core
1 files changed,  +29, -33
+29, -33
  1@@ -19,12 +19,8 @@ cc -DNDEBUG -O2 -g0 -s src/uxncli.c -lutil -o bin/uxncli
  2 typedef unsigned char Uint8;
  3 typedef unsigned short Uint16;
  4 
  5-typedef struct {
  6-	Uint8 dat[0x100], ptr;
  7-} Stack;
  8-
  9+static unsigned char ptr[2], stk[2][0x100];
 10 static Uint8 *ram, dev[0x100];
 11-static Stack wst, rst;
 12 
 13 Uint8 emu_dei(const Uint8 port);
 14 void emu_deo(const Uint8 port, const Uint8 value);
 15@@ -42,25 +38,25 @@ void emu_deo(const Uint8 port, const Uint8 value);
 16 	case 0x20|opc: {const int _2=1,_r=0;A B;} break;\
 17 	case 0x40|opc: {const int _2=0,_r=1;A B;} break;\
 18 	case 0x60|opc: {const int _2=1,_r=1;A B;} break;\
 19-	case 0x80|opc: {const int _2=0,_r=0;int k=wst.ptr;A wst.ptr=k;B;} break;\
 20-	case 0xa0|opc: {const int _2=1,_r=0;int k=wst.ptr;A wst.ptr=k;B;} break;\
 21-	case 0xc0|opc: {const int _2=0,_r=1;int k=rst.ptr;A rst.ptr=k;B;} break;\
 22-	case 0xe0|opc: {const int _2=1,_r=1;int k=rst.ptr;A rst.ptr=k;B;} break;\
 23+	case 0x80|opc: {const int _2=0,_r=0;int k=ptr[_r];A ptr[_r]=k;B;} break;\
 24+	case 0xa0|opc: {const int _2=1,_r=0;int k=ptr[_r];A ptr[_r]=k;B;} break;\
 25+	case 0xc0|opc: {const int _2=0,_r=1;int k=ptr[_r];A ptr[_r]=k;B;} break;\
 26+	case 0xe0|opc: {const int _2=1,_r=1;int k=ptr[_r];A ptr[_r]=k;B;} break;\
 27 }
 28 
 29 /* Microcode */
 30 
 31-#define REM if(_r) rst.ptr -= 1 + _2; else wst.ptr -= 1 + _2;
 32+#define REM    ptr[_r] -= 1 + _2;
 33+#define DEC(m) stk[m][--ptr[m]]
 34+#define INC(m) stk[m][ptr[m]++]
 35 #define IMM(o) o = ram[pc] << 8 | ram[pc + 1], pc += 2;
 36 #define MOV(x) { if(_2) pc = x; else pc += (signed char)x; }
 37-#define DEC(s) s.dat[--s.ptr]
 38-#define PO1(o) { if(_r) o = DEC(rst); else o = DEC(wst); }
 39-#define PO2(o) { PO1(o) if(_r) o |= DEC(rst) << 8; else o |= DEC(wst) << 8; }
 40+#define PO1(o) { o = DEC(_r); }
 41+#define PO2(o) { o = DEC(_r) | DEC(_r) << 8; }
 42 #define POx(o) { if(_2) PO2(o) else PO1(o) }
 43 #define GOT(o) { if(_2) PO1(o[1]) PO1(o[0]) }
 44-#define INC(s) s.dat[s.ptr++]
 45-#define RP1(i) { if(_r) INC(wst) = i; else INC(rst) = i; }
 46-#define PU1(i) { if(_r) INC(rst) = i; else INC(wst) = i; }
 47+#define RP1(i) { INC(!_r) = i; }
 48+#define PU1(i) { INC(_r) = i; }
 49 #define PUx(i) { if(_2) { c = (i); PU1(c >> 8) PU1(c) } else PU1(i) }
 50 #define PUT(i) { PU1(i[0]) if(_2) PU1(i[1]) }
 51 #define DEI(i,o) o[0] = emu_dei(i); if(_2) o[1] = emu_dei(i + 1); PUT(o)
 52@@ -75,13 +71,13 @@ uxn_eval(unsigned short pc)
 53 	while(step--) {
 54 		switch(ram[pc++]) {
 55 		/* BRK */ case 0x00: return 1;
 56-		/* JCI */ case 0x20: IMM(c) if(DEC(wst)) pc += c; break;
 57+		/* JCI */ case 0x20: IMM(c) if(DEC(0)) pc += c; break;
 58 		/* JMI */ case 0x40: IMM(c) pc += c; break;
 59-		/* JSI */ case 0x60: IMM(c) INC(rst) = pc >> 8, INC(rst) = pc, pc += c; break;
 60-		/* LI2 */ case 0xa0: INC(wst) = ram[pc++]; /* fall-through */
 61-		/* LIT */ case 0x80: INC(wst) = ram[pc++]; break;
 62-		/* L2r */ case 0xe0: INC(rst) = ram[pc++]; /* fall-through */
 63-		/* LIr */ case 0xc0: INC(rst) = ram[pc++]; break;
 64+		/* JSI */ case 0x60: IMM(c) INC(1) = pc >> 8, INC(1) = pc, pc += c; break;
 65+		/* LI2 */ case 0xa0: INC(0) = ram[pc++]; /* fall-through */
 66+		/* LIT */ case 0x80: INC(0) = ram[pc++]; break;
 67+		/* L2r */ case 0xe0: INC(1) = ram[pc++]; /* fall-through */
 68+		/* LIr */ case 0xc0: INC(1) = ram[pc++]; break;
 69 		/* INC */ OPC(0x01,POx(a),PUx(a + 1))
 70 		/* POP */ OPC(0x02,REM,{})
 71 		/* NIP */ OPC(0x03,GOT(x) REM,PUT(x))
 72@@ -115,7 +111,7 @@ uxn_eval(unsigned short pc)
 73 		/* SFT */ OPC(0x1f,PO1(a) POx(b),PUx(b >> (a & 0xf) << (a >> 4)))
 74 		}
 75 	}
 76-	return !fprintf(stdout, "Exhausted cycles limit.\n");
 77+	return 0;
 78 }
 79 
 80 /* clang-format on */
 81@@ -126,13 +122,13 @@ uxn_eval(unsigned short pc)
 82 static char *system_boot_path;
 83 
 84 static void
 85-system_print(char *name, Stack *s)
 86+system_print(char *name, int r)
 87 {
 88 	Uint8 i;
 89 	fprintf(stderr, "%s ", name);
 90-	for(i = s->ptr - 8; i != (Uint8)(s->ptr); i++)
 91-		fprintf(stderr, "%02x%c", s->dat[i], i == 0xff ? '|' : ' ');
 92-	fprintf(stderr, "<%02x\n", s->ptr);
 93+	for(i = ptr[r] - 8; i != ptr[r]; i++)
 94+		fprintf(stderr, "%02x%c", stk[r][i], i == 0xff ? '|' : ' ');
 95+	fprintf(stderr, "<%02x\n", ptr[r]);
 96 }
 97 
 98 static unsigned int
 99@@ -637,8 +633,8 @@ emu_dei(const Uint8 port)
100 {
101 	switch(port) {
102 	/* System */
103-	case 0x04: return wst.ptr;
104-	case 0x05: return rst.ptr;
105+	case 0x04: return ptr[0];
106+	case 0x05: return ptr[1];
107 	/* Console */
108 	case CMD_LIVE:
109 	case CMD_EXIT: check_child(); break;
110@@ -664,9 +660,9 @@ emu_deo(const Uint8 port, const Uint8 value)
111 	switch(port) {
112 	/* System */
113 	case 0x03: system_expansion(PEEK2(dev + 2)); break;
114-	case 0x04: wst.ptr = dev[4]; break;
115-	case 0x05: rst.ptr = dev[5]; break;
116-	case 0x0e: system_print("WST", &wst), system_print("RST", &rst); break;
117+	case 0x04: ptr[0] = dev[4]; break;
118+	case 0x05: ptr[1] = dev[5]; break;
119+	case 0x0e: system_print("WST", 0), system_print("RST", 1); break;
120 	/* Console */
121 	case 0x11: console_vector = PEEK2(&dev[0x10]); return;
122 	case 0x18: fputc(dev[0x18], stdout), fflush(stdout); break;
123@@ -696,7 +692,7 @@ main(int argc, char **argv)
124 {
125 	int i = 1;
126 	if(argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v')
127-		return !fprintf(stdout, "Uxn11 - Varvara Emulator(cli), 13 Aug 2025.\n");
128+		return !fprintf(stdout, "Uxn11 - Varvara Emulator(cli), 26 Sep 2025.\n");
129 	else if(argc == 1)
130 		return !fprintf(stdout, "usage: %s [-v] file.rom [args..]\n", argv[0]);
131 	else if(!system_boot(argv[i++], argc > 2))