comparison genesis.c @ 1556:075df0844baa

Randomize soft reset timing and fix silly bug that was accidentally clearing IO state on soft reset
author Michael Pavone <pavone@retrodev.com>
date Fri, 30 Mar 2018 22:01:05 -0700
parents 6ce36c3f250b
children a0fbb1e90533
comparison
equal deleted inserted replaced
1555:6ce36c3f250b 1556:075df0844baa
27 #define DEFAULT_SYNC_INTERVAL MCLKS_LINE 27 #define DEFAULT_SYNC_INTERVAL MCLKS_LINE
28 #define DEFAULT_LOWPASS_CUTOFF 3390 28 #define DEFAULT_LOWPASS_CUTOFF 3390
29 29
30 //TODO: Figure out the exact value for this 30 //TODO: Figure out the exact value for this
31 #define LINES_NTSC 262 31 #define LINES_NTSC 262
32 #define LINES_PAL 312 32 #define LINES_PAL 313
33 33
34 #define MAX_SOUND_CYCLES 100000 34 #define MAX_SOUND_CYCLES 100000
35 35
36 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc) 36 void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc)
37 { 37 {
306 306
307 uint32_t mclks = context->current_cycle; 307 uint32_t mclks = context->current_cycle;
308 sync_z80(z_context, mclks); 308 sync_z80(z_context, mclks);
309 sync_sound(gen, mclks); 309 sync_sound(gen, mclks);
310 vdp_run_context(v_context, mclks); 310 vdp_run_context(v_context, mclks);
311 if (mclks >= gen->reset_cycle) {
312 gen->reset_requested = 1;
313 context->should_return = 1;
314 gen->reset_cycle = CYCLE_NEVER;
315 }
311 if (v_context->frame != last_frame_num) { 316 if (v_context->frame != last_frame_num) {
312 //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); 317 //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);
313 last_frame_num = v_context->frame; 318 last_frame_num = v_context->frame;
314 319
315 if(exit_after){ 320 if(exit_after){
329 gen->ym->current_cycle -= deduction; 334 gen->ym->current_cycle -= deduction;
330 gen->psg->cycles -= deduction; 335 gen->psg->cycles -= deduction;
331 if (gen->ym->write_cycle != CYCLE_NEVER) { 336 if (gen->ym->write_cycle != CYCLE_NEVER) {
332 gen->ym->write_cycle = gen->ym->write_cycle >= deduction ? gen->ym->write_cycle - deduction : 0; 337 gen->ym->write_cycle = gen->ym->write_cycle >= deduction ? gen->ym->write_cycle - deduction : 0;
333 } 338 }
339 if (gen->reset_cycle != CYCLE_NEVER) {
340 gen->reset_cycle -= deduction;
341 }
334 } 342 }
335 } 343 }
336 gen->frame_end = vdp_cycles_to_frame_end(v_context); 344 gen->frame_end = vdp_cycles_to_frame_end(v_context);
337 context->sync_cycle = gen->frame_end; 345 context->sync_cycle = gen->frame_end;
338 //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot); 346 //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot);
343 } 351 }
344 if (!address && (gen->header.enter_debugger || gen->header.save_state)) { 352 if (!address && (gen->header.enter_debugger || gen->header.save_state)) {
345 context->sync_cycle = context->current_cycle + 1; 353 context->sync_cycle = context->current_cycle + 1;
346 } 354 }
347 adjust_int_cycle(context, v_context); 355 adjust_int_cycle(context, v_context);
356 if (gen->reset_cycle < context->target_cycle) {
357 context->target_cycle = gen->reset_cycle;
358 }
348 if (address) { 359 if (address) {
349 if (gen->header.enter_debugger) { 360 if (gen->header.enter_debugger) {
350 gen->header.enter_debugger = 0; 361 gen->header.enter_debugger = 0;
351 debugger(context, address); 362 debugger(context, address);
352 } 363 }
1037 { 1048 {
1038 while (gen->reset_requested || gen->header.delayed_load_slot) 1049 while (gen->reset_requested || gen->header.delayed_load_slot)
1039 { 1050 {
1040 if (gen->reset_requested) { 1051 if (gen->reset_requested) {
1041 gen->reset_requested = 0; 1052 gen->reset_requested = 0;
1053 gen->m68k->should_return = 0;
1042 z80_assert_reset(gen->z80, gen->m68k->current_cycle); 1054 z80_assert_reset(gen->z80, gen->m68k->current_cycle);
1043 z80_clear_busreq(gen->z80, gen->m68k->current_cycle); 1055 z80_clear_busreq(gen->z80, gen->m68k->current_cycle);
1044 ym_reset(gen->ym); 1056 ym_reset(gen->ym);
1045 //Is there any sort of VDP reset? 1057 //Is there any sort of VDP reset?
1046 m68k_reset(gen->m68k); 1058 m68k_reset(gen->m68k);
1161 } 1173 }
1162 1174
1163 static void soft_reset(system_header *system) 1175 static void soft_reset(system_header *system)
1164 { 1176 {
1165 genesis_context *gen = (genesis_context *)system; 1177 genesis_context *gen = (genesis_context *)system;
1166 gen->m68k->should_return = 1; 1178 if (gen->reset_cycle == CYCLE_NEVER) {
1167 gen->reset_requested = 1; 1179 double random = (double)rand()/(double)RAND_MAX;
1180 gen->reset_cycle = gen->m68k->current_cycle + random * MCLKS_LINE * (gen->version_reg & HZ50 ? LINES_PAL : LINES_NTSC);
1181 if (gen->reset_cycle < gen->m68k->target_cycle) {
1182 gen->m68k->target_cycle = gen->reset_cycle;
1183 }
1184 }
1168 } 1185 }
1169 1186
1170 static void free_genesis(system_header *system) 1187 static void free_genesis(system_header *system)
1171 { 1188 {
1172 genesis_context *gen = (genesis_context *)system; 1189 genesis_context *gen = (genesis_context *)system;