# HG changeset patch # User Michael Pavone # Date 1517465110 28800 # Node ID 1f745318f10a41987f6cc5546fa127b1d199a704 # Parent 713b504dc577624ec8ce1c3fd39ce07a2b44ae6c Made the NOR flash emulation a bit more flexible, but not yet flexible enough to properly support the flash chip in the MegaWiFi cart diff -r 713b504dc577 -r 1f745318f10a backend.c --- a/backend.c Wed Jan 31 21:59:08 2018 -0800 +++ b/backend.c Wed Jan 31 22:05:10 2018 -0800 @@ -75,7 +75,7 @@ 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 -r 713b504dc577 -r 1f745318f10a backend.h --- a/backend.h Wed Jan 31 21:59:08 2018 -0800 +++ b/backend.h Wed Jan 31 22:05:10 2018 -0800 @@ -56,6 +56,7 @@ #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 -r 713b504dc577 -r 1f745318f10a genesis.c --- a/genesis.c Wed Jan 31 21:59:08 2018 -0800 +++ b/genesis.c Wed Jan 31 22:05:10 2018 -0800 @@ -1288,7 +1288,8 @@ 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 -r 713b504dc577 -r 1f745318f10a nor.c --- a/nor.c Wed Jan 31 21:59:08 2018 -0800 +++ b/nor.c Wed Jan 31 22:05:10 2018 -0800 @@ -1,6 +1,7 @@ #include "genesis.h" #include #include +#include "util.h" enum { NOR_NORMAL, @@ -31,9 +32,11 @@ 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 @@ 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 @@ 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 @@ return 0xFE; default: return 0xFE; - } + } //HERE break; case NOR_BOOTBLOCK: break; @@ -103,6 +113,9 @@ 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 @@ 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 @@ } 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 @@ } } } 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 -r 713b504dc577 -r 1f745318f10a rom.db --- a/rom.db Wed Jan 31 21:59:08 2018 -0800 +++ b/rom.db Wed Jan 31 22:05:10 2018 -0800 @@ -1301,9 +1301,18 @@ } 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 -r 713b504dc577 -r 1f745318f10a romdb.c --- a/romdb.c Wed Jan 31 21:59:08 2018 -0800 +++ b/romdb.c Wed Jan 31 22:05:10 2018 -0800 @@ -57,6 +57,7 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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 -r 713b504dc577 -r 1f745318f10a romdb.h --- a/romdb.h Wed Jan 31 21:59:08 2018 -0800 +++ b/romdb.h Wed Jan 31 22:05:10 2018 -0800 @@ -31,6 +31,8 @@ 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 @@ 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