fix: convert structs to bitfield structs in interrupt.rs

This commit is contained in:
Rekai Nyangadzayi Musuka 2021-03-15 21:59:53 -05:00
parent 602a0af4b7
commit 84babc4d69
1 changed files with 123 additions and 39 deletions

View File

@ -1,67 +1,151 @@
use bitfield::bitfield;
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone, Copy, Default)]
pub struct Interrupt { pub struct Interrupt {
pub flag: InterruptFlag, pub flag: InterruptFlag,
pub enable: InterruptEnable, pub enable: InterruptEnable,
} }
#[derive(Debug, Clone, Copy, Default)] bitfield! {
pub struct InterruptEnable { pub struct InterruptEnable(u8);
vblank: bool, impl Debug;
lcd_stat: bool, _vblank, _set_vblank: 0;
timer: bool, _lcd_stat, _set_lcd_stat: 1;
serial: bool, _timer, _set_timer: 2;
joypad: bool, _serial, _set_serial: 3;
_joypad, _set_joypad: 4;
} }
// TODO: Is this the correct behaviour? (I think not)
impl InterruptEnable {
pub fn vblank(&self) -> bool {
self._vblank()
}
pub fn lcd_stat(&self) -> bool {
self._lcd_stat()
}
pub fn timer(&self) -> bool {
self._timer()
}
pub fn serial(&self) -> bool {
self._serial()
}
pub fn joypad(&self) -> bool {
self._joypad()
}
pub fn set_vblank(&self, flag: &mut InterruptFlag, value: bool) {
let prev = self._vblank();
if prev == false && value {
flag.set_vblank(true);
}
flag.set_vblank(value)
}
pub fn set_lcd_stat(&self, flag: &mut InterruptFlag, value: bool) {
let prev = self._lcd_stat();
if prev == false && value {
flag.set_lcd_stat(true);
}
flag.set_lcd_stat(value)
}
pub fn set_timer(&self, flag: &mut InterruptFlag, value: bool) {
let prev = self._timer();
if prev == false && value {
flag.set_timer(true);
}
flag.set_timer(value)
}
pub fn set_serial(&self, flag: &mut InterruptFlag, value: bool) {
let prev = self._serial();
if prev == false && value {
flag.set_serial(true);
}
flag.set_serial(value)
}
pub fn set_joypad(&self, flag: &mut InterruptFlag, value: bool) {
let prev = self._joypad();
if prev == false && value {
flag.set_joypad(true);
}
flag.set_joypad(value)
}
}
impl Copy for InterruptEnable {}
impl Clone for InterruptEnable {
fn clone(&self) -> Self {
*self
}
}
impl Default for InterruptEnable {
fn default() -> Self {
Self(0)
}
}
impl From<u8> for InterruptEnable { impl From<u8> for InterruptEnable {
fn from(byte: u8) -> Self { fn from(byte: u8) -> Self {
Self { Self(byte)
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<InterruptEnable> for u8 { impl From<InterruptEnable> for u8 {
fn from(flag: InterruptEnable) -> Self { fn from(enable: InterruptEnable) -> Self {
(flag.joypad as u8) << 4 enable.0
| (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)] bitfield! {
pub struct InterruptFlag { pub struct InterruptFlag(u8);
vblank: bool, impl Debug;
lcd_stat: bool, pub vblank, set_vblank: 0;
timer: bool, pub lcd_stat, set_lcd_stat: 1;
serial: bool, pub timer, set_timer: 2;
joypad: bool, pub serial, set_serial: 3;
pub joypad, set_joypad: 4;
}
impl Copy for InterruptFlag {}
impl Clone for InterruptFlag {
fn clone(&self) -> Self {
*self
}
}
impl Default for InterruptFlag {
fn default() -> Self {
Self(0)
}
} }
impl From<u8> for InterruptFlag { impl From<u8> for InterruptFlag {
fn from(byte: u8) -> Self { fn from(byte: u8) -> Self {
Self { Self(byte)
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<InterruptFlag> for u8 { impl From<InterruptFlag> for u8 {
fn from(flag: InterruptFlag) -> Self { fn from(flag: InterruptFlag) -> Self {
(flag.joypad as u8) << 4 flag.0
| (flag.serial as u8) << 3
| (flag.timer as u8) << 2
| (flag.lcd_stat as u8) << 1
| (flag.vblank as u8) << 0
} }
} }