Adds ComputerManager so no write access to the computer directly happens.

ComputerManager has a thread to run the CPU whenever its told to either
step or run.  It can be told to stop the CPU too.  Cycle count and keystate
feedback is available along with read-only of the computer from status()
This commit is contained in:
2024-10-18 09:59:43 -04:00
parent 902d5c1875
commit d829b9f03f
10 changed files with 209 additions and 87 deletions
+1
View File
@@ -81,6 +81,7 @@ impl Chip8Computer {
let new_location = current_index + offset;
self.memory.poke(new_location, new_value);
}
self.registers.set_pc(offset);
}
pub fn step_system(&mut self) -> &mut Chip8Computer {
+127
View File
@@ -0,0 +1,127 @@
use std::sync::mpsc::{channel, Sender};
use std::thread;
use std::thread::{sleep, JoinHandle, Thread};
use std::time::{Duration, Instant};
use crate::chip8::computer::Chip8Computer;
use crate::chip8::cpu_states::Chip8CpuStates::WaitingForInstruction;
pub enum ManagerDumpables {
Video,
Registers,
Keyboard
}
pub struct Chip8ComputerManager {
pub core_should_run: bool,
pub one_step: bool,
pub core_cycle_timer: bool,
pub core_last_cycle_start: Instant,
computer: Chip8Computer
}
impl Default for Chip8ComputerManager {
fn default() -> Self {
Chip8ComputerManager {
core_should_run: false,
one_step: true,
core_cycle_timer: false,
core_last_cycle_start: Instant::now() ,
computer: Chip8Computer::new()
}
}
}
impl Chip8ComputerManager {
pub fn reset(&mut self) {
self.computer.reset();
}
pub fn new() -> Chip8ComputerManager {
let core_handle = thread::spawn(move || {
loop {
let start_time = Instant::now();
println!("Core Thread starting at {start_time:?}");
let sleep_time = Instant::now().duration_since(start_time).as_millis();
println!("Core Thread sleeping for {sleep_time}ms");
sleep(Duration::from_millis((16 - sleep_time) as u64));
}
});
Chip8ComputerManager::default()
}
pub fn start(managed: &mut Chip8ComputerManager) {
managed.core_should_run = true;
}
pub fn stop(managed: &mut Chip8ComputerManager) {
managed.core_should_run = false
}
pub fn step(managed: &mut Chip8ComputerManager) {
managed.one_step = true;
}
pub fn state(&mut self) -> &Chip8Computer {
&self.computer
}
pub fn tick( &mut self) {
println!("STARTING TICK");
if self.one_step | self.core_should_run {
self.core_last_cycle_start = Instant::now();
self.computer.step_system();
println!("SYSTEM STEP");
};
if self.one_step {
println!("SYSTEM HALTED AFTER 1 STEP");
// stop the CPU for the next cycle, we are only
// wanting one step.
self.one_step = false;
}
}
pub fn press_key(&mut self, key_index: u8) {
self.computer.keypad.push_key(key_index);
}
pub fn release_key(&mut self, key_index: u8) {
self.computer.keypad.release_key(key_index);
}
pub fn sound(managed: &Chip8ComputerManager) -> bool {
managed.computer.sound_timer.current() > 0
}
pub fn wait_for_instruction(&mut self) {
self.computer.state = WaitingForInstruction;
}
pub fn is_key_pressed(&self, key_index: u8) -> bool {
self.computer.keypad.pressed(key_index)
}
pub fn num_cycles(&self) -> i32 {
self.computer.num_cycles
}
pub fn load_bytes_to_system_memory(&mut self, bytes_to_load: Vec<u8>) {
self.computer.load_bytes_to_memory(0x200, &bytes_to_load);
}
pub fn dump_to_string(&self, dump_type: ManagerDumpables) -> String {
match dump_type {
ManagerDumpables::Video => {
self.computer.video_memory.format_as_string()
}
ManagerDumpables::Registers => {
self.computer.registers.format_as_string()
}
ManagerDumpables::Keyboard => {
self.computer.keypad.format_as_string()
}
}
}
}
+2 -7
View File
@@ -1,4 +1,4 @@
use log::{debug, trace};
use log::{debug};
use crate::constants::{CHIP8_VIDEO_MEMORY, CHIP8_VIDEO_WIDTH};
#[derive(Clone, Copy)]
@@ -85,12 +85,7 @@ impl Chip8Video {
impl Default for Chip8Video {
fn default() -> Self {
debug!("DEFAULT VIDEO PREPARED");
let new_struct = Chip8Video { memory: [false; CHIP8_VIDEO_MEMORY], has_frame_changed: false };
println!("NEW DEFAULT MEMORY : {}", new_struct.format_as_string());
new_struct.clone()
Chip8Video { memory: [false; CHIP8_VIDEO_MEMORY], has_frame_changed: false }
}
}
+2
View File
@@ -11,6 +11,8 @@ pub mod chip8 {
pub mod registers;
pub mod stack;
pub mod computer_manager;
}
pub mod constants;