--- nono/debugger/branchhistory.cpp 2026/04/29 17:04:48 1.1.1.2 +++ nono/debugger/branchhistory.cpp 2026/04/29 17:04:53 1.1.1.4 @@ -11,9 +11,18 @@ #include "m88100.h" // コンストラクタ -BranchHistory::BranchHistory() +BranchHistory::BranchHistory(bool is_exhist_) + : inherited(is_exhist_ ? "ExceptionHistory" : "BranchHistory") { - monitor_size = nnSize(55, 33); + is_exhist = is_exhist_; + + monitor.func = (MonitorCallback_t)&BranchHistory::MonitorUpdate; + monitor.SetSize(55, 33); + if (is_exhist) { + monitor.Regist(ID_SUBWIN_EXHIST); + } else { + monitor.Regist(ID_SUBWIN_BRHIST); + } } // デストラクタ @@ -52,7 +61,7 @@ BranchHistory::GetUsed() const // モニタ更新 void -BranchHistory::MonitorUpdate(TextScreen& monitor) +BranchHistory::MonitorUpdate(Monitor *, TextScreen& screen) { uint8 t; int y; @@ -61,13 +70,10 @@ BranchHistory::MonitorUpdate(TextScreen& // userdata は表示開始位置と各種フラグ。 // 下位 32bit が表示開始位置で、0 なら先頭のエントリから、1 なら先頭の - // 一つ次のエントリから、…を表す (表示行数は monitor の高さ分)。 - // ExHist が %1 なら例外履歴、%0 ならブランチ履歴。これによって - // ヘッダを変えたい。 + // 一つ次のエントリから、…を表す (表示行数は screen の高さ分)。 // BottomToTop が %1 なら並び順を下から上に変える (コンソール用)。 - bool is_exhist = (monitor.userdata & ExHist); - bool bottom_to_top = (monitor.userdata & BottomToTop); - int pos = (int)monitor.userdata; + bool bottom_to_top = (screen.userdata & BottomToTop); + int pos = (int)screen.userdata; // 0 1 2 3 4 5 6 // 0123456789012345678901234567890123456789012345678901234567890123456789 @@ -78,16 +84,16 @@ BranchHistory::MonitorUpdate(TextScreen& // 002 S:01234567< 69> MFP Timer-C // 01234567890123456789012 - monitor.Clear(); - row = monitor.GetRow(); + screen.Clear(); + row = screen.GetRow(); // 最初の1行は常にヘッダ if (is_exhist) { - monitor.Print(0, 0, "No. FromAddr Vec. Exception"); - monitor.Print(45, 0, "Iteration"); + screen.Print(0, 0, "No. FromAddr Vec. Exception"); + screen.Print(45, 0, "Iteration"); } else { - monitor.Print(0, 0, "No. FromAddr Instruction"); - monitor.Print(35, 0, "ToAddr Iteration"); + screen.Print(0, 0, "No. FromAddr Instruction"); + screen.Print(35, 0, "ToAddr Iteration"); } // pos は最新を 0 とした通し番号。(スクロールしてたら開始が 0 とは限らない) @@ -108,9 +114,9 @@ BranchHistory::MonitorUpdate(TextScreen& continue; } std::string str = FormatEntry(e); - monitor.Print(0, y, "%3d %s", pos, str.c_str()); + screen.Print(0, y, "%3d %s", pos, str.c_str()); if (e.count > 1) { - monitor.Print(45, y, "x%9u", e.count); + screen.Print(45, y, "x%9u", e.count); } } } @@ -125,11 +131,14 @@ BranchHistory::MonitorUpdate(TextScreen& // ジャンプの3つを区別する。 // // 通常の分岐: -// from は分岐元 PC、to は分岐先 PC、inst の上位16ビットに命令の1ワード目。 +// from は上位31ビットが分岐元 PC、最下位ビットが S/U、 +// to は32ビット全体が分岐先 PC、 +// inst の上位16ビットに命令の1ワード目。 // inst の $8000 が立っていないことで区別する。 // // 例外発生: -// from は例外発生時の PC、to は不問(通常 0 をセットすること)、 +// from は上位31ビットが例外発生時の PC、最下位ビットが S/U、 +// to は不問(通常 0 をセットすること)、 // inst は $00008LVV で $8000 が例外フラグ、VV がベクタ番号である。 // ベクタ番号が $00 だと次項(ベクタによる分岐)と区別つかなくなってしまう // ため、リセット例外 (ベクタ番号0) は V=$01 で記録する。 @@ -137,11 +146,14 @@ BranchHistory::MonitorUpdate(TextScreen& // inst に $8000 が立っていて、かつ $8000 と一致しないことで区別する。 // // 例外ベクタによる分岐 (例外処理の最後に起きる): -// from はベクタアドレス、to は分岐先 (0 も起こりえる)、inst は $00008000。 +// from はベクタアドレス、 +// to は分岐先 (0 も起こりえる)、 +// inst は $00008000。 // inst が $00008000 と一致することで区別する (ビットが立っているではない)。 // コンストラクタ -BranchHistory_m680x0::BranchHistory_m680x0() +BranchHistory_m680x0::BranchHistory_m680x0(bool mode_) + : inherited(mode_) { } @@ -220,14 +232,19 @@ BranchHistory_m680x0::FormatEntry(const // m88k は例外ベクタを直接実行するのでそれは不要。 // // 通常の分岐: -// from は分岐元 XIP、to は分岐先アドレス、inst は命令ワード。 +// from は上位30ビットが分岐元 XIP、最下位ビットが S/U、 +// to は32ビット全体が分岐先アドレス、 +// inst は命令ワード。 // // 例外発生: -// from は例外発生時の XIP、to は 0。inst は $fc000VVV で VVV (9ビット)が -// ベクタ番号。命令ワードとは衝突しない (instruction.txt 参照)。 +// from は上位30ビットが例外発生時の XIP、最下位ビットが S/U、 +// to は 0。 +// inst は $fc000VVV で VVV (9ビット)がベクタ番号。 +// 命令ワードとは衝突しない (instruction.txt 参照)。 // コンストラクタ -BranchHistory_m88xx0::BranchHistory_m88xx0() +BranchHistory_m88xx0::BranchHistory_m88xx0(bool mode_) + : inherited(mode_) { }