interrupts work properly! and halt bug almost does
This commit is contained in:
parent
f0f194f5d2
commit
b574e1b1bf
|
@ -226,9 +226,9 @@ impl Cpu {
|
|||
self.memory.apu.div_apu_tick();
|
||||
}
|
||||
|
||||
self.memory
|
||||
.interrupts
|
||||
.set_interrupt(Interrupt::Timer, timer_return.timer_interrupt);
|
||||
if timer_return.timer_interrupt {
|
||||
self.memory.interrupts.set_interrupt(Interrupt::Timer, true);
|
||||
}
|
||||
|
||||
self.memory.apu.tick(steps);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::util::get_bit;
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Debug)]
|
||||
struct InterruptRegister {
|
||||
vblank: bool,
|
||||
lcd_stat: bool,
|
||||
|
@ -31,6 +31,7 @@ fn bool_to_shifted(input: bool, shift: u8) -> u8 {
|
|||
(if input { 1 } else { 0 }) << shift
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Interrupt {
|
||||
Vblank,
|
||||
LcdStat,
|
||||
|
@ -57,7 +58,7 @@ impl Interrupts {
|
|||
}
|
||||
|
||||
pub(super) fn get_flag_register(&self) -> u8 {
|
||||
self.flag_register.as_register()
|
||||
0b11100000 | self.flag_register.as_register()
|
||||
}
|
||||
|
||||
pub(super) fn set_flag_register(&mut self, data: u8) {
|
||||
|
@ -94,4 +95,12 @@ impl Interrupts {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_interrupt_queued(&self) -> bool {
|
||||
(self.enable_register.vblank && self.flag_register.vblank)
|
||||
|| (self.enable_register.lcd_stat && self.flag_register.lcd_stat)
|
||||
|| (self.enable_register.timer && self.flag_register.timer)
|
||||
|| (self.enable_register.serial && self.flag_register.serial)
|
||||
|| (self.enable_register.joypad && self.flag_register.joypad)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ pub struct Cpu {
|
|||
pub last_instruction: u8,
|
||||
last_instruction_addr: u16,
|
||||
halted: bool,
|
||||
should_halt_bug: bool,
|
||||
gamepad_handler: Gilrs,
|
||||
cycle_start: Instant,
|
||||
}
|
||||
|
@ -41,6 +42,7 @@ impl Cpu {
|
|||
last_instruction: 0x0,
|
||||
last_instruction_addr: 0x0,
|
||||
halted: false,
|
||||
should_halt_bug: false,
|
||||
gamepad_handler,
|
||||
cycle_start: Instant::now(),
|
||||
}
|
||||
|
@ -56,10 +58,6 @@ impl Cpu {
|
|||
return;
|
||||
}
|
||||
|
||||
self.last_instruction_addr = self.reg.pc;
|
||||
let opcode = self.next_opcode();
|
||||
self.last_instruction = opcode;
|
||||
|
||||
if self.memory.ime_scheduled > 0 {
|
||||
self.memory.ime_scheduled = self.memory.ime_scheduled.saturating_sub(1);
|
||||
if self.memory.ime_scheduled == 0 {
|
||||
|
@ -67,13 +65,20 @@ impl Cpu {
|
|||
}
|
||||
}
|
||||
|
||||
self.last_instruction_addr = self.reg.pc;
|
||||
let opcode = self.next_opcode();
|
||||
if self.should_halt_bug {
|
||||
self.reg.pc = self.reg.pc.wrapping_sub(0x1);
|
||||
self.should_halt_bug = false;
|
||||
}
|
||||
self.last_instruction = opcode;
|
||||
|
||||
verbose_println!(
|
||||
"exec {:#4X} from pc: {:#X}",
|
||||
opcode,
|
||||
self.last_instruction_addr
|
||||
);
|
||||
let cycles = self.run_opcode(opcode);
|
||||
self.increment_timers(cycles);
|
||||
self.run_and_increment_timers(opcode);
|
||||
}
|
||||
|
||||
fn next_opcode(&mut self) -> u8 {
|
||||
|
@ -82,8 +87,22 @@ impl Cpu {
|
|||
opcode
|
||||
}
|
||||
|
||||
fn run_and_increment_timers(&mut self, opcode: u8) {
|
||||
let cycles = self.run_opcode(opcode);
|
||||
self.increment_timers(cycles);
|
||||
}
|
||||
|
||||
fn halt(&mut self) {
|
||||
if !self.memory.ime && self.memory.interrupts.is_interrupt_queued() {
|
||||
// halt bug
|
||||
self.should_halt_bug = true;
|
||||
} else {
|
||||
self.halted = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_interrupts(&mut self) -> u8 {
|
||||
if self.memory.ime || self.halted {
|
||||
if self.memory.ime {
|
||||
if let Some(interrupt) = self.memory.interrupts.get_next_interrupt() {
|
||||
let interrupt_addr = match interrupt {
|
||||
Interrupt::Vblank => 0x40,
|
||||
|
@ -98,6 +117,9 @@ impl Cpu {
|
|||
0
|
||||
}
|
||||
} else {
|
||||
if self.halted && self.memory.interrupts.is_interrupt_queued() {
|
||||
self.halted = false;
|
||||
}
|
||||
0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -554,7 +554,7 @@ impl Cpu {
|
|||
2
|
||||
}
|
||||
0x76 => {
|
||||
self.halted = true;
|
||||
self.halt();
|
||||
1
|
||||
}
|
||||
0x77 => {
|
||||
|
|
Loading…
Reference in a new issue