Skip to content

Commit

Permalink
Implemented Inspect and Debug traits from emulator-hal (#5)
Browse files Browse the repository at this point in the history
* Implemented Inspect and Debug traits from emulator-hal

* Updated emulator-hal submodule

* Updated Cargo.lock

* Fixed missing feature flag and clippy

* Fixed tests
  • Loading branch information
transistorfet authored Mar 21, 2024
1 parent 5cd1111 commit 97aef5d
Show file tree
Hide file tree
Showing 21 changed files with 241 additions and 130 deletions.
23 changes: 13 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion emulator/cpus/m68k/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ log = "0.4"
thiserror = "1.0"
femtos = "0.1"
moa-parsing = { path = "../../libraries/parsing" }
emulator-hal = { path = "../../libraries/emulator-hal/emulator-hal" }
emulator-hal = { path = "../../libraries/emulator-hal/emulator-hal", features = ["femtos"] }

moa-core = { path = "../../core", optional = true }

Expand Down
84 changes: 78 additions & 6 deletions emulator/cpus/m68k/src/debugger.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use femtos::Instant;
use emulator_hal::bus::BusAccess;
// m68k Debugger

use super::state::M68kError;
use super::execute::M68kCycleExecutor;
use super::memory::M68kAddress;
use core::fmt;

use emulator_hal::time;
use emulator_hal::bus::{self, BusAccess};
use emulator_hal::step::{Inspect, Debug};

use crate::{M68k, M68kError, M68kAddress, M68kCycleExecutor};

#[derive(Clone, Default)]
pub struct StackTracer {
Expand All @@ -20,6 +23,74 @@ impl StackTracer {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum M68kInfo {
State,
}

impl<Bus, BusError, Instant, Writer> Inspect<M68kAddress, Instant, Bus, Writer> for M68k<Instant>
where
Bus: BusAccess<M68kAddress, Instant, Error = BusError>,
BusError: bus::Error,
Writer: fmt::Write,
{
type InfoType = M68kInfo;

type Error = M68kError<BusError>;

fn inspect(&mut self, info: Self::InfoType, _bus: &mut Bus, writer: &mut Writer) -> Result<(), Self::Error> {
match info {
M68kInfo::State => self
.state
.dump_state(writer)
.map_err(|_| M68kError::Other("error while formatting state".to_string())),
}
}

fn brief_summary(&mut self, bus: &mut Bus, writer: &mut Writer) -> Result<(), Self::Error> {
self.inspect(M68kInfo::State, bus, writer)
}

fn detailed_summary(&mut self, bus: &mut Bus, writer: &mut Writer) -> Result<(), Self::Error> {
self.inspect(M68kInfo::State, bus, writer)
}
}

/// Control the execution of a CPU device for debugging purposes
impl<Bus, BusError, Instant, Writer> Debug<M68kAddress, Instant, Bus, Writer> for M68k<Instant>
where
Bus: BusAccess<M68kAddress, Instant, Error = BusError>,
BusError: bus::Error,
Instant: time::Instant,
Writer: fmt::Write,
{
// TODO this should be a new type
type DebugError = M68kError<BusError>;

fn get_execution_address(&mut self) -> Result<M68kAddress, Self::DebugError> {
Ok(self.state.pc)
}

fn set_execution_address(&mut self, address: M68kAddress) -> Result<(), Self::DebugError> {
self.state.pc = address;
Ok(())
}

fn add_breakpoint(&mut self, address: M68kAddress) {
self.debugger.breakpoints.push(address);
}

fn remove_breakpoint(&mut self, address: M68kAddress) {
if let Some(index) = self.debugger.breakpoints.iter().position(|a| *a == address) {
self.debugger.breakpoints.remove(index);
}
}

fn clear_breakpoints(&mut self) {
self.debugger.breakpoints.clear();
}
}


#[derive(Clone, Default)]
pub struct M68kDebugger {
Expand All @@ -30,9 +101,10 @@ pub struct M68kDebugger {
pub(crate) stack_tracer: StackTracer,
}

impl<'a, Bus, BusError> M68kCycleExecutor<'a, Bus>
impl<'a, Bus, BusError, Instant> M68kCycleExecutor<'a, Bus, Instant>
where
Bus: BusAccess<M68kAddress, Instant, Error = BusError>,
Instant: Copy,
{
pub fn check_breakpoints(&mut self) -> Result<(), M68kError<BusError>> {
for breakpoint in &self.debugger.breakpoints {
Expand Down
34 changes: 20 additions & 14 deletions emulator/cpus/m68k/src/decode.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use femtos::Instant;
// Instruction Decoding

use core::marker::PhantomData;
use emulator_hal::bus::BusAccess;

use crate::state::{M68kType, M68kError, Exceptions};
use crate::memory::{M68kBusPort, M68kAddress};
use crate::{M68kType, M68kError, M68kBusPort, M68kAddress, Exceptions};
use crate::instructions::{
Size, Sign, Direction, XRegister, BaseRegister, IndexRegister, RegOrImmediate, ControlRegister, Condition, Target, Instruction,
sign_extend_to_long,
Expand All @@ -28,34 +29,39 @@ const OPCG_FLINE: u8 = 0xF;


#[derive(Clone, Debug)]
pub struct M68kDecoder {
pub struct M68kDecoder<Instant> {
pub cputype: M68kType,
pub is_supervisor: bool,
pub start: u32,
pub end: u32,
pub instruction_word: u16,
pub instruction: Instruction,
pub instant: PhantomData<Instant>,
}

pub struct InstructionDecoding<'a, Bus>
pub struct InstructionDecoding<'a, Bus, Instant>
where
Bus: BusAccess<M68kAddress, Instant>,
{
pub(crate) bus: &'a mut Bus,
pub(crate) memory: &'a mut M68kBusPort,
pub(crate) decoder: &'a mut M68kDecoder,
pub(crate) memory: &'a mut M68kBusPort<Instant>,
pub(crate) decoder: &'a mut M68kDecoder<Instant>,
}

impl M68kDecoder {
impl<Instant> M68kDecoder<Instant>
where
Instant: Copy,
{
#[inline]
pub fn new(cputype: M68kType, is_supervisor: bool, start: u32) -> M68kDecoder {
pub fn new(cputype: M68kType, is_supervisor: bool, start: u32) -> M68kDecoder<Instant> {
M68kDecoder {
cputype,
is_supervisor,
start,
end: start,
instruction_word: 0,
instruction: Instruction::NOP,
instant: PhantomData,
}
}

Expand All @@ -70,7 +76,7 @@ impl M68kDecoder {
pub fn decode_at<Bus>(
&mut self,
bus: &mut Bus,
memory: &mut M68kBusPort,
memory: &mut M68kBusPort<Instant>,
is_supervisor: bool,
start: u32,
) -> Result<(), M68kError<Bus::Error>>
Expand All @@ -87,14 +93,13 @@ impl M68kDecoder {
Ok(())
}

pub fn dump_disassembly<Bus>(&mut self, bus: &mut Bus, start: u32, length: u32)
pub fn dump_disassembly<Bus>(&mut self, bus: &mut Bus, memory: &mut M68kBusPort<Instant>, start: u32, length: u32)
where
Bus: BusAccess<M68kAddress, Instant>,
{
let mut memory = M68kBusPort::default();
let mut next = start;
while next < (start + length) {
match self.decode_at(bus, &mut memory, self.is_supervisor, next) {
match self.decode_at(bus, memory, self.is_supervisor, next) {
Ok(()) => {
self.dump_decoded(memory.current_clock, bus);
next = self.end;
Expand All @@ -121,9 +126,10 @@ impl M68kDecoder {
}
}

impl<'a, Bus> InstructionDecoding<'a, Bus>
impl<'a, Bus, Instant> InstructionDecoding<'a, Bus, Instant>
where
Bus: BusAccess<M68kAddress, Instant>,
Instant: Copy,
{
#[inline]
pub fn decode_next(&mut self) -> Result<Instruction, M68kError<Bus::Error>> {
Expand Down
Loading

0 comments on commit 97aef5d

Please sign in to comment.