Skip to content

Commit

Permalink
Fixed a bug that caused interrupts to not be called
Browse files Browse the repository at this point in the history
  • Loading branch information
velllu committed Feb 24, 2024
1 parent 0826e43 commit 07e6dc2
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 17 deletions.
23 changes: 12 additions & 11 deletions src/interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,28 @@ pub enum Interrupt {
}

impl GameBoy {
// TODO: Make this actually good
pub(crate) fn execute_interrupts(&mut self) {
if !self.flags.ime {
return;
}

let stat = self.bus[STAT];
if stat.get_bit(6) && self.bus[LYC] == self.bus[LY] {
self.execute_interrupt(Interrupt::Stat);
}
}

fn execute_interrupt(&mut self, interrupt: Interrupt) {
// We don't want to call the same interrupt twice
if let Some(previous_interrupt) = &self.previous_interrupt {
if *previous_interrupt == interrupt {
return;
let is_lcd_enabled = stat.get_bit(6) && self.bus[LYC] == self.bus[LY];

// All this thing is done because an interrupt can only be triggered if it was
// previously off
if let Some(is_previous_lcd_enabled) = self.previous_lcd {
if is_lcd_enabled && !is_previous_lcd_enabled {
self.execute_interrupt(Interrupt::Stat);
}
}

self.previous_lcd = Some(is_lcd_enabled);
}

fn execute_interrupt(&mut self, interrupt: Interrupt) {
// The bit corresponding to the correct interrupt, both in Interrupt Enable, and
// Interrupt Flag bytes
let if_bit: u8 = match interrupt {
Expand All @@ -56,7 +59,5 @@ impl GameBoy {
let mut input_flags = self.bus[IF];
input_flags.set_bit(if_bit, false);
self.bus[IF] = input_flags;

self.previous_interrupt = Some(interrupt);
}
}
11 changes: 5 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use common::merge_two_u8s_into_u16;
use consts::bus::ROM_SIZE;
use flags::Flags;
use gpu::states::Gpu;
use interrupts::Interrupt;
use registers::Registers;

mod bus;
Expand All @@ -26,9 +25,9 @@ pub struct GameBoy {
pub flags: Flags,
pub gpu: Gpu,

/// This is needed because we cannot fire the same interrupt twice in a row, so we
/// have to keep track of the last one
previous_interrupt: Option<Interrupt>,
// TODO: Remove this, to make the code better. Check `interrupts.rs` for more
// information on why this is needed
previous_lcd: Option<bool>,
}

impl GameBoy {
Expand All @@ -38,7 +37,7 @@ impl GameBoy {
registers: Registers::new(),
flags: Flags::new(),
gpu: Gpu::new(),
previous_interrupt: None,
previous_lcd: None,
})
}

Expand All @@ -48,7 +47,7 @@ impl GameBoy {
registers: Registers::new(),
flags: Flags::new(),
gpu: Gpu::new(),
previous_interrupt: None,
previous_lcd: None,
}
}

Expand Down

0 comments on commit 07e6dc2

Please sign in to comment.