cpu: Change ST and DT back to u8
This commit is contained in:
parent
57c2ac681c
commit
cb69af048f
33
src/cpu.rs
33
src/cpu.rs
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
Loading…
Reference in New Issue
Block a user