--- nono/debugger/debugger_private.h 2026/04/29 17:04:33 1.1.1.2 +++ nono/debugger/debugger_private.h 2026/04/29 17:04:40 1.1.1.4 @@ -6,6 +6,7 @@ #pragma once +#include "branchhistory.h" #include "bus.h" #include "cvprompt.h" #include "textscreen.h" @@ -17,23 +18,24 @@ using HelpMessages = std::vector0) なら n 回の成立をスキップし、(n+1) 回目でブレークの意。 + int32 skip {}; // スキップ回数 (ユーザ指定値) + int32 skipremain {}; // 残りスキップ回数 (0 で成立) } breakpoint_t; static const int MAX_BREAKPOINTS = 8; @@ -95,80 +124,114 @@ class Debugger final void Init(); void ThreadRun(); bool Check(); + void NotifyException(int vector); + + // ブレークポイントモニタを更新 + void MonitorBreakpoint(TextScreen& monitor); private: bool Accept(); bool AcquirePrompt(); CommandAction MainLoop(); + bool CheckAllBreakpoints(); + bool CheckBreakpointInst(breakpoint_t&); void ParseCmdbuf(); // コマンド名は大文字小文字を区別する関係でスネークスタイル。 void cmd_b(); + void cmd_bi(); + void cmd_bm(); + void cmd_bv(); void cmd_b_list(); + void cmd_b_set(BreakpointType); void cmd_brhist(); void cmd_bx(); void cmd_c(); void cmd_d(); void cmd_dt(); void cmd_D(); + void cmd_disp(); + void cmd_exhist(); void cmd_h(); + void cmd_hb(); + void cmd_hr(); void cmd_L(); void cmd_m(); void cmd_mt(); void cmd_M(); void cmd_minus(); void cmd_n(); + void cmd_nt(); void cmd_q(); + void cmd_reset(); void cmd_s(); + void cmd_st(); void cmd_so(); + void cmd_sot(); void cmd_show(); void cmd_t(); - int AddBreakpoint(uint32 addr, bool ismemory); - bool GetAddr(uint32& addr, uint32& lastaddr); + int AddBreakpoint(const breakpoint_t&); + void RecalcInstMask(); + bool GetAddr(saddr_t *addr); void cmd_d_common(MemdumpMode mode); + void cmd_hist_common(BranchHistory& hist, uint64 flag); void cmd_m_common(MemdumpMode mode); + void cmd_n_common(bool); + void cmd_s_common(bool); + void cmd_so_common(bool); + bool ParseVerbHex(const char *arg, uint32 *valp); bool ParseAddr(const char *arg, uint32_t *addrp); - bool SetNBreakpoint(); + void SetNBreakpoint(); static const HelpMessages HelpMsgMain; - void Help(const HelpMessages msgs); + static const HelpMessages HelpMsgBreakpoints; + static const HelpMessages HelpDetails; + void Help(const HelpMessages& msgs); + + // 個別ヘルプメッセージを出力用に置換 + std::string HelpConvert(const std::string& msg); // モニターを更新して表示 - void ShowMonitor(Object& obj); + void ShowMonitor(IMonitor& monitor); // テキストスクリーンを表示 void ShowTextScreen(TextScreen& screen); // アドレスをダンプ表示用に整形して返す bool FormatDumpAddr(saddr_t addr, std::string& addrstr); - DebuggerMD *md = NULL; // 機種依存部分 + DebuggerMD *md {}; // 機種依存部分 - Console *cons = NULL; // 入出力 - const char *prompt; // プロンプト文字列 + Console *cons {}; // 入出力 + const char *prompt {}; // プロンプト文字列 std::string cmdbuf {}; // 現在のコマンドライン std::string last_cmdbuf {}; // 直前のコマンドライン std::vector args {}; - uint32 pc = 0; - uint32 nextpc = 0; + uint32 pc {}; std::vector ir {}; // この後実行する命令のバイナリ列 std::array bpoint {}; - bool bc_enable = false; - uint32 bc_addr = 0; - uint32 d_last_addr = 0; - uint32 m_last_addr = 0; - bool n_enable = false; - bool n_breakenable = false; - uint32 n_breakaddr = 0; - uint32 n_count = 0; - bool s_enable = false; - uint32 s_count = 0; - bool so_enable = false; - bool t_enable = false; - uint32 t_count = 0; + bool bc_enable {}; + uint32 bc_addr {}; + uint32 bi_inst {}; + int bi_inst_bytes {}; + int bi_need_bytes {}; + int bv_vector = -1; + uint32 d_last_addr {}; + uint32 m_last_addr {}; + bool n_enable {}; + uint32 n_breakaddr {}; + uint32 n_count {}; + bool s_enable {}; + uint32 s_count {}; + bool so_enable {}; + bool t_enable {}; + uint32 t_count {}; // 一度VMを実行して再びプロンプトに来たら true - bool is_continued = false; + bool is_continued {}; + + // プロンプトで表示するレジスタ群 + std::vector disp_regs {}; static std::vector cmdtable; }; @@ -177,8 +240,8 @@ class Debugger final class DebuggerMD { public: - DebuggerMD(Debugger *arg) { - parent = arg; + DebuggerMD(Debugger *parent_) { + parent = parent_; } virtual ~DebuggerMD() { } @@ -200,11 +263,19 @@ class DebuggerMD // 現在の命令先頭アドレスを返す virtual uint32 GetPC() const = 0; + // MMU 状態を考慮して、プログラム空間の指定のアドレスから1命令語を + // 読み出して、下(右)詰めにして返す。 + // 命令語が可変長な CPU では最短命令長 (この命令の全ワードではない)。 + uint64 PeekFetch(saddr_t laddr); + // ステップアウトを設定する virtual void SetStepOut() = 0; // ステップアウトなら true を返す virtual bool IsStepOut() const = 0; + // この命令がステップイン出来るなら true を返す (cmd_n 用) + virtual bool IsOpStepIn(uint32 op) = 0; + // name で示されるのレジスタの値を返す。 // メモリダンプで指定するケースを想定しているので、明らかにアドレスでは // ないレジスタは含まなくてよい (m680x0 の SR など)。ただし Dn は含めて @@ -221,8 +292,9 @@ class DebuggerMD // レジスタ表示系コマンドのヘルプメッセージを取得 virtual const HelpMessages& GetRegisterHelp() const = 0; - // ブランチ履歴(オブジェクト)を取得 - virtual Object& GetBrHist() const = 0; + // ブランチ履歴・例外履歴(オブジェクト)を取得 + virtual BranchHistory& GetBrHist() const = 0; + virtual BranchHistory& GetExHist() const = 0; // 直近の命令でアクセスした laddr が一致したら true を返す // 1 命令で複数にアクセスする場合を考慮して、md 側で判断する @@ -246,8 +318,18 @@ class DebuggerMD virtual std::string FormatDisasmLive(const std::string& mnemonic, const std::vector& bin) = 0; + // 例外のベクタ番号から名前を取得。 + virtual const char *GetExceptionName(int vector) const = 0; + + // ベクタ番号の最大値 (+1) + int vector_max {}; + // 最短の1命令のバイト数 + uint inst_bytes {}; + // 命令が固定長ならそのバイト数、可変長なら 0 + uint inst_bytes_fixed {}; + protected: - Debugger *parent; // 親クラス + Debugger *parent {}; // 親クラス }; #define NORM "\x1b[0m"