--- nono/lib/branchhistory.cpp 2026/04/29 17:04:37 1.1.1.2 +++ nono/lib/branchhistory.cpp 2026/04/29 17:04:40 1.1.1.3 @@ -22,6 +22,20 @@ BranchHistory::~BranchHistory() { } +// 初期化 +void +BranchHistory::Clear() +{ + top = 0; + for (int i = 0; i < countof(entry); i++) { + BranchEntry& e = entry[i]; + e.count = 0; + e.from = 0xffffffff; + e.to = 0xffffffff; + e.inst = 0; + } +} + // 使用中のエントリ数を取得する int BranchHistory::GetUsed() const @@ -116,13 +130,16 @@ BranchHistory::MonitorUpdate(TextScreen& // inst の $8000 が立っていないことで区別する。 // // 例外発生: -// from は例外発生時の PC、to は 0。 -// inst は $00008LVV で $8000 が例外フラグ、V がベクタ番号、 -// L は割り込みなら割り込みレベルとする。 +// from は例外発生時の PC、to は不問(通常 0 をセットすること)、 +// inst は $00008LVV で $8000 が例外フラグ、VV がベクタ番号である。 +// ベクタ番号が $00 だと次項(ベクタによる分岐)と区別つかなくなってしまう +// ため、リセット例外 (ベクタ番号0) は V=$01 で記録する。 +// L は割り込みなら割り込みレベル。 +// inst に $8000 が立っていて、かつ $8000 と一致しないことで区別する。 // // 例外ベクタによる分岐 (例外処理の最後に起きる): -// from はベクタアドレス、to は分岐先、inst は $00008000。 -// inst と to によって区別する。 +// from はベクタアドレス、to は分岐先 (0 も起こりえる)、inst は $00008000。 +// inst が $00008000 と一致することで区別する (ビットが立っているではない)。 // コンストラクタ BranchHistory_m680x0::BranchHistory_m680x0() @@ -141,10 +158,13 @@ BranchHistory_m680x0::FormatEntry(const std::string desc; if ((e.inst & 0x8000)) { - if (e.to == 0) { + if ((e.inst & 0x7fff) != 0) { // 例外発生記録 // 発生アドレスとベクタ(と割り込みレベル)を表示 uint32 vector = e.inst & 0xff; + if (vector == 1) { + vector = 0; + } // とりあえず desc = string_format("<%3d> %s", vector, m68030_get_exception_name(vector)); @@ -227,6 +247,10 @@ BranchHistory_m88xx0::FormatEntry(const uint32 vector = e.inst & 0x1ff; const char *name = m88kcpu::GetExceptionName(vector); desc = string_format("<%3d> %s", vector, name ?: ""); + if (vector == 450) { + // OpenBSD のシステムコール番号 + desc += string_format("(%d)", (e.inst >> 12) & 0xfff); + } } else if (e.inst >= 0xc0000000) { // ブランチ const char *mnemonic = ""; @@ -257,7 +281,11 @@ BranchHistory_m88xx0::FormatEntry(const case 0xd: { uint32 lo6 = (e.inst >> 10) & 0x3f; if (lo6 == 0x30) { - mnemonic = ":jmp"; + if ((e.inst & 0x1f) == 1) { + mnemonic = ":jmp r1"; + } else { + mnemonic = ":jmp"; + } } else if (lo6 == 0x31) { mnemonic = ":jmp.n"; } else if (lo6 == 0x32) {