--- nono/debugger/debugger_m680x0.cpp 2026/04/29 17:05:09 1.1.1.8 +++ nono/debugger/debugger_m680x0.cpp 2026/04/29 17:05:24 1.1.1.10 @@ -8,20 +8,27 @@ // デバッガ (M680x0 依存部分) // -#include "debugger_private.h" #include "debugger_m680x0.h" +#include "debugger_memory.h" +#include "debugger.h" #include "m68030disasm.h" -#include "mpu.h" +#include "m68030mmu.h" +#include "mainbus.h" // コンストラクタ -DebuggerMD_m680x0::DebuggerMD_m680x0(Debugger *parent_, m68kcpu *cpu_) - : inherited(parent_, Arch::M680x0) +DebuggerMD_m680x0::DebuggerMD_m680x0(Debugger *parent_) + : inherited(parent_, CPUArch::M680x0) { - cpu = cpu_; + // この時点で Get*Device() は使える + cpu = GetMPU680x0Device(parent->mpu); + bus = GetMainbusDevice(); // 機種依存変数 inst_bytes = 2; inst_bytes_fixed = 0; + lasize = 32; + pasize = 32; + name = "mpu"; } // デストラクタ @@ -30,17 +37,10 @@ DebuggerMD_m680x0::~DebuggerMD_m680x0() } // アドレス変換 -uint64 -DebuggerMD_m680x0::TranslateAddr(saddr_t laddr, bool lookup) const +busaddr +DebuggerMD_m680x0::TranslateAddr(busaddr laddr) const { - uint fc; - - fc = laddr.IsData() ? FC_DATA : FC_PROG; - if (laddr.IsSuper()) { - fc |= FC_SUPER; - } - - return m68030_mmu_translate_peek(cpu, (uint32)laddr, fc, lookup); + return cpu->TranslatePeek(laddr); } // op が 68030 の条件命令 Bcc, Scc, TRAPcc, DBcc なら true を返す。 @@ -79,10 +79,10 @@ DebuggerMD_m680x0::IsDBcc(uint16 op) bool DebuggerMD_m680x0::IsCond(uint16 op) { - bool N = RegIsN; - bool Z = RegIsZ; - bool V = RegIsV; - bool C = RegIsC; + bool N = cpu->reg.ccr.IsN(); + bool Z = cpu->reg.ccr.IsZ(); + bool V = cpu->reg.ccr.IsV(); + bool C = cpu->reg.ccr.IsC(); switch ((op >> 8) & 0x0f) { case 0: // T @@ -141,7 +141,7 @@ DebuggerMD_m680x0::CondStr(const std::ve } // カウンタが -1 なら何もしない uint rr = op & 7; - if ((RegD(rr) & 0xffff) == 0) { + if ((cpu->reg.R[rr] & 0xffff) == 0) { return " (will expire)"; } // それ以外はブランチ @@ -164,21 +164,21 @@ DebuggerMD_m680x0::CondStr(const std::ve void DebuggerMD_m680x0::SetStepOut() { - so_a7 = RegA(7); - so_sr = RegSR & 0x3000; + so_a7 = cpu->reg.A[7]; + so_sr = cpu->GetSR() & 0x3000; } bool DebuggerMD_m680x0::IsStepOut() const { - return (RegA(7) > so_a7 || (RegSR & 0x3000) != so_sr); + return (cpu->reg.A[7] > so_a7 || (cpu->GetSR() & 0x3000) != so_sr); } // この命令がステップイン出来るなら true を返す bool DebuggerMD_m680x0::IsOpStepIn(DebuggerMemoryStream& mem) { - uint32 op = mem.FetchInst(); + uint32 op = mem.Read(inst_bytes); if ((op & 0xfff0) == 0x4e40 // TRAP || (op == 0x4e76) // TRAPV @@ -186,6 +186,7 @@ DebuggerMD_m680x0::IsOpStepIn(DebuggerMe || (op & 0xf0f8) == 0x50f8 // TRAPcc || (op & 0xff00) == 0x6100 // BSR || (op & 0xfff8) == 0xf278 // FTRAPcc + || (op & 0xfe00) == 0xfe00 // DOS($FFxx), FPACK($FExx) ) { return true; } @@ -193,7 +194,7 @@ DebuggerMD_m680x0::IsOpStepIn(DebuggerMe // IOCS コール(に逆アセンブラで見えるやつ)も一命令扱いにしておく。 // XXX 本当は X68k の時だけだが今の所副作用なさげなので if ((op & 0xff00) == 0x7000) { // MOVEQ to %d0 - uint32 op2 = mem.FetchInst(); + uint32 op2 = mem.Read(inst_bytes); if (op2 == 0x4e4f) { // TRAP #15 return true; } @@ -203,37 +204,37 @@ DebuggerMD_m680x0::IsOpStepIn(DebuggerMe } // レジスタ名からそのレジスタ値を返す。 -// メモリダンプのような用途なのでアドレスとして使えるアドレスのみ。 +// メモリダンプのような用途なのでアドレスとして使うレジスタのみ。 uint64 DebuggerMD_m680x0::GetRegAddr(const char *name) const { uint32 addr; if ((*name | 0x20) == 'a') { - addr = RegA(name[1] - '0'); + addr = cpu->reg.A[name[1] - '0']; } else if ((*name | 0x20) == 'd') { - addr = RegD(name[1] - '0'); + addr = cpu->reg.D[name[1] - '0']; } else if (strcmp(name, "sp") == 0) { - addr = RegA(7); + addr = cpu->reg.A[7]; #if 0 } else if (strcmp(name, "usp") == 0) { - addr = RegUSP; + addr = cpu->RegUSP; } else if (strcmp(name, "isp") == 0) { - addr = RegISP; + addr = cpu->RegISP; } else if (strcmp(name, "msp") == 0) { - addr = RegMSP; + addr = cpu->RegMSP; #endif } else if (strcmp(name, "pc") == 0) { - addr = RegPC; + addr = cpu->reg.pc; } else if (strcmp(name, "vbr") == 0) { - addr = RegVBR; + addr = cpu->GetVBR(); } else if (strcmp(name, "srp") == 0) { addr = cpu->GetSRPl(); @@ -354,25 +355,20 @@ D3:CCCCCCCC D7:00000003 A3:CCCCCCCC A7: */ bool vr[16]; - for (int i = 0; i < 16; i++) { - vr[i] = (cpu->reg.da[i] != prev.da[i]); + for (int i = 0; i < countof(cpu->reg.R); i++) { + vr[i] = (cpu->reg.R[i] != prev.R[i]); } // 1行目 fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s ", - BOLDIF(vr[ 0]), 0, RegR( 0), NORM, - BOLDIF(vr[ 4]), 4, RegR( 4), NORM, - BOLDIF(vr[ 8]), 0, RegR( 8), NORM, - BOLDIF(vr[12]), 4, RegR(12), NORM); + BOLDIF(vr[ 0]), 0, cpu->reg.R[ 0], NORM, + BOLDIF(vr[ 4]), 4, cpu->reg.R[ 4], NORM, + BOLDIF(vr[ 8]), 0, cpu->reg.R[ 8], NORM, + BOLDIF(vr[12]), 4, cpu->reg.R[12], NORM); // 1行目 SR - uint16 sr = RegSR; - uint16 prevsr = prev.sr_h() - | (prev.ccr.IsX() ? M68K_CCR_X : 0) - | (prev.ccr.IsN() ? M68K_CCR_N : 0) - | (prev.ccr.IsZ() ? M68K_CCR_Z : 0) - | (prev.ccr.IsV() ? M68K_CCR_V : 0) - | (prev.ccr.IsC() ? M68K_CCR_C : 0); + uint16 sr = cpu->GetSR(); + uint16 prevsr = prev.GetSR(); // SR は上位バイトと下位バイトが変化したくらいでいいか? fprintf(cons, " SR:%s%02x%s%s%02x%s", BOLDIF((sr & 0xff00) != (prevsr & 0xff00)), @@ -384,32 +380,32 @@ D3:CCCCCCCC D7:00000003 A3:CCCCCCCC A7: fprintf(cons, "(%c I=%d %c%c%c%c%c)\n", (sr & 0x2000) ? 'S' : '-', (sr >> 8) & 7, - (sr & M68K_CCR_X) ? 'X' : '-', - (sr & M68K_CCR_N) ? 'N' : '-', - (sr & M68K_CCR_Z) ? 'Z' : '-', - (sr & M68K_CCR_V) ? 'V' : '-', - (sr & M68K_CCR_C) ? 'C' : '-'); + (sr & M68K::CCR_X) ? 'X' : '-', + (sr & M68K::CCR_N) ? 'N' : '-', + (sr & M68K::CCR_Z) ? 'Z' : '-', + (sr & M68K::CCR_V) ? 'V' : '-', + (sr & M68K::CCR_C) ? 'C' : '-'); // 2行目 fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n", - BOLDIF(vr[ 1]), 1, RegR( 1), NORM, - BOLDIF(vr[ 5]), 5, RegR( 5), NORM, - BOLDIF(vr[ 9]), 1, RegR( 9), NORM, - BOLDIF(vr[13]), 5, RegR(13), NORM); + BOLDIF(vr[ 1]), 1, cpu->reg.R[ 1], NORM, + BOLDIF(vr[ 5]), 5, cpu->reg.R[ 5], NORM, + BOLDIF(vr[ 9]), 1, cpu->reg.R[ 9], NORM, + BOLDIF(vr[13]), 5, cpu->reg.R[13], NORM); // 3行目 fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n", - BOLDIF(vr[ 2]), 2, RegR( 2), NORM, - BOLDIF(vr[ 6]), 6, RegR( 6), NORM, - BOLDIF(vr[10]), 2, RegR(10), NORM, - BOLDIF(vr[14]), 6, RegR(14), NORM); + BOLDIF(vr[ 2]), 2, cpu->reg.R[ 2], NORM, + BOLDIF(vr[ 6]), 6, cpu->reg.R[ 6], NORM, + BOLDIF(vr[10]), 2, cpu->reg.R[10], NORM, + BOLDIF(vr[14]), 6, cpu->reg.R[14], NORM); // 4行目 fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n", - BOLDIF(vr[ 3]), 3, RegR( 3), NORM, - BOLDIF(vr[ 7]), 7, RegR( 7), NORM, - BOLDIF(vr[11]), 3, RegR(11), NORM, - BOLDIF(vr[15]), 7, RegR(15), NORM); + BOLDIF(vr[ 3]), 3, cpu->reg.R[ 3], NORM, + BOLDIF(vr[ 7]), 7, cpu->reg.R[ 7], NORM, + BOLDIF(vr[11]), 3, cpu->reg.R[11], NORM, + BOLDIF(vr[15]), 7, cpu->reg.R[15], NORM); } // FPU レジスタ表示 @@ -604,19 +600,19 @@ DebuggerMD_m680x0::ShowRegOther() s.Print(0, 1, EM(caar), "CAAR:%08x", cpu->reg.caar); s.Print(15, 0, EM(vbr), "VBR:%08x", cpu->reg.vbr); - s.Print(15, 1, EM(sfc), "SFC:%d", cpu->reg.sfc); - s.Print(22, 1, EM(dfc), "DFC:%d", cpu->reg.dfc); + s.Print(15, 1, EM(sfc), "SFC:%d", cpu->reg.GetSFC()); + s.Print(22, 1, EM(dfc), "DFC:%d", cpu->reg.GetDFC()); // スタック欄はモードによって表示を変える。 // ユーザ 割り込み マスタ // 1行目 ISP USP USP // 2行目 MSP MSP ISP - if (!cpu->reg.s) { + if (!cpu->IsSuper()) { s.Print(29, 0, EM(isp), "ISP:%08x", cpu->reg.isp); } else { s.Print(29, 0, EM(usp), "USP:%08x", cpu->reg.usp); } - if (!cpu->reg.m) { + if (!cpu->IsMaster()) { s.Print(29, 1, EM(msp), "MSP:%08x", cpu->reg.msp); } else { s.Print(29, 1, EM(isp), "ISP:%08x", cpu->reg.isp); @@ -625,51 +621,33 @@ DebuggerMD_m680x0::ShowRegOther() parent->ShowTextScreen(s); } -// 逆アセンブル -bool -DebuggerMD_m680x0::Disassemble(DebuggerMemoryStream& mem, - std::string& mnemonic, std::vector& bin) +// オンライン用逆アセンブル +std::string +DebuggerMD_m680x0::Disassemble(DebuggerMemoryStream& mem) { - m680x0disasm dis(mem); - if (dis.Exec() == false) { - return false; + m680x0disasm dis; + if (dis.Exec(&mem) == false) { + return "dis.Exec() failed"; + } + + // dis.bin は uint8 列なのでこれを uint16 列に変換 + std::vector words; + for (int i = 0; i < dis.bin.size(); i += 2) { + words.push_back((dis.bin[i] << 8) | dis.bin[i + 1]); } - mnemonic = dis.text; - bin = dis.bin; - return true; -} -// 逆アセンブルをフォーマット (オフライン版) -std::string -DebuggerMD_m680x0::FormatDisasm(const std::string& mnemonic, - const std::vector& bin) -{ // 16進ダンプ std::string dumpbuf; - for (int i = 0; i < bin.size(); i += 2) { - dumpbuf += string_format("%02x%02x ", bin[i], bin[i + 1]); + for (auto w : words) { + dumpbuf += string_format("%04x ", w); } // ダンプは5ワード分 (越えたら知らん) - return string_format("%-25s%s", dumpbuf.c_str(), mnemonic.c_str()); -} - -// 逆アセンブルをフォーマット (オンライン版) -std::string -DebuggerMD_m680x0::FormatDisasmLive(const std::string& mnemonic, - const std::vector& bin) -{ - // オフライン文字列 - std::string str = FormatDisasm(mnemonic, bin); - - // bin は uint8 列だが ir は uint16 列なので変換 - std::vector ir; - for (int i = 0; i < bin.size(); i += 2) { - ir.push_back((bin[i] << 8) | bin[i + 1]); - } - - // 条件判断をする - std::string condstr = CondStr(ir); + std::string str = string_format("%-25s", dumpbuf.c_str()); + // ニーモニック + str += dis.text; + // (あれば) 条件判断 + str += CondStr(words); - return str + condstr; + return str; }