comparison genesis.c @ 2041:638eb2d25696 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Thu, 05 Aug 2021 09:29:33 -0700
parents 0d5f88e53dca 3b8e29ef1145
children 804954731e3f
comparison
equal deleted inserted replaced
1984:0d5f88e53dca 2041:638eb2d25696
102 start_section(buf, SECTION_SOUND_RAM); 102 start_section(buf, SECTION_SOUND_RAM);
103 save_int8(buf, Z80_RAM_BYTES / 1024); 103 save_int8(buf, Z80_RAM_BYTES / 1024);
104 save_buffer8(buf, gen->zram, Z80_RAM_BYTES); 104 save_buffer8(buf, gen->zram, Z80_RAM_BYTES);
105 end_section(buf); 105 end_section(buf);
106 106
107 if (gen->version_reg & 0xF) {
108 //only save TMSS info if it's present
109 //that will allow a state saved on a model lacking TMSS
110 //to be loaded on a model that has it
111 start_section(buf, SECTION_TMSS);
112 save_int8(buf, gen->tmss);
113 save_buffer16(buf, gen->tmss_lock, 2);
114 end_section(buf);
115 }
116
107 cart_serialize(&gen->header, buf); 117 cart_serialize(&gen->header, buf);
108 } 118 }
109 } 119 }
110 120
111 static uint8_t *serialize(system_header *sys, size_t *size_out) 121 static uint8_t *serialize(system_header *sys, size_t *size_out)
171 gen->z80->reset = load_int8(buf); 181 gen->z80->reset = load_int8(buf);
172 gen->z80->busreq = load_int8(buf); 182 gen->z80->busreq = load_int8(buf);
173 gen->z80_bank_reg = load_int16(buf) & 0x1FF; 183 gen->z80_bank_reg = load_int16(buf) & 0x1FF;
174 } 184 }
175 185
186 static void tmss_deserialize(deserialize_buffer *buf, void *vgen)
187 {
188 genesis_context *gen = vgen;
189 gen->tmss = load_int8(buf);
190 load_buffer16(buf, gen->tmss_lock, 2);
191 }
192
176 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context); 193 static void adjust_int_cycle(m68k_context * context, vdp_context * v_context);
194 static void check_tmss_lock(genesis_context *gen);
195 static void toggle_tmss_rom(genesis_context *gen);
177 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen) 196 void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen)
178 { 197 {
179 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000); 198 register_section_handler(buf, (section_handler){.fun = m68k_deserialize, .data = gen->m68k}, SECTION_68000);
180 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80); 199 register_section_handler(buf, (section_handler){.fun = z80_deserialize, .data = gen->z80}, SECTION_Z80);
181 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP); 200 register_section_handler(buf, (section_handler){.fun = vdp_deserialize, .data = gen->vdp}, SECTION_VDP);
186 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2); 205 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 1}, SECTION_SEGA_IO_2);
187 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT); 206 register_section_handler(buf, (section_handler){.fun = io_deserialize, .data = gen->io.ports + 2}, SECTION_SEGA_IO_EXT);
188 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM); 207 register_section_handler(buf, (section_handler){.fun = ram_deserialize, .data = gen}, SECTION_MAIN_RAM);
189 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM); 208 register_section_handler(buf, (section_handler){.fun = zram_deserialize, .data = gen}, SECTION_SOUND_RAM);
190 register_section_handler(buf, (section_handler){.fun = cart_deserialize, .data = gen}, SECTION_MAPPER); 209 register_section_handler(buf, (section_handler){.fun = cart_deserialize, .data = gen}, SECTION_MAPPER);
210 register_section_handler(buf, (section_handler){.fun = tmss_deserialize, .data = gen}, SECTION_TMSS);
211 uint8_t tmss_old = gen->tmss;
212 gen->tmss = 0xFF;
191 while (buf->cur_pos < buf->size) 213 while (buf->cur_pos < buf->size)
192 { 214 {
193 load_section(buf); 215 load_section(buf);
216 }
217 if (gen->version_reg & 0xF) {
218 if (gen->tmss == 0xFF) {
219 //state lacked a TMSS section, assume that the game ROM is mapped in
220 //and that the VDP is unlocked
221 gen->tmss_lock[0] = 0x5345;
222 gen->tmss_lock[1] = 0x4741;
223 gen->tmss = 1;
224 }
225 if (gen->tmss != tmss_old) {
226 toggle_tmss_rom(gen);
227 }
228 check_tmss_lock(gen);
194 } 229 }
195 update_z80_bank_pointer(gen); 230 update_z80_bank_pointer(gen);
196 adjust_int_cycle(gen->m68k, gen->vdp); 231 adjust_int_cycle(gen->m68k, gen->vdp);
197 free(buf->handlers); 232 free(buf->handlers);
198 buf->handlers = NULL; 233 buf->handlers = NULL;
240 genesis_context *gen = context->system; 275 genesis_context *gen = context->system;
241 if (context->sync_cycle - context->current_cycle > gen->max_cycles) { 276 if (context->sync_cycle - context->current_cycle > gen->max_cycles) {
242 context->sync_cycle = context->current_cycle + gen->max_cycles; 277 context->sync_cycle = context->current_cycle + gen->max_cycles;
243 } 278 }
244 context->int_cycle = CYCLE_NEVER; 279 context->int_cycle = CYCLE_NEVER;
245 if ((context->status & 0x7) < 6) { 280 uint8_t mask = context->status & 0x7;
281 if (mask < 6) {
246 uint32_t next_vint = vdp_next_vint(v_context); 282 uint32_t next_vint = vdp_next_vint(v_context);
247 if (next_vint != CYCLE_NEVER) { 283 if (next_vint != CYCLE_NEVER) {
248 context->int_cycle = next_vint; 284 context->int_cycle = next_vint;
249 context->int_num = 6; 285 context->int_num = 6;
250 } 286 }
251 if ((context->status & 0x7) < 4) { 287 if (mask < 4) {
252 uint32_t next_hint = vdp_next_hint(v_context); 288 uint32_t next_hint = vdp_next_hint(v_context);
253 if (next_hint != CYCLE_NEVER) { 289 if (next_hint != CYCLE_NEVER) {
254 next_hint = next_hint < context->current_cycle ? context->current_cycle : next_hint; 290 next_hint = next_hint < context->current_cycle ? context->current_cycle : next_hint;
255 if (next_hint < context->int_cycle) { 291 if (next_hint < context->int_cycle) {
256 context->int_cycle = next_hint; 292 context->int_cycle = next_hint;
257 context->int_num = 4; 293 context->int_num = 4;
258 294
295 }
296 }
297 if (mask < 2 && (v_context->regs[REG_MODE_3] & BIT_EINT_EN)) {
298 uint32_t next_eint_port0 = io_next_interrupt(gen->io.ports, context->current_cycle);
299 uint32_t next_eint_port1 = io_next_interrupt(gen->io.ports + 1, context->current_cycle);
300 uint32_t next_eint_port2 = io_next_interrupt(gen->io.ports + 2, context->current_cycle);
301 uint32_t next_eint = next_eint_port0 < next_eint_port1
302 ? (next_eint_port0 < next_eint_port2 ? next_eint_port0 : next_eint_port2)
303 : (next_eint_port1 < next_eint_port2 ? next_eint_port1 : next_eint_port2);
304 if (next_eint != CYCLE_NEVER) {
305 next_eint = next_eint < context->current_cycle ? context->current_cycle : next_eint;
306 if (next_eint < context->int_cycle) {
307 context->int_cycle = next_eint;
308 context->int_num = 2;
309 }
259 } 310 }
260 } 311 }
261 } 312 }
262 } 313 }
263 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) { 314 if (context->int_cycle > context->current_cycle && context->int_pending == INT_PENDING_SR_CHANGE) {
272 context->target_cycle = context->current_cycle; 323 context->target_cycle = context->current_cycle;
273 return; 324 return;
274 } 325 }
275 326
276 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle; 327 context->target_cycle = context->int_cycle < context->sync_cycle ? context->int_cycle : context->sync_cycle;
277 if (context->should_return) { 328 if (context->should_return || gen->header.enter_debugger) {
278 context->target_cycle = context->current_cycle; 329 context->target_cycle = context->current_cycle;
279 } else if (context->target_cycle < context->current_cycle) { 330 } else if (context->target_cycle < context->current_cycle) {
280 //Changes to SR can result in an interrupt cycle that's in the past 331 //Changes to SR can result in an interrupt cycle that's in the past
281 //This can cause issues with the implementation of STOP though 332 //This can cause issues with the implementation of STOP though
282 context->target_cycle = context->current_cycle; 333 context->target_cycle = context->current_cycle;
387 438
388 uint32_t mclks = context->current_cycle; 439 uint32_t mclks = context->current_cycle;
389 sync_z80(z_context, mclks); 440 sync_z80(z_context, mclks);
390 sync_sound(gen, mclks); 441 sync_sound(gen, mclks);
391 vdp_run_context(v_context, mclks); 442 vdp_run_context(v_context, mclks);
443 io_run(gen->io.ports, mclks);
444 io_run(gen->io.ports + 1, mclks);
445 io_run(gen->io.ports + 2, mclks);
392 if (mclks >= gen->reset_cycle) { 446 if (mclks >= gen->reset_cycle) {
393 gen->reset_requested = 1; 447 gen->reset_requested = 1;
394 context->should_return = 1; 448 context->should_return = 1;
395 gen->reset_cycle = CYCLE_NEVER; 449 gen->reset_cycle = CYCLE_NEVER;
396 } 450 }
449 } 503 }
450 if (address) { 504 if (address) {
451 #ifndef NEW_CORE 505 #ifndef NEW_CORE
452 if (gen->header.enter_debugger) { 506 if (gen->header.enter_debugger) {
453 gen->header.enter_debugger = 0; 507 gen->header.enter_debugger = 0;
454 debugger(context, address); 508 if (gen->header.debugger_type == DEBUGGER_NATIVE) {
509 debugger(context, address);
510 } else {
511 gdb_debug_enter(context, address);
512 }
455 } 513 }
456 #endif 514 #endif
457 #ifdef NEW_CORE 515 #ifdef NEW_CORE
458 if (gen->header.save_state) { 516 if (gen->header.save_state) {
459 #else 517 #else
510 static m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value) 568 static m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_t value)
511 { 569 {
512 if (vdp_port & 0x2700E0) { 570 if (vdp_port & 0x2700E0) {
513 fatal_error("machine freeze due to write to address %X\n", 0xC00000 | vdp_port); 571 fatal_error("machine freeze due to write to address %X\n", 0xC00000 | vdp_port);
514 } 572 }
573 genesis_context * gen = context->system;
574 if (!gen->vdp_unlocked) {
575 fatal_error("machine freeze due to VDP write to %X without TMSS unlock\n", 0xC00000 | vdp_port);
576 }
515 vdp_port &= 0x1F; 577 vdp_port &= 0x1F;
516 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle); 578 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle);
517 #ifdef REFRESH_EMULATION 579 #ifdef REFRESH_EMULATION
518 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access 580 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access
519 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) { 581 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) {
522 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 584 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
523 last_sync_cycle = context->current_cycle; 585 last_sync_cycle = context->current_cycle;
524 } 586 }
525 #endif 587 #endif
526 sync_components(context, 0); 588 sync_components(context, 0);
527 genesis_context * gen = context->system;
528 vdp_context *v_context = gen->vdp; 589 vdp_context *v_context = gen->vdp;
529 uint32_t before_cycle = v_context->cycles; 590 uint32_t before_cycle = v_context->cycles;
530 if (vdp_port < 0x10) { 591 if (vdp_port < 0x10) {
531 int blocked; 592 int blocked;
532 if (vdp_port < 4) { 593 if (vdp_port < 4) {
599 psg_write(gen->psg, value); 660 psg_write(gen->psg, value);
600 } else { 661 } else {
601 vdp_test_port_write(gen->vdp, value); 662 vdp_test_port_write(gen->vdp, value);
602 } 663 }
603 #ifdef REFRESH_EMULATION 664 #ifdef REFRESH_EMULATION
604 last_sync_cycle -= 4; 665 last_sync_cycle -= 4 * MCLKS_PER_68K;
605 //refresh may have happened while we were waiting on the VDP, 666 //refresh may have happened while we were waiting on the VDP,
606 //so advance refresh_counter but don't add any delays 667 //so advance refresh_counter but don't add any delays
607 if (vdp_port >= 4 && vdp_port < 8 && v_context->cycles != before_cycle) { 668 if (vdp_port >= 4 && vdp_port < 8 && v_context->cycles != before_cycle) {
608 refresh_counter = 0; 669 refresh_counter = 0;
609 } else { 670 } else {
651 static uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context) 712 static uint16_t vdp_port_read(uint32_t vdp_port, m68k_context * context)
652 { 713 {
653 if (vdp_port & 0x2700E0) { 714 if (vdp_port & 0x2700E0) {
654 fatal_error("machine freeze due to read from address %X\n", 0xC00000 | vdp_port); 715 fatal_error("machine freeze due to read from address %X\n", 0xC00000 | vdp_port);
655 } 716 }
717 genesis_context *gen = context->system;
718 if (!gen->vdp_unlocked) {
719 fatal_error("machine freeze due to VDP read from %X without TMSS unlock\n", 0xC00000 | vdp_port);
720 }
656 vdp_port &= 0x1F; 721 vdp_port &= 0x1F;
657 uint16_t value; 722 uint16_t value;
658 #ifdef REFRESH_EMULATION 723 #ifdef REFRESH_EMULATION
659 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) { 724 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) {
660 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access 725 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access
662 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); 727 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
663 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 728 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
664 last_sync_cycle = context->current_cycle; 729 last_sync_cycle = context->current_cycle;
665 } 730 }
666 #endif 731 #endif
667 genesis_context *gen = context->system; 732 sync_components(context, 0);
668 vdp_context * v_context = gen->vdp; 733 vdp_context * v_context = gen->vdp;
734 uint32_t before_cycle = v_context->cycles;
669 if (vdp_port < 0x10) { 735 if (vdp_port < 0x10) {
670 if (vdp_port < 4) { 736 if (vdp_port < 4) {
671 sync_components(context, 0);
672 uint32_t before_cycle = v_context->cycles;
673 value = vdp_data_port_read(v_context); 737 value = vdp_data_port_read(v_context);
674 if (v_context->cycles != before_cycle) {
675 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for read\n", v_context->cycles - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle);
676 context->current_cycle = v_context->cycles;
677 //Lock the Z80 out of the bus until the VDP access is complete
678 genesis_context *gen = context->system;
679 gen->bus_busy = 1;
680 sync_z80(gen->z80, v_context->cycles);
681 gen->bus_busy = 0;
682 }
683 } else if(vdp_port < 8) { 738 } else if(vdp_port < 8) {
684 vdp_run_context(v_context, context->current_cycle);
685 value = vdp_control_port_read(v_context); 739 value = vdp_control_port_read(v_context);
686 } else { 740 } else {
687 vdp_run_context(v_context, context->current_cycle);
688 value = vdp_hv_counter_read(v_context); 741 value = vdp_hv_counter_read(v_context);
689 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles); 742 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles);
690 } 743 }
691 } else if (vdp_port < 0x18){ 744 } else if (vdp_port < 0x18){
692 fatal_error("Illegal read from PSG port %X\n", vdp_port); 745 fatal_error("Illegal read from PSG port %X\n", vdp_port);
693 } else { 746 } else {
694 value = get_open_bus_value(&gen->header); 747 value = get_open_bus_value(&gen->header);
695 } 748 }
749 if (v_context->cycles != before_cycle) {
750 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for read\n", v_context->cycles - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle);
751 context->current_cycle = v_context->cycles;
752 //Lock the Z80 out of the bus until the VDP access is complete
753 genesis_context *gen = context->system;
754 gen->bus_busy = 1;
755 sync_z80(gen->z80, v_context->cycles);
756 gen->bus_busy = 0;
757 }
696 #ifdef REFRESH_EMULATION 758 #ifdef REFRESH_EMULATION
697 last_sync_cycle -= 4; 759 last_sync_cycle -= 4 * MCLKS_PER_68K;
698 //refresh may have happened while we were waiting on the VDP, 760 //refresh may have happened while we were waiting on the VDP,
699 //so advance refresh_counter but don't add any delays 761 //so advance refresh_counter but don't add any delays
700 refresh_counter += (context->current_cycle - last_sync_cycle); 762 refresh_counter += (context->current_cycle - last_sync_cycle);
701 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 763 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
702 last_sync_cycle = context->current_cycle; 764 last_sync_cycle = context->current_cycle;
753 static uint32_t zram_counter = 0; 815 static uint32_t zram_counter = 0;
754 816
755 static m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value) 817 static m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value)
756 { 818 {
757 genesis_context * gen = context->system; 819 genesis_context * gen = context->system;
820 #ifdef REFRESH_EMULATION
821 //do refresh check here so we can avoid adding a penalty for a refresh that happens during an IO area access
822 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle;
823 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
824 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
825 last_sync_cycle = context->current_cycle - 4*MCLKS_PER_68K;
826 #endif
758 if (location < 0x10000) { 827 if (location < 0x10000) {
759 //Access to Z80 memory incurs a one 68K cycle wait state 828 //Access to Z80 memory incurs a one 68K cycle wait state
760 context->current_cycle += MCLKS_PER_68K; 829 context->current_cycle += MCLKS_PER_68K;
761 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) { 830 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) {
762 location &= 0x7FFF; 831 location &= 0x7FFF;
806 break; 875 break;
807 case 0x6: 876 case 0x6:
808 io_control_write(gen->io.ports+2, value, context->current_cycle); 877 io_control_write(gen->io.ports+2, value, context->current_cycle);
809 break; 878 break;
810 case 0x7: 879 case 0x7:
811 gen->io.ports[0].serial_out = value; 880 io_tx_write(gen->io.ports, value, context->current_cycle);
812 break; 881 break;
813 case 0x8: 882 case 0x8:
814 case 0xB: 883 case 0xB:
815 case 0xE: 884 case 0xE:
816 //serial input port is not writeable 885 //serial input port is not writeable
817 break; 886 break;
818 case 0x9: 887 case 0x9:
888 io_sctrl_write(gen->io.ports, value, context->current_cycle);
819 gen->io.ports[0].serial_ctrl = value; 889 gen->io.ports[0].serial_ctrl = value;
820 break; 890 break;
821 case 0xA: 891 case 0xA:
822 gen->io.ports[1].serial_out = value; 892 io_tx_write(gen->io.ports + 1, value, context->current_cycle);
823 break; 893 break;
824 case 0xC: 894 case 0xC:
825 gen->io.ports[1].serial_ctrl = value; 895 io_sctrl_write(gen->io.ports + 1, value, context->current_cycle);
826 break; 896 break;
827 case 0xD: 897 case 0xD:
828 gen->io.ports[2].serial_out = value; 898 io_tx_write(gen->io.ports + 2, value, context->current_cycle);
829 break; 899 break;
830 case 0xF: 900 case 0xF:
831 gen->io.ports[2].serial_ctrl = value; 901 io_sctrl_write(gen->io.ports + 2, value, context->current_cycle);
832 break; 902 break;
833 } 903 }
834 } else { 904 } else {
835 uint32_t masked = location & 0xFFF00; 905 uint32_t masked = location & 0xFFF00;
836 if (masked == 0x11100) { 906 if (masked == 0x11100) {
877 } else if (masked != 0x11300 && masked != 0x11000) { 947 } else if (masked != 0x11300 && masked != 0x11000) {
878 fatal_error("Machine freeze due to unmapped write to address %X\n", location | 0xA00000); 948 fatal_error("Machine freeze due to unmapped write to address %X\n", location | 0xA00000);
879 } 949 }
880 } 950 }
881 } 951 }
952 #ifdef REFRESH_EMULATION
953 //no refresh delays during IO access
954 refresh_counter += context->current_cycle - last_sync_cycle;
955 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
956 #endif
882 return context; 957 return context;
883 } 958 }
884 959
885 static m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value) 960 static m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value)
886 { 961 {
900 975
901 static uint8_t io_read(uint32_t location, m68k_context * context) 976 static uint8_t io_read(uint32_t location, m68k_context * context)
902 { 977 {
903 uint8_t value; 978 uint8_t value;
904 genesis_context *gen = context->system; 979 genesis_context *gen = context->system;
980 #ifdef REFRESH_EMULATION
981 //do refresh check here so we can avoid adding a penalty for a refresh that happens during an IO area access
982 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle;
983 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
984 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
985 last_sync_cycle = context->current_cycle - 4*MCLKS_PER_68K;
986 #endif
905 if (location < 0x10000) { 987 if (location < 0x10000) {
906 //Access to Z80 memory incurs a one 68K cycle wait state 988 //Access to Z80 memory incurs a one 68K cycle wait state
907 context->current_cycle += MCLKS_PER_68K; 989 context->current_cycle += MCLKS_PER_68K;
908 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) { 990 if (!z80_enabled || z80_get_busack(gen->z80, context->current_cycle)) {
909 location &= 0x7FFF; 991 location &= 0x7FFF;
950 break; 1032 break;
951 case 0x7: 1033 case 0x7:
952 value = gen->io.ports[0].serial_out; 1034 value = gen->io.ports[0].serial_out;
953 break; 1035 break;
954 case 0x8: 1036 case 0x8:
955 value = gen->io.ports[0].serial_in; 1037 value = io_rx_read(gen->io.ports, context->current_cycle);
956 break; 1038 break;
957 case 0x9: 1039 case 0x9:
958 value = gen->io.ports[0].serial_ctrl; 1040 value = io_sctrl_read(gen->io.ports, context->current_cycle);
959 break; 1041 break;
960 case 0xA: 1042 case 0xA:
961 value = gen->io.ports[1].serial_out; 1043 value = gen->io.ports[1].serial_out;
962 break; 1044 break;
963 case 0xB: 1045 case 0xB:
964 value = gen->io.ports[1].serial_in; 1046 value = io_rx_read(gen->io.ports + 1, context->current_cycle);
965 break; 1047 break;
966 case 0xC: 1048 case 0xC:
967 value = gen->io.ports[1].serial_ctrl; 1049 value = io_sctrl_read(gen->io.ports, context->current_cycle);
968 break; 1050 break;
969 case 0xD: 1051 case 0xD:
970 value = gen->io.ports[2].serial_out; 1052 value = gen->io.ports[2].serial_out;
971 break; 1053 break;
972 case 0xE: 1054 case 0xE:
973 value = gen->io.ports[2].serial_in; 1055 value = io_rx_read(gen->io.ports + 1, context->current_cycle);
974 break; 1056 break;
975 case 0xF: 1057 case 0xF:
976 value = gen->io.ports[2].serial_ctrl; 1058 value = io_sctrl_read(gen->io.ports, context->current_cycle);
977 break; 1059 break;
978 default: 1060 default:
979 value = get_open_bus_value(&gen->header) >> 8; 1061 value = get_open_bus_value(&gen->header) >> 8;
980 } 1062 }
981 } else { 1063 } else {
995 fatal_error("Machine freeze due to read of unmapped IO location %X\n", location); 1077 fatal_error("Machine freeze due to read of unmapped IO location %X\n", location);
996 value = 0xFF; 1078 value = 0xFF;
997 } 1079 }
998 } 1080 }
999 } 1081 }
1082 #ifdef REFRESH_EMULATION
1083 //no refresh delays during IO access
1084 refresh_counter += context->current_cycle - last_sync_cycle;
1085 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
1086 #endif
1000 return value; 1087 return value;
1001 } 1088 }
1002 1089
1003 static uint16_t io_read_w(uint32_t location, m68k_context * context) 1090 static uint16_t io_read_w(uint32_t location, m68k_context * context)
1004 { 1091 {
1107 1194
1108 static uint16_t unused_read(uint32_t location, void *vcontext) 1195 static uint16_t unused_read(uint32_t location, void *vcontext)
1109 { 1196 {
1110 m68k_context *context = vcontext; 1197 m68k_context *context = vcontext;
1111 genesis_context *gen = context->system; 1198 genesis_context *gen = context->system;
1112 if ((location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) { 1199 if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1113 //Only called if the cart/exp doesn't have a more specific handler for this region 1200 //Only called if the cart/exp doesn't have a more specific handler for this region
1114 return get_open_bus_value(&gen->header); 1201 return get_open_bus_value(&gen->header);
1115 } else if (location == 0xA14000 || location == 0xA14002) { 1202 } else if (location == 0xA14000 || location == 0xA14002) {
1116 if (gen->version_reg & 0xF) { 1203 if (gen->version_reg & 0xF) {
1117 return gen->tmss_lock[location >> 1 & 1]; 1204 return gen->tmss_lock[location >> 1 & 1];
1140 } else { 1227 } else {
1141 return v >> 8; 1228 return v >> 8;
1142 } 1229 }
1143 } 1230 }
1144 1231
1232 static void check_tmss_lock(genesis_context *gen)
1233 {
1234 gen->vdp_unlocked = gen->tmss_lock[0] == 0x5345 && gen->tmss_lock[1] == 0x4741;
1235 }
1236
1237 static void toggle_tmss_rom(genesis_context *gen)
1238 {
1239 m68k_context *context = gen->m68k;
1240 for (int i = 0; i < NUM_MEM_AREAS; i++)
1241 {
1242 uint16_t *tmp = context->mem_pointers[i];
1243 context->mem_pointers[i] = gen->tmss_pointers[i];
1244 gen->tmss_pointers[i] = tmp;
1245 }
1246 m68k_invalidate_code_range(context, 0, 0x400000);
1247 }
1248
1145 static void *unused_write(uint32_t location, void *vcontext, uint16_t value) 1249 static void *unused_write(uint32_t location, void *vcontext, uint16_t value)
1146 { 1250 {
1147 m68k_context *context = vcontext; 1251 m68k_context *context = vcontext;
1148 genesis_context *gen = context->system; 1252 genesis_context *gen = context->system;
1149 uint8_t has_tmss = gen->version_reg & 0xF; 1253 uint8_t has_tmss = gen->version_reg & 0xF;
1150 if (has_tmss && (location == 0xA14000 || location == 0xA14002)) { 1254 if (has_tmss && (location == 0xA14000 || location == 0xA14002)) {
1151 gen->tmss_lock[location >> 1 & 1] = value; 1255 gen->tmss_lock[location >> 1 & 1] = value;
1256 check_tmss_lock(gen);
1152 } else if (has_tmss && location == 0xA14100) { 1257 } else if (has_tmss && location == 0xA14100) {
1153 //TODO: implement TMSS control register 1258 value &= 1;
1154 } else if (location < 0xA12000 || location >= 0xA13100 || (location >= 0xA12100 && location < 0xA13000)) { 1259 if (gen->tmss != value) {
1260 gen->tmss = value;
1261 toggle_tmss_rom(gen);
1262 }
1263 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1264 //these writes are ignored when no relevant hardware is present
1265 } else {
1155 fatal_error("Machine freeze due to unmapped write to %X\n", location); 1266 fatal_error("Machine freeze due to unmapped write to %X\n", location);
1156 } 1267 }
1157 return vcontext; 1268 return vcontext;
1158 } 1269 }
1159 1270
1169 gen->tmss_lock[offset] |= value; 1280 gen->tmss_lock[offset] |= value;
1170 } else { 1281 } else {
1171 gen->tmss_lock[offset] &= 0xFF; 1282 gen->tmss_lock[offset] &= 0xFF;
1172 gen->tmss_lock[offset] |= value << 8; 1283 gen->tmss_lock[offset] |= value << 8;
1173 } 1284 }
1285 check_tmss_lock(gen);
1174 } else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) { 1286 } else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) {
1175 //TODO: implement TMSS control register 1287 if (location & 1) {
1176 } else if (location < 0xA12000 || location >= 0xA13100 || (location >= 0xA12100 && location < 0xA13000)) { 1288 value &= 1;
1289 if (gen->tmss != value) {
1290 gen->tmss = value;
1291 toggle_tmss_rom(gen);
1292 }
1293 }
1294 } else if (location < 0x800000 || (location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1295 //these writes are ignored when no relevant hardware is present
1296 } else {
1177 fatal_error("Machine freeze due to unmapped byte write to %X\n", location); 1297 fatal_error("Machine freeze due to unmapped byte write to %X\n", location);
1178 } 1298 }
1179 return vcontext; 1299 return vcontext;
1180 } 1300 }
1181 1301
1524 puts("Stopped VGM log"); 1644 puts("Stopped VGM log");
1525 genesis_context *gen = (genesis_context *)system; 1645 genesis_context *gen = (genesis_context *)system;
1526 vgm_close(gen->ym->vgm); 1646 vgm_close(gen->ym->vgm);
1527 gen->ym->vgm = gen->psg->vgm = NULL; 1647 gen->ym->vgm = gen->psg->vgm = NULL;
1528 gen->header.vgm_logging = 0; 1648 gen->header.vgm_logging = 0;
1649 }
1650
1651 static void *tmss_rom_write_16(uint32_t address, void *context, uint16_t value)
1652 {
1653 m68k_context *m68k = context;
1654 genesis_context *gen = m68k->system;
1655 if (gen->tmss) {
1656 return gen->tmss_write_16(address, context, value);
1657 }
1658
1659 return context;
1660 }
1661
1662 static void *tmss_rom_write_8(uint32_t address, void *context, uint8_t value)
1663 {
1664 m68k_context *m68k = context;
1665 genesis_context *gen = m68k->system;
1666 if (gen->tmss) {
1667 return gen->tmss_write_8(address, context, value);
1668 }
1669
1670 return context;
1671 }
1672
1673 static uint16_t tmss_rom_read_16(uint32_t address, void *context)
1674 {
1675 m68k_context *m68k = context;
1676 genesis_context *gen = m68k->system;
1677 if (gen->tmss) {
1678 return gen->tmss_read_16(address, context);
1679 }
1680 return ((uint16_t *)gen->tmss_buffer)[address >> 1];
1681 }
1682
1683 static uint8_t tmss_rom_read_8(uint32_t address, void *context)
1684 {
1685 m68k_context *m68k = context;
1686 genesis_context *gen = m68k->system;
1687 if (gen->tmss) {
1688 return gen->tmss_read_8(address, context);
1689 }
1690 #ifdef BLASTEM_BIG_ENDIAN
1691 return gen->tmss_buffer[address];
1692 #else
1693 return gen->tmss_buffer[address ^ 1];
1694 #endif
1695 }
1696
1697 static void *tmss_word_write_16(uint32_t address, void *context, uint16_t value)
1698 {
1699 m68k_context *m68k = context;
1700 genesis_context *gen = m68k->system;
1701 if (gen->tmss) {
1702 address += gen->tmss_write_offset;
1703 uint16_t *dest = get_native_pointer(address, (void **)m68k->mem_pointers, &m68k->options->gen);
1704 *dest = value;
1705 m68k_handle_code_write(address, m68k);
1706 }
1707
1708 return context;
1709 }
1710
1711 static void *tmss_word_write_8(uint32_t address, void *context, uint8_t value)
1712 {
1713 m68k_context *m68k = context;
1714 genesis_context *gen = m68k->system;
1715 if (gen->tmss) {
1716 address += gen->tmss_write_offset;
1717 uint8_t *dest = get_native_pointer(address & ~1, (void **)m68k->mem_pointers, &m68k->options->gen);
1718 #ifdef BLASTEM_BIG_ENDIAN
1719 dest[address & 1] = value;
1720 #else
1721 dest[address & 1 ^ 1] = value;
1722 #endif
1723 m68k_handle_code_write(address & ~1, m68k);
1724 }
1725
1726 return context;
1727 }
1728
1729 static void *tmss_odd_write_16(uint32_t address, void *context, uint16_t value)
1730 {
1731 m68k_context *m68k = context;
1732 genesis_context *gen = m68k->system;
1733 if (gen->tmss) {
1734 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1735 address >>= 1;
1736 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1737 base[address] = value;
1738 }
1739 return context;
1740 }
1741
1742 static void *tmss_odd_write_8(uint32_t address, void *context, uint8_t value)
1743 {
1744 m68k_context *m68k = context;
1745 genesis_context *gen = m68k->system;
1746 if (gen->tmss && (address & 1)) {
1747 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1748 address >>= 1;
1749 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1750 base[address] = value;
1751 }
1752 return context;
1753 }
1754
1755 static void *tmss_even_write_16(uint32_t address, void *context, uint16_t value)
1756 {
1757 m68k_context *m68k = context;
1758 genesis_context *gen = m68k->system;
1759 if (gen->tmss) {
1760 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1761 address >>= 1;
1762 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1763 base[address] = value >> 8;
1764 }
1765 return context;
1766 }
1767
1768 static void *tmss_even_write_8(uint32_t address, void *context, uint8_t value)
1769 {
1770 m68k_context *m68k = context;
1771 genesis_context *gen = m68k->system;
1772 if (gen->tmss && !(address & 1)) {
1773 memmap_chunk const *chunk = find_map_chunk(address + gen->tmss_write_offset, &m68k->options->gen, 0, NULL);
1774 address >>= 1;
1775 uint8_t *base = (uint8_t *)m68k->mem_pointers[chunk->ptr_index];
1776 base[address] = value;
1777 }
1778 return context;
1529 } 1779 }
1530 1780
1531 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region) 1781 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region)
1532 { 1782 {
1533 static memmap_chunk z80_map[] = { 1783 static memmap_chunk z80_map[] = {
1567 set_region(gen, rom, force_region); 1817 set_region(gen, rom, force_region);
1568 tern_node *model = get_model(config, SYSTEM_GENESIS); 1818 tern_node *model = get_model(config, SYSTEM_GENESIS);
1569 uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on"); 1819 uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on");
1570 if (tmss) { 1820 if (tmss) {
1571 gen->version_reg |= 1; 1821 gen->version_reg |= 1;
1822 } else {
1823 gen->vdp_unlocked = 1;
1572 } 1824 }
1573 1825
1574 uint8_t max_vsram = !strcmp(tern_find_ptr_default(model, "vsram", "40"), "64"); 1826 uint8_t max_vsram = !strcmp(tern_find_ptr_default(model, "vsram", "40"), "64");
1575 gen->vdp = init_vdp_context(gen->version_reg & 0x40, max_vsram); 1827 gen->vdp = init_vdp_context(gen->version_reg & 0x40, max_vsram);
1576 gen->vdp->system = &gen->header; 1828 gen->vdp->system = &gen->header;
1662 } 1914 }
1663 } else { 1915 } else {
1664 gen->save_storage = NULL; 1916 gen->save_storage = NULL;
1665 } 1917 }
1666 1918
1919 gen->mapper_start_index = rom->mapper_start_index;
1920
1667 //This must happen before we generate memory access functions in init_m68k_opts 1921 //This must happen before we generate memory access functions in init_m68k_opts
1922 uint8_t next_ptr_index = 0;
1923 uint32_t tmss_min_alloc = 16 * 1024;
1668 for (int i = 0; i < rom->map_chunks; i++) 1924 for (int i = 0; i < rom->map_chunks; i++)
1669 { 1925 {
1670 if (rom->map[i].start == 0xE00000) { 1926 if (rom->map[i].start == 0xE00000) {
1671 rom->map[i].buffer = gen->work_ram; 1927 rom->map[i].buffer = gen->work_ram;
1672 break; 1928 if (!tmss) {
1673 } 1929 break;
1930 }
1931 }
1932 if (rom->map[i].flags & MMAP_PTR_IDX && rom->map[i].ptr_index >= next_ptr_index) {
1933 next_ptr_index = rom->map[i].ptr_index + 1;
1934 }
1935 if (rom->map[i].start < 0x400000 && rom->map[i].read_16 != unused_read) {
1936 uint32_t highest_offset = (rom->map[i].end & rom->map[i].mask) + 1;
1937 if (highest_offset > tmss_min_alloc) {
1938 tmss_min_alloc = highest_offset;
1939 }
1940 }
1941 }
1942 if (tmss) {
1943 char *tmss_path = tern_find_path_default(config, "system\0tmss_path\0", (tern_val){.ptrval = "tmss.md"}, TVAL_PTR).ptrval;
1944 uint8_t *buffer = malloc(tmss_min_alloc);
1945 uint32_t tmss_size;
1946 if (is_absolute_path(tmss_path)) {
1947 FILE *f = fopen(tmss_path, "rb");
1948 if (!f) {
1949 fatal_error("Configured to use a model with TMSS, but failed to load the TMSS ROM from %s\n", tmss_path);
1950 }
1951 tmss_size = fread(buffer, 1, tmss_min_alloc, f);
1952 fclose(f);
1953 } else {
1954 char *tmp = read_bundled_file(tmss_path, &tmss_size);
1955 if (!tmp) {
1956 fatal_error("Configured to use a model with TMSS, but failed to load the TMSS ROM from %s\n", tmss_path);
1957 }
1958 memcpy(buffer, tmp, tmss_size);
1959 free(tmp);
1960 }
1961 for (uint32_t padded = nearest_pow2(tmss_size); tmss_size < padded; tmss_size++)
1962 {
1963 buffer[tmss_size] = 0xFF;
1964 }
1965 #ifndef BLASTEM_BIG_ENDIAN
1966 byteswap_rom(tmss_size, (uint16_t *)buffer);
1967 #endif
1968 //mirror TMSS ROM until we fill up to tmss_min_alloc
1969 for (uint32_t dst = tmss_size; dst < tmss_min_alloc; dst += tmss_size)
1970 {
1971 memcpy(buffer + dst, buffer, dst + tmss_size > tmss_min_alloc ? tmss_min_alloc - dst : tmss_size);
1972 }
1973 //modify mappings for ROM space to point to the TMSS ROM and fixup flags to allow switching back and forth
1974 //WARNING: This code makes some pretty big assumptions about the kinds of map chunks it will encounter
1975 for (int i = 0; i < rom->map_chunks; i++)
1976 {
1977 if (rom->map[i].start < 0x400000 && rom->map[i].read_16 != unused_read) {
1978 if (rom->map[i].flags == MMAP_READ) {
1979 //Normal ROM
1980 rom->map[i].flags |= MMAP_PTR_IDX | MMAP_CODE;
1981 rom->map[i].ptr_index = next_ptr_index++;
1982 if (rom->map[i].ptr_index >= NUM_MEM_AREAS) {
1983 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n");
1984 }
1985 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
1986 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
1987 } else if (rom->map[i].flags & MMAP_PTR_IDX) {
1988 //Sega mapper page or multi-game mapper
1989 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
1990 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
1991 if (rom->map[i].write_16) {
1992 if (!gen->tmss_write_16) {
1993 gen->tmss_write_16 = rom->map[i].write_16;
1994 gen->tmss_write_8 = rom->map[i].write_8;
1995 rom->map[i].write_16 = tmss_rom_write_16;
1996 rom->map[i].write_8 = tmss_rom_write_8;
1997 } else if (gen->tmss_write_16 == rom->map[i].write_16) {
1998 rom->map[i].write_16 = tmss_rom_write_16;
1999 rom->map[i].write_8 = tmss_rom_write_8;
2000 } else {
2001 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);
2002 }
2003 }
2004 } else if ((rom->map[i].flags & (MMAP_READ | MMAP_WRITE)) == (MMAP_READ | MMAP_WRITE)) {
2005 //RAM or SRAM
2006 rom->map[i].flags |= MMAP_PTR_IDX;
2007 rom->map[i].ptr_index = next_ptr_index++;
2008 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
2009 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
2010 if (!gen->tmss_write_offset || gen->tmss_write_offset == rom->map[i].start) {
2011 gen->tmss_write_offset = rom->map[i].start;
2012 rom->map[i].flags &= ~MMAP_WRITE;
2013 if (rom->map[i].flags & MMAP_ONLY_ODD) {
2014 rom->map[i].write_16 = tmss_odd_write_16;
2015 rom->map[i].write_8 = tmss_odd_write_8;
2016 } else if (rom->map[i].flags & MMAP_ONLY_EVEN) {
2017 rom->map[i].write_16 = tmss_even_write_16;
2018 rom->map[i].write_8 = tmss_even_write_8;
2019 } else {
2020 rom->map[i].write_16 = tmss_word_write_16;
2021 rom->map[i].write_8 = tmss_word_write_8;
2022 }
2023 } else {
2024 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);
2025 }
2026 } else if (rom->map[i].flags & MMAP_READ_CODE) {
2027 //NOR flash
2028 rom->map[i].flags |= MMAP_PTR_IDX;
2029 rom->map[i].ptr_index = next_ptr_index++;
2030 if (rom->map[i].ptr_index >= NUM_MEM_AREAS) {
2031 fatal_error("Too many memmap chunks with MMAP_PTR_IDX after TMSS remap\n");
2032 }
2033 gen->tmss_pointers[rom->map[i].ptr_index] = rom->map[i].buffer;
2034 rom->map[i].buffer = buffer + (rom->map[i].start & ~rom->map[i].mask & (tmss_size - 1));
2035 if (!gen->tmss_write_16) {
2036 gen->tmss_write_16 = rom->map[i].write_16;
2037 gen->tmss_write_8 = rom->map[i].write_8;
2038 gen->tmss_read_16 = rom->map[i].read_16;
2039 gen->tmss_read_8 = rom->map[i].read_8;
2040 rom->map[i].write_16 = tmss_rom_write_16;
2041 rom->map[i].write_8 = tmss_rom_write_8;
2042 rom->map[i].read_16 = tmss_rom_read_16;
2043 rom->map[i].read_8 = tmss_rom_read_8;
2044 } else if (gen->tmss_write_16 == rom->map[i].write_16) {
2045 rom->map[i].write_16 = tmss_rom_write_16;
2046 rom->map[i].write_8 = tmss_rom_write_8;
2047 rom->map[i].read_16 = tmss_rom_read_16;
2048 rom->map[i].read_8 = tmss_rom_read_8;
2049 } else {
2050 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);
2051 }
2052 } else {
2053 warning("Didn't remap chunk starting at %X for TMSS because it has flags %X\n", rom->map[i].start, rom->map[i].flags);
2054 }
2055 }
2056 }
2057 gen->tmss_buffer = buffer;
1674 } 2058 }
1675 2059
1676 m68k_options *opts = malloc(sizeof(m68k_options)); 2060 m68k_options *opts = malloc(sizeof(m68k_options));
1677 init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K); 2061 init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K);
1678 if (!strcmp(tern_find_ptr_default(model, "tas", "broken"), "broken")) { 2062 if (!strcmp(tern_find_ptr_default(model, "tas", "broken"), "broken")) {