comparison blastem.c @ 483:3e1573fa22cf

Implement turbo/slow motion feature that overclocks or underclocks the entire system at the push of a button
author Mike Pavone <pavone@retrodev.com>
date Tue, 01 Oct 2013 23:51:16 -0700
parents 4b24260125f3
children c08a4efeee7f
comparison
equal deleted inserted replaced
482:4b24260125f3 483:3e1573fa22cf
31 31
32 //TODO: Figure out the exact value for this 32 //TODO: Figure out the exact value for this
33 #define LINES_NTSC 262 33 #define LINES_NTSC 262
34 #define LINES_PAL 312 34 #define LINES_PAL 312
35 35
36 #define MAX_SOUND_CYCLES 100000
37
36 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC; 38 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC;
37 39
38 uint16_t cart[CARTRIDGE_WORDS]; 40 uint16_t cart[CARTRIDGE_WORDS];
39 uint16_t ram[RAM_WORDS]; 41 uint16_t ram[RAM_WORDS];
40 uint8_t z80_ram[Z80_RAM_BYTES]; 42 uint8_t z80_ram[Z80_RAM_BYTES];
204 } 206 }
205 207
206 void sync_sound(genesis_context * gen, uint32_t target) 208 void sync_sound(genesis_context * gen, uint32_t target)
207 { 209 {
208 //printf("YM | Cycle: %d, bpos: %d, PSG | Cycle: %d, bpos: %d\n", gen->ym->current_cycle, gen->ym->buffer_pos, gen->psg->cycles, gen->psg->buffer_pos * 2); 210 //printf("YM | Cycle: %d, bpos: %d, PSG | Cycle: %d, bpos: %d\n", gen->ym->current_cycle, gen->ym->buffer_pos, gen->psg->cycles, gen->psg->buffer_pos * 2);
211 while (target > gen->psg->cycles && target - gen->psg->cycles > MAX_SOUND_CYCLES) {
212 uint32_t cur_target = gen->psg->cycles + MAX_SOUND_CYCLES;
213 //printf("Running PSG to cycle %d\n", cur_target);
214 psg_run(gen->psg, cur_target);
215 //printf("Running YM-2612 to cycle %d\n", cur_target);
216 ym_run(gen->ym, cur_target);
217 }
209 psg_run(gen->psg, target); 218 psg_run(gen->psg, target);
210 ym_run(gen->ym, target); 219 ym_run(gen->ym, target);
211 220
212 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2); 221 //printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
213 } 222 }
1490 } 1499 }
1491 } 1500 }
1492 return context; 1501 return context;
1493 } 1502 }
1494 1503
1504 void set_speed_percent(genesis_context * context, uint32_t percent)
1505 {
1506 uint32_t old_clock = context->master_clock;
1507 context->master_clock = ((uint64_t)context->normal_clock * (uint64_t)percent) / 100;
1508 while (context->ym->current_cycle != context->psg->cycles) {
1509 sync_sound(context, context->psg->cycles + MCLKS_PER_PSG);
1510 }
1511 ym_adjust_master_clock(context->ym, context->master_clock);
1512 psg_adjust_master_clock(context->psg, context->master_clock);
1513 }
1514
1495 #define ROM_END 0x1A4 1515 #define ROM_END 0x1A4
1496 #define RAM_ID 0x1B0 1516 #define RAM_ID 0x1B0
1497 #define RAM_FLAGS 0x1B2 1517 #define RAM_FLAGS 0x1B2
1498 #define RAM_START 0x1B4 1518 #define RAM_START 0x1B4
1499 #define RAM_END 0x1B8 1519 #define RAM_END 0x1B8
1866 } 1886 }
1867 if (!headless) { 1887 if (!headless) {
1868 render_init(width, height, title, fps, fullscreen); 1888 render_init(width, height, title, fps, fullscreen);
1869 } 1889 }
1870 vdp_context v_context; 1890 vdp_context v_context;
1891 genesis_context gen;
1892 memset(&gen, 0, sizeof(gen));
1893 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL;
1871 1894
1872 init_vdp_context(&v_context); 1895 init_vdp_context(&v_context);
1873 1896
1874 ym2612_context y_context; 1897 ym2612_context y_context;
1875 ym_init(&y_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); 1898 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0);
1876 1899
1877 psg_context p_context; 1900 psg_context p_context;
1878 psg_init(&p_context, render_sample_rate(), fps == 60 ? MCLKS_NTSC : MCLKS_PAL, MCLKS_PER_PSG, render_audio_buffer()); 1901 psg_init(&p_context, render_sample_rate(), gen.master_clock, MCLKS_PER_PSG, render_audio_buffer());
1879 1902
1880 z80_context z_context; 1903 z80_context z_context;
1881 x86_z80_options z_opts; 1904 x86_z80_options z_opts;
1882 init_x86_z80_opts(&z_opts); 1905 init_x86_z80_opts(&z_opts);
1883 init_z80_context(&z_context, &z_opts); 1906 init_z80_context(&z_context, &z_opts);
1884
1885 genesis_context gen;
1886 memset(&gen, 0, sizeof(gen));
1887 1907
1888 z_context.system = &gen; 1908 z_context.system = &gen;
1889 z_context.mem_pointers[0] = z80_ram; 1909 z_context.mem_pointers[0] = z80_ram;
1890 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; 1910 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80;
1891 z_context.int_cycle = CYCLE_NEVER; 1911 z_context.int_cycle = CYCLE_NEVER;