/* SPDX-License-Identifier: Unlicense */ #pragma once #include "gdbremote_parser.hpp" #include #include enum class M68KRegister: size_t { kD0 = 0, kD1 = 1, kD2 = 2, kD3 = 3, kD4 = 4, kD5 = 5, kD6 = 6, kD7 = 7, kA0 = 8, kA1 = 9, kA2 = 10, kA3 = 11, kA4 = 12, kA5 = 13, kA6 = 14, /* Address of executing stack frame */ kFP = kA6, kA7 = 15, /* Address of top of stack (Stack pointer) */ kSP = kA7, kPS = 16, /* Processor status (Condition code register) */ kPC = 17, /* Program counter */ kRegistersCount, kFP0 = 18, /* Floating point register 0 */ kFPC = 26, /* 68881 control register */ kFPS = 27, /* 68881 status register */ kFPI = 28, /* Floating point register 1 */ }; struct M68KCPUState { size_t registers_count{}; uint32_t registers[static_cast(M68KRegister::kRegistersCount)]{}; }; class M68KDebuggingControl { public: using BreakpointType = GDBRemote::BreakpointType; M68KDebuggingControl() = default; M68KDebuggingControl(M68KDebuggingControl&&) = delete; M68KDebuggingControl(const M68KDebuggingControl&) = delete; uint32_t GetRegister(M68KRegister) const; M68KCPUState GetCPUState() const; void SetRegister(M68KRegister, uint32_t value); bool IsRunning() const { return _is_running; } void SetRunning(bool running) { _is_running = running; } bool IsNoAckModeEnabled() const { return _no_ack_mode; } void SetNoAckMode(bool enabled = true) { _no_ack_mode = enabled; } void Reset(); void Continue(); void Pause(); uint8_t Read8(uint32_t address) const; uint16_t Read16(uint32_t address) const; uint32_t Read32(uint32_t address) const; void Write8(uint32_t address, uint8_t value); void Write16(uint32_t address, uint16_t value); void Write32(uint32_t address, uint32_t value); void SetBreakpoint(BreakpointType type, uint32_t address, uint32_t length); void RemoveBreakpoint(BreakpointType type, uint32_t address, uint32_t length); void RaiseBreakpoint() { _have_break_risen = true; } bool HasBreakpoint() const { return _have_break_risen; } void ResetPendingBreakpoint() { _have_break_risen = false; } private: bool _is_running{}; bool _have_break_risen{}; bool _no_ack_mode{}; };