diff options
author | Bad Diode <bd@badd10de.dev> | 2023-08-27 22:52:43 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-08-27 22:52:43 +0200 |
commit | 8357708a6f73401886bc2bdf405cb19adf419cbc (patch) | |
tree | ad9b1c3d2fed68bd3cadcff1f5fd868040598706 | |
parent | 941ad8e28efb685e910b38b06f98bc79fb29677f (diff) | |
download | uxngba-8357708a6f73401886bc2bdf405cb19adf419cbc.tar.gz uxngba-8357708a6f73401886bc2bdf405cb19adf419cbc.zip |
Adjust add/sub instructions slightly
-rw-r--r-- | src/config.c | 11 | ||||
-rw-r--r-- | src/devices.c | 497 | ||||
-rw-r--r-- | src/main.c | 701 | ||||
-rw-r--r-- | src/profiling.c | 157 | ||||
-rw-r--r-- | src/uxn-core.s | 747 |
5 files changed, 1053 insertions, 1060 deletions
diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..d100233 --- /dev/null +++ b/src/config.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #if !defined(TEXT_MODE) || TEXT_MODE == 0 | ||
2 | #define TEXT_LAYER FG_BACK | ||
3 | #else | ||
4 | #define TEXT_LAYER BG_BACK | ||
5 | #endif | ||
6 | |||
7 | #ifndef CONTROL_METHODS | ||
8 | #define CONTROL_METHODS CONTROL_CONTROLLER,CONTROL_MOUSE,CONTROL_KEYBOARD | ||
9 | #endif | ||
10 | |||
11 | #define PROF_ENABLE 0 | ||
diff --git a/src/devices.c b/src/devices.c new file mode 100644 index 0000000..48d062d --- /dev/null +++ b/src/devices.c | |||
@@ -0,0 +1,497 @@ | |||
1 | static time_t seconds = 0; | ||
2 | |||
3 | typedef enum { | ||
4 | CONTROL_CONTROLLER, | ||
5 | CONTROL_MOUSE, | ||
6 | CONTROL_KEYBOARD, | ||
7 | } ControlMethod; | ||
8 | |||
9 | const ControlMethod ctrl_methods[] = { | ||
10 | CONTROL_METHODS | ||
11 | }; | ||
12 | static ControlMethod ctrl_idx = 0; | ||
13 | |||
14 | #define MOUSE_DELTA 1 | ||
15 | typedef struct Mouse { | ||
16 | int x; | ||
17 | int y; | ||
18 | } Mouse; | ||
19 | |||
20 | // static Uxn u; | ||
21 | |||
22 | static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; | ||
23 | |||
24 | int | ||
25 | uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) { | ||
26 | (void)u; | ||
27 | txt_printf("HALTED\n"); | ||
28 | txt_printf("I: %lu\n", instr); | ||
29 | txt_printf("E: %lu\n", err); | ||
30 | txt_printf("A: %lu\n", addr); | ||
31 | while (true); | ||
32 | } | ||
33 | |||
34 | IWRAM_CODE | ||
35 | u8 | ||
36 | screen_dei(u8 *d, u8 port) { | ||
37 | // switch(port) { | ||
38 | // case 0x2: return (SCREEN_WIDTH >> 8); | ||
39 | // case 0x3: return (SCREEN_WIDTH); | ||
40 | // case 0x4: return (SCREEN_HEIGHT >> 8); | ||
41 | // case 0x5: return (SCREEN_HEIGHT); | ||
42 | // default: return d[port]; | ||
43 | // } | ||
44 | } | ||
45 | |||
46 | IWRAM_CODE | ||
47 | void | ||
48 | screen_deo(u8 *ram, u8 *d, u8 port) { | ||
49 | // switch(port) { | ||
50 | // case 0xe: { | ||
51 | // u8 ctrl = d[0xe]; | ||
52 | // u8 color = ctrl & 0x3; | ||
53 | // u16 x0 = PEEK2(d + 0x8); | ||
54 | // u16 y0 = PEEK2(d + 0xa); | ||
55 | // u8 *layer = (ctrl & 0x40) ? FG_BACK : BG_BACK; | ||
56 | // if(ctrl & 0x80) { | ||
57 | // u16 x1 = SCREEN_WIDTH - 1; | ||
58 | // u16 y1 = SCREEN_HEIGHT - 1; | ||
59 | // if(ctrl & 0x10) x1 = x0, x0 = 0; | ||
60 | // if(ctrl & 0x20) y1 = y0, y0 = 0; | ||
61 | // PROF(screen_fill(layer, x0, y0, x1, y1, color), ppu_fill_cycles); | ||
62 | // } else { | ||
63 | // PROF(ppu_pixel(layer, x0, y0, color), ppu_pixel_cycles); | ||
64 | // if(d[0x6] & 0x1) POKE2(d + 0x8, x0 + 1); /* auto x+1 */ | ||
65 | // if(d[0x6] & 0x2) POKE2(d + 0xa, y0 + 1); /* auto y+1 */ | ||
66 | // } | ||
67 | // break; | ||
68 | // } | ||
69 | // case 0xf: { | ||
70 | // u16 x, y, dx, dy, addr; | ||
71 | // u8 n, twobpp = !!(d[0xf] & 0x80); | ||
72 | // x = PEEK2(d + 0x8); | ||
73 | // y = PEEK2(d + 0xa); | ||
74 | // addr = PEEK2(d + 0xc); | ||
75 | // n = d[0x6] >> 4; | ||
76 | // dx = (d[0x6] & 0x01) << 3; | ||
77 | // dy = (d[0x6] & 0x02) << 2; | ||
78 | // if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) { | ||
79 | // return; | ||
80 | // } | ||
81 | // u8 *layer = (d[0xf] & 0x40) ? FG_BACK : BG_BACK; | ||
82 | // u8 color = d[0xf] & 0xf; | ||
83 | // u8 flipx = d[0xf] & 0x10; | ||
84 | // u8 flipy = d[0xf] & 0x20; | ||
85 | // for(size_t i = 0; i <= n; i++) { | ||
86 | // u8 *sprite = &ram[addr]; | ||
87 | // if (twobpp) { | ||
88 | // PROF(ppu_2bpp(layer, | ||
89 | // x + dy * i, | ||
90 | // y + dx * i, | ||
91 | // sprite, | ||
92 | // color, | ||
93 | // flipx, flipy), ppu_chr_cycles); | ||
94 | // } else { | ||
95 | // PROF(ppu_1bpp(layer, | ||
96 | // x + dy * i, | ||
97 | // y + dx * i, | ||
98 | // sprite, | ||
99 | // color, | ||
100 | // flipx, flipy), ppu_icn_cycles); | ||
101 | // } | ||
102 | // addr += (d[0x6] & 0x04) << (1 + twobpp); | ||
103 | // } | ||
104 | // POKE2(d + 0xc, addr); /* auto addr+length */ | ||
105 | // POKE2(d + 0x8, x + dx); /* auto x+8 */ | ||
106 | // POKE2(d + 0xa, y + dy); /* auto y+8 */ | ||
107 | // break; | ||
108 | // } | ||
109 | // } | ||
110 | } | ||
111 | |||
112 | u8 | ||
113 | audio_dei(int instance, u8 *d, u8 port) { | ||
114 | // AudioChannel *c = &channels[instance]; | ||
115 | // switch(port) { | ||
116 | // // case 0x4: return apu_get_vu(instance); | ||
117 | // case 0x2: { | ||
118 | // POKE2(d + 0x2, c->pos); | ||
119 | // c->pos <<= 12; // fixed point. | ||
120 | // break; | ||
121 | // } | ||
122 | // } | ||
123 | return d[port]; | ||
124 | } | ||
125 | |||
126 | void | ||
127 | audio_deo(int instance, u8 *d, u8 port, Uxn *u) { | ||
128 | // AudioChannel *c = &channels[instance]; | ||
129 | // if (port == 0xf) { | ||
130 | // u16 length = 0; | ||
131 | // u16 adsr = 0; | ||
132 | // u16 addr = 0; | ||
133 | // u8 pitch = d[0xf] & 0x7f; | ||
134 | // adsr = PEEK2(d + 0x8); | ||
135 | // length = PEEK2(d + 0xa); | ||
136 | // addr = PEEK2(d + 0xc); | ||
137 | // u8 *data = &u->ram[addr]; | ||
138 | // u32 vol = MAX(d[0xe] >> 4, d[0xe] & 0xf) * 4 / 3; | ||
139 | // bool loop = !(d[0xf] & 0x80); | ||
140 | // update_channel(c, data, length, pitch, adsr, vol, loop); | ||
141 | // } | ||
142 | } | ||
143 | |||
144 | u8 | ||
145 | datetime_dei(u8 *d, u8 port) { | ||
146 | struct tm *t = gmtime(&seconds); | ||
147 | switch(port) { | ||
148 | case 0x0: return (t->tm_year + 1900) >> 8; | ||
149 | case 0x1: return (t->tm_year + 1900); | ||
150 | case 0x2: return t->tm_mon; | ||
151 | case 0x3: return t->tm_mday; | ||
152 | case 0x4: return t->tm_hour; | ||
153 | case 0x5: return t->tm_min; | ||
154 | case 0x6: return t->tm_sec; | ||
155 | case 0x7: return t->tm_wday; | ||
156 | case 0x8: return t->tm_yday >> 8; | ||
157 | case 0x9: return t->tm_yday; | ||
158 | case 0xa: return t->tm_isdst; | ||
159 | default: return d[port]; | ||
160 | } | ||
161 | } | ||
162 | |||
163 | u8 | ||
164 | file_dei(u8 id, u8 *d, u8 port) { | ||
165 | // UxnFile *c = &uxn_file[id]; | ||
166 | // u16 res; | ||
167 | // switch(port) { | ||
168 | // case 0xc: | ||
169 | // case 0xd: { | ||
170 | // res = file_read(c, &d[port], 1); | ||
171 | // POKE2(d + 0x2, res); | ||
172 | // break; | ||
173 | // } | ||
174 | // } | ||
175 | return d[port]; | ||
176 | } | ||
177 | |||
178 | void | ||
179 | file_deo(u8 id, u8 *ram, u8 *d, u8 port) { | ||
180 | // u16 a, b, res; | ||
181 | // UxnFile *f = &uxn_file[id]; | ||
182 | // switch(port) { | ||
183 | // case 0x5: { | ||
184 | // a = PEEK2(d + 0x4); | ||
185 | // b = PEEK2(d + 0xa); | ||
186 | // if(b > 0x10000 - a) { | ||
187 | // b = 0x10000 - a; | ||
188 | // } | ||
189 | // res = file_stat(f, &ram[a], b); | ||
190 | // POKE2(d + 0x2, res); | ||
191 | // } break; | ||
192 | // case 0x6: { | ||
193 | // // TODO: no file deletion for now | ||
194 | // // res = file_delete(); | ||
195 | // // POKE2(d + 0x2, res); | ||
196 | // } break; | ||
197 | // case 0x9: { | ||
198 | // a = PEEK2(d + 0x8); | ||
199 | // res = file_init(f, &ram[a]); | ||
200 | // POKE2(d + 0x2, res); | ||
201 | // } break; | ||
202 | // case 0xd: { | ||
203 | // a = PEEK2(d + 0xc); | ||
204 | // b = PEEK2(d + 0xa); | ||
205 | // if(b > 0x10000 - a) { | ||
206 | // b = 0x10000 - a; | ||
207 | // } | ||
208 | // res = file_read(f, &ram[a], b); | ||
209 | // POKE2(d + 0x2, res); | ||
210 | // } break; | ||
211 | // case 0xf: { | ||
212 | // a = PEEK2(d + 0xe); | ||
213 | // b = PEEK2(d + 0xa); | ||
214 | // if(b > 0x10000 - a) { | ||
215 | // b = 0x10000 - a; | ||
216 | // } | ||
217 | // res = file_write(f, &ram[a], b, d[0x7]); | ||
218 | // POKE2(d + 0x2, res); | ||
219 | // } break; | ||
220 | // } | ||
221 | } | ||
222 | |||
223 | void | ||
224 | console_deo(u8 *d, u8 port) { | ||
225 | // switch(port) { | ||
226 | // case 0x8: | ||
227 | // txt_putc(d[port]); | ||
228 | // return; | ||
229 | // case 0x9: | ||
230 | // txt_printf("ERROR: %c"); | ||
231 | // txt_putc(d[port]); | ||
232 | // return; | ||
233 | // } | ||
234 | } | ||
235 | |||
236 | #define RAM_PAGES 0x10 | ||
237 | |||
238 | static void | ||
239 | system_cmd(u8 *ram, u16 addr) { | ||
240 | if(ram[addr] == 0x01) { | ||
241 | // NOTE: Handle rom paging on a case by case basis if a rom has to be | ||
242 | // split in multiple chunks. The GBA compiler doesn't like allocating | ||
243 | // big arrays, but it's fine if we split it into chunks of 64KB, for | ||
244 | // example. | ||
245 | // | ||
246 | // u16 i, length = PEEK2(ram + addr + 1); | ||
247 | // u16 a_page = PEEK2(ram + addr + 1 + 2); | ||
248 | // u16 a_addr = PEEK2(ram + addr + 1 + 4); | ||
249 | // u16 b_addr = PEEK2(ram + addr + 1 + 8); | ||
250 | // u8 *rom = uxn_rom; | ||
251 | // for(i = 0; i < length; i++) { | ||
252 | // switch (a_page % RAM_PAGES) { | ||
253 | // case 0: { rom = uxn_rom; } break; | ||
254 | // case 1: { rom = uxn_rom_2; } break; | ||
255 | // case 2: { rom = uxn_rom_3; } break; | ||
256 | // case 3: { rom = uxn_rom_4; } break; | ||
257 | // case 4: { rom = uxn_rom_5; } break; | ||
258 | // case 5: { rom = uxn_rom_6; } break; | ||
259 | // case 6: { rom = uxn_rom_7; } break; | ||
260 | // } | ||
261 | // ram[(u16)(b_addr + i)] = rom[(u16)(a_addr + i)]; | ||
262 | // } | ||
263 | } | ||
264 | } | ||
265 | |||
266 | void | ||
267 | system_deo(Uxn *u, u8 *d, u8 port) { | ||
268 | // switch(port) { | ||
269 | // case 0x3: { | ||
270 | // system_cmd(u->ram, PEEK2(d + 2)); | ||
271 | // } break; | ||
272 | // } | ||
273 | } | ||
274 | |||
275 | u8 | ||
276 | uxn_dei(Uxn *u, u8 addr) { | ||
277 | u8 p = addr & 0x0f, d = addr & 0xf0; | ||
278 | switch(d) { | ||
279 | case 0x20: return screen_dei(&u->dev[d], p); | ||
280 | case 0x30: return audio_dei(0, &u->dev[d], p); | ||
281 | case 0x40: return audio_dei(1, &u->dev[d], p); | ||
282 | case 0x50: return audio_dei(2, &u->dev[d], p); | ||
283 | case 0x60: return audio_dei(3, &u->dev[d], p); | ||
284 | case 0xa0: return file_dei(0, &u->dev[d], p); | ||
285 | case 0xb0: return file_dei(1, &u->dev[d], p); | ||
286 | case 0xc0: return datetime_dei(&u->dev[d], p); | ||
287 | } | ||
288 | return u->dev[addr]; | ||
289 | } | ||
290 | |||
291 | void | ||
292 | uxn_deo(Uxn *u, u8 addr) { | ||
293 | u8 p = addr & 0x0f, d = addr & 0xf0; | ||
294 | switch(d) { | ||
295 | case 0x00: | ||
296 | system_deo(u, &u->dev[d], p); | ||
297 | if(p > 0x7 && p < 0xe) { | ||
298 | putcolors(&u->dev[0x8]); | ||
299 | } | ||
300 | break; | ||
301 | case 0x10: console_deo(&u->dev[d], p); break; | ||
302 | case 0x20: screen_deo(u->ram, &u->dev[d], p); break; | ||
303 | case 0x30: audio_deo(0, &u->dev[d], p, u); break; | ||
304 | case 0x40: audio_deo(1, &u->dev[d], p, u); break; | ||
305 | case 0x50: audio_deo(2, &u->dev[d], p, u); break; | ||
306 | case 0x60: audio_deo(3, &u->dev[d], p, u); break; | ||
307 | case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break; | ||
308 | case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break; | ||
309 | } | ||
310 | } | ||
311 | |||
312 | IWRAM_CODE | ||
313 | void | ||
314 | handle_input(Uxn *u) { | ||
315 | // poll_keys(); | ||
316 | // if (key_tap(KEY_SELECT)) { | ||
317 | // // Reset control variables on method switch. | ||
318 | // switch (ctrl_methods[ctrl_idx]) { | ||
319 | // case CONTROL_CONTROLLER: { | ||
320 | // u8 *d = &u->dev[0x80]; | ||
321 | // d[2] = 0; | ||
322 | // uxn_eval(u, PEEK2(d)); | ||
323 | // d[3] = 0; | ||
324 | // } break; | ||
325 | // case CONTROL_MOUSE: { | ||
326 | // u8 *d = &u->dev[0x90]; | ||
327 | // d[6] = 0; | ||
328 | // d[7] = 0; | ||
329 | // POKE2(d + 0x2, -10); | ||
330 | // POKE2(d + 0x4, -10); | ||
331 | // uxn_eval(u, PEEK2(d)); | ||
332 | // } break; | ||
333 | // case CONTROL_KEYBOARD: { | ||
334 | // toggle_keyboard(); | ||
335 | // } break; | ||
336 | // } | ||
337 | |||
338 | // // Update ctrl_idx. | ||
339 | // ctrl_idx = (ctrl_idx + 1 > (int)LEN(ctrl_methods) - 1) ? 0 : ctrl_idx + 1; | ||
340 | |||
341 | // // Initialize controller variables here. | ||
342 | // if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { | ||
343 | // toggle_keyboard(); | ||
344 | // } | ||
345 | // } | ||
346 | |||
347 | // if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) { | ||
348 | // u8 *d = &u->dev[0x80]; | ||
349 | // // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just | ||
350 | // // swap some things if needed. | ||
351 | // u8 *flag = &d[2]; | ||
352 | // if (key_tap(KEY_A)) { | ||
353 | // *flag |= 0x01; | ||
354 | // } else { | ||
355 | // *flag &= ~0x01; | ||
356 | // } | ||
357 | // if (key_tap(KEY_B)) { | ||
358 | // *flag |= 0x02; | ||
359 | // } else { | ||
360 | // *flag &= ~0x02; | ||
361 | // } | ||
362 | // if (key_tap(KEY_L)) { | ||
363 | // *flag |= 0x04; | ||
364 | // } else { | ||
365 | // *flag &= ~0x04; | ||
366 | // } | ||
367 | // if (key_tap(KEY_R)) { | ||
368 | // *flag |= 0x08; | ||
369 | // } else { | ||
370 | // *flag &= ~0x08; | ||
371 | // } | ||
372 | // if (key_tap(KEY_UP)) { | ||
373 | // *flag |= 0x10; | ||
374 | // } else { | ||
375 | // *flag &= ~0x10; | ||
376 | // } | ||
377 | // if (key_tap(KEY_DOWN)) { | ||
378 | // *flag |= 0x20; | ||
379 | // } else { | ||
380 | // *flag &= ~0x20; | ||
381 | // } | ||
382 | // if (key_tap(KEY_LEFT)) { | ||
383 | // *flag |= 0x40; | ||
384 | // } else { | ||
385 | // *flag &= ~0x40; | ||
386 | // } | ||
387 | // if (key_tap(KEY_RIGHT)) { | ||
388 | // *flag |= 0x80; | ||
389 | // } else { | ||
390 | // *flag &= ~0x80; | ||
391 | // } | ||
392 | |||
393 | // if (key_prev != key_curr) { | ||
394 | // uxn_eval(u, PEEK2(d)); | ||
395 | // } | ||
396 | // d[3] = 0; | ||
397 | // } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) { | ||
398 | // u8 *d = &u->dev[0x90]; | ||
399 | // // Detect "mouse key press". | ||
400 | // u8 flag = d[6]; | ||
401 | // bool event = false; | ||
402 | // if (key_tap(KEY_B)) { | ||
403 | // event = true; | ||
404 | // flag |= 0x01; | ||
405 | // } else if (key_released(KEY_B)) { | ||
406 | // event = true; | ||
407 | // flag &= ~0x01; | ||
408 | // } | ||
409 | // if (key_tap(KEY_A)) { | ||
410 | // event = true; | ||
411 | // flag |= 0x10; | ||
412 | // } else if (key_released(KEY_A)) { | ||
413 | // event = true; | ||
414 | // flag &= ~0x10; | ||
415 | // } | ||
416 | |||
417 | // // Handle chording. | ||
418 | // d[6] = flag; | ||
419 | // if(flag == 0x10 && (d[6] & 0x01)) { | ||
420 | // d[7] = 0x01; | ||
421 | // } | ||
422 | // if(flag == 0x01 && (d[6] & 0x10)) { | ||
423 | // d[7] = 0x10; | ||
424 | // } | ||
425 | |||
426 | // // Detect mouse movement. | ||
427 | // if (key_pressed(KEY_UP)) { | ||
428 | // event = true; | ||
429 | // mouse.y = CLAMP(mouse.y - MOUSE_DELTA, 0, SCREEN_HEIGHT - 8); | ||
430 | // } else if (key_pressed(KEY_DOWN)) { | ||
431 | // event = true; | ||
432 | // mouse.y = CLAMP(mouse.y + MOUSE_DELTA, 0, SCREEN_HEIGHT - 8); | ||
433 | // } | ||
434 | // if (key_pressed(KEY_LEFT)) { | ||
435 | // event = true; | ||
436 | // mouse.x = CLAMP(mouse.x - MOUSE_DELTA, 0, SCREEN_WIDTH - 8); | ||
437 | // } else if (key_pressed(KEY_RIGHT)) { | ||
438 | // event = true; | ||
439 | // mouse.x = CLAMP(mouse.x + MOUSE_DELTA, 0, SCREEN_WIDTH - 8); | ||
440 | // } | ||
441 | |||
442 | // // Eval mouse. | ||
443 | // POKE2(d + 0x2, mouse.x); | ||
444 | // POKE2(d + 0x4, mouse.y); | ||
445 | // if (event) { | ||
446 | // uxn_eval(u, PEEK2(d)); | ||
447 | // } | ||
448 | // } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { | ||
449 | // u8 *d = &u->dev[0x80]; | ||
450 | // if (key_tap(KEY_LEFT)) { | ||
451 | // update_cursor(cursor_position - 1); | ||
452 | // } else if (key_tap(KEY_RIGHT)) { | ||
453 | // update_cursor(cursor_position + 1); | ||
454 | // } | ||
455 | // if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) { | ||
456 | // update_cursor(cursor_position - KEYBOARD_ROW_SIZE); | ||
457 | // } else if (key_tap(KEY_DOWN) | ||
458 | // && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) { | ||
459 | // update_cursor(cursor_position + KEYBOARD_ROW_SIZE); | ||
460 | // } | ||
461 | // if (key_tap(KEY_B)) { | ||
462 | // u8 symbol = keyboard[cursor_position].symbol; | ||
463 | // switch (symbol) { | ||
464 | // case 0x7f: { | ||
465 | // // Backspace. | ||
466 | // d[3] = 0x08; | ||
467 | // } break; | ||
468 | // case 0x14: { | ||
469 | // // New line. | ||
470 | // d[3] = 0x0d; | ||
471 | // } break; | ||
472 | // case 0x18: { | ||
473 | // // Arrow up. | ||
474 | // d[2] = 0x10; | ||
475 | // } break; | ||
476 | // case 0x19: { | ||
477 | // // Arrow down. | ||
478 | // d[2] = 0x20; | ||
479 | // } break; | ||
480 | // case 0x1b: { | ||
481 | // // Arrow left. | ||
482 | // d[2] = 0x40; | ||
483 | // } break; | ||
484 | // case 0x1a: { | ||
485 | // // Arrow right. | ||
486 | // d[2] = 0x80; | ||
487 | // } break; | ||
488 | // default: { | ||
489 | // d[3] = symbol; | ||
490 | // } break; | ||
491 | // } | ||
492 | // uxn_eval(u, PEEK2(d)); | ||
493 | // d[3] = 0; | ||
494 | // } | ||
495 | // } | ||
496 | } | ||
497 | |||
@@ -15,499 +15,31 @@ | |||
15 | #include "common.h" | 15 | #include "common.h" |
16 | #include "filesystem.c" | 16 | #include "filesystem.c" |
17 | 17 | ||
18 | #include "uxn.h" | 18 | #include "uxn.c" |
19 | #include "ppu.c" | 19 | #include "ppu.c" |
20 | #include "apu.c" | 20 | #include "apu.c" |
21 | #include "file.c" | 21 | #include "file.c" |
22 | #include "text.h" | 22 | #include "text.h" |
23 | 23 | ||
24 | #include "rom.c" | 24 | #include "rom.c" |
25 | #include "config.c" | ||
26 | #include "profiling.c" | ||
27 | #include "devices.c" | ||
25 | 28 | ||
26 | // | 29 | #define STACK_SIZE 16 |
27 | // Config parameters. | 30 | u8 stack[STACK_SIZE] = {0}; |
28 | // | 31 | extern void uxn_eval_asm(u16 pc); |
29 | |||
30 | #if !defined(TEXT_MODE) || TEXT_MODE == 0 | ||
31 | #define TEXT_LAYER FG_BACK | ||
32 | #else | ||
33 | #define TEXT_LAYER BG_BACK | ||
34 | #endif | ||
35 | |||
36 | #ifndef CONTROL_METHODS | ||
37 | #define CONTROL_METHODS CONTROL_CONTROLLER,CONTROL_MOUSE,CONTROL_KEYBOARD | ||
38 | #endif | ||
39 | |||
40 | #define PROF_ENABLE 0 | ||
41 | #ifndef PROF_ENABLE | ||
42 | #define PROF_ENABLE 0 | ||
43 | #endif | ||
44 | |||
45 | #if PROF_ENABLE > 0 && PROF_ENABLE < 3 | ||
46 | |||
47 | #ifndef PROF_N_FRAMES | ||
48 | #define PROF_N_FRAMES 15 | ||
49 | #endif | ||
50 | |||
51 | // Profile method 1: Average per N frames. | ||
52 | #if PROF_ENABLE == 1 | ||
53 | #define TEXT_ENABLE 1 | ||
54 | #define PROF(F,VAR) \ | ||
55 | do { \ | ||
56 | u32 __tmp_prof = profile_measure();\ | ||
57 | (F);\ | ||
58 | (VAR) += profile_measure() - __tmp_prof;\ | ||
59 | } while (0) | ||
60 | |||
61 | // Profile method 2: Maximum in N frames. | ||
62 | #elif PROF_ENABLE == 2 | ||
63 | #define TEXT_ENABLE 1 | ||
64 | #define PROF(F,VAR) \ | ||
65 | do { \ | ||
66 | u32 __tmp_prof = profile_measure();\ | ||
67 | (F);\ | ||
68 | (VAR) = MAX(profile_measure() - __tmp_prof, (VAR));\ | ||
69 | } while (0) | ||
70 | #endif | ||
71 | |||
72 | #ifndef PROF_SHOW_X | ||
73 | #define PROF_SHOW_X 0 | ||
74 | #endif | ||
75 | #ifndef PROF_SHOW_Y | ||
76 | #define PROF_SHOW_Y 0 | ||
77 | #endif | ||
78 | |||
79 | #define PROF_SHOW() \ | ||
80 | do { \ | ||
81 | txt_position((PROF_SHOW_X), (PROF_SHOW_Y));\ | ||
82 | txt_printf("INPUT %.8lu\n", avg_input_cycles);\ | ||
83 | txt_printf("EVAL %.8lu\n", avg_eval_cycles);\ | ||
84 | txt_printf("VIDEO\n");\ | ||
85 | txt_printf(">PIX %.8lu\n", avg_ppu_pixel_cycles);\ | ||
86 | txt_printf(">FILL %.8lu\n", avg_ppu_fill_cycles);\ | ||
87 | txt_printf(">1BPP %.8lu\n", avg_ppu_icn_cycles);\ | ||
88 | txt_printf(">2BPP %.8lu\n", avg_ppu_chr_cycles);\ | ||
89 | txt_printf(">FLIP %.8lu\n", avg_flip_cycles);\ | ||
90 | txt_printf("AUDIO %.8lu\n", avg_mix_cycles);\ | ||
91 | txt_printf("TOTAL %.8lu\n", avg_frame_cycles);\ | ||
92 | u32 frame_time =\ | ||
93 | FP_DIV(\ | ||
94 | FP_NUM(avg_frame_cycles + 1, 2),\ | ||
95 | FP_NUM(2809, 2),\ | ||
96 | 2) * 166;\ | ||
97 | u32 fps =\ | ||
98 | FP_DIV(\ | ||
99 | FP_NUM(280896 * 60, 2),\ | ||
100 | FP_NUM(avg_frame_cycles + 1, 2),\ | ||
101 | 2);\ | ||
102 | txt_printf("TIME %.8lu\n", frame_time >> 2);\ | ||
103 | txt_printf("FPS %.8lu\n", (fps >> 2) + 1);\ | ||
104 | screen_fill(BG_BACK, 0, 0, 8 * 16, 8 * 12, 2);\ | ||
105 | } while (0) | ||
106 | |||
107 | static u32 prof_frame_counter = 0; | ||
108 | |||
109 | static u32 frame_cycles = 0; | ||
110 | static u32 ppu_pixel_cycles = 0; | ||
111 | static u32 ppu_fill_cycles = 0; | ||
112 | static u32 ppu_chr_cycles = 0; | ||
113 | static u32 ppu_icn_cycles = 0; | ||
114 | static u32 flip_cycles = 0; | ||
115 | static u32 eval_cycles = 0; | ||
116 | static u32 input_cycles = 0; | ||
117 | static u32 mix_cycles = 0; | ||
118 | |||
119 | static u32 avg_ppu_pixel_cycles = 0; | ||
120 | static u32 avg_ppu_fill_cycles = 0; | ||
121 | static u32 avg_ppu_chr_cycles = 0; | ||
122 | static u32 avg_ppu_icn_cycles = 0; | ||
123 | static u32 avg_flip_cycles = 0; | ||
124 | static u32 avg_eval_cycles = 0; | ||
125 | static u32 avg_input_cycles = 0; | ||
126 | static u32 avg_mix_cycles = 0; | ||
127 | static u32 avg_frame_cycles = 0; | ||
128 | |||
129 | #if PROF_ENABLE == 1 | ||
130 | #define FRAME_START()\ | ||
131 | do { \ | ||
132 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
133 | avg_ppu_pixel_cycles = ppu_pixel_cycles / prof_frame_counter;\ | ||
134 | avg_ppu_fill_cycles = ppu_fill_cycles / prof_frame_counter;\ | ||
135 | avg_ppu_chr_cycles = ppu_chr_cycles / prof_frame_counter;\ | ||
136 | avg_ppu_icn_cycles = ppu_icn_cycles / prof_frame_counter;\ | ||
137 | avg_flip_cycles = flip_cycles / prof_frame_counter;\ | ||
138 | avg_eval_cycles = eval_cycles / prof_frame_counter;\ | ||
139 | avg_input_cycles = input_cycles / prof_frame_counter;\ | ||
140 | avg_mix_cycles = mix_cycles / prof_frame_counter;\ | ||
141 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ | ||
142 | prof_frame_counter = 0;\ | ||
143 | frame_cycles = 0;\ | ||
144 | ppu_pixel_cycles = 0;\ | ||
145 | ppu_fill_cycles = 0;\ | ||
146 | ppu_chr_cycles = 0;\ | ||
147 | ppu_icn_cycles = 0;\ | ||
148 | flip_cycles = 0;\ | ||
149 | eval_cycles = 0;\ | ||
150 | input_cycles = 0;\ | ||
151 | mix_cycles = 0;\ | ||
152 | }\ | ||
153 | profile_start();\ | ||
154 | } while (0) | ||
155 | #elif PROF_ENABLE == 2 | ||
156 | #define FRAME_START()\ | ||
157 | do { \ | ||
158 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
159 | avg_ppu_pixel_cycles = ppu_pixel_cycles;\ | ||
160 | avg_ppu_fill_cycles = ppu_fill_cycles;\ | ||
161 | avg_ppu_chr_cycles = ppu_chr_cycles;\ | ||
162 | avg_ppu_icn_cycles = ppu_icn_cycles;\ | ||
163 | avg_flip_cycles = flip_cycles;\ | ||
164 | avg_eval_cycles = eval_cycles;\ | ||
165 | avg_input_cycles = input_cycles;\ | ||
166 | avg_mix_cycles = mix_cycles;\ | ||
167 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ | ||
168 | prof_frame_counter = 0;\ | ||
169 | frame_cycles = 0;\ | ||
170 | ppu_pixel_cycles = 0;\ | ||
171 | ppu_fill_cycles = 0;\ | ||
172 | ppu_chr_cycles = 0;\ | ||
173 | ppu_icn_cycles = 0;\ | ||
174 | flip_cycles = 0;\ | ||
175 | eval_cycles = 0;\ | ||
176 | input_cycles = 0;\ | ||
177 | mix_cycles = 0;\ | ||
178 | }\ | ||
179 | profile_start();\ | ||
180 | } while (0) | ||
181 | #endif | ||
182 | |||
183 | #define FRAME_END() \ | ||
184 | do { \ | ||
185 | prof_frame_counter++;\ | ||
186 | frame_cycles += profile_stop();\ | ||
187 | } while (0) | ||
188 | |||
189 | #else | ||
190 | |||
191 | // No profiling. | ||
192 | #define PROF(F,VAR) (F) | ||
193 | #define PROF_SHOW() | ||
194 | #define FRAME_START() | ||
195 | #define FRAME_END() | ||
196 | #endif | ||
197 | |||
198 | static time_t seconds = 0; | ||
199 | |||
200 | typedef enum { | ||
201 | CONTROL_CONTROLLER, | ||
202 | CONTROL_MOUSE, | ||
203 | CONTROL_KEYBOARD, | ||
204 | } ControlMethod; | ||
205 | |||
206 | const ControlMethod ctrl_methods[] = { | ||
207 | CONTROL_METHODS | ||
208 | }; | ||
209 | static ControlMethod ctrl_idx = 0; | ||
210 | 32 | ||
211 | #define MOUSE_DELTA 1 | 33 | // TODO: This should be on the IWRAM for maximum speed, as these are operations |
212 | typedef struct Mouse { | 34 | // we will use very often. |
213 | int x; | 35 | extern u8 wst[256]; |
214 | int y; | 36 | extern u8 rst[256]; |
215 | } Mouse; | 37 | extern u8 io_ports[256]; |
38 | extern uintptr_t wst_ptr; | ||
39 | extern uintptr_t rst_ptr; | ||
216 | 40 | ||
217 | EWRAM_BSS | 41 | EWRAM_BSS |
218 | u8 uxn_ram[0x10300]; | 42 | u8 uxn_ram[KB(64) * 2]; |
219 | |||
220 | // static Uxn u; | ||
221 | |||
222 | static Mouse mouse = {SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2}; | ||
223 | |||
224 | // int | ||
225 | // uxn_halt(Uxn *u, u8 instr, u8 err, u16 addr) { | ||
226 | // (void)u; | ||
227 | // txt_printf("HALTED\n"); | ||
228 | // txt_printf("I: %lu\n", instr); | ||
229 | // txt_printf("E: %lu\n", err); | ||
230 | // txt_printf("A: %lu\n", addr); | ||
231 | // while (true); | ||
232 | // } | ||
233 | |||
234 | IWRAM_CODE | ||
235 | u8 | ||
236 | screen_dei(u8 *d, u8 port) { | ||
237 | // switch(port) { | ||
238 | // case 0x2: return (SCREEN_WIDTH >> 8); | ||
239 | // case 0x3: return (SCREEN_WIDTH); | ||
240 | // case 0x4: return (SCREEN_HEIGHT >> 8); | ||
241 | // case 0x5: return (SCREEN_HEIGHT); | ||
242 | // default: return d[port]; | ||
243 | // } | ||
244 | } | ||
245 | |||
246 | IWRAM_CODE | ||
247 | void | ||
248 | screen_deo(u8 *ram, u8 *d, u8 port) { | ||
249 | // switch(port) { | ||
250 | // case 0xe: { | ||
251 | // u8 ctrl = d[0xe]; | ||
252 | // u8 color = ctrl & 0x3; | ||
253 | // u16 x0 = PEEK2(d + 0x8); | ||
254 | // u16 y0 = PEEK2(d + 0xa); | ||
255 | // u8 *layer = (ctrl & 0x40) ? FG_BACK : BG_BACK; | ||
256 | // if(ctrl & 0x80) { | ||
257 | // u16 x1 = SCREEN_WIDTH - 1; | ||
258 | // u16 y1 = SCREEN_HEIGHT - 1; | ||
259 | // if(ctrl & 0x10) x1 = x0, x0 = 0; | ||
260 | // if(ctrl & 0x20) y1 = y0, y0 = 0; | ||
261 | // PROF(screen_fill(layer, x0, y0, x1, y1, color), ppu_fill_cycles); | ||
262 | // } else { | ||
263 | // PROF(ppu_pixel(layer, x0, y0, color), ppu_pixel_cycles); | ||
264 | // if(d[0x6] & 0x1) POKE2(d + 0x8, x0 + 1); /* auto x+1 */ | ||
265 | // if(d[0x6] & 0x2) POKE2(d + 0xa, y0 + 1); /* auto y+1 */ | ||
266 | // } | ||
267 | // break; | ||
268 | // } | ||
269 | // case 0xf: { | ||
270 | // u16 x, y, dx, dy, addr; | ||
271 | // u8 n, twobpp = !!(d[0xf] & 0x80); | ||
272 | // x = PEEK2(d + 0x8); | ||
273 | // y = PEEK2(d + 0xa); | ||
274 | // addr = PEEK2(d + 0xc); | ||
275 | // n = d[0x6] >> 4; | ||
276 | // dx = (d[0x6] & 0x01) << 3; | ||
277 | // dy = (d[0x6] & 0x02) << 2; | ||
278 | // if(addr > 0x10000 - ((n + 1) << (3 + twobpp))) { | ||
279 | // return; | ||
280 | // } | ||
281 | // u8 *layer = (d[0xf] & 0x40) ? FG_BACK : BG_BACK; | ||
282 | // u8 color = d[0xf] & 0xf; | ||
283 | // u8 flipx = d[0xf] & 0x10; | ||
284 | // u8 flipy = d[0xf] & 0x20; | ||
285 | // for(size_t i = 0; i <= n; i++) { | ||
286 | // u8 *sprite = &ram[addr]; | ||
287 | // if (twobpp) { | ||
288 | // PROF(ppu_2bpp(layer, | ||
289 | // x + dy * i, | ||
290 | // y + dx * i, | ||
291 | // sprite, | ||
292 | // color, | ||
293 | // flipx, flipy), ppu_chr_cycles); | ||
294 | // } else { | ||
295 | // PROF(ppu_1bpp(layer, | ||
296 | // x + dy * i, | ||
297 | // y + dx * i, | ||
298 | // sprite, | ||
299 | // color, | ||
300 | // flipx, flipy), ppu_icn_cycles); | ||
301 | // } | ||
302 | // addr += (d[0x6] & 0x04) << (1 + twobpp); | ||
303 | // } | ||
304 | // POKE2(d + 0xc, addr); /* auto addr+length */ | ||
305 | // POKE2(d + 0x8, x + dx); /* auto x+8 */ | ||
306 | // POKE2(d + 0xa, y + dy); /* auto y+8 */ | ||
307 | // break; | ||
308 | // } | ||
309 | // } | ||
310 | } | ||
311 | |||
312 | u8 | ||
313 | audio_dei(int instance, u8 *d, u8 port) { | ||
314 | // AudioChannel *c = &channels[instance]; | ||
315 | // switch(port) { | ||
316 | // // case 0x4: return apu_get_vu(instance); | ||
317 | // case 0x2: { | ||
318 | // POKE2(d + 0x2, c->pos); | ||
319 | // c->pos <<= 12; // fixed point. | ||
320 | // break; | ||
321 | // } | ||
322 | // } | ||
323 | return d[port]; | ||
324 | } | ||
325 | |||
326 | void | ||
327 | audio_deo(int instance, u8 *d, u8 port, Uxn *u) { | ||
328 | // AudioChannel *c = &channels[instance]; | ||
329 | // if (port == 0xf) { | ||
330 | // u16 length = 0; | ||
331 | // u16 adsr = 0; | ||
332 | // u16 addr = 0; | ||
333 | // u8 pitch = d[0xf] & 0x7f; | ||
334 | // adsr = PEEK2(d + 0x8); | ||
335 | // length = PEEK2(d + 0xa); | ||
336 | // addr = PEEK2(d + 0xc); | ||
337 | // u8 *data = &u->ram[addr]; | ||
338 | // u32 vol = MAX(d[0xe] >> 4, d[0xe] & 0xf) * 4 / 3; | ||
339 | // bool loop = !(d[0xf] & 0x80); | ||
340 | // update_channel(c, data, length, pitch, adsr, vol, loop); | ||
341 | // } | ||
342 | } | ||
343 | |||
344 | u8 | ||
345 | datetime_dei(u8 *d, u8 port) { | ||
346 | struct tm *t = gmtime(&seconds); | ||
347 | switch(port) { | ||
348 | case 0x0: return (t->tm_year + 1900) >> 8; | ||
349 | case 0x1: return (t->tm_year + 1900); | ||
350 | case 0x2: return t->tm_mon; | ||
351 | case 0x3: return t->tm_mday; | ||
352 | case 0x4: return t->tm_hour; | ||
353 | case 0x5: return t->tm_min; | ||
354 | case 0x6: return t->tm_sec; | ||
355 | case 0x7: return t->tm_wday; | ||
356 | case 0x8: return t->tm_yday >> 8; | ||
357 | case 0x9: return t->tm_yday; | ||
358 | case 0xa: return t->tm_isdst; | ||
359 | default: return d[port]; | ||
360 | } | ||
361 | } | ||
362 | |||
363 | u8 | ||
364 | file_dei(u8 id, u8 *d, u8 port) { | ||
365 | // UxnFile *c = &uxn_file[id]; | ||
366 | // u16 res; | ||
367 | // switch(port) { | ||
368 | // case 0xc: | ||
369 | // case 0xd: { | ||
370 | // res = file_read(c, &d[port], 1); | ||
371 | // POKE2(d + 0x2, res); | ||
372 | // break; | ||
373 | // } | ||
374 | // } | ||
375 | return d[port]; | ||
376 | } | ||
377 | |||
378 | void | ||
379 | file_deo(u8 id, u8 *ram, u8 *d, u8 port) { | ||
380 | // u16 a, b, res; | ||
381 | // UxnFile *f = &uxn_file[id]; | ||
382 | // switch(port) { | ||
383 | // case 0x5: { | ||
384 | // a = PEEK2(d + 0x4); | ||
385 | // b = PEEK2(d + 0xa); | ||
386 | // if(b > 0x10000 - a) { | ||
387 | // b = 0x10000 - a; | ||
388 | // } | ||
389 | // res = file_stat(f, &ram[a], b); | ||
390 | // POKE2(d + 0x2, res); | ||
391 | // } break; | ||
392 | // case 0x6: { | ||
393 | // // TODO: no file deletion for now | ||
394 | // // res = file_delete(); | ||
395 | // // POKE2(d + 0x2, res); | ||
396 | // } break; | ||
397 | // case 0x9: { | ||
398 | // a = PEEK2(d + 0x8); | ||
399 | // res = file_init(f, &ram[a]); | ||
400 | // POKE2(d + 0x2, res); | ||
401 | // } break; | ||
402 | // case 0xd: { | ||
403 | // a = PEEK2(d + 0xc); | ||
404 | // b = PEEK2(d + 0xa); | ||
405 | // if(b > 0x10000 - a) { | ||
406 | // b = 0x10000 - a; | ||
407 | // } | ||
408 | // res = file_read(f, &ram[a], b); | ||
409 | // POKE2(d + 0x2, res); | ||
410 | // } break; | ||
411 | // case 0xf: { | ||
412 | // a = PEEK2(d + 0xe); | ||
413 | // b = PEEK2(d + 0xa); | ||
414 | // if(b > 0x10000 - a) { | ||
415 | // b = 0x10000 - a; | ||
416 | // } | ||
417 | // res = file_write(f, &ram[a], b, d[0x7]); | ||
418 | // POKE2(d + 0x2, res); | ||
419 | // } break; | ||
420 | // } | ||
421 | } | ||
422 | |||
423 | void | ||
424 | console_deo(u8 *d, u8 port) { | ||
425 | // switch(port) { | ||
426 | // case 0x8: | ||
427 | // txt_putc(d[port]); | ||
428 | // return; | ||
429 | // case 0x9: | ||
430 | // txt_printf("ERROR: %c"); | ||
431 | // txt_putc(d[port]); | ||
432 | // return; | ||
433 | // } | ||
434 | } | ||
435 | |||
436 | #define RAM_PAGES 0x10 | ||
437 | |||
438 | static void | ||
439 | system_cmd(u8 *ram, u16 addr) { | ||
440 | if(ram[addr] == 0x01) { | ||
441 | // NOTE: Handle rom paging on a case by case basis if a rom has to be | ||
442 | // split in multiple chunks. The GBA compiler doesn't like allocating | ||
443 | // big arrays, but it's fine if we split it into chunks of 64KB, for | ||
444 | // example. | ||
445 | // | ||
446 | // u16 i, length = PEEK2(ram + addr + 1); | ||
447 | // u16 a_page = PEEK2(ram + addr + 1 + 2); | ||
448 | // u16 a_addr = PEEK2(ram + addr + 1 + 4); | ||
449 | // u16 b_addr = PEEK2(ram + addr + 1 + 8); | ||
450 | // u8 *rom = uxn_rom; | ||
451 | // for(i = 0; i < length; i++) { | ||
452 | // switch (a_page % RAM_PAGES) { | ||
453 | // case 0: { rom = uxn_rom; } break; | ||
454 | // case 1: { rom = uxn_rom_2; } break; | ||
455 | // case 2: { rom = uxn_rom_3; } break; | ||
456 | // case 3: { rom = uxn_rom_4; } break; | ||
457 | // case 4: { rom = uxn_rom_5; } break; | ||
458 | // case 5: { rom = uxn_rom_6; } break; | ||
459 | // case 6: { rom = uxn_rom_7; } break; | ||
460 | // } | ||
461 | // ram[(u16)(b_addr + i)] = rom[(u16)(a_addr + i)]; | ||
462 | // } | ||
463 | } | ||
464 | } | ||
465 | |||
466 | void | ||
467 | system_deo(Uxn *u, u8 *d, u8 port) { | ||
468 | // switch(port) { | ||
469 | // case 0x3: { | ||
470 | // system_cmd(u->ram, PEEK2(d + 2)); | ||
471 | // } break; | ||
472 | // } | ||
473 | } | ||
474 | |||
475 | u8 | ||
476 | uxn_dei(Uxn *u, u8 addr) { | ||
477 | u8 p = addr & 0x0f, d = addr & 0xf0; | ||
478 | switch(d) { | ||
479 | case 0x20: return screen_dei(&u->dev[d], p); | ||
480 | case 0x30: return audio_dei(0, &u->dev[d], p); | ||
481 | case 0x40: return audio_dei(1, &u->dev[d], p); | ||
482 | case 0x50: return audio_dei(2, &u->dev[d], p); | ||
483 | case 0x60: return audio_dei(3, &u->dev[d], p); | ||
484 | case 0xa0: return file_dei(0, &u->dev[d], p); | ||
485 | case 0xb0: return file_dei(1, &u->dev[d], p); | ||
486 | case 0xc0: return datetime_dei(&u->dev[d], p); | ||
487 | } | ||
488 | return u->dev[addr]; | ||
489 | } | ||
490 | |||
491 | void | ||
492 | uxn_deo(Uxn *u, u8 addr) { | ||
493 | u8 p = addr & 0x0f, d = addr & 0xf0; | ||
494 | switch(d) { | ||
495 | case 0x00: | ||
496 | system_deo(u, &u->dev[d], p); | ||
497 | if(p > 0x7 && p < 0xe) { | ||
498 | putcolors(&u->dev[0x8]); | ||
499 | } | ||
500 | break; | ||
501 | case 0x10: console_deo(&u->dev[d], p); break; | ||
502 | case 0x20: screen_deo(u->ram, &u->dev[d], p); break; | ||
503 | case 0x30: audio_deo(0, &u->dev[d], p, u); break; | ||
504 | case 0x40: audio_deo(1, &u->dev[d], p, u); break; | ||
505 | case 0x50: audio_deo(2, &u->dev[d], p, u); break; | ||
506 | case 0x60: audio_deo(3, &u->dev[d], p, u); break; | ||
507 | case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break; | ||
508 | case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break; | ||
509 | } | ||
510 | } | ||
511 | 43 | ||
512 | void | 44 | void |
513 | init_uxn() { | 45 | init_uxn() { |
@@ -532,8 +64,9 @@ init_uxn() { | |||
532 | // #0004 #0008 ADD | 64 | // #0004 #0008 ADD |
533 | // 0xa0, 0x00, 0x04, 0xa0, 0x00, 0x08, 0x18, | 65 | // 0xa0, 0x00, 0x04, 0xa0, 0x00, 0x08, 0x18, |
534 | // #0004 #0008 ADD2 | 66 | // #0004 #0008 ADD2 |
535 | 0x80, 0xFF, 0xff, | 67 | // 0x80, 0xFF, 0xff, |
536 | 0xa0, 0x00, 0x08, 0xa0, 0x00, 0x04, 0x38, | 68 | // 0xa0, 0x00, 0x08, 0xa0, 0x00, 0x04, 0x38, |
69 | // 0xa0, 0x00, 0x08, 0xa0, 0x00, 0x04, 0x38, | ||
537 | // 0xa0, 0x00, 0x08, 0xa0, 0x00, 0x03, 0x39, | 70 | // 0xa0, 0x00, 0x08, 0xa0, 0x00, 0x03, 0x39, |
538 | // 0xa0, 0x00, 0x01, 0x38, | 71 | // 0xa0, 0x00, 0x01, 0x38, |
539 | // | 72 | // |
@@ -553,204 +86,6 @@ init_uxn() { | |||
553 | memcpy(uxn_ram + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); | 86 | memcpy(uxn_ram + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); |
554 | } | 87 | } |
555 | 88 | ||
556 | IWRAM_CODE | ||
557 | void | ||
558 | handle_input(Uxn *u) { | ||
559 | // poll_keys(); | ||
560 | // if (key_tap(KEY_SELECT)) { | ||
561 | // // Reset control variables on method switch. | ||
562 | // switch (ctrl_methods[ctrl_idx]) { | ||
563 | // case CONTROL_CONTROLLER: { | ||
564 | // u8 *d = &u->dev[0x80]; | ||
565 | // d[2] = 0; | ||
566 | // uxn_eval(u, PEEK2(d)); | ||
567 | // d[3] = 0; | ||
568 | // } break; | ||
569 | // case CONTROL_MOUSE: { | ||
570 | // u8 *d = &u->dev[0x90]; | ||
571 | // d[6] = 0; | ||
572 | // d[7] = 0; | ||
573 | // POKE2(d + 0x2, -10); | ||
574 | // POKE2(d + 0x4, -10); | ||
575 | // uxn_eval(u, PEEK2(d)); | ||
576 | // } break; | ||
577 | // case CONTROL_KEYBOARD: { | ||
578 | // toggle_keyboard(); | ||
579 | // } break; | ||
580 | // } | ||
581 | |||
582 | // // Update ctrl_idx. | ||
583 | // ctrl_idx = (ctrl_idx + 1 > (int)LEN(ctrl_methods) - 1) ? 0 : ctrl_idx + 1; | ||
584 | |||
585 | // // Initialize controller variables here. | ||
586 | // if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { | ||
587 | // toggle_keyboard(); | ||
588 | // } | ||
589 | // } | ||
590 | |||
591 | // if (ctrl_methods[ctrl_idx] == CONTROL_CONTROLLER) { | ||
592 | // u8 *d = &u->dev[0x80]; | ||
593 | // // TODO: We don't need ifs if we use KEY_INPUTS directly and maybe just | ||
594 | // // swap some things if needed. | ||
595 | // u8 *flag = &d[2]; | ||
596 | // if (key_tap(KEY_A)) { | ||
597 | // *flag |= 0x01; | ||
598 | // } else { | ||
599 | // *flag &= ~0x01; | ||
600 | // } | ||
601 | // if (key_tap(KEY_B)) { | ||
602 | // *flag |= 0x02; | ||
603 | // } else { | ||
604 | // *flag &= ~0x02; | ||
605 | // } | ||
606 | // if (key_tap(KEY_L)) { | ||
607 | // *flag |= 0x04; | ||
608 | // } else { | ||
609 | // *flag &= ~0x04; | ||
610 | // } | ||
611 | // if (key_tap(KEY_R)) { | ||
612 | // *flag |= 0x08; | ||
613 | // } else { | ||
614 | // *flag &= ~0x08; | ||
615 | // } | ||
616 | // if (key_tap(KEY_UP)) { | ||
617 | // *flag |= 0x10; | ||
618 | // } else { | ||
619 | // *flag &= ~0x10; | ||
620 | // } | ||
621 | // if (key_tap(KEY_DOWN)) { | ||
622 | // *flag |= 0x20; | ||
623 | // } else { | ||
624 | // *flag &= ~0x20; | ||
625 | // } | ||
626 | // if (key_tap(KEY_LEFT)) { | ||
627 | // *flag |= 0x40; | ||
628 | // } else { | ||
629 | // *flag &= ~0x40; | ||
630 | // } | ||
631 | // if (key_tap(KEY_RIGHT)) { | ||
632 | // *flag |= 0x80; | ||
633 | // } else { | ||
634 | // *flag &= ~0x80; | ||
635 | // } | ||
636 | |||
637 | // if (key_prev != key_curr) { | ||
638 | // uxn_eval(u, PEEK2(d)); | ||
639 | // } | ||
640 | // d[3] = 0; | ||
641 | // } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) { | ||
642 | // u8 *d = &u->dev[0x90]; | ||
643 | // // Detect "mouse key press". | ||
644 | // u8 flag = d[6]; | ||
645 | // bool event = false; | ||
646 | // if (key_tap(KEY_B)) { | ||
647 | // event = true; | ||
648 | // flag |= 0x01; | ||
649 | // } else if (key_released(KEY_B)) { | ||
650 | // event = true; | ||
651 | // flag &= ~0x01; | ||
652 | // } | ||
653 | // if (key_tap(KEY_A)) { | ||
654 | // event = true; | ||
655 | // flag |= 0x10; | ||
656 | // } else if (key_released(KEY_A)) { | ||
657 | // event = true; | ||
658 | // flag &= ~0x10; | ||
659 | // } | ||
660 | |||
661 | // // Handle chording. | ||
662 | // d[6] = flag; | ||
663 | // if(flag == 0x10 && (d[6] & 0x01)) { | ||
664 | // d[7] = 0x01; | ||
665 | // } | ||
666 | // if(flag == 0x01 && (d[6] & 0x10)) { | ||
667 | // d[7] = 0x10; | ||
668 | // } | ||
669 | |||
670 | // // Detect mouse movement. | ||
671 | // if (key_pressed(KEY_UP)) { | ||
672 | // event = true; | ||
673 | // mouse.y = CLAMP(mouse.y - MOUSE_DELTA, 0, SCREEN_HEIGHT - 8); | ||
674 | // } else if (key_pressed(KEY_DOWN)) { | ||
675 | // event = true; | ||
676 | // mouse.y = CLAMP(mouse.y + MOUSE_DELTA, 0, SCREEN_HEIGHT - 8); | ||
677 | // } | ||
678 | // if (key_pressed(KEY_LEFT)) { | ||
679 | // event = true; | ||
680 | // mouse.x = CLAMP(mouse.x - MOUSE_DELTA, 0, SCREEN_WIDTH - 8); | ||
681 | // } else if (key_pressed(KEY_RIGHT)) { | ||
682 | // event = true; | ||
683 | // mouse.x = CLAMP(mouse.x + MOUSE_DELTA, 0, SCREEN_WIDTH - 8); | ||
684 | // } | ||
685 | |||
686 | // // Eval mouse. | ||
687 | // POKE2(d + 0x2, mouse.x); | ||
688 | // POKE2(d + 0x4, mouse.y); | ||
689 | // if (event) { | ||
690 | // uxn_eval(u, PEEK2(d)); | ||
691 | // } | ||
692 | // } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { | ||
693 | // u8 *d = &u->dev[0x80]; | ||
694 | // if (key_tap(KEY_LEFT)) { | ||
695 | // update_cursor(cursor_position - 1); | ||
696 | // } else if (key_tap(KEY_RIGHT)) { | ||
697 | // update_cursor(cursor_position + 1); | ||
698 | // } | ||
699 | // if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) { | ||
700 | // update_cursor(cursor_position - KEYBOARD_ROW_SIZE); | ||
701 | // } else if (key_tap(KEY_DOWN) | ||
702 | // && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) { | ||
703 | // update_cursor(cursor_position + KEYBOARD_ROW_SIZE); | ||
704 | // } | ||
705 | // if (key_tap(KEY_B)) { | ||
706 | // u8 symbol = keyboard[cursor_position].symbol; | ||
707 | // switch (symbol) { | ||
708 | // case 0x7f: { | ||
709 | // // Backspace. | ||
710 | // d[3] = 0x08; | ||
711 | // } break; | ||
712 | // case 0x14: { | ||
713 | // // New line. | ||
714 | // d[3] = 0x0d; | ||
715 | // } break; | ||
716 | // case 0x18: { | ||
717 | // // Arrow up. | ||
718 | // d[2] = 0x10; | ||
719 | // } break; | ||
720 | // case 0x19: { | ||
721 | // // Arrow down. | ||
722 | // d[2] = 0x20; | ||
723 | // } break; | ||
724 | // case 0x1b: { | ||
725 | // // Arrow left. | ||
726 | // d[2] = 0x40; | ||
727 | // } break; | ||
728 | // case 0x1a: { | ||
729 | // // Arrow right. | ||
730 | // d[2] = 0x80; | ||
731 | // } break; | ||
732 | // default: { | ||
733 | // d[3] = symbol; | ||
734 | // } break; | ||
735 | // } | ||
736 | // uxn_eval(u, PEEK2(d)); | ||
737 | // d[3] = 0; | ||
738 | // } | ||
739 | // } | ||
740 | } | ||
741 | |||
742 | #define STACK_SIZE 16 | ||
743 | u8 stack[STACK_SIZE] = {0}; | ||
744 | extern void uxn_eval_asm(u16 pc); | ||
745 | |||
746 | // TODO: This should be on the IWRAM for maximum speed, as these are operations | ||
747 | // we will use very often. | ||
748 | extern u8 wst[256]; | ||
749 | extern u8 rst[256]; | ||
750 | extern u8 io_ports[256]; | ||
751 | extern uintptr_t wst_ptr; | ||
752 | extern uintptr_t rst_ptr; | ||
753 | |||
754 | int | 89 | int |
755 | main(void) { | 90 | main(void) { |
756 | // Adjust system wait times. | 91 | // Adjust system wait times. |
diff --git a/src/profiling.c b/src/profiling.c new file mode 100644 index 0000000..2d230df --- /dev/null +++ b/src/profiling.c | |||
@@ -0,0 +1,157 @@ | |||
1 | #ifndef PROF_ENABLE | ||
2 | #define PROF_ENABLE 0 | ||
3 | #endif | ||
4 | |||
5 | #if PROF_ENABLE > 0 && PROF_ENABLE < 3 | ||
6 | |||
7 | #ifndef PROF_N_FRAMES | ||
8 | #define PROF_N_FRAMES 15 | ||
9 | #endif | ||
10 | |||
11 | // Profile method 1: Average per N frames. | ||
12 | #if PROF_ENABLE == 1 | ||
13 | #define TEXT_ENABLE 1 | ||
14 | #define PROF(F,VAR) \ | ||
15 | do { \ | ||
16 | u32 __tmp_prof = profile_measure();\ | ||
17 | (F);\ | ||
18 | (VAR) += profile_measure() - __tmp_prof;\ | ||
19 | } while (0) | ||
20 | |||
21 | // Profile method 2: Maximum in N frames. | ||
22 | #elif PROF_ENABLE == 2 | ||
23 | #define TEXT_ENABLE 1 | ||
24 | #define PROF(F,VAR) \ | ||
25 | do { \ | ||
26 | u32 __tmp_prof = profile_measure();\ | ||
27 | (F);\ | ||
28 | (VAR) = MAX(profile_measure() - __tmp_prof, (VAR));\ | ||
29 | } while (0) | ||
30 | #endif | ||
31 | |||
32 | #ifndef PROF_SHOW_X | ||
33 | #define PROF_SHOW_X 0 | ||
34 | #endif | ||
35 | #ifndef PROF_SHOW_Y | ||
36 | #define PROF_SHOW_Y 0 | ||
37 | #endif | ||
38 | |||
39 | #define PROF_SHOW() \ | ||
40 | do { \ | ||
41 | txt_position((PROF_SHOW_X), (PROF_SHOW_Y));\ | ||
42 | txt_printf("INPUT %.8lu\n", avg_input_cycles);\ | ||
43 | txt_printf("EVAL %.8lu\n", avg_eval_cycles);\ | ||
44 | txt_printf("VIDEO\n");\ | ||
45 | txt_printf(">PIX %.8lu\n", avg_ppu_pixel_cycles);\ | ||
46 | txt_printf(">FILL %.8lu\n", avg_ppu_fill_cycles);\ | ||
47 | txt_printf(">1BPP %.8lu\n", avg_ppu_icn_cycles);\ | ||
48 | txt_printf(">2BPP %.8lu\n", avg_ppu_chr_cycles);\ | ||
49 | txt_printf(">FLIP %.8lu\n", avg_flip_cycles);\ | ||
50 | txt_printf("AUDIO %.8lu\n", avg_mix_cycles);\ | ||
51 | txt_printf("TOTAL %.8lu\n", avg_frame_cycles);\ | ||
52 | u32 frame_time =\ | ||
53 | FP_DIV(\ | ||
54 | FP_NUM(avg_frame_cycles + 1, 2),\ | ||
55 | FP_NUM(2809, 2),\ | ||
56 | 2) * 166;\ | ||
57 | u32 fps =\ | ||
58 | FP_DIV(\ | ||
59 | FP_NUM(280896 * 60, 2),\ | ||
60 | FP_NUM(avg_frame_cycles + 1, 2),\ | ||
61 | 2);\ | ||
62 | txt_printf("TIME %.8lu\n", frame_time >> 2);\ | ||
63 | txt_printf("FPS %.8lu\n", (fps >> 2) + 1);\ | ||
64 | screen_fill(BG_BACK, 0, 0, 8 * 16, 8 * 12, 2);\ | ||
65 | } while (0) | ||
66 | |||
67 | static u32 prof_frame_counter = 0; | ||
68 | |||
69 | static u32 frame_cycles = 0; | ||
70 | static u32 ppu_pixel_cycles = 0; | ||
71 | static u32 ppu_fill_cycles = 0; | ||
72 | static u32 ppu_chr_cycles = 0; | ||
73 | static u32 ppu_icn_cycles = 0; | ||
74 | static u32 flip_cycles = 0; | ||
75 | static u32 eval_cycles = 0; | ||
76 | static u32 input_cycles = 0; | ||
77 | static u32 mix_cycles = 0; | ||
78 | |||
79 | static u32 avg_ppu_pixel_cycles = 0; | ||
80 | static u32 avg_ppu_fill_cycles = 0; | ||
81 | static u32 avg_ppu_chr_cycles = 0; | ||
82 | static u32 avg_ppu_icn_cycles = 0; | ||
83 | static u32 avg_flip_cycles = 0; | ||
84 | static u32 avg_eval_cycles = 0; | ||
85 | static u32 avg_input_cycles = 0; | ||
86 | static u32 avg_mix_cycles = 0; | ||
87 | static u32 avg_frame_cycles = 0; | ||
88 | |||
89 | #if PROF_ENABLE == 1 | ||
90 | #define FRAME_START()\ | ||
91 | do { \ | ||
92 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
93 | avg_ppu_pixel_cycles = ppu_pixel_cycles / prof_frame_counter;\ | ||
94 | avg_ppu_fill_cycles = ppu_fill_cycles / prof_frame_counter;\ | ||
95 | avg_ppu_chr_cycles = ppu_chr_cycles / prof_frame_counter;\ | ||
96 | avg_ppu_icn_cycles = ppu_icn_cycles / prof_frame_counter;\ | ||
97 | avg_flip_cycles = flip_cycles / prof_frame_counter;\ | ||
98 | avg_eval_cycles = eval_cycles / prof_frame_counter;\ | ||
99 | avg_input_cycles = input_cycles / prof_frame_counter;\ | ||
100 | avg_mix_cycles = mix_cycles / prof_frame_counter;\ | ||
101 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ | ||
102 | prof_frame_counter = 0;\ | ||
103 | frame_cycles = 0;\ | ||
104 | ppu_pixel_cycles = 0;\ | ||
105 | ppu_fill_cycles = 0;\ | ||
106 | ppu_chr_cycles = 0;\ | ||
107 | ppu_icn_cycles = 0;\ | ||
108 | flip_cycles = 0;\ | ||
109 | eval_cycles = 0;\ | ||
110 | input_cycles = 0;\ | ||
111 | mix_cycles = 0;\ | ||
112 | }\ | ||
113 | profile_start();\ | ||
114 | } while (0) | ||
115 | #elif PROF_ENABLE == 2 | ||
116 | #define FRAME_START()\ | ||
117 | do { \ | ||
118 | if (prof_frame_counter == PROF_N_FRAMES) {\ | ||
119 | avg_ppu_pixel_cycles = ppu_pixel_cycles;\ | ||
120 | avg_ppu_fill_cycles = ppu_fill_cycles;\ | ||
121 | avg_ppu_chr_cycles = ppu_chr_cycles;\ | ||
122 | avg_ppu_icn_cycles = ppu_icn_cycles;\ | ||
123 | avg_flip_cycles = flip_cycles;\ | ||
124 | avg_eval_cycles = eval_cycles;\ | ||
125 | avg_input_cycles = input_cycles;\ | ||
126 | avg_mix_cycles = mix_cycles;\ | ||
127 | avg_frame_cycles = frame_cycles / prof_frame_counter;\ | ||
128 | prof_frame_counter = 0;\ | ||
129 | frame_cycles = 0;\ | ||
130 | ppu_pixel_cycles = 0;\ | ||
131 | ppu_fill_cycles = 0;\ | ||
132 | ppu_chr_cycles = 0;\ | ||
133 | ppu_icn_cycles = 0;\ | ||
134 | flip_cycles = 0;\ | ||
135 | eval_cycles = 0;\ | ||
136 | input_cycles = 0;\ | ||
137 | mix_cycles = 0;\ | ||
138 | }\ | ||
139 | profile_start();\ | ||
140 | } while (0) | ||
141 | #endif | ||
142 | |||
143 | #define FRAME_END() \ | ||
144 | do { \ | ||
145 | prof_frame_counter++;\ | ||
146 | frame_cycles += profile_stop();\ | ||
147 | } while (0) | ||
148 | |||
149 | #else | ||
150 | |||
151 | // No profiling. | ||
152 | #define PROF(F,VAR) (F) | ||
153 | #define PROF_SHOW() | ||
154 | #define FRAME_START() | ||
155 | #define FRAME_END() | ||
156 | #endif | ||
157 | |||
diff --git a/src/uxn-core.s b/src/uxn-core.s index a9fc3f9..32ec26b 100644 --- a/src/uxn-core.s +++ b/src/uxn-core.s | |||
@@ -30,532 +30,525 @@ io_ports: .space 256 | |||
30 | .global uxn_eval_asm | 30 | .global uxn_eval_asm |
31 | uxn_eval_asm: | 31 | uxn_eval_asm: |
32 | @ Initialization. | 32 | @ Initialization. |
33 | push {r4-r7} | 33 | push {r4-r7} |
34 | ldr r1, wst_ptr | 34 | ldr r1, wst_ptr |
35 | ldr r2, =uxn_ram | 35 | ldr r2, =uxn_ram |
36 | add r0, r0, r2 | 36 | add r0, r0, r2 |
37 | 37 | ||
38 | uxn_decode: | 38 | uxn_decode: |
39 | ldrb r3, [r0], #1 @ current OP value / table index | 39 | ldrb r3, [r0], #1 @ current OP value / table index |
40 | |||
41 | @ TODO: Setup wst/rst? or fill operations accordingly? | ||
42 | @ str r3, [r1], #1 @ Push to stack: Debugging | ||
43 | 40 | ||
44 | @ Decode OP based on table lookup. | 41 | @ Decode OP based on table lookup. |
45 | adr r4, op_table @ decoding table | 42 | adr r4, op_table @ decoding table |
46 | ldr r4, [r4, r3, lsl #2] @ op_table[idx * 4] | 43 | ldr r4, [r4, r3, lsl #2] @ op_table[idx * 4] |
47 | bx r4 @ op_table[idx * 4]() | 44 | bx r4 @ op_table[idx * 4]() |
48 | 45 | ||
49 | uxn_ret: | 46 | uxn_ret: |
50 | @ Update stack pointer and return. | 47 | @ Update stack pointer and return. |
51 | adr r0, wst_ptr | 48 | adr r0, wst_ptr |
52 | str r1, [r0] | 49 | str r1, [r0] |
53 | pop {r4-r7} | 50 | pop {r4-r7} |
54 | bx lr | 51 | bx lr |
55 | 52 | ||
56 | @ | 53 | @ |
57 | @ OP implementations. | 54 | @ OP implementations. |
58 | @ | 55 | @ |
59 | 56 | ||
60 | brk: | 57 | brk: |
61 | b uxn_ret | 58 | b uxn_ret |
62 | 59 | ||
63 | jci: | 60 | jci: |
64 | b uxn_decode | 61 | b uxn_decode |
65 | 62 | ||
66 | jmi: | 63 | jmi: |
67 | b uxn_decode | 64 | b uxn_decode |
68 | 65 | ||
69 | jsi: | 66 | jsi: |
70 | b uxn_decode | 67 | b uxn_decode |
71 | 68 | ||
72 | litr: | 69 | litr: |
73 | ldrb r3, [r0], #1 | 70 | ldrb r3, [r0], #1 |
74 | strb r3, [r1], #1 | 71 | strb r3, [r1], #1 |
75 | b uxn_decode | 72 | b uxn_decode |
76 | 73 | ||
77 | lit2r: | 74 | lit2r: |
78 | ldrb r3, [r0], #1 | 75 | ldrb r3, [r0], #1 |
79 | ldrb r4, [r0], #1 | 76 | ldrb r4, [r0], #1 |
80 | strb r3, [r1], #1 | 77 | strb r3, [r1], #1 |
81 | strb r4, [r1], #1 | 78 | strb r4, [r1], #1 |
82 | b uxn_decode | 79 | b uxn_decode |
83 | 80 | ||
84 | inc: | 81 | inc: |
85 | b uxn_decode | 82 | b uxn_decode |
86 | 83 | ||
87 | inc2: | 84 | inc2: |
88 | b uxn_decode | 85 | b uxn_decode |
89 | 86 | ||
90 | pop: | 87 | pop: |
91 | b uxn_decode | 88 | b uxn_decode |
92 | 89 | ||
93 | pop2: | 90 | pop2: |
94 | b uxn_decode | 91 | b uxn_decode |
95 | 92 | ||
96 | nip: | 93 | nip: |
97 | b uxn_decode | 94 | b uxn_decode |
98 | 95 | ||
99 | nip2: | 96 | nip2: |
100 | b uxn_decode | 97 | b uxn_decode |
101 | 98 | ||
102 | swp: | 99 | swp: |
103 | b uxn_decode | 100 | b uxn_decode |
104 | 101 | ||
105 | swp2: | 102 | swp2: |
106 | b uxn_decode | 103 | b uxn_decode |
107 | 104 | ||
108 | rot: | 105 | rot: |
109 | b uxn_decode | 106 | b uxn_decode |
110 | 107 | ||
111 | rot2: | 108 | rot2: |
112 | b uxn_decode | 109 | b uxn_decode |
113 | 110 | ||
114 | dup: | 111 | dup: |
115 | b uxn_decode | 112 | b uxn_decode |
116 | 113 | ||
117 | dup2: | 114 | dup2: |
118 | b uxn_decode | 115 | b uxn_decode |
119 | 116 | ||
120 | ovr: | 117 | ovr: |
121 | b uxn_decode | 118 | b uxn_decode |
122 | 119 | ||
123 | ovr2: | 120 | ovr2: |
124 | b uxn_decode | 121 | b uxn_decode |
125 | 122 | ||
126 | equ: | 123 | equ: |
127 | b uxn_decode | 124 | b uxn_decode |
128 | 125 | ||
129 | equ2: | 126 | equ2: |
130 | b uxn_decode | 127 | b uxn_decode |
131 | 128 | ||
132 | neq: | 129 | neq: |
133 | b uxn_decode | 130 | b uxn_decode |
134 | 131 | ||
135 | neq2: | 132 | neq2: |
136 | b uxn_decode | 133 | b uxn_decode |
137 | 134 | ||
138 | gth: | 135 | gth: |
139 | b uxn_decode | 136 | b uxn_decode |
140 | 137 | ||
141 | gth2: | 138 | gth2: |
142 | b uxn_decode | 139 | b uxn_decode |
143 | 140 | ||
144 | lth: | 141 | lth: |
145 | b uxn_decode | 142 | b uxn_decode |
146 | 143 | ||
147 | lth2: | 144 | lth2: |
148 | b uxn_decode | 145 | b uxn_decode |
149 | 146 | ||
150 | jmp: | 147 | jmp: |
151 | b uxn_decode | 148 | b uxn_decode |
152 | 149 | ||
153 | jmp2: | 150 | jmp2: |
154 | b uxn_decode | 151 | b uxn_decode |
155 | 152 | ||
156 | jcn: | 153 | jcn: |
157 | b uxn_decode | 154 | b uxn_decode |
158 | 155 | ||
159 | jcn2: | 156 | jcn2: |
160 | b uxn_decode | 157 | b uxn_decode |
161 | 158 | ||
162 | jsr: | 159 | jsr: |
163 | b uxn_decode | 160 | b uxn_decode |
164 | 161 | ||
165 | jsr2: | 162 | jsr2: |
166 | b uxn_decode | 163 | b uxn_decode |
167 | 164 | ||
168 | sth: | 165 | sth: |
169 | b uxn_decode | 166 | b uxn_decode |
170 | 167 | ||
171 | sth2: | 168 | sth2: |
172 | b uxn_decode | 169 | b uxn_decode |
173 | 170 | ||
174 | ldz: | 171 | ldz: |
175 | b uxn_decode | 172 | b uxn_decode |
176 | 173 | ||
177 | ldz2: | 174 | ldz2: |
178 | b uxn_decode | 175 | b uxn_decode |
179 | 176 | ||
180 | stz: | 177 | stz: |
181 | b uxn_decode | 178 | b uxn_decode |
182 | 179 | ||
183 | stz2: | 180 | stz2: |
184 | b uxn_decode | 181 | b uxn_decode |
185 | 182 | ||
186 | ldr: | 183 | ldr: |
187 | b uxn_decode | 184 | b uxn_decode |
188 | 185 | ||
189 | ldr2: | 186 | ldr2: |
190 | b uxn_decode | 187 | b uxn_decode |
191 | 188 | ||
192 | str: | 189 | str: |
193 | b uxn_decode | 190 | b uxn_decode |
194 | 191 | ||
195 | str2: | 192 | str2: |
196 | b uxn_decode | 193 | b uxn_decode |
197 | 194 | ||
198 | lda: | 195 | lda: |
199 | b uxn_decode | 196 | b uxn_decode |
200 | 197 | ||
201 | lda2: | 198 | lda2: |
202 | b uxn_decode | 199 | b uxn_decode |
203 | 200 | ||
204 | sta: | 201 | sta: |
205 | b uxn_decode | 202 | b uxn_decode |
206 | 203 | ||
207 | sta2: | 204 | sta2: |
208 | b uxn_decode | 205 | b uxn_decode |
209 | 206 | ||
210 | dei: | 207 | dei: |
211 | b uxn_decode | 208 | b uxn_decode |
212 | 209 | ||
213 | dei2: | 210 | dei2: |
214 | b uxn_decode | 211 | b uxn_decode |
215 | 212 | ||
216 | deo: | 213 | deo: |
217 | b uxn_decode | 214 | b uxn_decode |
218 | 215 | ||
219 | deo2: | 216 | deo2: |
220 | b uxn_decode | 217 | b uxn_decode |
221 | 218 | ||
222 | add: | 219 | add: |
223 | ldr r3, [r1, #-1]! | 220 | ldrb r3, [r1, #-1]! |
224 | ldr r4, [r1, #-1]! | 221 | ldrb r4, [r1, #-1]! |
225 | add r3, r3, r4 | 222 | add r3, r3, r4 |
226 | strb r3, [r1], #1 | 223 | strb r3, [r1], #1 |
227 | b uxn_decode | 224 | b uxn_decode |
228 | 225 | ||
229 | add2: | 226 | add2: |
230 | ldrb r3, [r1, #-1]! | 227 | ldrb r3, [r1, #-1]! |
231 | lsl r3, #8 | 228 | ldrb r5, [r1, #-1]! |
232 | ldrb r5, [r1, #-1]! | 229 | orr r3, r5, r3, lsl #8 |
233 | add r3, r5 | 230 | ldrb r4, [r1, #-1]! |
234 | ldrb r4, [r1, #-1]! | 231 | ldrb r5, [r1, #-1]! |
235 | ldrb r5, [r1, #-1]! | 232 | orr r4, r5, r4, lsl #8 |
236 | lsl r4, #8 | 233 | add r3, r3, r4 |
237 | add r4, r5 | 234 | strb r3, [r1], #1 |
238 | add r3, r3, r4 | 235 | lsr r3, #8 |
239 | strb r3, [r1], #1 | 236 | strb r3, [r1], #1 |
240 | lsr r3, #8 | 237 | b uxn_decode |
241 | strb r3, [r1], #1 | ||
242 | b uxn_decode | ||
243 | 238 | ||
244 | sub: | 239 | sub: |
245 | ldr r3, [r1, #-1]! | 240 | ldr r3, [r1, #-1]! |
246 | ldr r4, [r1, #-1]! | 241 | ldr r4, [r1, #-1]! |
247 | sub r4, r4, r3 | 242 | sub r4, r4, r3 |
248 | strb r4, [r1], #1 | 243 | strb r4, [r1], #1 |
249 | b uxn_decode | 244 | b uxn_decode |
250 | 245 | ||
251 | sub2: | 246 | sub2: |
252 | ldrb r3, [r1, #-1]! | 247 | ldrb r3, [r1, #-1]! |
253 | ldrb r5, [r1, #-1]! | 248 | ldrb r5, [r1, #-1]! |
254 | lsl r3, #8 | 249 | orr r3, r5, r3, lsl #8 |
255 | add r3, r5 | 250 | ldrb r4, [r1, #-1]! |
256 | ldrb r4, [r1, #-1]! | 251 | ldrb r5, [r1, #-1]! |
257 | ldrb r5, [r1, #-1]! | 252 | orr r4, r5, r4, lsl #8 |
258 | lsl r4, #8 | 253 | sub r3, r4, r3 |
259 | add r4, r5 | 254 | strb r3, [r1], #1 |
260 | sub r3, r4, r3 | 255 | lsr r3, #8 |
261 | strb r3, [r1], #1 | 256 | strb r3, [r1], #1 |
262 | lsr r3, #8 | 257 | b uxn_decode |
263 | strb r3, [r1], #1 | ||
264 | b uxn_decode | ||
265 | 258 | ||
266 | mul: | 259 | mul: |
267 | b uxn_decode | 260 | b uxn_decode |
268 | 261 | ||
269 | mul2: | 262 | mul2: |
270 | b uxn_decode | 263 | b uxn_decode |
271 | 264 | ||
272 | div: | 265 | div: |
273 | b uxn_decode | 266 | b uxn_decode |
274 | 267 | ||
275 | div2: | 268 | div2: |
276 | b uxn_decode | 269 | b uxn_decode |
277 | 270 | ||
278 | and: | 271 | and: |
279 | b uxn_decode | 272 | b uxn_decode |
280 | 273 | ||
281 | and2: | 274 | and2: |
282 | b uxn_decode | 275 | b uxn_decode |
283 | 276 | ||
284 | ora: | 277 | ora: |
285 | b uxn_decode | 278 | b uxn_decode |
286 | 279 | ||
287 | ora2: | 280 | ora2: |
288 | b uxn_decode | 281 | b uxn_decode |
289 | 282 | ||
290 | eor: | 283 | eor: |
291 | b uxn_decode | 284 | b uxn_decode |
292 | 285 | ||
293 | eor2: | 286 | eor2: |
294 | b uxn_decode | 287 | b uxn_decode |
295 | 288 | ||
296 | sft: | 289 | sft: |
297 | b uxn_decode | 290 | b uxn_decode |
298 | 291 | ||
299 | sft2: | 292 | sft2: |
300 | b uxn_decode | 293 | b uxn_decode |
301 | 294 | ||
302 | @ OP table | 295 | @ OP table |
303 | op_table: | 296 | op_table: |
304 | .word brk @ 0x00 | 297 | .word brk @ 0x00 |
305 | .word inc @ 0x01 | 298 | .word inc @ 0x01 |
306 | .word pop @ 0x02 | 299 | .word pop @ 0x02 |
307 | .word nip @ 0x03 | 300 | .word nip @ 0x03 |
308 | .word swp @ 0x04 | 301 | .word swp @ 0x04 |
309 | .word rot @ 0x05 | 302 | .word rot @ 0x05 |
310 | .word dup @ 0x06 | 303 | .word dup @ 0x06 |
311 | .word ovr @ 0x07 | 304 | .word ovr @ 0x07 |
312 | .word equ @ 0x08 | 305 | .word equ @ 0x08 |
313 | .word neq @ 0x09 | 306 | .word neq @ 0x09 |
314 | .word gth @ 0x0a | 307 | .word gth @ 0x0a |
315 | .word lth @ 0x0b | 308 | .word lth @ 0x0b |
316 | .word jmp @ 0x0c | 309 | .word jmp @ 0x0c |
317 | .word jcn @ 0x0d | 310 | .word jcn @ 0x0d |
318 | .word jsr @ 0x0e | 311 | .word jsr @ 0x0e |
319 | .word sth @ 0x0f | 312 | .word sth @ 0x0f |
320 | .word ldz @ 0x00 | 313 | .word ldz @ 0x00 |
321 | .word stz @ 0x11 | 314 | .word stz @ 0x11 |
322 | .word ldr @ 0x12 | 315 | .word ldr @ 0x12 |
323 | .word str @ 0x13 | 316 | .word str @ 0x13 |
324 | .word lda @ 0x14 | 317 | .word lda @ 0x14 |
325 | .word sta @ 0x15 | 318 | .word sta @ 0x15 |
326 | .word dei @ 0x16 | 319 | .word dei @ 0x16 |
327 | .word deo @ 0x17 | 320 | .word deo @ 0x17 |
328 | .word add @ 0x18 | 321 | .word add @ 0x18 |
329 | .word sub @ 0x19 | 322 | .word sub @ 0x19 |
330 | .word mul @ 0x1a | 323 | .word mul @ 0x1a |
331 | .word div @ 0x1b | 324 | .word div @ 0x1b |
332 | .word and @ 0x1c | 325 | .word and @ 0x1c |
333 | .word ora @ 0x1d | 326 | .word ora @ 0x1d |
334 | .word eor @ 0x1e | 327 | .word eor @ 0x1e |
335 | .word sft @ 0x1f | 328 | .word sft @ 0x1f |
336 | .word brk @ 0x20 | 329 | .word brk @ 0x20 |
337 | .word inc2 @ 0x21 | 330 | .word inc2 @ 0x21 |
338 | .word pop2 @ 0x22 | 331 | .word pop2 @ 0x22 |
339 | .word nip2 @ 0x23 | 332 | .word nip2 @ 0x23 |
340 | .word swp2 @ 0x24 | 333 | .word swp2 @ 0x24 |
341 | .word rot2 @ 0x25 | 334 | .word rot2 @ 0x25 |
342 | .word dup2 @ 0x26 | 335 | .word dup2 @ 0x26 |
343 | .word ovr2 @ 0x27 | 336 | .word ovr2 @ 0x27 |
344 | .word equ2 @ 0x28 | 337 | .word equ2 @ 0x28 |
345 | .word neq2 @ 0x29 | 338 | .word neq2 @ 0x29 |
346 | .word gth2 @ 0x2a | 339 | .word gth2 @ 0x2a |
347 | .word lth2 @ 0x2b | 340 | .word lth2 @ 0x2b |
348 | .word jmp2 @ 0x2c | 341 | .word jmp2 @ 0x2c |
349 | .word jcn2 @ 0x2d | 342 | .word jcn2 @ 0x2d |
350 | .word jsr2 @ 0x2e | 343 | .word jsr2 @ 0x2e |
351 | .word sth2 @ 0x2f | 344 | .word sth2 @ 0x2f |
352 | .word ldz2 @ 0x30 | 345 | .word ldz2 @ 0x30 |
353 | .word stz2 @ 0x31 | 346 | .word stz2 @ 0x31 |
354 | .word ldr2 @ 0x32 | 347 | .word ldr2 @ 0x32 |
355 | .word str2 @ 0x33 | 348 | .word str2 @ 0x33 |
356 | .word lda2 @ 0x34 | 349 | .word lda2 @ 0x34 |
357 | .word sta2 @ 0x35 | 350 | .word sta2 @ 0x35 |
358 | .word dei2 @ 0x36 | 351 | .word dei2 @ 0x36 |
359 | .word deo2 @ 0x37 | 352 | .word deo2 @ 0x37 |
360 | .word add2 @ 0x38 | 353 | .word add2 @ 0x38 |
361 | .word sub2 @ 0x39 | 354 | .word sub2 @ 0x39 |
362 | .word mul2 @ 0x3a | 355 | .word mul2 @ 0x3a |
363 | .word div2 @ 0x3b | 356 | .word div2 @ 0x3b |
364 | .word and2 @ 0x3c | 357 | .word and2 @ 0x3c |
365 | .word ora2 @ 0x3d | 358 | .word ora2 @ 0x3d |
366 | .word eor2 @ 0x3e | 359 | .word eor2 @ 0x3e |
367 | .word sft2 @ 0x3f | 360 | .word sft2 @ 0x3f |
368 | @ TODO: Can we mask this instead of having empty space? | 361 | @ TODO: Can we mask this instead of having empty space? |
369 | .word brk @ 0x40 | 362 | .word brk @ 0x40 |
370 | .word brk @ 0x41 | 363 | .word brk @ 0x41 |
371 | .word brk @ 0x42 | 364 | .word brk @ 0x42 |
372 | .word brk @ 0x43 | 365 | .word brk @ 0x43 |
373 | .word brk @ 0x44 | 366 | .word brk @ 0x44 |
374 | .word brk @ 0x45 | 367 | .word brk @ 0x45 |
375 | .word brk @ 0x46 | 368 | .word brk @ 0x46 |
376 | .word brk @ 0x47 | 369 | .word brk @ 0x47 |
377 | .word brk @ 0x48 | 370 | .word brk @ 0x48 |
378 | .word brk @ 0x49 | 371 | .word brk @ 0x49 |
379 | .word brk @ 0x4a | 372 | .word brk @ 0x4a |
380 | .word brk @ 0x4b | 373 | .word brk @ 0x4b |
381 | .word brk @ 0x4c | 374 | .word brk @ 0x4c |
382 | .word brk @ 0x4d | 375 | .word brk @ 0x4d |
383 | .word brk @ 0x4e | 376 | .word brk @ 0x4e |
384 | .word brk @ 0x4f | 377 | .word brk @ 0x4f |
385 | .word brk @ 0x50 | 378 | .word brk @ 0x50 |
386 | .word brk @ 0x51 | 379 | .word brk @ 0x51 |
387 | .word brk @ 0x52 | 380 | .word brk @ 0x52 |
388 | .word brk @ 0x53 | 381 | .word brk @ 0x53 |
389 | .word brk @ 0x54 | 382 | .word brk @ 0x54 |
390 | .word brk @ 0x55 | 383 | .word brk @ 0x55 |
391 | .word brk @ 0x56 | 384 | .word brk @ 0x56 |
392 | .word brk @ 0x57 | 385 | .word brk @ 0x57 |
393 | .word brk @ 0x58 | 386 | .word brk @ 0x58 |
394 | .word brk @ 0x59 | 387 | .word brk @ 0x59 |
395 | .word brk @ 0x5a | 388 | .word brk @ 0x5a |
396 | .word brk @ 0x5b | 389 | .word brk @ 0x5b |
397 | .word brk @ 0x5c | 390 | .word brk @ 0x5c |
398 | .word brk @ 0x5d | 391 | .word brk @ 0x5d |
399 | .word brk @ 0x5e | 392 | .word brk @ 0x5e |
400 | .word brk @ 0x5f | 393 | .word brk @ 0x5f |
401 | .word brk @ 0x60 | 394 | .word brk @ 0x60 |
402 | .word brk @ 0x61 | 395 | .word brk @ 0x61 |
403 | .word brk @ 0x62 | 396 | .word brk @ 0x62 |
404 | .word brk @ 0x63 | 397 | .word brk @ 0x63 |
405 | .word brk @ 0x64 | 398 | .word brk @ 0x64 |
406 | .word brk @ 0x65 | 399 | .word brk @ 0x65 |
407 | .word brk @ 0x66 | 400 | .word brk @ 0x66 |
408 | .word brk @ 0x67 | 401 | .word brk @ 0x67 |
409 | .word brk @ 0x68 | 402 | .word brk @ 0x68 |
410 | .word brk @ 0x69 | 403 | .word brk @ 0x69 |
411 | .word brk @ 0x6a | 404 | .word brk @ 0x6a |
412 | .word brk @ 0x6b | 405 | .word brk @ 0x6b |
413 | .word brk @ 0x6c | 406 | .word brk @ 0x6c |
414 | .word brk @ 0x6d | 407 | .word brk @ 0x6d |
415 | .word brk @ 0x6e | 408 | .word brk @ 0x6e |
416 | .word brk @ 0x6f | 409 | .word brk @ 0x6f |
417 | .word brk @ 0x70 | 410 | .word brk @ 0x70 |
418 | .word brk @ 0x71 | 411 | .word brk @ 0x71 |
419 | .word brk @ 0x72 | 412 | .word brk @ 0x72 |
420 | .word brk @ 0x73 | 413 | .word brk @ 0x73 |
421 | .word brk @ 0x74 | 414 | .word brk @ 0x74 |
422 | .word brk @ 0x75 | 415 | .word brk @ 0x75 |
423 | .word brk @ 0x76 | 416 | .word brk @ 0x76 |
424 | .word brk @ 0x77 | 417 | .word brk @ 0x77 |
425 | .word brk @ 0x78 | 418 | .word brk @ 0x78 |
426 | .word brk @ 0x79 | 419 | .word brk @ 0x79 |
427 | .word brk @ 0x7a | 420 | .word brk @ 0x7a |
428 | .word brk @ 0x7b | 421 | .word brk @ 0x7b |
429 | .word brk @ 0x7c | 422 | .word brk @ 0x7c |
430 | .word brk @ 0x7d | 423 | .word brk @ 0x7d |
431 | .word brk @ 0x7e | 424 | .word brk @ 0x7e |
432 | .word brk @ 0x7f | 425 | .word brk @ 0x7f |
433 | .word litr @ 0x80 | 426 | .word litr @ 0x80 |
434 | .word brk @ 0x81 | 427 | .word brk @ 0x81 |
435 | .word brk @ 0x82 | 428 | .word brk @ 0x82 |
436 | .word brk @ 0x83 | 429 | .word brk @ 0x83 |
437 | .word brk @ 0x84 | 430 | .word brk @ 0x84 |
438 | .word brk @ 0x85 | 431 | .word brk @ 0x85 |
439 | .word brk @ 0x86 | 432 | .word brk @ 0x86 |
440 | .word brk @ 0x87 | 433 | .word brk @ 0x87 |
441 | .word brk @ 0x88 | 434 | .word brk @ 0x88 |
442 | .word brk @ 0x89 | 435 | .word brk @ 0x89 |
443 | .word brk @ 0x8a | 436 | .word brk @ 0x8a |
444 | .word brk @ 0x8b | 437 | .word brk @ 0x8b |
445 | .word brk @ 0x8c | 438 | .word brk @ 0x8c |
446 | .word brk @ 0x8d | 439 | .word brk @ 0x8d |
447 | .word brk @ 0x8e | 440 | .word brk @ 0x8e |
448 | .word brk @ 0x8f | 441 | .word brk @ 0x8f |
449 | .word brk @ 0x90 | 442 | .word brk @ 0x90 |
450 | .word brk @ 0x91 | 443 | .word brk @ 0x91 |
451 | .word brk @ 0x92 | 444 | .word brk @ 0x92 |
452 | .word brk @ 0x93 | 445 | .word brk @ 0x93 |
453 | .word brk @ 0x94 | 446 | .word brk @ 0x94 |
454 | .word brk @ 0x95 | 447 | .word brk @ 0x95 |
455 | .word brk @ 0x96 | 448 | .word brk @ 0x96 |
456 | .word brk @ 0x97 | 449 | .word brk @ 0x97 |
457 | .word brk @ 0x98 | 450 | .word brk @ 0x98 |
458 | .word brk @ 0x99 | 451 | .word brk @ 0x99 |
459 | .word brk @ 0x9a | 452 | .word brk @ 0x9a |
460 | .word brk @ 0x9b | 453 | .word brk @ 0x9b |
461 | .word brk @ 0x9c | 454 | .word brk @ 0x9c |
462 | .word brk @ 0x9d | 455 | .word brk @ 0x9d |
463 | .word brk @ 0x9e | 456 | .word brk @ 0x9e |
464 | .word brk @ 0x9f | 457 | .word brk @ 0x9f |
465 | .word lit2r @ 0xa0 | 458 | .word lit2r @ 0xa0 |
466 | .word brk @ 0xa1 | 459 | .word brk @ 0xa1 |
467 | .word brk @ 0xa2 | 460 | .word brk @ 0xa2 |
468 | .word brk @ 0xa3 | 461 | .word brk @ 0xa3 |
469 | .word brk @ 0xa4 | 462 | .word brk @ 0xa4 |
470 | .word brk @ 0xa5 | 463 | .word brk @ 0xa5 |
471 | .word brk @ 0xa6 | 464 | .word brk @ 0xa6 |
472 | .word brk @ 0xa7 | 465 | .word brk @ 0xa7 |
473 | .word brk @ 0xa8 | 466 | .word brk @ 0xa8 |
474 | .word brk @ 0xa9 | 467 | .word brk @ 0xa9 |
475 | .word brk @ 0xaa | 468 | .word brk @ 0xaa |
476 | .word brk @ 0xab | 469 | .word brk @ 0xab |
477 | .word brk @ 0xac | 470 | .word brk @ 0xac |
478 | .word brk @ 0xad | 471 | .word brk @ 0xad |
479 | .word brk @ 0xae | 472 | .word brk @ 0xae |
480 | .word brk @ 0xaf | 473 | .word brk @ 0xaf |
481 | .word brk @ 0xb0 | 474 | .word brk @ 0xb0 |
482 | .word brk @ 0xb1 | 475 | .word brk @ 0xb1 |
483 | .word brk @ 0xb2 | 476 | .word brk @ 0xb2 |
484 | .word brk @ 0xb3 | 477 | .word brk @ 0xb3 |
485 | .word brk @ 0xb4 | 478 | .word brk @ 0xb4 |
486 | .word brk @ 0xb5 | 479 | .word brk @ 0xb5 |
487 | .word brk @ 0xb6 | 480 | .word brk @ 0xb6 |
488 | .word brk @ 0xb7 | 481 | .word brk @ 0xb7 |
489 | .word brk @ 0xb8 | 482 | .word brk @ 0xb8 |
490 | .word brk @ 0xb9 | 483 | .word brk @ 0xb9 |
491 | .word brk @ 0xba | 484 | .word brk @ 0xba |
492 | .word brk @ 0xbb | 485 | .word brk @ 0xbb |
493 | .word brk @ 0xbc | 486 | .word brk @ 0xbc |
494 | .word brk @ 0xbd | 487 | .word brk @ 0xbd |
495 | .word brk @ 0xbe | 488 | .word brk @ 0xbe |
496 | .word brk @ 0xbf | 489 | .word brk @ 0xbf |
497 | .word brk @ 0xc0 | 490 | .word brk @ 0xc0 |
498 | .word brk @ 0xc1 | 491 | .word brk @ 0xc1 |
499 | .word brk @ 0xc2 | 492 | .word brk @ 0xc2 |
500 | .word brk @ 0xc3 | 493 | .word brk @ 0xc3 |
501 | .word brk @ 0xc4 | 494 | .word brk @ 0xc4 |
502 | .word brk @ 0xc5 | 495 | .word brk @ 0xc5 |
503 | .word brk @ 0xc6 | 496 | .word brk @ 0xc6 |
504 | .word brk @ 0xc7 | 497 | .word brk @ 0xc7 |
505 | .word brk @ 0xc8 | 498 | .word brk @ 0xc8 |
506 | .word brk @ 0xc9 | 499 | .word brk @ 0xc9 |
507 | .word brk @ 0xca | 500 | .word brk @ 0xca |
508 | .word brk @ 0xcb | 501 | .word brk @ 0xcb |
509 | .word brk @ 0xcc | 502 | .word brk @ 0xcc |
510 | .word brk @ 0xcd | 503 | .word brk @ 0xcd |
511 | .word brk @ 0xce | 504 | .word brk @ 0xce |
512 | .word brk @ 0xcf | 505 | .word brk @ 0xcf |
513 | .word brk @ 0xd0 | 506 | .word brk @ 0xd0 |
514 | .word brk @ 0xd1 | 507 | .word brk @ 0xd1 |
515 | .word brk @ 0xd2 | 508 | .word brk @ 0xd2 |
516 | .word brk @ 0xd3 | 509 | .word brk @ 0xd3 |
517 | .word brk @ 0xd4 | 510 | .word brk @ 0xd4 |
518 | .word brk @ 0xd5 | 511 | .word brk @ 0xd5 |
519 | .word brk @ 0xd6 | 512 | .word brk @ 0xd6 |
520 | .word brk @ 0xd7 | 513 | .word brk @ 0xd7 |
521 | .word brk @ 0xd8 | 514 | .word brk @ 0xd8 |
522 | .word brk @ 0xd9 | 515 | .word brk @ 0xd9 |
523 | .word brk @ 0xda | 516 | .word brk @ 0xda |
524 | .word brk @ 0xdb | 517 | .word brk @ 0xdb |
525 | .word brk @ 0xdc | 518 | .word brk @ 0xdc |
526 | .word brk @ 0xdd | 519 | .word brk @ 0xdd |
527 | .word brk @ 0xde | 520 | .word brk @ 0xde |
528 | .word brk @ 0xdf | 521 | .word brk @ 0xdf |
529 | .word brk @ 0xe0 | 522 | .word brk @ 0xe0 |
530 | .word brk @ 0xe1 | 523 | .word brk @ 0xe1 |
531 | .word brk @ 0xe2 | 524 | .word brk @ 0xe2 |
532 | .word brk @ 0xe3 | 525 | .word brk @ 0xe3 |
533 | .word brk @ 0xe4 | 526 | .word brk @ 0xe4 |
534 | .word brk @ 0xe5 | 527 | .word brk @ 0xe5 |
535 | .word brk @ 0xe6 | 528 | .word brk @ 0xe6 |
536 | .word brk @ 0xe7 | 529 | .word brk @ 0xe7 |
537 | .word brk @ 0xe8 | 530 | .word brk @ 0xe8 |
538 | .word brk @ 0xe9 | 531 | .word brk @ 0xe9 |
539 | .word brk @ 0xea | 532 | .word brk @ 0xea |
540 | .word brk @ 0xeb | 533 | .word brk @ 0xeb |
541 | .word brk @ 0xec | 534 | .word brk @ 0xec |
542 | .word brk @ 0xed | 535 | .word brk @ 0xed |
543 | .word brk @ 0xee | 536 | .word brk @ 0xee |
544 | .word brk @ 0xef | 537 | .word brk @ 0xef |
545 | .word brk @ 0xf0 | 538 | .word brk @ 0xf0 |
546 | .word brk @ 0xf1 | 539 | .word brk @ 0xf1 |
547 | .word brk @ 0xf2 | 540 | .word brk @ 0xf2 |
548 | .word brk @ 0xf3 | 541 | .word brk @ 0xf3 |
549 | .word brk @ 0xf4 | 542 | .word brk @ 0xf4 |
550 | .word brk @ 0xf5 | 543 | .word brk @ 0xf5 |
551 | .word brk @ 0xf6 | 544 | .word brk @ 0xf6 |
552 | .word brk @ 0xf7 | 545 | .word brk @ 0xf7 |
553 | .word brk @ 0xf8 | 546 | .word brk @ 0xf8 |
554 | @ TODO: Can we mask this instead of having empty space? | 547 | @ TODO: Can we mask this instead of having empty space? |
555 | .word lit2r @ 0xf9 | 548 | .word lit2r @ 0xf9 |
556 | .word litr @ 0xfa | 549 | .word litr @ 0xfa |
557 | .word lit2r @ 0xfb | 550 | .word lit2r @ 0xfb |
558 | .word litr @ 0xfc | 551 | .word litr @ 0xfc |
559 | .word jsi @ 0xfd | 552 | .word jsi @ 0xfd |
560 | .word jmi @ 0xfe | 553 | .word jmi @ 0xfe |
561 | .word jci @ 0xff | 554 | .word jci @ 0xff |