~vertigo/forthbox

e44c37514cf8fae1c826af0e861c3928fdab9b51 — Samuel A. Falvo II 4 months ago 9c012ac
Refactor address decode logic.

This patch should make it easier to relocate emulator I/O to any
arbitrary location in the 65816's address space.
1 files changed, 43 insertions(+), 28 deletions(-)

M emulator/main.c
M emulator/main.c => emulator/main.c +43 -28
@@ 23,8 23,9 @@
#define THROTTLE_TICKS		40000

/* Determines the bank for MVP/MVN-block I/O access */

#define BLOCK_IO_BANK		0xFD
#define EMU_IO_BASE			0x00FE00
#define EMU_IO_LIMIT		0x00FEFF

static uint32_t cpu_inst_count;
static uint32_t most_recent_insn;


@@ 344,6 345,31 @@ static void io_write(uint32_t addr, uint8_t value)
	CPU_abort();
}

static bool
addressing_emulator_io(uint32_t addr) {
	return (addr >= EMU_IO_BASE && addr <= EMU_IO_LIMIT);
}

static bool
addressing_ram(uint32_t addr) {
	return addr < sizeof(ram);
}

static bool
addressing_z80_io(uint32_t addr) {
	return (addr >= 0xFF0000 && addr <= 0xFFFFFF);
}

static bool
addressing_video_ram(uint32_t addr) {
	return (addr >> 16) == 0xFE;
}

static bool
addressing_block_io_bank(uint32_t addr) {
	return (addr >> 16) == BLOCK_IO_BANK;
}

uint8_t MEM_readMem(uint32_t addr, uint32_t unused_timestamp, uint32_t emul_flags)
{
	addr &= 0xFFFFFF;	// bug in lib65816; sometimes $FF000000 <= addr <= $FFFFFFFF!  Why?


@@ 353,13 379,9 @@ uint8_t MEM_readMem(uint32_t addr, uint32_t unused_timestamp, uint32_t emul_flag
		cpu_inst_count++;
	}

	if ((addr >> 16) == BLOCK_IO_BANK)
		addr = 0xFE00 + dma;

	if ((addr >> 16) == 0xFE)
		return video_read_ram(addr);

	if(addr >= 0xFF0000 && addr <= 0xFFFFFF) { // Z80 I/O space
	if(addressing_block_io_bank(addr)) addr = EMU_IO_BASE + dma;
	if(addressing_video_ram(addr)) return video_read_ram(addr);
	if(addressing_z80_io(addr)) {
		int ioaddr = addr & 0xFF;
		switch(ioaddr) {
		case 0: case 1:


@@ 369,32 391,27 @@ uint8_t MEM_readMem(uint32_t addr, uint32_t unused_timestamp, uint32_t emul_flag
			return 0xFF;
		}
	}

	if (addr >= 0xFE00 && addr < 0xFF00) {
	if(addressing_emulator_io(addr)) {
		/* Don't cause I/O when using debug trace read */
		if (g_debug)
			return 0xFF;
		else
			return io_read(addr);
	} else if (addr < sizeof(ram))
		return ram[addr];
	else {
		if (!g_debug) {
			fprintf(stderr, "Invalid mem read %x (at K:PC $%06lX)\n", addr, most_recent_insn);
		}
		CPU_abort();
		return 0xFF;
	}
	if(addressing_ram(addr)) return ram[addr];

	if (!g_debug) {
		fprintf(stderr, "Invalid mem read %x (at K:PC $%06lX)\n", addr, most_recent_insn);
	}
	CPU_abort();
	return 0xFF;
}

void MEM_writeMem(uint32_t addr, uint8_t value, uint32_t unused_timestamp)
{
	if ((addr >> 16) == BLOCK_IO_BANK)
		addr = 0xFE00 + dma;

	if ((addr >> 16) == 0xFE)
		video_write_ram(addr, value);
	else if (addr >= 0xFF0000 && addr <= 0xFFFFFF) { // Z80 I/O space
	if(addressing_block_io_bank(addr)) addr = EMU_IO_BASE + dma;
	else if(addressing_video_ram(addr)) video_write_ram(addr, value);
	else if(addressing_z80_io(addr)) {
		int ioaddr = addr & 0xFF;
		switch(ioaddr) {
		case 0: case 1:


@@ 406,10 423,8 @@ void MEM_writeMem(uint32_t addr, uint8_t value, uint32_t unused_timestamp)
			break;
		}
	}
	else if (addr >= 0xFE00 && addr < 0xFF00)
		io_write(addr, value);
	else if (addr < sizeof(ram))
		ram[addr] = value;
	else if(addressing_emulator_io(addr)) io_write(addr, value);
	else if(addressing_ram(addr)) ram[addr] = value;
	else {
	  fprintf(stderr, "Invalid mem write %X := %02X (at K:PC $%06lX)\n", addr, value, most_recent_insn);
		CPU_abort();