summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2018-01-31 22:05:10 -0800
committerMichael Pavone <pavone@retrodev.com>2018-01-31 22:05:10 -0800
commitc2653ab569c2a0139089db6586f1213884b03b2c (patch)
tree256e5c28b18ebc394c19cff6bc2768259b8f7379
parentaeb32eebf529a82a624f2c88f51a7706aad0bcc5 (diff)
Made the NOR flash emulation a bit more flexible, but not yet flexible enough to properly support the flash chip in the MegaWiFi cart
-rw-r--r--backend.c2
-rw-r--r--backend.h1
-rw-r--r--genesis.c3
-rw-r--r--nor.c33
-rw-r--r--rom.db11
-rw-r--r--romdb.c37
-rw-r--r--romdb.h5
7 files changed, 70 insertions, 22 deletions
diff --git a/backend.c b/backend.c
index 08601da..acf66d5 100644
--- a/backend.c
+++ b/backend.c
@@ -75,7 +75,7 @@ void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options *
for (uint32_t chunk = 0; chunk < opts->memmap_chunks; chunk++)
{
if (address >= memmap[chunk].start && address < memmap[chunk].end) {
- if (!(memmap[chunk].flags & MMAP_READ)) {
+ if (!(memmap[chunk].flags & (MMAP_READ|MMAP_READ_CODE))) {
return NULL;
}
uint8_t * base = memmap[chunk].flags & MMAP_PTR_IDX
diff --git a/backend.h b/backend.h
index b82f5a1..c55b143 100644
--- a/backend.h
+++ b/backend.h
@@ -56,6 +56,7 @@ typedef enum {
#define MMAP_FUNC_NULL 0x40
#define MMAP_BYTESWAP 0x80
#define MMAP_AUX_BUFF 0x100
+#define MMAP_READ_CODE 0x200
typedef uint16_t (*read_16_fun)(uint32_t address, void * context);
typedef uint8_t (*read_8_fun)(uint32_t address, void * context);
diff --git a/genesis.c b/genesis.c
index 4514b9e..606e29a 100644
--- a/genesis.c
+++ b/genesis.c
@@ -1288,7 +1288,8 @@ genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on
if (gen->save_type == SAVE_I2C) {
eeprom_init(&gen->eeprom, gen->save_storage, gen->save_size);
} else if (gen->save_type == SAVE_NOR) {
- nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus);
+ memcpy(&gen->nor, rom->nor, sizeof(gen->nor));
+ //nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus);
}
} else {
gen->save_storage = NULL;
diff --git a/nor.c b/nor.c
index deae094..7317011 100644
--- a/nor.c
+++ b/nor.c
@@ -1,6 +1,7 @@
#include "genesis.h"
#include <stdlib.h>
#include <string.h>
+#include "util.h"
enum {
NOR_NORMAL,
@@ -31,9 +32,11 @@ void nor_flash_init(nor_state *state, uint8_t *buffer, uint32_t size, uint32_t p
state->cmd_state = NOR_CMD_IDLE;
state->alt_cmd = 0;
state->bus_flags = bus_flags;
+ state->cmd_address1 = 0x5555;
+ state->cmd_address2 = 0x2AAA;
}
-void nor_run(nor_state *state, uint32_t cycle)
+void nor_run(nor_state *state, m68k_context *m68k, uint32_t cycle)
{
if (state->last_write_cycle == 0xFFFFFFFF) {
return;
@@ -44,6 +47,10 @@ void nor_run(nor_state *state, uint32_t cycle)
state->buffer[state->current_page + i] = state->page_buffer[i];
}
memset(state->page_buffer, 0xFF, state->page_size);
+ if (state->bus_flags == RAM_FLAG_BOTH) {
+ //TODO: add base address of NOR device to start and end addresses
+ m68k_invalidate_code_range(m68k, state->current_page, state->current_page + state->page_size);
+ }
}
}
@@ -62,10 +69,13 @@ uint8_t nor_flash_read_b(uint32_t address, void *vcontext)
address = address >> 1;
}
- nor_run(state, m68k->current_cycle);
+ nor_run(state, m68k, m68k->current_cycle);
switch (state->mode)
{
case NOR_NORMAL:
+ if (state->bus_flags == RAM_FLAG_BOTH) {
+ address ^= 1;
+ }
return state->buffer[address & (state->size-1)];
break;
case NOR_PRODUCTID:
@@ -80,7 +90,7 @@ uint8_t nor_flash_read_b(uint32_t address, void *vcontext)
return 0xFE;
default:
return 0xFE;
- }
+ } //HERE
break;
case NOR_BOOTBLOCK:
break;
@@ -103,6 +113,9 @@ void nor_write_byte(nor_state *state, uint32_t address, uint8_t value, uint32_t
if (state->last_write_cycle != 0xFFFFFFFF) {
state->current_page = address & (state->size - 1) & ~(state->page_size - 1);
}
+ if (state->bus_flags == RAM_FLAG_BOTH) {
+ address ^= 1;
+ }
state->page_buffer[address & (state->page_size - 1)] = value;
break;
case NOR_PRODUCTID:
@@ -129,11 +142,11 @@ void *nor_flash_write_b(uint32_t address, void *vcontext, uint8_t value)
address = address >> 1;
}
- nor_run(state, m68k->current_cycle);
+ nor_run(state, m68k, m68k->current_cycle);
switch (state->cmd_state)
{
case NOR_CMD_IDLE:
- if (value == 0xAA && (address & (state->size - 1)) == 0x5555) {
+ if (value == 0xAA && (address & (state->size - 1)) == state->cmd_address1) {
state->cmd_state = NOR_CMD_AA;
} else {
nor_write_byte(state, address, value, m68k->current_cycle);
@@ -141,16 +154,16 @@ void *nor_flash_write_b(uint32_t address, void *vcontext, uint8_t value)
}
break;
case NOR_CMD_AA:
- if (value == 0x55 && (address & (state->size - 1)) == 0x2AAA) {
+ if (value == 0x55 && (address & (state->size - 1)) == state->cmd_address2) {
state->cmd_state = NOR_CMD_55;
} else {
- nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle);
+ nor_write_byte(state, state->cmd_address1, 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 ((address & (state->size - 1)) == state->cmd_address1) {
if (state->alt_cmd) {
switch(value)
{
@@ -187,8 +200,8 @@ void *nor_flash_write_b(uint32_t address, void *vcontext, uint8_t value)
}
}
} else {
- nor_write_byte(state, 0x5555, 0xAA, m68k->current_cycle);
- nor_write_byte(state, 0x2AAA, 0x55, m68k->current_cycle);
+ nor_write_byte(state, state->cmd_address1, 0xAA, m68k->current_cycle);
+ nor_write_byte(state, state->cmd_address2, 0x55, m68k->current_cycle);
nor_write_byte(state, address, value, m68k->current_cycle);
}
state->cmd_state = NOR_CMD_IDLE;
diff --git a/rom.db b/rom.db
index e74cbc9..cf704fb 100644
--- a/rom.db
+++ b/rom.db
@@ -1301,9 +1301,18 @@ e1c041ba69da087c428dcda16850159f3caebd4b {
}
cda73e4caf53cbc8f0750b69e5e7f394ad3735d1 {
name MegaWiFi Bootloader
+ NOR {
+ size 4194304
+ page_size 128
+ product_id DA45
+ bus both
+ init ROM
+ cmd_address1 AAB
+ cmd_address2 555
+ }
map {
0 {
- device ROM
+ device NOR
last 3FFFFF
}
A130C0 {
diff --git a/romdb.c b/romdb.c
index e580797..65e1e9b 100644
--- a/romdb.c
+++ b/romdb.c
@@ -57,6 +57,7 @@ void free_rom_info(rom_info *info)
free(info->port2_override);
free(info->ext_override);
free(info->mouse_mode);
+ free(info->nor);
}
void cart_serialize(system_header *sys, serialize_buffer *buf)
@@ -500,15 +501,15 @@ void process_nor_def(char *key, map_iter_state *state)
if (!page_size) {
fatal_error("ROM DB map entry %d with address %s has device type NOR, but the NOR page size is not defined\n", state->index, key);
}
- state->info->save_page_size = atoi(size);
- if (!state->info->save_page_size) {
- fatal_error("NOR page size %s is invalid\n", size);
+ uint32_t save_page_size = atoi(page_size);
+ if (!save_page_size) {
+ fatal_error("NOR page size %s is invalid\n", page_size);
}
char *product_id = tern_find_path(state->root, "NOR\0product_id\0", TVAL_PTR).ptrval;
if (!product_id) {
fatal_error("ROM DB map entry %d with address %s has device type NOR, but the NOR product ID is not defined\n", state->index, key);
}
- state->info->save_product_id = strtol(product_id, NULL, 16);
+ uint16_t save_product_id = strtol(product_id, NULL, 16);
char *bus = tern_find_path(state->root, "NOR\0bus\0", TVAL_PTR).ptrval;
if (!strcmp(bus, "odd")) {
state->info->save_bus = RAM_FLAG_ODD;
@@ -519,7 +520,26 @@ void process_nor_def(char *key, map_iter_state *state)
}
state->info->save_type = SAVE_NOR;
state->info->save_buffer = malloc(state->info->save_size);
- memset(state->info->save_buffer, 0xFF, state->info->save_size);
+ char *init = tern_find_path_default(state->root, "NOR\0init\0", (tern_val){.ptrval="FF"}, TVAL_PTR).ptrval;
+ if (!strcmp(init, "ROM")) {
+ uint32_t init_size = state->rom_size > state->info->save_size ? state->info->save_size : state->rom_size;
+ memcpy(state->info->save_buffer, state->rom, init_size);
+ if (state->info->save_bus == RAM_FLAG_BOTH) {
+ byteswap_rom(state->info->save_size, (uint16_t *)state->info->save_buffer);
+ }
+ } else {
+ memset(state->info->save_buffer, strtol(init, NULL, 16), state->info->save_size);
+ }
+ state->info->nor = calloc(1, sizeof(nor_state));
+ nor_flash_init(state->info->nor, state->info->save_buffer, state->info->save_size, save_page_size, save_product_id, state->info->save_bus);
+ char *cmd1 = tern_find_path(state->root, "NOR\0cmd_address1\0", TVAL_PTR).ptrval;
+ if (cmd1) {
+ state->info->nor->cmd_address1 = strtol(cmd1, NULL, 16);
+ }
+ char *cmd2 = tern_find_path(state->root, "NOR\0cmd_address2\0", TVAL_PTR).ptrval;
+ if (cmd2) {
+ state->info->nor->cmd_address2 = strtol(cmd2, NULL, 16);
+ }
}
}
@@ -616,8 +636,7 @@ void map_iter_fun(char *key, tern_val val, uint8_t valtype, void *data)
state->info->save_buffer = lock_info.save_buffer;
state->info->save_size = lock_info.save_size;
state->info->save_mask = lock_info.save_mask;
- state->info->save_page_size = lock_info.save_page_size;
- state->info->save_product_id = lock_info.save_product_id;
+ state->info->nor = lock_info.nor;
state->info->save_type = lock_info.save_type;
state->info->save_bus = lock_info.save_bus;
lock_info.save_buffer = NULL;
@@ -667,6 +686,10 @@ void map_iter_fun(char *key, tern_val val, uint8_t valtype, void *data)
map->write_8 = nor_flash_write_b;
map->read_16 = nor_flash_read_w;
map->read_8 = nor_flash_read_b;
+ if (state->info->save_bus == RAM_FLAG_BOTH) {
+ map->flags |= MMAP_READ_CODE | MMAP_CODE;
+ map->buffer = state->info->save_buffer;
+ }
map->mask = 0xFFFFFF;
} else if (!strcmp(dtype, "Sega mapper")) {
state->info->mapper_type = MAPPER_SEGA;
diff --git a/romdb.h b/romdb.h
index caf4e89..fa38b84 100644
--- a/romdb.h
+++ b/romdb.h
@@ -31,6 +31,8 @@ typedef struct {
uint32_t page_size;
uint32_t current_page;
uint32_t last_write_cycle;
+ uint32_t cmd_address1;
+ uint32_t cmd_address2;
uint16_t product_id;
uint8_t mode;
uint8_t cmd_state;
@@ -61,13 +63,12 @@ struct rom_info {
char *port2_override;
char *ext_override;
char *mouse_mode;
+ nor_state *nor;
uint32_t num_eeprom;
uint32_t map_chunks;
uint32_t rom_size;
uint32_t save_size;
uint32_t save_mask;
- uint32_t save_page_size;
- uint16_t save_product_id;
uint16_t mapper_start_index;
uint8_t save_type;
uint8_t save_bus; //only used for NOR currently