Added MMU operation
This commit is contained in:
parent
4020917b2e
commit
7603ddf9cc
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue