# HG changeset patch # User Michael Pavone # Date 1647661747 25200 # Node ID 9caebcfeac7238d1fd3c87ad7e34863f246a94fb # Parent 8554751f17b5ca1a72c59d4bb486c3d22a6151b8 Implement word RAM interleaving in 1M mode, now passes mcd-verificator word RAM tests diff -r 8554751f17b5 -r 9caebcfeac72 backend.c --- a/backend.c Thu Mar 17 22:41:42 2022 -0700 +++ b/backend.c Fri Mar 18 20:49:07 2022 -0700 @@ -96,11 +96,23 @@ : memmap[chunk].buffer; if (!base) { if (memmap[chunk].flags & MMAP_AUX_BUFF) { - return ((uint8_t *)memmap[chunk].buffer) + (address & memmap[chunk].aux_mask); + address &= memmap[chunk].aux_mask; + if (memmap[chunk].shift > 0) { + address <<= memmap[chunk].shift; + } else if (memmap[chunk].shift < 0) { + address >>= -memmap[chunk].shift; + } + return ((uint8_t *)memmap[chunk].buffer) + address; } return NULL; } - return base + (address & memmap[chunk].mask); + address &= memmap[chunk].mask; + if (memmap[chunk].shift > 0) { + address <<= memmap[chunk].shift; + } else if (memmap[chunk].shift < 0) { + address >>= -memmap[chunk].shift; + } + return base + address; } } return NULL; @@ -121,11 +133,23 @@ : memmap[chunk].buffer; if (!base) { if (memmap[chunk].flags & MMAP_AUX_BUFF) { - return ((uint8_t *)memmap[chunk].buffer) + (address & memmap[chunk].aux_mask); + address &= memmap[chunk].aux_mask; + if (memmap[chunk].shift > 0) { + address <<= memmap[chunk].shift; + } else if (memmap[chunk].shift < 0) { + address >>= -memmap[chunk].shift; + } + return ((uint8_t *)memmap[chunk].buffer) + address; } return NULL; } - return base + (address & memmap[chunk].mask); + address &= memmap[chunk].mask; + if (memmap[chunk].shift > 0) { + address <<= memmap[chunk].shift; + } else if (memmap[chunk].shift < 0) { + address >>= -memmap[chunk].shift; + } + return base + address; } } return NULL; @@ -147,6 +171,11 @@ } if (base) { uint16_t val; + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= chunk->shift; + } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { offset /= 2; val = base[offset]; @@ -182,6 +211,11 @@ base = chunk->buffer; } if (base) { + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= chunk->shift; + } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { offset /= 2; if (chunk->flags & MMAP_ONLY_EVEN) { @@ -214,6 +248,11 @@ base = chunk->buffer; } if (base) { + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= chunk->shift; + } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { if (address & 1) { if (chunk->flags & MMAP_ONLY_EVEN) { @@ -250,6 +289,11 @@ base = chunk->buffer; } if (base) { + if (chunk->shift > 0) { + offset <<= chunk->shift; + } else if (chunk->shift < 0){ + offset >>= chunk->shift; + } if ((chunk->flags & MMAP_ONLY_ODD) || (chunk->flags & MMAP_ONLY_EVEN)) { if (address & 1) { if (chunk->flags & MMAP_ONLY_EVEN) { diff -r 8554751f17b5 -r 9caebcfeac72 backend_x86.c --- a/backend_x86.c Thu Mar 17 22:41:42 2022 -0700 +++ b/backend_x86.c Fri Mar 18 20:49:07 2022 -0700 @@ -165,6 +165,29 @@ if (memmap[chunk].mask != opts->address_mask) { and_ir(code, memmap[chunk].mask, adr_reg, opts->address_size); } + code_ptr after_normal = NULL; + if (size == SZ_B && memmap[chunk].shift != 0) { + btr_ir(code, 0, adr_reg, opts->address_size); + code_ptr normal = code->cur+1; + jcc(code, CC_NC, normal); + if (memmap[chunk].shift > 0) { + shl_ir(code, memmap[chunk].shift, adr_reg, opts->address_size); + } else { + shr_ir(code, -memmap[chunk].shift, adr_reg, opts->address_size); + } + or_ir(code, 1, adr_reg, opts->address_size); + after_normal = code->cur + 1; + jmp(code, after_normal); + *normal = code->cur - (normal + 1); + } + if (memmap[chunk].shift > 0) { + shl_ir(code, memmap[chunk].shift, adr_reg, opts->address_size); + } else if (memmap[chunk].shift < 0) { + shr_ir(code, -memmap[chunk].shift, adr_reg, opts->address_size); + } + if (after_normal) { + *after_normal = code->cur - (after_normal + 1); + } void * cfun; switch (fun_type) { diff -r 8554751f17b5 -r 9caebcfeac72 genesis.c --- a/genesis.c Thu Mar 17 22:41:42 2022 -0700 +++ b/genesis.c Fri Mar 18 20:49:07 2022 -0700 @@ -1799,11 +1799,11 @@ static genesis_context *shared_init(uint32_t system_opts, rom_info *rom, uint8_t force_region) { static memmap_chunk z80_map[] = { - { 0x0000, 0x4000, 0x1FFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL, NULL, NULL, NULL, NULL }, - { 0x8000, 0x10000, 0x7FFF, 0, 0, 0, NULL, NULL, NULL, z80_read_bank, z80_write_bank}, - { 0x4000, 0x6000, 0x0003, 0, 0, 0, NULL, NULL, NULL, z80_read_ym, z80_write_ym}, - { 0x6000, 0x6100, 0xFFFF, 0, 0, 0, NULL, NULL, NULL, NULL, z80_write_bank_reg}, - { 0x7F00, 0x8000, 0x00FF, 0, 0, 0, NULL, NULL, NULL, z80_vdp_port_read, z80_vdp_port_write} + { 0x0000, 0x4000, 0x1FFF, .flags = MMAP_READ | MMAP_WRITE | MMAP_CODE}, + { 0x8000, 0x10000, 0x7FFF, .read_8 = z80_read_bank, .write_8 = z80_write_bank}, + { 0x4000, 0x6000, 0x0003, .read_8 = z80_read_ym, .write_8 = z80_write_ym}, + { 0x6000, 0x6100, 0xFFFF, .write_8 = z80_write_bank_reg}, + { 0x7F00, 0x8000, 0x00FF, .read_8 = z80_vdp_port_read, .write_8 = z80_vdp_port_write} }; char *m68k_divider = tern_find_path(config, "clocks\0m68k_divider\0", TVAL_PTR).ptrval; @@ -1926,17 +1926,13 @@ } static memmap_chunk base_map[] = { - {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL, - NULL, NULL, NULL, NULL}, - {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL, - (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, - (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, - {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL, - (read_16_fun)io_read_w, (write_16_fun)io_write_w, - (read_8_fun)io_read, (write_8_fun)io_write}, - {0x000000, 0xFFFFFF, 0xFFFFFF, 0, 0, 0, NULL, - (read_16_fun)unused_read, (write_16_fun)unused_write, - (read_8_fun)unused_read_b, (write_8_fun)unused_write_b} + {0xE00000, 0x1000000, 0xFFFF, .flags = MMAP_READ | MMAP_WRITE | MMAP_CODE}, + {0xC00000, 0xE00000, 0x1FFFFF, .read_16 = (read_16_fun)vdp_port_read, .write_16 =(write_16_fun)vdp_port_write, + .read_8 = (read_8_fun)vdp_port_read_b, .write_8 = (write_8_fun)vdp_port_write_b}, + {0xA00000, 0xA12000, 0x1FFFF, .read_16 = (read_16_fun)io_read_w, .write_16 = (write_16_fun)io_write_w, + .read_8 = (read_8_fun)io_read, .write_8 = (write_8_fun)io_write}, + {0x000000, 0xFFFFFF, 0xFFFFFF, .read_16 = (read_16_fun)unused_read, .write_16 = unused_write, + .read_8 = (read_8_fun)unused_read_b, .write_8 = (write_8_fun)unused_write_b} }; const size_t base_chunks = sizeof(base_map)/sizeof(*base_map); diff -r 8554751f17b5 -r 9caebcfeac72 memmap.h --- a/memmap.h Thu Mar 17 22:41:42 2022 -0700 +++ b/memmap.h Fri Mar 18 20:49:07 2022 -0700 @@ -29,6 +29,7 @@ uint32_t end; uint32_t mask; uint32_t aux_mask; + int32_t shift; uint16_t ptr_index; uint16_t flags; void * buffer; diff -r 8554751f17b5 -r 9caebcfeac72 segacd.c --- a/segacd.c Thu Mar 17 22:41:42 2022 -0700 +++ b/segacd.c Fri Mar 18 20:49:07 2022 -0700 @@ -131,12 +131,11 @@ static uint16_t word_ram_2M_read16(uint32_t address, void *vcontext) { m68k_context *m68k = vcontext; - //TODO: fixme for interleaving uint16_t* bank = m68k->mem_pointers[1]; if (!bank) { return 0xFFFF; } - uint16_t raw = bank[address >> 2]; + uint16_t raw = bank[address >> 1 & ~1]; if (address & 2) { return (raw & 0xF) | (raw << 4 & 0xF00); } else { @@ -157,30 +156,45 @@ { m68k_context *m68k = vcontext; segacd_context *cd = m68k->system; - value &= 0xF; - uint16_t priority = cd->gate_array[GA_MEM_MODE] & MASK_PRIORITY; + if (!(cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE)) { + if (address & 1) { + address >>= 1; + cd->word_ram[address] &= 0xFF00; + cd->word_ram[address] |= value; + } else { + address >>= 1; + cd->word_ram[address] &= 0x00FF; + cd->word_ram[address] |= value << 8; + } + cd->sub_paused_wordram = 1; + m68k->sync_cycle = m68k->target_cycle = m68k->current_cycle; + m68k->should_return = 1; + } else { + value &= 0xF; + uint16_t priority = cd->gate_array[GA_MEM_MODE] & MASK_PRIORITY; - if (priority == BIT_OVERWRITE && !value) { - return vcontext; - } - if (priority == BIT_UNDERWRITE) { - if (!value) { + if (priority == BIT_OVERWRITE && !value) { return vcontext; } - uint8_t old = word_ram_2M_read8(address, vcontext); - if (old) { + if (priority == BIT_UNDERWRITE) { + if (!value) { + return vcontext; + } + uint8_t old = word_ram_2M_read8(address, vcontext); + if (old) { + return vcontext; + } + } + uint16_t* bank = m68k->mem_pointers[1]; + if (!bank) { return vcontext; } - } - uint16_t* bank = m68k->mem_pointers[1]; - if (!bank) { - return vcontext; + uint16_t raw = bank[address >> 1 & ~1]; + uint16_t shift = ((address & 3) * 4); + raw &= ~(0xF000 >> shift); + raw |= value << (12 - shift); + bank[address >> 1 & ~1] = raw; } - uint16_t raw = bank[address >> 2]; - uint16_t shift = ((address & 3) * 4); - raw &= ~(0xF000 >> shift); - raw |= value << (12 - shift); - bank[address >> 2] = raw; return vcontext; } @@ -234,21 +248,60 @@ static uint16_t unmapped_word_read16(uint32_t address, void *vcontext) { - return 0xFFFF; + m68k_context *m68k = vcontext; + genesis_context *gen = m68k->system; + segacd_context *cd = gen->expansion; + if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { + return cd->word_ram[address + cd->bank_toggle]; + } else { + return 0xFFFF; + } } static uint8_t unmapped_word_read8(uint32_t address, void *vcontext) { - return 0xFF; + m68k_context *m68k = vcontext; + genesis_context *gen = m68k->system; + segacd_context *cd = gen->expansion; + if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { + if (address & 1) { + return cd->word_ram[(address & ~1) + cd->bank_toggle]; + } else { + return cd->word_ram[address + cd->bank_toggle] >> 8; + } + } else { + return 0xFF; + } } static void *unmapped_word_write16(uint32_t address, void *vcontext, uint16_t value) { + m68k_context *m68k = vcontext; + genesis_context *gen = m68k->system; + segacd_context *cd = gen->expansion; + if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { + cd->word_ram[address + cd->bank_toggle] = value; + m68k_invalidate_code_range(m68k, cd->base + address, address + 1); + } return vcontext; } static void *unmapped_word_write8(uint32_t address, void *vcontext, uint8_t value) { + m68k_context *m68k = vcontext; + genesis_context *gen = m68k->system; + segacd_context *cd = gen->expansion; + if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { + if (address & 1) { + uint32_t offset = (address & ~1) + cd->bank_toggle; + cd->word_ram[offset] &= 0xFF00; + cd->word_ram[offset] |= value; + } else { + cd->word_ram[address + cd->bank_toggle] &= 0xFF; + cd->word_ram[address + cd->bank_toggle] |= value << 8; + } + m68k_invalidate_code_range(m68k, cd->base + (address & ~1), address + 1); + } return vcontext; } @@ -286,10 +339,10 @@ m68k_context *m68k = vcontext; genesis_context *gen = m68k->system; segacd_context *cd = gen->expansion; - if (!m68k->mem_pointers[cd->memptr_start_index + 1]) { + if (!(cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE)) { return 0xFFFF; } - return m68k->mem_pointers[cd->memptr_start_index + 1][address>>1]; + return cd->word_ram[address + cd->bank_toggle]; } static uint8_t cell_image_read8(uint32_t address, void *vcontext) @@ -303,12 +356,12 @@ static void *cell_image_write16(uint32_t address, void *vcontext, uint16_t value) { - address = cell_image_translate_address(address); m68k_context *m68k = vcontext; genesis_context *gen = m68k->system; segacd_context *cd = gen->expansion; - if (m68k->mem_pointers[cd->memptr_start_index + 1]) { - m68k->mem_pointers[cd->memptr_start_index + 1][address>>1] = value; + if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { + address = cell_image_translate_address(address); + cd->word_ram[address + cd->bank_toggle] = value; } return vcontext; } @@ -320,13 +373,13 @@ m68k_context *m68k = vcontext; genesis_context *gen = m68k->system; segacd_context *cd = gen->expansion; - if (m68k->mem_pointers[cd->memptr_start_index + 1]) { + if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { if (byte) { - m68k->mem_pointers[cd->memptr_start_index + 1][address>>1] &= 0xFF00; - m68k->mem_pointers[cd->memptr_start_index + 1][address>>1] |= value; + cd->word_ram[address + cd->bank_toggle] &= 0xFF00; + cd->word_ram[address + cd->bank_toggle] |= value; } else { - m68k->mem_pointers[cd->memptr_start_index + 1][address>>1] &= 0x00FF; - m68k->mem_pointers[cd->memptr_start_index + 1][address>>1] |= value << 8; + cd->word_ram[address + cd->bank_toggle] &= 0x00FF; + cd->word_ram[address + cd->bank_toggle] |= value << 8; } } return vcontext; @@ -624,14 +677,13 @@ genesis_context *gen = cd->genesis; cd->gate_array[reg] &= 0xFFC0; if (changed & BIT_MEM_MODE) { - //FIXME: ram banks are supposed to be interleaved when in 2M mode cd->main_swap_request = cd->bank_toggle && !old_bank_toggle; if (value & BIT_MEM_MODE) { //switch to 1M mode - gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram; + gen->m68k->mem_pointers[cd->memptr_start_index + 1] = NULL; //(value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram; gen->m68k->mem_pointers[cd->memptr_start_index + 2] = NULL; m68k->mem_pointers[0] = NULL; - m68k->mem_pointers[1] = cd->bank_toggle ? cd->word_ram : cd->word_ram + 0x10000; + m68k->mem_pointers[1] = cd->bank_toggle ? cd->word_ram : cd->word_ram + 1; cd->gate_array[reg] |= value & (MASK_PRIORITY|BIT_RET|BIT_MEM_MODE); if (cd->main_swap_request) { cd->gate_array[reg] |= BIT_DMNA; @@ -659,8 +711,7 @@ } else if (value & BIT_MEM_MODE) { //1M mode if (old_bank_toggle != cd->bank_toggle) { - gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram; - m68k->mem_pointers[1] = (value & BIT_RET) ? cd->word_ram : cd->word_ram + 0x10000; + m68k->mem_pointers[1] = (value & BIT_RET) ? cd->word_ram : cd->word_ram + 1; m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000); m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000); cd->main_swap_request = 0; @@ -920,8 +971,8 @@ case DST_WORD_RAM: if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { //1M mode, write to bank assigned to Sub CPU - dma_addr &= (1 << 17) - 1; - cd->m68k->mem_pointers[1][dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA]; + dma_addr &= (1 << 17) - 2; + cd->m68k->mem_pointers[1][dma_addr] = cd->gate_array[GA_CDC_HOST_DATA]; m68k_invalidate_code_range(cd->m68k, 0x0C0000 + dma_addr - 1, 0x0C0000 + dma_addr + 1); } else { //2M mode, check if Sub CPU has access @@ -1001,7 +1052,7 @@ { uint8_t m68k_run = !can_main_access_prog(cd); while (cycle > cd->m68k->current_cycle) { - if (m68k_run) { + if (m68k_run && !cd->sub_paused_wordram) { uint32_t start = cd->m68k->current_cycle; cd->m68k->sync_cycle = cd->enter_debugger ? cd->m68k->current_cycle + 1 : cycle; if (cd->need_reset) { @@ -1202,6 +1253,9 @@ cd->m68k->mem_pointers[0] = cd->word_ram; cd->gate_array[reg] &= ~BIT_RET; cd->main_has_word2m = 0; + if (cd->sub_paused_wordram) { + cd->sub_paused_wordram = 0; + } uint16_t dst = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7; if (dst == DST_WORD_RAM) { @@ -1289,7 +1343,7 @@ {0x080000, 0x0C0000, 0x03FFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE | MMAP_PTR_IDX | MMAP_FUNC_NULL, .ptr_index = 0, .read_16 = word_ram_2M_read16, .write_16 = word_ram_2M_write16, .read_8 = word_ram_2M_read8, .write_8 = word_ram_2M_write8}, {0x0C0000, 0x0E0000, 0x01FFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE | MMAP_PTR_IDX | MMAP_FUNC_NULL, .ptr_index = 1, - .read_16 = word_ram_1M_read16, .write_16 = word_ram_1M_write16, .read_8 = word_ram_1M_read8, .write_8 = word_ram_1M_write8}, + .read_16 = word_ram_1M_read16, .write_16 = word_ram_1M_write16, .read_8 = word_ram_1M_read8, .write_8 = word_ram_1M_write8, .shift = 1}, {0xFE0000, 0xFF0000, 0x003FFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_ONLY_ODD}, {0xFF0000, 0xFF8000, 0x003FFF, .read_16 = pcm_read16, .write_16 = pcm_write16, .read_8 = pcm_read8, .write_8 = pcm_write8}, {0xFF8000, 0xFF8200, 0x0001FF, .read_16 = sub_gate_read16, .write_16 = sub_gate_write16, .read_8 = sub_gate_read8, .write_8 = sub_gate_write8} diff -r 8554751f17b5 -r 9caebcfeac72 segacd.h --- a/segacd.h Thu Mar 17 22:41:42 2022 -0700 +++ b/segacd.h Fri Mar 18 20:49:07 2022 -0700 @@ -47,6 +47,7 @@ uint8_t main_has_word2m; uint8_t main_swap_request; uint8_t bank_toggle; + uint8_t sub_paused_wordram; } segacd_context; segacd_context *alloc_configure_segacd(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info); diff -r 8554751f17b5 -r 9caebcfeac72 sms.c --- a/sms.c Thu Mar 17 22:41:42 2022 -0700 +++ b/sms.c Fri Mar 18 20:49:07 2022 -0700 @@ -196,10 +196,10 @@ } 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}, - {0x80, 0xC0, 0xFF, 0, 0, 0, NULL, NULL, NULL, vdp_read, vdp_write}, - {0xC0, 0x100,0xFF, 0, 0, 0, NULL, NULL, NULL, io_read, NULL} + {0x00, 0x40, 0xFF, .write_8 = memory_io_write}, + {0x40, 0x80, 0xFF, .read_8 = hv_read, .write_8 = sms_psg_write}, + {0x80, 0xC0, 0xFF, .read_8 = vdp_read, .write_8 = vdp_write}, + {0xC0, 0x100,0xFF, .read_8 = io_read} }; static void set_speed_percent(system_header * system, uint32_t percent) @@ -216,33 +216,33 @@ start_section(buf, SECTION_Z80); z80_serialize(sms->z80, buf); end_section(buf); - + start_section(buf, SECTION_VDP); vdp_serialize(sms->vdp, buf); end_section(buf); - + start_section(buf, SECTION_PSG); psg_serialize(sms->psg, buf); end_section(buf); - + start_section(buf, SECTION_SEGA_IO_1); io_serialize(sms->io.ports, buf); end_section(buf); - + start_section(buf, SECTION_SEGA_IO_2); io_serialize(sms->io.ports + 1, buf); end_section(buf); - + start_section(buf, SECTION_MAIN_RAM); save_int8(buf, sizeof(sms->ram) / 1024); save_buffer8(buf, sms->ram, sizeof(sms->ram)); end_section(buf); - + start_section(buf, SECTION_MAPPER); save_int8(buf, 1);//mapper type, 1 for Sega mapper save_buffer8(buf, sms->bank_regs, sizeof(sms->bank_regs)); end_section(buf); - + start_section(buf, SECTION_CART_RAM); save_int8(buf, SMS_CART_RAM_SIZE / 1024); save_buffer8(buf, sms->cart_ram, SMS_CART_RAM_SIZE); @@ -364,7 +364,7 @@ system->delayed_load_slot = slot + 1; } goto done; - + } #endif ret = load_state_path(sms, statepath); @@ -384,7 +384,7 @@ if (system->delayed_load_slot) { load_state(system, system->delayed_load_slot - 1); system->delayed_load_slot = 0; - + } if (system->enter_debugger && sms->z80->pc) { system->enter_debugger = 0; @@ -407,7 +407,7 @@ target_cycle = sms->z80->Z80_CYCLE; vdp_run_context(sms->vdp, target_cycle); psg_run(sms->psg, target_cycle); - + if (system->save_state) { while (!sms->z80->pc) { //advance Z80 to an instruction boundary @@ -416,7 +416,7 @@ save_state(sms, system->save_state - 1); system->save_state = 0; } - + target_cycle += 3420*16; if (target_cycle > 0x10000000) { uint32_t adjust = sms->z80->Z80_CYCLE - 3420*262*2; @@ -451,19 +451,19 @@ static void start_sms(system_header *system, char *statefile) { sms_context *sms = (sms_context *)system; - + z80_assert_reset(sms->z80, 0); z80_clear_reset(sms->z80, 128*15); - + if (statefile) { load_state_path(sms, statefile); } - + if (system->enter_debugger) { system->enter_debugger = 0; zinsert_breakpoint(sms->z80, sms->z80->pc, (uint8_t *)zdebugger); } - + run_sms(system); } @@ -592,16 +592,16 @@ if (media->size > 0xC000) { sms->header.info.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, media->buffer, NULL, NULL, NULL, NULL}; - memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, 0, 0, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL}; - memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, 0, 1, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, NULL}; - memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, 0, 2, MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, NULL, NULL, NULL, NULL, cart_ram_write}; - 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, 0x0003, 0, 0, MMAP_READ, ram_reg_overlap, NULL, NULL, NULL, mapper_write}; + memory_map[0] = (memmap_chunk){0x0000, 0x0400, 0xFFFF, .flags = MMAP_READ, .buffer = media->buffer}; + memory_map[1] = (memmap_chunk){0x0400, 0x4000, 0xFFFF, .ptr_index = 0, .flags = MMAP_READ|MMAP_PTR_IDX|MMAP_CODE}; + memory_map[2] = (memmap_chunk){0x4000, 0x8000, 0x3FFF, .ptr_index = 1, .flags = MMAP_READ|MMAP_PTR_IDX|MMAP_CODE}; + memory_map[3] = (memmap_chunk){0x8000, 0xC000, 0x3FFF, .ptr_index = 2, .flags = MMAP_READ|MMAP_PTR_IDX|MMAP_CODE, .write_8 = cart_ram_write}; + memory_map[4] = (memmap_chunk){0xC000, 0xFFFC, sizeof(sms->ram)-1, .ptr_index = 0, .flags = MMAP_READ|MMAP_WRITE|MMAP_CODE, .buffer = sms->ram}; + memory_map[5] = (memmap_chunk){0xFFFC, 0x10000, 0x0003, .ptr_index = 0, .flags = MMAP_READ, .buffer = ram_reg_overlap, .write_8 = mapper_write}; } else { sms->header.info.map_chunks = 2; - memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, MMAP_READ, media->buffer, 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}; + memory_map[0] = (memmap_chunk){0x0000, 0xC000, rom_size-1, 0, 0, .flags = MMAP_READ, .buffer = media->buffer}; + memory_map[1] = (memmap_chunk){0xC000, 0x10000, sizeof(sms->ram)-1, 0, 0, .flags = MMAP_READ|MMAP_WRITE|MMAP_CODE, .buffer = sms->ram}; }; sms->header.info.map = malloc(sizeof(memmap_chunk) * sms->header.info.map_chunks); memcpy(sms->header.info.map, memory_map, sizeof(memmap_chunk) * sms->header.info.map_chunks); @@ -610,7 +610,7 @@ sms->z80 = init_z80_context(zopts); sms->z80->system = sms; sms->z80->Z80_OPTS->gen.debug_cmd_handler = debug_commands; - + sms->rom = media->buffer; sms->rom_size = rom_size; if (sms->header.info.map_chunks > 2) { @@ -621,24 +621,24 @@ sms->bank_regs[2] = 0x4000 >> 14; sms->bank_regs[3] = 0x8000 >> 14; } - + //TODO: Detect region and pick master clock based off of that sms->normal_clock = sms->master_clock = 53693175; - + sms->psg = malloc(sizeof(psg_context)); psg_init(sms->psg, sms->master_clock, 15*16); - + set_gain_config(sms); - + sms->vdp = init_vdp_context(0, 0); sms->vdp->system = &sms->header; - + sms->header.info.save_type = SAVE_NONE; sms->header.info.name = strdup(media->name); - + setup_io_devices(config, &sms->header.info, &sms->io); sms->header.has_keyboard = io_has_keyboard(&sms->io); - + sms->header.set_speed_percent = set_speed_percent; sms->header.start_context = start_sms; sms->header.resume_context = resume_sms; @@ -662,6 +662,6 @@ sms->header.serialize = serialize; sms->header.deserialize = deserialize; sms->header.type = SYSTEM_SMS; - + return sms; -} \ No newline at end of file +}