summaryrefslogtreecommitdiff
path: root/sms.c
diff options
context:
space:
mode:
Diffstat (limited to 'sms.c')
-rw-r--r--sms.c59
1 files changed, 52 insertions, 7 deletions
diff --git a/sms.c b/sms.c
index 11aeeba..345f85c 100644
--- a/sms.c
+++ b/sms.c
@@ -97,6 +97,32 @@ static uint8_t io_read(uint32_t location, void *vcontext)
return 0xFF;
}
+static void *mapper_write(uint32_t location, void *vcontext, uint8_t value)
+{
+ z80_context *z80 = vcontext;
+ sms_context *sms = z80->system;
+ sms->ram[location & (sizeof(sms->ram)-1)] = value;
+ switch (location & 3)
+ {
+ case 0:
+ //TODO: implement me
+ break;
+ case 1:
+ z80->mem_pointers[0] = sms->rom + (value << 14 & (sms->rom_size-1)) + 0x400;
+ //TODO: invalidate translated code in range 0x400-0x4000
+ break;
+ case 2:
+ z80->mem_pointers[1] = sms->rom + (value << 14 & (sms->rom_size-1));
+ //TODO: invalidate translated code in range 0x4000-0x8000
+ break;
+ case 3:
+ z80->mem_pointers[2] = sms->rom + (value << 14 & (sms->rom_size-1));
+ //TODO: invalidate translated code in range 0x8000-0xC000
+ break;
+ }
+ return vcontext;
+}
+
static memmap_chunk io_map[] = {
{0x00, 0x40, 0xFF, 0, 0, 0, NULL, NULL, NULL, NULL, memory_io_write},
{0x40, 0x80, 0xFF, 0, 0, 0, NULL, NULL, NULL, hv_read, sms_psg_write},
@@ -202,19 +228,38 @@ sms_context *alloc_configure_sms(void *rom, uint32_t rom_size, void *extra_rom,
{
memset(info_out, 0, sizeof(*info_out));
sms_context *sms = calloc(1, sizeof(sms_context));
+ uint32_t orig_size = rom_size;
rom_size = nearest_pow2(rom_size);
- uint32_t mask = rom_size >= 0xC000 ? 0xFFFF : rom_size-1;
- memmap_chunk memory_map[] = {
- {0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL},
- {0xC000, 0x10000, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL}
+ memmap_chunk memory_map[6];
+ if (orig_size > 0xC000) {
+ info_out->map_chunks = 6;
+ uint8_t *ram_reg_overlap = sms->ram + sizeof(sms->ram) - 4;
+ memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL};
+ memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX, NULL, NULL, NULL, NULL, NULL};
+ memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX, NULL, NULL, NULL, NULL, NULL};
+ memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX, NULL, NULL, NULL, NULL, NULL};
+ memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
+ memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0xFFFF, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write};
+ } else {
+ info_out->map_chunks = 2;
+ memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, rom, NULL, NULL, NULL, NULL};
+ memory_map[1] = (memmap_chunk){0xC000, 0x10000, sizeof(sms->ram)-1, 0, 0, MMAP_READ|MMAP_WRITE|MMAP_CODE, sms->ram, NULL, NULL, NULL, NULL};
};
- info_out->map = malloc(sizeof(memory_map));
- memcpy(info_out->map, memory_map, sizeof(memory_map));
+ info_out->map = malloc(sizeof(memmap_chunk) * info_out->map_chunks);
+ memcpy(info_out->map, memory_map, sizeof(memmap_chunk) * info_out->map_chunks);
z80_options *zopts = malloc(sizeof(z80_options));
- init_z80_opts(zopts, info_out->map, 2, io_map, 4, 15, 0xFF);
+ init_z80_opts(zopts, info_out->map, info_out->map_chunks, io_map, 4, 15, 0xFF);
sms->z80 = init_z80_context(zopts);
sms->z80->system = sms;
+ sms->rom = rom;
+ sms->rom_size = rom_size;
+ if (info_out->map_chunks > 2) {
+ sms->z80->mem_pointers[0] = sms->rom;
+ sms->z80->mem_pointers[1] = sms->rom + 0x4000;
+ sms->z80->mem_pointers[2] = sms->rom + 0x8000;
+ }
+
char * lowpass_cutoff_str = tern_find_path(config, "audio\0lowpass_cutoff\0").ptrval;
uint32_t lowpass_cutoff = lowpass_cutoff_str ? atoi(lowpass_cutoff_str) : 3390;