Added MMU operation

This commit is contained in:
Devine Lu Linvega 2023-01-28 16:47:41 -08:00
parent 4020917b2e
commit 7603ddf9cc
4 changed files with 53 additions and 15 deletions

View File

@ -1,10 +1,11 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "../uxn.h" #include "../uxn.h"
#include "system.h" #include "system.h"
/* /*
Copyright (c) 2022 Devine Lu Linvega, Andrew Alderwick Copyright (c) 2022-2023 Devine Lu Linvega, Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -42,27 +43,56 @@ int
uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr) uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr)
{ {
Uint8 *d = &u->dev[0x00]; Uint8 *d = &u->dev[0x00];
if(instr & 0x40) Uint16 handler = GETVEC(d);
u->rst->err = err; if(handler) {
else u->wst->ptr = 4;
u->wst->err = err; u->wst->dat[0] = addr >> 0x8;
if(GETVEC(d)) u->wst->dat[1] = addr & 0xff;
uxn_eval(u, GETVEC(d)); u->wst->dat[2] = instr;
else { u->wst->dat[3] = err;
return uxn_eval(u, handler);
} else {
system_inspect(u); system_inspect(u);
fprintf(stderr, "%s %s, by %02x at 0x%04x.\n", (instr & 0x40) ? "Return-stack" : "Working-stack", errors[err - 1], instr, addr); fprintf(stderr, "%s %s, by %02x at 0x%04x.\n", (instr & 0x40) ? "Return-stack" : "Working-stack", errors[err - 1], instr, addr);
} }
return 0; 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_eval(Uint8 *ram, Uint16 addr)
{
Uint16 a = addr, i = 0;
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];
for(i = 0; i < length; i++)
ram[dst_page * 0x10000 + dst_addr + i] = ram[src_page * 0x10000 + src_addr + i];
}
}
/* IO */ /* IO */
void void
system_deo(Uxn *u, Uint8 *d, Uint8 port) system_deo(Uxn *u, Uint8 *d, Uint8 port)
{ {
Uint16 a;
switch(port) { switch(port) {
case 0x2: u->wst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10000)); break; case 0x3:
case 0x3: u->rst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10100)); break; PEKDEV(a, 0x2);
mmu_eval(u->ram, a);
break;
case 0xe: case 0xe:
if(u->wst->ptr || u->rst->ptr) system_inspect(u); if(u->wst->ptr || u->rst->ptr) system_inspect(u);
break; break;

View File

@ -11,3 +11,9 @@ WITH REGARD TO THIS SOFTWARE.
void system_inspect(Uxn *u); void system_inspect(Uxn *u);
void system_deo(Uxn *u, Uint8 *d, Uint8 port); void system_deo(Uxn *u, Uint8 *d, Uint8 port);
typedef struct {
Uint8 length, *pages;
} Mmu;
Uint8 *mmu_init(Mmu *m, Uint16 pages);

View File

@ -225,6 +225,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
Uxn u; Uxn u;
Mmu m;
int i; int i;
char expirations[8]; char expirations[8];
struct pollfd fds[2]; struct pollfd fds[2];
@ -232,7 +233,7 @@ main(int argc, char **argv)
if(argc < 2) if(argc < 2)
return emu_error("Usage", "uxn11 game.rom args"); return emu_error("Usage", "uxn11 game.rom args");
rom_path = argv[1]; rom_path = argv[1];
if(!uxn_boot(&u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) if(!uxn_boot(&u, mmu_init(&m, 16), emu_dei, emu_deo))
return emu_error("Boot", "Failed"); return emu_error("Boot", "Failed");
/* start sequence */ /* start sequence */
if(!emu_start(&u, rom_path)) if(!emu_start(&u, rom_path))

View File

@ -7,7 +7,7 @@
#include "devices/datetime.h" #include "devices/datetime.h"
/* /*
Copyright (c) 2021 Devine Lu Linvega Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -37,8 +37,8 @@ console_input(Uxn *u, char c)
static void static void
console_deo(Uint8 *d, Uint8 port) console_deo(Uint8 *d, Uint8 port)
{ {
FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr : FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr
0; : 0;
if(fd) { if(fd) {
fputc(d[port], fd); fputc(d[port], fd);
fflush(fd); fflush(fd);
@ -78,9 +78,10 @@ main(int argc, char **argv)
{ {
Uxn u; Uxn u;
int i; int i;
Mmu mmu;
if(argc < 2) if(argc < 2)
return emu_error("Usage", "uxncli game.rom args"); 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"); return emu_error("Boot", "Failed");
if(!load_rom(&u, argv[1])) if(!load_rom(&u, argv[1]))
return emu_error("Load", "Failed"); return emu_error("Load", "Failed");