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