ir + cleaning
This commit is contained in:
parent
9ff6196ecf
commit
fbae48596e
|
@ -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<ColourFormat, R, C>
|
||||
where
|
||||
ColourFormat: From<Colour> + Clone,
|
||||
|
@ -95,14 +101,13 @@ where
|
|||
pub(super) ime_scheduled: u8,
|
||||
pub(super) user_mode: bool,
|
||||
oam_dma: OamDma,
|
||||
vram_dma: Option<VramDma>,
|
||||
joypad: Joypad,
|
||||
gpu: Gpu<ColourFormat, R>,
|
||||
apu: Apu,
|
||||
serial: Serial,
|
||||
timers: Timer,
|
||||
camera: CameraWrapperRef<C>,
|
||||
is_cgb: bool,
|
||||
cgb_peripherals: Option<CgbPeripherals>,
|
||||
}
|
||||
|
||||
#[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<VramDma>,
|
||||
joypad: Joypad,
|
||||
gpu: GpuSaveState<ColourFormat, R>,
|
||||
apu: ApuSaveState,
|
||||
serial: SerialSaveState,
|
||||
timers: Timer,
|
||||
is_cgb: bool,
|
||||
cgb_peripherals: Option<CgbPeripherals>,
|
||||
}
|
||||
|
||||
impl<ColourFormat, R> MemorySaveState<ColourFormat, R>
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
20
lib/src/processor/memory/mmio/ir.rs
Normal file
20
lib/src/processor/memory/mmio/ir.rs
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue