cpu gets interrupts from struct rather than accessing memory directly
This commit is contained in:
parent
710912d150
commit
b95ab33ec9
|
@ -1,14 +1,11 @@
|
||||||
|
use self::mmio::{Apu, Gpu, Joypad, Serial, Timer};
|
||||||
pub use self::rom::Rom;
|
pub use self::rom::Rom;
|
||||||
use self::{
|
|
||||||
interrupts::Interrupt,
|
|
||||||
mmio::{Apu, Gpu, Joypad, Serial, Timer},
|
|
||||||
};
|
|
||||||
use crate::{processor::SplitRegister, verbose_println, Cpu};
|
use crate::{processor::SplitRegister, verbose_println, Cpu};
|
||||||
use gilrs::Gilrs;
|
use gilrs::Gilrs;
|
||||||
use minifb::{Key, Window};
|
use minifb::{Key, Window};
|
||||||
|
|
||||||
mod interrupts;
|
mod interrupts;
|
||||||
pub use interrupts::Interrupts;
|
pub use interrupts::{Interrupt, Interrupts};
|
||||||
pub mod mmio;
|
pub mod mmio;
|
||||||
pub(crate) mod rom;
|
pub(crate) mod rom;
|
||||||
|
|
||||||
|
@ -21,7 +18,7 @@ pub struct Memory {
|
||||||
ram: [u8; 8192],
|
ram: [u8; 8192],
|
||||||
switchable_ram: [u8; 8192],
|
switchable_ram: [u8; 8192],
|
||||||
cpu_ram: [u8; 128],
|
cpu_ram: [u8; 128],
|
||||||
interrupts: Interrupts,
|
pub(super) interrupts: Interrupts,
|
||||||
pub(super) ime: bool,
|
pub(super) ime: bool,
|
||||||
pub(super) ime_scheduled: u8,
|
pub(super) ime_scheduled: u8,
|
||||||
dma_addr: u8,
|
dma_addr: u8,
|
||||||
|
|
|
@ -74,4 +74,25 @@ impl Interrupts {
|
||||||
Interrupt::Joypad => self.flag_register.joypad = status,
|
Interrupt::Joypad => self.flag_register.joypad = status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_next_interrupt(&mut self) -> Option<Interrupt> {
|
||||||
|
if self.enable_register.vblank && self.flag_register.vblank {
|
||||||
|
self.flag_register.vblank = false;
|
||||||
|
Some(Interrupt::Vblank)
|
||||||
|
} else if self.enable_register.lcd_stat && self.flag_register.lcd_stat {
|
||||||
|
self.flag_register.lcd_stat = false;
|
||||||
|
Some(Interrupt::LcdStat)
|
||||||
|
} else if self.enable_register.timer && self.flag_register.timer {
|
||||||
|
self.flag_register.timer = false;
|
||||||
|
Some(Interrupt::Timer)
|
||||||
|
} else if self.enable_register.serial && self.flag_register.serial {
|
||||||
|
self.flag_register.serial = false;
|
||||||
|
Some(Interrupt::Serial)
|
||||||
|
} else if self.enable_register.joypad && self.flag_register.joypad {
|
||||||
|
self.flag_register.joypad = false;
|
||||||
|
Some(Interrupt::Joypad)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
use std::time::Instant;
|
use self::memory::{Interrupt, Memory};
|
||||||
|
use crate::verbose_println;
|
||||||
use self::memory::Memory;
|
|
||||||
use crate::{
|
|
||||||
util::{clear_bit, get_bit},
|
|
||||||
verbose_println,
|
|
||||||
};
|
|
||||||
use gilrs::Gilrs;
|
use gilrs::Gilrs;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
mod instructions;
|
mod instructions;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
@ -88,37 +84,15 @@ impl Cpu {
|
||||||
|
|
||||||
fn handle_interrupts(&mut self) -> u8 {
|
fn handle_interrupts(&mut self) -> u8 {
|
||||||
if self.memory.ime || self.halted {
|
if self.memory.ime || self.halted {
|
||||||
let req_and_enabled = self.memory.get(0xFF0F) & self.memory.get(0xFFFF);
|
if let Some(interrupt) = self.memory.interrupts.get_next_interrupt() {
|
||||||
// all interrupts should last 5 cycles?
|
let interrupt_addr = match interrupt {
|
||||||
if get_bit(req_and_enabled, 0) {
|
Interrupt::Vblank => 0x40,
|
||||||
// vblank
|
Interrupt::LcdStat => 0x48,
|
||||||
self.service_interrupt(0x40);
|
Interrupt::Timer => 0x50,
|
||||||
self.memory
|
Interrupt::Serial => 0x58,
|
||||||
.set(0xFF0F, clear_bit(self.memory.get(0xFF0F), 0));
|
Interrupt::Joypad => 0x60,
|
||||||
5
|
};
|
||||||
} else if get_bit(req_and_enabled, 1) {
|
self.service_interrupt(interrupt_addr);
|
||||||
// lcd stat
|
|
||||||
self.service_interrupt(0x48);
|
|
||||||
self.memory
|
|
||||||
.set(0xFF0F, clear_bit(self.memory.get(0xFF0F), 1));
|
|
||||||
5
|
|
||||||
} else if get_bit(req_and_enabled, 2) {
|
|
||||||
// timer
|
|
||||||
self.service_interrupt(0x50);
|
|
||||||
self.memory
|
|
||||||
.set(0xFF0F, clear_bit(self.memory.get(0xFF0F), 2));
|
|
||||||
5
|
|
||||||
} else if get_bit(req_and_enabled, 3) {
|
|
||||||
// serial
|
|
||||||
self.service_interrupt(0x58);
|
|
||||||
self.memory
|
|
||||||
.set(0xFF0F, clear_bit(self.memory.get(0xFF0F), 3));
|
|
||||||
5
|
|
||||||
} else if get_bit(req_and_enabled, 4) {
|
|
||||||
// joypad
|
|
||||||
self.service_interrupt(0x60);
|
|
||||||
self.memory
|
|
||||||
.set(0xFF0F, clear_bit(self.memory.get(0xFF0F), 4));
|
|
||||||
5
|
5
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
|
|
Loading…
Reference in a new issue