commit 8612695
Devine Lu Linvega
·
2026-01-20 18:09:46 +0000 UTC
parent 60b2607
Inlined dei/deo handler checks
1 files changed,
+93,
-89
+93,
-89
1@@ -33,8 +33,7 @@ static XImage *emu_img;
2 static int emu_x11;
3 static int emu_timer;
4 static Uint8 *ram, dev[0x100], ptr[2], stk[2][0x100];
5-static Uint8 emu_dei(const Uint8 port);
6-static void emu_deo(const Uint8 port, const Uint8 value);
7+static unsigned int uxn_eval(Uint16 pc);
8
9 /* clang-format off */
10
11@@ -47,85 +46,6 @@ static void emu_deo(const Uint8 port, const Uint8 value);
12 #define TWOS(v) (v & 0x8000 ? (int)v - 0x10000 : (int)v)
13 #define PEEK2(d) (*(d) << 8 | (d)[1])
14
15-#define REM *p -= 1 + _2;
16-#define DEC s[--(*p)]
17-#define INC s[(*p)++]
18-#define MOV { if(_2) pc = a; else pc += (signed char)a; }
19-#define JMP(x) { c = ram[pc] << 8, c |= ram[pc + 1]; pc += x + 2; }
20-#define STK(m) Uint8 *s = stk[m], *p = &ptr[m];
21-#define PO1(o) o = DEC;
22-#define PO2(o) { PO1(o) o |= DEC << 8; }
23-#define POx(o) { PO1(o) if(_2) o |= DEC << 8; }
24-#define POt(o) if(_2) PO1(o[1]) PO1(o[0])
25-#define PU1(i) INC = i;
26-#define PU2(i) PU1(i >> 8) PU1(i)
27-#define PUx(i) c = (i); if(_2) PU1(c >> 8) PU1(c)
28-#define PUt(i) PU1(i[0]) if(_2) PU1(i[1])
29-#define PUr(i) stk[!_r][ptr[!_r]++] = i;
30-#define DEO(o,r) emu_deo(o, r[0]); if(_2) emu_deo(o + 1, r[1]);
31-#define DEI(i,r) r[0] = emu_dei(i); if(_2) r[1] = emu_dei(i + 1);
32-#define POK(o,r,m) ram[o] = r[0]; if(_2) ram[(o + 1) & m] = r[1];
33-#define PEK(i,r,m) r[0] = ram[i]; if(_2) r[1] = ram[(i + 1) & m];
34-
35-#define OPC(opc, A, B) {\
36- case 0x00|opc: {const int _2=0,_r=0;STK(_r)A B} goto step;\
37- case 0x20|opc: {const int _2=1,_r=0;STK(_r)A B} goto step;\
38- case 0x40|opc: {const int _2=0,_r=1;STK(_r)A B} goto step;\
39- case 0x60|opc: {const int _2=1,_r=1;STK(_r)A B} goto step;\
40- case 0x80|opc: {const int _2=0,_r=0;STK(_r)int k=*p; A *p=k;B} goto step;\
41- case 0xa0|opc: {const int _2=1,_r=0;STK(_r)int k=*p; A *p=k;B} goto step;\
42- case 0xc0|opc: {const int _2=0,_r=1;STK(_r)int k=*p; A *p=k;B} goto step;\
43- case 0xe0|opc: {const int _2=1,_r=1;STK(_r)int k=*p; A *p=k;B} goto step;}
44-
45-static unsigned int
46-uxn_eval(Uint16 pc)
47-{
48- Uint16 a, b, c, x[2], y[2], z[2];
49-step:
50- switch(ram[pc++]) {
51- /* BRK */ case 0x00: return 1;
52- /* JCI */ case 0x20: if(stk[0][--ptr[0]]) JMP(c) else pc += 2; goto step;
53- /* JMI */ case 0x40: JMP(c) goto step;
54- /* JSI */ case 0x60: { STK(1) JMP(0) PU2(pc) pc += c; } goto step;
55- /* LI2 */ case 0xa0: { STK(0) INC = ram[pc++]; INC = ram[pc++]; } goto step;
56- /* LIT */ case 0x80: { stk[0][ptr[0]++] = ram[pc++]; } goto step;
57- /* L2r */ case 0xe0: { STK(1) INC = ram[pc++]; INC = ram[pc++]; } goto step;
58- /* LIr */ case 0xc0: { stk[1][ptr[1]++] = ram[pc++]; } goto step;
59- /* INC */ OPC(0x01,POx(a),PUx(a + 1))
60- /* POP */ OPC(0x02,REM,(void)s;)
61- /* NIP */ OPC(0x03,POt(x) REM,PUt(x))
62- /* SWP */ OPC(0x04,POt(x) POt(y),PUt(x) PUt(y))
63- /* ROT */ OPC(0x05,POt(x) POt(y) POt(z),PUt(y) PUt(x) PUt(z))
64- /* DUP */ OPC(0x06,POt(x),PUt(x) PUt(x))
65- /* OVR */ OPC(0x07,POt(x) POt(y),PUt(y) PUt(x) PUt(y))
66- /* EQU */ OPC(0x08,POx(a) POx(b),PU1(b == a))
67- /* NEQ */ OPC(0x09,POx(a) POx(b),PU1(b != a))
68- /* GTH */ OPC(0x0a,POx(a) POx(b),PU1(b > a))
69- /* LTH */ OPC(0x0b,POx(a) POx(b),PU1(b < a))
70- /* JMP */ OPC(0x0c,POx(a),MOV)
71- /* JCN */ OPC(0x0d,POx(a) PO1(b),if(b) MOV)
72- /* JSR */ OPC(0x0e,POx(a),PUr(pc >> 8) PUr(pc) MOV)
73- /* STH */ OPC(0x0f,POt(x),PUr(x[0]) if(_2) PUr(x[1]))
74- /* LDZ */ OPC(0x10,PO1(a),PEK(a, x, 0xff) PUt(x))
75- /* STZ */ OPC(0x11,PO1(a) POt(y),POK(a, y, 0xff))
76- /* LDR */ OPC(0x12,PO1(a),PEK(pc + (signed char)a, x, 0xffff) PUt(x))
77- /* STR */ OPC(0x13,PO1(a) POt(y),POK(pc + (signed char)a, y, 0xffff))
78- /* LDA */ OPC(0x14,PO2(a),PEK(a, x, 0xffff) PUt(x))
79- /* STA */ OPC(0x15,PO2(a) POt(y),POK(a, y, 0xffff))
80- /* DEI */ OPC(0x16,PO1(a),DEI(a, x) PUt(x))
81- /* DEO */ OPC(0x17,PO1(a) POt(y),DEO(a, y))
82- /* ADD */ OPC(0x18,POx(a) POx(b),PUx(b + a))
83- /* SUB */ OPC(0x19,POx(a) POx(b),PUx(b - a))
84- /* MUL */ OPC(0x1a,POx(a) POx(b),PUx(b * a))
85- /* DIV */ OPC(0x1b,POx(a) POx(b),PUx(a ? b / a : 0))
86- /* AND */ OPC(0x1c,POx(a) POx(b),PUx(b & a))
87- /* ORA */ OPC(0x1d,POx(a) POx(b),PUx(b | a))
88- /* EOR */ OPC(0x1e,POx(a) POx(b),PUx(b ^ a))
89- /* SFT */ OPC(0x1f,PO1(a) POx(b),PUx(b >> (a & 0xf) << (a >> 4)))
90- }
91- return 0;
92-}
93-
94 /* clang-format on */
95
96 /*
97@@ -1094,22 +1014,106 @@ static const deo_handler deo_handlers[256] = {
98 [0xbd] = fileb_deo_read,
99 [0xbf] = fileb_deo_write};
100
101-#define CONINBUFSIZE 256
102-
103-Uint8
104+static inline Uint8
105 emu_dei(const Uint8 port)
106 {
107- if(dei_handlers[port]) return dei_handlers[port]();
108- return dev[port];
109+ dei_handler h = dei_handlers[port];
110+ return h ? h() : dev[port];
111 }
112
113-void
114+static inline void
115 emu_deo(const Uint8 port, const Uint8 value)
116 {
117+ deo_handler h = deo_handlers[port];
118 dev[port] = value;
119- if(deo_handlers[port]) deo_handlers[port]();
120+ if(h) h();
121 }
122
123+/* clang-format off */
124+
125+#define REM *p -= 1 + _2;
126+#define DEC s[--(*p)]
127+#define INC s[(*p)++]
128+#define MOV { if(_2) pc = a; else pc += (signed char)a; }
129+#define JMP(x) { c = ram[pc] << 8, c |= ram[pc + 1]; pc += x + 2; }
130+#define STK(m) Uint8 *s = stk[m], *p = &ptr[m];
131+#define PO1(o) o = DEC;
132+#define PO2(o) { PO1(o) o |= DEC << 8; }
133+#define POx(o) { PO1(o) if(_2) o |= DEC << 8; }
134+#define POt(o) if(_2) PO1(o[1]) PO1(o[0])
135+#define PU1(i) INC = i;
136+#define PU2(i) PU1(i >> 8) PU1(i)
137+#define PUx(i) c = (i); if(_2) PU1(c >> 8) PU1(c)
138+#define PUt(i) PU1(i[0]) if(_2) PU1(i[1])
139+#define PUr(i) stk[!_r][ptr[!_r]++] = i;
140+#define DEO(o,r) emu_deo(o, r[0]); if(_2) emu_deo(o + 1, r[1]);
141+#define DEI(i,r) r[0] = emu_dei(i); if(_2) r[1] = emu_dei(i + 1);
142+#define POK(o,r,m) ram[o] = r[0]; if(_2) ram[(o + 1) & m] = r[1];
143+#define PEK(i,r,m) r[0] = ram[i]; if(_2) r[1] = ram[(i + 1) & m];
144+
145+#define OPC(opc, A, B) {\
146+ case 0x00|opc: {const int _2=0,_r=0;STK(_r)A B} goto step;\
147+ case 0x20|opc: {const int _2=1,_r=0;STK(_r)A B} goto step;\
148+ case 0x40|opc: {const int _2=0,_r=1;STK(_r)A B} goto step;\
149+ case 0x60|opc: {const int _2=1,_r=1;STK(_r)A B} goto step;\
150+ case 0x80|opc: {const int _2=0,_r=0;STK(_r)int k=*p; A *p=k;B} goto step;\
151+ case 0xa0|opc: {const int _2=1,_r=0;STK(_r)int k=*p; A *p=k;B} goto step;\
152+ case 0xc0|opc: {const int _2=0,_r=1;STK(_r)int k=*p; A *p=k;B} goto step;\
153+ case 0xe0|opc: {const int _2=1,_r=1;STK(_r)int k=*p; A *p=k;B} goto step;}
154+
155+static unsigned int
156+uxn_eval(Uint16 pc)
157+{
158+ Uint16 a, b, c, x[2], y[2], z[2];
159+step:
160+ switch(ram[pc++]) {
161+ /* BRK */ case 0x00: return 1;
162+ /* JCI */ case 0x20: if(stk[0][--ptr[0]]) JMP(c) else pc += 2; goto step;
163+ /* JMI */ case 0x40: JMP(c) goto step;
164+ /* JSI */ case 0x60: { STK(1) JMP(0) PU2(pc) pc += c; } goto step;
165+ /* LI2 */ case 0xa0: { STK(0) INC = ram[pc++]; INC = ram[pc++]; } goto step;
166+ /* LIT */ case 0x80: { stk[0][ptr[0]++] = ram[pc++]; } goto step;
167+ /* L2r */ case 0xe0: { STK(1) INC = ram[pc++]; INC = ram[pc++]; } goto step;
168+ /* LIr */ case 0xc0: { stk[1][ptr[1]++] = ram[pc++]; } goto step;
169+ /* INC */ OPC(0x01,POx(a),PUx(a + 1))
170+ /* POP */ OPC(0x02,REM,(void)s;)
171+ /* NIP */ OPC(0x03,POt(x) REM,PUt(x))
172+ /* SWP */ OPC(0x04,POt(x) POt(y),PUt(x) PUt(y))
173+ /* ROT */ OPC(0x05,POt(x) POt(y) POt(z),PUt(y) PUt(x) PUt(z))
174+ /* DUP */ OPC(0x06,POt(x),PUt(x) PUt(x))
175+ /* OVR */ OPC(0x07,POt(x) POt(y),PUt(y) PUt(x) PUt(y))
176+ /* EQU */ OPC(0x08,POx(a) POx(b),PU1(b == a))
177+ /* NEQ */ OPC(0x09,POx(a) POx(b),PU1(b != a))
178+ /* GTH */ OPC(0x0a,POx(a) POx(b),PU1(b > a))
179+ /* LTH */ OPC(0x0b,POx(a) POx(b),PU1(b < a))
180+ /* JMP */ OPC(0x0c,POx(a),MOV)
181+ /* JCN */ OPC(0x0d,POx(a) PO1(b),if(b) MOV)
182+ /* JSR */ OPC(0x0e,POx(a),PUr(pc >> 8) PUr(pc) MOV)
183+ /* STH */ OPC(0x0f,POt(x),PUr(x[0]) if(_2) PUr(x[1]))
184+ /* LDZ */ OPC(0x10,PO1(a),PEK(a, x, 0xff) PUt(x))
185+ /* STZ */ OPC(0x11,PO1(a) POt(y),POK(a, y, 0xff))
186+ /* LDR */ OPC(0x12,PO1(a),PEK(pc + (signed char)a, x, 0xffff) PUt(x))
187+ /* STR */ OPC(0x13,PO1(a) POt(y),POK(pc + (signed char)a, y, 0xffff))
188+ /* LDA */ OPC(0x14,PO2(a),PEK(a, x, 0xffff) PUt(x))
189+ /* STA */ OPC(0x15,PO2(a) POt(y),POK(a, y, 0xffff))
190+ /* DEI */ OPC(0x16,PO1(a),DEI(a, x) PUt(x))
191+ /* DEO */ OPC(0x17,PO1(a) POt(y),DEO(a, y))
192+ /* ADD */ OPC(0x18,POx(a) POx(b),PUx(b + a))
193+ /* SUB */ OPC(0x19,POx(a) POx(b),PUx(b - a))
194+ /* MUL */ OPC(0x1a,POx(a) POx(b),PUx(b * a))
195+ /* DIV */ OPC(0x1b,POx(a) POx(b),PUx(a ? b / a : 0))
196+ /* AND */ OPC(0x1c,POx(a) POx(b),PUx(b & a))
197+ /* ORA */ OPC(0x1d,POx(a) POx(b),PUx(b | a))
198+ /* EOR */ OPC(0x1e,POx(a) POx(b),PUx(b ^ a))
199+ /* SFT */ OPC(0x1f,PO1(a) POx(b),PUx(b >> (a & 0xf) << (a >> 4)))
200+ }
201+ return 0;
202+}
203+
204+/* clang-format on */
205+
206+#define CONINBUFSIZE 256
207+
208 void
209 emu_resize(void)
210 {
211@@ -1316,7 +1320,7 @@ main(int argc, char **argv)
212 {
213 int i = 1;
214 if(argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v')
215- return !fprintf(stdout, "%s - Varvara Emulator, 13 Jan 2026.\n", argv[0]);
216+ return !fprintf(stdout, "%s - Varvara Emulator, 20 Jan 2026.\n", argv[0]);
217 else if(argc == 1)
218 return !fprintf(stdout, "usage: %s [-v] file.rom [args..]\n", argv[0]);
219 else if(!system_boot(argv[i++], argc > 2))