Finally fixed the animation speed in sonic 2

It turned out to be an issue with the interrupts and when the
vertical interrupt was triggered vs when the vertical blanking
bit was set.  The interrupt code in sonic 2 tries to read the
status bit after the vint occurs, and if the vblank bit is set,
it runs the Vint_Level function, but the hacky code I wrote
turned the vblanking bit on after 14ms and off when it triggered
the vint, instead of turning it on at 15ms, and off at 1.2ms, with
the int occuring at the *start* of the time the blanking bit is
set.  So the code had been waiting for 14ms after the vint until
it actually started processing thing, which didn't complete before
the next vint, so it only ran the main game loop every 33.2ms which
is why doubling the speed of the simulated execution time made it
seem about the right speed
This commit is contained in:
transistor 2021-12-20 20:41:25 -08:00
parent 18e54f4a44
commit ed030082cd

View File

@ -625,26 +625,29 @@ impl Steppable for Ym7101 {
}
self.state.h_clock += diff;
if (self.state.status & STATUS_IN_HBLANK) == 0 && self.state.v_clock > 58_820 {
self.state.status |= STATUS_IN_HBLANK;
}
if self.state.h_clock > 63_500 {
if (self.state.status & STATUS_IN_HBLANK) != 0 && self.state.h_clock >= 2_340 && self.state.h_clock <= 61_160 {
self.state.status &= !STATUS_IN_HBLANK;
self.state.h_clock = 0;
self.state.h_scanlines = self.state.h_scanlines.wrapping_sub(1);
}
if (self.state.status & STATUS_IN_HBLANK) == 0 && self.state.h_clock >= 61_160 {
self.state.status |= STATUS_IN_HBLANK;
if self.state.hsync_int_enabled() && self.state.h_scanlines == 0 {
self.state.h_scanlines = self.state.h_int_lines;
system.get_interrupt_controller().set(true, 4, 28)?;
}
}
if self.state.h_clock > 63_500 {
self.state.h_clock -= 63_500;
self.state.h_scanlines = self.state.h_scanlines.wrapping_sub(1);
}
self.state.v_clock += diff;
if (self.state.status & STATUS_IN_VBLANK) == 0 && self.state.v_clock > 14_218_000 {
self.state.status |= STATUS_IN_VBLANK;
}
if self.state.v_clock > 16_630_000 {
if (self.state.status & STATUS_IN_VBLANK) != 0 && self.state.v_clock >= 1_205_992 && self.state.v_clock <= 15_424_008 {
self.state.status &= !STATUS_IN_VBLANK;
self.state.v_clock -= 16_630_000;
}
if (self.state.status & STATUS_IN_VBLANK) == 0 && self.state.v_clock >= 15_424_008 {
self.state.status |= STATUS_IN_VBLANK;
if self.state.vsync_int_enabled() {
system.get_interrupt_controller().set(true, 6, 30)?;
}
@ -654,6 +657,9 @@ impl Steppable for Ym7101 {
self.frame_complete.signal();
}
if self.state.v_clock > 16_630_000 {
self.state.v_clock -= 16_630_000;
}
if self.state.transfer_run != DmaType::None && (self.state.mode_2 & MODE2_BF_DMA_ENABLED) != 0 {
// TODO we will just do the full dma transfer here, but it really should be stepped