| ... | ... |
@@ -1,4 +1,5 @@ |
| 1 | 1 |
#include <stdio.h> |
| 2 |
+#include <stdlib.h> |
|
| 2 | 3 |
|
| 3 | 4 |
#include "../uxn.h" |
| 4 | 5 |
#include "system.h" |
| ... | ... |
@@ -57,14 +58,49 @@ uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr) |
| 57 | 58 |
return 0; |
| 58 | 59 |
} |
| 59 | 60 |
|
| 61 |
+/* MMU */ |
|
| 62 |
+ |
|
| 63 |
+Uint8 * |
|
| 64 |
+mmu_init(Mmu *m, Uint16 pages) |
|
| 65 |
+{
|
|
| 66 |
+ m->length = pages; |
|
| 67 |
+ m->pages = (Uint8 *)calloc(0x10000 * pages, sizeof(Uint8)); |
|
| 68 |
+ return m->pages; |
|
| 69 |
+} |
|
| 70 |
+ |
|
| 71 |
+void |
|
| 72 |
+mmu_copy(Uint8 *ram, Uint16 length, Uint16 src_page, Uint16 src_addr, Uint16 dst_page, Uint16 dst_addr) |
|
| 73 |
+{
|
|
| 74 |
+ Uint16 i; |
|
| 75 |
+ for(i = 0; i < length; i++) {
|
|
| 76 |
+ ram[dst_page * 0x10000 + dst_addr + i] = ram[src_page * 0x10000 + src_addr + i]; |
|
| 77 |
+ } |
|
| 78 |
+} |
|
| 79 |
+ |
|
| 80 |
+void |
|
| 81 |
+mmu_eval(Uint8 *ram, Uint16 addr) |
|
| 82 |
+{
|
|
| 83 |
+ Uint16 a = addr; |
|
| 84 |
+ Uint8 o = ram[a++]; |
|
| 85 |
+ if(o == 1) {
|
|
| 86 |
+ Uint16 length = (ram[a++] << 8) + ram[a++]; |
|
| 87 |
+ Uint16 src_page = ((ram[a++] << 8) + ram[a++]) % 16, src_addr = (ram[a++] << 8) + ram[a++]; |
|
| 88 |
+ Uint16 dst_page = ((ram[a++] << 8) + ram[a++]) % 16, dst_addr = (ram[a++] << 8) + ram[a]; |
|
| 89 |
+ mmu_copy(ram, length, src_page, src_addr, dst_page, dst_addr); |
|
| 90 |
+ } |
|
| 91 |
+} |
|
| 92 |
+ |
|
| 60 | 93 |
/* IO */ |
| 61 | 94 |
|
| 62 | 95 |
void |
| 63 | 96 |
system_deo(Uxn *u, Uint8 *d, Uint8 port) |
| 64 | 97 |
{
|
| 98 |
+ Uint16 a; |
|
| 65 | 99 |
switch(port) {
|
| 66 |
- case 0x2: u->wst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10000)); break; |
|
| 67 |
- case 0x3: u->rst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10100)); break; |
|
| 100 |
+ case 0x3: |
|
| 101 |
+ PEKDEV(a, 0x2); |
|
| 102 |
+ mmu_eval(u->ram, a); |
|
| 103 |
+ break; |
|
| 68 | 104 |
case 0xe: |
| 69 | 105 |
if(u->wst->ptr || u->rst->ptr) system_inspect(u); |
| 70 | 106 |
break; |
| ... | ... |
@@ -100,9 +100,9 @@ uxn_boot(Uxn *u, Uint8 *ram, Dei *dei, Deo *deo) |
| 100 | 100 |
char *cptr = (char *)u; |
| 101 | 101 |
for(i = 0; i < sizeof(*u); i++) |
| 102 | 102 |
cptr[i] = 0x00; |
| 103 |
- u->wst = (Stack *)(ram + 0x10000); |
|
| 104 |
- u->rst = (Stack *)(ram + 0x10100); |
|
| 105 |
- u->dev = (Uint8 *)(ram + 0x10200); |
|
| 103 |
+ u->wst = (Stack *)(ram + 0xf0000); |
|
| 104 |
+ u->rst = (Stack *)(ram + 0xf0100); |
|
| 105 |
+ u->dev = (Uint8 *)(ram + 0xf0200); |
|
| 106 | 106 |
u->ram = ram; |
| 107 | 107 |
u->dei = dei; |
| 108 | 108 |
u->deo = deo; |
| ... | ... |
@@ -78,9 +78,10 @@ main(int argc, char **argv) |
| 78 | 78 |
{
|
| 79 | 79 |
Uxn u; |
| 80 | 80 |
int i; |
| 81 |
+ Mmu mmu; |
|
| 81 | 82 |
if(argc < 2) |
| 82 | 83 |
return emu_error("Usage", "uxncli game.rom args");
|
| 83 |
- if(!uxn_boot(&u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) |
|
| 84 |
+ if(!uxn_boot(&u, mmu_init(&mmu, 16), emu_dei, emu_deo)) |
|
| 84 | 85 |
return emu_error("Boot", "Failed");
|
| 85 | 86 |
if(!load_rom(&u, argv[1])) |
| 86 | 87 |
return emu_error("Load", "Failed");
|
| ... | ... |
@@ -53,6 +53,7 @@ static Uint32 stdin_event, audio0_event; |
| 53 | 53 |
static Uint64 exec_deadline, deadline_interval, ms_interval; |
| 54 | 54 |
|
| 55 | 55 |
char *rom_path; |
| 56 |
+Mmu mmu; |
|
| 56 | 57 |
|
| 57 | 58 |
static int |
| 58 | 59 |
error(char *msg, const char *err) |
| ... | ... |
@@ -262,8 +263,8 @@ init(void) |
| 262 | 263 |
static int |
| 263 | 264 |
start(Uxn *u, char *rom) |
| 264 | 265 |
{
|
| 265 |
- free(u->ram); |
|
| 266 |
- if(!uxn_boot(u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) |
|
| 266 |
+ free(mmu.pages); |
|
| 267 |
+ if(!uxn_boot(u, mmu_init(&mmu, 16), emu_dei, emu_deo)) |
|
| 267 | 268 |
return error("Boot", "Failed to start uxn.");
|
| 268 | 269 |
if(!load_rom(u, rom)) |
| 269 | 270 |
return error("Boot", "Failed to load rom.");
|
| ... | ... |
@@ -453,7 +454,8 @@ run(Uxn *u) |
| 453 | 454 |
} else |
| 454 | 455 |
SDL_WaitEvent(NULL); |
| 455 | 456 |
} |
| 456 |
- return error("SDL_WaitEvent", SDL_GetError());;
|
|
| 457 |
+ return error("SDL_WaitEvent", SDL_GetError());
|
|
| 458 |
+ ; |
|
| 457 | 459 |
} |
| 458 | 460 |
|
| 459 | 461 |
int |
| ... | ... |
@@ -462,11 +464,9 @@ main(int argc, char **argv) |
| 462 | 464 |
SDL_DisplayMode DM; |
| 463 | 465 |
Uxn u = {0};
|
| 464 | 466 |
int i, loaded = 0; |
| 465 |
- |
|
| 466 | 467 |
if(!init()) |
| 467 | 468 |
return error("Init", "Failed to initialize emulator.");
|
| 468 | 469 |
screen_resize(&uxn_screen, WIDTH, HEIGHT); |
| 469 |
- |
|
| 470 | 470 |
/* set default zoom */ |
| 471 | 471 |
if(SDL_GetCurrentDisplayMode(0, &DM) == 0) |
| 472 | 472 |
set_zoom(DM.w / 1280); |
| 473 | 473 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 1 |
+ |
|
| 2 |
+|0100 |
|
| 3 |
+ |
|
| 4 |
+ ;mmu-write #02 DEO2 |
|
| 5 |
+ ;mmu-read #02 DEO2 |
|
| 6 |
+ ;mmu-read2 #02 DEO2 |
|
| 7 |
+ #0200 pstr #0a18 DEO |
|
| 8 |
+ #010e DEO |
|
| 9 |
+ #010f DEO |
|
| 10 |
+ |
|
| 11 |
+BRK |
|
| 12 |
+ |
|
| 13 |
+@pstr ( str* -- ) |
|
| 14 |
+ |
|
| 15 |
+ &w |
|
| 16 |
+ LDAk #18 DEO |
|
| 17 |
+ INC2 LDAk ,&w JCN |
|
| 18 |
+ POP2 |
|
| 19 |
+ |
|
| 20 |
+JMP2r |
|
| 21 |
+ |
|
| 22 |
+@mmu-write 01 0100 0000 =hello 0001 0800 |
|
| 23 |
+@mmu-read 01 0100 0001 0800 0000 0200 |
|
| 24 |
+@mmu-read2 01 0100 0001 0800 0000 0205 |
|
| 25 |
+ |
|
| 26 |
+@hello "hello $1 |
|
| 27 |
+ |
|
| 28 |
+ |