2024-12-12 12:53:56 +00:00
|
|
|
use num_traits::Unsigned;
|
|
|
|
|
use thiserror::Error;
|
2024-12-05 10:42:36 +00:00
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
#[derive(Error, Debug)]
|
|
|
|
|
pub enum ExecutionError {
|
|
|
|
|
#[error("Trying to access invalid memory location!")]
|
|
|
|
|
InvalidMemoryLocation,
|
2024-12-05 10:42:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct CpuStats {
|
|
|
|
|
pub cycles: usize,
|
|
|
|
|
pub memory_access_score: usize,
|
2024-12-05 10:42:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub trait CpuTrait {
|
2024-12-12 12:53:56 +00:00
|
|
|
type Size: Unsigned;
|
2024-12-05 10:42:36 +00:00
|
|
|
fn set_verbose(&mut self, verbose: bool);
|
|
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
fn load_memory(&mut self, address: Self::Size, memory: &[Self::Size]);
|
2024-12-05 10:42:36 +00:00
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
fn execute(&mut self, run_mode: RunMode) -> Result<CpuStats, ExecutionError>;
|
2024-12-05 10:42:36 +00:00
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
fn get_registers(&self) -> &[Self::Size];
|
2024-12-05 10:42:36 +00:00
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
fn get_memory(&self) -> &[Self::Size];
|
2024-12-05 10:42:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
#[derive(Debug)]
|
2024-12-05 10:42:36 +00:00
|
|
|
pub enum RunMode {
|
|
|
|
|
Run, // Run to completion
|
|
|
|
|
Debug(DebugMode), // Debug mode
|
|
|
|
|
StepOver, // Step over calls
|
|
|
|
|
StepInto, // Step into calls
|
|
|
|
|
StepOut, // Step out of calls
|
2024-12-12 12:53:56 +00:00
|
|
|
RunFor(isize), // Run for a specific number of cycles
|
2024-12-05 10:42:36 +00:00
|
|
|
}
|
|
|
|
|
|
2024-12-12 12:53:56 +00:00
|
|
|
#[derive(Debug)]
|
2024-12-05 10:42:36 +00:00
|
|
|
pub enum DebugMode {
|
|
|
|
|
All, // Break on any breakpoint
|
|
|
|
|
Code, // Break on code breakpoints
|
|
|
|
|
Data, // Break on data breakpoints
|
|
|
|
|
}
|