comparison genesis.c @ 1931:374a5ae694e8 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 18 Apr 2020 11:42:53 -0700
parents 49f65d240299 9fd4bedc1a31
children 2c1c88cd1a3f
comparison
equal deleted inserted replaced
1843:13abdc98379e 1931:374a5ae694e8
16 #include "debug.h" 16 #include "debug.h"
17 #include "gdb_remote.h" 17 #include "gdb_remote.h"
18 #include "saves.h" 18 #include "saves.h"
19 #include "bindings.h" 19 #include "bindings.h"
20 #include "jcart.h" 20 #include "jcart.h"
21 #include "config.h"
21 #define MCLKS_NTSC 53693175 22 #define MCLKS_NTSC 53693175
22 #define MCLKS_PAL 53203395 23 #define MCLKS_PAL 53203395
23 24
24 uint32_t MCLKS_PER_68K; 25 uint32_t MCLKS_PER_68K;
25 #define MCLKS_PER_YM 7 26 #define MCLKS_PER_YM 7
32 //TODO: Figure out the exact value for this 33 //TODO: Figure out the exact value for this
33 #define LINES_NTSC 262 34 #define LINES_NTSC 262
34 #define LINES_PAL 313 35 #define LINES_PAL 313
35 36
36 #ifdef IS_LIB 37 #ifdef IS_LIB
37 #define MAX_SOUND_CYCLES 1000 38 #define MAX_SOUND_CYCLES (MCLKS_PER_YM*NUM_OPERATORS*6*4)
38 #else 39 #else
39 #define MAX_SOUND_CYCLES 100000 40 #define MAX_SOUND_CYCLES 100000
40 #endif 41 #endif
41 42
42 #ifndef USE_NATIVE 43 #ifdef NEW_CORE
43 #define Z80_CYCLE cycles 44 #define Z80_CYCLE cycles
44 #define Z80_OPTS opts 45 #define Z80_OPTS opts
45 #define z80_handle_code_write(...) 46 #define z80_handle_code_write(...)
46 #include "musashi/m68kcpu.h" 47 #include "musashi/m68kcpu.h"
47 #else 48 #else
197 { 198 {
198 genesis_context *gen = (genesis_context *)sys; 199 genesis_context *gen = (genesis_context *)sys;
199 deserialize_buffer buffer; 200 deserialize_buffer buffer;
200 init_deserialize(&buffer, data, size); 201 init_deserialize(&buffer, data, size);
201 genesis_deserialize(&buffer, gen); 202 genesis_deserialize(&buffer, gen);
202 #ifdef USE_NATIVE 203 #ifndef NEW_CORE
203 //HACK: Fix this once PC/IR is represented in a better way in 68K core 204 //HACK: Fix this once PC/IR is represented in a better way in 68K core
204 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, gen->m68k->last_prefetch_address); 205 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, gen->m68k->last_prefetch_address);
205 #endif 206 #endif
206 } 207 }
207 208
218 } 219 }
219 220
220 static uint16_t get_open_bus_value(system_header *system) 221 static uint16_t get_open_bus_value(system_header *system)
221 { 222 {
222 genesis_context *genesis = (genesis_context *)system; 223 genesis_context *genesis = (genesis_context *)system;
223 #ifdef USE_NATIVE 224 #ifndef NEW_CORE
224 return read_dma_value(genesis->m68k->last_prefetch_address/2); 225 return read_dma_value(genesis->m68k->last_prefetch_address/2);
225 #else 226 #else
226 m68000_base_device *device = (m68000_base_device *)genesis->m68k; 227 m68000_base_device *device = (m68000_base_device *)genesis->m68k;
227 return read_dma_value(device->pref_addr/2); 228 return read_dma_value(device->pref_addr/2);
228 #endif 229 #endif
303 #endif 304 #endif
304 305
305 static void z80_next_int_pulse(z80_context * z_context) 306 static void z80_next_int_pulse(z80_context * z_context)
306 { 307 {
307 genesis_context * gen = z_context->system; 308 genesis_context * gen = z_context->system;
308 #ifndef USE_NATIVE 309 #ifdef NEW_CORE
309 z_context->int_cycle = vdp_next_vint_z80(gen->vdp); 310 z_context->int_cycle = vdp_next_vint_z80(gen->vdp);
310 z_context->int_end_cycle = z_context->int_cycle + Z80_INT_PULSE_MCLKS; 311 z_context->int_end_cycle = z_context->int_cycle + Z80_INT_PULSE_MCLKS;
311 z_context->int_value = 0xFF; 312 z_context->int_value = 0xFF;
312 z80_sync_cycle(z_context, z_context->sync_cycle); 313 z80_sync_cycle(z_context, z_context->sync_cycle);
313 #else 314 #else
319 320
320 static void sync_z80(z80_context * z_context, uint32_t mclks) 321 static void sync_z80(z80_context * z_context, uint32_t mclks)
321 { 322 {
322 #ifndef NO_Z80 323 #ifndef NO_Z80
323 if (z80_enabled) { 324 if (z80_enabled) {
324 #ifndef USE_NATIVE 325 #ifdef NEW_CORE
325 if (z_context->int_cycle == 0xFFFFFFFFU) { 326 if (z_context->int_cycle == 0xFFFFFFFFU) {
326 z80_next_int_pulse(z_context); 327 z80_next_int_pulse(z_context);
327 } 328 }
328 #endif 329 #endif
329 z80_run(z_context, mclks); 330 z80_run(z_context, mclks);
371 genesis_context * gen = context->system; 372 genesis_context * gen = context->system;
372 vdp_context * v_context = gen->vdp; 373 vdp_context * v_context = gen->vdp;
373 z80_context * z_context = gen->z80; 374 z80_context * z_context = gen->z80;
374 #ifdef REFRESH_EMULATION 375 #ifdef REFRESH_EMULATION
375 if (context->current_cycle != last_sync_cycle) { 376 if (context->current_cycle != last_sync_cycle) {
376 //lame estimation of refresh cycle delay 377 //lame estimation of refresh cycle delay
377 refresh_counter += context->current_cycle - last_sync_cycle; 378 refresh_counter += context->current_cycle - last_sync_cycle;
378 if (!gen->bus_busy) { 379 if (!gen->bus_busy) {
379 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); 380 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
380 } 381 }
381 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 382 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
382 } 383 }
383 #endif 384 #endif
384 385
385 uint32_t mclks = context->current_cycle; 386 uint32_t mclks = context->current_cycle;
386 sync_z80(z_context, mclks); 387 sync_z80(z_context, mclks);
410 if (gen->mapper_type == MAPPER_JCART) { 411 if (gen->mapper_type == MAPPER_JCART) {
411 jcart_adjust_cycles(gen, deduction); 412 jcart_adjust_cycles(gen, deduction);
412 } 413 }
413 context->current_cycle -= deduction; 414 context->current_cycle -= deduction;
414 z80_adjust_cycles(z_context, deduction); 415 z80_adjust_cycles(z_context, deduction);
415 gen->ym->current_cycle -= deduction; 416 ym_adjust_cycles(gen->ym, deduction);
417 if (gen->ym->vgm) {
418 vgm_adjust_cycles(gen->ym->vgm, deduction);
419 }
416 gen->psg->cycles -= deduction; 420 gen->psg->cycles -= deduction;
417 if (gen->ym->write_cycle != CYCLE_NEVER) {
418 gen->ym->write_cycle = gen->ym->write_cycle >= deduction ? gen->ym->write_cycle - deduction : 0;
419 }
420 if (gen->reset_cycle != CYCLE_NEVER) { 421 if (gen->reset_cycle != CYCLE_NEVER) {
421 gen->reset_cycle -= deduction; 422 gen->reset_cycle -= deduction;
422 } 423 }
423 } 424 }
424 } 425 }
436 adjust_int_cycle(context, v_context); 437 adjust_int_cycle(context, v_context);
437 if (gen->reset_cycle < context->target_cycle) { 438 if (gen->reset_cycle < context->target_cycle) {
438 context->target_cycle = gen->reset_cycle; 439 context->target_cycle = gen->reset_cycle;
439 } 440 }
440 if (address) { 441 if (address) {
441 #ifdef USE_NATIVE 442 #ifndef NEW_CORE
442 if (gen->header.enter_debugger) { 443 if (gen->header.enter_debugger) {
443 gen->header.enter_debugger = 0; 444 gen->header.enter_debugger = 0;
444 debugger(context, address); 445 debugger(context, address);
445 } 446 }
447 #endif
448 #ifdef NEW_CORE
449 if (gen->header.save_state) {
450 #else
446 if (gen->header.save_state && (z_context->pc || !z_context->native_pc || z_context->reset || !z_context->busreq)) { 451 if (gen->header.save_state && (z_context->pc || !z_context->native_pc || z_context->reset || !z_context->busreq)) {
447 #else
448 if (gen->header.save_state) {
449 #endif 452 #endif
450 uint8_t slot = gen->header.save_state - 1; 453 uint8_t slot = gen->header.save_state - 1;
451 gen->header.save_state = 0; 454 gen->header.save_state = 0;
452 #ifdef USE_NATIVE 455 #ifndef NEW_CORE
453 if (z_context->native_pc && !z_context->reset) { 456 if (z_context->native_pc && !z_context->reset) {
454 //advance Z80 core to the start of an instruction 457 //advance Z80 core to the start of an instruction
455 while (!z_context->pc) 458 while (!z_context->pc)
456 { 459 {
457 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80); 460 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80);
458 } 461 }
459 } 462 }
460 #endif 463 #endif
461 char *save_path = slot == SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst"); 464 char *save_path = slot == SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst");
462 #ifdef USE_NATIVE 465 #ifndef NEW_CORE
463 if (use_native_states || slot == SERIALIZE_SLOT) { 466 if (use_native_states || slot == SERIALIZE_SLOT) {
464 #endif 467 #endif
465 serialize_buffer state; 468 serialize_buffer state;
466 init_serialize(&state); 469 init_serialize(&state);
467 genesis_serialize(gen, &state, address); 470 genesis_serialize(gen, &state, address);
472 context->should_return = 1; 475 context->should_return = 1;
473 } else { 476 } else {
474 save_to_file(&state, save_path); 477 save_to_file(&state, save_path);
475 free(state.data); 478 free(state.data);
476 } 479 }
477 #ifdef USE_NATIVE 480 #ifndef NEW_CORE
478 } else { 481 } else {
479 save_gst(gen, save_path, address); 482 save_gst(gen, save_path, address);
480 } 483 }
481 #endif 484 #endif
482 printf("Saved state to %s\n", save_path); 485 printf("Saved state to %s\n", save_path);
499 vdp_port &= 0x1F; 502 vdp_port &= 0x1F;
500 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle); 503 //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle);
501 #ifdef REFRESH_EMULATION 504 #ifdef REFRESH_EMULATION
502 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access 505 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access
503 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) { 506 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) {
504 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle; 507 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle;
505 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); 508 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
506 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 509 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
507 last_sync_cycle = context->current_cycle; 510 last_sync_cycle = context->current_cycle;
508 } 511 }
509 #endif 512 #endif
510 sync_components(context, 0); 513 sync_components(context, 0);
511 genesis_context * gen = context->system; 514 genesis_context * gen = context->system;
512 vdp_context *v_context = gen->vdp; 515 vdp_context *v_context = gen->vdp;
646 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); 649 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
647 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 650 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
648 last_sync_cycle = context->current_cycle; 651 last_sync_cycle = context->current_cycle;
649 } 652 }
650 #endif 653 #endif
651 sync_components(context, 0);
652 genesis_context *gen = context->system; 654 genesis_context *gen = context->system;
653 vdp_context * v_context = gen->vdp; 655 vdp_context * v_context = gen->vdp;
654 uint32_t before_cycle = v_context->cycles;
655 if (vdp_port < 0x10) { 656 if (vdp_port < 0x10) {
656 if (vdp_port < 4) { 657 if (vdp_port < 4) {
658 sync_components(context, 0);
659 uint32_t before_cycle = v_context->cycles;
657 value = vdp_data_port_read(v_context); 660 value = vdp_data_port_read(v_context);
661 if (v_context->cycles != before_cycle) {
662 //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);
663 context->current_cycle = v_context->cycles;
664 //Lock the Z80 out of the bus until the VDP access is complete
665 genesis_context *gen = context->system;
666 gen->bus_busy = 1;
667 sync_z80(gen->z80, v_context->cycles);
668 gen->bus_busy = 0;
669 }
658 } else if(vdp_port < 8) { 670 } else if(vdp_port < 8) {
671 vdp_run_context(v_context, context->current_cycle);
659 value = vdp_control_port_read(v_context); 672 value = vdp_control_port_read(v_context);
660 } else { 673 } else {
674 vdp_run_context(v_context, context->current_cycle);
661 value = vdp_hv_counter_read(v_context); 675 value = vdp_hv_counter_read(v_context);
662 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles); 676 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles);
663 } 677 }
664 } else if (vdp_port < 0x18){ 678 } else if (vdp_port < 0x18){
665 fatal_error("Illegal read from PSG port %X\n", vdp_port); 679 fatal_error("Illegal read from PSG port %X\n", vdp_port);
666 } else { 680 } else {
667 value = vdp_test_port_read(v_context); 681 value = get_open_bus_value(&gen->header);
668 }
669 if (v_context->cycles != before_cycle) {
670 //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);
671 context->current_cycle = v_context->cycles;
672 //Lock the Z80 out of the bus until the VDP access is complete
673 genesis_context *gen = context->system;
674 gen->bus_busy = 1;
675 sync_z80(gen->z80, v_context->cycles);
676 gen->bus_busy = 0;
677 } 682 }
678 #ifdef REFRESH_EMULATION 683 #ifdef REFRESH_EMULATION
679 last_sync_cycle -= 4; 684 last_sync_cycle -= 4;
680 //refresh may have happened while we were waiting on the VDP, 685 //refresh may have happened while we were waiting on the VDP,
681 //so advance refresh_counter but don't add any delays 686 //so advance refresh_counter but don't add any delays
766 } else { 771 } else {
767 fatal_error("68K write to unhandled Z80 address %X\n", location); 772 fatal_error("68K write to unhandled Z80 address %X\n", location);
768 } 773 }
769 } 774 }
770 } else { 775 } else {
771 location &= 0x1FFF; 776 if (location < 0x10100) {
772 if (location < 0x100) { 777 switch(location >> 1 & 0xFF)
773 switch(location/2)
774 { 778 {
775 case 0x1: 779 case 0x1:
776 io_data_write(gen->io.ports, value, context->current_cycle); 780 io_data_write(gen->io.ports, value, context->current_cycle);
777 break; 781 break;
778 case 0x2: 782 case 0x2:
813 case 0xF: 817 case 0xF:
814 gen->io.ports[2].serial_ctrl = value; 818 gen->io.ports[2].serial_ctrl = value;
815 break; 819 break;
816 } 820 }
817 } else { 821 } else {
818 if (location == 0x1100) { 822 uint32_t masked = location & 0xFFF00;
823 if (masked == 0x11100) {
819 if (value & 1) { 824 if (value & 1) {
820 dputs("bus requesting Z80"); 825 dputs("bus requesting Z80");
821 if (z80_enabled) { 826 if (z80_enabled) {
822 z80_assert_busreq(gen->z80, context->current_cycle); 827 z80_assert_busreq(gen->z80, context->current_cycle);
823 } else { 828 } else {
838 z80_clear_busreq(gen->z80, context->current_cycle); 843 z80_clear_busreq(gen->z80, context->current_cycle);
839 } else { 844 } else {
840 gen->z80->busack = 0; 845 gen->z80->busack = 0;
841 } 846 }
842 } 847 }
843 } else if (location == 0x1200) { 848 } else if (masked == 0x11200) {
844 sync_z80(gen->z80, context->current_cycle); 849 sync_z80(gen->z80, context->current_cycle);
845 if (value & 1) { 850 if (value & 1) {
846 if (z80_enabled) { 851 if (z80_enabled) {
847 z80_clear_reset(gen->z80, context->current_cycle); 852 z80_clear_reset(gen->z80, context->current_cycle);
848 } else { 853 } else {
854 } else { 859 } else {
855 gen->z80->reset = 1; 860 gen->z80->reset = 1;
856 } 861 }
857 ym_reset(gen->ym); 862 ym_reset(gen->ym);
858 } 863 }
864 } else if (masked != 0x11300 && masked != 0x11000) {
865 fatal_error("Machine freeze due to unmapped write to address %X\n", location | 0xA00000);
859 } 866 }
860 } 867 }
861 } 868 }
862 return context; 869 return context;
863 } 870 }
889 location &= 0x7FFF; 896 location &= 0x7FFF;
890 if (location < 0x4000) { 897 if (location < 0x4000) {
891 value = gen->zram[location & 0x1FFF]; 898 value = gen->zram[location & 0x1FFF];
892 } else if (location < 0x6000) { 899 } else if (location < 0x6000) {
893 sync_sound(gen, context->current_cycle); 900 sync_sound(gen, context->current_cycle);
894 value = ym_read_status(gen->ym); 901 value = ym_read_status(gen->ym, context->current_cycle, location);
902 } else if (location < 0x7F00) {
903 value = 0xFF;
895 } else { 904 } else {
905 fatal_error("Machine freeze due to read of Z80 VDP memory window by 68K: %X\n", location | 0xA00000);
896 value = 0xFF; 906 value = 0xFF;
897 } 907 }
898 } else { 908 } else {
899 value = 0xFF; 909 uint16_t word = get_open_bus_value(&gen->header);
900 } 910 value = location & 1 ? word : word >> 8;
901 } else { 911 }
902 location &= 0x1FFF; 912 } else {
903 if (location < 0x100) { 913 if (location < 0x10100) {
904 switch(location/2) 914 switch(location >> 1 & 0xFF)
905 { 915 {
906 case 0x0: 916 case 0x0:
907 //version bits should be 0 for now since we're not emulating TMSS 917 //version bits should be 0 for now since we're not emulating TMSS
908 value = gen->version_reg; 918 value = gen->version_reg;
909 break; 919 break;
951 break; 961 break;
952 case 0xF: 962 case 0xF:
953 value = gen->io.ports[2].serial_ctrl; 963 value = gen->io.ports[2].serial_ctrl;
954 break; 964 break;
955 default: 965 default:
956 value = 0xFF; 966 value = get_open_bus_value(&gen->header) >> 8;
957 } 967 }
958 } else { 968 } else {
959 if (location == 0x1100) { 969 uint32_t masked = location & 0xFFF00;
970 if (masked == 0x11100) {
960 value = z80_enabled ? !z80_get_busack(gen->z80, context->current_cycle) : !gen->z80->busack; 971 value = z80_enabled ? !z80_get_busack(gen->z80, context->current_cycle) : !gen->z80->busack;
961 value |= (get_open_bus_value(&gen->header) >> 8) & 0xFE; 972 value |= (get_open_bus_value(&gen->header) >> 8) & 0xFE;
962 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d)\n", value, context->current_cycle, gen->z80->reset); 973 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d)\n", value, context->current_cycle, gen->z80->reset);
963 } else if (location == 0x1200) { 974 } else if (masked == 0x11200) {
964 value = !gen->z80->reset; 975 value = !gen->z80->reset;
976 } else if (masked == 0x11300 || masked == 0x11000) {
977 //A11300 is apparently completely unused
978 //A11000 is the memory control register which I am assuming is write only
979 value = get_open_bus_value(&gen->header) >> 8;
965 } else { 980 } else {
981 location |= 0xA00000;
982 fatal_error("Machine freeze due to read of unmapped IO location %X\n", location);
966 value = 0xFF; 983 value = 0xFF;
967 printf("Byte read of unknown IO location: %X\n", location);
968 } 984 }
969 } 985 }
970 } 986 }
971 return value; 987 return value;
972 } 988 }
1002 static uint8_t z80_read_ym(uint32_t location, void * vcontext) 1018 static uint8_t z80_read_ym(uint32_t location, void * vcontext)
1003 { 1019 {
1004 z80_context * context = vcontext; 1020 z80_context * context = vcontext;
1005 genesis_context * gen = context->system; 1021 genesis_context * gen = context->system;
1006 sync_sound(gen, context->Z80_CYCLE); 1022 sync_sound(gen, context->Z80_CYCLE);
1007 return ym_read_status(gen->ym); 1023 return ym_read_status(gen->ym, context->Z80_CYCLE, location);
1008 } 1024 }
1009 1025
1010 static uint8_t z80_read_bank(uint32_t location, void * vcontext) 1026 static uint8_t z80_read_bank(uint32_t location, void * vcontext)
1011 { 1027 {
1012 z80_context * context = vcontext; 1028 z80_context * context = vcontext;
1013 genesis_context *gen = context->system; 1029 genesis_context *gen = context->system;
1014
1015 if (gen->bus_busy) { 1030 if (gen->bus_busy) {
1016 context->Z80_CYCLE = gen->m68k->current_cycle; 1031 context->Z80_CYCLE = gen->m68k->current_cycle;
1017 } 1032 }
1018
1019 //typical delay from bus arbitration 1033 //typical delay from bus arbitration
1020 context->Z80_CYCLE += 3 * MCLKS_PER_Z80; 1034 context->Z80_CYCLE += 3 * MCLKS_PER_Z80;
1021 //TODO: add cycle for an access right after a previous one 1035 //TODO: add cycle for an access right after a previous one
1022 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high 1036 //TODO: Below cycle time is an estimate based on the time between 68K !BG goes low and Z80 !MREQ goes high
1023 // Needs a new logic analyzer capture to get the actual delay on the 68K side 1037 // Needs a new logic analyzer capture to get the actual delay on the 68K side
1028 return context->mem_pointers[1][location ^ 1]; 1042 return context->mem_pointers[1][location ^ 1];
1029 } 1043 }
1030 uint32_t address = gen->z80_bank_reg << 15 | location; 1044 uint32_t address = gen->z80_bank_reg << 15 | location;
1031 if (address >= 0xC00000 && address < 0xE00000) { 1045 if (address >= 0xC00000 && address < 0xE00000) {
1032 return z80_vdp_port_read(location & 0xFF, context); 1046 return z80_vdp_port_read(location & 0xFF, context);
1047 } else if (address >= 0xA10000 && address <= 0xA10001) {
1048 //Apparently version reg can be read through Z80 banked area
1049 //TODO: Check rest of IO region addresses
1050 return gen->version_reg;
1033 } else { 1051 } else {
1034 fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area (%X)\n", address, gen->z80_bank_reg << 15); 1052 fprintf(stderr, "Unhandled read by Z80 from address %X through banked memory area (%X)\n", address, gen->z80_bank_reg << 15);
1035 } 1053 }
1036 return 0; 1054 return 0;
1037 } 1055 }
1070 1088
1071 gen->z80_bank_reg = (gen->z80_bank_reg >> 1 | value << 8) & 0x1FF; 1089 gen->z80_bank_reg = (gen->z80_bank_reg >> 1 | value << 8) & 0x1FF;
1072 update_z80_bank_pointer(context->system); 1090 update_z80_bank_pointer(context->system);
1073 1091
1074 return context; 1092 return context;
1093 }
1094
1095 static uint16_t unused_read(uint32_t location, void *vcontext)
1096 {
1097 m68k_context *context = vcontext;
1098 genesis_context *gen = context->system;
1099 if ((location >= 0xA13000 && location < 0xA13100) || (location >= 0xA12000 && location < 0xA12100)) {
1100 //Only called if the cart/exp doesn't have a more specific handler for this region
1101 return get_open_bus_value(&gen->header);
1102 } else if (location == 0xA14000 || location == 0xA14002) {
1103 if (gen->version_reg & 0xF) {
1104 return gen->tmss_lock[location >> 1 & 1];
1105 } else {
1106 fatal_error("Machine freeze due to read from TMSS lock when TMSS is not present %X\n", location);
1107 return 0xFFFF;
1108 }
1109 } else if (location == 0xA14100) {
1110 if (gen->version_reg & 0xF) {
1111 return get_open_bus_value(&gen->header);
1112 } else {
1113 fatal_error("Machine freeze due to read from TMSS control when TMSS is not present %X\n", location);
1114 return 0xFFFF;
1115 }
1116 } else {
1117 fatal_error("Machine freeze due to unmapped read from %X\n", location);
1118 return 0xFFFF;
1119 }
1120 }
1121
1122 static uint8_t unused_read_b(uint32_t location, void *vcontext)
1123 {
1124 uint16_t v = unused_read(location & 0xFFFFFE, vcontext);
1125 if (location & 1) {
1126 return v;
1127 } else {
1128 return v >> 8;
1129 }
1130 }
1131
1132 static void *unused_write(uint32_t location, void *vcontext, uint16_t value)
1133 {
1134 m68k_context *context = vcontext;
1135 genesis_context *gen = context->system;
1136 uint8_t has_tmss = gen->version_reg & 0xF;
1137 if (has_tmss && (location == 0xA14000 || location == 0xA14002)) {
1138 gen->tmss_lock[location >> 1 & 1] = value;
1139 } else if (has_tmss && location == 0xA14100) {
1140 //TODO: implement TMSS control register
1141 } else if (location < 0xA12000 || location >= 0xA13100 || (location >= 0xA12100 && location < 0xA13000)) {
1142 fatal_error("Machine freeze due to unmapped write to %X\n", location);
1143 }
1144 return vcontext;
1145 }
1146
1147 static void *unused_write_b(uint32_t location, void *vcontext, uint8_t value)
1148 {
1149 m68k_context *context = vcontext;
1150 genesis_context *gen = context->system;
1151 uint8_t has_tmss = gen->version_reg & 0xF;
1152 if (has_tmss && location >= 0xA14000 && location <= 0xA14003) {
1153 uint32_t offset = location >> 1 & 1;
1154 if (location & 1) {
1155 gen->tmss_lock[offset] &= 0xFF00;
1156 gen->tmss_lock[offset] |= value;
1157 } else {
1158 gen->tmss_lock[offset] &= 0xFF;
1159 gen->tmss_lock[offset] |= value << 8;
1160 }
1161 } else if (has_tmss && (location == 0xA14100 || location == 0xA14101)) {
1162 //TODO: implement TMSS control register
1163 } else if (location < 0xA12000 || location >= 0xA13100 || (location >= 0xA12100 && location < 0xA13000)) {
1164 fatal_error("Machine freeze due to unmapped byte write to %X\n", location);
1165 }
1166 return vcontext;
1075 } 1167 }
1076 1168
1077 static void set_speed_percent(system_header * system, uint32_t percent) 1169 static void set_speed_percent(system_header * system, uint32_t percent)
1078 { 1170 {
1079 genesis_context *context = (genesis_context *)system; 1171 genesis_context *context = (genesis_context *)system;
1130 goto done; 1222 goto done;
1131 } 1223 }
1132 if (load_from_file(&state, statepath)) { 1224 if (load_from_file(&state, statepath)) {
1133 genesis_deserialize(&state, gen); 1225 genesis_deserialize(&state, gen);
1134 free(state.data); 1226 free(state.data);
1135 #ifdef USE_NATIVE 1227 #ifndef NEW_CORE
1136 //HACK 1228 //HACK
1137 pc = gen->m68k->last_prefetch_address; 1229 pc = gen->m68k->last_prefetch_address;
1138 #endif 1230 #endif
1139 ret = 1; 1231 ret = 1;
1140 } else { 1232 } else {
1141 #ifdef USE_NATIVE 1233 #ifndef NEW_CORE
1142 strcpy(statepath + strlen(statepath)-strlen("state"), "gst"); 1234 strcpy(statepath + strlen(statepath)-strlen("state"), "gst");
1143 pc = load_gst(gen, statepath); 1235 pc = load_gst(gen, statepath);
1144 ret = pc != 0; 1236 ret = pc != 0;
1145 #endif 1237 #endif
1146 } 1238 }
1147 #ifdef USE_NATIVE 1239 #ifndef NEW_CORE
1148 if (ret) { 1240 if (ret) {
1149 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc); 1241 gen->m68k->resume_pc = get_native_address_trans(gen->m68k, pc);
1150 } 1242 }
1151 #endif 1243 #endif
1152 done: 1244 done:
1189 deserialize_buffer state; 1281 deserialize_buffer state;
1190 uint32_t pc; 1282 uint32_t pc;
1191 if (load_from_file(&state, statefile)) { 1283 if (load_from_file(&state, statefile)) {
1192 genesis_deserialize(&state, gen); 1284 genesis_deserialize(&state, gen);
1193 free(state.data); 1285 free(state.data);
1194 #ifdef USE_NATIVE 1286 #ifndef NEW_CORE
1195 //HACK 1287 //HACK
1196 pc = gen->m68k->last_prefetch_address; 1288 pc = gen->m68k->last_prefetch_address;
1197 #endif 1289 #endif
1198 } else { 1290 } else {
1199 #ifdef USE_NATIVE 1291 #ifndef NEW_CORE
1200 pc = load_gst(gen, statefile); 1292 pc = load_gst(gen, statefile);
1201 if (!pc) { 1293 if (!pc) {
1202 fatal_error("Failed to load save state %s\n", statefile); 1294 fatal_error("Failed to load save state %s\n", statefile);
1203 } 1295 }
1204 #endif 1296 #endif
1205 } 1297 }
1206 printf("Loaded %s\n", statefile); 1298 printf("Loaded %s\n", statefile);
1207 #ifdef USE_NATIVE 1299 #ifndef NEW_CORE
1208 if (gen->header.enter_debugger) { 1300 if (gen->header.enter_debugger) {
1209 gen->header.enter_debugger = 0; 1301 gen->header.enter_debugger = 0;
1210 insert_breakpoint(gen->m68k, pc, gen->header.debugger_type == DEBUGGER_NATIVE ? debugger : gdb_debug_enter); 1302 insert_breakpoint(gen->m68k, pc, gen->header.debugger_type == DEBUGGER_NATIVE ? debugger : gdb_debug_enter);
1211 } 1303 }
1212 #endif 1304 #endif
1213 adjust_int_cycle(gen->m68k, gen->vdp); 1305 adjust_int_cycle(gen->m68k, gen->vdp);
1214 start_68k_context(gen->m68k, pc); 1306 start_68k_context(gen->m68k, pc);
1215 } else { 1307 } else {
1216 #ifdef USE_NATIVE 1308 #ifndef NEW_CORE
1217 if (gen->header.enter_debugger) { 1309 if (gen->header.enter_debugger) {
1218 gen->header.enter_debugger = 0; 1310 gen->header.enter_debugger = 0;
1219 uint32_t address = gen->cart[2] << 16 | gen->cart[3]; 1311 uint32_t address = gen->cart[2] << 16 | gen->cart[3];
1220 insert_breakpoint(gen->m68k, address, gen->header.debugger_type == DEBUGGER_NATIVE ? debugger : gdb_debug_enter); 1312 insert_breakpoint(gen->m68k, address, gen->header.debugger_type == DEBUGGER_NATIVE ? debugger : gdb_debug_enter);
1221 } 1313 }
1262 FILE * f = fopen(save_filename, "wb"); 1354 FILE * f = fopen(save_filename, "wb");
1263 if (!f) { 1355 if (!f) {
1264 fprintf(stderr, "Failed to open %s file %s for writing\n", save_type_name(gen->save_type), save_filename); 1356 fprintf(stderr, "Failed to open %s file %s for writing\n", save_type_name(gen->save_type), save_filename);
1265 return; 1357 return;
1266 } 1358 }
1359 if (gen->save_type == RAM_FLAG_BOTH) {
1360 byteswap_rom(gen->save_size, (uint16_t *)gen->save_storage);
1361 }
1267 fwrite(gen->save_storage, 1, gen->save_size, f); 1362 fwrite(gen->save_storage, 1, gen->save_size, f);
1363 if (gen->save_type == RAM_FLAG_BOTH) {
1364 byteswap_rom(gen->save_size, (uint16_t *)gen->save_storage);
1365 }
1268 fclose(f); 1366 fclose(f);
1269 printf("Saved %s to %s\n", save_type_name(gen->save_type), save_filename); 1367 printf("Saved %s to %s\n", save_type_name(gen->save_type), save_filename);
1270 } 1368 }
1271 1369
1272 static void load_save(system_header *system) 1370 static void load_save(system_header *system)
1275 FILE * f = fopen(save_filename, "rb"); 1373 FILE * f = fopen(save_filename, "rb");
1276 if (f) { 1374 if (f) {
1277 uint32_t read = fread(gen->save_storage, 1, gen->save_size, f); 1375 uint32_t read = fread(gen->save_storage, 1, gen->save_size, f);
1278 fclose(f); 1376 fclose(f);
1279 if (read > 0) { 1377 if (read > 0) {
1378 if (gen->save_type == RAM_FLAG_BOTH) {
1379 byteswap_rom(gen->save_size, (uint16_t *)gen->save_storage);
1380 }
1280 printf("Loaded %s from %s\n", save_type_name(gen->save_type), save_filename); 1381 printf("Loaded %s from %s\n", save_type_name(gen->save_type), save_filename);
1281 } 1382 }
1282 } 1383 }
1283 } 1384 }
1284 1385
1383 static void config_updated(system_header *system) 1484 static void config_updated(system_header *system)
1384 { 1485 {
1385 genesis_context *gen = (genesis_context *)system; 1486 genesis_context *gen = (genesis_context *)system;
1386 setup_io_devices(config, &system->info, &gen->io); 1487 setup_io_devices(config, &system->info, &gen->io);
1387 set_audio_config(gen); 1488 set_audio_config(gen);
1489 }
1490
1491 static void start_vgm_log(system_header *system, char *filename)
1492 {
1493 genesis_context *gen = (genesis_context *)system;
1494 vgm_writer *vgm = vgm_write_open(filename, gen->version_reg & HZ50 ? 50 : 60, gen->master_clock, gen->m68k->current_cycle);
1495 if (vgm) {
1496 printf("Started logging VGM to %s\n", filename);
1497 sync_sound(gen, vgm->last_cycle);
1498 ym_vgm_log(gen->ym, gen->master_clock, vgm);
1499 psg_vgm_log(gen->psg, gen->master_clock, vgm);
1500 gen->header.vgm_logging = 1;
1501 } else {
1502 printf("Failed to start logging to %s\n", filename);
1503 }
1504 }
1505
1506 static void stop_vgm_log(system_header *system)
1507 {
1508 puts("Stopped VGM log");
1509 genesis_context *gen = (genesis_context *)system;
1510 vgm_close(gen->ym->vgm);
1511 gen->ym->vgm = gen->psg->vgm = NULL;
1512 gen->header.vgm_logging = 0;
1388 } 1513 }
1389 1514
1390 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region) 1515 genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on, uint32_t system_opts, uint8_t force_region)
1391 { 1516 {
1392 static memmap_chunk z80_map[] = { 1517 static memmap_chunk z80_map[] = {
1417 gen->header.keyboard_down = keyboard_down; 1542 gen->header.keyboard_down = keyboard_down;
1418 gen->header.keyboard_up = keyboard_up; 1543 gen->header.keyboard_up = keyboard_up;
1419 gen->header.config_updated = config_updated; 1544 gen->header.config_updated = config_updated;
1420 gen->header.serialize = serialize; 1545 gen->header.serialize = serialize;
1421 gen->header.deserialize = deserialize; 1546 gen->header.deserialize = deserialize;
1547 gen->header.start_vgm_log = start_vgm_log;
1548 gen->header.stop_vgm_log = stop_vgm_log;
1422 gen->header.type = SYSTEM_GENESIS; 1549 gen->header.type = SYSTEM_GENESIS;
1423 gen->header.info = *rom; 1550 gen->header.info = *rom;
1424 set_region(gen, rom, force_region); 1551 set_region(gen, rom, force_region);
1425 1552 tern_node *model = get_model(config, SYSTEM_GENESIS);
1426 gen->vdp = init_vdp_context(gen->version_reg & 0x40); 1553 uint8_t tmss = !strcmp(tern_find_ptr_default(model, "tmss", "off"), "on");
1554 if (tmss) {
1555 gen->version_reg |= 1;
1556 }
1557
1558 uint8_t max_vsram = !strcmp(tern_find_ptr_default(model, "vsram", "40"), "64");
1559 gen->vdp = init_vdp_context(gen->version_reg & 0x40, max_vsram);
1427 gen->vdp->system = &gen->header; 1560 gen->vdp->system = &gen->header;
1428 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp); 1561 gen->frame_end = vdp_cycles_to_frame_end(gen->vdp);
1429 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval; 1562 char * config_cycles = tern_find_path(config, "clocks\0max_cycles\0", TVAL_PTR).ptrval;
1430 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL; 1563 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL;
1431 gen->int_latency_prev1 = MCLKS_PER_68K * 32; 1564 gen->int_latency_prev1 = MCLKS_PER_68K * 32;
1444 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES); 1577 z80_map[0].buffer = gen->zram = calloc(1, Z80_RAM_BYTES);
1445 #ifndef NO_Z80 1578 #ifndef NO_Z80
1446 z80_options *z_opts = malloc(sizeof(z80_options)); 1579 z80_options *z_opts = malloc(sizeof(z80_options));
1447 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF); 1580 init_z80_opts(z_opts, z80_map, 5, NULL, 0, MCLKS_PER_Z80, 0xFFFF);
1448 gen->z80 = init_z80_context(z_opts); 1581 gen->z80 = init_z80_context(z_opts);
1449 #ifdef USE_NATIVE 1582 #ifndef NEW_CORE
1450 gen->z80->next_int_pulse = z80_next_int_pulse; 1583 gen->z80->next_int_pulse = z80_next_int_pulse;
1451 #endif 1584 #endif
1452 z80_assert_reset(gen->z80, 0); 1585 z80_assert_reset(gen->z80, 0);
1453 #else 1586 #else
1454 gen->z80 = calloc(1, sizeof(z80_context)); 1587 gen->z80 = calloc(1, sizeof(z80_context));
1482 } 1615 }
1483 for (int i = 0; i < CRAM_SIZE; i++) 1616 for (int i = 0; i < CRAM_SIZE; i++)
1484 { 1617 {
1485 write_cram_internal(gen->vdp, i, rand()); 1618 write_cram_internal(gen->vdp, i, rand());
1486 } 1619 }
1487 for (int i = 0; i < VSRAM_SIZE; i++) 1620 for (int i = 0; i < gen->vdp->vsram_size; i++)
1488 { 1621 {
1489 gen->vdp->vsram[i] = rand(); 1622 gen->vdp->vsram[i] = rand();
1490 } 1623 }
1491 } 1624 }
1492 setup_io_devices(config, rom, &gen->io); 1625 setup_io_devices(config, rom, &gen->io);
1519 } 1652 }
1520 } 1653 }
1521 1654
1522 m68k_options *opts = malloc(sizeof(m68k_options)); 1655 m68k_options *opts = malloc(sizeof(m68k_options));
1523 init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K); 1656 init_m68k_opts(opts, rom->map, rom->map_chunks, MCLKS_PER_68K);
1524 //TODO: make this configurable 1657 if (!strcmp(tern_find_ptr_default(model, "tas", "broken"), "broken")) {
1525 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY; 1658 opts->gen.flags |= M68K_OPT_BROKEN_READ_MODIFY;
1659 }
1526 gen->m68k = init_68k_context(opts, NULL); 1660 gen->m68k = init_68k_context(opts, NULL);
1527 gen->m68k->system = gen; 1661 gen->m68k->system = gen;
1528 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL; 1662 opts->address_log = (system_opts & OPT_ADDRESS_LOG) ? fopen("address.log", "w") : NULL;
1529 1663
1530 //This must happen after the 68K context has been allocated 1664 //This must happen after the 68K context has been allocated
1554 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL, 1688 {0xC00000, 0xE00000, 0x1FFFFF, 0, 0, 0, NULL,
1555 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write, 1689 (read_16_fun)vdp_port_read, (write_16_fun)vdp_port_write,
1556 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b}, 1690 (read_8_fun)vdp_port_read_b, (write_8_fun)vdp_port_write_b},
1557 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL, 1691 {0xA00000, 0xA12000, 0x1FFFF, 0, 0, 0, NULL,
1558 (read_16_fun)io_read_w, (write_16_fun)io_write_w, 1692 (read_16_fun)io_read_w, (write_16_fun)io_write_w,
1559 (read_8_fun)io_read, (write_8_fun)io_write} 1693 (read_8_fun)io_read, (write_8_fun)io_write},
1694 {0x000000, 0xFFFFFF, 0xFFFFFF, 0, 0, 0, NULL,
1695 (read_16_fun)unused_read, (write_16_fun)unused_write,
1696 (read_8_fun)unused_read_b, (write_8_fun)unused_write_b}
1560 }; 1697 };
1561 static tern_node *rom_db; 1698 static tern_node *rom_db;
1562 if (!rom_db) { 1699 if (!rom_db) {
1563 rom_db = load_rom_db(); 1700 rom_db = load_rom_db();
1564 } 1701 }