changeset 1414:d94855080529

Move I2C EEPROM and NOR Flash functions out of romdb.c into new files
author Michael Pavone <pavone@retrodev.com>
date Fri, 23 Jun 2017 21:48:38 -0700
parents 3d7f668dce3d
children f7d653bb8899
files Makefile genesis.c genesis.h i2c.c i2c.h nor.c nor.h romdb.c romdb.h
diffstat 9 files changed, 490 insertions(+), 463 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Thu Jun 22 23:40:05 2017 -0700
+++ b/Makefile	Fri Jun 23 21:48:38 2017 -0700
@@ -127,7 +127,7 @@
 AUDIOOBJS=ym2612.o psg.o wave.o
 CONFIGOBJS=config.o tern.o util.o
 
-MAINOBJS=blastem.o system.o genesis.o debug.o gdb_remote.o vdp.o render_sdl.o ppm.o io.o romdb.o hash.o menu.o xband.o realtec.o $(TERMINAL) $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS)
+MAINOBJS=blastem.o system.o genesis.o debug.o gdb_remote.o vdp.o render_sdl.o ppm.o io.o romdb.o hash.o menu.o xband.o realtec.o i2c.o nor.o $(TERMINAL) $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS)
 
 ifeq ($(CPU),x86_64)
 CFLAGS+=-DX86_64 -m64
--- a/genesis.c	Thu Jun 22 23:40:05 2017 -0700
+++ b/genesis.c	Fri Jun 23 21:48:38 2017 -0700
@@ -5,6 +5,7 @@
 */
 #include "genesis.h"
 #include "blastem.h"
+#include "nor.h"
 #include <stdlib.h>
 #include <ctype.h>
 #include <time.h>
--- a/genesis.h	Thu Jun 22 23:40:05 2017 -0700
+++ b/genesis.h	Fri Jun 23 21:48:38 2017 -0700
@@ -16,6 +16,7 @@
 #include "io.h"
 #include "romdb.h"
 #include "arena.h"
+#include "i2c.h"
 
 typedef struct genesis_context genesis_context;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i2c.c	Fri Jun 23 21:48:38 2017 -0700
@@ -0,0 +1,250 @@
+#include "genesis.h"
+#include "util.h"
+
+enum {
+	I2C_IDLE,
+	I2C_START,
+	I2C_DEVICE_ACK,
+	I2C_ADDRESS_HI,
+	I2C_ADDRESS_HI_ACK,
+	I2C_ADDRESS,
+	I2C_ADDRESS_ACK,
+	I2C_READ,
+	I2C_READ_ACK,
+	I2C_WRITE,
+	I2C_WRITE_ACK
+};
+
+char * i2c_states[] = {
+	"idle",
+	"start",
+	"device ack",
+	"address hi",
+	"address hi ack",
+	"address",
+	"address ack",
+	"read",
+	"read_ack",
+	"write",
+	"write_ack"
+};
+
+void eeprom_init(eeprom_state *state, uint8_t *buffer, uint32_t size)
+{
+	state->slave_sda = 1;
+	state->host_sda = state->scl = 0;
+	state->buffer = buffer;
+	state->size = size;
+	state->state = I2C_IDLE;
+}
+
+void set_host_sda(eeprom_state *state, uint8_t val)
+{
+	if (state->scl) {
+		if (val & ~state->host_sda) {
+			//low to high, stop condition
+			state->state = I2C_IDLE;
+			state->slave_sda = 1;
+		} else if (~val & state->host_sda) {
+			//high to low, start condition
+			state->state = I2C_START;
+			state->slave_sda = 1;
+			state->counter = 8;
+		}
+	}
+	state->host_sda = val;
+}
+
+void set_scl(eeprom_state *state, uint8_t val)
+{
+	if (val & ~state->scl) {
+		//low to high transition
+		switch (state->state)
+		{
+		case I2C_START:
+		case I2C_ADDRESS_HI:
+		case I2C_ADDRESS:
+		case I2C_WRITE:
+			state->latch = state->host_sda | state->latch << 1;
+			state->counter--;
+			if (!state->counter) {
+				switch (state->state & 0x7F)
+				{
+				case I2C_START:
+					state->state = I2C_DEVICE_ACK;
+					break;
+				case I2C_ADDRESS_HI:
+					state->address = state->latch << 8;
+					state->state = I2C_ADDRESS_HI_ACK;
+					break;
+				case I2C_ADDRESS:
+					state->address |= state->latch;
+					state->state = I2C_ADDRESS_ACK;
+					break;
+				case I2C_WRITE:
+					state->buffer[state->address] = state->latch;
+					state->state = I2C_WRITE_ACK;
+					break;
+				}
+			}
+			break;
+		case I2C_DEVICE_ACK:
+			if (state->latch & 1) {
+				state->state = I2C_READ;
+				state->counter = 8;
+				if (state->size < 256) {
+					state->address = state->latch >> 1;
+				}
+				state->latch = state->buffer[state->address];
+			} else {
+				if (state->size < 256) {
+					state->address = state->latch >> 1;
+					state->state = I2C_WRITE;
+				} else if (state->size < 4096) {
+					state->address = (state->latch & 0xE) << 7;
+					state->state = I2C_ADDRESS;
+				} else {
+					state->state = I2C_ADDRESS_HI;
+				}
+				state->counter = 8;
+			}
+			break;
+		case I2C_ADDRESS_HI_ACK:
+			state->state = I2C_ADDRESS;
+			state->counter = 8;
+			break;
+		case I2C_ADDRESS_ACK:
+			state->state = I2C_WRITE;
+			state->address &= state->size-1;
+			state->counter = 8;
+			break;
+		case I2C_READ:
+			state->counter--;
+			if (!state->counter) {
+				state->state = I2C_READ_ACK;
+			}
+			break;
+		case I2C_READ_ACK:
+			state->state = I2C_READ;
+			state->counter = 8;
+			state->address++;
+			//TODO: page mask
+			state->address &= state->size-1;
+			state->latch = state->buffer[state->address];
+			break;
+		case I2C_WRITE_ACK:
+			state->state = I2C_WRITE;
+			state->counter = 8;
+			state->address++;
+			//TODO: page mask
+			state->address &= state->size-1;
+			break;
+		}
+	} else if (~val & state->scl) {
+		//high to low transition
+		switch (state->state & 0x7F)
+		{
+		case I2C_DEVICE_ACK:
+		case I2C_ADDRESS_HI_ACK:
+		case I2C_ADDRESS_ACK:
+		case I2C_READ_ACK:
+		case I2C_WRITE_ACK:
+			state->slave_sda = 0;
+			break;
+		case I2C_READ:
+			state->slave_sda = state->latch >> 7;
+			state->latch = state->latch << 1;
+			break;
+		default:
+			state->slave_sda = 1;
+			break;
+		}
+	}
+	state->scl = val;
+}
+
+uint8_t get_sda(eeprom_state *state)
+{
+	return state->host_sda & state->slave_sda;
+}
+
+eeprom_map *find_eeprom_map(uint32_t address, genesis_context *gen)
+{
+	for (int i = 0; i < gen->num_eeprom; i++)
+	{
+		if (address >= gen->eeprom_map[i].start && address <= gen->eeprom_map[i].end) {
+			return  gen->eeprom_map + i;
+		}
+	}
+	return NULL;
+}
+
+void * write_eeprom_i2c_w(uint32_t address, void * context, uint16_t value)
+{
+	genesis_context *gen = ((m68k_context *)context)->system;
+	eeprom_map *map = find_eeprom_map(address, gen);
+	if (!map) {
+		fatal_error("Could not find EEPROM map for address %X\n", address);
+	}
+	if (map->scl_mask) {
+		set_scl(&gen->eeprom, (value & map->scl_mask) != 0);
+	}
+	if (map->sda_write_mask) {
+		set_host_sda(&gen->eeprom, (value & map->sda_write_mask) != 0);
+	}
+	return context;
+}
+
+void * write_eeprom_i2c_b(uint32_t address, void * context, uint8_t value)
+{
+	genesis_context *gen = ((m68k_context *)context)->system;
+	eeprom_map *map = find_eeprom_map(address, gen);
+	if (!map) {
+		fatal_error("Could not find EEPROM map for address %X\n", address);
+	}
+
+	uint16_t expanded, mask;
+	if (address & 1) {
+		expanded = value;
+		mask = 0xFF;
+	} else {
+		expanded = value << 8;
+		mask = 0xFF00;
+	}
+	if (map->scl_mask & mask) {
+		set_scl(&gen->eeprom, (expanded & map->scl_mask) != 0);
+	}
+	if (map->sda_write_mask & mask) {
+		set_host_sda(&gen->eeprom, (expanded & map->sda_write_mask) != 0);
+	}
+	return context;
+}
+
+uint16_t read_eeprom_i2c_w(uint32_t address, void * context)
+{
+	genesis_context *gen = ((m68k_context *)context)->system;
+	eeprom_map *map = find_eeprom_map(address, gen);
+	if (!map) {
+		fatal_error("Could not find EEPROM map for address %X\n", address);
+	}
+	uint16_t ret = 0;
+	if (map->sda_read_bit < 16) {
+		ret = get_sda(&gen->eeprom) << map->sda_read_bit;
+	}
+	return ret;	
+}
+
+uint8_t read_eeprom_i2c_b(uint32_t address, void * context)
+{
+	genesis_context *gen = ((m68k_context *)context)->system;
+	eeprom_map *map = find_eeprom_map(address, gen);
+	if (!map) {
+		fatal_error("Could not find EEPROM map for address %X\n", address);
+	}
+	uint8_t bit = address & 1 ? map->sda_read_bit : map->sda_read_bit - 8;
+	uint8_t ret = 0;
+	if (bit < 8) {
+		ret = get_sda(&gen->eeprom) << bit;
+	}
+	return ret;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/i2c.h	Fri Jun 23 21:48:38 2017 -0700
@@ -0,0 +1,22 @@
+#ifndef I2C_H_
+#define I2C_H_
+
+typedef struct {
+	char        *buffer;
+	uint32_t    size;
+	uint16_t    address;
+	uint8_t     host_sda;
+	uint8_t     slave_sda;
+	uint8_t     scl;
+	uint8_t     state;
+	uint8_t     counter;
+	uint8_t     latch;
+} eeprom_state;
+
+void eeprom_init(eeprom_state *state, uint8_t *buffer, uint32_t size);
+void * write_eeprom_i2c_w(uint32_t address, void * context, uint16_t value);
+void * write_eeprom_i2c_b(uint32_t address, void * context, uint8_t value);
+uint16_t read_eeprom_i2c_w(uint32_t address, void * context);
+uint8_t read_eeprom_i2c_b(uint32_t address, void * context);
+
+#endif //I2C_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nor.c	Fri Jun 23 21:48:38 2017 -0700
@@ -0,0 +1,204 @@
+#include "genesis.h"
+#include <stdlib.h>
+#include <string.h>
+
+enum {
+	NOR_NORMAL,
+	NOR_PRODUCTID,
+	NOR_BOOTBLOCK
+};
+
+enum {
+	NOR_CMD_IDLE,
+	NOR_CMD_AA,
+	NOR_CMD_55
+};
+
+//Technically this value shoudl be slightly different between NTSC and PAL
+//as it's defined as 200 micro-seconds, not in clock cycles
+#define NOR_WRITE_PAUSE 10690 
+
+void nor_flash_init(nor_state *state, uint8_t *buffer, uint32_t size, uint32_t page_size, uint16_t product_id, uint8_t bus_flags)
+{
+	state->buffer = buffer;
+	state->page_buffer = malloc(page_size);
+	memset(state->page_buffer, 0xFF, page_size);
+	state->size = size;
+	state->page_size = page_size;
+	state->product_id = product_id;
+	state->last_write_cycle = 0xFFFFFFFF;
+	state->mode = NOR_NORMAL;
+	state->cmd_state = NOR_CMD_IDLE;
+	state->alt_cmd = 0;
+	state->bus_flags = bus_flags;
+}
+
+void nor_run(nor_state *state, uint32_t cycle)
+{
+	if (state->last_write_cycle == 0xFFFFFFFF) {
+		return;
+	}
+	if (cycle - state->last_write_cycle >= NOR_WRITE_PAUSE) {
+		state->last_write_cycle = 0xFFFFFFFF;
+		for (uint32_t i = 0; i < state->page_size; i++) {
+			state->buffer[state->current_page + i] = state->page_buffer[i];
+		}
+		memset(state->page_buffer, 0xFF, state->page_size);
+	}
+}
+
+uint8_t nor_flash_read_b(uint32_t address, void *vcontext)
+{
+	m68k_context *m68k = vcontext;
+	genesis_context *gen = m68k->system;
+	nor_state *state = &gen->nor;
+	if (
+		((address & 1) && state->bus_flags == RAM_FLAG_EVEN) ||
+		(!(address & 1) && state->bus_flags == RAM_FLAG_ODD)
+	) {
+		return 0xFF;
+	}
+	if (state->bus_flags != RAM_FLAG_BOTH) {
+		address = address >> 1;
+	}
+	
+	nor_run(state, m68k->current_cycle);
+	switch (state->mode)
+	{
+	case NOR_NORMAL:
+		return state->buffer[address & (state->size-1)];
+		break;
+	case NOR_PRODUCTID:
+		switch (address & (state->size - 1))
+		{
+		case 0:
+			return state->product_id >> 8;
+		case 1:
+			return state->product_id;
+		case 2:
+			//TODO: Implement boot block protection
+			return 0xFE;
+		default:
+			return 0xFE;
+		}
+		break;
+	case NOR_BOOTBLOCK:
+		break;
+	}
+	return 0xFF;
+}
+
+uint16_t nor_flash_read_w(uint32_t address, void *context)
+{
+	uint16_t value = nor_flash_read_b(address, context) << 8;
+	value |= nor_flash_read_b(address+1, context);
+	return value;
+}
+
+void nor_write_byte(nor_state *state, uint32_t address, uint8_t value, uint32_t cycle)
+{
+	switch(state->mode)
+	{
+	case NOR_NORMAL:
+		if (state->last_write_cycle != 0xFFFFFFFF) {
+			state->current_page = address & (state->size - 1) & ~(state->page_size - 1);
+		}
+		state->page_buffer[address & (state->page_size - 1)] = value;
+		break;
+	case NOR_PRODUCTID:
+		break;
+	case NOR_BOOTBLOCK:
+		//TODO: Implement boot block protection
+		state->mode = NOR_NORMAL;
+		break;
+	}
+}
+
+void *nor_flash_write_b(uint32_t address, void *vcontext, uint8_t value)
+{
+	m68k_context *m68k = vcontext;
+	genesis_context *gen = m68k->system;
+	nor_state *state = &gen->nor;
+	if (
+		((address & 1) && state->bus_flags == RAM_FLAG_EVEN) ||
+		(!(address & 1) && state->bus_flags == RAM_FLAG_ODD)
+	) {
+		return vcontext;
+	}
+	if (state->bus_flags != RAM_FLAG_BOTH) {
+		address = address >> 1;
+	}
+	
+	nor_run(state, m68k->current_cycle);
+	switch (state->cmd_state)
+	{
+	case NOR_CMD_IDLE:
+		if (value == 0xAA && (address & (state->size - 1)) == 0x5555) {
+			state->cmd_state = NOR_CMD_AA;
+		} else {
+			nor_write_byte(state, address, value, m68k->current_cycle);
+			state->cmd_state = NOR_CMD_IDLE;
+		}
+		break;
+	case NOR_CMD_AA:
+		if (value == 0x55 && (address & (state->size - 1)) == 0x2AAA) {
+			state->cmd_state = NOR_CMD_55;
+		} else {
+			nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle);
+			nor_write_byte(state, address, value, m68k->current_cycle);
+			state->cmd_state = NOR_CMD_IDLE;
+		}
+		break;
+	case NOR_CMD_55:
+		if ((address & (state->size - 1)) == 0x5555) {
+			if (state->alt_cmd) {
+				switch(value)
+				{
+				case 0x10:
+					puts("UNIMPLEMENTED: NOR flash erase");
+					break;
+				case 0x20:
+					puts("UNIMPLEMENTED: NOR flash disable protection");
+					break;
+				case 0x40:
+					state->mode = NOR_BOOTBLOCK;
+					break;
+				case 0x60:
+					state->mode = NOR_PRODUCTID;
+					break;
+				}
+			} else {
+				switch(value)
+				{
+				case 0x80:
+					state->alt_cmd = 1;
+					break;
+				case 0x90:
+					state->mode = NOR_PRODUCTID;
+					break;
+				case 0xA0:
+					puts("UNIMPLEMENTED: NOR flash enable protection");
+					break;
+				case 0xF0:
+					state->mode = NOR_NORMAL;
+					break;
+				default:
+					printf("Unrecognized unshifted NOR flash command %X\n", value);
+				}
+			}
+		} else {
+			nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle);
+			nor_write_byte(state, 0x2AAA, 0x55, m68k->current_cycle);
+			nor_write_byte(state, address, value, m68k->current_cycle);
+		}
+		state->cmd_state = NOR_CMD_IDLE;
+		break;
+	}
+	return vcontext;
+}
+
+void *nor_flash_write_w(uint32_t address, void *vcontext, uint16_t value)
+{
+	nor_flash_write_b(address, vcontext, value >> 8);
+	return nor_flash_write_b(address + 1, vcontext, value);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nor.h	Fri Jun 23 21:48:38 2017 -0700
@@ -0,0 +1,10 @@
+#ifndef NOR_H_
+#define NOR_H_
+
+void nor_flash_init(nor_state *state, uint8_t *buffer, uint32_t size, uint32_t page_size, uint16_t product_id, uint8_t bus_flags);
+uint8_t nor_flash_read_b(uint32_t address, void *vcontext);
+uint16_t nor_flash_read_w(uint32_t address, void *context);
+void *nor_flash_write_b(uint32_t address, void *vcontext, uint8_t value);
+void *nor_flash_write_w(uint32_t address, void *vcontext, uint16_t value);
+
+#endif //NOR_H_
--- a/romdb.c	Thu Jun 22 23:40:05 2017 -0700
+++ b/romdb.c	Fri Jun 23 21:48:38 2017 -0700
@@ -8,6 +8,7 @@
 #include "menu.h"
 #include "xband.h"
 #include "realtec.h"
+#include "nor.h"
 
 #define DOM_TITLE_START 0x120
 #define DOM_TITLE_END 0x150
@@ -30,374 +31,6 @@
 	return "SRAM";
 }
 
-enum {
-	I2C_IDLE,
-	I2C_START,
-	I2C_DEVICE_ACK,
-	I2C_ADDRESS_HI,
-	I2C_ADDRESS_HI_ACK,
-	I2C_ADDRESS,
-	I2C_ADDRESS_ACK,
-	I2C_READ,
-	I2C_READ_ACK,
-	I2C_WRITE,
-	I2C_WRITE_ACK
-};
-
-char * i2c_states[] = {
-	"idle",
-	"start",
-	"device ack",
-	"address hi",
-	"address hi ack",
-	"address",
-	"address ack",
-	"read",
-	"read_ack",
-	"write",
-	"write_ack"
-};
-
-void eeprom_init(eeprom_state *state, uint8_t *buffer, uint32_t size)
-{
-	state->slave_sda = 1;
-	state->host_sda = state->scl = 0;
-	state->buffer = buffer;
-	state->size = size;
-	state->state = I2C_IDLE;
-}
-
-void set_host_sda(eeprom_state *state, uint8_t val)
-{
-	if (state->scl) {
-		if (val & ~state->host_sda) {
-			//low to high, stop condition
-			state->state = I2C_IDLE;
-			state->slave_sda = 1;
-		} else if (~val & state->host_sda) {
-			//high to low, start condition
-			state->state = I2C_START;
-			state->slave_sda = 1;
-			state->counter = 8;
-		}
-	}
-	state->host_sda = val;
-}
-
-void set_scl(eeprom_state *state, uint8_t val)
-{
-	if (val & ~state->scl) {
-		//low to high transition
-		switch (state->state)
-		{
-		case I2C_START:
-		case I2C_ADDRESS_HI:
-		case I2C_ADDRESS:
-		case I2C_WRITE:
-			state->latch = state->host_sda | state->latch << 1;
-			state->counter--;
-			if (!state->counter) {
-				switch (state->state & 0x7F)
-				{
-				case I2C_START:
-					state->state = I2C_DEVICE_ACK;
-					break;
-				case I2C_ADDRESS_HI:
-					state->address = state->latch << 8;
-					state->state = I2C_ADDRESS_HI_ACK;
-					break;
-				case I2C_ADDRESS:
-					state->address |= state->latch;
-					state->state = I2C_ADDRESS_ACK;
-					break;
-				case I2C_WRITE:
-					state->buffer[state->address] = state->latch;
-					state->state = I2C_WRITE_ACK;
-					break;
-				}
-			}
-			break;
-		case I2C_DEVICE_ACK:
-			if (state->latch & 1) {
-				state->state = I2C_READ;
-				state->counter = 8;
-				if (state->size < 256) {
-					state->address = state->latch >> 1;
-				}
-				state->latch = state->buffer[state->address];
-			} else {
-				if (state->size < 256) {
-					state->address = state->latch >> 1;
-					state->state = I2C_WRITE;
-				} else if (state->size < 4096) {
-					state->address = (state->latch & 0xE) << 7;
-					state->state = I2C_ADDRESS;
-				} else {
-					state->state = I2C_ADDRESS_HI;
-				}
-				state->counter = 8;
-			}
-			break;
-		case I2C_ADDRESS_HI_ACK:
-			state->state = I2C_ADDRESS;
-			state->counter = 8;
-			break;
-		case I2C_ADDRESS_ACK:
-			state->state = I2C_WRITE;
-			state->address &= state->size-1;
-			state->counter = 8;
-			break;
-		case I2C_READ:
-			state->counter--;
-			if (!state->counter) {
-				state->state = I2C_READ_ACK;
-			}
-			break;
-		case I2C_READ_ACK:
-			state->state = I2C_READ;
-			state->counter = 8;
-			state->address++;
-			//TODO: page mask
-			state->address &= state->size-1;
-			state->latch = state->buffer[state->address];
-			break;
-		case I2C_WRITE_ACK:
-			state->state = I2C_WRITE;
-			state->counter = 8;
-			state->address++;
-			//TODO: page mask
-			state->address &= state->size-1;
-			break;
-		}
-	} else if (~val & state->scl) {
-		//high to low transition
-		switch (state->state & 0x7F)
-		{
-		case I2C_DEVICE_ACK:
-		case I2C_ADDRESS_HI_ACK:
-		case I2C_ADDRESS_ACK:
-		case I2C_READ_ACK:
-		case I2C_WRITE_ACK:
-			state->slave_sda = 0;
-			break;
-		case I2C_READ:
-			state->slave_sda = state->latch >> 7;
-			state->latch = state->latch << 1;
-			break;
-		default:
-			state->slave_sda = 1;
-			break;
-		}
-	}
-	state->scl = val;
-}
-
-uint8_t get_sda(eeprom_state *state)
-{
-	return state->host_sda & state->slave_sda;
-}
-
-enum {
-	NOR_NORMAL,
-	NOR_PRODUCTID,
-	NOR_BOOTBLOCK
-};
-
-enum {
-	NOR_CMD_IDLE,
-	NOR_CMD_AA,
-	NOR_CMD_55
-};
-
-//Technically this value shoudl be slightly different between NTSC and PAL
-//as it's defined as 200 micro-seconds, not in clock cycles
-#define NOR_WRITE_PAUSE 10690 
-
-void nor_flash_init(nor_state *state, uint8_t *buffer, uint32_t size, uint32_t page_size, uint16_t product_id, uint8_t bus_flags)
-{
-	state->buffer = buffer;
-	state->page_buffer = malloc(page_size);
-	memset(state->page_buffer, 0xFF, page_size);
-	state->size = size;
-	state->page_size = page_size;
-	state->product_id = product_id;
-	state->last_write_cycle = 0xFFFFFFFF;
-	state->mode = NOR_NORMAL;
-	state->cmd_state = NOR_CMD_IDLE;
-	state->alt_cmd = 0;
-	state->bus_flags = bus_flags;
-}
-
-void nor_run(nor_state *state, uint32_t cycle)
-{
-	if (state->last_write_cycle == 0xFFFFFFFF) {
-		return;
-	}
-	if (cycle - state->last_write_cycle >= NOR_WRITE_PAUSE) {
-		state->last_write_cycle = 0xFFFFFFFF;
-		for (uint32_t i = 0; i < state->page_size; i++) {
-			state->buffer[state->current_page + i] = state->page_buffer[i];
-		}
-		memset(state->page_buffer, 0xFF, state->page_size);
-	}
-}
-
-uint8_t nor_flash_read_b(uint32_t address, void *vcontext)
-{
-	m68k_context *m68k = vcontext;
-	genesis_context *gen = m68k->system;
-	nor_state *state = &gen->nor;
-	if (
-		((address & 1) && state->bus_flags == RAM_FLAG_EVEN) ||
-		(!(address & 1) && state->bus_flags == RAM_FLAG_ODD)
-	) {
-		return 0xFF;
-	}
-	if (state->bus_flags != RAM_FLAG_BOTH) {
-		address = address >> 1;
-	}
-	
-	nor_run(state, m68k->current_cycle);
-	switch (state->mode)
-	{
-	case NOR_NORMAL:
-		return state->buffer[address & (state->size-1)];
-		break;
-	case NOR_PRODUCTID:
-		switch (address & (state->size - 1))
-		{
-		case 0:
-			return state->product_id >> 8;
-		case 1:
-			return state->product_id;
-		case 2:
-			//TODO: Implement boot block protection
-			return 0xFE;
-		default:
-			return 0xFE;
-		}
-		break;
-	case NOR_BOOTBLOCK:
-		break;
-	}
-	return 0xFF;
-}
-
-uint16_t nor_flash_read_w(uint32_t address, void *context)
-{
-	uint16_t value = nor_flash_read_b(address, context) << 8;
-	value |= nor_flash_read_b(address+1, context);
-	return value;
-}
-
-void nor_write_byte(nor_state *state, uint32_t address, uint8_t value, uint32_t cycle)
-{
-	switch(state->mode)
-	{
-	case NOR_NORMAL:
-		if (state->last_write_cycle != 0xFFFFFFFF) {
-			state->current_page = address & (state->size - 1) & ~(state->page_size - 1);
-		}
-		state->page_buffer[address & (state->page_size - 1)] = value;
-		break;
-	case NOR_PRODUCTID:
-		break;
-	case NOR_BOOTBLOCK:
-		//TODO: Implement boot block protection
-		state->mode = NOR_NORMAL;
-		break;
-	}
-}
-
-void *nor_flash_write_b(uint32_t address, void *vcontext, uint8_t value)
-{
-	m68k_context *m68k = vcontext;
-	genesis_context *gen = m68k->system;
-	nor_state *state = &gen->nor;
-	if (
-		((address & 1) && state->bus_flags == RAM_FLAG_EVEN) ||
-		(!(address & 1) && state->bus_flags == RAM_FLAG_ODD)
-	) {
-		return vcontext;
-	}
-	if (state->bus_flags != RAM_FLAG_BOTH) {
-		address = address >> 1;
-	}
-	
-	nor_run(state, m68k->current_cycle);
-	switch (state->cmd_state)
-	{
-	case NOR_CMD_IDLE:
-		if (value == 0xAA && (address & (state->size - 1)) == 0x5555) {
-			state->cmd_state = NOR_CMD_AA;
-		} else {
-			nor_write_byte(state, address, value, m68k->current_cycle);
-			state->cmd_state = NOR_CMD_IDLE;
-		}
-		break;
-	case NOR_CMD_AA:
-		if (value == 0x55 && (address & (state->size - 1)) == 0x2AAA) {
-			state->cmd_state = NOR_CMD_55;
-		} else {
-			nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle);
-			nor_write_byte(state, address, value, m68k->current_cycle);
-			state->cmd_state = NOR_CMD_IDLE;
-		}
-		break;
-	case NOR_CMD_55:
-		if ((address & (state->size - 1)) == 0x5555) {
-			if (state->alt_cmd) {
-				switch(value)
-				{
-				case 0x10:
-					puts("UNIMPLEMENTED: NOR flash erase");
-					break;
-				case 0x20:
-					puts("UNIMPLEMENTED: NOR flash disable protection");
-					break;
-				case 0x40:
-					state->mode = NOR_BOOTBLOCK;
-					break;
-				case 0x60:
-					state->mode = NOR_PRODUCTID;
-					break;
-				}
-			} else {
-				switch(value)
-				{
-				case 0x80:
-					state->alt_cmd = 1;
-					break;
-				case 0x90:
-					state->mode = NOR_PRODUCTID;
-					break;
-				case 0xA0:
-					puts("UNIMPLEMENTED: NOR flash enable protection");
-					break;
-				case 0xF0:
-					state->mode = NOR_NORMAL;
-					break;
-				default:
-					printf("Unrecognized unshifted NOR flash command %X\n", value);
-				}
-			}
-		} else {
-			nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle);
-			nor_write_byte(state, 0x2AAA, 0x55, m68k->current_cycle);
-			nor_write_byte(state, address, value, m68k->current_cycle);
-		}
-		state->cmd_state = NOR_CMD_IDLE;
-		break;
-	}
-	return vcontext;
-}
-
-void *nor_flash_write_w(uint32_t address, void *vcontext, uint16_t value)
-{
-	nor_flash_write_b(address, vcontext, value >> 8);
-	return nor_flash_write_b(address + 1, vcontext, value);
-}
-
 uint16_t read_sram_w(uint32_t address, m68k_context * context)
 {
 	genesis_context * gen = context->system;
@@ -531,86 +164,6 @@
 	}
 	return context;
 }
-eeprom_map *find_eeprom_map(uint32_t address, genesis_context *gen)
-{
-	for (int i = 0; i < gen->num_eeprom; i++)
-	{
-		if (address >= gen->eeprom_map[i].start && address <= gen->eeprom_map[i].end) {
-			return  gen->eeprom_map + i;
-		}
-	}
-	return NULL;
-}
-
-void * write_eeprom_i2c_w(uint32_t address, void * context, uint16_t value)
-{
-	genesis_context *gen = ((m68k_context *)context)->system;
-	eeprom_map *map = find_eeprom_map(address, gen);
-	if (!map) {
-		fatal_error("Could not find EEPROM map for address %X\n", address);
-	}
-	if (map->scl_mask) {
-		set_scl(&gen->eeprom, (value & map->scl_mask) != 0);
-	}
-	if (map->sda_write_mask) {
-		set_host_sda(&gen->eeprom, (value & map->sda_write_mask) != 0);
-	}
-	return context;
-}
-
-void * write_eeprom_i2c_b(uint32_t address, void * context, uint8_t value)
-{
-	genesis_context *gen = ((m68k_context *)context)->system;
-	eeprom_map *map = find_eeprom_map(address, gen);
-	if (!map) {
-		fatal_error("Could not find EEPROM map for address %X\n", address);
-	}
-
-	uint16_t expanded, mask;
-	if (address & 1) {
-		expanded = value;
-		mask = 0xFF;
-	} else {
-		expanded = value << 8;
-		mask = 0xFF00;
-	}
-	if (map->scl_mask & mask) {
-		set_scl(&gen->eeprom, (expanded & map->scl_mask) != 0);
-	}
-	if (map->sda_write_mask & mask) {
-		set_host_sda(&gen->eeprom, (expanded & map->sda_write_mask) != 0);
-	}
-	return context;
-}
-
-uint16_t read_eeprom_i2c_w(uint32_t address, void * context)
-{
-	genesis_context *gen = ((m68k_context *)context)->system;
-	eeprom_map *map = find_eeprom_map(address, gen);
-	if (!map) {
-		fatal_error("Could not find EEPROM map for address %X\n", address);
-	}
-	uint16_t ret = 0;
-	if (map->sda_read_bit < 16) {
-		ret = get_sda(&gen->eeprom) << map->sda_read_bit;
-	}
-	return ret;	
-}
-
-uint8_t read_eeprom_i2c_b(uint32_t address, void * context)
-{
-	genesis_context *gen = ((m68k_context *)context)->system;
-	eeprom_map *map = find_eeprom_map(address, gen);
-	if (!map) {
-		fatal_error("Could not find EEPROM map for address %X\n", address);
-	}
-	uint8_t bit = address & 1 ? map->sda_read_bit : map->sda_read_bit - 8;
-	uint8_t ret = 0;
-	if (bit < 8) {
-		ret = get_sda(&gen->eeprom) << bit;
-	}
-	return ret;
-}
 
 tern_node *load_rom_db()
 {
--- a/romdb.h	Thu Jun 22 23:40:05 2017 -0700
+++ b/romdb.h	Fri Jun 23 21:48:38 2017 -0700
@@ -24,18 +24,6 @@
 } eeprom_map;
 
 typedef struct {
-	char        *buffer;
-	uint32_t    size;
-	uint16_t    address;
-	uint8_t     host_sda;
-	uint8_t     slave_sda;
-	uint8_t     scl;
-	uint8_t     state;
-	uint8_t     counter;
-	uint8_t     latch;
-} eeprom_state;
-
-typedef struct {
 	uint8_t     *buffer;
 	uint8_t     *page_buffer;
 	uint32_t    size;
@@ -83,8 +71,6 @@
 rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, memmap_chunk const *base_map, uint32_t base_chunks);
 rom_info configure_rom_heuristics(uint8_t *rom, uint32_t rom_size, memmap_chunk const *base_map, uint32_t base_chunks);
 uint8_t translate_region_char(uint8_t c);
-void eeprom_init(eeprom_state *state, uint8_t *buffer, uint32_t size);
-void nor_flash_init(nor_state *state, uint8_t *buffer, uint32_t size, uint32_t page_size, uint16_t product_id, uint8_t bus_flags);
 char const *save_type_name(uint8_t save_type);
 //Note: free_rom_info only frees things pointed to by a rom_info struct, not the struct itself
 //this is because rom_info structs are typically stack allocated