1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use femtos::{Instant, Duration};
use emulator_hal::{ErrorType, BusAdapter};

use moa_core::{System, Error, Address, Steppable, Interruptable, Addressable, Debuggable, Transmutable};

use crate::{M68k, M68kError, M68kDecoder, M68kCycle, M68kBusPort};

impl Steppable for M68k<Instant> {
    fn step(&mut self, system: &System) -> Result<Duration, Error> {
        let cycle = M68kCycle::new(self, system.clock);

        let mut bus = system.bus.borrow_mut();
        let mut adapter: BusAdapter<u32, u64, &mut dyn Addressable, Error> = BusAdapter::new(&mut *bus, |addr| addr as u64);

        let mut executor = cycle.begin(self, &mut adapter);
        executor.check_breakpoints()?;
        executor.step()?;

        let interrupt = system.get_interrupt_controller().check();
        if let (priority, Some(_)) = executor.check_pending_interrupts(interrupt)? {
            log::debug!("interrupt: {:?} @ {} ns", priority, system.clock.as_duration().as_nanos());
            system.get_interrupt_controller().acknowledge(priority as u8)?;
        }

        self.cycle = Some(executor.end());
        Ok(self.last_cycle_duration())
    }

    fn on_error(&mut self, _system: &System) {
        let mut output = String::with_capacity(256);
        let _ = self.dump_state(&mut output);
        println!("{}", output);
    }
}

impl Interruptable for M68k<Instant> {}

impl Transmutable for M68k<Instant> {
    fn as_steppable(&mut self) -> Option<&mut dyn Steppable> {
        Some(self)
    }

    fn as_interruptable(&mut self) -> Option<&mut dyn Interruptable> {
        Some(self)
    }

    fn as_debuggable(&mut self) -> Option<&mut dyn Debuggable> {
        Some(self)
    }
}

impl<BusError> From<Error> for M68kError<BusError> {
    fn from(err: Error) -> Self {
        match err {
            Error::Processor(ex) => M68kError::Interrupt(ex as u8),
            Error::Breakpoint(_) => M68kError::Breakpoint,
            Error::Other(msg) | Error::Assertion(msg) | Error::Emulator(_, msg) => M68kError::Other(msg),
        }
    }
}

impl<BusError: ErrorType> From<M68kError<BusError>> for Error {
    fn from(err: M68kError<BusError>) -> Self {
        match err {
            M68kError::Halted => Self::Other("cpu halted".to_string()),
            M68kError::Exception(ex) => Self::Processor(ex as u32),
            M68kError::Interrupt(num) => Self::Processor(num as u32),
            M68kError::Breakpoint => Self::Breakpoint("breakpoint".to_string()),
            M68kError::InvalidTarget(target) => Self::new(target.to_string()),
            M68kError::BusError(msg) => Self::Other(format!("{:?}", msg)),
            M68kError::Other(msg) => Self::Other(msg),
        }
    }
}


impl Debuggable for M68k<Instant> {
    fn add_breakpoint(&mut self, addr: Address) {
        self.debugger.breakpoints.push(addr as u32);
    }

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

    fn print_current_step(&mut self, system: &System) -> Result<(), Error> {
        let mut bus = system.bus.borrow_mut();
        let mut adapter: BusAdapter<u32, u64, &mut dyn Addressable, Error> = BusAdapter::new(&mut *bus, |addr| addr as u64);

        // TODO this is called by the debugger, but should be called some other way
        let mut decoder = M68kDecoder::new(self.info.chip, true, self.state.pc);
        decoder.decode_at(&mut adapter, &mut M68kBusPort::default(), true, self.state.pc)?;
        decoder.dump_decoded(system.clock, &mut adapter);
        let mut writer = String::new();
        self.dump_state(&mut writer)?;
        println!("{}", writer);
        Ok(())
    }

    fn print_disassembly(&mut self, system: &System, addr: Address, count: usize) {
        let mut decoder = M68kDecoder::new(self.info.chip, true, 0);
        let mut memory = M68kBusPort::from_info(&self.info, system.clock);

        let mut bus = system.bus.borrow_mut();
        let mut adapter: BusAdapter<u32, u64, &mut dyn Addressable, Error> = BusAdapter::new(&mut *bus, |addr| addr as u64);

        decoder.dump_disassembly(&mut adapter, &mut memory, addr as u32, count as u32);
    }

    fn run_command(&mut self, system: &System, args: &[&str]) -> Result<bool, Error> {
        match args[0] {
            "ds" | "stack" | "dumpstack" => {
                println!("Stack:");
                for addr in &self.debugger.stack_tracer.calls {
                    println!("  {:08x}", system.bus.borrow_mut().read_beu32(system.clock, *addr as Address)?);
                }
            },
            "so" | "stepout" => {
                self.debugger.step_until_return = Some(self.debugger.stack_tracer.calls.len() - 1);
            },
            _ => {
                return Ok(true);
            },
        }
        Ok(false)
    }
}