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