comparison genesis.c @ 2054:8ee7ecbf3f21 segacd

Implement enough of Sega CD gate array and Sub CPU to pass Sik's Mode 1 test ROM
author Michael Pavone <pavone@retrodev.com>
date Tue, 18 Jan 2022 00:03:50 -0800
parents 3414a4423de1
children bafb757e1cd2
comparison
equal deleted inserted replaced
2053:3414a4423de1 2054:8ee7ecbf3f21
245 } 245 }
246 246
247 uint16_t read_dma_value(uint32_t address) 247 uint16_t read_dma_value(uint32_t address)
248 { 248 {
249 genesis_context *genesis = (genesis_context *)current_system; 249 genesis_context *genesis = (genesis_context *)current_system;
250 address *= 2;
250 //TODO: Figure out what happens when you try to DMA from weird adresses like IO or banked Z80 area 251 //TODO: Figure out what happens when you try to DMA from weird adresses like IO or banked Z80 area
251 if ((address >= 0xA00000 && address < 0xB00000) || (address >= 0xC00000 && address <= 0xE00000)) { 252 if ((address >= 0xA00000 && address < 0xB00000) || (address >= 0xC00000 && address <= 0xE00000)) {
252 return 0; 253 return 0;
253 } 254 }
254 255 if (genesis->expansion) {
255 //addresses here are word addresses (i.e. bit 0 corresponds to A1), so no need to do multiply by 2 256 segacd_context *cd = genesis->expansion;
256 return read_word(address * 2, (void **)genesis->m68k->mem_pointers, &genesis->m68k->options->gen, genesis->m68k); 257 uint32_t word_ram = cd->base + 0x200000;
258 uint32_t word_ram_end = cd->base + 0x240000;
259 if (address >= word_ram && address < word_ram_end) {
260 //FIXME: first word should just be garbage
261 address -= 2;
262 }
263 }
264
265 return read_word(address, (void **)genesis->m68k->mem_pointers, &genesis->m68k->options->gen, genesis->m68k);
257 } 266 }
258 267
259 static uint16_t get_open_bus_value(system_header *system) 268 static uint16_t get_open_bus_value(system_header *system)
260 { 269 {
261 genesis_context *genesis = (genesis_context *)system; 270 genesis_context *genesis = (genesis_context *)system;
411 420
412 #include <limits.h> 421 #include <limits.h>
413 #define ADJUST_BUFFER (8*MCLKS_LINE*313) 422 #define ADJUST_BUFFER (8*MCLKS_LINE*313)
414 #define MAX_NO_ADJUST (UINT_MAX-ADJUST_BUFFER) 423 #define MAX_NO_ADJUST (UINT_MAX-ADJUST_BUFFER)
415 424
416 m68k_context * sync_components(m68k_context * context, uint32_t address) 425 static m68k_context *sync_components(m68k_context * context, uint32_t address)
417 { 426 {
418 genesis_context * gen = context->system; 427 genesis_context * gen = context->system;
419 vdp_context * v_context = gen->vdp; 428 vdp_context * v_context = gen->vdp;
420 z80_context * z_context = gen->z80; 429 z80_context * z_context = gen->z80;
421 #ifdef REFRESH_EMULATION 430 #ifdef REFRESH_EMULATION
432 sync_sound(gen, mclks); 441 sync_sound(gen, mclks);
433 vdp_run_context(v_context, mclks); 442 vdp_run_context(v_context, mclks);
434 io_run(gen->io.ports, mclks); 443 io_run(gen->io.ports, mclks);
435 io_run(gen->io.ports + 1, mclks); 444 io_run(gen->io.ports + 1, mclks);
436 io_run(gen->io.ports + 2, mclks); 445 io_run(gen->io.ports + 2, mclks);
446 if (gen->expansion) {
447 scd_run(gen->expansion, gen_cycle_to_scd(mclks, gen));
448 }
437 if (mclks >= gen->reset_cycle) { 449 if (mclks >= gen->reset_cycle) {
438 gen->reset_requested = 1; 450 gen->reset_requested = 1;
439 context->should_return = 1; 451 context->should_return = 1;
440 gen->reset_cycle = CYCLE_NEVER; 452 gen->reset_cycle = CYCLE_NEVER;
441 } 453 }
469 gen->psg->cycles -= deduction; 481 gen->psg->cycles -= deduction;
470 if (gen->reset_cycle != CYCLE_NEVER) { 482 if (gen->reset_cycle != CYCLE_NEVER) {
471 gen->reset_cycle -= deduction; 483 gen->reset_cycle -= deduction;
472 } 484 }
473 event_cycle_adjust(mclks, deduction); 485 event_cycle_adjust(mclks, deduction);
486 if (gen->expansion) {
487 scd_adjust_cycle(gen->expansion, deduction);
488 }
474 gen->last_flush_cycle -= deduction; 489 gen->last_flush_cycle -= deduction;
475 } 490 }
476 } else if (mclks - gen->last_flush_cycle > gen->soft_flush_cycles) { 491 } else if (mclks - gen->last_flush_cycle > gen->soft_flush_cycles) {
477 event_soft_flush(mclks); 492 event_soft_flush(mclks);
478 gen->last_flush_cycle = mclks; 493 gen->last_flush_cycle = mclks;
1876 } 1891 }
1877 1892
1878 return gen; 1893 return gen;
1879 } 1894 }
1880 1895
1881 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region) 1896 static memmap_chunk base_map[] = {
1882 { 1897 {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL,
1883 genesis_context *gen = shared_init(system_opts, rom, force_region); 1898 NULL, NULL, NULL, NULL},
1884 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = (uint8_t *)main_rom; 1899 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL,
1885 1900 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
1886 gen->cart = main_rom; 1901 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
1902 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL,
1903 (read_16_fun)io_read_w, (write_16_fun)io_write_w,
1904 (read_8_fun)io_read, (write_8_fun)io_write},
1905 {0x000000, 0xFFFFFF, 0xFFFFFF, 0, 0, 0, NULL,
1906 (read_16_fun)unused_read, (write_16_fun)unused_write,
1907 (read_8_fun)unused_read_b, (write_8_fun)unused_write_b}
1908 };
1909 const size_t base_chunks = sizeof(base_map)/sizeof(*base_map);
1910
1911 genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t ym_opts, uint8_t force_region)
1912 {
1913 tern_node *rom_db = get_rom_db();
1914 rom_info info = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks);
1915 rom = info.rom;
1916 rom_size = info.rom_size;
1917 #ifndef BLASTEM_BIG_ENDIAN
1918 byteswap_rom(rom_size, rom);
1919 if (lock_on) {
1920 byteswap_rom(lock_on_size, lock_on);
1921 }
1922 #endif
1923 char *m68k_divider = tern_find_path(config, "clocks\0m68k_divider\0", TVAL_PTR).ptrval;
1924 if (!m68k_divider) {
1925 m68k_divider = "7";
1926 }
1927 MCLKS_PER_68K = atoi(m68k_divider);
1928 if (!MCLKS_PER_68K) {
1929 MCLKS_PER_68K = 7;
1930 }
1931 genesis_context *gen = shared_init(ym_opts, &info, force_region);
1932 gen->z80->mem_pointers[1] = gen->z80->mem_pointers[2] = rom;
1933
1934 gen->cart = rom;
1887 gen->lock_on = lock_on; 1935 gen->lock_on = lock_on;
1888 1936
1889 setup_io_devices(config, rom, &gen->io); 1937 setup_io_devices(config, &info, &gen->io);
1890 gen->header.has_keyboard = io_has_keyboard(&gen->io); 1938 gen->header.has_keyboard = io_has_keyboard(&gen->io);
1891 gen->mapper_type = rom->mapper_type; 1939 gen->mapper_type = info.mapper_type;
1892 gen->save_type = rom->save_type; 1940 gen->save_type = info.save_type;
1893 if (gen->save_type != SAVE_NONE) { 1941 if (gen->save_type != SAVE_NONE) {
1894 gen->save_ram_mask = rom->save_mask; 1942 gen->save_ram_mask = info.save_mask;
1895 gen->save_size = rom->save_size; 1943 gen->save_size = info.save_size;
1896 gen->save_storage = rom->save_buffer; 1944 gen->save_storage = info.save_buffer;
1897 gen->eeprom_map = rom->eeprom_map; 1945 gen->eeprom_map = info.eeprom_map;
1898 gen->num_eeprom = rom->num_eeprom; 1946 gen->num_eeprom = info.num_eeprom;
1899 if (gen->save_type == SAVE_I2C) { 1947 if (gen->save_type == SAVE_I2C) {
1900 eeprom_init(&gen->eeprom, gen->save_storage, gen->save_size); 1948 eeprom_init(&gen->eeprom, gen->save_storage, gen->save_size);
1901 } else if (gen->save_type == SAVE_NOR) { 1949 } else if (gen->save_type == SAVE_NOR) {
1902 memcpy(&gen->nor, rom->nor, sizeof(gen->nor)); 1950 memcpy(&gen->nor, info.nor, sizeof(gen->nor));
1903 //nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, rom->save_page_size, rom->save_product_id, rom->save_bus); 1951 //nor_flash_init(&gen->nor, gen->save_storage, gen->save_size, info.save_page_size, info.save_product_id, info.save_bus);
1904 } 1952 }
1905 } else { 1953 } else {
1906 gen->save_storage = NULL; 1954 gen->save_storage = NULL;
1907 } 1955 }
1908 1956
1909 gen->mapper_start_index = rom->mapper_start_index; 1957 gen->mapper_start_index = info.mapper_start_index;
1910 1958
1911 tern_node *model = get_model(config, SYSTEM_GENESIS); 1959 tern_node *model = get_model(config, SYSTEM_GENESIS);
1912 uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on"); 1960 uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on");
1913 1961
1914 //This must happen before we generate memory access functions in init_m68k_opts 1962 //This must happen before we generate memory access functions in init_m68k_opts
1915 uint8_t next_ptr_index = 0; 1963 uint8_t next_ptr_index = 0;
1916 uint32_t tmss_min_alloc = 16 * 1024; 1964 uint32_t tmss_min_alloc = 16 * 1024;
1917 for (int i = 0; i < rom->map_chunks; i++) 1965 for (int i = 0; i < info.map_chunks; i++)
1918 { 1966 {
1919 if (rom->map[i].start == 0xE00000) { 1967 if (info.map[i].start == 0xE00000) {
1920 rom->map[i].buffer = gen->work_ram; 1968 info.map[i].buffer = gen->work_ram;
1921 if (!tmss) { 1969 if (!tmss) {
1922 break; 1970 break;
1923 } 1971 }
1924 } 1972 }
1925 if (rom->map[i].flags & MMAP_PTR_IDX && rom->map[i].ptr_index >= next_ptr_index) { 1973 if (info.map[i].flags & MMAP_PTR_IDX && info.map[i].ptr_index >= next_ptr_index) {
1926 next_ptr_index = rom->map[i].ptr_index + 1; 1974 next_ptr_index = info.map[i].ptr_index + 1;
1927 } 1975 }
1928 if (rom->map[i].start < 0x400000 && rom->map[i].read_16 != unused_read) { 1976 if (info.map[i].start < 0x400000 && info.map[i].read_16 != unused_read) {
1929 uint32_t highest_offset = (rom->map[i].end & rom->map[i].mask) + 1; 1977 uint32_t highest_offset = (info.map[i].end & info.map[i].mask) + 1;
1930 if (highest_offset > tmss_min_alloc) { 1978 if (highest_offset > tmss_min_alloc) {
1931 tmss_min_alloc = highest_offset; 1979 tmss_min_alloc = highest_offset;
1932 } 1980 }
1933 } 1981 }
1934 } 1982 }
1963 { 2011 {
1964 memcpy(buffer + dst, buffer, dst + tmss_size > tmss_min_alloc ? tmss_min_alloc - dst : tmss_size); 2012 memcpy(buffer + dst, buffer, dst + tmss_size > tmss_min_alloc ? tmss_min_alloc - dst : tmss_size);
1965 } 2013 }
1966 //modify mappings for ROM space to point to the TMSS ROM and fixup flags to allow switching back and forth 2014 //modify mappings for ROM space to point to the TMSS ROM and fixup flags to allow switching back and forth
1967 //WARNING: This code makes some pretty big assumptions about the kinds of map chunks it will encounter 2015 //WARNING: This code makes some pretty big assumptions about the kinds of map chunks it will encounter
1968 for (int i = 0; i < rom->map_chunks; i++) 2016 for (int i = 0; i < info.map_chunks; i++)
1969 { 2017 {
1970 if (rom->map[i].start < 0x400000 && rom->map[i].read_16 != unused_read) { 2018 if (info.map[i].start < 0x400000 && info.map[i].read_16 != unused_read) {
1971 if (rom->map[i].flags == MMAP_READ) { 2019 if (info.map[i].flags == MMAP_READ) {
1972 //Normal ROM 2020 //Normal ROM
1973 rom->map[i].flags |= MMAP_PTR_IDX | MMAP_CODE; 2021 info.map[i].flags |= MMAP_PTR_IDX | MMAP_CODE;
1974 rom->map[i].ptr_index = next_ptr_index++; 2022 info.map[i].ptr_index = next_ptr_index++;
1975 if (rom->map[i].ptr_index >= NUM_MEM_AREAS) { 2023 if (info.map[i].ptr_index >= NUM_MEM_AREAS) {
1976 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n"); 2024 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n");
1977 } 2025 }
1978 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer; 2026 gen->tmss_pointers[info.map[i].ptr_index] = info.map[i].buffer;
1979 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1)); 2027 info.map[i].buffer = buffer + (info.map[i].start & ~info.map[i].mask & (tmss_size - 1));
1980 } else if (rom->map[i].flags & MMAP_PTR_IDX) { 2028 } else if (info.map[i].flags & MMAP_PTR_IDX) {
1981 //Sega mapper page or multi-game mapper 2029 //Sega mapper page or multi-game mapper
1982 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer; 2030 gen->tmss_pointers[info.map[i].ptr_index] = info.map[i].buffer;
1983 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1)); 2031 info.map[i].buffer = buffer + (info.map[i].start & ~info.map[i].mask & (tmss_size - 1));
1984 if (rom->map[i].write_16) { 2032 if (info.map[i].write_16) {
1985 if (!gen->tmss_write_16) { 2033 if (!gen->tmss_write_16) {
1986 gen->tmss_write_16 = rom->map[i].write_16; 2034 gen->tmss_write_16 = info.map[i].write_16;
1987 gen->tmss_write_8 = rom->map[i].write_8; 2035 gen->tmss_write_8 = info.map[i].write_8;
1988 rom->map[i].write_16 = tmss_rom_write_16; 2036 info.map[i].write_16 = tmss_rom_write_16;
1989 rom->map[i].write_8 = tmss_rom_write_8; 2037 info.map[i].write_8 = tmss_rom_write_8;
1990 } else if (gen->tmss_write_16 == rom->map[i].write_16) { 2038 } else if (gen->tmss_write_16 == info.map[i].write_16) {
1991 rom->map[i].write_16 = tmss_rom_write_16; 2039 info.map[i].write_16 = tmss_rom_write_16;
1992 rom->map[i].write_8 = tmss_rom_write_8; 2040 info.map[i].write_8 = tmss_rom_write_8;
1993 } else { 2041 } else {
1994 warning("Chunk starting at %X has a write function, but we've already stored a different one for TMSS remap\n", rom->map[i].start); 2042 warning("Chunk starting at %X has a write function, but we've already stored a different one for TMSS remap\n", info.map[i].start);
1995 } 2043 }
1996 } 2044 }
1997 } else if ((rom->map[i].flags & (MMAP_READ | MMAP_WRITE)) == (MMAP_READ | MMAP_WRITE)) { 2045 } else if ((info.map[i].flags & (MMAP_READ | MMAP_WRITE)) == (MMAP_READ | MMAP_WRITE)) {
1998 //RAM or SRAM 2046 //RAM or SRAM
1999 rom->map[i].flags |= MMAP_PTR_IDX; 2047 info.map[i].flags |= MMAP_PTR_IDX;
2000 rom->map[i].ptr_index = next_ptr_index++; 2048 info.map[i].ptr_index = next_ptr_index++;
2001 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer; 2049 gen->tmss_pointers[info.map[i].ptr_index] = info.map[i].buffer;
2002 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1)); 2050 info.map[i].buffer = buffer + (info.map[i].start & ~info.map[i].mask & (tmss_size - 1));
2003 if (!gen->tmss_write_offset || gen->tmss_write_offset == rom->map[i].start) { 2051 if (!gen->tmss_write_offset || gen->tmss_write_offset == info.map[i].start) {
2004 gen->tmss_write_offset = rom->map[i].start; 2052 gen->tmss_write_offset = info.map[i].start;
2005 rom->map[i].flags &= ~MMAP_WRITE; 2053 info.map[i].flags &= ~MMAP_WRITE;
2006 if (rom->map[i].flags & MMAP_ONLY_ODD) { 2054 if (info.map[i].flags & MMAP_ONLY_ODD) {
2007 rom->map[i].write_16 = tmss_odd_write_16; 2055 info.map[i].write_16 = tmss_odd_write_16;
2008 rom->map[i].write_8 = tmss_odd_write_8; 2056 info.map[i].write_8 = tmss_odd_write_8;
2009 } else if (rom->map[i].flags & MMAP_ONLY_EVEN) { 2057 } else if (info.map[i].flags & MMAP_ONLY_EVEN) {
2010 rom->map[i].write_16 = tmss_even_write_16; 2058 info.map[i].write_16 = tmss_even_write_16;
2011 rom->map[i].write_8 = tmss_even_write_8; 2059 info.map[i].write_8 = tmss_even_write_8;
2012 } else { 2060 } else {
2013 rom->map[i].write_16 = tmss_word_write_16; 2061 info.map[i].write_16 = tmss_word_write_16;
2014 rom->map[i].write_8 = tmss_word_write_8; 2062 info.map[i].write_8 = tmss_word_write_8;
2015 } 2063 }
2016 } else { 2064 } else {
2017 warning("Could not remap writes for chunk starting at %X for TMSS because write_offset is %X\n", rom->map[i].start, gen->tmss_write_offset); 2065 warning("Could not remap writes for chunk starting at %X for TMSS because write_offset is %X\n", info.map[i].start, gen->tmss_write_offset);
2018 } 2066 }
2019 } else if (rom->map[i].flags & MMAP_READ_CODE) { 2067 } else if (info.map[i].flags & MMAP_READ_CODE) {
2020 //NOR flash 2068 //NOR flash
2021 rom->map[i].flags |= MMAP_PTR_IDX; 2069 info.map[i].flags |= MMAP_PTR_IDX;
2022 rom->map[i].ptr_index = next_ptr_index++; 2070 info.map[i].ptr_index = next_ptr_index++;
2023 if (rom->map[i].ptr_index >= NUM_MEM_AREAS) { 2071 if (info.map[i].ptr_index >= NUM_MEM_AREAS) {
2024 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n"); 2072 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n");
2025 } 2073 }
2026 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer; 2074 gen->tmss_pointers[info.map[i].ptr_index] = info.map[i].buffer;
2027 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1)); 2075 info.map[i].buffer = buffer + (info.map[i].start & ~info.map[i].mask & (tmss_size - 1));
2028 if (!gen->tmss_write_16) { 2076 if (!gen->tmss_write_16) {
2029 gen->tmss_write_16 = rom->map[i].write_16; 2077 gen->tmss_write_16 = info.map[i].write_16;
2030 gen->tmss_write_8 = rom->map[i].write_8; 2078 gen->tmss_write_8 = info.map[i].write_8;
2031 gen->tmss_read_16 = rom->map[i].read_16; 2079 gen->tmss_read_16 = info.map[i].read_16;
2032 gen->tmss_read_8 = rom->map[i].read_8; 2080 gen->tmss_read_8 = info.map[i].read_8;
2033 rom->map[i].write_16 = tmss_rom_write_16; 2081 info.map[i].write_16 = tmss_rom_write_16;
2034 rom->map[i].write_8 = tmss_rom_write_8; 2082 info.map[i].write_8 = tmss_rom_write_8;
2035 rom->map[i].read_16 = tmss_rom_read_16; 2083 info.map[i].read_16 = tmss_rom_read_16;
2036 rom->map[i].read_8 = tmss_rom_read_8; 2084 info.map[i].read_8 = tmss_rom_read_8;
2037 } else if (gen->tmss_write_16 == rom->map[i].write_16) { 2085 } else if (gen->tmss_write_16 == info.map[i].write_16) {
2038 rom->map[i].write_16 = tmss_rom_write_16; 2086 info.map[i].write_16 = tmss_rom_write_16;
2039 rom->map[i].write_8 = tmss_rom_write_8; 2087 info.map[i].write_8 = tmss_rom_write_8;
2040 rom->map[i].read_16 = tmss_rom_read_16; 2088 info.map[i].read_16 = tmss_rom_read_16;
2041 rom->map[i].read_8 = tmss_rom_read_8; 2089 info.map[i].read_8 = tmss_rom_read_8;
2042 } else { 2090 } else {
2043 warning("Chunk starting at %X has a write function, but we've already stored a different one for TMSS remap\n", rom->map[i].start); 2091 warning("Chunk starting at %X has a write function, but we've already stored a different one for TMSS remap\n", info.map[i].start);
2044 } 2092 }
2045 } else { 2093 } else {
2046 warning("Didn't remap chunk starting at %X for TMSS because it has flags %X\n", rom->map[i].start, rom->map[i].flags); 2094 warning("Didn't remap chunk starting at %X for TMSS because it has flags %X\n", info.map[i].start, info.map[i].flags);
2047 } 2095 }
2048 } 2096 }
2049 } 2097 }
2050 gen->tmss_buffer = buffer; 2098 gen->tmss_buffer = buffer;
2051 } 2099 }
2100 memmap_chunk* map = info.map;
2101 uint32_t map_chunks = info.map_chunks;
2102 if (info.wants_cd) {
2103 segacd_context *cd = alloc_configure_segacd((system_media *)current_media(), 0, force_region, &info);
2104 gen->expansion = cd;
2105 gen->version_reg &= ~NO_DISK;
2106 cd->genesis = gen;
2107 uint32_t cd_chunks;
2108 memmap_chunk *cd_map = segacd_main_cpu_map(gen->expansion, 1, &cd_chunks);
2109 map_chunks = cd_chunks + info.map_chunks;
2110 map = calloc(map_chunks, sizeof(memmap_chunk));
2111 memcpy(map, info.map, sizeof(memmap_chunk) * (info.map_chunks - 1));
2112 memcpy(map + info.map_chunks - 1, cd_map, sizeof(memmap_chunk) * cd_chunks);
2113 memcpy(map + map_chunks - 1, info.map + info.map_chunks - 1, sizeof(memmap_chunk));
2114 free(info.map);
2115 int max_ptr_index = -1;
2116 for (int i = 0; i < info.map_chunks - 1; i++)
2117 {
2118 if (map[i].flags & MMAP_PTR_IDX && map[i].ptr_index > max_ptr_index) {
2119 max_ptr_index = map[i].ptr_index;
2120 }
2121 }
2122 cd->memptr_start_index + max_ptr_index + 1;
2123 for (int i = info.map_chunks - 1; i < map_chunks - 1; i++)
2124 {
2125 if (map[i].flags & MMAP_PTR_IDX) {
2126 map[i].ptr_index += cd->memptr_start_index;
2127 }
2128 }
2129 cd->base = 0x400000;
2130 }
2052 2131
2053 m68k_options *opts = malloc(sizeof(m68k_options)); 2132 m68k_options *opts = malloc(sizeof(m68k_options));
2054 init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K); 2133 init_m68k_opts(opts, map, map_chunks, MCLKS_PER_68K, sync_components);
2055 if (!strcmp(tern_find_ptr_default(model, "tas", "broken"), "broken")) { 2134 if (!strcmp(tern_find_ptr_default(model, "tas", "broken"), "broken")) {
2056 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY; 2135 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY;
2057 } 2136 }
2058 gen->m68k = init_68k_context(opts, NULL); 2137 gen->m68k = init_68k_context(opts, NULL);
2059 gen->m68k->system = gen; 2138 gen->m68k->system = gen;
2060 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL; 2139 opts->address_log = (ym_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL;
2061 2140
2062 //This must happen after the 68K context has been allocated 2141 //This must happen after the 68K context has been allocated
2063 for (int i = 0; i < rom->map_chunks; i++) 2142 for (int i = 0; i < map_chunks; i++)
2064 { 2143 {
2065 if (rom->map[i].flags & MMAP_PTR_IDX) { 2144 if (map[i].flags & MMAP_PTR_IDX) {
2066 gen->m68k->mem_pointers[rom->map[i].ptr_index] = rom->map[i].buffer; 2145 gen->m68k->mem_pointers[map[i].ptr_index] = map[i].buffer;
2067 } 2146 }
2068 } 2147 }
2069 2148
2070 if (gen->mapper_type == MAPPER_SEGA) { 2149 if (gen->mapper_type == MAPPER_SEGA) {
2071 //initialize bank registers 2150 //initialize bank registers
2075 } 2154 }
2076 } 2155 }
2077 gen->reset_cycle = CYCLE_NEVER; 2156 gen->reset_cycle = CYCLE_NEVER;
2078 2157
2079 return gen; 2158 return gen;
2080 }
2081
2082 static memmap_chunk base_map[] = {
2083 {0xE00000, 0x1000000, 0xFFFF, 0, 0, MMAP_READ | MMAP_WRITE | MMAP_CODE, NULL,
2084 NULL, NULL, NULL, NULL},
2085 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL,
2086 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
2087 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
2088 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL,
2089 (read_16_fun)io_read_w, (write_16_fun)io_write_w,
2090 (read_8_fun)io_read, (write_8_fun)io_write},
2091 {0x000000, 0xFFFFFF, 0xFFFFFF, 0, 0, 0, NULL,
2092 (read_16_fun)unused_read, (write_16_fun)unused_write,
2093 (read_8_fun)unused_read_b, (write_8_fun)unused_write_b}
2094 };
2095 const size_t base_chunks = sizeof(base_map)/sizeof(*base_map);
2096
2097 genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t ym_opts, uint8_t force_region)
2098 {
2099 tern_node *rom_db = get_rom_db();
2100 rom_info info = configure_rom(rom_db, rom, rom_size, lock_on, lock_on_size, base_map, base_chunks);
2101 rom = info.rom;
2102 rom_size = info.rom_size;
2103 #ifndef BLASTEM_BIG_ENDIAN
2104 byteswap_rom(rom_size, rom);
2105 if (lock_on) {
2106 byteswap_rom(lock_on_size, lock_on);
2107 }
2108 #endif
2109 char *m68k_divider = tern_find_path(config, "clocks\0m68k_divider\0", TVAL_PTR).ptrval;
2110 if (!m68k_divider) {
2111 m68k_divider = "7";
2112 }
2113 MCLKS_PER_68K = atoi(m68k_divider);
2114 if (!MCLKS_PER_68K) {
2115 MCLKS_PER_68K = 7;
2116 }
2117 return alloc_init_genesis(&info, rom, lock_on, ym_opts, force_region);
2118 } 2159 }
2119 2160
2120 genesis_context *alloc_config_genesis_cdboot(system_media *media, uint32_t system_opts, uint8_t force_region) 2161 genesis_context *alloc_config_genesis_cdboot(system_media *media, uint32_t system_opts, uint8_t force_region)
2121 { 2162 {
2122 tern_node *rom_db = get_rom_db(); 2163 tern_node *rom_db = get_rom_db();
2128 gen->save_storage = NULL; 2169 gen->save_storage = NULL;
2129 gen->save_type = SAVE_NONE; 2170 gen->save_type = SAVE_NONE;
2130 gen->version_reg &= ~NO_DISK; 2171 gen->version_reg &= ~NO_DISK;
2131 2172
2132 gen->expansion = cd; 2173 gen->expansion = cd;
2174 gen->version_reg &= ~NO_DISK;
2175 cd->genesis = gen;
2133 setup_io_devices(config, &info, &gen->io); 2176 setup_io_devices(config, &info, &gen->io);
2134 2177
2135 uint32_t cd_chunks; 2178 uint32_t cd_chunks;
2136 memmap_chunk *cd_map = segacd_main_cpu_map(gen->expansion, &cd_chunks); 2179 memmap_chunk *cd_map = segacd_main_cpu_map(gen->expansion, 0, &cd_chunks);
2137 memmap_chunk *map = malloc(sizeof(memmap_chunk) * (cd_chunks + base_chunks)); 2180 memmap_chunk *map = malloc(sizeof(memmap_chunk) * (cd_chunks + base_chunks));
2138 memcpy(map, cd_map, sizeof(memmap_chunk) * cd_chunks); 2181 memcpy(map, cd_map, sizeof(memmap_chunk) * cd_chunks);
2139 memcpy(map + cd_chunks, base_map, sizeof(memmap_chunk) * base_chunks); 2182 memcpy(map + cd_chunks, base_map, sizeof(memmap_chunk) * base_chunks);
2140 map[cd_chunks].buffer = gen->work_ram; 2183 map[cd_chunks].buffer = gen->work_ram;
2141 uint32_t num_chunks = cd_chunks + base_chunks; 2184 uint32_t num_chunks = cd_chunks + base_chunks;
2142 2185
2143 m68k_options *opts = malloc(sizeof(m68k_options)); 2186 m68k_options *opts = malloc(sizeof(m68k_options));
2144 init_m68k_opts(opts, map, num_chunks, MCLKS_PER_68K); 2187 init_m68k_opts(opts, map, num_chunks, MCLKS_PER_68K, sync_components);
2145 //TODO: make this configurable 2188 //TODO: make this configurable
2146 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY; 2189 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY;
2147 gen->m68k = init_68k_context(opts, NULL); 2190 gen->m68k = init_68k_context(opts, NULL);
2148 gen->m68k->system = gen; 2191 gen->m68k->system = gen;
2149 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL; 2192 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL;