1use crate::{BusInterface, M68000};
2
3pub trait M68000Debugger {
4    fn check_read<const WORD: bool>(&mut self, address: u32, cpu: &mut M68000);
5
6    fn check_write<const WORD: bool>(&mut self, address: u32, value: u16, cpu: &mut M68000);
7
8    fn check_execute(&mut self, pc: u32, cpu: &mut M68000);
9
10    fn check_interrupt(&mut self, interrupt_level: u8, cpu: &mut M68000);
11}
12
13pub struct DummyM68000Debugger;
14
15impl M68000Debugger for DummyM68000Debugger {
16    fn check_read<const WORD: bool>(&mut self, _address: u32, _cpu: &mut M68000) {}
17
18    fn check_write<const WORD: bool>(&mut self, _address: u32, _value: u16, _cpu: &mut M68000) {}
19
20    fn check_execute(&mut self, _pc: u32, _cpu: &mut M68000) {}
21
22    fn check_interrupt(&mut self, _interrupt_level: u8, _cpu: &mut M68000) {}
23}
24
25pub(crate) trait BusDebugExt {
26    fn read_byte_debug(&mut self, address: u32, cpu: &mut M68000) -> u8;
27
28    fn read_word_debug(&mut self, address: u32, cpu: &mut M68000) -> u16;
29
30    fn read_longword_debug(&mut self, address: u32, cpu: &mut M68000) -> u32 {
31        let high: u32 = self.read_word_debug(address, cpu).into();
32        let low: u32 = self.read_word_debug(address + 2, cpu).into();
33        low | (high << 16)
34    }
35
36    fn write_byte_debug(&mut self, address: u32, value: u8, cpu: &mut M68000);
37
38    fn write_word_debug(&mut self, address: u32, value: u16, cpu: &mut M68000);
39
40    fn write_longword_debug(&mut self, address: u32, value: u32, cpu: &mut M68000) {
41        self.write_word_debug(address, (value >> 16) as u16, cpu);
42        self.write_word_debug(address + 2, value as u16, cpu);
43    }
44
45    fn check_execute(&mut self, pc: u32, cpu: &mut M68000);
46}
47
48impl<B: BusInterface> BusDebugExt for B {
49    fn read_byte_debug(&mut self, address: u32, cpu: &mut M68000) -> u8 {
50        if let Some(mut debugger) = self.debug_view() {
51            debugger.check_read::<false>(address, cpu);
52        }
53        self.read_byte(address)
54    }
55
56    fn read_word_debug(&mut self, address: u32, cpu: &mut M68000) -> u16 {
57        if let Some(mut debugger) = self.debug_view() {
58            debugger.check_read::<true>(address, cpu);
59        }
60        self.read_word(address)
61    }
62
63    fn write_byte_debug(&mut self, address: u32, value: u8, cpu: &mut M68000) {
64        if let Some(mut debugger) = self.debug_view() {
65            debugger.check_write::<false>(address, value.into(), cpu);
66        }
67        self.write_byte(address, value);
68    }
69
70    fn write_word_debug(&mut self, address: u32, value: u16, cpu: &mut M68000) {
71        if let Some(mut debugger) = self.debug_view() {
72            debugger.check_write::<true>(address, value, cpu);
73        }
74        self.write_word(address, value);
75    }
76
77    fn check_execute(&mut self, pc: u32, cpu: &mut M68000) {
78        if let Some(mut debugger) = self.debug_view() {
79            debugger.check_execute(pc, cpu);
80        }
81    }
82}