diff --git a/src/cpu/mode.rs b/src/cpu/mode.rs index 3397d76..27d34fe 100644 --- a/src/cpu/mode.rs +++ b/src/cpu/mode.rs @@ -1,8 +1,9 @@ //! Selects the memory behavior of the [super::CPU] //! -//! Since [super::Quirks] implements [From], +//! Since [Quirks] implements [`From`], //! this can be used to select the appropriate quirk-set +use super::Quirks; use crate::error::Error; use std::str::FromStr; @@ -12,7 +13,7 @@ pub enum Mode { /// VIP emulation mode #[default] Chip8, - /// Chip-48 emulation mode + /// Super Chip emulation mode SChip, /// XO-Chip emulation mode XOChip, @@ -32,3 +33,20 @@ impl FromStr for Mode { } } } + +impl From 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, + }, + } + } +} diff --git a/src/cpu/quirks.rs b/src/cpu/quirks.rs index 4f2e283..9d04387 100644 --- a/src/cpu/quirks.rs +++ b/src/cpu/quirks.rs @@ -1,17 +1,21 @@ //! 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)] 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, - /// 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, - /// 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, - /// 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, - /// 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, } @@ -22,6 +26,7 @@ impl From for Quirks { bin_ops: true, shift: true, draw_wait: true, + screen_wrap: false, dma_inc: true, stupid_jumps: true, } @@ -30,6 +35,7 @@ impl From for Quirks { bin_ops: false, shift: false, draw_wait: false, + screen_wrap: false, dma_inc: false, stupid_jumps: false, } @@ -37,22 +43,6 @@ impl From for Quirks { } } -impl From 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 { fn default() -> Self { Self::from(false) diff --git a/src/cpu/tests.rs b/src/cpu/tests.rs index 45f2163..2bde028 100644 --- a/src/cpu/tests.rs +++ b/src/cpu/tests.rs @@ -13,7 +13,7 @@ //! Some of these tests run >16M times, which is very silly use super::*; -pub(self) use crate::{ +use crate::{ bus, bus::{Bus, Region::*}, }; @@ -674,9 +674,9 @@ mod i { /// - Random number generation /// - Drawing to the display mod io { + use super::*; use std::io::Write; - use super::*; /// Cxbb: Stores a random number & the provided byte into vX #[test] fn rand() { @@ -712,6 +712,7 @@ mod io { bin_ops: false, shift: false, draw_wait: false, + screen_wrap: true, dma_inc: false, stupid_jumps: false, }, @@ -727,6 +728,7 @@ mod io { bin_ops: false, shift: false, draw_wait: true, + screen_wrap: true, dma_inc: false, stupid_jumps: false, }, @@ -740,6 +742,7 @@ mod io { bin_ops: false, shift: false, draw_wait: true, + screen_wrap: true, dma_inc: false, stupid_jumps: false, }, diff --git a/tests/integration.rs b/tests/integration.rs index e8b7248..bae07db 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -226,6 +226,7 @@ mod quirks { bin_ops: true, shift: true, draw_wait: true, + screen_wrap: false, dma_inc: true, stupid_jumps: true, } @@ -241,6 +242,7 @@ mod quirks { bin_ops: false, shift: false, draw_wait: false, + screen_wrap: false, dma_inc: false, stupid_jumps: false, } @@ -253,6 +255,7 @@ mod quirks { bin_ops: false, shift: true, draw_wait: false, + screen_wrap: false, dma_inc: true, stupid_jumps: false, };