diff --git a/src/bus.rs b/src/bus.rs index ffba980..6d58d21 100644 --- a/src/bus.rs +++ b/src/bus.rs @@ -1,7 +1,9 @@ use super::cartridge::Cartridge; +use super::interrupt::Interrupt; use super::ppu::PPU; use super::timer::Timer; use super::work_ram::{VariableWorkRAM, WorkRAM}; + #[derive(Debug, Clone)] pub struct Bus { boot: Option<[u8; 256]>, // Boot ROM is 256b long @@ -10,6 +12,7 @@ pub struct Bus { wram: WorkRAM, vwram: VariableWorkRAM, timer: Timer, + interrupt: Interrupt, } impl Default for Bus { @@ -21,6 +24,7 @@ impl Default for Bus { wram: Default::default(), vwram: Default::default(), timer: Default::default(), + interrupt: Default::default(), } } } @@ -91,6 +95,7 @@ impl Bus { // IO Registers match addr { 0xFF07 => self.timer.control.into(), + 0xFF0F => self.interrupt.flag.into(), _ => unimplemented!("Unable to read {:#06X} in I/O Registers", addr), } } @@ -100,7 +105,7 @@ impl Bus { } 0xFFFF => { // Interupts Enable Register - unimplemented!("Unable to read IE Register {:#06X} ", addr); + self.interrupt.enable.into() } } } @@ -147,6 +152,7 @@ impl Bus { // IO Registers match addr { 0xFF07 => self.timer.control = byte.into(), + 0xFF0F => self.interrupt.flag = byte.into(), _ => unimplemented!("Unable to write to {:#06X} in I/O Registers", addr), }; } @@ -156,7 +162,7 @@ impl Bus { } 0xFFFF => { // Interupts Enable Register - unimplemented!("Unable to write to IE Register {:#06X} ", addr); + self.interrupt.enable = byte.into(); } } } diff --git a/src/interrupt.rs b/src/interrupt.rs new file mode 100644 index 0000000..4e97bcc --- /dev/null +++ b/src/interrupt.rs @@ -0,0 +1,74 @@ +#[derive(Debug, Clone, Copy, Default)] +pub struct Interrupt { + pub flag: InterruptFlag, + pub enable: InterruptEnable, +} + +#[derive(Debug, Clone, Copy, Default)] +pub struct InterruptEnable { + vblank: bool, + lcd_stat: bool, + timer: bool, + serial: bool, + joypad: bool, +} +impl From for InterruptEnable { + fn from(byte: u8) -> Self { + Self { + vblank: (byte >> 0 & 0x01) == 0x01, + lcd_stat: (byte >> 1 & 0x01) == 0x01, + timer: (byte >> 2 & 0x01) == 0x01, + serial: (byte >> 3 & 0x01) == 0x01, + joypad: (byte >> 4 & 0x01) == 0x01, + } + } +} + +impl From for u8 { + fn from(flag: InterruptEnable) -> Self { + (flag.joypad as u8) << 4 + | (flag.serial as u8) << 3 + | (flag.timer as u8) << 2 + | (flag.lcd_stat as u8) << 1 + | (flag.vblank as u8) << 0 + } +} + +#[derive(Debug, Clone, Copy, Default)] +pub struct InterruptFlag { + vblank: bool, + lcd_stat: bool, + timer: bool, + serial: bool, + joypad: bool, +} + +impl From for InterruptFlag { + fn from(byte: u8) -> Self { + Self { + vblank: (byte >> 0 & 0x01) == 0x01, + lcd_stat: (byte >> 1 & 0x01) == 0x01, + timer: (byte >> 2 & 0x01) == 0x01, + serial: (byte >> 3 & 0x01) == 0x01, + joypad: (byte >> 4 & 0x01) == 0x01, + } + } +} + +impl From for u8 { + fn from(flag: InterruptFlag) -> Self { + (flag.joypad as u8) << 4 + | (flag.serial as u8) << 3 + | (flag.timer as u8) << 2 + | (flag.lcd_stat as u8) << 1 + | (flag.vblank as u8) << 0 + } +} + +enum InterruptType { + VBlank, + LCDStat, + Timer, + Serial, + Joypad, +} diff --git a/src/lib.rs b/src/lib.rs index 266f13d..e9d0efb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ mod bus; mod cartridge; pub mod cpu; mod instruction; +mod interrupt; mod ppu; mod timer; mod work_ram;