--- nono/debugger/debugger_m680x0.cpp 2026/04/29 17:04:37 1.1.1.3 +++ nono/debugger/debugger_m680x0.cpp 2026/04/29 17:04:48 1.1.1.6 @@ -9,20 +9,17 @@ #include "debugger_m680x0.h" #include "m68030disasm.h" #include "mpu.h" -#include "mystring.h" // コンストラクタ DebuggerMD_m680x0::DebuggerMD_m680x0(Debugger *parent_, m68kcpu *cpu_) - : inherited(parent_) + : inherited(parent_, Debugger::Arch::M680x0) { cpu = cpu_; // 機種依存変数 vector_max = 256; - inst_bits = 16; - - // 奇数にしておくことで初回に必ずアドレス変換を起こさせる。 - last_lpage.addr = 0xffffffff; + inst_bytes = 2; + inst_bytes_fixed = 0; } // デストラクタ @@ -32,28 +29,16 @@ DebuggerMD_m680x0::~DebuggerMD_m680x0() // アドレス変換 uint64 -DebuggerMD_m680x0::TranslateAddr(saddr_t laddr) +DebuggerMD_m680x0::TranslateAddr(saddr_t laddr, bool lookup) const { - uint64 paddr; + uint fc; - // ページ境界(と初回)でアドレス変換 - saddr_t lpage; - lpage.addr = laddr.addr & cpu->mmu_tc.lmask; - lpage.super = laddr.super; - if (lpage.GetSaddr() != last_lpage.GetSaddr()) { - last_lpage = lpage; - uint32 fc2 = (lpage.super ? FC_SUPER : 0) | FC_PROG; // DATAは? - - bool do_search = laddr.IsSearch(); - paddr = m68030_mmu_translate_peek(cpu, laddr.addr, fc2, do_search); - if ((int64)paddr < 0) { - last_lpage.addr = 0xffffffff; - } - last_ppage = paddr & cpu->mmu_tc.lmask; - } else { - paddr = last_ppage | (laddr.addr & cpu->mmu_tc.pgmask); + fc = laddr.IsData() ? FC_DATA : FC_PROG; + if (laddr.IsSuper()) { + fc |= FC_SUPER; } - return paddr; + + return m68030_mmu_translate_peek(cpu, (uint32)laddr, fc, lookup); } // op が 68030 の条件命令 Bcc, Scc, TRAPcc, DBcc なら true を返す。 @@ -187,6 +172,34 @@ DebuggerMD_m680x0::IsStepOut() const return (RegA(7) > so_a7 || (RegSR & 0x3000) != so_sr); } +// この命令がステップイン出来るなら true を返す +bool +DebuggerMD_m680x0::IsOpStepIn(DebuggerMemoryStream& mem) +{ + uint32 op = mem.FetchInst(); + + if ((op & 0xfff0) == 0x4e40 // TRAP + || (op == 0x4e76) // TRAPV + || (op & 0xffc0) == 0x4e80 // JSR + || (op & 0xf0f8) == 0x50f8 // TRAPcc + || (op & 0xff00) == 0x6100 // BSR + || (op & 0xfff8) == 0xf278 // FTRAPcc + ) { + return true; + } + + // IOCS コール(に逆アセンブラで見えるやつ)も一命令扱いにしておく。 + // XXX 本当は X68k の時だけだが今の所副作用なさげなので + if ((op & 0xff00) == 0x7000) { // MOVEQ to %d0 + uint32 op2 = mem.FetchInst(); + if (op2 == 0x4e4f) { // TRAP #15 + return true; + } + } + + return false; +} + // レジスタ名からそのレジスタ値を返す。 // メモリダンプのような用途なのでアドレスとして使えるアドレスのみ。 uint64 @@ -234,18 +247,64 @@ DebuggerMD_m680x0::GetRegAddr(const char // レジスタ表示系コマンドのヘルプ /*static*/ const HelpMessages -DebuggerMD_m680x0::HelpMsgRegister = { - { "r", "通常レジスタを表示" }, - { "ra", "ATC を表示" }, - { "rf", "FPU レジスタを表示" }, - { "rm", "MMU レジスタを表示" }, - { "ro", "その他のレジスタを表示" }, +DebuggerMD_m680x0::HelpListReg = { + { "r", "Show general registers" }, + { "ra", "Show ATC" }, + { "rf", "Show FPU registers" }, + { "rm", "Show MMU registers" }, + { "ro", "Show other registers" }, }; +/*static*/ const HelpMessages +DebuggerMD_m680x0::HelpReg = { + //----- + { "r", R"**( + Command: r + + Shows main registers. + )**" }, + + //----- + { "ra", R"**( + Command: ra + + Shows m68030 ATC(Address Translation Cache) information. Note that + nono's ATC implementation is very different from the real one (to + improve performance). + )**" }, + + //----- + { "rf", R"**( + Command: rf + + Shows 68881/68882's FPU registers. + )**" }, + + //----- + { "rm", R"**( + Command: rm + + Shows registers related to MMU and cache. + )**" }, + + //----- + { "ro", R"**( + Command: ro + + Shows other registers. + )**" }, +}; + +const HelpMessages& +DebuggerMD_m680x0::GetHelpListReg() const +{ + return HelpListReg; +} + const HelpMessages& -DebuggerMD_m680x0::GetRegisterHelp() const +DebuggerMD_m680x0::GetHelpReg() const { - return HelpMsgRegister; + return HelpReg; } // レジスタ表示系コマンド @@ -566,11 +625,11 @@ DebuggerMD_m680x0::ShowRegOther(Console // 逆アセンブル bool -DebuggerMD_m680x0::Disassemble(saddr_t laddr, +DebuggerMD_m680x0::Disassemble(DebuggerMemoryStream& mem, std::string& mnemonic, std::vector& bin) { - m680x0disasm dis(this); - if (dis.Exec(laddr) == false) { + m680x0disasm dis(mem); + if (dis.Exec() == false) { return false; } mnemonic = dis.text; @@ -612,3 +671,10 @@ DebuggerMD_m680x0::FormatDisasmLive(cons return str + condstr; } + +// 例外のベクタ番号から名前を取得。 +const char * +DebuggerMD_m680x0::GetExceptionName(int vector) const +{ + return m68030_get_exception_name(vector); +}