... | ... |
@@ -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 |
+ |