Mercurial > repos > blastem
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; |