diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 162 |
1 files changed, 99 insertions, 63 deletions
@@ -13,16 +13,16 @@ | |||
13 | #include <time.h> | 13 | #include <time.h> |
14 | 14 | ||
15 | #include "common.h" | 15 | #include "common.h" |
16 | #include "bitmap.h" | ||
17 | #include "filesystem.c" | 16 | #include "filesystem.c" |
18 | 17 | ||
19 | #include "rom.c" | ||
20 | #include "uxn.c" | 18 | #include "uxn.c" |
21 | #include "ppu.c" | 19 | #include "ppu.c" |
22 | #include "apu.c" | 20 | #include "apu.c" |
23 | #include "file.c" | 21 | #include "file.c" |
24 | #include "text.h" | 22 | #include "text.h" |
25 | 23 | ||
24 | #include "rom.c" | ||
25 | |||
26 | // | 26 | // |
27 | // Config parameters. | 27 | // Config parameters. |
28 | // | 28 | // |
@@ -37,6 +37,8 @@ | |||
37 | #define CONTROL_METHODS CONTROL_CONTROLLER,CONTROL_MOUSE,CONTROL_KEYBOARD | 37 | #define CONTROL_METHODS CONTROL_CONTROLLER,CONTROL_MOUSE,CONTROL_KEYBOARD |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #define PROF_ENABLE 1 | ||
41 | |||
40 | #ifdef PROF_ENABLE | 42 | #ifdef PROF_ENABLE |
41 | #if PROF_ENABLE == 0 | 43 | #if PROF_ENABLE == 0 |
42 | #define TEXT_ENABLE 1 | 44 | #define TEXT_ENABLE 1 |
@@ -148,20 +150,29 @@ screen_deo(u8 *ram, u8 *d, u8 port) { | |||
148 | switch(port) { | 150 | switch(port) { |
149 | case 0xe: { | 151 | case 0xe: { |
150 | u16 x, y; | 152 | u16 x, y; |
151 | u8 layer = d[0xe] & 0x40; | 153 | u8 *layer = (d[0xe] & 0x40) ? ppu.fg : ppu.bg; |
152 | PEKDEV(x, 0x8); | 154 | x = PEEK2(d + 0x8); |
153 | PEKDEV(y, 0xa); | 155 | y = PEEK2(d + 0xa); |
154 | PROF(ppu_pixel(layer ? ppu.fg : ppu.bg, x, y, d[0xe] & 0x3), ppu_pixel_cycles); | 156 | if(d[0xe] & 0x80) { |
155 | if(d[0x6] & 0x01) POKDEV(0x8, x + 1); /* auto x+1 */ | 157 | screen_fill(layer, |
156 | if(d[0x6] & 0x02) POKDEV(0xa, y + 1); /* auto y+1 */ | 158 | (d[0xe] & 0x10) ? 0 : x, |
159 | (d[0xe] & 0x20) ? 0 : y, | ||
160 | (d[0xe] & 0x10) ? x : SCREEN_WIDTH, | ||
161 | (d[0xe] & 0x20) ? y : SCREEN_HEIGHT, | ||
162 | (d[0xe] & 0x03)); | ||
163 | } else { | ||
164 | PROF(ppu_pixel(layer, x, y, d[0xe] & 0x3), ppu_pixel_cycles); | ||
165 | if(d[0x6] & 0x01) POKE2(d + 0x8, x + 1); /* auto x+1 */ | ||
166 | if(d[0x6] & 0x02) POKE2(d + 0xa, y + 1); /* auto y+1 */ | ||
167 | } | ||
157 | break; | 168 | break; |
158 | } | 169 | } |
159 | case 0xf: { | 170 | case 0xf: { |
160 | u16 x, y, dx, dy, addr; | 171 | u16 x, y, dx, dy, addr; |
161 | u8 n, twobpp = !!(d[0xf] & 0x80); | 172 | u8 n, twobpp = !!(d[0xf] & 0x80); |
162 | PEKDEV(x, 0x8); | 173 | x = PEEK2(d + 0x8); |
163 | PEKDEV(y, 0xa); | 174 | y = PEEK2(d + 0xa); |
164 | PEKDEV(addr, 0xc); | 175 | addr = PEEK2(d + 0xc); |
165 | n = d[0x6] >> 4; | 176 | n = d[0x6] >> 4; |
166 | dx = (d[0x6] & 0x01) << 3; | 177 | dx = (d[0x6] & 0x01) << 3; |
167 | dy = (d[0x6] & 0x02) << 2; | 178 | dy = (d[0x6] & 0x02) << 2; |
@@ -181,9 +192,9 @@ screen_deo(u8 *ram, u8 *d, u8 port) { | |||
181 | } | 192 | } |
182 | addr += (d[0x6] & 0x04) << (1 + twobpp); | 193 | addr += (d[0x6] & 0x04) << (1 + twobpp); |
183 | } | 194 | } |
184 | POKDEV(0xc, addr); /* auto addr+length */ | 195 | POKE2(d + 0xc, addr); /* auto addr+length */ |
185 | POKDEV(0x8, x + dx); /* auto x+8 */ | 196 | POKE2(d + 0x8, x + dx); /* auto x+8 */ |
186 | POKDEV(0xa, y + dy); /* auto y+8 */ | 197 | POKE2(d + 0xa, y + dy); /* auto y+8 */ |
187 | break; | 198 | break; |
188 | } | 199 | } |
189 | } | 200 | } |
@@ -195,7 +206,7 @@ audio_dei(int instance, u8 *d, u8 port) { | |||
195 | switch(port) { | 206 | switch(port) { |
196 | // case 0x4: return apu_get_vu(instance); | 207 | // case 0x4: return apu_get_vu(instance); |
197 | case 0x2: { | 208 | case 0x2: { |
198 | POKDEV(0x2, c->pos); | 209 | POKE2(d + 0x2, c->pos); |
199 | c->pos <<= 12; // fixed point. | 210 | c->pos <<= 12; // fixed point. |
200 | break; | 211 | break; |
201 | } | 212 | } |
@@ -211,9 +222,9 @@ audio_deo(int instance, u8 *d, u8 port, Uxn *u) { | |||
211 | u16 adsr = 0; | 222 | u16 adsr = 0; |
212 | u16 addr = 0; | 223 | u16 addr = 0; |
213 | u8 pitch = d[0xf] & 0x7f; | 224 | u8 pitch = d[0xf] & 0x7f; |
214 | PEKDEV(adsr, 0x8); | 225 | adsr = PEEK2(d + 0x8); |
215 | PEKDEV(length, 0xa); | 226 | length = PEEK2(d + 0xa); |
216 | PEKDEV(addr, 0xc); | 227 | addr = PEEK2(d + 0xc); |
217 | u8 *data = &u->ram[addr]; | 228 | u8 *data = &u->ram[addr]; |
218 | u32 vol = MAX(d[0xe] >> 4, d[0xe] & 0xf) * 4 / 3; | 229 | u32 vol = MAX(d[0xe] >> 4, d[0xe] & 0xf) * 4 / 3; |
219 | bool loop = !(d[0xf] & 0x80); | 230 | bool loop = !(d[0xf] & 0x80); |
@@ -248,7 +259,7 @@ file_dei(u8 id, u8 *d, u8 port) { | |||
248 | case 0xc: | 259 | case 0xc: |
249 | case 0xd: { | 260 | case 0xd: { |
250 | res = file_read(c, &d[port], 1); | 261 | res = file_read(c, &d[port], 1); |
251 | POKDEV(0x2, res); | 262 | POKE2(d + 0x2, res); |
252 | break; | 263 | break; |
253 | } | 264 | } |
254 | } | 265 | } |
@@ -261,41 +272,41 @@ file_deo(u8 id, u8 *ram, u8 *d, u8 port) { | |||
261 | UxnFile *f = &uxn_file[id]; | 272 | UxnFile *f = &uxn_file[id]; |
262 | switch(port) { | 273 | switch(port) { |
263 | case 0x5: { | 274 | case 0x5: { |
264 | PEKDEV(a, 0x4); | 275 | a = PEEK2(d + 0x4); |
265 | PEKDEV(b, 0xa); | 276 | b = PEEK2(d + 0xa); |
266 | if(b > 0x10000 - a) { | 277 | if(b > 0x10000 - a) { |
267 | b = 0x10000 - a; | 278 | b = 0x10000 - a; |
268 | } | 279 | } |
269 | res = file_stat(f, &ram[a], b); | 280 | res = file_stat(f, &ram[a], b); |
270 | POKDEV(0x2, res); | 281 | POKE2(d + 0x2, res); |
271 | } break; | 282 | } break; |
272 | case 0x6: { | 283 | case 0x6: { |
273 | // TODO: no file deletion for now | 284 | // TODO: no file deletion for now |
274 | // res = file_delete(); | 285 | // res = file_delete(); |
275 | // POKDEV(0x2, res); | 286 | // POKE2(d + 0x2, res); |
276 | } break; | 287 | } break; |
277 | case 0x9: { | 288 | case 0x9: { |
278 | PEKDEV(a, 0x8); | 289 | a = PEEK2(d + 0x8); |
279 | res = file_init(f, &ram[a]); | 290 | res = file_init(f, &ram[a]); |
280 | POKDEV(0x2, res); | 291 | POKE2(d + 0x2, res); |
281 | } break; | 292 | } break; |
282 | case 0xd: { | 293 | case 0xd: { |
283 | PEKDEV(a, 0xc); | 294 | a = PEEK2(d + 0xc); |
284 | PEKDEV(b, 0xa); | 295 | b = PEEK2(d + 0xa); |
285 | if(b > 0x10000 - a) { | 296 | if(b > 0x10000 - a) { |
286 | b = 0x10000 - a; | 297 | b = 0x10000 - a; |
287 | } | 298 | } |
288 | res = file_read(f, &ram[a], b); | 299 | res = file_read(f, &ram[a], b); |
289 | POKDEV(0x2, res); | 300 | POKE2(d + 0x2, res); |
290 | } break; | 301 | } break; |
291 | case 0xf: { | 302 | case 0xf: { |
292 | PEKDEV(a, 0xe); | 303 | a = PEEK2(d + 0xe); |
293 | PEKDEV(b, 0xa); | 304 | b = PEEK2(d + 0xa); |
294 | if(b > 0x10000 - a) { | 305 | if(b > 0x10000 - a) { |
295 | b = 0x10000 - a; | 306 | b = 0x10000 - a; |
296 | } | 307 | } |
297 | res = file_write(f, &ram[a], b, d[0x7]); | 308 | res = file_write(f, &ram[a], b, d[0x7]); |
298 | POKDEV(0x2, res); | 309 | POKE2(d + 0x2, res); |
299 | } break; | 310 | } break; |
300 | } | 311 | } |
301 | } | 312 | } |
@@ -313,16 +324,42 @@ console_deo(u8 *d, u8 port) { | |||
313 | } | 324 | } |
314 | } | 325 | } |
315 | 326 | ||
327 | #define RAM_PAGES 0x10 | ||
328 | |||
329 | static void | ||
330 | system_cmd(u8 *ram, u16 addr) { | ||
331 | // if(ram[addr] == 0x01) { | ||
332 | // u16 i, length = PEEK2(ram + addr + 1); | ||
333 | // u16 a_page = PEEK2(ram + addr + 1 + 2); | ||
334 | // u16 a_addr = PEEK2(ram + addr + 1 + 4); | ||
335 | // u16 b_addr = PEEK2(ram + addr + 1 + 8); | ||
336 | // u8 *rom = uxn_rom; | ||
337 | // for(i = 0; i < length; i++) { | ||
338 | // switch (a_page % RAM_PAGES) { | ||
339 | // case 0: { rom = uxn_rom; } break; | ||
340 | // case 1: { rom = uxn_rom_2; } break; | ||
341 | // case 2: { rom = uxn_rom_3; } break; | ||
342 | // case 3: { rom = uxn_rom_4; } break; | ||
343 | // case 4: { rom = uxn_rom_5; } break; | ||
344 | // case 5: { rom = uxn_rom_6; } break; | ||
345 | // case 6: { rom = uxn_rom_7; } break; | ||
346 | // } | ||
347 | // ram[(u16)(b_addr + i)] = rom[(u16)(a_addr + i)]; | ||
348 | // } | ||
349 | // } | ||
350 | } | ||
351 | |||
316 | void | 352 | void |
317 | system_deo(Uxn *u, u8 *d, u8 port) { | 353 | system_deo(Uxn *u, u8 *d, u8 port) { |
318 | switch(port) { | 354 | switch(port) { |
319 | case 0x2: u->wst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10000)); break; | 355 | case 0x3: { |
320 | case 0x3: u->rst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10100)); break; | 356 | system_cmd(u->ram, PEEK2(d + 2)); |
357 | } break; | ||
321 | } | 358 | } |
322 | } | 359 | } |
323 | 360 | ||
324 | u8 | 361 | u8 |
325 | emu_dei(Uxn *u, u8 addr) { | 362 | uxn_dei(Uxn *u, u8 addr) { |
326 | u8 p = addr & 0x0f, d = addr & 0xf0; | 363 | u8 p = addr & 0x0f, d = addr & 0xf0; |
327 | switch(d) { | 364 | switch(d) { |
328 | case 0x20: return screen_dei(&u->dev[d], p); | 365 | case 0x20: return screen_dei(&u->dev[d], p); |
@@ -338,24 +375,23 @@ emu_dei(Uxn *u, u8 addr) { | |||
338 | } | 375 | } |
339 | 376 | ||
340 | void | 377 | void |
341 | emu_deo(Uxn *u, u8 addr, u8 v) { | 378 | uxn_deo(Uxn *u, u8 addr) { |
342 | u8 p = addr & 0x0f, d = addr & 0xf0; | 379 | u8 p = addr & 0x0f, d = addr & 0xf0; |
343 | u->dev[addr] = v; | 380 | switch(d) { |
344 | switch(d) { | 381 | case 0x00: |
345 | case 0x00: | 382 | system_deo(u, &u->dev[d], p); |
346 | system_deo(u, &u->dev[d], p); | 383 | if(p > 0x7 && p < 0xe) |
347 | if(p > 0x7 && p < 0xe) | 384 | putcolors(&u->dev[0x8]); |
348 | putcolors(&u->dev[0x8]); | 385 | break; |
349 | break; | 386 | case 0x10: console_deo(&u->dev[d], p); break; |
350 | case 0x10: console_deo(&u->dev[d], p); break; | 387 | case 0x20: screen_deo(u->ram, &u->dev[d], p); break; |
351 | case 0x20: screen_deo(u->ram, &u->dev[d], p); break; | 388 | case 0x30: audio_deo(0, &u->dev[d], p, u); break; |
352 | case 0x30: audio_deo(0, &u->dev[d], p, u); break; | 389 | case 0x40: audio_deo(1, &u->dev[d], p, u); break; |
353 | case 0x40: audio_deo(1, &u->dev[d], p, u); break; | 390 | case 0x50: audio_deo(2, &u->dev[d], p, u); break; |
354 | case 0x50: audio_deo(2, &u->dev[d], p, u); break; | 391 | case 0x60: audio_deo(3, &u->dev[d], p, u); break; |
355 | case 0x60: audio_deo(3, &u->dev[d], p, u); break; | 392 | case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break; |
356 | case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break; | 393 | case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break; |
357 | case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break; | 394 | } |
358 | } | ||
359 | } | 395 | } |
360 | 396 | ||
361 | void | 397 | void |
@@ -363,7 +399,7 @@ init_uxn(Uxn *u) { | |||
363 | // Initialize uxn. | 399 | // Initialize uxn. |
364 | u32 fill = 0; | 400 | u32 fill = 0; |
365 | dma_fill(umem, fill, 0x10300, 3); | 401 | dma_fill(umem, fill, 0x10300, 3); |
366 | uxn_boot(u, umem, emu_dei, emu_deo); | 402 | uxn_boot(u, umem, uxn_dei, uxn_deo); |
367 | 403 | ||
368 | // Copy rom to VM. | 404 | // Copy rom to VM. |
369 | memcpy(u->ram + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); | 405 | memcpy(u->ram + PAGE_PROGRAM, uxn_rom, sizeof(uxn_rom)); |
@@ -379,16 +415,16 @@ handle_input(Uxn *u) { | |||
379 | case CONTROL_CONTROLLER: { | 415 | case CONTROL_CONTROLLER: { |
380 | u8 *d = &u->dev[0x80]; | 416 | u8 *d = &u->dev[0x80]; |
381 | d[2] = 0; | 417 | d[2] = 0; |
382 | uxn_eval(u, GETVEC(d)); | 418 | uxn_eval(u, PEEK2(d)); |
383 | d[3] = 0; | 419 | d[3] = 0; |
384 | } break; | 420 | } break; |
385 | case CONTROL_MOUSE: { | 421 | case CONTROL_MOUSE: { |
386 | u8 *d = &u->dev[0x90]; | 422 | u8 *d = &u->dev[0x90]; |
387 | d[6] = 0; | 423 | d[6] = 0; |
388 | d[7] = 0; | 424 | d[7] = 0; |
389 | POKDEV(0x2, -10); | 425 | POKE2(d + 0x2, -10); |
390 | POKDEV(0x4, -10); | 426 | POKE2(d + 0x4, -10); |
391 | uxn_eval(u, GETVEC(d)); | 427 | uxn_eval(u, PEEK2(d)); |
392 | } break; | 428 | } break; |
393 | case CONTROL_KEYBOARD: { | 429 | case CONTROL_KEYBOARD: { |
394 | toggle_keyboard(); | 430 | toggle_keyboard(); |
@@ -451,7 +487,7 @@ handle_input(Uxn *u) { | |||
451 | } | 487 | } |
452 | 488 | ||
453 | if (key_prev != key_curr) { | 489 | if (key_prev != key_curr) { |
454 | uxn_eval(u, GETVEC(d)); | 490 | uxn_eval(u, PEEK2(d)); |
455 | } | 491 | } |
456 | d[3] = 0; | 492 | d[3] = 0; |
457 | } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) { | 493 | } else if (ctrl_methods[ctrl_idx] == CONTROL_MOUSE) { |
@@ -500,10 +536,10 @@ handle_input(Uxn *u) { | |||
500 | } | 536 | } |
501 | 537 | ||
502 | // Eval mouse. | 538 | // Eval mouse. |
503 | POKDEV(0x2, mouse.x); | 539 | POKE2(d + 0x2, mouse.x); |
504 | POKDEV(0x4, mouse.y); | 540 | POKE2(d + 0x4, mouse.y); |
505 | if (event) { | 541 | if (event) { |
506 | uxn_eval(u, GETVEC(d)); | 542 | uxn_eval(u, PEEK2(d)); |
507 | } | 543 | } |
508 | } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { | 544 | } else if (ctrl_methods[ctrl_idx] == CONTROL_KEYBOARD) { |
509 | u8 *d = &u->dev[0x80]; | 545 | u8 *d = &u->dev[0x80]; |
@@ -549,7 +585,7 @@ handle_input(Uxn *u) { | |||
549 | d[3] = symbol; | 585 | d[3] = symbol; |
550 | } break; | 586 | } break; |
551 | } | 587 | } |
552 | uxn_eval(u, GETVEC(d)); | 588 | uxn_eval(u, PEEK2(d)); |
553 | d[3] = 0; | 589 | d[3] = 0; |
554 | } | 590 | } |
555 | } | 591 | } |
@@ -588,7 +624,7 @@ main(void) { | |||
588 | while(true) { | 624 | while(true) { |
589 | bios_vblank_wait(); | 625 | bios_vblank_wait(); |
590 | PROF(handle_input(&u), input_cycles); | 626 | PROF(handle_input(&u), input_cycles); |
591 | PROF(uxn_eval(&u, GETVEC(&u.dev[0x20])), eval_cycles); | 627 | PROF(uxn_eval(&u, PEEK2(&u.dev[0x20])), eval_cycles); |
592 | PROF(sound_mix(), mix_cycles); | 628 | PROF(sound_mix(), mix_cycles); |
593 | PROF_SHOW(); | 629 | PROF_SHOW(); |
594 | PROF(flipbuf(&ppu), flip_cycles); | 630 | PROF(flipbuf(&ppu), flip_cycles); |