Skip to content

Commit

Permalink
Increase interrupt/HDMA cycle accuracy
Browse files Browse the repository at this point in the history
  • Loading branch information
twvd committed Nov 19, 2023
1 parent d33772f commit af77f92
Showing 1 changed file with 31 additions and 29 deletions.
60 changes: 31 additions & 29 deletions src/snes/bus/mainbus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,41 +745,43 @@ where
{
fn tick(&mut self, ticks: Ticks) -> Result<()> {
// This ratio is not based on anything that makes sense yet
self.ppu.tick(ticks * 8)?;
for _ in 0..(ticks * 8) {
self.ppu.tick(1)?;

let entered_vblank = self.ppu.get_clr_intreq_vblank();
let entered_hblank = self.ppu.get_clr_intreq_hblank();
let entered_vblank = self.ppu.get_clr_intreq_vblank();
let entered_hblank = self.ppu.get_clr_intreq_hblank();

if entered_hblank && !self.ppu.in_vblank() {
if self.ppu.get_current_scanline() == 0 {
self.hdma_reset();
}
if entered_hblank && !self.ppu.in_vblank() {
if self.ppu.get_current_scanline() == 0 {
self.hdma_reset();
}

self.hdma_run();
}
self.hdma_run();
}

if entered_vblank && self.nmitimen & (1 << 7) != 0 {
self.intreq_nmi = true;
}
if entered_vblank && self.nmitimen & (1 << 7) != 0 {
self.intreq_nmi = true;
}

// H/V interrupt
// TODO stop at EXACT H rather than at 0
let hvint = match (self.nmitimen >> 4) & 0x03 {
// Disabled
0 => false,
// H=H + V=*
1 => self.ppu.get_current_scanline() != self.last_scanline,
// H=0, V=V (2) + H=H, V=V (3)
2 | 3 => {
self.ppu.get_current_scanline() != self.last_scanline
&& self.ppu.get_current_scanline() == usize::from(self.vtime)
// H/V interrupt
// TODO stop at EXACT H rather than at 0
let hvint = match (self.nmitimen >> 4) & 0x03 {
// Disabled
0 => false,
// H=H + V=*
1 => self.ppu.get_current_scanline() != self.last_scanline,
// H=0, V=V (2) + H=H, V=V (3)
2 | 3 => {
self.ppu.get_current_scanline() != self.last_scanline
&& self.ppu.get_current_scanline() == usize::from(self.vtime)
}
_ => unreachable!(),
};
self.last_scanline = self.ppu.get_current_scanline();
if hvint {
self.intreq_int = true;
self.timeup.set(true);
}
_ => unreachable!(),
};
self.last_scanline = self.ppu.get_current_scanline();
if hvint {
self.intreq_int = true;
self.timeup.set(true);
}

Ok(())
Expand Down

0 comments on commit af77f92

Please sign in to comment.