--- nono/debugger/branchhistory.h 2026/04/29 17:04:43 1.1.1.1 +++ nono/debugger/branchhistory.h 2026/04/29 17:05:59 1.1.1.10 @@ -4,12 +4,16 @@ // Licensed under nono-license.txt // +// // ブランチ履歴 +// #pragma once #include "object.h" +class VectorTable; + // MPU に依存しないブランチ履歴。 // // count = 0 なら書き込み前の無効エントリを示す。 @@ -23,32 +27,33 @@ class BranchHistory : public Object { + using inherited = Object; + protected: struct BranchEntry { uint32 count; // 連続通過回数 uint32 from; // ジャンプ元アドレス(VA) uint32 to; // ジャンプ先アドレス(VA) - uint32 inst; // ジャンプ元命令や例外情報など (機種による↓) + uint32 info; // ジャンプ元命令や例外情報など (機種による) } __packed; public: // 表示系フラグ - static const uint64 ExHist = (1ULL << 63); // ヘッダを例外履歴に - static const uint64 BottomToTop = (1ULL << 62); // 新しい方を下に + static const uint64 BottomToTop = (1ULL << 63); // 新しい方を下に public: - BranchHistory(); - virtual ~BranchHistory() override; + explicit BranchHistory(uint objid_); + ~BranchHistory() override; // 初期化 void Clear(); // エントリを追加。 // エントリを返す。 - const BranchEntry& AddEntry(uint32 from, uint32 to, uint32 inst) { + const BranchEntry& AddEntry(uint32 from, uint32 to, uint32 info) { BranchEntry *e = &entry[top]; - if (e->from == from && e->to == to) { + if (e->from == from && e->to == to && e->info == info) { // 前回と同じなら通過回数++ e->count++; } else { @@ -58,13 +63,11 @@ class BranchHistory : public Object e->count = 1; e->from = from; e->to = to; - e->inst = inst; + e->info = info; } return *e; } - void MonitorUpdate(TextScreen&) override; - // 使用中のエントリ数を取得する int GetUsed() const; @@ -73,8 +76,22 @@ class BranchHistory : public Object // 直近に使用した位置 uint8 top {}; + // モニタ (デバッガから直接参照する) + Monitor *monitor {}; + protected: + virtual std::string FormatHeader() const; virtual std::string FormatEntry(const BranchEntry& e) = 0; + + DECLARE_MONITOR_SCREEN(MonitorScreen); + + // 例外履歴かどうか。ヘッダ行が違う。 + bool is_exhist {}; + + // カウンタの表示開始座標 (HD64180 だけ違うため) + int x_count {}; + + VectorTable *vectortable {}; }; // @@ -84,9 +101,36 @@ class BranchHistory : public Object class BranchHistory_m680x0 : public BranchHistory { using inherited = BranchHistory; + + // info の分岐種別 + static constexpr uint32 NORMAL = 0x00000000; // 通常分岐 + static constexpr uint32 VECTORJUMP = 0x40000000; // ベクタによる分岐 + static constexpr uint32 SERVICECALL_HUMAN = 0x80000000; // IOCS/DOS call + static constexpr uint32 SERVICECALL_NETBSD = 0x80010000; // NetBSD syscall + static constexpr uint32 EXCEPTION = 0xc0000000; // 例外発生 + public: - BranchHistory_m680x0(); - virtual ~BranchHistory_m680x0() override; + explicit BranchHistory_m680x0(uint objid_); + ~BranchHistory_m680x0() override; + + static constexpr uint32 InfoNormal(uint16 inst) { + return NORMAL | inst; + } + static constexpr uint32 InfoVectorJump() { + return VECTORJUMP; + } + static constexpr uint32 InfoException(uint8 vector) { + return EXCEPTION | vector; + } + static constexpr uint32 InfoIOCSCall(uint8 num) { + return SERVICECALL_HUMAN | num; + } + static constexpr uint32 InfoDOSCall(uint16 ir) { + return SERVICECALL_HUMAN | ir; + } + static constexpr uint32 InfoNetBSDSyscall(uint16 syscall) { + return SERVICECALL_NETBSD | syscall; + } std::string FormatEntry(const BranchEntry& e) override; }; @@ -99,8 +143,25 @@ class BranchHistory_m88xx0 : public Bran { using inherited = BranchHistory; public: - BranchHistory_m88xx0(); - virtual ~BranchHistory_m88xx0() override; + explicit BranchHistory_m88xx0(uint objid_); + ~BranchHistory_m88xx0() override; + + std::string FormatEntry(const BranchEntry& e) override; +}; + +// +// HD64180 ブランチ履歴 +// +class BranchHistory_hd64180 : public BranchHistory +{ + using inherited = BranchHistory; + public: + explicit BranchHistory_hd64180(uint objid_); + ~BranchHistory_hd64180() override; + std::string FormatHeader() const override; std::string FormatEntry(const BranchEntry& e) override; + + private: + static std::string fstr(int); };