aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-01-23 13:36:05 +0100
committerBad Diode <bd@badd10de.dev>2023-01-23 13:36:05 +0100
commit2c9b9630b38e7e890daf65ef7b65beb1f5a5783f (patch)
tree979cd45ae5a3ff85d5e8abb2aa13de1780b7bc62
parent0af009f1c78fd678869a0313078c7d747510a989 (diff)
downloaduxngba-2c9b9630b38e7e890daf65ef7b65beb1f5a5783f.tar.gz
uxngba-2c9b9630b38e7e890daf65ef7b65beb1f5a5783f.zip
Update UXN core to latest version
This modernizes the uxn core and emulator approach (dei/deo instead of _talk), forgoing the previous uxn-fast core implementation. As a consequence, there are some performance regressions. That tradeoff gives us an easier way of keeping uxngba up to date as it follows more closely the upstream version.
-rw-r--r--src/main.c494
-rw-r--r--src/ppu.c7
-rw-r--r--src/uxn.c4334
-rw-r--r--src/uxn.h52
4 files changed, 381 insertions, 4506 deletions
diff --git a/src/main.c b/src/main.c
index a2661cd..beb65e3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,12 +1,12 @@
1/* 1/*
2Copyright (c) 2021 Bad Diode 2 Copyright (c) 2021 Bad Diode
3 3
4Permission to use, copy, modify, and distribute this software for any 4 Permission to use, copy, modify, and distribute this software for any
5purpose with or without fee is hereby granted, provided that the above 5 purpose with or without fee is hereby granted, provided that the above
6copyright notice and this permission notice appear in all copies. 6 copyright notice and this permission notice appear in all copies.
7 7
8THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9WITH REGARD TO THIS SOFTWARE. 9 WITH REGARD TO THIS SOFTWARE.
10*/ 10*/
11 11
12#include <string.h> 12#include <string.h>
@@ -39,8 +39,10 @@ WITH REGARD TO THIS SOFTWARE.
39 39
40#ifdef PROF_ENABLE 40#ifdef PROF_ENABLE
41#if PROF_ENABLE == 0 41#if PROF_ENABLE == 0
42#define TEXT_ENABLE 1
42#define PROF(F,VAR) (profile_start(),(F),(VAR) = profile_stop()) 43#define PROF(F,VAR) (profile_start(),(F),(VAR) = profile_stop())
43#elif PROF_ENABLE == 1 44#elif PROF_ENABLE == 1
45#define TEXT_ENABLE 1
44#define PROF(F,VAR) (profile_start(),(F),(VAR) = MAX(profile_stop(), (VAR))) 46#define PROF(F,VAR) (profile_start(),(F),(VAR) = MAX(profile_stop(), (VAR)))
45#endif 47#endif
46#ifndef PROF_SHOW_X 48#ifndef PROF_SHOW_X
@@ -90,219 +92,254 @@ typedef struct Mouse {
90 int y; 92 int y;
91} Mouse; 93} Mouse;
92 94
95EWRAM_BSS
96static u8 umem[0x10300];
97
98static Uxn u;
93static Ppu ppu; 99static Ppu ppu;
94static Device *devscreen;
95static Device *devctrl;
96static Device *devmouse;
97static Device *devaudio;
98 100
99static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; 101static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2};
100 102
101void 103int
102nil_talk(Device *d, u8 b0, u8 w) { 104uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) {
103 (void)d; 105 (void)u;
104 (void)b0; 106 txt_printf("HALTED\n");
105 (void)w; 107 txt_printf("I: %lu\n", instr);
106} 108 txt_printf("E: %lu\n", err);
107 109 txt_printf("A: %lu\n", addr);
108void 110 while (true);
109console_talk(Device *d, u8 b0, u8 w) {
110 char stmp[2];
111 if(!w) {
112 return;
113 }
114 switch(b0) {
115 case 0x8: stmp[0] = d->dat[0x8]; stmp[1] = 0; txt_printf(stmp); break;
116 case 0x9: txt_printf("0x%02x", d->dat[0x9]); break;
117 case 0xb: txt_printf("0x%04x", mempeek16(d->dat, 0xa)); break;
118 case 0xd: txt_printf("%s", &d->mem[mempeek16(d->dat, 0xc)]); break;
119 }
120} 111}
121 112
122void 113IWRAM_CODE
123system_talk(Device *d, u8 b0, u8 w) { 114u8
124 if(!w) { 115screen_dei(u8 *d, u8 port) {
125 d->dat[0x2] = d->u->wst.ptr; 116 switch(port) {
126 d->dat[0x3] = d->u->rst.ptr; 117 case 0x2: return (SCREEN_WIDTH >> 8);
127 } else { 118 case 0x3: return (SCREEN_WIDTH);
128 putcolors(&d->dat[0x8]); 119 case 0x4: return (SCREEN_HEIGHT >> 8);
120 case 0x5: return (SCREEN_HEIGHT);
121 default: return d[port];
129 } 122 }
130 (void)b0;
131} 123}
132 124
133IWRAM_CODE 125IWRAM_CODE
134void 126void
135screen_talk(Device *d, u8 b0, u8 w) { 127screen_deo(u8 *ram, u8 *d, u8 port) {
136 if (!w) { 128 switch(port) {
137 switch(b0) { 129 case 0xe: {
138 case 0x2: d->dat[b0] = (SCREEN_WIDTH >> 8); break; 130 u16 x, y;
139 case 0x3: d->dat[b0] = (SCREEN_WIDTH); break; 131 u8 layer = d[0xe] & 0x40;
140 case 0x4: d->dat[b0] = (SCREEN_HEIGHT >> 8); break; 132 PEKDEV(x, 0x8);
141 case 0x5: d->dat[b0] = (SCREEN_HEIGHT); break; 133 PEKDEV(y, 0xa);
134 ppu_pixel(layer ? ppu.fg : ppu.bg, x, y, d[0xe] & 0x3);
135 if(d[0x6] & 0x01) POKDEV(0x8, x + 1); /* auto x+1 */
136 if(d[0x6] & 0x02) POKDEV(0xa, y + 1); /* auto y+1 */
137 break;
142 } 138 }
143 } else { 139 case 0xf: {
144 switch (b0) { 140 u16 x, y, dx, dy, addr;
145 case 0x1: { 141 u8 n, twobpp = !!(d[0xf] & 0x80);
146 d->vector = mempeek16(d->dat, 0x0); 142 PEKDEV(x, 0x8);
147 } break; 143 PEKDEV(y, 0xa);
148 case 0xe: { 144 PEKDEV(addr, 0xc);
149 u16 x, y; 145 n = d[0x6] >> 4;
150 u8 layer = d->dat[0xe] & 0x40; 146 dx = (d[0x6] & 0x01) << 3;
151 DEVPEEK16(x, 0x8); 147 dy = (d[0x6] & 0x02) << 2;
152 DEVPEEK16(y, 0xa); 148 if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) {
153 ppu_pixel(layer ? ppu.fg : ppu.bg, x, y, d->dat[0xe] & 0x3); 149 return;
154 if(d->dat[0x6] & 0x01) DEVPOKE16(0x8, x + 1); /* auto x+1 */ 150 }
155 if(d->dat[0x6] & 0x02) DEVPOKE16(0xa, y + 1); /* auto y+1 */ 151 u8 *layer = (d[0xf] & 0x40) ? ppu.fg : ppu.bg;
156 } break; 152 u8 color = d[0xf] & 0xf;
157 case 0xf: { 153 u8 flipx = d[0xf] & 0x10;
158 u16 x, y, dx, dy, addr; 154 u8 flipy = d[0xf] & 0x20;
159 u8 twobpp = !!(d->dat[0xf] & 0x80); 155 for(size_t i = 0; i <= n; i++) {
160 DEVPEEK16(x, 0x8); 156 u8 *sprite = &ram[addr];
161 DEVPEEK16(y, 0xa); 157 if (twobpp) {
162 DEVPEEK16(addr, 0xc); 158 ppu_2bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy);
163 u8 n = d->dat[0x6] >> 4; 159 } else {
164 dx = (d->dat[0x6] & 0x01) << 3; 160 ppu_1bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy);
165 dy = (d->dat[0x6] & 0x02) << 2;
166 if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) {
167 return;
168 }
169 u8 *layer = (d->dat[0xf] & 0x40) ? ppu.fg : ppu.bg;
170 u8 color = d->dat[0xf] & 0xf;
171 u8 flipx = d->dat[0xf] & 0x10;
172 u8 flipy = d->dat[0xf] & 0x20;
173 for(size_t i = 0; i <= n; i++) {
174 u8 *sprite = &d->mem[addr];
175 if (twobpp) {
176 ppu_2bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy);
177 } else {
178 ppu_1bpp(layer, x + dy * i, y + dx * i, sprite, color, flipx, flipy);
179 }
180 addr += (d->dat[0x6] & 0x04) << (1 + twobpp);
181 } 161 }
182 DEVPOKE16(0xc, addr); /* auto addr+length */ 162 addr += (d[0x6] & 0x04) << (1 + twobpp);
183 DEVPOKE16(0x8, x + dx); /* auto x+8 */ 163 }
184 DEVPOKE16(0xa, y + dy); /* auto y+8 */ 164 POKDEV(0xc, addr); /* auto addr+length */
185 } break; 165 POKDEV(0x8, x + dx); /* auto x+8 */
186 default: break; 166 POKDEV(0xa, y + dy); /* auto y+8 */
167 break;
187 } 168 }
188 } 169 }
189} 170}
190 171
191static void 172u8
192audio_talk(Device *d, u8 b0, u8 w) { 173audio_dei(int instance, u8 *d, u8 port) {
193 AudioChannel *c = &channels[d - devaudio]; 174 AudioChannel *c = &channels[instance];
194 if(!w) { 175 switch(port) {
195 if(b0 == 0x2) { 176 // case 0x4: return apu_get_vu(instance);
196 mempoke16(d->dat, 0x2, c->pos); 177 case 0x2: {
178 POKDEV(0x2, c->pos);
197 c->pos <<= 12; // fixed point. 179 c->pos <<= 12; // fixed point.
198 } else if(b0 == 0x4) { 180 break;
199 // d->dat[0x4] = apu_get_vu(c);
200 } 181 }
201 } else if(b0 == 0xf) {
202 u16 length = mempeek16(d->dat, 0xa);
203 u8 *data = &d->mem[mempeek16(d->dat, 0xc)];
204 u8 pitch = d->dat[0xf] & 0x7f;
205 u16 adsr = mempeek16(d->dat, 0x8);
206 u32 vol = MAX(d->dat[0xe] >> 4, d->dat[0xe] & 0xf) * 4 / 3;
207 bool loop = !(d->dat[0xf] & 0x80);
208 update_channel(c, data, length, pitch, adsr, vol, loop);
209 } 182 }
183 return d[port];
210} 184}
211 185
212void 186void
213datetime_talk(Device *d, u8 b0, u8 w) { 187audio_deo(int instance, u8 *d, u8 port, Uxn *u) {
214 (void)b0; 188 AudioChannel *c = &channels[instance];
215 (void)w; 189 if (port == 0xf) {
190 u16 length = 0;
191 u16 adsr = 0;
192 u16 addr = 0;
193 u8 pitch = d[0xf] & 0x7f;
194 PEKDEV(adsr, 0x8);
195 PEKDEV(length, 0xa);
196 PEKDEV(addr, 0xc);
197 u8 *data = &u->ram[addr];
198 u32 vol = MAX(d[0xe] >> 4, d[0xe] & 0xf) * 4 / 3;
199 bool loop = !(d[0xf] & 0x80);
200 update_channel(c, data, length, pitch, adsr, vol, loop);
201 }
202}
203
204u8
205datetime_dei(u8 *d, u8 port) {
216 struct tm *t = gmtime(&seconds); 206 struct tm *t = gmtime(&seconds);
217 t->tm_year += 1900; 207 switch(port) {
218 DEVPOKE16(0x0, t->tm_year); 208 case 0x0: return (t->tm_year + 1900) >> 8;
219 d->dat[0x2] = t->tm_mon; 209 case 0x1: return (t->tm_year + 1900);
220 d->dat[0x3] = t->tm_mday; 210 case 0x2: return t->tm_mon;
221 d->dat[0x4] = t->tm_hour; 211 case 0x3: return t->tm_mday;
222 d->dat[0x5] = t->tm_min; 212 case 0x4: return t->tm_hour;
223 d->dat[0x6] = t->tm_sec; 213 case 0x5: return t->tm_min;
224 d->dat[0x7] = t->tm_wday; 214 case 0x6: return t->tm_sec;
225 DEVPOKE16(0x08, t->tm_yday); 215 case 0x7: return t->tm_wday;
226 d->dat[0xa] = t->tm_isdst; 216 case 0x8: return t->tm_yday >> 8;
217 case 0x9: return t->tm_yday;
218 case 0xa: return t->tm_isdst;
219 default: return d[port];
220 }
227} 221}
228 222
229void 223u8
230file_talk(Device *d, u8 b0, u8 w) { 224file_dei(u8 id, u8 *d, u8 port) {
231 if (w) { 225 UxnFile *c = &uxn_file[id];
232 u16 a, b, res; 226 u16 res;
233 UxnFile *f = &uxn_file[d - &d->u->dev[0xa]]; 227 switch(port) {
234 switch(b0) { 228 case 0xc:
235 case 0x5: { 229 case 0xd: {
236 DEVPEEK16(a, 0x4); 230 res = file_read(c, &d[port], 1);
237 DEVPEEK16(b, 0xa); 231 POKDEV(0x2, res);
238 if(b > 0x10000 - a) { 232 break;
239 b = 0x10000 - a;
240 }
241 res = file_stat(f, &d->mem[a], b);
242 DEVPOKE16(0x2, res);
243 } break;
244 case 0x6: {
245 // TODO: no file deletion for now
246 // res = file_delete();
247 // DEVPOKE16(0x2, res);
248 } break;
249 case 0x9: {
250 DEVPEEK16(a, 0x8);
251 res = file_init(f, &d->mem[a]);
252 DEVPOKE16(0x2, res);
253 } break;
254 case 0xd: {
255 DEVPEEK16(a, 0xc);
256 DEVPEEK16(b, 0xa);
257 if(b > 0x10000 - a) {
258 b = 0x10000 - a;
259 }
260 res = file_read(f, &d->mem[a], b);
261 DEVPOKE16(0x2, res);
262 } break;
263 case 0xf: {
264 DEVPEEK16(a, 0xe);
265 DEVPEEK16(b, 0xa);
266 if(b > 0x10000 - a) {
267 b = 0x10000 - a;
268 }
269 res = file_write(f, &d->mem[a], b, d->dat[0x7]);
270 DEVPOKE16(0x2, res);
271 } break;
272 } 233 }
273 } 234 }
235 return d[port];
274} 236}
275 237
276void 238void
277init_uxn(Uxn *u) { 239file_deo(u8 id, u8 *ram, u8 *d, u8 port) {
278 // Initialize PPU. 240 u16 a, b, res;
279 initppu(&ppu, 30, 20); 241 UxnFile *f = &uxn_file[id];
242 switch(port) {
243 case 0x5: {
244 PEKDEV(a, 0x4);
245 PEKDEV(b, 0xa);
246 if(b > 0x10000 - a) {
247 b = 0x10000 - a;
248 }
249 res = file_stat(f, &ram[a], b);
250 POKDEV(0x2, res);
251 } break;
252 case 0x6: {
253 // TODO: no file deletion for now
254 // res = file_delete();
255 // POKDEV(0x2, res);
256 } break;
257 case 0x9: {
258 PEKDEV(a, 0x8);
259 res = file_init(f, &ram[a]);
260 POKDEV(0x2, res);
261 } break;
262 case 0xd: {
263 PEKDEV(a, 0xc);
264 PEKDEV(b, 0xa);
265 if(b > 0x10000 - a) {
266 b = 0x10000 - a;
267 }
268 res = file_read(f, &ram[a], b);
269 POKDEV(0x2, res);
270 } break;
271 case 0xf: {
272 PEKDEV(a, 0xe);
273 PEKDEV(b, 0xa);
274 if(b > 0x10000 - a) {
275 b = 0x10000 - a;
276 }
277 res = file_write(f, &ram[a], b, d[0x7]);
278 POKDEV(0x2, res);
279 } break;
280 }
281}
280 282
281 // Enable sound. 283void
282 init_sound(); 284console_deo(u8 *d, u8 port) {
285 txt_printf("%c", d[port]);
286}
287
288void
289system_deo(Uxn *u, u8 *d, u8 port) {
290 switch(port) {
291 case 0x2: u->wst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10000)); break;
292 case 0x3: u->rst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10100)); break;
293 }
294}
295
296u8
297emu_dei(Uxn *u, u8 addr) {
298 u8 p = addr & 0x0f, d = addr & 0xf0;
299 switch(d) {
300 case 0x20: return screen_dei(&u->dev[d], p);
301 case 0x30: return audio_dei(0, &u->dev[d], p);
302 case 0x40: return audio_dei(1, &u->dev[d], p);
303 case 0x50: return audio_dei(2, &u->dev[d], p);
304 case 0x60: return audio_dei(3, &u->dev[d], p);
305 case 0xa0: return file_dei(0, &u->dev[d], p);
306 case 0xb0: return file_dei(1, &u->dev[d], p);
307 case 0xc0: return datetime_dei(&u->dev[d], p);
308 }
309 return u->dev[addr];
310 return 0;
311}
312
313void
314emu_deo(Uxn *u, u8 addr, u8 v) {
315 u8 p = addr & 0x0f, d = addr & 0xf0;
316 u->dev[addr] = v;
317 switch(d) {
318 case 0x00:
319 system_deo(u, &u->dev[d], p);
320 if(p > 0x7 && p < 0xe)
321 putcolors(&u->dev[0x8]);
322 break;
323 case 0x10: console_deo(&u->dev[d], p); break;
324 case 0x20: screen_deo(u->ram, &u->dev[d], p); break;
325 case 0x30: audio_deo(0, &u->dev[d], p, u); break;
326 case 0x40: audio_deo(1, &u->dev[d], p, u); break;
327 case 0x50: audio_deo(2, &u->dev[d], p, u); break;
328 case 0x60: audio_deo(3, &u->dev[d], p, u); break;
329 case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break;
330 case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break;
331 }
332}
333
334void
335init_uxn(Uxn *u) {
336 // Initialize uxn.
337 u32 fill = 0;
338 dma_fill(umem, fill, 0x10300, 3);
339 uxn_boot(u, umem, emu_dei, emu_deo);
283 340
284 // Copy rom to VM. 341 // Copy rom to VM.
285 memcpy(u->ram.dat + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); 342 memcpy(u->ram + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom));
286
287 // Prepare devices.
288 uxn_port(u, 0x0, "system", system_talk);
289 uxn_port(u, 0x1, "console", console_talk);
290 devscreen = uxn_port(u, 0x2, "screen", screen_talk);
291 devaudio = uxn_port(u, 0x3, "audio0", audio_talk);
292 uxn_port(u, 0x4, "audio1", audio_talk);
293 uxn_port(u, 0x5, "audio2", audio_talk);
294 uxn_port(u, 0x6, "audio3", audio_talk);
295 uxn_port(u, 0x7, "---", nil_talk);
296 devctrl = uxn_port(u, 0x8, "controller", nil_talk);
297 devmouse = uxn_port(u, 0x9, "mouse", nil_talk);
298 uxn_port(u, 0xa, "file1", file_talk);
299 uxn_port(u, 0xb, "file2", file_talk); // TODO: support second file device
300 uxn_port(u, 0xc, "datetime", datetime_talk);
301 uxn_port(u, 0xd, "---", nil_talk);
302 uxn_port(u, 0xe, "---", nil_talk);
303 uxn_port(u, 0xf, "---", nil_talk);
304 mempoke16(devscreen->dat, 2, ppu.hor * 8);
305 mempoke16(devscreen->dat, 4, ppu.ver * 8);
306} 343}
307 344
308IWRAM_CODE 345IWRAM_CODE
@@ -313,16 +350,18 @@ handle_input(Uxn *u) {
313 // Reset control variables on method switch. 350 // Reset control variables on method switch.
314 switch (ctrl_methods[ctrl_idx]) { 351 switch (ctrl_methods[ctrl_idx]) {
315 case CONTROL_CONTROLLER: { 352 case CONTROL_CONTROLLER: {
316 devctrl->dat[2] = 0; 353 u8 *d = &u->dev[0x80];
317 uxn_eval(u, mempeek16(devctrl->dat, 0)); 354 d[2] = 0;
318 devctrl->dat[3] = 0; 355 uxn_eval(u, GETVEC(d));
356 d[3] = 0;
319 } break; 357 } break;
320 case CONTROL_MOUSE: { 358 case CONTROL_MOUSE: {
321 devmouse->dat[6] = 0; 359 u8 *d = &u->dev[0x90];
322 devmouse->dat[7] = 0; 360 d[6] = 0;
323 mempoke16(devmouse->dat, 0x2, -10); 361 d[7] = 0;
324 mempoke16(devmouse->dat, 0x4, -10); 362 POKDEV(0x2, -10);
325 uxn_eval(u, mempeek16(devmouse->dat, 0)); 363 POKDEV(0x4, -10);
364 uxn_eval(u, GETVEC(d));
326 } break; 365 } break;
327 case CONTROL_KEYBOARD: { 366 case CONTROL_KEYBOARD: {
328 toggle_keyboard(); 367 toggle_keyboard();
@@ -339,9 +378,10 @@ handle_input(Uxn *u) {
339 } 378 }
340 379
341 if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) { 380 if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) {
342 // TODO: We don't need ifs if we use KEY_INPUTS directly and mayvbe just 381 u8 *d = &u->dev[0x80];
382 // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just
343 // swap some things if needed. 383 // swap some things if needed.
344 u8 *flag = &devctrl->dat[2]; 384 u8 *flag = &d[2];
345 if (key_tap(KEY_A)) { 385 if (key_tap(KEY_A)) {
346 *flag |= 0x01; 386 *flag |= 0x01;
347 } else { 387 } else {
@@ -383,11 +423,12 @@ handle_input(Uxn *u) {
383 *flag &= ~0x80; 423 *flag &= ~0x80;
384 } 424 }
385 425
386 uxn_eval(u, mempeek16(devctrl->dat, 0)); 426 uxn_eval(u, GETVEC(d));
387 devctrl->dat[3] = 0; 427 d[3] = 0;
388 } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) { 428 } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) {
429 u8 *d = &u->dev[0x90];
389 // Detect "mouse key press". 430 // Detect "mouse key press".
390 u8 flag = devmouse->dat[6]; 431 u8 flag = d[6];
391 if (key_tap(KEY_B)) { 432 if (key_tap(KEY_B)) {
392 flag |= 0x01; 433 flag |= 0x01;
393 } else if (key_released(KEY_B)) { 434 } else if (key_released(KEY_B)) {
@@ -400,12 +441,12 @@ handle_input(Uxn *u) {
400 } 441 }
401 442
402 // Handle chording. 443 // Handle chording.
403 devmouse->dat[6] = flag; 444 d[6] = flag;
404 if(flag == 0x10 && (devmouse->dat[6] & 0x01)) { 445 if(flag == 0x10 && (d[6] & 0x01)) {
405 devmouse->dat[7] = 0x01; 446 d[7] = 0x01;
406 } 447 }
407 if(flag == 0x01 && (devmouse->dat[6] & 0x10)) { 448 if(flag == 0x01 && (d[6] & 0x10)) {
408 devmouse->dat[7] = 0x10; 449 d[7] = 0x10;
409 } 450 }
410 451
411 // Detect mouse movement. 452 // Detect mouse movement.
@@ -421,10 +462,11 @@ handle_input(Uxn *u) {
421 } 462 }
422 463
423 // Eval mouse. 464 // Eval mouse.
424 mempoke16(devmouse->dat, 0x2, mouse.x); 465 POKDEV(0x2, mouse.x);
425 mempoke16(devmouse->dat, 0x4, mouse.y); 466 POKDEV(0x4, mouse.y);
426 uxn_eval(u, mempeek16(devmouse->dat, 0)); 467 uxn_eval(u, GETVEC(d));
427 } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { 468 } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) {
469 u8 *d = &u->dev[0x80];
428 if (key_tap(KEY_LEFT)) { 470 if (key_tap(KEY_LEFT)) {
429 update_cursor(cursor_position - 1); 471 update_cursor(cursor_position - 1);
430 } else if (key_tap(KEY_RIGHT)) { 472 } else if (key_tap(KEY_RIGHT)) {
@@ -441,43 +483,40 @@ handle_input(Uxn *u) {
441 switch (symbol) { 483 switch (symbol) {
442 case 0x7f: { 484 case 0x7f: {
443 // Backspace. 485 // Backspace.
444 devctrl->dat[3] = 0x08; 486 d[3] = 0x08;
445 } break; 487 } break;
446 case 0x14: { 488 case 0x14: {
447 // New line. 489 // New line.
448 devctrl->dat[3] = 0x0d; 490 d[3] = 0x0d;
449 } break; 491 } break;
450 case 0x18: { 492 case 0x18: {
451 // Arrow up. 493 // Arrow up.
452 devctrl->dat[2] = 0x10; 494 d[2] = 0x10;
453 } break; 495 } break;
454 case 0x19: { 496 case 0x19: {
455 // Arrow down. 497 // Arrow down.
456 devctrl->dat[2] = 0x20; 498 d[2] = 0x20;
457 } break; 499 } break;
458 case 0x1b: { 500 case 0x1b: {
459 // Arrow left. 501 // Arrow left.
460 devctrl->dat[2] = 0x40; 502 d[2] = 0x40;
461 } break; 503 } break;
462 case 0x1a: { 504 case 0x1a: {
463 // Arrow right. 505 // Arrow right.
464 devctrl->dat[2] = 0x80; 506 d[2] = 0x80;
465 } break; 507 } break;
466 default: { 508 default: {
467 devctrl->dat[3] = symbol; 509 d[3] = symbol;
468 } break; 510 } break;
469 } 511 }
470 uxn_eval(u, mempeek16(devctrl->dat, 0)); 512 uxn_eval(u, GETVEC(d));
471 devctrl->dat[3] = 0; 513 d[3] = 0;
472 } 514 }
473 } 515 }
474} 516}
475 517
476static Uxn u; 518int
477EWRAM_BSS 519main(void) {
478static u8 umem[KB(64)];
479
480int main(void) {
481 // Adjust system wait times. 520 // Adjust system wait times.
482 SYSTEM_WAIT = SYSTEM_WAIT_CARTRIDGE; 521 SYSTEM_WAIT = SYSTEM_WAIT_CARTRIDGE;
483 522
@@ -488,16 +527,19 @@ int main(void) {
488 irq_init(); 527 irq_init();
489 irs_set(IRQ_VBLANK, sound_vsync); 528 irs_set(IRQ_VBLANK, sound_vsync);
490 529
491 // Initialize VM. 530 // Initialize PPU.
492 dma_fill(&u, 0, sizeof(u), 3); 531 initppu(&ppu, 30, 20);
493 u.ram.dat = umem;
494 init_uxn(&u);
495 532
496 // Initialize text engine. 533 // Initialize text engine.
534#ifdef TEXT_ENABLE
497 txt_init(1, TEXT_LAYER); 535 txt_init(1, TEXT_LAYER);
498 txt_position(0,0); 536 txt_position(0,0);
537#endif
538
539 // Initialize UXN.
540 init_uxn(&u);
499 541
500 // Initialize sound mixer. 542 // Enable sound.
501 init_sound(); 543 init_sound();
502 544
503 // Main loop. 545 // Main loop.
@@ -507,7 +549,7 @@ int main(void) {
507 while(true) { 549 while(true) {
508 bios_vblank_wait(); 550 bios_vblank_wait();
509 PROF(handle_input(&u), input_cycles); 551 PROF(handle_input(&u), input_cycles);
510 PROF(uxn_eval(&u, mempeek16(devscreen->dat, 0)), eval_cycles); 552 PROF(uxn_eval(&u, GETVEC(&u.dev[0x20])), eval_cycles);
511 PROF(sound_mix(), mix_cycles); 553 PROF(sound_mix(), mix_cycles);
512 PROF_SHOW(); 554 PROF_SHOW();
513 PROF(flipbuf(&ppu), flip_cycles); 555 PROF(flipbuf(&ppu), flip_cycles);
diff --git a/src/ppu.c b/src/ppu.c
index 0f8fefd..1a13ba3 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -386,6 +386,13 @@ flipbuf(Ppu *p) {
386 } 386 }
387} 387}
388 388
389void
390redraw(void) {
391 for (size_t i = 0; i < 21; i++) {
392 dirty_tiles[i] = 0xFFFFFFFF;
393 }
394}
395
389typedef struct KeyboardChar { 396typedef struct KeyboardChar {
390 int x; 397 int x;
391 int y; 398 int y;
diff --git a/src/uxn.c b/src/uxn.c
index a8fe7ac..5c39803 100644
--- a/src/uxn.c
+++ b/src/uxn.c
@@ -1,11 +1,7 @@
1#include <stdio.h>
2#include "uxn.h" 1#include "uxn.h"
3 2
4#define NO_STACK_CHECKS
5
6/* 3/*
7Copyright (u) 2021 Devine Lu Linvega 4Copyright (u) 2022-2023 Devine Lu Linvega, Andrew Alderwick, Andrew Richards
8Copyright (u) 2021 Andrew Alderwick
9 5
10Permission to use, copy, modify, and distribute this software for any 6Permission to use, copy, modify, and distribute this software for any
11purpose with or without fee is hereby granted, provided that the above 7purpose with or without fee is hereby granted, provided that the above
@@ -15,4255 +11,101 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15WITH REGARD TO THIS SOFTWARE. 11WITH REGARD TO THIS SOFTWARE.
16*/ 12*/
17 13
18/* 14/* a,b,c: general use. bs: byte/short bool. src, dst: stack ptrs, swapped in return mode.
19 ^ 15 pc: program counter. sp: ptr to src stack ptr. kptr: "keep" mode copy of src stack ptr.
20/!\ THIS FILE IS AUTOMATICALLY GENERATED 16 x,y: macro in params. d: macro in device. j: macro temp variables. o: macro out param. */
21---
22
23Its contents can get overwritten with the processed contents of src/uxn.c.
24See etc/mkuxn-fast.moon for instructions.
25
26*/
27 17
28#define MODE_RETURN 0x40 18#define HALT(c) { return uxn_halt(u, instr, (c), pc - 1); }
29#define MODE_KEEP 0x80 19#define JUMP(x) { if(bs) pc = (x); else pc += (s8)(x); }
20#define PUSH8(s, x) { if(s->ptr == 0xff) HALT(2) s->dat[s->ptr++] = (x); }
21#define PUSH16(s, x) { if((j = s->ptr) >= 0xfe) HALT(2) k = (x); s->dat[j] = k >> 8; s->dat[j + 1] = k; s->ptr = j + 2; }
22#define PUSH(s, x) { if(bs) { PUSH16(s, (x)) } else { PUSH8(s, (x)) } }
23#define POP8(o) { if(!(j = *sp)) HALT(1) o = (u16)src->dat[--j]; *sp = j; }
24#define POP16(o) { if((j = *sp) <= 1) HALT(1) o = (src->dat[j - 2] << 8) + src->dat[j - 1]; *sp = j - 2; }
25#define POP(o) { if(bs) { POP16(o) } else { POP8(o) } }
26#define POKE(x, y) { if(bs) { u->ram[(x)] = (y) >> 8; u->ram[(x) + 1] = (y); } else { u->ram[(x)] = y; } }
27#define PEEK16(o, x) { o = (u->ram[(x)] << 8) + u->ram[(x) + 1]; }
28#define PEEK(o, x) { if(bs) PEEK16(o, x) else o = u->ram[(x)]; }
29#define DEVR(o, x) { o = u->dei(u, x); if (bs) o = (o << 8) + u->dei(u, (x) + 1); }
30#define DEVW(x, y) { if (bs) { u->deo(u, (x), (y) >> 8); u->deo(u, (x) + 1, (y)); } else { u->deo(u, x, (y)); } }
30 31
31IWRAM_CODE 32IWRAM_CODE
32int 33int
33uxn_eval(Uxn *u, u16 vec) 34uxn_eval(Uxn *u, u16 pc)
34{ 35{
35 u8 instr; 36 u8 kptr, *sp;
36 if(!vec || u->dev[0].dat[0xf]) 37 u16 a, b, c, j, k, bs, instr, opcode;
37 return 0; 38 Stack *src, *dst;
38 u->ram.ptr = vec; 39 if(!pc || u->dev[0x0f]) return 0;
39 if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8; 40 for(;;) {
40 while((instr = u->ram.dat[u->ram.ptr++])) { 41 instr = u->ram[pc++];
41 switch(instr) { 42 /* Return Mode */
42#pragma GCC diagnostic push 43 if(instr & 0x40) { src = u->rst; dst = u->wst; }
43#pragma GCC diagnostic ignored "-Wunused-value" 44 else { src = u->wst; dst = u->rst; }
44#pragma GCC diagnostic ignored "-Wunused-variable" 45 /* Keep Mode */
45 case 0x00: /* LIT */ 46 if(instr & 0x80) { kptr = src->ptr; sp = &kptr; }
46 case 0x80: /* LITk */ 47 else sp = &src->ptr;
47 __asm__("evaluxn_00_LIT:"); 48 /* Short Mode */
48 { 49 bs = instr & 0x20;
49 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++); 50 opcode = instr & 0x1f;
50#ifndef NO_STACK_CHECKS 51 switch(opcode - (!opcode * (instr >> 5))) {
51 if(__builtin_expect(u->wst.ptr > 254, 0)) { 52 /* Literals/Calls */
52 u->wst.error = 2; 53 case -0x0: /* BRK */ return 1;
53 goto error; 54 case -0x1: /* JCI */ POP8(b) if(!b) { pc += 2; break; } // fallthrough
54 } 55 case -0x2: /* JMI */ PEEK16(a, pc) pc += a + 2; break;
55#endif 56 case -0x3: /* JSI */ PUSH16(u->rst, pc + 2) PEEK16(a, pc) pc += a + 2; break;
56 u->wst.ptr += 1; 57 case -0x4: /* LIT */
57 } 58 case -0x6: /* LITr */ a = u->ram[pc++]; PUSH8(src, a) break;
58 break; 59 case -0x5: /* LIT2 */
59 case 0x01: /* INC */ 60 case -0x7: /* LIT2r */ PEEK16(a, pc) PUSH16(src, a) pc += 2; break;
60 __asm__("evaluxn_01_INC:"); 61 /* ALU */
61 { 62 case 0x01: /* INC */ POP(a) PUSH(src, a + 1) break;
62 u8 a = u->wst.dat[u->wst.ptr - 1]; 63 case 0x02: /* POP */ POP(a) break;
63 u->wst.dat[u->wst.ptr - 1] = a + 1; 64 case 0x03: /* NIP */ POP(a) POP(b) PUSH(src, a) break;
64#ifndef NO_STACK_CHECKS 65 case 0x04: /* SWP */ POP(a) POP(b) PUSH(src, a) PUSH(src, b) break;
65 if(__builtin_expect(u->wst.ptr < 1, 0)) { 66 case 0x05: /* ROT */ POP(a) POP(b) POP(c) PUSH(src, b) PUSH(src, a) PUSH(src, c) break;
66 u->wst.error = 1; 67 case 0x06: /* DUP */ POP(a) PUSH(src, a) PUSH(src, a) break;
67 goto error; 68 case 0x07: /* OVR */ POP(a) POP(b) PUSH(src, b) PUSH(src, a) PUSH(src, b) break;
68 } 69 case 0x08: /* EQU */ POP(a) POP(b) PUSH8(src, b == a) break;
69#endif 70 case 0x09: /* NEQ */ POP(a) POP(b) PUSH8(src, b != a) break;
70 } 71 case 0x0a: /* GTH */ POP(a) POP(b) PUSH8(src, b > a) break;
71 break; 72 case 0x0b: /* LTH */ POP(a) POP(b) PUSH8(src, b < a) break;
72 case 0x02: /* POP */ 73 case 0x0c: /* JMP */ POP(a) JUMP(a) break;
73 __asm__("evaluxn_02_POP:"); 74 case 0x0d: /* JCN */ POP(a) POP8(b) if(b) JUMP(a) break;
74 { 75 case 0x0e: /* JSR */ POP(a) PUSH16(dst, pc) JUMP(a) break;
75 u->wst.dat[u->wst.ptr - 1]; 76 case 0x0f: /* STH */ POP(a) PUSH(dst, a) break;
76#ifndef NO_STACK_CHECKS 77 case 0x10: /* LDZ */ POP8(a) PEEK(b, a) PUSH(src, b) break;
77 if(__builtin_expect(u->wst.ptr < 1, 0)) { 78 case 0x11: /* STZ */ POP8(a) POP(b) POKE(a, b) break;
78 u->wst.error = 1; 79 case 0x12: /* LDR */ POP8(a) b = pc + (s8)a; PEEK(c, b) PUSH(src, c) break;
79 goto error; 80 case 0x13: /* STR */ POP8(a) POP(b) c = pc + (s8)a; POKE(c, b) break;
80 } 81 case 0x14: /* LDA */ POP16(a) PEEK(b, a) PUSH(src, b) break;
81#endif 82 case 0x15: /* STA */ POP16(a) POP(b) POKE(a, b) break;
82 u->wst.ptr -= 1; 83 case 0x16: /* DEI */ POP8(a) DEVR(b, a) PUSH(src, b) break;
83 } 84 case 0x17: /* DEO */ POP8(a) POP(b) DEVW(a, b) break;
84 break; 85 case 0x18: /* ADD */ POP(a) POP(b) PUSH(src, b + a) break;
85 case 0x06: /* DUP */ 86 case 0x19: /* SUB */ POP(a) POP(b) PUSH(src, b - a) break;
86 __asm__("evaluxn_03_DUP:"); 87 case 0x1a: /* MUL */ POP(a) POP(b) PUSH(src, (u32)b * a) break;
87 { 88 case 0x1b: /* DIV */ POP(a) POP(b) if(!a) HALT(3) PUSH(src, b / a) break;
88 u8 a = u->wst.dat[u->wst.ptr - 1]; 89 case 0x1c: /* AND */ POP(a) POP(b) PUSH(src, b & a) break;
89 u->wst.dat[u->wst.ptr] = a; 90 case 0x1d: /* ORA */ POP(a) POP(b) PUSH(src, b | a) break;
90#ifndef NO_STACK_CHECKS 91 case 0x1e: /* EOR */ POP(a) POP(b) PUSH(src, b ^ a) break;
91 if(__builtin_expect(u->wst.ptr < 1, 0)) { 92 case 0x1f: /* SFT */ POP8(a) POP(b) PUSH(src, b >> (a & 0x0f) << ((a & 0xf0) >> 4)) break;
92 u->wst.error = 1;
93 goto error;
94 }
95 if(__builtin_expect(u->wst.ptr > 254, 0)) {
96 u->wst.error = 2;
97 goto error;
98 }
99#endif
100 u->wst.ptr += 1;
101 }
102 break;
103 case 0x03: /* NIP */
104 __asm__("evaluxn_04_NIP:");
105 {
106 u8 a = u->wst.dat[u->wst.ptr - 1];
107 u->wst.dat[u->wst.ptr - 2];
108 u->wst.dat[u->wst.ptr - 2] = a;
109#ifndef NO_STACK_CHECKS
110 if(__builtin_expect(u->wst.ptr < 2, 0)) {
111 u->wst.error = 1;
112 goto error;
113 }
114#endif
115 u->wst.ptr -= 1;
116 }
117 break;
118 case 0x04: /* SWP */
119 __asm__("evaluxn_05_SWP:");
120 {
121 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
122 u->wst.dat[u->wst.ptr - 2] = a;
123 u->wst.dat[u->wst.ptr - 1] = b;
124#ifndef NO_STACK_CHECKS
125 if(__builtin_expect(u->wst.ptr < 2, 0)) {
126 u->wst.error = 1;
127 goto error;
128 }
129#endif
130 }
131 break;
132 case 0x07: /* OVR */
133 __asm__("evaluxn_06_OVR:");
134 {
135 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
136 u->wst.dat[u->wst.ptr] = b;
137#ifndef NO_STACK_CHECKS
138 if(__builtin_expect(u->wst.ptr < 2, 0)) {
139 u->wst.error = 1;
140 goto error;
141 }
142 if(__builtin_expect(u->wst.ptr > 254, 0)) {
143 u->wst.error = 2;
144 goto error;
145 }
146#endif
147 u->wst.ptr += 1;
148 }
149 break;
150 case 0x05: /* ROT */
151 __asm__("evaluxn_07_ROT:");
152 {
153 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3];
154 u->wst.dat[u->wst.ptr - 3] = b;
155 u->wst.dat[u->wst.ptr - 2] = a;
156 u->wst.dat[u->wst.ptr - 1] = c;
157#ifndef NO_STACK_CHECKS
158 if(__builtin_expect(u->wst.ptr < 3, 0)) {
159 u->wst.error = 1;
160 goto error;
161 }
162#endif
163 }
164 break;
165 case 0x08: /* EQU */
166 __asm__("evaluxn_08_EQU:");
167 {
168 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
169 u->wst.dat[u->wst.ptr - 2] = b == a;
170#ifndef NO_STACK_CHECKS
171 if(__builtin_expect(u->wst.ptr < 2, 0)) {
172 u->wst.error = 1;
173 goto error;
174 }
175#endif
176 u->wst.ptr -= 1;
177 }
178 break;
179 case 0x09: /* NEQ */
180 __asm__("evaluxn_09_NEQ:");
181 {
182 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
183 u->wst.dat[u->wst.ptr - 2] = b != a;
184#ifndef NO_STACK_CHECKS
185 if(__builtin_expect(u->wst.ptr < 2, 0)) {
186 u->wst.error = 1;
187 goto error;
188 }
189#endif
190 u->wst.ptr -= 1;
191 }
192 break;
193 case 0x0a: /* GTH */
194 __asm__("evaluxn_0a_GTH:");
195 {
196 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
197 u->wst.dat[u->wst.ptr - 2] = b > a;
198#ifndef NO_STACK_CHECKS
199 if(__builtin_expect(u->wst.ptr < 2, 0)) {
200 u->wst.error = 1;
201 goto error;
202 }
203#endif
204 u->wst.ptr -= 1;
205 }
206 break;
207 case 0x0b: /* LTH */
208 __asm__("evaluxn_0b_LTH:");
209 {
210 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
211 u->wst.dat[u->wst.ptr - 2] = b < a;
212#ifndef NO_STACK_CHECKS
213 if(__builtin_expect(u->wst.ptr < 2, 0)) {
214 u->wst.error = 1;
215 goto error;
216 }
217#endif
218 u->wst.ptr -= 1;
219 }
220 break;
221 case 0x0c: /* JMP */
222 __asm__("evaluxn_0c_JMP:");
223 {
224 u8 a = u->wst.dat[u->wst.ptr - 1];
225 u->ram.ptr += (s8)a;
226#ifndef NO_STACK_CHECKS
227 if(__builtin_expect(u->wst.ptr < 1, 0)) {
228 u->wst.error = 1;
229 goto error;
230 }
231#endif
232 u->wst.ptr -= 1;
233 }
234 break;
235 case 0x0d: /* JCN */
236 __asm__("evaluxn_0d_JCN:");
237 {
238 u8 a = u->wst.dat[u->wst.ptr - 1];
239 if(u->wst.dat[u->wst.ptr - 2]) u->ram.ptr += (s8)a;
240#ifndef NO_STACK_CHECKS
241 if(__builtin_expect(u->wst.ptr < 2, 0)) {
242 u->wst.error = 1;
243 goto error;
244 }
245#endif
246 u->wst.ptr -= 2;
247 }
248 break;
249 case 0x0e: /* JSR */
250 __asm__("evaluxn_0e_JSR:");
251 {
252 u8 a = u->wst.dat[u->wst.ptr - 1];
253 u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8;
254 u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff;
255 u->ram.ptr += (s8)a;
256#ifndef NO_STACK_CHECKS
257 if(__builtin_expect(u->wst.ptr < 1, 0)) {
258 u->wst.error = 1;
259 goto error;
260 }
261#endif
262 u->wst.ptr -= 1;
263#ifndef NO_STACK_CHECKS
264 if(__builtin_expect(u->rst.ptr > 253, 0)) {
265 u->rst.error = 2;
266 goto error;
267 }
268#endif
269 u->rst.ptr += 2;
270 }
271 break;
272 case 0x0f: /* STH */
273 __asm__("evaluxn_0f_STH:");
274 {
275 u8 a = u->wst.dat[u->wst.ptr - 1];
276 u->rst.dat[u->rst.ptr] = a;
277#ifndef NO_STACK_CHECKS
278 if(__builtin_expect(u->wst.ptr < 1, 0)) {
279 u->wst.error = 1;
280 goto error;
281 }
282#endif
283 u->wst.ptr -= 1;
284#ifndef NO_STACK_CHECKS
285 if(__builtin_expect(u->rst.ptr > 254, 0)) {
286 u->rst.error = 2;
287 goto error;
288 }
289#endif
290 u->rst.ptr += 1;
291 }
292 break;
293 case 0x10: /* LDZ */
294 __asm__("evaluxn_10_LDZ:");
295 {
296 u8 a = u->wst.dat[u->wst.ptr - 1];
297 u->wst.dat[u->wst.ptr - 1] = mempeek8(u->ram.dat, a);
298#ifndef NO_STACK_CHECKS
299 if(__builtin_expect(u->wst.ptr < 1, 0)) {
300 u->wst.error = 1;
301 goto error;
302 }
303#endif
304 }
305 break;
306 case 0x11: /* STZ */
307 __asm__("evaluxn_11_STZ:");
308 {
309 u8 a = u->wst.dat[u->wst.ptr - 1];
310 u8 b = u->wst.dat[u->wst.ptr - 2];
311 mempoke8(u->ram.dat, a, b);
312#ifndef NO_STACK_CHECKS
313 if(__builtin_expect(u->wst.ptr < 2, 0)) {
314 u->wst.error = 1;
315 goto error;
316 }
317#endif
318 u->wst.ptr -= 2;
319 }
320 break;
321 case 0x12: /* LDR */
322 __asm__("evaluxn_12_LDR:");
323 {
324 u8 a = u->wst.dat[u->wst.ptr - 1];
325 u->wst.dat[u->wst.ptr - 1] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
326#ifndef NO_STACK_CHECKS
327 if(__builtin_expect(u->wst.ptr < 1, 0)) {
328 u->wst.error = 1;
329 goto error;
330 }
331#endif
332 }
333 break;
334 case 0x13: /* STR */
335 __asm__("evaluxn_13_STR:");
336 {
337 u8 a = u->wst.dat[u->wst.ptr - 1];
338 u8 b = u->wst.dat[u->wst.ptr - 2];
339 mempoke8(u->ram.dat, u->ram.ptr + (s8)a, b);
340#ifndef NO_STACK_CHECKS
341 if(__builtin_expect(u->wst.ptr < 2, 0)) {
342 u->wst.error = 1;
343 goto error;
344 }
345#endif
346 u->wst.ptr -= 2;
347 }
348 break;
349 case 0x14: /* LDA */
350 __asm__("evaluxn_14_LDA:");
351 {
352 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
353 u->wst.dat[u->wst.ptr - 2] = mempeek8(u->ram.dat, a);
354#ifndef NO_STACK_CHECKS
355 if(__builtin_expect(u->wst.ptr < 2, 0)) {
356 u->wst.error = 1;
357 goto error;
358 }
359#endif
360 u->wst.ptr -= 1;
361 }
362 break;
363 case 0x15: /* STA */
364 __asm__("evaluxn_15_STA:");
365 {
366 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
367 u8 b = u->wst.dat[u->wst.ptr - 3];
368 mempoke8(u->ram.dat, a, b);
369#ifndef NO_STACK_CHECKS
370 if(__builtin_expect(u->wst.ptr < 3, 0)) {
371 u->wst.error = 1;
372 goto error;
373 }
374#endif
375 u->wst.ptr -= 3;
376 }
377 break;
378 case 0x16: /* DEI */
379 __asm__("evaluxn_16_DEI:");
380 {
381 u8 a = u->wst.dat[u->wst.ptr - 1];
382 u->wst.dat[u->wst.ptr - 1] = devpeek8(&u->dev[a >> 4], a);
383#ifndef NO_STACK_CHECKS
384 if(__builtin_expect(u->wst.ptr < 1, 0)) {
385 u->wst.error = 1;
386 goto error;
387 }
388#endif
389 }
390 break;
391 case 0x17: /* DEO */
392 __asm__("evaluxn_17_DEO:");
393 {
394 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
395 devpoke8(&u->dev[a >> 4], a, b);
396#ifndef NO_STACK_CHECKS
397 if(__builtin_expect(u->wst.ptr < 2, 0)) {
398 u->wst.error = 1;
399 goto error;
400 }
401#endif
402 u->wst.ptr -= 2;
403 }
404 break;
405 case 0x18: /* ADD */
406 __asm__("evaluxn_18_ADD:");
407 {
408 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
409 u->wst.dat[u->wst.ptr - 2] = b + a;
410#ifndef NO_STACK_CHECKS
411 if(__builtin_expect(u->wst.ptr < 2, 0)) {
412 u->wst.error = 1;
413 goto error;
414 }
415#endif
416 u->wst.ptr -= 1;
417 }
418 break;
419 case 0x19: /* SUB */
420 __asm__("evaluxn_19_SUB:");
421 {
422 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
423 u->wst.dat[u->wst.ptr - 2] = b - a;
424#ifndef NO_STACK_CHECKS
425 if(__builtin_expect(u->wst.ptr < 2, 0)) {
426 u->wst.error = 1;
427 goto error;
428 }
429#endif
430 u->wst.ptr -= 1;
431 }
432 break;
433 case 0x1a: /* MUL */
434 __asm__("evaluxn_1a_MUL:");
435 {
436 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
437 u->wst.dat[u->wst.ptr - 2] = b * a;
438#ifndef NO_STACK_CHECKS
439 if(__builtin_expect(u->wst.ptr < 2, 0)) {
440 u->wst.error = 1;
441 goto error;
442 }
443#endif
444 u->wst.ptr -= 1;
445 }
446 break;
447 case 0x1b: /* DIV */
448 __asm__("evaluxn_1b_DIV:");
449 {
450 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
451 if(a == 0) {
452 u->wst.error = 3;
453#ifndef NO_STACK_CHECKS
454 goto error;
455#endif
456 a = 1;
457 }
458 u->wst.dat[u->wst.ptr - 2] = b / a;
459#ifndef NO_STACK_CHECKS
460 if(__builtin_expect(u->wst.ptr < 2, 0)) {
461 u->wst.error = 1;
462 goto error;
463 }
464#endif
465 u->wst.ptr -= 1;
466 }
467 break;
468 case 0x1c: /* AND */
469 __asm__("evaluxn_1c_AND:");
470 {
471 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
472 u->wst.dat[u->wst.ptr - 2] = b & a;
473#ifndef NO_STACK_CHECKS
474 if(__builtin_expect(u->wst.ptr < 2, 0)) {
475 u->wst.error = 1;
476 goto error;
477 }
478#endif
479 u->wst.ptr -= 1;
480 }
481 break;
482 case 0x1d: /* ORA */
483 __asm__("evaluxn_1d_ORA:");
484 {
485 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
486 u->wst.dat[u->wst.ptr - 2] = b | a;
487#ifndef NO_STACK_CHECKS
488 if(__builtin_expect(u->wst.ptr < 2, 0)) {
489 u->wst.error = 1;
490 goto error;
491 }
492#endif
493 u->wst.ptr -= 1;
494 }
495 break;
496 case 0x1e: /* EOR */
497 __asm__("evaluxn_1e_EOR:");
498 {
499 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
500 u->wst.dat[u->wst.ptr - 2] = b ^ a;
501#ifndef NO_STACK_CHECKS
502 if(__builtin_expect(u->wst.ptr < 2, 0)) {
503 u->wst.error = 1;
504 goto error;
505 }
506#endif
507 u->wst.ptr -= 1;
508 }
509 break;
510 case 0x1f: /* SFT */
511 __asm__("evaluxn_1f_SFT:");
512 {
513 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
514 u->wst.dat[u->wst.ptr - 2] = b >> (a & 0x07) << ((a & 0x70) >> 4);
515#ifndef NO_STACK_CHECKS
516 if(__builtin_expect(u->wst.ptr < 2, 0)) {
517 u->wst.error = 1;
518 goto error;
519 }
520#endif
521 u->wst.ptr -= 1;
522 }
523 break;
524 case 0x20: /* LIT2 */
525 case 0xa0: /* LIT2k */
526 __asm__("evaluxn_20_LIT2:");
527 {
528 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
529 u->wst.dat[u->wst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++);
530#ifndef NO_STACK_CHECKS
531 if(__builtin_expect(u->wst.ptr > 253, 0)) {
532 u->wst.error = 2;
533 goto error;
534 }
535#endif
536 u->wst.ptr += 2;
537 }
538 break;
539 case 0x21: /* INC2 */
540 __asm__("evaluxn_21_INC2:");
541 {
542 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
543 u->wst.dat[u->wst.ptr - 2] = (a + 1) >> 8;
544 u->wst.dat[u->wst.ptr - 1] = (a + 1) & 0xff;
545#ifndef NO_STACK_CHECKS
546 if(__builtin_expect(u->wst.ptr < 2, 0)) {
547 u->wst.error = 1;
548 goto error;
549 }
550#endif
551 }
552 break;
553 case 0x22: /* POP2 */
554 __asm__("evaluxn_22_POP2:");
555 {
556 (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
557#ifndef NO_STACK_CHECKS
558 if(__builtin_expect(u->wst.ptr < 2, 0)) {
559 u->wst.error = 1;
560 goto error;
561 }
562#endif
563 u->wst.ptr -= 2;
564 }
565 break;
566 case 0x26: /* DUP2 */
567 __asm__("evaluxn_23_DUP2:");
568 {
569 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
570 u->wst.dat[u->wst.ptr] = b;
571 u->wst.dat[u->wst.ptr + 1] = a;
572#ifndef NO_STACK_CHECKS
573 if(__builtin_expect(u->wst.ptr < 2, 0)) {
574 u->wst.error = 1;
575 goto error;
576 }
577 if(__builtin_expect(u->wst.ptr > 253, 0)) {
578 u->wst.error = 2;
579 goto error;
580 }
581#endif
582 u->wst.ptr += 2;
583 }
584 break;
585 case 0x23: /* NIP2 */
586 __asm__("evaluxn_24_NIP2:");
587 {
588 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
589 (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
590 u->wst.dat[u->wst.ptr - 4] = a >> 8;
591 u->wst.dat[u->wst.ptr - 3] = a & 0xff;
592#ifndef NO_STACK_CHECKS
593 if(__builtin_expect(u->wst.ptr < 4, 0)) {
594 u->wst.error = 1;
595 goto error;
596 }
597#endif
598 u->wst.ptr -= 2;
599 }
600 break;
601 case 0x24: /* SWP2 */
602 __asm__("evaluxn_25_SWP2:");
603 {
604 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
605 u->wst.dat[u->wst.ptr - 4] = b;
606 u->wst.dat[u->wst.ptr - 3] = a;
607 u->wst.dat[u->wst.ptr - 2] = d;
608 u->wst.dat[u->wst.ptr - 1] = c;
609#ifndef NO_STACK_CHECKS
610 if(__builtin_expect(u->wst.ptr < 4, 0)) {
611 u->wst.error = 1;
612 goto error;
613 }
614#endif
615 }
616 break;
617 case 0x27: /* OVR2 */
618 __asm__("evaluxn_26_OVR2:");
619 {
620 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
621 u->wst.dat[u->wst.ptr] = d;
622 u->wst.dat[u->wst.ptr + 1] = c;
623#ifndef NO_STACK_CHECKS
624 if(__builtin_expect(u->wst.ptr < 4, 0)) {
625 u->wst.error = 1;
626 goto error;
627 }
628 if(__builtin_expect(u->wst.ptr > 253, 0)) {
629 u->wst.error = 2;
630 goto error;
631 }
632#endif
633 u->wst.ptr += 2;
634 }
635 break;
636 case 0x25: /* ROT2 */
637 __asm__("evaluxn_27_ROT2:");
638 {
639 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4], e = u->wst.dat[u->wst.ptr - 5], f = u->wst.dat[u->wst.ptr - 6];
640 u->wst.dat[u->wst.ptr - 6] = d;
641 u->wst.dat[u->wst.ptr - 5] = c;
642 u->wst.dat[u->wst.ptr - 4] = b;
643 u->wst.dat[u->wst.ptr - 3] = a;
644 u->wst.dat[u->wst.ptr - 2] = f;
645 u->wst.dat[u->wst.ptr - 1] = e;
646#ifndef NO_STACK_CHECKS
647 if(__builtin_expect(u->wst.ptr < 6, 0)) {
648 u->wst.error = 1;
649 goto error;
650 }
651#endif
652 }
653 break;
654 case 0x28: /* EQU2 */
655 __asm__("evaluxn_28_EQU2:");
656 {
657 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
658 u->wst.dat[u->wst.ptr - 4] = b == a;
659#ifndef NO_STACK_CHECKS
660 if(__builtin_expect(u->wst.ptr < 4, 0)) {
661 u->wst.error = 1;
662 goto error;
663 }
664#endif
665 u->wst.ptr -= 3;
666 }
667 break;
668 case 0x29: /* NEQ2 */
669 __asm__("evaluxn_29_NEQ2:");
670 {
671 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
672 u->wst.dat[u->wst.ptr - 4] = b != a;
673#ifndef NO_STACK_CHECKS
674 if(__builtin_expect(u->wst.ptr < 4, 0)) {
675 u->wst.error = 1;
676 goto error;
677 }
678#endif
679 u->wst.ptr -= 3;
680 }
681 break;
682 case 0x2a: /* GTH2 */
683 __asm__("evaluxn_2a_GTH2:");
684 {
685 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
686 u->wst.dat[u->wst.ptr - 4] = b > a;
687#ifndef NO_STACK_CHECKS
688 if(__builtin_expect(u->wst.ptr < 4, 0)) {
689 u->wst.error = 1;
690 goto error;
691 }
692#endif
693 u->wst.ptr -= 3;
694 }
695 break;
696 case 0x2b: /* LTH2 */
697 __asm__("evaluxn_2b_LTH2:");
698 {
699 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
700 u->wst.dat[u->wst.ptr - 4] = b < a;
701#ifndef NO_STACK_CHECKS
702 if(__builtin_expect(u->wst.ptr < 4, 0)) {
703 u->wst.error = 1;
704 goto error;
705 }
706#endif
707 u->wst.ptr -= 3;
708 }
709 break;
710 case 0x2c: /* JMP2 */
711 __asm__("evaluxn_2c_JMP2:");
712 {
713 u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
714#ifndef NO_STACK_CHECKS
715 if(__builtin_expect(u->wst.ptr < 2, 0)) {
716 u->wst.error = 1;
717 goto error;
718 }
719#endif
720 u->wst.ptr -= 2;
721 }
722 break;
723 case 0x2d: /* JCN2 */
724 __asm__("evaluxn_2d_JCN2:");
725 {
726 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
727 if(u->wst.dat[u->wst.ptr - 3]) u->ram.ptr = a;
728#ifndef NO_STACK_CHECKS
729 if(__builtin_expect(u->wst.ptr < 3, 0)) {
730 u->wst.error = 1;
731 goto error;
732 }
733#endif
734 u->wst.ptr -= 3;
735 }
736 break;
737 case 0x2e: /* JSR2 */
738 __asm__("evaluxn_2e_JSR2:");
739 {
740 u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8;
741 u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff;
742 u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
743#ifndef NO_STACK_CHECKS
744 if(__builtin_expect(u->wst.ptr < 2, 0)) {
745 u->wst.error = 1;
746 goto error;
747 }
748#endif
749 u->wst.ptr -= 2;
750#ifndef NO_STACK_CHECKS
751 if(__builtin_expect(u->rst.ptr > 253, 0)) {
752 u->rst.error = 2;
753 goto error;
754 }
755#endif
756 u->rst.ptr += 2;
757 }
758 break;
759 case 0x2f: /* STH2 */
760 __asm__("evaluxn_2f_STH2:");
761 {
762 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
763 u->rst.dat[u->rst.ptr] = b;
764 u->rst.dat[u->rst.ptr + 1] = a;
765#ifndef NO_STACK_CHECKS
766 if(__builtin_expect(u->wst.ptr < 2, 0)) {
767 u->wst.error = 1;
768 goto error;
769 }
770#endif
771 u->wst.ptr -= 2;
772#ifndef NO_STACK_CHECKS
773 if(__builtin_expect(u->rst.ptr > 253, 0)) {
774 u->rst.error = 2;
775 goto error;
776 }
777#endif
778 u->rst.ptr += 2;
779 }
780 break;
781 case 0x30: /* LDZ2 */
782 __asm__("evaluxn_30_LDZ2:");
783 {
784 u8 a = u->wst.dat[u->wst.ptr - 1];
785 u->wst.dat[u->wst.ptr - 1] = mempeek8(u->ram.dat, a);
786 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, a + 1);
787#ifndef NO_STACK_CHECKS
788 if(__builtin_expect(u->wst.ptr < 1, 0)) {
789 u->wst.error = 1;
790 goto error;
791 }
792 if(__builtin_expect(u->wst.ptr > 254, 0)) {
793 u->wst.error = 2;
794 goto error;
795 }
796#endif
797 u->wst.ptr += 1;
798 }
799 break;
800 case 0x31: /* STZ2 */
801 __asm__("evaluxn_31_STZ2:");
802 {
803 u8 a = u->wst.dat[u->wst.ptr - 1];
804 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
805 mempoke16(u->ram.dat, a, b);
806#ifndef NO_STACK_CHECKS
807 if(__builtin_expect(u->wst.ptr < 3, 0)) {
808 u->wst.error = 1;
809 goto error;
810 }
811#endif
812 u->wst.ptr -= 3;
813 }
814 break;
815 case 0x32: /* LDR2 */
816 __asm__("evaluxn_32_LDR2:");
817 {
818 u8 a = u->wst.dat[u->wst.ptr - 1];
819 u->wst.dat[u->wst.ptr - 1] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
820 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a + 1);
821#ifndef NO_STACK_CHECKS
822 if(__builtin_expect(u->wst.ptr < 1, 0)) {
823 u->wst.error = 1;
824 goto error;
825 }
826 if(__builtin_expect(u->wst.ptr > 254, 0)) {
827 u->wst.error = 2;
828 goto error;
829 }
830#endif
831 u->wst.ptr += 1;
832 }
833 break;
834 case 0x33: /* STR2 */
835 __asm__("evaluxn_33_STR2:");
836 {
837 u8 a = u->wst.dat[u->wst.ptr - 1];
838 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
839 mempoke16(u->ram.dat, u->ram.ptr + (s8)a, b);
840#ifndef NO_STACK_CHECKS
841 if(__builtin_expect(u->wst.ptr < 3, 0)) {
842 u->wst.error = 1;
843 goto error;
844 }
845#endif
846 u->wst.ptr -= 3;
847 }
848 break;
849 case 0x34: /* LDA2 */
850 __asm__("evaluxn_34_LDA2:");
851 {
852 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
853 u->wst.dat[u->wst.ptr - 2] = mempeek8(u->ram.dat, a);
854 u->wst.dat[u->wst.ptr - 1] = mempeek8(u->ram.dat, a + 1);
855#ifndef NO_STACK_CHECKS
856 if(__builtin_expect(u->wst.ptr < 2, 0)) {
857 u->wst.error = 1;
858 goto error;
859 }
860#endif
861 }
862 break;
863 case 0x35: /* STA2 */
864 __asm__("evaluxn_35_STA2:");
865 {
866 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
867 u16 b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
868 mempoke16(u->ram.dat, a, b);
869#ifndef NO_STACK_CHECKS
870 if(__builtin_expect(u->wst.ptr < 4, 0)) {
871 u->wst.error = 1;
872 goto error;
873 }
874#endif
875 u->wst.ptr -= 4;
876 }
877 break;
878 case 0x36: /* DEI2 */
879 __asm__("evaluxn_36_DEI2:");
880 {
881 u8 a = u->wst.dat[u->wst.ptr - 1];
882 u->wst.dat[u->wst.ptr - 1] = devpeek8(&u->dev[a >> 4], a);
883 u->wst.dat[u->wst.ptr] = devpeek8(&u->dev[a >> 4], a + 1);
884#ifndef NO_STACK_CHECKS
885 if(__builtin_expect(u->wst.ptr < 1, 0)) {
886 u->wst.error = 1;
887 goto error;
888 }
889 if(__builtin_expect(u->wst.ptr > 254, 0)) {
890 u->wst.error = 2;
891 goto error;
892 }
893#endif
894 u->wst.ptr += 1;
895 }
896 break;
897 case 0x37: /* DEO2 */
898 __asm__("evaluxn_37_DEO2:");
899 {
900 u8 a = u->wst.dat[u->wst.ptr - 1];
901 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
902 devpoke16(&u->dev[a >> 4], a, b);
903#ifndef NO_STACK_CHECKS
904 if(__builtin_expect(u->wst.ptr < 3, 0)) {
905 u->wst.error = 1;
906 goto error;
907 }
908#endif
909 u->wst.ptr -= 3;
910 }
911 break;
912 case 0x38: /* ADD2 */
913 __asm__("evaluxn_38_ADD2:");
914 {
915 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
916 u->wst.dat[u->wst.ptr - 4] = (b + a) >> 8;
917 u->wst.dat[u->wst.ptr - 3] = (b + a) & 0xff;
918#ifndef NO_STACK_CHECKS
919 if(__builtin_expect(u->wst.ptr < 4, 0)) {
920 u->wst.error = 1;
921 goto error;
922 }
923#endif
924 u->wst.ptr -= 2;
925 }
926 break;
927 case 0x39: /* SUB2 */
928 __asm__("evaluxn_39_SUB2:");
929 {
930 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
931 u->wst.dat[u->wst.ptr - 4] = (b - a) >> 8;
932 u->wst.dat[u->wst.ptr - 3] = (b - a) & 0xff;
933#ifndef NO_STACK_CHECKS
934 if(__builtin_expect(u->wst.ptr < 4, 0)) {
935 u->wst.error = 1;
936 goto error;
937 }
938#endif
939 u->wst.ptr -= 2;
940 }
941 break;
942 case 0x3a: /* MUL2 */
943 __asm__("evaluxn_3a_MUL2:");
944 {
945 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
946 u->wst.dat[u->wst.ptr - 4] = (b * a) >> 8;
947 u->wst.dat[u->wst.ptr - 3] = (b * a) & 0xff;
948#ifndef NO_STACK_CHECKS
949 if(__builtin_expect(u->wst.ptr < 4, 0)) {
950 u->wst.error = 1;
951 goto error;
952 }
953#endif
954 u->wst.ptr -= 2;
955 }
956 break;
957 case 0x3b: /* DIV2 */
958 __asm__("evaluxn_3b_DIV2:");
959 {
960 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
961 if(a == 0) {
962 u->wst.error = 3;
963#ifndef NO_STACK_CHECKS
964 goto error;
965#endif
966 a = 1;
967 }
968 u->wst.dat[u->wst.ptr - 4] = (b / a) >> 8;
969 u->wst.dat[u->wst.ptr - 3] = (b / a) & 0xff;
970#ifndef NO_STACK_CHECKS
971 if(__builtin_expect(u->wst.ptr < 4, 0)) {
972 u->wst.error = 1;
973 goto error;
974 }
975#endif
976 u->wst.ptr -= 2;
977 }
978 break;
979 case 0x3c: /* AND2 */
980 __asm__("evaluxn_3c_AND2:");
981 {
982 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
983 u->wst.dat[u->wst.ptr - 4] = d & b;
984 u->wst.dat[u->wst.ptr - 3] = c & a;
985#ifndef NO_STACK_CHECKS
986 if(__builtin_expect(u->wst.ptr < 4, 0)) {
987 u->wst.error = 1;
988 goto error;
989 }
990#endif
991 u->wst.ptr -= 2;
992 }
993 break;
994 case 0x3d: /* ORA2 */
995 __asm__("evaluxn_3d_ORA2:");
996 {
997 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
998 u->wst.dat[u->wst.ptr - 4] = d | b;
999 u->wst.dat[u->wst.ptr - 3] = c | a;
1000#ifndef NO_STACK_CHECKS
1001 if(__builtin_expect(u->wst.ptr < 4, 0)) {
1002 u->wst.error = 1;
1003 goto error;
1004 }
1005#endif
1006 u->wst.ptr -= 2;
1007 }
1008 break;
1009 case 0x3e: /* EOR2 */
1010 __asm__("evaluxn_3e_EOR2:");
1011 {
1012 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
1013 u->wst.dat[u->wst.ptr - 4] = d ^ b;
1014 u->wst.dat[u->wst.ptr - 3] = c ^ a;
1015#ifndef NO_STACK_CHECKS
1016 if(__builtin_expect(u->wst.ptr < 4, 0)) {
1017 u->wst.error = 1;
1018 goto error;
1019 }
1020#endif
1021 u->wst.ptr -= 2;
1022 }
1023 break;
1024 case 0x3f: /* SFT2 */
1025 __asm__("evaluxn_3f_SFT2:");
1026 {
1027 u8 a = u->wst.dat[u->wst.ptr - 1];
1028 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
1029 u->wst.dat[u->wst.ptr - 3] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8;
1030 u->wst.dat[u->wst.ptr - 2] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff;
1031#ifndef NO_STACK_CHECKS
1032 if(__builtin_expect(u->wst.ptr < 3, 0)) {
1033 u->wst.error = 1;
1034 goto error;
1035 }
1036#endif
1037 u->wst.ptr -= 1;
1038 }
1039 break;
1040 case 0x40: /* LITr */
1041 case 0xc0: /* LITkr */
1042 __asm__("evaluxn_40_LITr:");
1043 {
1044 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
1045#ifndef NO_STACK_CHECKS
1046 if(__builtin_expect(u->rst.ptr > 254, 0)) {
1047 u->rst.error = 2;
1048 goto error;
1049 }
1050#endif
1051 u->rst.ptr += 1;
1052 }
1053 break;
1054 case 0x41: /* INCr */
1055 __asm__("evaluxn_41_INCr:");
1056 {
1057 u8 a = u->rst.dat[u->rst.ptr - 1];
1058 u->rst.dat[u->rst.ptr - 1] = a + 1;
1059#ifndef NO_STACK_CHECKS
1060 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1061 u->rst.error = 1;
1062 goto error;
1063 }
1064#endif
1065 }
1066 break;
1067 case 0x42: /* POPr */
1068 __asm__("evaluxn_42_POPr:");
1069 {
1070 u->rst.dat[u->rst.ptr - 1];
1071#ifndef NO_STACK_CHECKS
1072 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1073 u->rst.error = 1;
1074 goto error;
1075 }
1076#endif
1077 u->rst.ptr -= 1;
1078 }
1079 break;
1080 case 0x46: /* DUPr */
1081 __asm__("evaluxn_43_DUPr:");
1082 {
1083 u8 a = u->rst.dat[u->rst.ptr - 1];
1084 u->rst.dat[u->rst.ptr] = a;
1085#ifndef NO_STACK_CHECKS
1086 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1087 u->rst.error = 1;
1088 goto error;
1089 }
1090 if(__builtin_expect(u->rst.ptr > 254, 0)) {
1091 u->rst.error = 2;
1092 goto error;
1093 }
1094#endif
1095 u->rst.ptr += 1;
1096 }
1097 break;
1098 case 0x43: /* NIPr */
1099 __asm__("evaluxn_44_NIPr:");
1100 {
1101 u8 a = u->rst.dat[u->rst.ptr - 1];
1102 u->rst.dat[u->rst.ptr - 2];
1103 u->rst.dat[u->rst.ptr - 2] = a;
1104#ifndef NO_STACK_CHECKS
1105 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1106 u->rst.error = 1;
1107 goto error;
1108 }
1109#endif
1110 u->rst.ptr -= 1;
1111 }
1112 break;
1113 case 0x44: /* SWPr */
1114 __asm__("evaluxn_45_SWPr:");
1115 {
1116 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1117 u->rst.dat[u->rst.ptr - 2] = a;
1118 u->rst.dat[u->rst.ptr - 1] = b;
1119#ifndef NO_STACK_CHECKS
1120 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1121 u->rst.error = 1;
1122 goto error;
1123 }
1124#endif
1125 }
1126 break;
1127 case 0x47: /* OVRr */
1128 __asm__("evaluxn_46_OVRr:");
1129 {
1130 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1131 u->rst.dat[u->rst.ptr] = b;
1132#ifndef NO_STACK_CHECKS
1133 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1134 u->rst.error = 1;
1135 goto error;
1136 }
1137 if(__builtin_expect(u->rst.ptr > 254, 0)) {
1138 u->rst.error = 2;
1139 goto error;
1140 }
1141#endif
1142 u->rst.ptr += 1;
1143 }
1144 break;
1145 case 0x45: /* ROTr */
1146 __asm__("evaluxn_47_ROTr:");
1147 {
1148 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3];
1149 u->rst.dat[u->rst.ptr - 3] = b;
1150 u->rst.dat[u->rst.ptr - 2] = a;
1151 u->rst.dat[u->rst.ptr - 1] = c;
1152#ifndef NO_STACK_CHECKS
1153 if(__builtin_expect(u->rst.ptr < 3, 0)) {
1154 u->rst.error = 1;
1155 goto error;
1156 }
1157#endif
1158 }
1159 break;
1160 case 0x48: /* EQUr */
1161 __asm__("evaluxn_48_EQUr:");
1162 {
1163 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1164 u->rst.dat[u->rst.ptr - 2] = b == a;
1165#ifndef NO_STACK_CHECKS
1166 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1167 u->rst.error = 1;
1168 goto error;
1169 }
1170#endif
1171 u->rst.ptr -= 1;
1172 }
1173 break;
1174 case 0x49: /* NEQr */
1175 __asm__("evaluxn_49_NEQr:");
1176 {
1177 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1178 u->rst.dat[u->rst.ptr - 2] = b != a;
1179#ifndef NO_STACK_CHECKS
1180 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1181 u->rst.error = 1;
1182 goto error;
1183 }
1184#endif
1185 u->rst.ptr -= 1;
1186 }
1187 break;
1188 case 0x4a: /* GTHr */
1189 __asm__("evaluxn_4a_GTHr:");
1190 {
1191 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1192 u->rst.dat[u->rst.ptr - 2] = b > a;
1193#ifndef NO_STACK_CHECKS
1194 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1195 u->rst.error = 1;
1196 goto error;
1197 }
1198#endif
1199 u->rst.ptr -= 1;
1200 }
1201 break;
1202 case 0x4b: /* LTHr */
1203 __asm__("evaluxn_4b_LTHr:");
1204 {
1205 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1206 u->rst.dat[u->rst.ptr - 2] = b < a;
1207#ifndef NO_STACK_CHECKS
1208 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1209 u->rst.error = 1;
1210 goto error;
1211 }
1212#endif
1213 u->rst.ptr -= 1;
1214 }
1215 break;
1216 case 0x4c: /* JMPr */
1217 __asm__("evaluxn_4c_JMPr:");
1218 {
1219 u8 a = u->rst.dat[u->rst.ptr - 1];
1220 u->ram.ptr += (s8)a;
1221#ifndef NO_STACK_CHECKS
1222 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1223 u->rst.error = 1;
1224 goto error;
1225 }
1226#endif
1227 u->rst.ptr -= 1;
1228 }
1229 break;
1230 case 0x4d: /* JCNr */
1231 __asm__("evaluxn_4d_JCNr:");
1232 {
1233 u8 a = u->rst.dat[u->rst.ptr - 1];
1234 if(u->rst.dat[u->rst.ptr - 2]) u->ram.ptr += (s8)a;
1235#ifndef NO_STACK_CHECKS
1236 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1237 u->rst.error = 1;
1238 goto error;
1239 }
1240#endif
1241 u->rst.ptr -= 2;
1242 }
1243 break;
1244 case 0x4e: /* JSRr */
1245 __asm__("evaluxn_4e_JSRr:");
1246 {
1247 u8 a = u->rst.dat[u->rst.ptr - 1];
1248 u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8;
1249 u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff;
1250 u->ram.ptr += (s8)a;
1251#ifndef NO_STACK_CHECKS
1252 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1253 u->rst.error = 1;
1254 goto error;
1255 }
1256#endif
1257 u->rst.ptr -= 1;
1258#ifndef NO_STACK_CHECKS
1259 if(__builtin_expect(u->wst.ptr > 253, 0)) {
1260 u->wst.error = 2;
1261 goto error;
1262 }
1263#endif
1264 u->wst.ptr += 2;
1265 }
1266 break;
1267 case 0x4f: /* STHr */
1268 __asm__("evaluxn_4f_STHr:");
1269 {
1270 u8 a = u->rst.dat[u->rst.ptr - 1];
1271 u->wst.dat[u->wst.ptr] = a;
1272#ifndef NO_STACK_CHECKS
1273 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1274 u->rst.error = 1;
1275 goto error;
1276 }
1277#endif
1278 u->rst.ptr -= 1;
1279#ifndef NO_STACK_CHECKS
1280 if(__builtin_expect(u->wst.ptr > 254, 0)) {
1281 u->wst.error = 2;
1282 goto error;
1283 }
1284#endif
1285 u->wst.ptr += 1;
1286 }
1287 break;
1288 case 0x50: /* LDZr */
1289 __asm__("evaluxn_50_LDZr:");
1290 {
1291 u8 a = u->rst.dat[u->rst.ptr - 1];
1292 u->rst.dat[u->rst.ptr - 1] = mempeek8(u->ram.dat, a);
1293#ifndef NO_STACK_CHECKS
1294 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1295 u->rst.error = 1;
1296 goto error;
1297 }
1298#endif
1299 }
1300 break;
1301 case 0x51: /* STZr */
1302 __asm__("evaluxn_51_STZr:");
1303 {
1304 u8 a = u->rst.dat[u->rst.ptr - 1];
1305 u8 b = u->rst.dat[u->rst.ptr - 2];
1306 mempoke8(u->ram.dat, a, b);
1307#ifndef NO_STACK_CHECKS
1308 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1309 u->rst.error = 1;
1310 goto error;
1311 }
1312#endif
1313 u->rst.ptr -= 2;
1314 }
1315 break;
1316 case 0x52: /* LDRr */
1317 __asm__("evaluxn_52_LDRr:");
1318 {
1319 u8 a = u->rst.dat[u->rst.ptr - 1];
1320 u->rst.dat[u->rst.ptr - 1] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
1321#ifndef NO_STACK_CHECKS
1322 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1323 u->rst.error = 1;
1324 goto error;
1325 }
1326#endif
1327 }
1328 break;
1329 case 0x53: /* STRr */
1330 __asm__("evaluxn_53_STRr:");
1331 {
1332 u8 a = u->rst.dat[u->rst.ptr - 1];
1333 u8 b = u->rst.dat[u->rst.ptr - 2];
1334 mempoke8(u->ram.dat, u->ram.ptr + (s8)a, b);
1335#ifndef NO_STACK_CHECKS
1336 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1337 u->rst.error = 1;
1338 goto error;
1339 }
1340#endif
1341 u->rst.ptr -= 2;
1342 }
1343 break;
1344 case 0x54: /* LDAr */
1345 __asm__("evaluxn_54_LDAr:");
1346 {
1347 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1348 u->rst.dat[u->rst.ptr - 2] = mempeek8(u->ram.dat, a);
1349#ifndef NO_STACK_CHECKS
1350 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1351 u->rst.error = 1;
1352 goto error;
1353 }
1354#endif
1355 u->rst.ptr -= 1;
1356 }
1357 break;
1358 case 0x55: /* STAr */
1359 __asm__("evaluxn_55_STAr:");
1360 {
1361 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1362 u8 b = u->rst.dat[u->rst.ptr - 3];
1363 mempoke8(u->ram.dat, a, b);
1364#ifndef NO_STACK_CHECKS
1365 if(__builtin_expect(u->rst.ptr < 3, 0)) {
1366 u->rst.error = 1;
1367 goto error;
1368 }
1369#endif
1370 u->rst.ptr -= 3;
1371 }
1372 break;
1373 case 0x56: /* DEIr */
1374 __asm__("evaluxn_56_DEIr:");
1375 {
1376 u8 a = u->rst.dat[u->rst.ptr - 1];
1377 u->rst.dat[u->rst.ptr - 1] = devpeek8(&u->dev[a >> 4], a);
1378#ifndef NO_STACK_CHECKS
1379 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1380 u->rst.error = 1;
1381 goto error;
1382 }
1383#endif
1384 }
1385 break;
1386 case 0x57: /* DEOr */
1387 __asm__("evaluxn_57_DEOr:");
1388 {
1389 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1390 devpoke8(&u->dev[a >> 4], a, b);
1391#ifndef NO_STACK_CHECKS
1392 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1393 u->rst.error = 1;
1394 goto error;
1395 }
1396#endif
1397 u->rst.ptr -= 2;
1398 }
1399 break;
1400 case 0x58: /* ADDr */
1401 __asm__("evaluxn_58_ADDr:");
1402 {
1403 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1404 u->rst.dat[u->rst.ptr - 2] = b + a;
1405#ifndef NO_STACK_CHECKS
1406 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1407 u->rst.error = 1;
1408 goto error;
1409 }
1410#endif
1411 u->rst.ptr -= 1;
1412 }
1413 break;
1414 case 0x59: /* SUBr */
1415 __asm__("evaluxn_59_SUBr:");
1416 {
1417 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1418 u->rst.dat[u->rst.ptr - 2] = b - a;
1419#ifndef NO_STACK_CHECKS
1420 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1421 u->rst.error = 1;
1422 goto error;
1423 }
1424#endif
1425 u->rst.ptr -= 1;
1426 }
1427 break;
1428 case 0x5a: /* MULr */
1429 __asm__("evaluxn_5a_MULr:");
1430 {
1431 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1432 u->rst.dat[u->rst.ptr - 2] = b * a;
1433#ifndef NO_STACK_CHECKS
1434 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1435 u->rst.error = 1;
1436 goto error;
1437 }
1438#endif
1439 u->rst.ptr -= 1;
1440 }
1441 break;
1442 case 0x5b: /* DIVr */
1443 __asm__("evaluxn_5b_DIVr:");
1444 {
1445 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1446 if(a == 0) {
1447 u->rst.error = 3;
1448#ifndef NO_STACK_CHECKS
1449 goto error;
1450#endif
1451 a = 1;
1452 }
1453 u->rst.dat[u->rst.ptr - 2] = b / a;
1454#ifndef NO_STACK_CHECKS
1455 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1456 u->rst.error = 1;
1457 goto error;
1458 }
1459#endif
1460 u->rst.ptr -= 1;
1461 }
1462 break;
1463 case 0x5c: /* ANDr */
1464 __asm__("evaluxn_5c_ANDr:");
1465 {
1466 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1467 u->rst.dat[u->rst.ptr - 2] = b & a;
1468#ifndef NO_STACK_CHECKS
1469 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1470 u->rst.error = 1;
1471 goto error;
1472 }
1473#endif
1474 u->rst.ptr -= 1;
1475 }
1476 break;
1477 case 0x5d: /* ORAr */
1478 __asm__("evaluxn_5d_ORAr:");
1479 {
1480 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1481 u->rst.dat[u->rst.ptr - 2] = b | a;
1482#ifndef NO_STACK_CHECKS
1483 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1484 u->rst.error = 1;
1485 goto error;
1486 }
1487#endif
1488 u->rst.ptr -= 1;
1489 }
1490 break;
1491 case 0x5e: /* EORr */
1492 __asm__("evaluxn_5e_EORr:");
1493 {
1494 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1495 u->rst.dat[u->rst.ptr - 2] = b ^ a;
1496#ifndef NO_STACK_CHECKS
1497 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1498 u->rst.error = 1;
1499 goto error;
1500 }
1501#endif
1502 u->rst.ptr -= 1;
1503 }
1504 break;
1505 case 0x5f: /* SFTr */
1506 __asm__("evaluxn_5f_SFTr:");
1507 {
1508 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1509 u->rst.dat[u->rst.ptr - 2] = b >> (a & 0x07) << ((a & 0x70) >> 4);
1510#ifndef NO_STACK_CHECKS
1511 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1512 u->rst.error = 1;
1513 goto error;
1514 }
1515#endif
1516 u->rst.ptr -= 1;
1517 }
1518 break;
1519 case 0x60: /* LIT2r */
1520 case 0xe0: /* LIT2kr */
1521 __asm__("evaluxn_60_LIT2r:");
1522 {
1523 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
1524 u->rst.dat[u->rst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++);
1525#ifndef NO_STACK_CHECKS
1526 if(__builtin_expect(u->rst.ptr > 253, 0)) {
1527 u->rst.error = 2;
1528 goto error;
1529 }
1530#endif
1531 u->rst.ptr += 2;
1532 }
1533 break;
1534 case 0x61: /* INC2r */
1535 __asm__("evaluxn_61_INC2r:");
1536 {
1537 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1538 u->rst.dat[u->rst.ptr - 2] = (a + 1) >> 8;
1539 u->rst.dat[u->rst.ptr - 1] = (a + 1) & 0xff;
1540#ifndef NO_STACK_CHECKS
1541 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1542 u->rst.error = 1;
1543 goto error;
1544 }
1545#endif
1546 }
1547 break;
1548 case 0x62: /* POP2r */
1549 __asm__("evaluxn_62_POP2r:");
1550 {
1551 (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1552#ifndef NO_STACK_CHECKS
1553 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1554 u->rst.error = 1;
1555 goto error;
1556 }
1557#endif
1558 u->rst.ptr -= 2;
1559 }
1560 break;
1561 case 0x66: /* DUP2r */
1562 __asm__("evaluxn_63_DUP2r:");
1563 {
1564 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1565 u->rst.dat[u->rst.ptr] = b;
1566 u->rst.dat[u->rst.ptr + 1] = a;
1567#ifndef NO_STACK_CHECKS
1568 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1569 u->rst.error = 1;
1570 goto error;
1571 }
1572 if(__builtin_expect(u->rst.ptr > 253, 0)) {
1573 u->rst.error = 2;
1574 goto error;
1575 }
1576#endif
1577 u->rst.ptr += 2;
1578 }
1579 break;
1580 case 0x63: /* NIP2r */
1581 __asm__("evaluxn_64_NIP2r:");
1582 {
1583 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1584 (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1585 u->rst.dat[u->rst.ptr - 4] = a >> 8;
1586 u->rst.dat[u->rst.ptr - 3] = a & 0xff;
1587#ifndef NO_STACK_CHECKS
1588 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1589 u->rst.error = 1;
1590 goto error;
1591 }
1592#endif
1593 u->rst.ptr -= 2;
1594 }
1595 break;
1596 case 0x64: /* SWP2r */
1597 __asm__("evaluxn_65_SWP2r:");
1598 {
1599 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
1600 u->rst.dat[u->rst.ptr - 4] = b;
1601 u->rst.dat[u->rst.ptr - 3] = a;
1602 u->rst.dat[u->rst.ptr - 2] = d;
1603 u->rst.dat[u->rst.ptr - 1] = c;
1604#ifndef NO_STACK_CHECKS
1605 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1606 u->rst.error = 1;
1607 goto error;
1608 }
1609#endif
1610 }
1611 break;
1612 case 0x67: /* OVR2r */
1613 __asm__("evaluxn_66_OVR2r:");
1614 {
1615 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
1616 u->rst.dat[u->rst.ptr] = d;
1617 u->rst.dat[u->rst.ptr + 1] = c;
1618#ifndef NO_STACK_CHECKS
1619 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1620 u->rst.error = 1;
1621 goto error;
1622 }
1623 if(__builtin_expect(u->rst.ptr > 253, 0)) {
1624 u->rst.error = 2;
1625 goto error;
1626 }
1627#endif
1628 u->rst.ptr += 2;
1629 }
1630 break;
1631 case 0x65: /* ROT2r */
1632 __asm__("evaluxn_67_ROT2r:");
1633 {
1634 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4], e = u->rst.dat[u->rst.ptr - 5], f = u->rst.dat[u->rst.ptr - 6];
1635 u->rst.dat[u->rst.ptr - 6] = d;
1636 u->rst.dat[u->rst.ptr - 5] = c;
1637 u->rst.dat[u->rst.ptr - 4] = b;
1638 u->rst.dat[u->rst.ptr - 3] = a;
1639 u->rst.dat[u->rst.ptr - 2] = f;
1640 u->rst.dat[u->rst.ptr - 1] = e;
1641#ifndef NO_STACK_CHECKS
1642 if(__builtin_expect(u->rst.ptr < 6, 0)) {
1643 u->rst.error = 1;
1644 goto error;
1645 }
1646#endif
1647 }
1648 break;
1649 case 0x68: /* EQU2r */
1650 __asm__("evaluxn_68_EQU2r:");
1651 {
1652 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1653 u->rst.dat[u->rst.ptr - 4] = b == a;
1654#ifndef NO_STACK_CHECKS
1655 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1656 u->rst.error = 1;
1657 goto error;
1658 }
1659#endif
1660 u->rst.ptr -= 3;
1661 }
1662 break;
1663 case 0x69: /* NEQ2r */
1664 __asm__("evaluxn_69_NEQ2r:");
1665 {
1666 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1667 u->rst.dat[u->rst.ptr - 4] = b != a;
1668#ifndef NO_STACK_CHECKS
1669 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1670 u->rst.error = 1;
1671 goto error;
1672 }
1673#endif
1674 u->rst.ptr -= 3;
1675 }
1676 break;
1677 case 0x6a: /* GTH2r */
1678 __asm__("evaluxn_6a_GTH2r:");
1679 {
1680 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1681 u->rst.dat[u->rst.ptr - 4] = b > a;
1682#ifndef NO_STACK_CHECKS
1683 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1684 u->rst.error = 1;
1685 goto error;
1686 }
1687#endif
1688 u->rst.ptr -= 3;
1689 }
1690 break;
1691 case 0x6b: /* LTH2r */
1692 __asm__("evaluxn_6b_LTH2r:");
1693 {
1694 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1695 u->rst.dat[u->rst.ptr - 4] = b < a;
1696#ifndef NO_STACK_CHECKS
1697 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1698 u->rst.error = 1;
1699 goto error;
1700 }
1701#endif
1702 u->rst.ptr -= 3;
1703 }
1704 break;
1705 case 0x6c: /* JMP2r */
1706 __asm__("evaluxn_6c_JMP2r:");
1707 {
1708 u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1709#ifndef NO_STACK_CHECKS
1710 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1711 u->rst.error = 1;
1712 goto error;
1713 }
1714#endif
1715 u->rst.ptr -= 2;
1716 }
1717 break;
1718 case 0x6d: /* JCN2r */
1719 __asm__("evaluxn_6d_JCN2r:");
1720 {
1721 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1722 if(u->rst.dat[u->rst.ptr - 3]) u->ram.ptr = a;
1723#ifndef NO_STACK_CHECKS
1724 if(__builtin_expect(u->rst.ptr < 3, 0)) {
1725 u->rst.error = 1;
1726 goto error;
1727 }
1728#endif
1729 u->rst.ptr -= 3;
1730 }
1731 break;
1732 case 0x6e: /* JSR2r */
1733 __asm__("evaluxn_6e_JSR2r:");
1734 {
1735 u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8;
1736 u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff;
1737 u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1738#ifndef NO_STACK_CHECKS
1739 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1740 u->rst.error = 1;
1741 goto error;
1742 }
1743#endif
1744 u->rst.ptr -= 2;
1745#ifndef NO_STACK_CHECKS
1746 if(__builtin_expect(u->wst.ptr > 253, 0)) {
1747 u->wst.error = 2;
1748 goto error;
1749 }
1750#endif
1751 u->wst.ptr += 2;
1752 }
1753 break;
1754 case 0x6f: /* STH2r */
1755 __asm__("evaluxn_6f_STH2r:");
1756 {
1757 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
1758 u->wst.dat[u->wst.ptr] = b;
1759 u->wst.dat[u->wst.ptr + 1] = a;
1760#ifndef NO_STACK_CHECKS
1761 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1762 u->rst.error = 1;
1763 goto error;
1764 }
1765#endif
1766 u->rst.ptr -= 2;
1767#ifndef NO_STACK_CHECKS
1768 if(__builtin_expect(u->wst.ptr > 253, 0)) {
1769 u->wst.error = 2;
1770 goto error;
1771 }
1772#endif
1773 u->wst.ptr += 2;
1774 }
1775 break;
1776 case 0x70: /* LDZ2r */
1777 __asm__("evaluxn_70_LDZ2r:");
1778 {
1779 u8 a = u->rst.dat[u->rst.ptr - 1];
1780 u->rst.dat[u->rst.ptr - 1] = mempeek8(u->ram.dat, a);
1781 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, a + 1);
1782#ifndef NO_STACK_CHECKS
1783 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1784 u->rst.error = 1;
1785 goto error;
1786 }
1787 if(__builtin_expect(u->rst.ptr > 254, 0)) {
1788 u->rst.error = 2;
1789 goto error;
1790 }
1791#endif
1792 u->rst.ptr += 1;
1793 }
1794 break;
1795 case 0x71: /* STZ2r */
1796 __asm__("evaluxn_71_STZ2r:");
1797 {
1798 u8 a = u->rst.dat[u->rst.ptr - 1];
1799 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
1800 mempoke16(u->ram.dat, a, b);
1801#ifndef NO_STACK_CHECKS
1802 if(__builtin_expect(u->rst.ptr < 3, 0)) {
1803 u->rst.error = 1;
1804 goto error;
1805 }
1806#endif
1807 u->rst.ptr -= 3;
1808 }
1809 break;
1810 case 0x72: /* LDR2r */
1811 __asm__("evaluxn_72_LDR2r:");
1812 {
1813 u8 a = u->rst.dat[u->rst.ptr - 1];
1814 u->rst.dat[u->rst.ptr - 1] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
1815 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a + 1);
1816#ifndef NO_STACK_CHECKS
1817 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1818 u->rst.error = 1;
1819 goto error;
1820 }
1821 if(__builtin_expect(u->rst.ptr > 254, 0)) {
1822 u->rst.error = 2;
1823 goto error;
1824 }
1825#endif
1826 u->rst.ptr += 1;
1827 }
1828 break;
1829 case 0x73: /* STR2r */
1830 __asm__("evaluxn_73_STR2r:");
1831 {
1832 u8 a = u->rst.dat[u->rst.ptr - 1];
1833 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
1834 mempoke16(u->ram.dat, u->ram.ptr + (s8)a, b);
1835#ifndef NO_STACK_CHECKS
1836 if(__builtin_expect(u->rst.ptr < 3, 0)) {
1837 u->rst.error = 1;
1838 goto error;
1839 }
1840#endif
1841 u->rst.ptr -= 3;
1842 }
1843 break;
1844 case 0x74: /* LDA2r */
1845 __asm__("evaluxn_74_LDA2r:");
1846 {
1847 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1848 u->rst.dat[u->rst.ptr - 2] = mempeek8(u->ram.dat, a);
1849 u->rst.dat[u->rst.ptr - 1] = mempeek8(u->ram.dat, a + 1);
1850#ifndef NO_STACK_CHECKS
1851 if(__builtin_expect(u->rst.ptr < 2, 0)) {
1852 u->rst.error = 1;
1853 goto error;
1854 }
1855#endif
1856 }
1857 break;
1858 case 0x75: /* STA2r */
1859 __asm__("evaluxn_75_STA2r:");
1860 {
1861 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1862 u16 b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1863 mempoke16(u->ram.dat, a, b);
1864#ifndef NO_STACK_CHECKS
1865 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1866 u->rst.error = 1;
1867 goto error;
1868 }
1869#endif
1870 u->rst.ptr -= 4;
1871 }
1872 break;
1873 case 0x76: /* DEI2r */
1874 __asm__("evaluxn_76_DEI2r:");
1875 {
1876 u8 a = u->rst.dat[u->rst.ptr - 1];
1877 u->rst.dat[u->rst.ptr - 1] = devpeek8(&u->dev[a >> 4], a);
1878 u->rst.dat[u->rst.ptr] = devpeek8(&u->dev[a >> 4], a + 1);
1879#ifndef NO_STACK_CHECKS
1880 if(__builtin_expect(u->rst.ptr < 1, 0)) {
1881 u->rst.error = 1;
1882 goto error;
1883 }
1884 if(__builtin_expect(u->rst.ptr > 254, 0)) {
1885 u->rst.error = 2;
1886 goto error;
1887 }
1888#endif
1889 u->rst.ptr += 1;
1890 }
1891 break;
1892 case 0x77: /* DEO2r */
1893 __asm__("evaluxn_77_DEO2r:");
1894 {
1895 u8 a = u->rst.dat[u->rst.ptr - 1];
1896 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
1897 devpoke16(&u->dev[a >> 4], a, b);
1898#ifndef NO_STACK_CHECKS
1899 if(__builtin_expect(u->rst.ptr < 3, 0)) {
1900 u->rst.error = 1;
1901 goto error;
1902 }
1903#endif
1904 u->rst.ptr -= 3;
1905 }
1906 break;
1907 case 0x78: /* ADD2r */
1908 __asm__("evaluxn_78_ADD2r:");
1909 {
1910 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1911 u->rst.dat[u->rst.ptr - 4] = (b + a) >> 8;
1912 u->rst.dat[u->rst.ptr - 3] = (b + a) & 0xff;
1913#ifndef NO_STACK_CHECKS
1914 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1915 u->rst.error = 1;
1916 goto error;
1917 }
1918#endif
1919 u->rst.ptr -= 2;
1920 }
1921 break;
1922 case 0x79: /* SUB2r */
1923 __asm__("evaluxn_79_SUB2r:");
1924 {
1925 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1926 u->rst.dat[u->rst.ptr - 4] = (b - a) >> 8;
1927 u->rst.dat[u->rst.ptr - 3] = (b - a) & 0xff;
1928#ifndef NO_STACK_CHECKS
1929 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1930 u->rst.error = 1;
1931 goto error;
1932 }
1933#endif
1934 u->rst.ptr -= 2;
1935 }
1936 break;
1937 case 0x7a: /* MUL2r */
1938 __asm__("evaluxn_7a_MUL2r:");
1939 {
1940 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1941 u->rst.dat[u->rst.ptr - 4] = (b * a) >> 8;
1942 u->rst.dat[u->rst.ptr - 3] = (b * a) & 0xff;
1943#ifndef NO_STACK_CHECKS
1944 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1945 u->rst.error = 1;
1946 goto error;
1947 }
1948#endif
1949 u->rst.ptr -= 2;
1950 }
1951 break;
1952 case 0x7b: /* DIV2r */
1953 __asm__("evaluxn_7b_DIV2r:");
1954 {
1955 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
1956 if(a == 0) {
1957 u->rst.error = 3;
1958#ifndef NO_STACK_CHECKS
1959 goto error;
1960#endif
1961 a = 1;
1962 }
1963 u->rst.dat[u->rst.ptr - 4] = (b / a) >> 8;
1964 u->rst.dat[u->rst.ptr - 3] = (b / a) & 0xff;
1965#ifndef NO_STACK_CHECKS
1966 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1967 u->rst.error = 1;
1968 goto error;
1969 }
1970#endif
1971 u->rst.ptr -= 2;
1972 }
1973 break;
1974 case 0x7c: /* AND2r */
1975 __asm__("evaluxn_7c_AND2r:");
1976 {
1977 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
1978 u->rst.dat[u->rst.ptr - 4] = d & b;
1979 u->rst.dat[u->rst.ptr - 3] = c & a;
1980#ifndef NO_STACK_CHECKS
1981 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1982 u->rst.error = 1;
1983 goto error;
1984 }
1985#endif
1986 u->rst.ptr -= 2;
1987 }
1988 break;
1989 case 0x7d: /* ORA2r */
1990 __asm__("evaluxn_7d_ORA2r:");
1991 {
1992 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
1993 u->rst.dat[u->rst.ptr - 4] = d | b;
1994 u->rst.dat[u->rst.ptr - 3] = c | a;
1995#ifndef NO_STACK_CHECKS
1996 if(__builtin_expect(u->rst.ptr < 4, 0)) {
1997 u->rst.error = 1;
1998 goto error;
1999 }
2000#endif
2001 u->rst.ptr -= 2;
2002 }
2003 break;
2004 case 0x7e: /* EOR2r */
2005 __asm__("evaluxn_7e_EOR2r:");
2006 {
2007 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
2008 u->rst.dat[u->rst.ptr - 4] = d ^ b;
2009 u->rst.dat[u->rst.ptr - 3] = c ^ a;
2010#ifndef NO_STACK_CHECKS
2011 if(__builtin_expect(u->rst.ptr < 4, 0)) {
2012 u->rst.error = 1;
2013 goto error;
2014 }
2015#endif
2016 u->rst.ptr -= 2;
2017 }
2018 break;
2019 case 0x7f: /* SFT2r */
2020 __asm__("evaluxn_7f_SFT2r:");
2021 {
2022 u8 a = u->rst.dat[u->rst.ptr - 1];
2023 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
2024 u->rst.dat[u->rst.ptr - 3] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8;
2025 u->rst.dat[u->rst.ptr - 2] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff;
2026#ifndef NO_STACK_CHECKS
2027 if(__builtin_expect(u->rst.ptr < 3, 0)) {
2028 u->rst.error = 1;
2029 goto error;
2030 }
2031#endif
2032 u->rst.ptr -= 1;
2033 }
2034 break;
2035 case 0x81: /* INCk */
2036 __asm__("evaluxn_81_INCk:");
2037 {
2038 u8 a = u->wst.dat[u->wst.ptr - 1];
2039 u->wst.dat[u->wst.ptr] = a + 1;
2040#ifndef NO_STACK_CHECKS
2041 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2042 u->wst.error = 1;
2043 goto error;
2044 }
2045 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2046 u->wst.error = 2;
2047 goto error;
2048 }
2049#endif
2050 u->wst.ptr += 1;
2051 }
2052 break;
2053 case 0x82: /* POPk */
2054 __asm__("evaluxn_82_POPk:");
2055 {
2056 u->wst.dat[u->wst.ptr - 1];
2057#ifndef NO_STACK_CHECKS
2058 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2059 u->wst.error = 1;
2060 goto error;
2061 }
2062#endif
2063 }
2064 break;
2065 case 0x86: /* DUPk */
2066 __asm__("evaluxn_83_DUPk:");
2067 {
2068 u8 a = u->wst.dat[u->wst.ptr - 1];
2069 u->wst.dat[u->wst.ptr] = a;
2070 u->wst.dat[u->wst.ptr + 1] = a;
2071#ifndef NO_STACK_CHECKS
2072 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2073 u->wst.error = 1;
2074 goto error;
2075 }
2076 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2077 u->wst.error = 2;
2078 goto error;
2079 }
2080#endif
2081 u->wst.ptr += 2;
2082 }
2083 break;
2084 case 0x83: /* NIPk */
2085 __asm__("evaluxn_84_NIPk:");
2086 {
2087 u8 a = u->wst.dat[u->wst.ptr - 1];
2088 u->wst.dat[u->wst.ptr - 2];
2089 u->wst.dat[u->wst.ptr] = a;
2090#ifndef NO_STACK_CHECKS
2091 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2092 u->wst.error = 1;
2093 goto error;
2094 }
2095 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2096 u->wst.error = 2;
2097 goto error;
2098 }
2099#endif
2100 u->wst.ptr += 1;
2101 }
2102 break;
2103 case 0x84: /* SWPk */
2104 __asm__("evaluxn_85_SWPk:");
2105 {
2106 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2107 u->wst.dat[u->wst.ptr] = a;
2108 u->wst.dat[u->wst.ptr + 1] = b;
2109#ifndef NO_STACK_CHECKS
2110 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2111 u->wst.error = 1;
2112 goto error;
2113 }
2114 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2115 u->wst.error = 2;
2116 goto error;
2117 }
2118#endif
2119 u->wst.ptr += 2;
2120 }
2121 break;
2122 case 0x87: /* OVRk */
2123 __asm__("evaluxn_86_OVRk:");
2124 {
2125 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2126 u->wst.dat[u->wst.ptr] = b;
2127 u->wst.dat[u->wst.ptr + 1] = a;
2128 u->wst.dat[u->wst.ptr + 2] = b;
2129#ifndef NO_STACK_CHECKS
2130 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2131 u->wst.error = 1;
2132 goto error;
2133 }
2134 if(__builtin_expect(u->wst.ptr > 252, 0)) {
2135 u->wst.error = 2;
2136 goto error;
2137 }
2138#endif
2139 u->wst.ptr += 3;
2140 }
2141 break;
2142 case 0x85: /* ROTk */
2143 __asm__("evaluxn_87_ROTk:");
2144 {
2145 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3];
2146 u->wst.dat[u->wst.ptr] = b;
2147 u->wst.dat[u->wst.ptr + 1] = a;
2148 u->wst.dat[u->wst.ptr + 2] = c;
2149#ifndef NO_STACK_CHECKS
2150 if(__builtin_expect(u->wst.ptr < 3, 0)) {
2151 u->wst.error = 1;
2152 goto error;
2153 }
2154 if(__builtin_expect(u->wst.ptr > 252, 0)) {
2155 u->wst.error = 2;
2156 goto error;
2157 }
2158#endif
2159 u->wst.ptr += 3;
2160 }
2161 break;
2162 case 0x88: /* EQUk */
2163 __asm__("evaluxn_88_EQUk:");
2164 {
2165 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2166 u->wst.dat[u->wst.ptr] = b == a;
2167#ifndef NO_STACK_CHECKS
2168 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2169 u->wst.error = 1;
2170 goto error;
2171 }
2172 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2173 u->wst.error = 2;
2174 goto error;
2175 }
2176#endif
2177 u->wst.ptr += 1;
2178 }
2179 break;
2180 case 0x89: /* NEQk */
2181 __asm__("evaluxn_89_NEQk:");
2182 {
2183 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2184 u->wst.dat[u->wst.ptr] = b != a;
2185#ifndef NO_STACK_CHECKS
2186 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2187 u->wst.error = 1;
2188 goto error;
2189 }
2190 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2191 u->wst.error = 2;
2192 goto error;
2193 }
2194#endif
2195 u->wst.ptr += 1;
2196 }
2197 break;
2198 case 0x8a: /* GTHk */
2199 __asm__("evaluxn_8a_GTHk:");
2200 {
2201 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2202 u->wst.dat[u->wst.ptr] = b > a;
2203#ifndef NO_STACK_CHECKS
2204 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2205 u->wst.error = 1;
2206 goto error;
2207 }
2208 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2209 u->wst.error = 2;
2210 goto error;
2211 }
2212#endif
2213 u->wst.ptr += 1;
2214 }
2215 break;
2216 case 0x8b: /* LTHk */
2217 __asm__("evaluxn_8b_LTHk:");
2218 {
2219 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2220 u->wst.dat[u->wst.ptr] = b < a;
2221#ifndef NO_STACK_CHECKS
2222 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2223 u->wst.error = 1;
2224 goto error;
2225 }
2226 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2227 u->wst.error = 2;
2228 goto error;
2229 }
2230#endif
2231 u->wst.ptr += 1;
2232 }
2233 break;
2234 case 0x8c: /* JMPk */
2235 __asm__("evaluxn_8c_JMPk:");
2236 {
2237 u8 a = u->wst.dat[u->wst.ptr - 1];
2238 u->ram.ptr += (s8)a;
2239#ifndef NO_STACK_CHECKS
2240 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2241 u->wst.error = 1;
2242 goto error;
2243 }
2244#endif
2245 }
2246 break;
2247 case 0x8d: /* JCNk */
2248 __asm__("evaluxn_8d_JCNk:");
2249 {
2250 u8 a = u->wst.dat[u->wst.ptr - 1];
2251 if(u->wst.dat[u->wst.ptr - 2]) u->ram.ptr += (s8)a;
2252#ifndef NO_STACK_CHECKS
2253 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2254 u->wst.error = 1;
2255 goto error;
2256 }
2257#endif
2258 }
2259 break;
2260 case 0x8e: /* JSRk */
2261 __asm__("evaluxn_8e_JSRk:");
2262 {
2263 u8 a = u->wst.dat[u->wst.ptr - 1];
2264 u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8;
2265 u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff;
2266 u->ram.ptr += (s8)a;
2267#ifndef NO_STACK_CHECKS
2268 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2269 u->wst.error = 1;
2270 goto error;
2271 }
2272 if(__builtin_expect(u->rst.ptr > 253, 0)) {
2273 u->rst.error = 2;
2274 goto error;
2275 }
2276#endif
2277 u->rst.ptr += 2;
2278 }
2279 break;
2280 case 0x8f: /* STHk */
2281 __asm__("evaluxn_8f_STHk:");
2282 {
2283 u8 a = u->wst.dat[u->wst.ptr - 1];
2284 u->rst.dat[u->rst.ptr] = a;
2285#ifndef NO_STACK_CHECKS
2286 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2287 u->wst.error = 1;
2288 goto error;
2289 }
2290 if(__builtin_expect(u->rst.ptr > 254, 0)) {
2291 u->rst.error = 2;
2292 goto error;
2293 }
2294#endif
2295 u->rst.ptr += 1;
2296 }
2297 break;
2298 case 0x90: /* LDZk */
2299 __asm__("evaluxn_90_LDZk:");
2300 {
2301 u8 a = u->wst.dat[u->wst.ptr - 1];
2302 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, a);
2303#ifndef NO_STACK_CHECKS
2304 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2305 u->wst.error = 1;
2306 goto error;
2307 }
2308 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2309 u->wst.error = 2;
2310 goto error;
2311 }
2312#endif
2313 u->wst.ptr += 1;
2314 }
2315 break;
2316 case 0x91: /* STZk */
2317 __asm__("evaluxn_91_STZk:");
2318 {
2319 u8 a = u->wst.dat[u->wst.ptr - 1];
2320 u8 b = u->wst.dat[u->wst.ptr - 2];
2321 mempoke8(u->ram.dat, a, b);
2322#ifndef NO_STACK_CHECKS
2323 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2324 u->wst.error = 1;
2325 goto error;
2326 }
2327#endif
2328 }
2329 break;
2330 case 0x92: /* LDRk */
2331 __asm__("evaluxn_92_LDRk:");
2332 {
2333 u8 a = u->wst.dat[u->wst.ptr - 1];
2334 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
2335#ifndef NO_STACK_CHECKS
2336 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2337 u->wst.error = 1;
2338 goto error;
2339 }
2340 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2341 u->wst.error = 2;
2342 goto error;
2343 }
2344#endif
2345 u->wst.ptr += 1;
2346 }
2347 break;
2348 case 0x93: /* STRk */
2349 __asm__("evaluxn_93_STRk:");
2350 {
2351 u8 a = u->wst.dat[u->wst.ptr - 1];
2352 u8 b = u->wst.dat[u->wst.ptr - 2];
2353 mempoke8(u->ram.dat, u->ram.ptr + (s8)a, b);
2354#ifndef NO_STACK_CHECKS
2355 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2356 u->wst.error = 1;
2357 goto error;
2358 }
2359#endif
2360 }
2361 break;
2362 case 0x94: /* LDAk */
2363 __asm__("evaluxn_94_LDAk:");
2364 {
2365 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2366 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, a);
2367#ifndef NO_STACK_CHECKS
2368 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2369 u->wst.error = 1;
2370 goto error;
2371 }
2372 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2373 u->wst.error = 2;
2374 goto error;
2375 }
2376#endif
2377 u->wst.ptr += 1;
2378 }
2379 break;
2380 case 0x95: /* STAk */
2381 __asm__("evaluxn_95_STAk:");
2382 {
2383 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2384 u8 b = u->wst.dat[u->wst.ptr - 3];
2385 mempoke8(u->ram.dat, a, b);
2386#ifndef NO_STACK_CHECKS
2387 if(__builtin_expect(u->wst.ptr < 3, 0)) {
2388 u->wst.error = 1;
2389 goto error;
2390 }
2391#endif
2392 }
2393 break;
2394 case 0x96: /* DEIk */
2395 __asm__("evaluxn_96_DEIk:");
2396 {
2397 u8 a = u->wst.dat[u->wst.ptr - 1];
2398 u->wst.dat[u->wst.ptr] = devpeek8(&u->dev[a >> 4], a);
2399#ifndef NO_STACK_CHECKS
2400 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2401 u->wst.error = 1;
2402 goto error;
2403 }
2404 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2405 u->wst.error = 2;
2406 goto error;
2407 }
2408#endif
2409 u->wst.ptr += 1;
2410 }
2411 break;
2412 case 0x97: /* DEOk */
2413 __asm__("evaluxn_97_DEOk:");
2414 {
2415 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2416 devpoke8(&u->dev[a >> 4], a, b);
2417#ifndef NO_STACK_CHECKS
2418 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2419 u->wst.error = 1;
2420 goto error;
2421 }
2422#endif
2423 }
2424 break;
2425 case 0x98: /* ADDk */
2426 __asm__("evaluxn_98_ADDk:");
2427 {
2428 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2429 u->wst.dat[u->wst.ptr] = b + a;
2430#ifndef NO_STACK_CHECKS
2431 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2432 u->wst.error = 1;
2433 goto error;
2434 }
2435 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2436 u->wst.error = 2;
2437 goto error;
2438 }
2439#endif
2440 u->wst.ptr += 1;
2441 }
2442 break;
2443 case 0x99: /* SUBk */
2444 __asm__("evaluxn_99_SUBk:");
2445 {
2446 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2447 u->wst.dat[u->wst.ptr] = b - a;
2448#ifndef NO_STACK_CHECKS
2449 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2450 u->wst.error = 1;
2451 goto error;
2452 }
2453 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2454 u->wst.error = 2;
2455 goto error;
2456 }
2457#endif
2458 u->wst.ptr += 1;
2459 }
2460 break;
2461 case 0x9a: /* MULk */
2462 __asm__("evaluxn_9a_MULk:");
2463 {
2464 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2465 u->wst.dat[u->wst.ptr] = b * a;
2466#ifndef NO_STACK_CHECKS
2467 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2468 u->wst.error = 1;
2469 goto error;
2470 }
2471 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2472 u->wst.error = 2;
2473 goto error;
2474 }
2475#endif
2476 u->wst.ptr += 1;
2477 }
2478 break;
2479 case 0x9b: /* DIVk */
2480 __asm__("evaluxn_9b_DIVk:");
2481 {
2482 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2483 if(a == 0) {
2484 u->wst.error = 3;
2485#ifndef NO_STACK_CHECKS
2486 goto error;
2487#endif
2488 a = 1;
2489 }
2490 u->wst.dat[u->wst.ptr] = b / a;
2491#ifndef NO_STACK_CHECKS
2492 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2493 u->wst.error = 1;
2494 goto error;
2495 }
2496 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2497 u->wst.error = 2;
2498 goto error;
2499 }
2500#endif
2501 u->wst.ptr += 1;
2502 }
2503 break;
2504 case 0x9c: /* ANDk */
2505 __asm__("evaluxn_9c_ANDk:");
2506 {
2507 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2508 u->wst.dat[u->wst.ptr] = b & a;
2509#ifndef NO_STACK_CHECKS
2510 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2511 u->wst.error = 1;
2512 goto error;
2513 }
2514 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2515 u->wst.error = 2;
2516 goto error;
2517 }
2518#endif
2519 u->wst.ptr += 1;
2520 }
2521 break;
2522 case 0x9d: /* ORAk */
2523 __asm__("evaluxn_9d_ORAk:");
2524 {
2525 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2526 u->wst.dat[u->wst.ptr] = b | a;
2527#ifndef NO_STACK_CHECKS
2528 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2529 u->wst.error = 1;
2530 goto error;
2531 }
2532 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2533 u->wst.error = 2;
2534 goto error;
2535 }
2536#endif
2537 u->wst.ptr += 1;
2538 }
2539 break;
2540 case 0x9e: /* EORk */
2541 __asm__("evaluxn_9e_EORk:");
2542 {
2543 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2544 u->wst.dat[u->wst.ptr] = b ^ a;
2545#ifndef NO_STACK_CHECKS
2546 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2547 u->wst.error = 1;
2548 goto error;
2549 }
2550 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2551 u->wst.error = 2;
2552 goto error;
2553 }
2554#endif
2555 u->wst.ptr += 1;
2556 }
2557 break;
2558 case 0x9f: /* SFTk */
2559 __asm__("evaluxn_9f_SFTk:");
2560 {
2561 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2562 u->wst.dat[u->wst.ptr] = b >> (a & 0x07) << ((a & 0x70) >> 4);
2563#ifndef NO_STACK_CHECKS
2564 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2565 u->wst.error = 1;
2566 goto error;
2567 }
2568 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2569 u->wst.error = 2;
2570 goto error;
2571 }
2572#endif
2573 u->wst.ptr += 1;
2574 }
2575 break;
2576 case 0xa1: /* INC2k */
2577 __asm__("evaluxn_a1_INC2k:");
2578 {
2579 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2580 u->wst.dat[u->wst.ptr] = (a + 1) >> 8;
2581 u->wst.dat[u->wst.ptr + 1] = (a + 1) & 0xff;
2582#ifndef NO_STACK_CHECKS
2583 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2584 u->wst.error = 1;
2585 goto error;
2586 }
2587 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2588 u->wst.error = 2;
2589 goto error;
2590 }
2591#endif
2592 u->wst.ptr += 2;
2593 }
2594 break;
2595 case 0xa2: /* POP2k */
2596 __asm__("evaluxn_a2_POP2k:");
2597 {
2598 (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2599#ifndef NO_STACK_CHECKS
2600 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2601 u->wst.error = 1;
2602 goto error;
2603 }
2604#endif
2605 }
2606 break;
2607 case 0xa6: /* DUP2k */
2608 __asm__("evaluxn_a3_DUP2k:");
2609 {
2610 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2611 u->wst.dat[u->wst.ptr] = b;
2612 u->wst.dat[u->wst.ptr + 1] = a;
2613 u->wst.dat[u->wst.ptr + 2] = b;
2614 u->wst.dat[u->wst.ptr + 3] = a;
2615#ifndef NO_STACK_CHECKS
2616 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2617 u->wst.error = 1;
2618 goto error;
2619 }
2620 if(__builtin_expect(u->wst.ptr > 251, 0)) {
2621 u->wst.error = 2;
2622 goto error;
2623 }
2624#endif
2625 u->wst.ptr += 4;
2626 }
2627 break;
2628 case 0xa3: /* NIP2k */
2629 __asm__("evaluxn_a4_NIP2k:");
2630 {
2631 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2632 (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
2633 u->wst.dat[u->wst.ptr] = a >> 8;
2634 u->wst.dat[u->wst.ptr + 1] = a & 0xff;
2635#ifndef NO_STACK_CHECKS
2636 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2637 u->wst.error = 1;
2638 goto error;
2639 }
2640 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2641 u->wst.error = 2;
2642 goto error;
2643 }
2644#endif
2645 u->wst.ptr += 2;
2646 }
2647 break;
2648 case 0xa4: /* SWP2k */
2649 __asm__("evaluxn_a5_SWP2k:");
2650 {
2651 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
2652 u->wst.dat[u->wst.ptr] = b;
2653 u->wst.dat[u->wst.ptr + 1] = a;
2654 u->wst.dat[u->wst.ptr + 2] = d;
2655 u->wst.dat[u->wst.ptr + 3] = c;
2656#ifndef NO_STACK_CHECKS
2657 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2658 u->wst.error = 1;
2659 goto error;
2660 }
2661 if(__builtin_expect(u->wst.ptr > 251, 0)) {
2662 u->wst.error = 2;
2663 goto error;
2664 }
2665#endif
2666 u->wst.ptr += 4;
2667 }
2668 break;
2669 case 0xa7: /* OVR2k */
2670 __asm__("evaluxn_a6_OVR2k:");
2671 {
2672 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
2673 u->wst.dat[u->wst.ptr] = d;
2674 u->wst.dat[u->wst.ptr + 1] = c;
2675 u->wst.dat[u->wst.ptr + 2] = b;
2676 u->wst.dat[u->wst.ptr + 3] = a;
2677 u->wst.dat[u->wst.ptr + 4] = d;
2678 u->wst.dat[u->wst.ptr + 5] = c;
2679#ifndef NO_STACK_CHECKS
2680 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2681 u->wst.error = 1;
2682 goto error;
2683 }
2684 if(__builtin_expect(u->wst.ptr > 249, 0)) {
2685 u->wst.error = 2;
2686 goto error;
2687 }
2688#endif
2689 u->wst.ptr += 6;
2690 }
2691 break;
2692 case 0xa5: /* ROT2k */
2693 __asm__("evaluxn_a7_ROT2k:");
2694 {
2695 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4], e = u->wst.dat[u->wst.ptr - 5], f = u->wst.dat[u->wst.ptr - 6];
2696 u->wst.dat[u->wst.ptr] = d;
2697 u->wst.dat[u->wst.ptr + 1] = c;
2698 u->wst.dat[u->wst.ptr + 2] = b;
2699 u->wst.dat[u->wst.ptr + 3] = a;
2700 u->wst.dat[u->wst.ptr + 4] = f;
2701 u->wst.dat[u->wst.ptr + 5] = e;
2702#ifndef NO_STACK_CHECKS
2703 if(__builtin_expect(u->wst.ptr < 6, 0)) {
2704 u->wst.error = 1;
2705 goto error;
2706 }
2707 if(__builtin_expect(u->wst.ptr > 249, 0)) {
2708 u->wst.error = 2;
2709 goto error;
2710 }
2711#endif
2712 u->wst.ptr += 6;
2713 }
2714 break;
2715 case 0xa8: /* EQU2k */
2716 __asm__("evaluxn_a8_EQU2k:");
2717 {
2718 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
2719 u->wst.dat[u->wst.ptr] = b == a;
2720#ifndef NO_STACK_CHECKS
2721 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2722 u->wst.error = 1;
2723 goto error;
2724 }
2725 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2726 u->wst.error = 2;
2727 goto error;
2728 }
2729#endif
2730 u->wst.ptr += 1;
2731 }
2732 break;
2733 case 0xa9: /* NEQ2k */
2734 __asm__("evaluxn_a9_NEQ2k:");
2735 {
2736 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
2737 u->wst.dat[u->wst.ptr] = b != a;
2738#ifndef NO_STACK_CHECKS
2739 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2740 u->wst.error = 1;
2741 goto error;
2742 }
2743 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2744 u->wst.error = 2;
2745 goto error;
2746 }
2747#endif
2748 u->wst.ptr += 1;
2749 }
2750 break;
2751 case 0xaa: /* GTH2k */
2752 __asm__("evaluxn_aa_GTH2k:");
2753 {
2754 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
2755 u->wst.dat[u->wst.ptr] = b > a;
2756#ifndef NO_STACK_CHECKS
2757 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2758 u->wst.error = 1;
2759 goto error;
2760 }
2761 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2762 u->wst.error = 2;
2763 goto error;
2764 }
2765#endif
2766 u->wst.ptr += 1;
2767 }
2768 break;
2769 case 0xab: /* LTH2k */
2770 __asm__("evaluxn_ab_LTH2k:");
2771 {
2772 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
2773 u->wst.dat[u->wst.ptr] = b < a;
2774#ifndef NO_STACK_CHECKS
2775 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2776 u->wst.error = 1;
2777 goto error;
2778 }
2779 if(__builtin_expect(u->wst.ptr > 254, 0)) {
2780 u->wst.error = 2;
2781 goto error;
2782 }
2783#endif
2784 u->wst.ptr += 1;
2785 }
2786 break;
2787 case 0xac: /* JMP2k */
2788 __asm__("evaluxn_ac_JMP2k:");
2789 {
2790 u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2791#ifndef NO_STACK_CHECKS
2792 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2793 u->wst.error = 1;
2794 goto error;
2795 }
2796#endif
2797 }
2798 break;
2799 case 0xad: /* JCN2k */
2800 __asm__("evaluxn_ad_JCN2k:");
2801 {
2802 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2803 if(u->wst.dat[u->wst.ptr - 3]) u->ram.ptr = a;
2804#ifndef NO_STACK_CHECKS
2805 if(__builtin_expect(u->wst.ptr < 3, 0)) {
2806 u->wst.error = 1;
2807 goto error;
2808 }
2809#endif
2810 }
2811 break;
2812 case 0xae: /* JSR2k */
2813 __asm__("evaluxn_ae_JSR2k:");
2814 {
2815 u->rst.dat[u->rst.ptr] = u->ram.ptr >> 8;
2816 u->rst.dat[u->rst.ptr + 1] = u->ram.ptr & 0xff;
2817 u->ram.ptr = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2818#ifndef NO_STACK_CHECKS
2819 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2820 u->wst.error = 1;
2821 goto error;
2822 }
2823 if(__builtin_expect(u->rst.ptr > 253, 0)) {
2824 u->rst.error = 2;
2825 goto error;
2826 }
2827#endif
2828 u->rst.ptr += 2;
2829 }
2830 break;
2831 case 0xaf: /* STH2k */
2832 __asm__("evaluxn_af_STH2k:");
2833 {
2834 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
2835 u->rst.dat[u->rst.ptr] = b;
2836 u->rst.dat[u->rst.ptr + 1] = a;
2837#ifndef NO_STACK_CHECKS
2838 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2839 u->wst.error = 1;
2840 goto error;
2841 }
2842 if(__builtin_expect(u->rst.ptr > 253, 0)) {
2843 u->rst.error = 2;
2844 goto error;
2845 }
2846#endif
2847 u->rst.ptr += 2;
2848 }
2849 break;
2850 case 0xb0: /* LDZ2k */
2851 __asm__("evaluxn_b0_LDZ2k:");
2852 {
2853 u8 a = u->wst.dat[u->wst.ptr - 1];
2854 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, a);
2855 u->wst.dat[u->wst.ptr + 1] = mempeek8(u->ram.dat, a + 1);
2856#ifndef NO_STACK_CHECKS
2857 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2858 u->wst.error = 1;
2859 goto error;
2860 }
2861 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2862 u->wst.error = 2;
2863 goto error;
2864 }
2865#endif
2866 u->wst.ptr += 2;
2867 }
2868 break;
2869 case 0xb1: /* STZ2k */
2870 __asm__("evaluxn_b1_STZ2k:");
2871 {
2872 u8 a = u->wst.dat[u->wst.ptr - 1];
2873 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
2874 mempoke16(u->ram.dat, a, b);
2875#ifndef NO_STACK_CHECKS
2876 if(__builtin_expect(u->wst.ptr < 3, 0)) {
2877 u->wst.error = 1;
2878 goto error;
2879 }
2880#endif
2881 }
2882 break;
2883 case 0xb2: /* LDR2k */
2884 __asm__("evaluxn_b2_LDR2k:");
2885 {
2886 u8 a = u->wst.dat[u->wst.ptr - 1];
2887 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
2888 u->wst.dat[u->wst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a + 1);
2889#ifndef NO_STACK_CHECKS
2890 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2891 u->wst.error = 1;
2892 goto error;
2893 }
2894 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2895 u->wst.error = 2;
2896 goto error;
2897 }
2898#endif
2899 u->wst.ptr += 2;
2900 }
2901 break;
2902 case 0xb3: /* STR2k */
2903 __asm__("evaluxn_b3_STR2k:");
2904 {
2905 u8 a = u->wst.dat[u->wst.ptr - 1];
2906 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
2907 mempoke16(u->ram.dat, u->ram.ptr + (s8)a, b);
2908#ifndef NO_STACK_CHECKS
2909 if(__builtin_expect(u->wst.ptr < 3, 0)) {
2910 u->wst.error = 1;
2911 goto error;
2912 }
2913#endif
2914 }
2915 break;
2916 case 0xb4: /* LDA2k */
2917 __asm__("evaluxn_b4_LDA2k:");
2918 {
2919 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2920 u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, a);
2921 u->wst.dat[u->wst.ptr + 1] = mempeek8(u->ram.dat, a + 1);
2922#ifndef NO_STACK_CHECKS
2923 if(__builtin_expect(u->wst.ptr < 2, 0)) {
2924 u->wst.error = 1;
2925 goto error;
2926 }
2927 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2928 u->wst.error = 2;
2929 goto error;
2930 }
2931#endif
2932 u->wst.ptr += 2;
2933 }
2934 break;
2935 case 0xb5: /* STA2k */
2936 __asm__("evaluxn_b5_STA2k:");
2937 {
2938 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2939 u16 b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
2940 mempoke16(u->ram.dat, a, b);
2941#ifndef NO_STACK_CHECKS
2942 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2943 u->wst.error = 1;
2944 goto error;
2945 }
2946#endif
2947 }
2948 break;
2949 case 0xb6: /* DEI2k */
2950 __asm__("evaluxn_b6_DEI2k:");
2951 {
2952 u8 a = u->wst.dat[u->wst.ptr - 1];
2953 u->wst.dat[u->wst.ptr] = devpeek8(&u->dev[a >> 4], a);
2954 u->wst.dat[u->wst.ptr + 1] = devpeek8(&u->dev[a >> 4], a + 1);
2955#ifndef NO_STACK_CHECKS
2956 if(__builtin_expect(u->wst.ptr < 1, 0)) {
2957 u->wst.error = 1;
2958 goto error;
2959 }
2960 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2961 u->wst.error = 2;
2962 goto error;
2963 }
2964#endif
2965 u->wst.ptr += 2;
2966 }
2967 break;
2968 case 0xb7: /* DEO2k */
2969 __asm__("evaluxn_b7_DEO2k:");
2970 {
2971 u8 a = u->wst.dat[u->wst.ptr - 1];
2972 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
2973 devpoke16(&u->dev[a >> 4], a, b);
2974#ifndef NO_STACK_CHECKS
2975 if(__builtin_expect(u->wst.ptr < 3, 0)) {
2976 u->wst.error = 1;
2977 goto error;
2978 }
2979#endif
2980 }
2981 break;
2982 case 0xb8: /* ADD2k */
2983 __asm__("evaluxn_b8_ADD2k:");
2984 {
2985 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
2986 u->wst.dat[u->wst.ptr] = (b + a) >> 8;
2987 u->wst.dat[u->wst.ptr + 1] = (b + a) & 0xff;
2988#ifndef NO_STACK_CHECKS
2989 if(__builtin_expect(u->wst.ptr < 4, 0)) {
2990 u->wst.error = 1;
2991 goto error;
2992 }
2993 if(__builtin_expect(u->wst.ptr > 253, 0)) {
2994 u->wst.error = 2;
2995 goto error;
2996 }
2997#endif
2998 u->wst.ptr += 2;
2999 }
3000 break;
3001 case 0xb9: /* SUB2k */
3002 __asm__("evaluxn_b9_SUB2k:");
3003 {
3004 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
3005 u->wst.dat[u->wst.ptr] = (b - a) >> 8;
3006 u->wst.dat[u->wst.ptr + 1] = (b - a) & 0xff;
3007#ifndef NO_STACK_CHECKS
3008 if(__builtin_expect(u->wst.ptr < 4, 0)) {
3009 u->wst.error = 1;
3010 goto error;
3011 }
3012 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3013 u->wst.error = 2;
3014 goto error;
3015 }
3016#endif
3017 u->wst.ptr += 2;
3018 }
3019 break;
3020 case 0xba: /* MUL2k */
3021 __asm__("evaluxn_ba_MUL2k:");
3022 {
3023 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
3024 u->wst.dat[u->wst.ptr] = (b * a) >> 8;
3025 u->wst.dat[u->wst.ptr + 1] = (b * a) & 0xff;
3026#ifndef NO_STACK_CHECKS
3027 if(__builtin_expect(u->wst.ptr < 4, 0)) {
3028 u->wst.error = 1;
3029 goto error;
3030 }
3031 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3032 u->wst.error = 2;
3033 goto error;
3034 }
3035#endif
3036 u->wst.ptr += 2;
3037 }
3038 break;
3039 case 0xbb: /* DIV2k */
3040 __asm__("evaluxn_bb_DIV2k:");
3041 {
3042 u16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8)), b = (u->wst.dat[u->wst.ptr - 3] | (u->wst.dat[u->wst.ptr - 4] << 8));
3043 if(a == 0) {
3044 u->wst.error = 3;
3045#ifndef NO_STACK_CHECKS
3046 goto error;
3047#endif
3048 a = 1;
3049 }
3050 u->wst.dat[u->wst.ptr] = (b / a) >> 8;
3051 u->wst.dat[u->wst.ptr + 1] = (b / a) & 0xff;
3052#ifndef NO_STACK_CHECKS
3053 if(__builtin_expect(u->wst.ptr < 4, 0)) {
3054 u->wst.error = 1;
3055 goto error;
3056 }
3057 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3058 u->wst.error = 2;
3059 goto error;
3060 }
3061#endif
3062 u->wst.ptr += 2;
3063 }
3064 break;
3065 case 0xbc: /* AND2k */
3066 __asm__("evaluxn_bc_AND2k:");
3067 {
3068 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
3069 u->wst.dat[u->wst.ptr] = d & b;
3070 u->wst.dat[u->wst.ptr + 1] = c & a;
3071#ifndef NO_STACK_CHECKS
3072 if(__builtin_expect(u->wst.ptr < 4, 0)) {
3073 u->wst.error = 1;
3074 goto error;
3075 }
3076 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3077 u->wst.error = 2;
3078 goto error;
3079 }
3080#endif
3081 u->wst.ptr += 2;
3082 }
3083 break;
3084 case 0xbd: /* ORA2k */
3085 __asm__("evaluxn_bd_ORA2k:");
3086 {
3087 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
3088 u->wst.dat[u->wst.ptr] = d | b;
3089 u->wst.dat[u->wst.ptr + 1] = c | a;
3090#ifndef NO_STACK_CHECKS
3091 if(__builtin_expect(u->wst.ptr < 4, 0)) {
3092 u->wst.error = 1;
3093 goto error;
3094 }
3095 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3096 u->wst.error = 2;
3097 goto error;
3098 }
3099#endif
3100 u->wst.ptr += 2;
3101 }
3102 break;
3103 case 0xbe: /* EOR2k */
3104 __asm__("evaluxn_be_EOR2k:");
3105 {
3106 u8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2], c = u->wst.dat[u->wst.ptr - 3], d = u->wst.dat[u->wst.ptr - 4];
3107 u->wst.dat[u->wst.ptr] = d ^ b;
3108 u->wst.dat[u->wst.ptr + 1] = c ^ a;
3109#ifndef NO_STACK_CHECKS
3110 if(__builtin_expect(u->wst.ptr < 4, 0)) {
3111 u->wst.error = 1;
3112 goto error;
3113 }
3114 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3115 u->wst.error = 2;
3116 goto error;
3117 }
3118#endif
3119 u->wst.ptr += 2;
3120 }
3121 break;
3122 case 0xbf: /* SFT2k */
3123 __asm__("evaluxn_bf_SFT2k:");
3124 {
3125 u8 a = u->wst.dat[u->wst.ptr - 1];
3126 u16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
3127 u->wst.dat[u->wst.ptr] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8;
3128 u->wst.dat[u->wst.ptr + 1] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff;
3129#ifndef NO_STACK_CHECKS
3130 if(__builtin_expect(u->wst.ptr < 3, 0)) {
3131 u->wst.error = 1;
3132 goto error;
3133 }
3134 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3135 u->wst.error = 2;
3136 goto error;
3137 }
3138#endif
3139 u->wst.ptr += 2;
3140 }
3141 break;
3142 case 0xc1: /* INCkr */
3143 __asm__("evaluxn_c1_INCkr:");
3144 {
3145 u8 a = u->rst.dat[u->rst.ptr - 1];
3146 u->rst.dat[u->rst.ptr] = a + 1;
3147#ifndef NO_STACK_CHECKS
3148 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3149 u->rst.error = 1;
3150 goto error;
3151 }
3152 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3153 u->rst.error = 2;
3154 goto error;
3155 }
3156#endif
3157 u->rst.ptr += 1;
3158 }
3159 break;
3160 case 0xc2: /* POPkr */
3161 __asm__("evaluxn_c2_POPkr:");
3162 {
3163 u->rst.dat[u->rst.ptr - 1];
3164#ifndef NO_STACK_CHECKS
3165 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3166 u->rst.error = 1;
3167 goto error;
3168 }
3169#endif
3170 }
3171 break;
3172 case 0xc6: /* DUPkr */
3173 __asm__("evaluxn_c3_DUPkr:");
3174 {
3175 u8 a = u->rst.dat[u->rst.ptr - 1];
3176 u->rst.dat[u->rst.ptr] = a;
3177 u->rst.dat[u->rst.ptr + 1] = a;
3178#ifndef NO_STACK_CHECKS
3179 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3180 u->rst.error = 1;
3181 goto error;
3182 }
3183 if(__builtin_expect(u->rst.ptr > 253, 0)) {
3184 u->rst.error = 2;
3185 goto error;
3186 }
3187#endif
3188 u->rst.ptr += 2;
3189 }
3190 break;
3191 case 0xc3: /* NIPkr */
3192 __asm__("evaluxn_c4_NIPkr:");
3193 {
3194 u8 a = u->rst.dat[u->rst.ptr - 1];
3195 u->rst.dat[u->rst.ptr - 2];
3196 u->rst.dat[u->rst.ptr] = a;
3197#ifndef NO_STACK_CHECKS
3198 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3199 u->rst.error = 1;
3200 goto error;
3201 }
3202 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3203 u->rst.error = 2;
3204 goto error;
3205 }
3206#endif
3207 u->rst.ptr += 1;
3208 }
3209 break;
3210 case 0xc4: /* SWPkr */
3211 __asm__("evaluxn_c5_SWPkr:");
3212 {
3213 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3214 u->rst.dat[u->rst.ptr] = a;
3215 u->rst.dat[u->rst.ptr + 1] = b;
3216#ifndef NO_STACK_CHECKS
3217 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3218 u->rst.error = 1;
3219 goto error;
3220 }
3221 if(__builtin_expect(u->rst.ptr > 253, 0)) {
3222 u->rst.error = 2;
3223 goto error;
3224 }
3225#endif
3226 u->rst.ptr += 2;
3227 }
3228 break;
3229 case 0xc7: /* OVRkr */
3230 __asm__("evaluxn_c6_OVRkr:");
3231 {
3232 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3233 u->rst.dat[u->rst.ptr] = b;
3234 u->rst.dat[u->rst.ptr + 1] = a;
3235 u->rst.dat[u->rst.ptr + 2] = b;
3236#ifndef NO_STACK_CHECKS
3237 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3238 u->rst.error = 1;
3239 goto error;
3240 }
3241 if(__builtin_expect(u->rst.ptr > 252, 0)) {
3242 u->rst.error = 2;
3243 goto error;
3244 }
3245#endif
3246 u->rst.ptr += 3;
3247 }
3248 break;
3249 case 0xc5: /* ROTkr */
3250 __asm__("evaluxn_c7_ROTkr:");
3251 {
3252 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3];
3253 u->rst.dat[u->rst.ptr] = b;
3254 u->rst.dat[u->rst.ptr + 1] = a;
3255 u->rst.dat[u->rst.ptr + 2] = c;
3256#ifndef NO_STACK_CHECKS
3257 if(__builtin_expect(u->rst.ptr < 3, 0)) {
3258 u->rst.error = 1;
3259 goto error;
3260 }
3261 if(__builtin_expect(u->rst.ptr > 252, 0)) {
3262 u->rst.error = 2;
3263 goto error;
3264 }
3265#endif
3266 u->rst.ptr += 3;
3267 }
3268 break;
3269 case 0xc8: /* EQUkr */
3270 __asm__("evaluxn_c8_EQUkr:");
3271 {
3272 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3273 u->rst.dat[u->rst.ptr] = b == a;
3274#ifndef NO_STACK_CHECKS
3275 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3276 u->rst.error = 1;
3277 goto error;
3278 }
3279 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3280 u->rst.error = 2;
3281 goto error;
3282 }
3283#endif
3284 u->rst.ptr += 1;
3285 }
3286 break;
3287 case 0xc9: /* NEQkr */
3288 __asm__("evaluxn_c9_NEQkr:");
3289 {
3290 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3291 u->rst.dat[u->rst.ptr] = b != a;
3292#ifndef NO_STACK_CHECKS
3293 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3294 u->rst.error = 1;
3295 goto error;
3296 }
3297 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3298 u->rst.error = 2;
3299 goto error;
3300 }
3301#endif
3302 u->rst.ptr += 1;
3303 }
3304 break;
3305 case 0xca: /* GTHkr */
3306 __asm__("evaluxn_ca_GTHkr:");
3307 {
3308 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3309 u->rst.dat[u->rst.ptr] = b > a;
3310#ifndef NO_STACK_CHECKS
3311 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3312 u->rst.error = 1;
3313 goto error;
3314 }
3315 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3316 u->rst.error = 2;
3317 goto error;
3318 }
3319#endif
3320 u->rst.ptr += 1;
3321 }
3322 break;
3323 case 0xcb: /* LTHkr */
3324 __asm__("evaluxn_cb_LTHkr:");
3325 {
3326 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3327 u->rst.dat[u->rst.ptr] = b < a;
3328#ifndef NO_STACK_CHECKS
3329 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3330 u->rst.error = 1;
3331 goto error;
3332 }
3333 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3334 u->rst.error = 2;
3335 goto error;
3336 }
3337#endif
3338 u->rst.ptr += 1;
3339 }
3340 break;
3341 case 0xcc: /* JMPkr */
3342 __asm__("evaluxn_cc_JMPkr:");
3343 {
3344 u8 a = u->rst.dat[u->rst.ptr - 1];
3345 u->ram.ptr += (s8)a;
3346#ifndef NO_STACK_CHECKS
3347 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3348 u->rst.error = 1;
3349 goto error;
3350 }
3351#endif
3352 }
3353 break;
3354 case 0xcd: /* JCNkr */
3355 __asm__("evaluxn_cd_JCNkr:");
3356 {
3357 u8 a = u->rst.dat[u->rst.ptr - 1];
3358 if(u->rst.dat[u->rst.ptr - 2]) u->ram.ptr += (s8)a;
3359#ifndef NO_STACK_CHECKS
3360 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3361 u->rst.error = 1;
3362 goto error;
3363 }
3364#endif
3365 }
3366 break;
3367 case 0xce: /* JSRkr */
3368 __asm__("evaluxn_ce_JSRkr:");
3369 {
3370 u8 a = u->rst.dat[u->rst.ptr - 1];
3371 u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8;
3372 u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff;
3373 u->ram.ptr += (s8)a;
3374#ifndef NO_STACK_CHECKS
3375 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3376 u->rst.error = 1;
3377 goto error;
3378 }
3379 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3380 u->wst.error = 2;
3381 goto error;
3382 }
3383#endif
3384 u->wst.ptr += 2;
3385 }
3386 break;
3387 case 0xcf: /* STHkr */
3388 __asm__("evaluxn_cf_STHkr:");
3389 {
3390 u8 a = u->rst.dat[u->rst.ptr - 1];
3391 u->wst.dat[u->wst.ptr] = a;
3392#ifndef NO_STACK_CHECKS
3393 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3394 u->rst.error = 1;
3395 goto error;
3396 }
3397 if(__builtin_expect(u->wst.ptr > 254, 0)) {
3398 u->wst.error = 2;
3399 goto error;
3400 }
3401#endif
3402 u->wst.ptr += 1;
3403 }
3404 break;
3405 case 0xd0: /* LDZkr */
3406 __asm__("evaluxn_d0_LDZkr:");
3407 {
3408 u8 a = u->rst.dat[u->rst.ptr - 1];
3409 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, a);
3410#ifndef NO_STACK_CHECKS
3411 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3412 u->rst.error = 1;
3413 goto error;
3414 }
3415 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3416 u->rst.error = 2;
3417 goto error;
3418 }
3419#endif
3420 u->rst.ptr += 1;
3421 }
3422 break;
3423 case 0xd1: /* STZkr */
3424 __asm__("evaluxn_d1_STZkr:");
3425 {
3426 u8 a = u->rst.dat[u->rst.ptr - 1];
3427 u8 b = u->rst.dat[u->rst.ptr - 2];
3428 mempoke8(u->ram.dat, a, b);
3429#ifndef NO_STACK_CHECKS
3430 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3431 u->rst.error = 1;
3432 goto error;
3433 }
3434#endif
3435 }
3436 break;
3437 case 0xd2: /* LDRkr */
3438 __asm__("evaluxn_d2_LDRkr:");
3439 {
3440 u8 a = u->rst.dat[u->rst.ptr - 1];
3441 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
3442#ifndef NO_STACK_CHECKS
3443 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3444 u->rst.error = 1;
3445 goto error;
3446 }
3447 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3448 u->rst.error = 2;
3449 goto error;
3450 }
3451#endif
3452 u->rst.ptr += 1;
3453 }
3454 break;
3455 case 0xd3: /* STRkr */
3456 __asm__("evaluxn_d3_STRkr:");
3457 {
3458 u8 a = u->rst.dat[u->rst.ptr - 1];
3459 u8 b = u->rst.dat[u->rst.ptr - 2];
3460 mempoke8(u->ram.dat, u->ram.ptr + (s8)a, b);
3461#ifndef NO_STACK_CHECKS
3462 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3463 u->rst.error = 1;
3464 goto error;
3465 }
3466#endif
3467 }
3468 break;
3469 case 0xd4: /* LDAkr */
3470 __asm__("evaluxn_d4_LDAkr:");
3471 {
3472 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3473 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, a);
3474#ifndef NO_STACK_CHECKS
3475 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3476 u->rst.error = 1;
3477 goto error;
3478 }
3479 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3480 u->rst.error = 2;
3481 goto error;
3482 }
3483#endif
3484 u->rst.ptr += 1;
3485 }
3486 break;
3487 case 0xd5: /* STAkr */
3488 __asm__("evaluxn_d5_STAkr:");
3489 {
3490 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3491 u8 b = u->rst.dat[u->rst.ptr - 3];
3492 mempoke8(u->ram.dat, a, b);
3493#ifndef NO_STACK_CHECKS
3494 if(__builtin_expect(u->rst.ptr < 3, 0)) {
3495 u->rst.error = 1;
3496 goto error;
3497 }
3498#endif
3499 }
3500 break;
3501 case 0xd6: /* DEIkr */
3502 __asm__("evaluxn_d6_DEIkr:");
3503 {
3504 u8 a = u->rst.dat[u->rst.ptr - 1];
3505 u->rst.dat[u->rst.ptr] = devpeek8(&u->dev[a >> 4], a);
3506#ifndef NO_STACK_CHECKS
3507 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3508 u->rst.error = 1;
3509 goto error;
3510 }
3511 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3512 u->rst.error = 2;
3513 goto error;
3514 }
3515#endif
3516 u->rst.ptr += 1;
3517 }
3518 break;
3519 case 0xd7: /* DEOkr */
3520 __asm__("evaluxn_d7_DEOkr:");
3521 {
3522 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3523 devpoke8(&u->dev[a >> 4], a, b);
3524#ifndef NO_STACK_CHECKS
3525 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3526 u->rst.error = 1;
3527 goto error;
3528 }
3529#endif
3530 }
3531 break;
3532 case 0xd8: /* ADDkr */
3533 __asm__("evaluxn_d8_ADDkr:");
3534 {
3535 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3536 u->rst.dat[u->rst.ptr] = b + a;
3537#ifndef NO_STACK_CHECKS
3538 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3539 u->rst.error = 1;
3540 goto error;
3541 }
3542 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3543 u->rst.error = 2;
3544 goto error;
3545 }
3546#endif
3547 u->rst.ptr += 1;
3548 }
3549 break;
3550 case 0xd9: /* SUBkr */
3551 __asm__("evaluxn_d9_SUBkr:");
3552 {
3553 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3554 u->rst.dat[u->rst.ptr] = b - a;
3555#ifndef NO_STACK_CHECKS
3556 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3557 u->rst.error = 1;
3558 goto error;
3559 }
3560 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3561 u->rst.error = 2;
3562 goto error;
3563 }
3564#endif
3565 u->rst.ptr += 1;
3566 }
3567 break;
3568 case 0xda: /* MULkr */
3569 __asm__("evaluxn_da_MULkr:");
3570 {
3571 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3572 u->rst.dat[u->rst.ptr] = b * a;
3573#ifndef NO_STACK_CHECKS
3574 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3575 u->rst.error = 1;
3576 goto error;
3577 }
3578 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3579 u->rst.error = 2;
3580 goto error;
3581 }
3582#endif
3583 u->rst.ptr += 1;
3584 }
3585 break;
3586 case 0xdb: /* DIVkr */
3587 __asm__("evaluxn_db_DIVkr:");
3588 {
3589 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3590 if(a == 0) {
3591 u->rst.error = 3;
3592#ifndef NO_STACK_CHECKS
3593 goto error;
3594#endif
3595 a = 1;
3596 }
3597 u->rst.dat[u->rst.ptr] = b / a;
3598#ifndef NO_STACK_CHECKS
3599 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3600 u->rst.error = 1;
3601 goto error;
3602 }
3603 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3604 u->rst.error = 2;
3605 goto error;
3606 }
3607#endif
3608 u->rst.ptr += 1;
3609 }
3610 break;
3611 case 0xdc: /* ANDkr */
3612 __asm__("evaluxn_dc_ANDkr:");
3613 {
3614 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3615 u->rst.dat[u->rst.ptr] = b & a;
3616#ifndef NO_STACK_CHECKS
3617 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3618 u->rst.error = 1;
3619 goto error;
3620 }
3621 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3622 u->rst.error = 2;
3623 goto error;
3624 }
3625#endif
3626 u->rst.ptr += 1;
3627 }
3628 break;
3629 case 0xdd: /* ORAkr */
3630 __asm__("evaluxn_dd_ORAkr:");
3631 {
3632 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3633 u->rst.dat[u->rst.ptr] = b | a;
3634#ifndef NO_STACK_CHECKS
3635 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3636 u->rst.error = 1;
3637 goto error;
3638 }
3639 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3640 u->rst.error = 2;
3641 goto error;
3642 }
3643#endif
3644 u->rst.ptr += 1;
3645 }
3646 break;
3647 case 0xde: /* EORkr */
3648 __asm__("evaluxn_de_EORkr:");
3649 {
3650 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3651 u->rst.dat[u->rst.ptr] = b ^ a;
3652#ifndef NO_STACK_CHECKS
3653 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3654 u->rst.error = 1;
3655 goto error;
3656 }
3657 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3658 u->rst.error = 2;
3659 goto error;
3660 }
3661#endif
3662 u->rst.ptr += 1;
3663 }
3664 break;
3665 case 0xdf: /* SFTkr */
3666 __asm__("evaluxn_df_SFTkr:");
3667 {
3668 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3669 u->rst.dat[u->rst.ptr] = b >> (a & 0x07) << ((a & 0x70) >> 4);
3670#ifndef NO_STACK_CHECKS
3671 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3672 u->rst.error = 1;
3673 goto error;
3674 }
3675 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3676 u->rst.error = 2;
3677 goto error;
3678 }
3679#endif
3680 u->rst.ptr += 1;
3681 }
3682 break;
3683 case 0xe1: /* INC2kr */
3684 __asm__("evaluxn_e1_INC2kr:");
3685 {
3686 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3687 u->rst.dat[u->rst.ptr] = (a + 1) >> 8;
3688 u->rst.dat[u->rst.ptr + 1] = (a + 1) & 0xff;
3689#ifndef NO_STACK_CHECKS
3690 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3691 u->rst.error = 1;
3692 goto error;
3693 }
3694 if(__builtin_expect(u->rst.ptr > 253, 0)) {
3695 u->rst.error = 2;
3696 goto error;
3697 }
3698#endif
3699 u->rst.ptr += 2;
3700 }
3701 break;
3702 case 0xe2: /* POP2kr */
3703 __asm__("evaluxn_e2_POP2kr:");
3704 {
3705 (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3706#ifndef NO_STACK_CHECKS
3707 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3708 u->rst.error = 1;
3709 goto error;
3710 }
3711#endif
3712 }
3713 break;
3714 case 0xe6: /* DUP2kr */
3715 __asm__("evaluxn_e3_DUP2kr:");
3716 {
3717 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3718 u->rst.dat[u->rst.ptr] = b;
3719 u->rst.dat[u->rst.ptr + 1] = a;
3720 u->rst.dat[u->rst.ptr + 2] = b;
3721 u->rst.dat[u->rst.ptr + 3] = a;
3722#ifndef NO_STACK_CHECKS
3723 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3724 u->rst.error = 1;
3725 goto error;
3726 }
3727 if(__builtin_expect(u->rst.ptr > 251, 0)) {
3728 u->rst.error = 2;
3729 goto error;
3730 }
3731#endif
3732 u->rst.ptr += 4;
3733 }
3734 break;
3735 case 0xe3: /* NIP2kr */
3736 __asm__("evaluxn_e4_NIP2kr:");
3737 {
3738 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3739 (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
3740 u->rst.dat[u->rst.ptr] = a >> 8;
3741 u->rst.dat[u->rst.ptr + 1] = a & 0xff;
3742#ifndef NO_STACK_CHECKS
3743 if(__builtin_expect(u->rst.ptr < 4, 0)) {
3744 u->rst.error = 1;
3745 goto error;
3746 }
3747 if(__builtin_expect(u->rst.ptr > 253, 0)) {
3748 u->rst.error = 2;
3749 goto error;
3750 }
3751#endif
3752 u->rst.ptr += 2;
3753 }
3754 break;
3755 case 0xe4: /* SWP2kr */
3756 __asm__("evaluxn_e5_SWP2kr:");
3757 {
3758 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
3759 u->rst.dat[u->rst.ptr] = b;
3760 u->rst.dat[u->rst.ptr + 1] = a;
3761 u->rst.dat[u->rst.ptr + 2] = d;
3762 u->rst.dat[u->rst.ptr + 3] = c;
3763#ifndef NO_STACK_CHECKS
3764 if(__builtin_expect(u->rst.ptr < 4, 0)) {
3765 u->rst.error = 1;
3766 goto error;
3767 }
3768 if(__builtin_expect(u->rst.ptr > 251, 0)) {
3769 u->rst.error = 2;
3770 goto error;
3771 }
3772#endif
3773 u->rst.ptr += 4;
3774 }
3775 break;
3776 case 0xe7: /* OVR2kr */
3777 __asm__("evaluxn_e6_OVR2kr:");
3778 {
3779 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
3780 u->rst.dat[u->rst.ptr] = d;
3781 u->rst.dat[u->rst.ptr + 1] = c;
3782 u->rst.dat[u->rst.ptr + 2] = b;
3783 u->rst.dat[u->rst.ptr + 3] = a;
3784 u->rst.dat[u->rst.ptr + 4] = d;
3785 u->rst.dat[u->rst.ptr + 5] = c;
3786#ifndef NO_STACK_CHECKS
3787 if(__builtin_expect(u->rst.ptr < 4, 0)) {
3788 u->rst.error = 1;
3789 goto error;
3790 }
3791 if(__builtin_expect(u->rst.ptr > 249, 0)) {
3792 u->rst.error = 2;
3793 goto error;
3794 }
3795#endif
3796 u->rst.ptr += 6;
3797 }
3798 break;
3799 case 0xe5: /* ROT2kr */
3800 __asm__("evaluxn_e7_ROT2kr:");
3801 {
3802 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4], e = u->rst.dat[u->rst.ptr - 5], f = u->rst.dat[u->rst.ptr - 6];
3803 u->rst.dat[u->rst.ptr] = d;
3804 u->rst.dat[u->rst.ptr + 1] = c;
3805 u->rst.dat[u->rst.ptr + 2] = b;
3806 u->rst.dat[u->rst.ptr + 3] = a;
3807 u->rst.dat[u->rst.ptr + 4] = f;
3808 u->rst.dat[u->rst.ptr + 5] = e;
3809#ifndef NO_STACK_CHECKS
3810 if(__builtin_expect(u->rst.ptr < 6, 0)) {
3811 u->rst.error = 1;
3812 goto error;
3813 }
3814 if(__builtin_expect(u->rst.ptr > 249, 0)) {
3815 u->rst.error = 2;
3816 goto error;
3817 }
3818#endif
3819 u->rst.ptr += 6;
3820 }
3821 break;
3822 case 0xe8: /* EQU2kr */
3823 __asm__("evaluxn_e8_EQU2kr:");
3824 {
3825 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
3826 u->rst.dat[u->rst.ptr] = b == a;
3827#ifndef NO_STACK_CHECKS
3828 if(__builtin_expect(u->rst.ptr < 4, 0)) {
3829 u->rst.error = 1;
3830 goto error;
3831 }
3832 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3833 u->rst.error = 2;
3834 goto error;
3835 }
3836#endif
3837 u->rst.ptr += 1;
3838 }
3839 break;
3840 case 0xe9: /* NEQ2kr */
3841 __asm__("evaluxn_e9_NEQ2kr:");
3842 {
3843 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
3844 u->rst.dat[u->rst.ptr] = b != a;
3845#ifndef NO_STACK_CHECKS
3846 if(__builtin_expect(u->rst.ptr < 4, 0)) {
3847 u->rst.error = 1;
3848 goto error;
3849 }
3850 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3851 u->rst.error = 2;
3852 goto error;
3853 }
3854#endif
3855 u->rst.ptr += 1;
3856 }
3857 break;
3858 case 0xea: /* GTH2kr */
3859 __asm__("evaluxn_ea_GTH2kr:");
3860 {
3861 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
3862 u->rst.dat[u->rst.ptr] = b > a;
3863#ifndef NO_STACK_CHECKS
3864 if(__builtin_expect(u->rst.ptr < 4, 0)) {
3865 u->rst.error = 1;
3866 goto error;
3867 }
3868 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3869 u->rst.error = 2;
3870 goto error;
3871 }
3872#endif
3873 u->rst.ptr += 1;
3874 }
3875 break;
3876 case 0xeb: /* LTH2kr */
3877 __asm__("evaluxn_eb_LTH2kr:");
3878 {
3879 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
3880 u->rst.dat[u->rst.ptr] = b < a;
3881#ifndef NO_STACK_CHECKS
3882 if(__builtin_expect(u->rst.ptr < 4, 0)) {
3883 u->rst.error = 1;
3884 goto error;
3885 }
3886 if(__builtin_expect(u->rst.ptr > 254, 0)) {
3887 u->rst.error = 2;
3888 goto error;
3889 }
3890#endif
3891 u->rst.ptr += 1;
3892 }
3893 break;
3894 case 0xec: /* JMP2kr */
3895 __asm__("evaluxn_ec_JMP2kr:");
3896 {
3897 u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3898#ifndef NO_STACK_CHECKS
3899 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3900 u->rst.error = 1;
3901 goto error;
3902 }
3903#endif
3904 }
3905 break;
3906 case 0xed: /* JCN2kr */
3907 __asm__("evaluxn_ed_JCN2kr:");
3908 {
3909 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3910 if(u->rst.dat[u->rst.ptr - 3]) u->ram.ptr = a;
3911#ifndef NO_STACK_CHECKS
3912 if(__builtin_expect(u->rst.ptr < 3, 0)) {
3913 u->rst.error = 1;
3914 goto error;
3915 }
3916#endif
3917 }
3918 break;
3919 case 0xee: /* JSR2kr */
3920 __asm__("evaluxn_ee_JSR2kr:");
3921 {
3922 u->wst.dat[u->wst.ptr] = u->ram.ptr >> 8;
3923 u->wst.dat[u->wst.ptr + 1] = u->ram.ptr & 0xff;
3924 u->ram.ptr = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3925#ifndef NO_STACK_CHECKS
3926 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3927 u->rst.error = 1;
3928 goto error;
3929 }
3930 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3931 u->wst.error = 2;
3932 goto error;
3933 }
3934#endif
3935 u->wst.ptr += 2;
3936 }
3937 break;
3938 case 0xef: /* STH2kr */
3939 __asm__("evaluxn_ef_STH2kr:");
3940 {
3941 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
3942 u->wst.dat[u->wst.ptr] = b;
3943 u->wst.dat[u->wst.ptr + 1] = a;
3944#ifndef NO_STACK_CHECKS
3945 if(__builtin_expect(u->rst.ptr < 2, 0)) {
3946 u->rst.error = 1;
3947 goto error;
3948 }
3949 if(__builtin_expect(u->wst.ptr > 253, 0)) {
3950 u->wst.error = 2;
3951 goto error;
3952 }
3953#endif
3954 u->wst.ptr += 2;
3955 }
3956 break;
3957 case 0xf0: /* LDZ2kr */
3958 __asm__("evaluxn_f0_LDZ2kr:");
3959 {
3960 u8 a = u->rst.dat[u->rst.ptr - 1];
3961 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, a);
3962 u->rst.dat[u->rst.ptr + 1] = mempeek8(u->ram.dat, a + 1);
3963#ifndef NO_STACK_CHECKS
3964 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3965 u->rst.error = 1;
3966 goto error;
3967 }
3968 if(__builtin_expect(u->rst.ptr > 253, 0)) {
3969 u->rst.error = 2;
3970 goto error;
3971 }
3972#endif
3973 u->rst.ptr += 2;
3974 }
3975 break;
3976 case 0xf1: /* STZ2kr */
3977 __asm__("evaluxn_f1_STZ2kr:");
3978 {
3979 u8 a = u->rst.dat[u->rst.ptr - 1];
3980 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
3981 mempoke16(u->ram.dat, a, b);
3982#ifndef NO_STACK_CHECKS
3983 if(__builtin_expect(u->rst.ptr < 3, 0)) {
3984 u->rst.error = 1;
3985 goto error;
3986 }
3987#endif
3988 }
3989 break;
3990 case 0xf2: /* LDR2kr */
3991 __asm__("evaluxn_f2_LDR2kr:");
3992 {
3993 u8 a = u->rst.dat[u->rst.ptr - 1];
3994 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a);
3995 u->rst.dat[u->rst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr + (s8)a + 1);
3996#ifndef NO_STACK_CHECKS
3997 if(__builtin_expect(u->rst.ptr < 1, 0)) {
3998 u->rst.error = 1;
3999 goto error;
4000 }
4001 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4002 u->rst.error = 2;
4003 goto error;
4004 }
4005#endif
4006 u->rst.ptr += 2;
4007 }
4008 break;
4009 case 0xf3: /* STR2kr */
4010 __asm__("evaluxn_f3_STR2kr:");
4011 {
4012 u8 a = u->rst.dat[u->rst.ptr - 1];
4013 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
4014 mempoke16(u->ram.dat, u->ram.ptr + (s8)a, b);
4015#ifndef NO_STACK_CHECKS
4016 if(__builtin_expect(u->rst.ptr < 3, 0)) {
4017 u->rst.error = 1;
4018 goto error;
4019 }
4020#endif
4021 }
4022 break;
4023 case 0xf4: /* LDA2kr */
4024 __asm__("evaluxn_f4_LDA2kr:");
4025 {
4026 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
4027 u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, a);
4028 u->rst.dat[u->rst.ptr + 1] = mempeek8(u->ram.dat, a + 1);
4029#ifndef NO_STACK_CHECKS
4030 if(__builtin_expect(u->rst.ptr < 2, 0)) {
4031 u->rst.error = 1;
4032 goto error;
4033 }
4034 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4035 u->rst.error = 2;
4036 goto error;
4037 }
4038#endif
4039 u->rst.ptr += 2;
4040 }
4041 break;
4042 case 0xf5: /* STA2kr */
4043 __asm__("evaluxn_f5_STA2kr:");
4044 {
4045 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
4046 u16 b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
4047 mempoke16(u->ram.dat, a, b);
4048#ifndef NO_STACK_CHECKS
4049 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4050 u->rst.error = 1;
4051 goto error;
4052 }
4053#endif
4054 }
4055 break;
4056 case 0xf6: /* DEI2kr */
4057 __asm__("evaluxn_f6_DEI2kr:");
4058 {
4059 u8 a = u->rst.dat[u->rst.ptr - 1];
4060 u->rst.dat[u->rst.ptr] = devpeek8(&u->dev[a >> 4], a);
4061 u->rst.dat[u->rst.ptr + 1] = devpeek8(&u->dev[a >> 4], a + 1);
4062#ifndef NO_STACK_CHECKS
4063 if(__builtin_expect(u->rst.ptr < 1, 0)) {
4064 u->rst.error = 1;
4065 goto error;
4066 }
4067 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4068 u->rst.error = 2;
4069 goto error;
4070 }
4071#endif
4072 u->rst.ptr += 2;
4073 }
4074 break;
4075 case 0xf7: /* DEO2kr */
4076 __asm__("evaluxn_f7_DEO2kr:");
4077 {
4078 u8 a = u->rst.dat[u->rst.ptr - 1];
4079 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
4080 devpoke16(&u->dev[a >> 4], a, b);
4081#ifndef NO_STACK_CHECKS
4082 if(__builtin_expect(u->rst.ptr < 3, 0)) {
4083 u->rst.error = 1;
4084 goto error;
4085 }
4086#endif
4087 }
4088 break;
4089 case 0xf8: /* ADD2kr */
4090 __asm__("evaluxn_f8_ADD2kr:");
4091 {
4092 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
4093 u->rst.dat[u->rst.ptr] = (b + a) >> 8;
4094 u->rst.dat[u->rst.ptr + 1] = (b + a) & 0xff;
4095#ifndef NO_STACK_CHECKS
4096 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4097 u->rst.error = 1;
4098 goto error;
4099 }
4100 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4101 u->rst.error = 2;
4102 goto error;
4103 }
4104#endif
4105 u->rst.ptr += 2;
4106 }
4107 break;
4108 case 0xf9: /* SUB2kr */
4109 __asm__("evaluxn_f9_SUB2kr:");
4110 {
4111 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
4112 u->rst.dat[u->rst.ptr] = (b - a) >> 8;
4113 u->rst.dat[u->rst.ptr + 1] = (b - a) & 0xff;
4114#ifndef NO_STACK_CHECKS
4115 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4116 u->rst.error = 1;
4117 goto error;
4118 }
4119 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4120 u->rst.error = 2;
4121 goto error;
4122 }
4123#endif
4124 u->rst.ptr += 2;
4125 }
4126 break;
4127 case 0xfa: /* MUL2kr */
4128 __asm__("evaluxn_fa_MUL2kr:");
4129 {
4130 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
4131 u->rst.dat[u->rst.ptr] = (b * a) >> 8;
4132 u->rst.dat[u->rst.ptr + 1] = (b * a) & 0xff;
4133#ifndef NO_STACK_CHECKS
4134 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4135 u->rst.error = 1;
4136 goto error;
4137 }
4138 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4139 u->rst.error = 2;
4140 goto error;
4141 }
4142#endif
4143 u->rst.ptr += 2;
4144 }
4145 break;
4146 case 0xfb: /* DIV2kr */
4147 __asm__("evaluxn_fb_DIV2kr:");
4148 {
4149 u16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8)), b = (u->rst.dat[u->rst.ptr - 3] | (u->rst.dat[u->rst.ptr - 4] << 8));
4150 if(a == 0) {
4151 u->rst.error = 3;
4152#ifndef NO_STACK_CHECKS
4153 goto error;
4154#endif
4155 a = 1;
4156 }
4157 u->rst.dat[u->rst.ptr] = (b / a) >> 8;
4158 u->rst.dat[u->rst.ptr + 1] = (b / a) & 0xff;
4159#ifndef NO_STACK_CHECKS
4160 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4161 u->rst.error = 1;
4162 goto error;
4163 }
4164 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4165 u->rst.error = 2;
4166 goto error;
4167 }
4168#endif
4169 u->rst.ptr += 2;
4170 }
4171 break;
4172 case 0xfc: /* AND2kr */
4173 __asm__("evaluxn_fc_AND2kr:");
4174 {
4175 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
4176 u->rst.dat[u->rst.ptr] = d & b;
4177 u->rst.dat[u->rst.ptr + 1] = c & a;
4178#ifndef NO_STACK_CHECKS
4179 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4180 u->rst.error = 1;
4181 goto error;
4182 }
4183 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4184 u->rst.error = 2;
4185 goto error;
4186 }
4187#endif
4188 u->rst.ptr += 2;
4189 }
4190 break;
4191 case 0xfd: /* ORA2kr */
4192 __asm__("evaluxn_fd_ORA2kr:");
4193 {
4194 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
4195 u->rst.dat[u->rst.ptr] = d | b;
4196 u->rst.dat[u->rst.ptr + 1] = c | a;
4197#ifndef NO_STACK_CHECKS
4198 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4199 u->rst.error = 1;
4200 goto error;
4201 }
4202 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4203 u->rst.error = 2;
4204 goto error;
4205 }
4206#endif
4207 u->rst.ptr += 2;
4208 }
4209 break;
4210 case 0xfe: /* EOR2kr */
4211 __asm__("evaluxn_fe_EOR2kr:");
4212 {
4213 u8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2], c = u->rst.dat[u->rst.ptr - 3], d = u->rst.dat[u->rst.ptr - 4];
4214 u->rst.dat[u->rst.ptr] = d ^ b;
4215 u->rst.dat[u->rst.ptr + 1] = c ^ a;
4216#ifndef NO_STACK_CHECKS
4217 if(__builtin_expect(u->rst.ptr < 4, 0)) {
4218 u->rst.error = 1;
4219 goto error;
4220 }
4221 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4222 u->rst.error = 2;
4223 goto error;
4224 }
4225#endif
4226 u->rst.ptr += 2;
4227 }
4228 break;
4229 case 0xff: /* SFT2kr */
4230 __asm__("evaluxn_ff_SFT2kr:");
4231 {
4232 u8 a = u->rst.dat[u->rst.ptr - 1];
4233 u16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
4234 u->rst.dat[u->rst.ptr] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) >> 8;
4235 u->rst.dat[u->rst.ptr + 1] = (b >> (a & 0x0f) << ((a & 0xf0) >> 4)) & 0xff;
4236#ifndef NO_STACK_CHECKS
4237 if(__builtin_expect(u->rst.ptr < 3, 0)) {
4238 u->rst.error = 1;
4239 goto error;
4240 }
4241 if(__builtin_expect(u->rst.ptr > 253, 0)) {
4242 u->rst.error = 2;
4243 goto error;
4244 }
4245#endif
4246 u->rst.ptr += 2;
4247 }
4248 break;
4249#pragma GCC diagnostic pop
4250 } 93 }
4251 } 94 }
4252 return 1;
4253#ifndef NO_STACK_CHECKS
4254error:
4255 return 0;
4256#endif
4257} 95}
4258 96
4259Device * 97int
4260uxn_port(Uxn *u, u8 id, char *name, void (*talkfn)(Device *d, u8 b0, u8 w)) 98uxn_boot(Uxn *u, u8 *ram, Dei *dei, Deo *deo)
4261{ 99{
4262 Device *d = &u->dev[id]; 100 u32 i;
4263 d->addr = id * 0x10; 101 char *cptr = (char *)u;
4264 d->u = u; 102 for(i = 0; i < sizeof(*u); i++)
4265 d->mem = u->ram.dat; 103 cptr[i] = 0x00;
4266 d->talk = talkfn; 104 u->wst = (Stack *)(ram + 0x10000);
4267 (void)name; 105 u->rst = (Stack *)(ram + 0x10100);
4268 return d; 106 u->dev = (u8 *)(ram + 0x10200);
107 u->ram = ram;
108 u->dei = dei;
109 u->deo = deo;
110 return 1;
4269} 111}
diff --git a/src/uxn.h b/src/uxn.h
index 5d68528..f9bee16 100644
--- a/src/uxn.h
+++ b/src/uxn.h
@@ -1,8 +1,5 @@
1#ifndef UXNGBA_UXN_H 1#ifndef UXNGBA_UXN_H
2#define UXNGBA_UXN_H 2#define UXNGBA_UXN_H
3
4#include <stdio.h>
5
6/* 3/*
7Copyright (c) 2021 Devine Lu Linvega 4Copyright (c) 2021 Devine Lu Linvega
8 5
@@ -15,43 +12,30 @@ WITH REGARD TO THIS SOFTWARE.
15*/ 12*/
16 13
17#define PAGE_PROGRAM 0x0100 14#define PAGE_PROGRAM 0x0100
18#define DEVPEEK16(o, x) { (o) = (d->dat[(x)] << 8) + d->dat[(x) + 1]; }
19#define DEVPOKE16(x, y) { d->dat[(x)] = (y) >> 8; d->dat[(x) + 1] = (y); }
20 15
21typedef struct { 16/* clang-format off */
22 u8 ptr, kptr, error;
23 u8 dat[256];
24} Stack;
25 17
26typedef struct { 18#define GETVEC(d) ((d)[0] << 8 | (d)[1])
27 u16 ptr; 19#define POKDEV(x, y) { d[(x)] = (y) >> 8; d[(x) + 1] = (y); }
28 u8 *dat; 20#define PEKDEV(o, x) { (o) = (d[(x)] << 8) + d[(x) + 1]; }
29} Memory;
30 21
31typedef struct Device { 22/* clang-format on */
32 struct Uxn *u; 23
33 u8 addr, dat[16], *mem; 24typedef struct {
34 u16 vector; 25 u8 dat[255], ptr;
35 void (*talk)(struct Device *d, u8, u8); 26} Stack;
36} Device;
37 27
38typedef struct Uxn { 28typedef struct Uxn {
39 Stack wst, rst, *src, *dst; 29 u8 *ram, *dev;
40 Memory ram; 30 Stack *wst, *rst;
41 Device dev[16]; 31 u8 (*dei)(struct Uxn *u, u8 addr);
32 void (*deo)(struct Uxn *u, u8 addr, u8 value);
42} Uxn; 33} Uxn;
43 34
44struct Uxn; 35typedef u8 Dei(Uxn *u, u8 addr);
45 36typedef void Deo(Uxn *u, u8 addr, u8 value);
46static inline void mempoke8(u8 *m, u16 a, u8 b) { m[a] = b; }
47static inline u8 mempeek8(u8 *m, u16 a) { return m[a]; }
48static inline void mempoke16(u8 *m, u16 a, u16 b) { mempoke8(m, a, b >> 8); mempoke8(m, a + 1, b); }
49static inline u16 mempeek16(u8 *m, u16 a) { return (mempeek8(m, a) << 8) + mempeek8(m, a + 1); }
50static inline void devpoke8(Device *d, u8 a, u8 b) { d->dat[a & 0xf] = b; d->talk(d, a & 0x0f, 1); }
51static inline u8 devpeek8(Device *d, u8 a) { d->talk(d, a & 0x0f, 0); return d->dat[a & 0xf]; }
52static inline void devpoke16(Device *d, u8 a, u16 b) { devpoke8(d, a, b >> 8); devpoke8(d, a + 1, b); }
53static inline u16 devpeek16(Device *d, u16 a) { return (devpeek8(d, a) << 8) + devpeek8(d, a + 1); }
54 37
55int uxn_eval(Uxn *u, u16 vec); 38int uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr);
56Device *uxn_port(Uxn *u, u8 id, char *name, void (*talkfn)(Device *, u8, u8)); 39int uxn_boot(Uxn *u, u8 *ram, Dei *dei, Deo *deo);
40int uxn_eval(Uxn *u, u16 pc);
57#endif // UXNGBA_UXN_H 41#endif // UXNGBA_UXN_H