From fd84ff44d707976e05b896b2d9c2891450796090 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Sat, 28 Jan 2023 14:45:31 -0800 Subject: [PATCH] Initial draft for MMU --- src/devices/system.c | 40 ++++++++++++++++++++++++++++++++++++++-- src/devices/system.h | 6 ++++++ src/uxn.c | 6 +++--- src/uxncli.c | 3 ++- src/uxnemu.c | 10 +++++----- test.tal | 28 ++++++++++++++++++++++++++++ 6 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 test.tal diff --git a/src/devices/system.c b/src/devices/system.c index 344056b..8488056 100644 --- a/src/devices/system.c +++ b/src/devices/system.c @@ -1,4 +1,5 @@ #include +#include #include "../uxn.h" #include "system.h" @@ -57,14 +58,49 @@ uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr) return 0; } +/* MMU */ + +Uint8 * +mmu_init(Mmu *m, Uint16 pages) +{ + m->length = pages; + m->pages = (Uint8 *)calloc(0x10000 * pages, sizeof(Uint8)); + return m->pages; +} + +void +mmu_copy(Uint8 *ram, Uint16 length, Uint16 src_page, Uint16 src_addr, Uint16 dst_page, Uint16 dst_addr) +{ + Uint16 i; + for(i = 0; i < length; i++) { + ram[dst_page * 0x10000 + dst_addr + i] = ram[src_page * 0x10000 + src_addr + i]; + } +} + +void +mmu_eval(Uint8 *ram, Uint16 addr) +{ + Uint16 a = addr; + Uint8 o = ram[a++]; + if(o == 1) { + Uint16 length = (ram[a++] << 8) + ram[a++]; + Uint16 src_page = ((ram[a++] << 8) + ram[a++]) % 16, src_addr = (ram[a++] << 8) + ram[a++]; + Uint16 dst_page = ((ram[a++] << 8) + ram[a++]) % 16, dst_addr = (ram[a++] << 8) + ram[a]; + mmu_copy(ram, length, src_page, src_addr, dst_page, dst_addr); + } +} + /* IO */ void system_deo(Uxn *u, Uint8 *d, Uint8 port) { + Uint16 a; switch(port) { - case 0x2: u->wst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10000)); break; - case 0x3: u->rst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10100)); break; + case 0x3: + PEKDEV(a, 0x2); + mmu_eval(u->ram, a); + break; case 0xe: if(u->wst->ptr || u->rst->ptr) system_inspect(u); break; diff --git a/src/devices/system.h b/src/devices/system.h index 9d8117d..6be1005 100644 --- a/src/devices/system.h +++ b/src/devices/system.h @@ -11,3 +11,9 @@ WITH REGARD TO THIS SOFTWARE. void system_inspect(Uxn *u); void system_deo(Uxn *u, Uint8 *d, Uint8 port); + +typedef struct { + Uint8 length, *pages; +} Mmu; + +Uint8 *mmu_init(Mmu *m, Uint16 pages); diff --git a/src/uxn.c b/src/uxn.c index 0d33674..967040d 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -100,9 +100,9 @@ uxn_boot(Uxn *u, Uint8 *ram, Dei *dei, Deo *deo) char *cptr = (char *)u; for(i = 0; i < sizeof(*u); i++) cptr[i] = 0x00; - u->wst = (Stack *)(ram + 0x10000); - u->rst = (Stack *)(ram + 0x10100); - u->dev = (Uint8 *)(ram + 0x10200); + u->wst = (Stack *)(ram + 0xf0000); + u->rst = (Stack *)(ram + 0xf0100); + u->dev = (Uint8 *)(ram + 0xf0200); u->ram = ram; u->dei = dei; u->deo = deo; diff --git a/src/uxncli.c b/src/uxncli.c index 02a1c29..94d7935 100644 --- a/src/uxncli.c +++ b/src/uxncli.c @@ -78,9 +78,10 @@ main(int argc, char **argv) { Uxn u; int i; + Mmu mmu; if(argc < 2) return emu_error("Usage", "uxncli game.rom args"); - if(!uxn_boot(&u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) + if(!uxn_boot(&u, mmu_init(&mmu, 16), emu_dei, emu_deo)) return emu_error("Boot", "Failed"); if(!load_rom(&u, argv[1])) return emu_error("Load", "Failed"); diff --git a/src/uxnemu.c b/src/uxnemu.c index 36bac08..c4bc7a4 100644 --- a/src/uxnemu.c +++ b/src/uxnemu.c @@ -53,6 +53,7 @@ static Uint32 stdin_event, audio0_event; static Uint64 exec_deadline, deadline_interval, ms_interval; char *rom_path; +Mmu mmu; static int error(char *msg, const char *err) @@ -262,8 +263,8 @@ init(void) static int start(Uxn *u, char *rom) { - free(u->ram); - if(!uxn_boot(u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) + free(mmu.pages); + if(!uxn_boot(u, mmu_init(&mmu, 16), emu_dei, emu_deo)) return error("Boot", "Failed to start uxn."); if(!load_rom(u, rom)) return error("Boot", "Failed to load rom."); @@ -453,7 +454,8 @@ run(Uxn *u) } else SDL_WaitEvent(NULL); } - return error("SDL_WaitEvent", SDL_GetError());; + return error("SDL_WaitEvent", SDL_GetError()); + ; } int @@ -462,11 +464,9 @@ main(int argc, char **argv) SDL_DisplayMode DM; Uxn u = {0}; int i, loaded = 0; - if(!init()) return error("Init", "Failed to initialize emulator."); screen_resize(&uxn_screen, WIDTH, HEIGHT); - /* set default zoom */ if(SDL_GetCurrentDisplayMode(0, &DM) == 0) set_zoom(DM.w / 1280); diff --git a/test.tal b/test.tal new file mode 100644 index 0000000..638c918 --- /dev/null +++ b/test.tal @@ -0,0 +1,28 @@ + +|0100 + + ;mmu-write #02 DEO2 + ;mmu-read #02 DEO2 + ;mmu-read2 #02 DEO2 + #0200 pstr #0a18 DEO + #010e DEO + #010f DEO + +BRK + +@pstr ( str* -- ) + + &w + LDAk #18 DEO + INC2 LDAk ,&w JCN + POP2 + +JMP2r + +@mmu-write 01 0100 0000 =hello 0001 0800 +@mmu-read 01 0100 0001 0800 0000 0200 +@mmu-read2 01 0100 0001 0800 0000 0205 + +@hello "hello $1 + +