Skip to content

Commit

Permalink
Fix SPC700 clock ratio (kind of..)
Browse files Browse the repository at this point in the history
  • Loading branch information
twvd committed Nov 27, 2023
1 parent 4e2746e commit b892d78
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 36 deletions.
8 changes: 4 additions & 4 deletions src/snes/apu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ pub struct Apu {
}

impl Apu {
/// One SPC cycle = 25 master cycles
const SPC_MASTER_FACTOR: Ticks = 1;
/// One SPC cycle = 3 master cycles
const SPC_MASTER_FACTOR: Ticks = 3;

const IPL_ENTRYPOINT: SpcAddress = 0xFFC0;
const IPL_SIZE: usize = 64;
Expand Down Expand Up @@ -81,13 +81,13 @@ impl Apu {

impl Tickable for Apu {
fn tick(&mut self, ticks: Ticks) -> Result<()> {
// Step the SPC700 every 25 master clock ticks
// Step the SPC700 every 3 CPU clock ticks
// and wait for every SPC cycle consumed so they
// run somewhat in sync.
self.spc_master_credit += ticks;

while self.spc_master_credit >= Self::SPC_MASTER_FACTOR {
if true || self.spc_cycles_taken == 0 {
if self.spc_cycles_taken == 0 {
if self.verbose && self.cpu.regs.read(Register::PC) < Self::IPL_ENTRYPOINT {
println!("{}", self.cpu.dump_state().red());
}
Expand Down
65 changes: 33 additions & 32 deletions src/snes/bus/mainbus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,46 +754,47 @@ where
TRenderer: Renderer,
{
fn tick(&mut self, ticks: Ticks) -> Result<()> {
// APU deals with its own stuff
self.apu.tick(ticks)?;

// This ratio is not based on anything that makes sense yet
for _ in 0..(ticks * 8) {
self.ppu.tick(1)?;
// The PPU is supposed to run at 5.3/5.6 MHz dot clock
// for a 3.5 MHz CPU.
// TODO this is not right
self.ppu.tick(8)?;

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();
}

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

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

// 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);
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)
}
_ => 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 b892d78

Please sign in to comment.