~rabbits/uxn

fd84ff44d707976e05b896b2d9c2891450796090 — Devine Lu Linvega a month ago 2279764
Initial draft for MMU
6 files changed, 82 insertions(+), 11 deletions(-)

M src/devices/system.c
M src/devices/system.h
M src/uxn.c
M src/uxncli.c
M src/uxnemu.c
A test.tal
M src/devices/system.c => src/devices/system.c +38 -2
@@ 1,4 1,5 @@
#include <stdio.h>
#include <stdlib.h>

#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;

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/uxn.c => src/uxn.c +3 -3
@@ 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;

M src/uxncli.c => src/uxncli.c +2 -1
@@ 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");

M src/uxnemu.c => src/uxnemu.c +5 -5
@@ 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);

A test.tal => test.tal +28 -0
@@ 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