comparison genesis.c @ 1983:a7b753e260a2 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 09 May 2020 23:39:44 -0700
parents 2c1c88cd1a3f 81df9aa2de9b
children 0d5f88e53dca
comparison
equal deleted inserted replaced
1937:cafde1255ad3 1983:a7b753e260a2
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 #include "config.h"
22 #include "event_log.h"
22 #define MCLKS_NTSC 53693175 23 #define MCLKS_NTSC 53693175
23 #define MCLKS_PAL 53203395 24 #define MCLKS_PAL 53203395
24 25
25 uint32_t MCLKS_PER_68K; 26 uint32_t MCLKS_PER_68K;
26 #define MCLKS_PER_YM 7 27 #define MCLKS_PER_YM 7
48 #else 49 #else
49 #define Z80_CYCLE current_cycle 50 #define Z80_CYCLE current_cycle
50 #define Z80_OPTS options 51 #define Z80_OPTS options
51 #endif 52 #endif
52 53
53 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc) 54 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc, uint8_t all)
54 { 55 {
55 start_section(buf, SECTION_68000); 56 if (all) {
56 m68k_serialize(gen->m68k, m68k_pc, buf); 57 start_section(buf, SECTION_68000);
57 end_section(buf); 58 m68k_serialize(gen->m68k, m68k_pc, buf);
58 59 end_section(buf);
59 start_section(buf, SECTION_Z80); 60
60 z80_serialize(gen->z80, buf); 61 start_section(buf, SECTION_Z80);
61 end_section(buf); 62 z80_serialize(gen->z80, buf);
63 end_section(buf);
64 }
62 65
63 start_section(buf, SECTION_VDP); 66 start_section(buf, SECTION_VDP);
64 vdp_serialize(gen->vdp, buf); 67 vdp_serialize(gen->vdp, buf);
65 end_section(buf); 68 end_section(buf);
66 69
70 73
71 start_section(buf, SECTION_PSG); 74 start_section(buf, SECTION_PSG);
72 psg_serialize(gen->psg, buf); 75 psg_serialize(gen->psg, buf);
73 end_section(buf); 76 end_section(buf);
74 77
75 start_section(buf, SECTION_GEN_BUS_ARBITER); 78 if (all) {
76 save_int8(buf, gen->z80->reset); 79 start_section(buf, SECTION_GEN_BUS_ARBITER);
77 save_int8(buf, gen->z80->busreq); 80 save_int8(buf, gen->z80->reset);
78 save_int16(buf, gen->z80_bank_reg); 81 save_int8(buf, gen->z80->busreq);
79 end_section(buf); 82 save_int16(buf, gen->z80_bank_reg);
80 83 end_section(buf);
81 start_section(buf, SECTION_SEGA_IO_1); 84
82 io_serialize(gen->io.ports, buf); 85 start_section(buf, SECTION_SEGA_IO_1);
83 end_section(buf); 86 io_serialize(gen->io.ports, buf);
84 87 end_section(buf);
85 start_section(buf, SECTION_SEGA_IO_2); 88
86 io_serialize(gen->io.ports + 1, buf); 89 start_section(buf, SECTION_SEGA_IO_2);
87 end_section(buf); 90 io_serialize(gen->io.ports + 1, buf);
88 91 end_section(buf);
89 start_section(buf, SECTION_SEGA_IO_EXT); 92
90 io_serialize(gen->io.ports + 2, buf); 93 start_section(buf, SECTION_SEGA_IO_EXT);
91 end_section(buf); 94 io_serialize(gen->io.ports + 2, buf);
92 95 end_section(buf);
93 start_section(buf, SECTION_MAIN_RAM); 96
94 save_int8(buf, RAM_WORDS * 2 / 1024); 97 start_section(buf, SECTION_MAIN_RAM);
95 save_buffer16(buf, gen->work_ram, RAM_WORDS); 98 save_int8(buf, RAM_WORDS * 2 / 1024);
96 end_section(buf); 99 save_buffer16(buf, gen->work_ram, RAM_WORDS);
97 100 end_section(buf);
98 start_section(buf, SECTION_SOUND_RAM); 101
99 save_int8(buf, Z80_RAM_BYTES / 1024); 102 start_section(buf, SECTION_SOUND_RAM);
100 save_buffer8(buf, gen->zram, Z80_RAM_BYTES); 103 save_int8(buf, Z80_RAM_BYTES / 1024);
101 end_section(buf); 104 save_buffer8(buf, gen->zram, Z80_RAM_BYTES);
102 105 end_section(buf);
103 cart_serialize(&gen->header, buf); 106
107 cart_serialize(&gen->header, buf);
108 }
104 } 109 }
105 110
106 static uint8_t *serialize(system_header *sys, size_t *size_out) 111 static uint8_t *serialize(system_header *sys, size_t *size_out)
107 { 112 {
108 genesis_context *gen = (genesis_context *)sys; 113 genesis_context *gen = (genesis_context *)sys;
118 } else { 123 } else {
119 serialize_buffer state; 124 serialize_buffer state;
120 init_serialize(&state); 125 init_serialize(&state);
121 uint32_t address = read_word(4, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k) << 16; 126 uint32_t address = read_word(4, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k) << 16;
122 address |= read_word(6, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k); 127 address |= read_word(6, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k);
123 genesis_serialize(gen, &state, address); 128 genesis_serialize(gen, &state, address, 1);
124 if (size_out) { 129 if (size_out) {
125 *size_out = state.size; 130 *size_out = state.size;
126 } 131 }
127 return state.data; 132 return state.data;
128 } 133 }
349 ym_run(gen->ym, target); 354 ym_run(gen->ym, target);
350 355
351 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); 356 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
352 } 357 }
353 358
354 //TODO: move this inside the system context
355 static uint32_t last_frame_num;
356
357 //My refresh emulation isn't currently good enough and causes more problems than it solves 359 //My refresh emulation isn't currently good enough and causes more problems than it solves
358 #define REFRESH_EMULATION 360 #define REFRESH_EMULATION
359 #ifdef REFRESH_EMULATION 361 #ifdef REFRESH_EMULATION
360 #define REFRESH_INTERVAL 128 362 #define REFRESH_INTERVAL 128
361 #define REFRESH_DELAY 2 363 #define REFRESH_DELAY 2
390 if (mclks >= gen->reset_cycle) { 392 if (mclks >= gen->reset_cycle) {
391 gen->reset_requested = 1; 393 gen->reset_requested = 1;
392 context->should_return = 1; 394 context->should_return = 1;
393 gen->reset_cycle = CYCLE_NEVER; 395 gen->reset_cycle = CYCLE_NEVER;
394 } 396 }
395 if (v_context->frame != last_frame_num) { 397 if (v_context->frame != gen->last_frame) {
396 //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", last_frame_num, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot); 398 //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", gen->last_frame, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot);
397 last_frame_num = v_context->frame; 399 gen->last_frame = v_context->frame;
400 event_flush(mclks);
401 gen->last_flush_cycle = mclks;
398 402
399 if(exit_after){ 403 if(exit_after){
400 --exit_after; 404 --exit_after;
401 if (!exit_after) { 405 if (!exit_after) {
402 exit(0); 406 exit(0);
419 } 423 }
420 gen->psg->cycles -= deduction; 424 gen->psg->cycles -= deduction;
421 if (gen->reset_cycle != CYCLE_NEVER) { 425 if (gen->reset_cycle != CYCLE_NEVER) {
422 gen->reset_cycle -= deduction; 426 gen->reset_cycle -= deduction;
423 } 427 }
424 } 428 event_cycle_adjust(mclks, deduction);
429 gen->last_flush_cycle -= deduction;
430 }
431 } else if (mclks - gen->last_flush_cycle > gen->soft_flush_cycles) {
432 event_soft_flush(mclks);
433 gen->last_flush_cycle = mclks;
425 } 434 }
426 gen->frame_end = vdp_cycles_to_frame_end(v_context); 435 gen->frame_end = vdp_cycles_to_frame_end(v_context);
427 context->sync_cycle = gen->frame_end; 436 context->sync_cycle = gen->frame_end;
428 //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot); 437 //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot);
429 if (context->int_ack) { 438 if (context->int_ack) {
459 { 468 {
460 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80); 469 sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80);
461 } 470 }
462 } 471 }
463 #endif 472 #endif
464 char *save_path = slot == SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst"); 473 char *save_path = slot >= SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst");
465 #ifndef NEW_CORE 474 #ifndef NEW_CORE
466 if (use_native_states || slot == SERIALIZE_SLOT) { 475 if (use_native_states || slot >= SERIALIZE_SLOT) {
467 #endif 476 #endif
468 serialize_buffer state; 477 serialize_buffer state;
469 init_serialize(&state); 478 init_serialize(&state);
470 genesis_serialize(gen, &state, address); 479 genesis_serialize(gen, &state, address);
471 if (slot == SERIALIZE_SLOT) { 480 if (slot == SERIALIZE_SLOT) {
472 gen->serialize_tmp = state.data; 481 gen->serialize_tmp = state.data;
473 gen->serialize_size = state.size; 482 gen->serialize_size = state.size;
474 context->sync_cycle = context->current_cycle; 483 context->sync_cycle = context->current_cycle;
475 context->should_return = 1; 484 context->should_return = 1;
485 } else if (slot == EVENTLOG_SLOT) {
486 event_state(context->current_cycle, &state);
476 } else { 487 } else {
477 save_to_file(&state, save_path); 488 save_to_file(&state, save_path);
478 free(state.data); 489 free(state.data);
479 } 490 }
480 #ifndef NEW_CORE 491 #ifndef NEW_CORE
481 } else { 492 } else {
482 save_gst(gen, save_path, address); 493 save_gst(gen, save_path, address);
483 } 494 }
484 #endif 495 #endif
485 printf("Saved state to %s\n", save_path); 496 if (slot != SERIALIZE_SLOT) {
497 debug_message("Saved state to %s\n", save_path);
498 }
486 free(save_path); 499 free(save_path);
487 } else if(gen->header.save_state) { 500 } else if(gen->header.save_state) {
488 context->sync_cycle = context->current_cycle + 1; 501 context->sync_cycle = context->current_cycle + 1;
489 } 502 }
490 } 503 }
642 } 655 }
643 vdp_port &= 0x1F; 656 vdp_port &= 0x1F;
644 uint16_t value; 657 uint16_t value;
645 #ifdef REFRESH_EMULATION 658 #ifdef REFRESH_EMULATION
646 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) { 659 if (context->current_cycle - 4*MCLKS_PER_68K > last_sync_cycle) {
647 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access 660 //do refresh check here so we can avoid adding a penalty for a refresh that happens during a VDP access
648 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle; 661 refresh_counter += context->current_cycle - 4*MCLKS_PER_68K - last_sync_cycle;
649 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL)); 662 context->current_cycle += REFRESH_DELAY * MCLKS_PER_68K * (refresh_counter / (MCLKS_PER_68K * REFRESH_INTERVAL));
650 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); 663 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL);
651 last_sync_cycle = context->current_cycle; 664 last_sync_cycle = context->current_cycle;
652 } 665 }
653 #endif 666 #endif
654 genesis_context *gen = context->system; 667 genesis_context *gen = context->system;
655 vdp_context * v_context = gen->vdp; 668 vdp_context * v_context = gen->vdp;
656 if (vdp_port < 0x10) { 669 if (vdp_port < 0x10) {
1196 gen->version_reg = NO_DISK | USA; 1209 gen->version_reg = NO_DISK | USA;
1197 } 1210 }
1198 1211
1199 if (region & HZ50) { 1212 if (region & HZ50) {
1200 gen->normal_clock = MCLKS_PAL; 1213 gen->normal_clock = MCLKS_PAL;
1214 gen->soft_flush_cycles = MCLKS_LINE * 262 / 3 + 2;
1201 } else { 1215 } else {
1202 gen->normal_clock = MCLKS_NTSC; 1216 gen->normal_clock = MCLKS_NTSC;
1217 gen->soft_flush_cycles = MCLKS_LINE * 313 / 3 + 2;
1203 } 1218 }
1204 gen->master_clock = gen->normal_clock; 1219 gen->master_clock = gen->normal_clock;
1205 } 1220 }
1206 1221
1207 static uint8_t load_state(system_header *system, uint8_t slot) 1222 static uint8_t load_state(system_header *system, uint8_t slot)
1263 load_state(&gen->header, gen->header.delayed_load_slot - 1); 1278 load_state(&gen->header, gen->header.delayed_load_slot - 1);
1264 gen->header.delayed_load_slot = 0; 1279 gen->header.delayed_load_slot = 0;
1265 resume_68k(gen->m68k); 1280 resume_68k(gen->m68k);
1266 } 1281 }
1267 } 1282 }
1268 if (render_should_release_on_exit()) { 1283 if (gen->header.force_release || render_should_release_on_exit()) {
1269 bindings_release_capture(); 1284 bindings_release_capture();
1270 vdp_release_framebuffer(gen->vdp); 1285 vdp_release_framebuffer(gen->vdp);
1271 render_pause_source(gen->ym->audio); 1286 render_pause_source(gen->ym->audio);
1272 render_pause_source(gen->psg->audio); 1287 render_pause_source(gen->psg->audio);
1273 } 1288 }
1319 } 1334 }
1320 1335
1321 static void resume_genesis(system_header *system) 1336 static void resume_genesis(system_header *system)
1322 { 1337 {
1323 genesis_context *gen = (genesis_context *)system; 1338 genesis_context *gen = (genesis_context *)system;
1324 if (render_should_release_on_exit()) { 1339 if (gen->header.force_release || render_should_release_on_exit()) {
1340 gen->header.force_release = 0;
1325 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); 1341 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1326 bindings_reacquire_capture(); 1342 bindings_reacquire_capture();
1327 vdp_reacquire_framebuffer(gen->vdp); 1343 vdp_reacquire_framebuffer(gen->vdp);
1328 render_resume_source(gen->ym->audio); 1344 render_resume_source(gen->ym->audio);
1329 render_resume_source(gen->psg->audio); 1345 render_resume_source(gen->psg->audio);
1563 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL; 1579 gen->max_cycles = config_cycles ? atoi(config_cycles) : DEFAULT_SYNC_INTERVAL;
1564 gen->int_latency_prev1 = MCLKS_PER_68K * 32; 1580 gen->int_latency_prev1 = MCLKS_PER_68K * 32;
1565 gen->int_latency_prev2 = MCLKS_PER_68K * 16; 1581 gen->int_latency_prev2 = MCLKS_PER_68K * 16;
1566 1582
1567 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC); 1583 render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
1584 event_system_start(SYSTEM_GENESIS, (gen->version_reg & HZ50) ? VID_PAL : VID_NTSC, rom->name);
1568 1585
1569 gen->ym = malloc(sizeof(ym2612_context)); 1586 gen->ym = malloc(sizeof(ym2612_context));
1587 char *fm = tern_find_ptr_default(model, "fm", "discrete 2612");
1588 if (!strcmp(fm + strlen(fm) -4, "3834")) {
1589 system_opts |= YM_OPT_3834;
1590 }
1570 ym_init(gen->ym, gen->master_clock, MCLKS_PER_YM, system_opts); 1591 ym_init(gen->ym, gen->master_clock, MCLKS_PER_YM, system_opts);
1571 1592
1572 gen->psg = malloc(sizeof(psg_context)); 1593 gen->psg = malloc(sizeof(psg_context));
1573 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG); 1594 psg_init(gen->psg, gen->master_clock, MCLKS_PER_PSG);
1574 1595
1674 for (int i = 1; i < sizeof(gen->bank_regs); i++) 1695 for (int i = 1; i < sizeof(gen->bank_regs); i++)
1675 { 1696 {
1676 gen->bank_regs[i] = i; 1697 gen->bank_regs[i] = i;
1677 } 1698 }
1678 } 1699 }
1700 gen->reset_cycle = CYCLE_NEVER;
1679 1701
1680 return gen; 1702 return gen;
1681 } 1703 }
1682 1704
1683 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) 1705 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)