wow! ding!
This commit is contained in:
parent
37be5599d2
commit
2a5d8b816c
|
@ -101,6 +101,7 @@ where
|
|||
serial: Serial,
|
||||
timers: Timer,
|
||||
camera: CameraWrapperRef<C>,
|
||||
is_cgb: bool,
|
||||
}
|
||||
|
||||
#[serde_with::serde_as]
|
||||
|
@ -124,6 +125,7 @@ where
|
|||
apu: ApuSaveState,
|
||||
serial: SerialSaveState,
|
||||
timers: Timer,
|
||||
is_cgb: bool,
|
||||
}
|
||||
|
||||
impl<ColourFormat, R> MemorySaveState<ColourFormat, R>
|
||||
|
@ -147,6 +149,7 @@ where
|
|||
apu: ApuSaveState::create(&memory.apu),
|
||||
serial: SerialSaveState::create(&memory.serial),
|
||||
timers: memory.timers,
|
||||
is_cgb: memory.is_cgb,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -217,6 +220,7 @@ where
|
|||
serial: Serial::new(output.serial_target),
|
||||
timers: Timer::init(),
|
||||
camera: output.camera,
|
||||
is_cgb: cgb,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,11 +244,19 @@ where
|
|||
Address::Rom(address) => {
|
||||
// rom access
|
||||
// todo - switchable rom banks
|
||||
if let Some(bootrom) = &self.bootrom && (address.inner() as usize) < bootrom.len() {
|
||||
bootrom[address.inner() as usize]
|
||||
} else {
|
||||
self.rom.get(address)
|
||||
if let Some(bootrom) = &self.bootrom {
|
||||
if self.is_cgb {
|
||||
if address.inner() < 0x100
|
||||
|| (address.inner() >= 0x200
|
||||
&& ((address.inner()) as usize) < bootrom.len())
|
||||
{
|
||||
return bootrom[address.inner() as usize];
|
||||
}
|
||||
} else if (address.inner() as usize) < bootrom.len() {
|
||||
return bootrom[address.inner() as usize];
|
||||
}
|
||||
}
|
||||
self.rom.get(address)
|
||||
}
|
||||
Address::Vram(address) => self.gpu.get_vram(address),
|
||||
Address::CartRam(address) => self.rom.get_ram(address),
|
||||
|
@ -344,7 +356,7 @@ where
|
|||
CgbIoAddress::VramDma(_) => todo!(),
|
||||
CgbIoAddress::Infrared => todo!(),
|
||||
CgbIoAddress::Palette(address) => self.gpu.get_cgb_palette(address),
|
||||
CgbIoAddress::ObjPriority => todo!(),
|
||||
CgbIoAddress::ObjPriority => self.gpu.get_obj_priority(),
|
||||
CgbIoAddress::WramBank => ((*selected) & 0b111) as u8,
|
||||
CgbIoAddress::Pcm12 => todo!(),
|
||||
CgbIoAddress::Pcm34 => todo!(),
|
||||
|
@ -362,6 +374,7 @@ where
|
|||
}
|
||||
|
||||
fn set_io(&mut self, address: IoAddress, data: u8) {
|
||||
// println!("set 0x{:0>4X} to 0x{:0>2X}", address.inner(), data);
|
||||
match address {
|
||||
IoAddress::Joypad => self.joypad.mmio_write(data),
|
||||
IoAddress::Serial(address) => match address.inner() {
|
||||
|
@ -404,7 +417,7 @@ where
|
|||
CgbIoAddress::VramDma(_) => todo!(),
|
||||
CgbIoAddress::Infrared => todo!(),
|
||||
CgbIoAddress::Palette(address) => self.gpu.set_cgb_palette(address, data),
|
||||
CgbIoAddress::ObjPriority => todo!(),
|
||||
CgbIoAddress::ObjPriority => self.gpu.set_obj_priority(data),
|
||||
CgbIoAddress::WramBank => *selected = (data & 0b111).max(1) as usize,
|
||||
CgbIoAddress::Pcm12 => todo!(),
|
||||
CgbIoAddress::Pcm34 => todo!(),
|
||||
|
@ -485,6 +498,7 @@ where
|
|||
serial: Serial::from_save_state(state.serial, serial_target),
|
||||
timers: state.timers,
|
||||
camera,
|
||||
is_cgb: state.is_cgb,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -522,14 +536,14 @@ where
|
|||
|
||||
let gpu_interrupts = self.memory.gpu.tick(steps);
|
||||
|
||||
self.memory
|
||||
.interrupts
|
||||
.set_interrupt(Interrupt::Vblank, gpu_interrupts.vblank);
|
||||
self.memory
|
||||
.interrupts
|
||||
.set_interrupt(Interrupt::LcdStat, gpu_interrupts.lcd_stat);
|
||||
|
||||
if gpu_interrupts.vblank {
|
||||
self.memory
|
||||
.interrupts
|
||||
.set_interrupt(Interrupt::Vblank, true);
|
||||
let latest_state = self.memory.gpu.window.latest_joypad_state();
|
||||
let joypad_interrupt = self.memory.update_pressed_keys(latest_state);
|
||||
self.memory
|
||||
|
|
|
@ -26,11 +26,13 @@ pub(crate) type VideoAddress = BoundedAddress<0xFF40, 0xFF4C>;
|
|||
pub(crate) type VramDmaAddress = BoundedAddress<0xFF51, 0xFF56>;
|
||||
pub(crate) type CgbPaletteAddress = BoundedAddress<0xFF68, 0xFF6C>;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum RomAddress {
|
||||
Bank0(Bank0Address),
|
||||
MappedBank(MappedBankAddress),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum IoAddress {
|
||||
Joypad,
|
||||
Serial(SerialAddress),
|
||||
|
@ -43,6 +45,7 @@ pub(crate) enum IoAddress {
|
|||
Unused(u16),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum CgbIoAddress {
|
||||
PrepareSpeed,
|
||||
VramBank,
|
||||
|
@ -56,6 +59,7 @@ pub(crate) enum CgbIoAddress {
|
|||
Unused(u16),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum Address {
|
||||
Rom(RomAddress),
|
||||
Vram(VramAddress),
|
||||
|
|
|
@ -8,9 +8,25 @@ use crate::{
|
|||
|
||||
use super::{Colour, Gpu};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Default)]
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
pub(super) struct CgbData {
|
||||
palettes: CgbPaletteRegisters,
|
||||
object_priority_mode: ObjectPriorityMode,
|
||||
}
|
||||
|
||||
impl Default for CgbData {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
palettes: Default::default(),
|
||||
object_priority_mode: ObjectPriorityMode::Coordinate,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy)]
|
||||
enum ObjectPriorityMode {
|
||||
OamLocation = 0,
|
||||
Coordinate = 1,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Default)]
|
||||
|
@ -50,6 +66,9 @@ impl CgbPalette {
|
|||
|
||||
fn set_data(&mut self, data: u8) {
|
||||
self.data[self.index as usize] = data;
|
||||
if self.auto_increment {
|
||||
self.index = (self.index + 1) & 0b111111
|
||||
}
|
||||
}
|
||||
|
||||
fn get_data(&self) -> u8 {
|
||||
|
@ -87,4 +106,22 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_obj_priority(&self) -> u8 {
|
||||
if let Some(cgb_data) = &self.cgb_data {
|
||||
cgb_data.object_priority_mode as u8
|
||||
} else {
|
||||
0xFF
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_obj_priority(&mut self, data: u8) {
|
||||
if let Some(cgb_data) = &mut self.cgb_data {
|
||||
cgb_data.object_priority_mode = if data & 0b1 == 0 {
|
||||
ObjectPriorityMode::OamLocation
|
||||
} else {
|
||||
ObjectPriorityMode::Coordinate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue