From 84babc4d69207a23a2db2cd700257d4c31a06056 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Mon, 15 Mar 2021 21:59:53 -0500 Subject: [PATCH] fix: convert structs to bitfield structs in interrupt.rs --- src/interrupt.rs | 162 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 123 insertions(+), 39 deletions(-) diff --git a/src/interrupt.rs b/src/interrupt.rs index 4e97bcc..e4d7362 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -1,67 +1,151 @@ +use bitfield::bitfield; + #[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, +bitfield! { + pub struct InterruptEnable(u8); + impl Debug; + _vblank, _set_vblank: 0; + _lcd_stat, _set_lcd_stat: 1; + _timer, _set_timer: 2; + _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 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, - } + Self(byte) } } 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 + fn from(enable: InterruptEnable) -> Self { + enable.0 } } -#[derive(Debug, Clone, Copy, Default)] -pub struct InterruptFlag { - vblank: bool, - lcd_stat: bool, - timer: bool, - serial: bool, - joypad: bool, +bitfield! { + pub struct InterruptFlag(u8); + impl Debug; + pub vblank, set_vblank: 0; + pub lcd_stat, set_lcd_stat: 1; + pub timer, set_timer: 2; + 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 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, - } + Self(byte) } } 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 + flag.0 } }