summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2015-07-20 21:15:34 -0700
committerMichael Pavone <pavone@retrodev.com>2015-07-20 21:15:34 -0700
commit9d475a3ccb5b2e1e206cf4c219ec5984cec3574f (patch)
tree990b3714bc4f92006e716bb9ceeb0324a4da9587
parent5733306bcd4e653994b5830cf035e7487869aeb7 (diff)
Full support for Sega mapper when it comes to data. Code in remapped sections may not work reliably. SSF2 now works.
-rw-r--r--blastem.c37
-rw-r--r--blastem.h4
-rw-r--r--gst.c4
-rw-r--r--m68k_core.h2
-rw-r--r--rom.db28
-rw-r--r--romdb.c84
-rw-r--r--romdb.h1
7 files changed, 101 insertions, 59 deletions
diff --git a/blastem.c b/blastem.c
index 3f71631..256f152 100644
--- a/blastem.c
+++ b/blastem.c
@@ -34,7 +34,7 @@
#define MAX_SOUND_CYCLES 100000
-uint16_t cart[CARTRIDGE_WORDS];
+uint16_t *cart;
uint16_t ram[RAM_WORDS];
uint8_t z80_ram[Z80_RAM_BYTES];
@@ -73,9 +73,9 @@ int load_smd_rom(long filesize, FILE * f)
return filesize;
}
-void byteswap_rom()
+void byteswap_rom(int filesize)
{
- for(unsigned short * cur = cart; cur - cart < CARTRIDGE_WORDS; ++cur)
+ for(unsigned short * cur = cart; cur - cart < filesize/2; ++cur)
{
*cur = (*cur >> 8) | (*cur << 8);
}
@@ -88,13 +88,12 @@ int load_rom(char * filename)
if (!f) {
return 0;
}
- fread(header, 1, sizeof(header), f);
+ if (sizeof(header) != fread(header, 1, sizeof(header), f)) {
+ fprintf(stderr, "Error reading from %s\n", filename);
+ exit(1);
+ }
fseek(f, 0, SEEK_END);
long filesize = ftell(f);
- if (filesize/2 > CARTRIDGE_WORDS) {
- //carts bigger than 4MB not currently supported
- filesize = CARTRIDGE_WORDS*2;
- }
fseek(f, 0, SEEK_SET);
if (header[1] == SMD_MAGIC1 && header[8] == SMD_MAGIC2 && header[9] == SMD_MAGIC3) {
int i;
@@ -111,7 +110,11 @@ int load_rom(char * filename)
return load_smd_rom(filesize, f);
}
}
- fread(cart, 2, filesize/2, f);
+ cart = malloc(filesize);
+ if (filesize != fread(cart, 1, filesize, f)) {
+ fprintf(stderr, "Error reading from %s\n", filename);
+ exit(1);
+ }
fclose(f);
return filesize;
}
@@ -839,14 +842,12 @@ void init_run_cpu(genesis_context * gen, rom_info *rom, FILE * address_log, char
context->video_context = gen->vdp;
context->system = gen;
- //cartridge ROM
- context->mem_pointers[0] = cart;
- context->target_cycle = context->sync_cycle = gen->frame_end > gen->max_cycles ? gen->frame_end : gen->max_cycles;
- //work RAM
- context->mem_pointers[1] = ram;
- //save RAM/map
- context->mem_pointers[2] = rom->map[1].buffer;
- context->mem_pointers[3] = (uint16_t *)gen->save_storage;
+ for (int i = 0; i < rom->map_chunks; i++)
+ {
+ if (rom->map[i].flags & MMAP_PTR_IDX) {
+ context->mem_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
+ }
+ }
if (statefile) {
uint32_t pc = load_gst(gen, statefile);
@@ -1026,7 +1027,7 @@ int main(int argc, char ** argv)
}
tern_node *rom_db = load_rom_db();
rom_info info = configure_rom(rom_db, cart, rom_size, base_map, sizeof(base_map)/sizeof(base_map[0]));
- byteswap_rom();
+ byteswap_rom(rom_size);
set_region(&info, force_version);
update_title(info.name);
int def_width = 0;
diff --git a/blastem.h b/blastem.h
index 7d051b6..43f694d 100644
--- a/blastem.h
+++ b/blastem.h
@@ -32,6 +32,7 @@ typedef struct {
uint32_t frame_end;
uint32_t max_cycles;
uint8_t bank_regs[8];
+ uint16_t mapper_start_index;
uint8_t save_type;
io_port ports[3];
uint8_t bus_busy;
@@ -44,11 +45,10 @@ extern int break_on_sync;
extern int save_state;
extern tern_node * config;
-#define CARTRIDGE_WORDS 0x200000
#define RAM_WORDS 32 * 1024
#define Z80_RAM_BYTES 8 * 1024
-extern uint16_t cart[CARTRIDGE_WORDS];
+extern uint16_t *cart;
extern uint16_t ram[RAM_WORDS];
extern uint8_t z80_ram[Z80_RAM_BYTES];
diff --git a/gst.c b/gst.c
index 28cc4ca..48dbd0e 100644
--- a/gst.c
+++ b/gst.c
@@ -100,7 +100,7 @@ uint32_t m68k_load_gst(m68k_context * context, FILE * gstfile)
return 0;
}
for(curpos = buffer; curpos < (buffer + sizeof(buffer)); curpos += sizeof(uint16_t)) {
- context->mem_pointers[1][i++] = read_be_16(curpos);
+ ram[i++] = read_be_16(curpos);
}
}
return pc;
@@ -141,7 +141,7 @@ uint8_t m68k_save_gst(m68k_context * context, uint32_t pc, FILE * gstfile)
fseek(gstfile, GST_68K_RAM, SEEK_SET);
for (int i = 0; i < (32*1024);) {
for(curpos = buffer; curpos < (buffer + sizeof(buffer)); curpos += sizeof(uint16_t)) {
- write_be_16(curpos, context->mem_pointers[1][i++]);
+ write_be_16(curpos, ram[i++]);
}
if (fwrite(buffer, 1, sizeof(buffer), gstfile) != sizeof(buffer)) {
fputs("Failed to write 68K RAM to savestate\n", stderr);
diff --git a/m68k_core.h b/m68k_core.h
index b91a37b..421302f 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -11,7 +11,7 @@
//#include "68kinst.h"
struct m68kinst;
-#define NUM_MEM_AREAS 4
+#define NUM_MEM_AREAS 8
#define NATIVE_MAP_CHUNKS (64*1024)
#define NATIVE_CHUNK_SIZE ((16 * 1024 * 1024 / NATIVE_MAP_CHUNKS)/2)
#define MAX_NATIVE_SIZE 255
diff --git a/rom.db b/rom.db
index 5759789..a2a00fe 100644
--- a/rom.db
+++ b/rom.db
@@ -173,4 +173,32 @@ T-81476 {
}
}
}
+}
+MK-12056 {
+ name Super Street Fighter 2: The New Challengers
+ map {
+ 0 {
+ device ROM
+ last 7FFFF
+ }
+ 80000 {
+ device Sega mapper
+ last 3FFFFF
+ offset 80000
+ }
+ }
+}
+T-12056 {
+ name Super Street Fighter 2: The New Challengers
+ map {
+ 0 {
+ device ROM
+ last 7FFFF
+ }
+ 80000 {
+ device Sega mapper
+ last 3FFFFF
+ offset 80000
+ }
+ }
} \ No newline at end of file
diff --git a/romdb.c b/romdb.c
index a422fe7..b79635e 100644
--- a/romdb.c
+++ b/romdb.c
@@ -273,10 +273,21 @@ m68k_context * write_bank_reg_w(uint32_t address, m68k_context * context, uint16
gen->bank_regs[address] = value;
if (!address) {
if (value & 1) {
- context->mem_pointers[2] = NULL;
+ for (int i = 0; i < 8; i++)
+ {
+ context->mem_pointers[gen->mapper_start_index + i] = NULL;
+ }
} else {
- context->mem_pointers[2] = cart + 0x200000/2;
+ //Used for games that only use the mapper for SRAM
+ context->mem_pointers[gen->mapper_start_index] = cart + 0x200000/2;
+ //For games that need more than 4MB
+ for (int i = 1; i < 8; i++)
+ {
+ context->mem_pointers[gen->mapper_start_index + i] = cart + 0x40000*gen->bank_regs[i];
+ }
}
+ } else {
+ context->mem_pointers[gen->mapper_start_index + address] = cart + 0x40000*value;
}
return context;
}
@@ -284,17 +295,7 @@ m68k_context * write_bank_reg_w(uint32_t address, m68k_context * context, uint16
m68k_context * write_bank_reg_b(uint32_t address, m68k_context * context, uint8_t value)
{
if (address & 1) {
- genesis_context * gen = context->system;
- address &= 0xE;
- address >>= 1;
- gen->bank_regs[address] = value;
- if (!address) {
- if (value & 1) {
- context->mem_pointers[2] = NULL;
- } else {
- context->mem_pointers[2] = cart + 0x200000/2;
- }
- }
+ write_bank_reg_w(address, context, value);
}
return context;
}
@@ -526,7 +527,7 @@ void add_memmap_header(rom_info *info, uint8_t *rom, uint32_t size, memmap_chunk
info->map[1].end = 0x400000;
info->map[1].mask = 0x1FFFFF;
info->map[1].flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL;
- info->map[1].ptr_index = 2;
+ info->map[1].ptr_index = info->mapper_start_index = 0;
info->map[1].read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
info->map[1].read_8 = (read_8_fun)read_sram_b;
info->map[1].write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
@@ -571,6 +572,7 @@ typedef struct {
uint32_t rom_size;
int index;
int num_els;
+ uint16_t ptr_index;
} map_iter_state;
void eeprom_read_fun(char *key, tern_val val, void *data)
@@ -727,31 +729,41 @@ void map_iter_fun(char *key, tern_val val, void *data)
}
map->mask = calc_mask(state->info->save_size, start, end);
} else if (!strcmp(dtype, "Sega mapper")) {
- map->buffer = state->rom + offset;
- //TODO: Calculate this
- map->ptr_index = 2;
- map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL;
- map->mask = calc_mask(state->rom_size - offset, start, end);
+ state->info->mapper_start_index = state->ptr_index++;
+ state->info->map_chunks+=7;
+ state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
+ memset(state->info->map + state->info->map_chunks - 7, 0, sizeof(memmap_chunk) * 7);
+ map = state->info->map + state->index;
char *save_device = tern_find_path(node, "save\0device\0").ptrval;
- if (save_device && !strcmp(save_device, "SRAM")) {
- process_sram_def(key, state);
- map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
- map->read_8 = (read_8_fun)read_sram_b;
- map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
- map->write_8 = (write_8_fun)write_sram_area_b;
- } else if (save_device && !strcmp(save_device, "EEPROM")) {
+ if (save_device && !strcmp(save_device, "EEPROM")) {
process_eeprom_def(key, state);
add_eeprom_map(node, start & map->mask, end & map->mask, state);
- map->write_16 = write_eeprom_i2c_w;
- map->write_8 = write_eeprom_i2c_b;
- map->read_16 = read_eeprom_i2c_w;
- map->read_8 = read_eeprom_i2c_b;
}
- state->info->map_chunks++;
- state->info->map = realloc(state->info->map, sizeof(memmap_chunk) * state->info->map_chunks);
- state->index++;
- memset(state->info->map + state->info->map_chunks - 1, 0, sizeof(memmap_chunk));
- map = state->info->map + state->index;
+ for (int i = 0; i < 7; i++, state->index++, map++)
+ {
+ map->start = start + i * 0x80000;
+ map->end = start + (i + 1) * 0x80000;
+ map->mask = 0x7FFFF;
+ map->buffer = state->rom + offset + i * 0x80000;
+ map->ptr_index = state->ptr_index++;
+ if (i < 3 || !save_device) {
+ map->flags = MMAP_READ | MMAP_PTR_IDX;
+ } else {
+ map->flags = MMAP_READ | MMAP_PTR_IDX | MMAP_FUNC_NULL;
+ if (!strcmp(save_device, "SRAM")) {
+ process_sram_def(key, state);
+ map->read_16 = (read_16_fun)read_sram_w;//these will only be called when mem_pointers[2] == NULL
+ map->read_8 = (read_8_fun)read_sram_b;
+ map->write_16 = (write_16_fun)write_sram_area_w;//these will be called all writes to the area
+ map->write_8 = (write_8_fun)write_sram_area_b;
+ } else if (!strcmp(save_device, "EEPROM")) {
+ map->write_16 = write_eeprom_i2c_w;
+ map->write_8 = write_eeprom_i2c_b;
+ map->read_16 = read_eeprom_i2c_w;
+ map->read_8 = read_eeprom_i2c_b;
+ }
+ }
+ }
map->start = 0xA13000;
map->end = 0xA13100;
map->mask = 0xFF;
@@ -817,7 +829,7 @@ rom_info configure_rom(tern_node *rom_db, void *vrom, uint32_t rom_size, memmap_
info.eeprom_map = NULL;
info.num_eeprom = 0;
memset(info.map, 0, sizeof(memmap_chunk) * info.map_chunks);
- map_iter_state state = {&info, rom, entry, rom_size, 0, info.map_chunks - base_chunks};
+ map_iter_state state = {&info, rom, entry, rom_size, 0, info.map_chunks - base_chunks, 0};
tern_foreach(map, map_iter_fun, &state);
memcpy(info.map + state.index, base_map, sizeof(memmap_chunk) * base_chunks);
} else {
diff --git a/romdb.h b/romdb.h
index 3bf9fa6..e2af1de 100644
--- a/romdb.h
+++ b/romdb.h
@@ -44,6 +44,7 @@ typedef struct {
uint32_t map_chunks;
uint32_t save_size;
uint32_t save_mask;
+ uint16_t mapper_start_index;
uint8_t save_type;
uint8_t regions;
} rom_info;