cpu: Change ST and DT back to u8

This commit is contained in:
John 2023-04-29 18:37:29 -05:00
parent 57c2ac681c
commit cb69af048f
3 changed files with 25 additions and 29 deletions

View File

@ -51,8 +51,8 @@ pub struct CPU {
pc: Adr, pc: Adr,
i: Adr, i: Adr,
v: [u8; 16], v: [u8; 16],
delay: f64, delay: u8,
sound: f64, sound: u8,
// I/O // I/O
keys: [bool; 16], keys: [bool; 16],
/// Set to the last key that's been *released* after a keypause /// Set to the last key that's been *released* after a keypause
@ -257,7 +257,7 @@ impl CPU {
/// assert_eq!(0, cpu.sound()); /// assert_eq!(0, cpu.sound());
/// ``` /// ```
pub fn sound(&self) -> u8 { pub fn sound(&self) -> u8 {
self.sound as u8 self.sound
} }
/// Gets the value in the Delay Timer register /// Gets the value in the Delay Timer register
@ -268,7 +268,7 @@ impl CPU {
/// assert_eq!(0, cpu.delay()); /// assert_eq!(0, cpu.delay());
/// ``` /// ```
pub fn delay(&self) -> u8 { pub fn delay(&self) -> u8 {
self.delay as u8 self.delay
} }
/// Gets the number of cycles the CPU has executed /// Gets the number of cycles the CPU has executed
@ -332,8 +332,8 @@ impl CPU {
// Zero the registers // Zero the registers
self.i = 0; self.i = 0;
self.v = [0; 16]; self.v = [0; 16];
self.delay = 0.0; self.delay = 0;
self.sound = 0.0; self.sound = 0;
// I/O // I/O
self.keys = [false; 16]; self.keys = [false; 16];
self.lastkey = None; self.lastkey = None;
@ -415,25 +415,22 @@ impl CPU {
/// ```rust /// ```rust
/// # use chirp::*; /// # use chirp::*;
/// let mut cpu = CPU::default(); /// let mut cpu = CPU::default();
/// let mut bus = bus!{ /// let mut screen = bus!{
/// Program [0x0200..0x0f00] = &[ /// Screen [0x000..0x100],
/// 0x00, 0xe0, // cls
/// 0x22, 0x02, // jump 0x202 (pc)
/// ],
/// Screen [0x0f00..0x1000],
/// }; /// };
/// cpu.multistep(&mut bus, 0x20) /// cpu.load_program_bytes(&[0x00, 0xe0, 0x22, 0x02]);
/// cpu.multistep(&mut screen, 0x20)
/// .expect("The program should only have valid opcodes."); /// .expect("The program should only have valid opcodes.");
/// assert_eq!(0x202, cpu.pc()); /// assert_eq!(0x202, cpu.pc());
/// assert_eq!(0x20, cpu.cycle()); /// assert_eq!(0x20, cpu.cycle());
/// ``` /// ```
pub fn multistep(&mut self, screen: &mut Bus, steps: usize) -> Result<&mut Self> { pub fn multistep(&mut self, screen: &mut Bus, steps: usize) -> Result<&mut Self> {
//let speed = 1.0 / steps as f64;
for _ in 0..steps { for _ in 0..steps {
self.tick(screen)?; self.tick(screen)?;
let speed = 1.0 / steps as f64;
self.delay -= speed;
self.sound -= speed;
} }
self.delay = self.delay.saturating_sub(1);
self.sound = self.sound.saturating_sub(1);
self.flags.draw_wait = false; self.flags.draw_wait = false;
Ok(self) Ok(self)
} }
@ -613,8 +610,8 @@ impl Default for CPU {
pc: 0x200, pc: 0x200,
i: 0, i: 0,
v: [0; 16], v: [0; 16],
delay: 0.0, delay: 0,
sound: 0.0, sound: 0,
cycle: 0, cycle: 0,
keys: [false; 16], keys: [false; 16],
lastkey: None, lastkey: None,

View File

@ -520,7 +520,7 @@ impl CPU {
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub(super) fn load_delay_timer(&mut self, x: Reg) { pub(super) fn load_delay_timer(&mut self, x: Reg) {
self.v[x] = self.delay as u8; self.v[x] = self.delay;
} }
/// |`Fx0A`| Wait for key, then vX = K /// |`Fx0A`| Wait for key, then vX = K
#[inline(always)] #[inline(always)]
@ -539,7 +539,7 @@ impl CPU {
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub(super) fn store_delay_timer(&mut self, x: Reg) { pub(super) fn store_delay_timer(&mut self, x: Reg) {
self.delay = self.v[x] as f64; self.delay = self.v[x];
} }
/// |`Fx18`| Load vX into ST /// |`Fx18`| Load vX into ST
/// ```py /// ```py
@ -547,7 +547,7 @@ impl CPU {
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub(super) fn store_sound_timer(&mut self, x: Reg) { pub(super) fn store_sound_timer(&mut self, x: Reg) {
self.sound = self.v[x] as f64; self.sound = self.v[x];
} }
/// |`Fx1e`| Add vX to I, /// |`Fx1e`| Add vX to I,
/// ```py /// ```py

View File

@ -875,8 +875,7 @@ mod io {
for word in 0..=0xff { for word in 0..=0xff {
for x in 0..=0xf { for x in 0..=0xf {
// set the register under test to `word` // set the register under test to `word`
cpu.delay = word as f64; cpu.delay = word;
cpu.load_delay_timer(x); cpu.load_delay_timer(x);
assert_eq!(cpu.v[x], word); assert_eq!(cpu.v[x], word);
@ -895,7 +894,7 @@ mod io {
cpu.store_delay_timer(x); cpu.store_delay_timer(x);
assert_eq!(cpu.delay, word as f64); assert_eq!(cpu.delay, word);
} }
} }
} }
@ -911,7 +910,7 @@ mod io {
cpu.store_sound_timer(x); cpu.store_sound_timer(x);
assert_eq!(cpu.sound, word as f64); assert_eq!(cpu.sound, word);
} }
} }
} }
@ -1072,28 +1071,28 @@ mod behavior {
#[test] #[test]
fn delay() { fn delay() {
let (mut cpu, mut bus) = setup_environment(); let (mut cpu, mut bus) = setup_environment();
cpu.delay = 10.0;
cpu.flags.monotonic = false; cpu.flags.monotonic = false;
cpu.delay = 10;
for _ in 0..2 { for _ in 0..2 {
cpu.multistep(&mut bus, 8) cpu.multistep(&mut bus, 8)
.expect("Running valid instructions should always succeed"); .expect("Running valid instructions should always succeed");
std::thread::sleep(Duration::from_secs_f64(1.0 / 60.0)); std::thread::sleep(Duration::from_secs_f64(1.0 / 60.0));
} }
// time is within 1 frame deviance over a theoretical 2 frame pause // time is within 1 frame deviance over a theoretical 2 frame pause
assert!(7.0 <= cpu.delay && cpu.delay <= 9.0); assert_eq!(cpu.delay, 8);
} }
#[test] #[test]
fn sound() { fn sound() {
let (mut cpu, mut bus) = setup_environment(); let (mut cpu, mut bus) = setup_environment();
cpu.sound = 10.0;
cpu.flags.monotonic = false; // disable monotonic timing cpu.flags.monotonic = false; // disable monotonic timing
cpu.sound = 10;
for _ in 0..2 { for _ in 0..2 {
cpu.multistep(&mut bus, 8) cpu.multistep(&mut bus, 8)
.expect("Running valid instructions should always succeed"); .expect("Running valid instructions should always succeed");
std::thread::sleep(Duration::from_secs_f64(1.0 / 60.0)); std::thread::sleep(Duration::from_secs_f64(1.0 / 60.0));
} }
// time is within 1 frame deviance over a theoretical 2 frame pause // time is within 1 frame deviance over a theoretical 2 frame pause
assert!(7.0 <= cpu.sound && cpu.sound <= 9.0); assert_eq!(cpu.sound, 8);
} }
#[test] #[test]
fn vbi_wait() { fn vbi_wait() {