quirks.rs: Prepare screen_wrap quirk for future xochip compat

This commit is contained in:
John 2023-04-17 05:09:16 -05:00
parent bafb576705
commit 7d25a9f5f1
4 changed files with 41 additions and 27 deletions

View File

@ -1,8 +1,9 @@
//! Selects the memory behavior of the [super::CPU] //! Selects the memory behavior of the [super::CPU]
//! //!
//! Since [super::Quirks] implements [From<Mode>], //! Since [Quirks] implements [`From<Mode>`],
//! this can be used to select the appropriate quirk-set //! this can be used to select the appropriate quirk-set
use super::Quirks;
use crate::error::Error; use crate::error::Error;
use std::str::FromStr; use std::str::FromStr;
@ -12,7 +13,7 @@ pub enum Mode {
/// VIP emulation mode /// VIP emulation mode
#[default] #[default]
Chip8, Chip8,
/// Chip-48 emulation mode /// Super Chip emulation mode
SChip, SChip,
/// XO-Chip emulation mode /// XO-Chip emulation mode
XOChip, XOChip,
@ -32,3 +33,20 @@ impl FromStr for Mode {
} }
} }
} }
impl From<Mode> for Quirks {
fn from(value: Mode) -> Self {
match value {
Mode::Chip8 => false.into(),
Mode::SChip => true.into(),
Mode::XOChip => Self {
bin_ops: true,
shift: false,
draw_wait: true,
screen_wrap: true,
dma_inc: false,
stupid_jumps: false,
},
}
}
}

View File

@ -1,17 +1,21 @@
//! Controls the [Quirks] behavior of the CPU on a granular level. //! Controls the [Quirks] behavior of the CPU on a granular level.
use super::Mode;
/// Controls the authenticity behavior of the CPU on a granular level. /// Controls the quirk behavior of the CPU on a granular level.
///
/// `false` is Cosmac-VIP-like behavior
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Quirks { pub struct Quirks {
/// Binary ops in `8xy`(`1`, `2`, `3`) shouldn't set vF to 0 /// Super Chip: Binary ops in `8xy`(`1`, `2`, `3`) shouldn't set vF to 0
pub bin_ops: bool, pub bin_ops: bool,
/// Shift ops in `8xy`(`6`, `E`) shouldn't source from vY instead of vX /// Super Chip: Shift ops in `8xy`(`6`, `E`) shouldn't source from vY instead of vX
pub shift: bool, pub shift: bool,
/// Draw operations shouldn't pause execution until the next timer tick /// Super Chip: Draw operations shouldn't pause execution until the next timer tick
pub draw_wait: bool, pub draw_wait: bool,
/// DMA instructions `Fx55`/`Fx65` shouldn't change I to I + x + 1 /// XO-Chip: Draw operations shouldn't wrap from the bottom of the screen to the top
pub screen_wrap: bool,
/// Super Chip: DMA instructions `Fx55`/`Fx65` shouldn't change I to I + x + 1
pub dma_inc: bool, pub dma_inc: bool,
/// Indexed jump instructions should go to `adr` + v`a` where `a` is high nibble of `adr`. /// Super Chip: Indexed jump instructions should go to `adr` + v`a` where `a` is high nibble of `adr`.
pub stupid_jumps: bool, pub stupid_jumps: bool,
} }
@ -22,6 +26,7 @@ impl From<bool> for Quirks {
bin_ops: true, bin_ops: true,
shift: true, shift: true,
draw_wait: true, draw_wait: true,
screen_wrap: false,
dma_inc: true, dma_inc: true,
stupid_jumps: true, stupid_jumps: true,
} }
@ -30,6 +35,7 @@ impl From<bool> for Quirks {
bin_ops: false, bin_ops: false,
shift: false, shift: false,
draw_wait: false, draw_wait: false,
screen_wrap: false,
dma_inc: false, dma_inc: false,
stupid_jumps: false, stupid_jumps: false,
} }
@ -37,22 +43,6 @@ impl From<bool> for Quirks {
} }
} }
impl From<Mode> for Quirks {
fn from(value: Mode) -> Self {
match value {
Mode::Chip8 => false.into(),
Mode::SChip => true.into(),
Mode::XOChip => Self {
bin_ops: true,
shift: false,
draw_wait: true,
dma_inc: false,
stupid_jumps: false,
},
}
}
}
impl Default for Quirks { impl Default for Quirks {
fn default() -> Self { fn default() -> Self {
Self::from(false) Self::from(false)

View File

@ -13,7 +13,7 @@
//! Some of these tests run >16M times, which is very silly //! Some of these tests run >16M times, which is very silly
use super::*; use super::*;
pub(self) use crate::{ use crate::{
bus, bus,
bus::{Bus, Region::*}, bus::{Bus, Region::*},
}; };
@ -674,9 +674,9 @@ mod i {
/// - Random number generation /// - Random number generation
/// - Drawing to the display /// - Drawing to the display
mod io { mod io {
use super::*;
use std::io::Write; use std::io::Write;
use super::*;
/// Cxbb: Stores a random number & the provided byte into vX /// Cxbb: Stores a random number & the provided byte into vX
#[test] #[test]
fn rand() { fn rand() {
@ -712,6 +712,7 @@ mod io {
bin_ops: false, bin_ops: false,
shift: false, shift: false,
draw_wait: false, draw_wait: false,
screen_wrap: true,
dma_inc: false, dma_inc: false,
stupid_jumps: false, stupid_jumps: false,
}, },
@ -727,6 +728,7 @@ mod io {
bin_ops: false, bin_ops: false,
shift: false, shift: false,
draw_wait: true, draw_wait: true,
screen_wrap: true,
dma_inc: false, dma_inc: false,
stupid_jumps: false, stupid_jumps: false,
}, },
@ -740,6 +742,7 @@ mod io {
bin_ops: false, bin_ops: false,
shift: false, shift: false,
draw_wait: true, draw_wait: true,
screen_wrap: true,
dma_inc: false, dma_inc: false,
stupid_jumps: false, stupid_jumps: false,
}, },

View File

@ -226,6 +226,7 @@ mod quirks {
bin_ops: true, bin_ops: true,
shift: true, shift: true,
draw_wait: true, draw_wait: true,
screen_wrap: false,
dma_inc: true, dma_inc: true,
stupid_jumps: true, stupid_jumps: true,
} }
@ -241,6 +242,7 @@ mod quirks {
bin_ops: false, bin_ops: false,
shift: false, shift: false,
draw_wait: false, draw_wait: false,
screen_wrap: false,
dma_inc: false, dma_inc: false,
stupid_jumps: false, stupid_jumps: false,
} }
@ -253,6 +255,7 @@ mod quirks {
bin_ops: false, bin_ops: false,
shift: true, shift: true,
draw_wait: false, draw_wait: false,
screen_wrap: false,
dma_inc: true, dma_inc: true,
stupid_jumps: false, stupid_jumps: false,
}; };