~rabbits/uxn11

7603ddf9cc694925ab6b36bdb230de3ab741e478 — Devine Lu Linvega a month ago 4020917
Added MMU operation
4 files changed, 53 insertions(+), 15 deletions(-)

M src/devices/system.c
M src/devices/system.h
M src/uxn11.c
M src/uxncli.c
M src/devices/system.c => src/devices/system.c +40 -10
@@ 1,10 1,11 @@
#include <stdio.h>
#include <stdlib.h>

#include "../uxn.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
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)
{
	Uint8 *d = &u->dev[0x00];
	if(instr & 0x40)
		u->rst->err = err;
	else
		u->wst->err = err;
	if(GETVEC(d))
		uxn_eval(u, GETVEC(d));
	else {
	Uint16 handler = GETVEC(d);
	if(handler) {
		u->wst->ptr = 4;
		u->wst->dat[0] = addr >> 0x8;
		u->wst->dat[1] = addr & 0xff;
		u->wst->dat[2] = instr;
		u->wst->dat[3] = err;
		return uxn_eval(u, handler);
	} else {
		system_inspect(u);
		fprintf(stderr, "%s %s, by %02x at 0x%04x.\n", (instr & 0x40) ? "Return-stack" : "Working-stack", errors[err - 1], instr, 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_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 */

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;

M src/devices/system.h => src/devices/system.h +6 -0
@@ 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);

M src/uxn11.c => src/uxn11.c +2 -1
@@ 225,6 225,7 @@ int
main(int argc, char **argv)
{
	Uxn u;
	Mmu m;
	int i;
	char expirations[8];
	struct pollfd fds[2];


@@ 232,7 233,7 @@ main(int argc, char **argv)
	if(argc < 2)
		return emu_error("Usage", "uxn11 game.rom args");
	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");
	/* start sequence */
	if(!emu_start(&u, rom_path))

M src/uxncli.c => src/uxncli.c +5 -4
@@ 7,7 7,7 @@
#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
purpose with or without fee is hereby granted, provided that the above


@@ 37,8 37,8 @@ console_input(Uxn *u, char c)
static void
console_deo(Uint8 *d, Uint8 port)
{
	FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr :
													0;
	FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr
												  : 0;
	if(fd) {
		fputc(d[port], fd);
		fflush(fd);


@@ 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");