From fbae48596e8e973c1d0d2665ad7abbde0c3a5704 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Fri, 21 Apr 2023 10:38:51 +1000 Subject: [PATCH] ir + cleaning --- lib/src/processor/memory.rs | 41 +++++++++++++---------- lib/src/processor/memory/mmio/ir.rs | 20 +++++++++++ lib/src/processor/memory/mmio/mod.rs | 2 ++ lib/src/processor/memory/mmio/vram_dma.rs | 27 ++++++++------- 4 files changed, 59 insertions(+), 31 deletions(-) create mode 100644 lib/src/processor/memory/mmio/ir.rs diff --git a/lib/src/processor/memory.rs b/lib/src/processor/memory.rs index 3f477e6..21216ea 100644 --- a/lib/src/processor/memory.rs +++ b/lib/src/processor/memory.rs @@ -7,7 +7,7 @@ use self::{ apu::ApuSaveState, gpu::{Colour, GpuSaveState}, serial::SerialSaveState, - Apu, Gpu, Joypad, OamDma, Serial, Timer, VramDma, + Apu, Gpu, Infrared, Joypad, OamDma, Serial, Timer, VramDma, }, rom::RomSaveState, }; @@ -80,6 +80,12 @@ impl Wram { } } +#[derive(Clone, Copy, Serialize, Deserialize, Default)] +struct CgbPeripherals { + vram_dma: VramDma, + infrared: Infrared, +} + pub struct Memory where ColourFormat: From + Clone, @@ -95,14 +101,13 @@ where pub(super) ime_scheduled: u8, pub(super) user_mode: bool, oam_dma: OamDma, - vram_dma: Option, joypad: Joypad, gpu: Gpu, apu: Apu, serial: Serial, timers: Timer, camera: CameraWrapperRef, - is_cgb: bool, + cgb_peripherals: Option, } #[serde_with::serde_as] @@ -121,13 +126,12 @@ where pub(super) ime_scheduled: u8, pub(super) user_mode: bool, oam_dma: OamDma, - vram_dma: Option, joypad: Joypad, gpu: GpuSaveState, apu: ApuSaveState, serial: SerialSaveState, timers: Timer, - is_cgb: bool, + cgb_peripherals: Option, } impl MemorySaveState @@ -146,13 +150,12 @@ where ime_scheduled: memory.ime_scheduled, user_mode: memory.user_mode, oam_dma: memory.oam_dma, - vram_dma: memory.vram_dma, joypad: memory.joypad, gpu: GpuSaveState::create(&memory.gpu), apu: ApuSaveState::create(&memory.apu), serial: SerialSaveState::create(&memory.serial), timers: memory.timers, - is_cgb: memory.is_cgb, + cgb_peripherals: memory.cgb_peripherals, } } } @@ -217,14 +220,17 @@ where ime_scheduled: 0x0, user_mode: false, oam_dma: OamDma::default(), - vram_dma: if cgb { Some(VramDma::default()) } else { None }, joypad: Joypad::default(), gpu: Gpu::new(cgb, output.window, output.tile_window), apu: Apu::new(output.audio), serial: Serial::new(output.serial_target), timers: Timer::init(), camera: output.camera, - is_cgb: cgb, + cgb_peripherals: if cgb { + Some(CgbPeripherals::default()) + } else { + None + }, } } @@ -249,7 +255,7 @@ where // rom access // todo - switchable rom banks if let Some(bootrom) = &self.bootrom { - if self.is_cgb { + if self.cgb_peripherals.is_some() { if address.inner() < 0x100 || (address.inner() >= 0x200 && ((address.inner()) as usize) < bootrom.len()) @@ -353,12 +359,12 @@ where 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, IoAddress::Cgb(address) => { - if let WramBanks::Cgb { banks: _, selected } = &self.ram.banks && let Some(vram_dma) = &self.vram_dma { + if let WramBanks::Cgb { banks: _, selected } = &self.ram.banks && let Some(cgb_peripherals) = &self.cgb_peripherals { match address { CgbIoAddress::PrepareSpeed => todo!(), CgbIoAddress::VramBank => self.gpu.vram.get_vram_bank(), - CgbIoAddress::VramDma(address) => vram_dma.get_register(address), - CgbIoAddress::Infrared => todo!(), + CgbIoAddress::VramDma(address) => cgb_peripherals.vram_dma.get_register(address), + CgbIoAddress::Infrared => cgb_peripherals.infrared.get(), CgbIoAddress::Palette(address) => self.gpu.get_cgb_palette(address), CgbIoAddress::ObjPriority => self.gpu.get_obj_priority(), CgbIoAddress::WramBank => ((*selected) & 0b111) as u8, @@ -412,12 +418,12 @@ where 0x0..0xFF40 | 0xFF4C..=0xFFFF => unreachable!(), }, IoAddress::Cgb(address) => { - if let WramBanks::Cgb { banks: _, selected } = &mut self.ram.banks && let Some(vram_dma) = &mut self.vram_dma { + if let WramBanks::Cgb { banks: _, selected } = &mut self.ram.banks && let Some(cgb_peripherals) = &mut self.cgb_peripherals { match address { CgbIoAddress::PrepareSpeed => todo!(), CgbIoAddress::VramBank => self.gpu.vram.set_vram_bank(data), - CgbIoAddress::VramDma(address) => vram_dma.set_register(address, data), - CgbIoAddress::Infrared => todo!(), + CgbIoAddress::VramDma(address) => cgb_peripherals.vram_dma.set_register(address, data), + CgbIoAddress::Infrared => cgb_peripherals.infrared.set(data), CgbIoAddress::Palette(address) => self.gpu.set_cgb_palette(address, data), CgbIoAddress::ObjPriority => self.gpu.set_obj_priority(data), CgbIoAddress::WramBank => *selected = (data & 0b111).max(1) as usize, @@ -493,14 +499,13 @@ where ime_scheduled: state.ime_scheduled, user_mode: state.user_mode, oam_dma: state.oam_dma, - vram_dma: state.vram_dma, joypad: state.joypad, gpu: Gpu::from_save_state(state.gpu, window, None), apu: Apu::from_save_state(state.apu, output), serial: Serial::from_save_state(state.serial, serial_target), timers: state.timers, camera, - is_cgb: state.is_cgb, + cgb_peripherals: state.cgb_peripherals, } } } diff --git a/lib/src/processor/memory/mmio/ir.rs b/lib/src/processor/memory/mmio/ir.rs new file mode 100644 index 0000000..e1a92eb --- /dev/null +++ b/lib/src/processor/memory/mmio/ir.rs @@ -0,0 +1,20 @@ +use serde::{Deserialize, Serialize}; + +use crate::util::get_bit; + +#[derive(Default, Clone, Copy, Serialize, Deserialize)] +pub struct Infrared { + led: bool, + read_enable: bool, +} + +impl Infrared { + pub(crate) fn get(&self) -> u8 { + 0b111110 | if self.led { 1 } else { 0 } | if self.read_enable { 0b11 << 6 } else { 0 } + } + + pub(crate) fn set(&mut self, data: u8) { + self.led = get_bit(data, 0); + self.read_enable = get_bit(data, 6) && get_bit(data, 7); + } +} diff --git a/lib/src/processor/memory/mmio/mod.rs b/lib/src/processor/memory/mmio/mod.rs index d4500bd..439bdec 100644 --- a/lib/src/processor/memory/mmio/mod.rs +++ b/lib/src/processor/memory/mmio/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod apu; pub(crate) mod gpu; +mod ir; pub(crate) mod joypad; mod oam_dma; pub(crate) mod serial; @@ -7,6 +8,7 @@ mod timer; mod vram_dma; pub use apu::Apu; pub use gpu::Gpu; +pub use ir::Infrared; pub use joypad::Joypad; pub use oam_dma::OamDma; pub use serial::Serial; diff --git a/lib/src/processor/memory/mmio/vram_dma.rs b/lib/src/processor/memory/mmio/vram_dma.rs index b46a1e2..0bc5b99 100644 --- a/lib/src/processor/memory/mmio/vram_dma.rs +++ b/lib/src/processor/memory/mmio/vram_dma.rs @@ -69,12 +69,6 @@ impl VramDma { } else { DmaMode::Waiting }; - println!("vram dma - entered mode {:?}", self.mode); - println!( - " for transfer from 0x{:0>4X} to 0x{:0>4X}", - self.source, self.destination - ); - println!(" num bytes/lines: 0x{num:X}"); } _ => unreachable!(), } @@ -89,20 +83,28 @@ where { pub(crate) fn vram_dma_tick(&mut self) -> usize { let mut copy = None; - let returning = if let Some(vram_dma) = &mut self.vram_dma { - match vram_dma.mode { + let returning = if let Some(cgb_peripherals) = &mut self.cgb_peripherals { + match cgb_peripherals.vram_dma.mode { DmaMode::Halt(l) => { - copy = Some((vram_dma.destination, vram_dma.source, 16 * ((l as u16) + 1))); - vram_dma.mode = DmaMode::Waiting; + copy = Some(( + cgb_peripherals.vram_dma.destination, + cgb_peripherals.vram_dma.source, + 16 * ((l as u16) + 1), + )); + cgb_peripherals.vram_dma.mode = DmaMode::Waiting; ((l as usize) + 1) * 8 } DmaMode::Hblank(l, ref mut progress) => { if self.gpu.get_mode() == DrawMode::HBlank { let offset = *progress * 16; - copy = Some((vram_dma.destination + offset, vram_dma.source + offset, 16)); + copy = Some(( + cgb_peripherals.vram_dma.destination + offset, + cgb_peripherals.vram_dma.source + offset, + 16, + )); *progress += 1; if *progress > (l as u16) { - vram_dma.mode = DmaMode::Waiting + cgb_peripherals.vram_dma.mode = DmaMode::Waiting } 8 } else { @@ -115,7 +117,6 @@ where 0 }; if let Some((source, dest, length)) = copy { - println!("copying 0x{length:X} bytes from {source:0>4X} to {dest:0>4X}"); for i in 0..length { self.set(dest + i, self.get(source + i)); }