Skip to content

Commit 97aef5d

Browse files
Implemented Inspect and Debug traits from emulator-hal (#5)
* Implemented Inspect and Debug traits from emulator-hal * Updated emulator-hal submodule * Updated Cargo.lock * Fixed missing feature flag and clippy * Fixed tests
1 parent 5cd1111 commit 97aef5d

File tree

21 files changed

+241
-130
lines changed

21 files changed

+241
-130
lines changed

Cargo.lock

+13-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

emulator/cpus/m68k/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ log = "0.4"
88
thiserror = "1.0"
99
femtos = "0.1"
1010
moa-parsing = { path = "../../libraries/parsing" }
11-
emulator-hal = { path = "../../libraries/emulator-hal/emulator-hal" }
11+
emulator-hal = { path = "../../libraries/emulator-hal/emulator-hal", features = ["femtos"] }
1212

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

emulator/cpus/m68k/src/debugger.rs

+78-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
use femtos::Instant;
2-
use emulator_hal::bus::BusAccess;
1+
// m68k Debugger
32

4-
use super::state::M68kError;
5-
use super::execute::M68kCycleExecutor;
6-
use super::memory::M68kAddress;
3+
use core::fmt;
4+
5+
use emulator_hal::time;
6+
use emulator_hal::bus::{self, BusAccess};
7+
use emulator_hal::step::{Inspect, Debug};
8+
9+
use crate::{M68k, M68kError, M68kAddress, M68kCycleExecutor};
710

811
#[derive(Clone, Default)]
912
pub struct StackTracer {
@@ -20,6 +23,74 @@ impl StackTracer {
2023
}
2124
}
2225

26+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
27+
pub enum M68kInfo {
28+
State,
29+
}
30+
31+
impl<Bus, BusError, Instant, Writer> Inspect<M68kAddress, Instant, Bus, Writer> for M68k<Instant>
32+
where
33+
Bus: BusAccess<M68kAddress, Instant, Error = BusError>,
34+
BusError: bus::Error,
35+
Writer: fmt::Write,
36+
{
37+
type InfoType = M68kInfo;
38+
39+
type Error = M68kError<BusError>;
40+
41+
fn inspect(&mut self, info: Self::InfoType, _bus: &mut Bus, writer: &mut Writer) -> Result<(), Self::Error> {
42+
match info {
43+
M68kInfo::State => self
44+
.state
45+
.dump_state(writer)
46+
.map_err(|_| M68kError::Other("error while formatting state".to_string())),
47+
}
48+
}
49+
50+
fn brief_summary(&mut self, bus: &mut Bus, writer: &mut Writer) -> Result<(), Self::Error> {
51+
self.inspect(M68kInfo::State, bus, writer)
52+
}
53+
54+
fn detailed_summary(&mut self, bus: &mut Bus, writer: &mut Writer) -> Result<(), Self::Error> {
55+
self.inspect(M68kInfo::State, bus, writer)
56+
}
57+
}
58+
59+
/// Control the execution of a CPU device for debugging purposes
60+
impl<Bus, BusError, Instant, Writer> Debug<M68kAddress, Instant, Bus, Writer> for M68k<Instant>
61+
where
62+
Bus: BusAccess<M68kAddress, Instant, Error = BusError>,
63+
BusError: bus::Error,
64+
Instant: time::Instant,
65+
Writer: fmt::Write,
66+
{
67+
// TODO this should be a new type
68+
type DebugError = M68kError<BusError>;
69+
70+
fn get_execution_address(&mut self) -> Result<M68kAddress, Self::DebugError> {
71+
Ok(self.state.pc)
72+
}
73+
74+
fn set_execution_address(&mut self, address: M68kAddress) -> Result<(), Self::DebugError> {
75+
self.state.pc = address;
76+
Ok(())
77+
}
78+
79+
fn add_breakpoint(&mut self, address: M68kAddress) {
80+
self.debugger.breakpoints.push(address);
81+
}
82+
83+
fn remove_breakpoint(&mut self, address: M68kAddress) {
84+
if let Some(index) = self.debugger.breakpoints.iter().position(|a| *a == address) {
85+
self.debugger.breakpoints.remove(index);
86+
}
87+
}
88+
89+
fn clear_breakpoints(&mut self) {
90+
self.debugger.breakpoints.clear();
91+
}
92+
}
93+
2394

2495
#[derive(Clone, Default)]
2596
pub struct M68kDebugger {
@@ -30,9 +101,10 @@ pub struct M68kDebugger {
30101
pub(crate) stack_tracer: StackTracer,
31102
}
32103

33-
impl<'a, Bus, BusError> M68kCycleExecutor<'a, Bus>
104+
impl<'a, Bus, BusError, Instant> M68kCycleExecutor<'a, Bus, Instant>
34105
where
35106
Bus: BusAccess<M68kAddress, Instant, Error = BusError>,
107+
Instant: Copy,
36108
{
37109
pub fn check_breakpoints(&mut self) -> Result<(), M68kError<BusError>> {
38110
for breakpoint in &self.debugger.breakpoints {

emulator/cpus/m68k/src/decode.rs

+20-14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use femtos::Instant;
1+
// Instruction Decoding
2+
3+
use core::marker::PhantomData;
24
use emulator_hal::bus::BusAccess;
35

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

2930

3031
#[derive(Clone, Debug)]
31-
pub struct M68kDecoder {
32+
pub struct M68kDecoder<Instant> {
3233
pub cputype: M68kType,
3334
pub is_supervisor: bool,
3435
pub start: u32,
3536
pub end: u32,
3637
pub instruction_word: u16,
3738
pub instruction: Instruction,
39+
pub instant: PhantomData<Instant>,
3840
}
3941

40-
pub struct InstructionDecoding<'a, Bus>
42+
pub struct InstructionDecoding<'a, Bus, Instant>
4143
where
4244
Bus: BusAccess<M68kAddress, Instant>,
4345
{
4446
pub(crate) bus: &'a mut Bus,
45-
pub(crate) memory: &'a mut M68kBusPort,
46-
pub(crate) decoder: &'a mut M68kDecoder,
47+
pub(crate) memory: &'a mut M68kBusPort<Instant>,
48+
pub(crate) decoder: &'a mut M68kDecoder<Instant>,
4749
}
4850

49-
impl M68kDecoder {
51+
impl<Instant> M68kDecoder<Instant>
52+
where
53+
Instant: Copy,
54+
{
5055
#[inline]
51-
pub fn new(cputype: M68kType, is_supervisor: bool, start: u32) -> M68kDecoder {
56+
pub fn new(cputype: M68kType, is_supervisor: bool, start: u32) -> M68kDecoder<Instant> {
5257
M68kDecoder {
5358
cputype,
5459
is_supervisor,
5560
start,
5661
end: start,
5762
instruction_word: 0,
5863
instruction: Instruction::NOP,
64+
instant: PhantomData,
5965
}
6066
}
6167

@@ -70,7 +76,7 @@ impl M68kDecoder {
7076
pub fn decode_at<Bus>(
7177
&mut self,
7278
bus: &mut Bus,
73-
memory: &mut M68kBusPort,
79+
memory: &mut M68kBusPort<Instant>,
7480
is_supervisor: bool,
7581
start: u32,
7682
) -> Result<(), M68kError<Bus::Error>>
@@ -87,14 +93,13 @@ impl M68kDecoder {
8793
Ok(())
8894
}
8995

90-
pub fn dump_disassembly<Bus>(&mut self, bus: &mut Bus, start: u32, length: u32)
96+
pub fn dump_disassembly<Bus>(&mut self, bus: &mut Bus, memory: &mut M68kBusPort<Instant>, start: u32, length: u32)
9197
where
9298
Bus: BusAccess<M68kAddress, Instant>,
9399
{
94-
let mut memory = M68kBusPort::default();
95100
let mut next = start;
96101
while next < (start + length) {
97-
match self.decode_at(bus, &mut memory, self.is_supervisor, next) {
102+
match self.decode_at(bus, memory, self.is_supervisor, next) {
98103
Ok(()) => {
99104
self.dump_decoded(memory.current_clock, bus);
100105
next = self.end;
@@ -121,9 +126,10 @@ impl M68kDecoder {
121126
}
122127
}
123128

124-
impl<'a, Bus> InstructionDecoding<'a, Bus>
129+
impl<'a, Bus, Instant> InstructionDecoding<'a, Bus, Instant>
125130
where
126131
Bus: BusAccess<M68kAddress, Instant>,
132+
Instant: Copy,
127133
{
128134
#[inline]
129135
pub fn decode_next(&mut self) -> Result<Instruction, M68kError<Bus::Error>> {

0 commit comments

Comments
 (0)