--- nono/debugger/debugger_m680x0.cpp 2026/04/29 17:04:40 1.1.1.4 +++ nono/debugger/debugger_m680x0.cpp 2026/04/29 17:05:32 1.1.1.11 @@ -4,26 +4,32 @@ // Licensed under nono-license.txt // -#include "console.h" -#include "debugger_private.h" +// +// デバッガ (M680x0 依存部分) +// + #include "debugger_m680x0.h" -#include "m68030disasm.h" -#include "mpu.h" -#include "mystring.h" +#include "debugger_memory.h" +#include "debugger.h" +#include "exttostr.h" +#include "m680x0disasm.h" +#include "m68030mmu.h" +#include "mainbus.h" // コンストラクタ -DebuggerMD_m680x0::DebuggerMD_m680x0(Debugger *parent_, m68kcpu *cpu_) - : inherited(parent_) +DebuggerMD_m680x0::DebuggerMD_m680x0(Debugger *parent_) + : inherited(parent_, CPUArch::M680x0) { - cpu = cpu_; + // この時点で Get*Device() は使える + cpu = GetMPU680x0Device(parent->mpu); + bus = GetMainbusDevice(); // 機種依存変数 - vector_max = 256; inst_bytes = 2; inst_bytes_fixed = 0; - - // 奇数にしておくことで初回に必ずアドレス変換を起こさせる。 - last_lpage.addr = 0xffffffff; + lasize = 32; + pasize = 32; + name = "mpu"; } // デストラクタ @@ -32,33 +38,14 @@ DebuggerMD_m680x0::~DebuggerMD_m680x0() } // アドレス変換 -uint64 -DebuggerMD_m680x0::TranslateAddr(saddr_t laddr) +busaddr +DebuggerMD_m680x0::TranslateAddr(busaddr laddr) const { - uint64 paddr; - - // ページ境界(と初回)でアドレス変換 - 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); - } - return paddr; + return cpu->TranslatePeek(laddr); } -// op が 68030 の条件命令 Bcc, Scc, TRAPcc, DBcc なら true を返す。 -bool +// op が 680x0 の条件命令 Bcc, Scc, TRAPcc, DBcc なら true を返す。 +/*static*/ bool DebuggerMD_m680x0::IsOPcc(uint16 op) { uint16 cc; @@ -80,7 +67,7 @@ DebuggerMD_m680x0::IsOPcc(uint16 op) } // op が DBcc 命令なら true を返す。 -bool +/*static*/ bool DebuggerMD_m680x0::IsDBcc(uint16 op) { if ((op & 0xf0f8) == 0x50c8) { // DBcc @@ -89,14 +76,42 @@ DebuggerMD_m680x0::IsDBcc(uint16 op) return false; } +// ir[] が FBcc, FScc, FDBcc, FTRAPcc 命令なら condition のあるワード位置を +// 返す。これらの条件命令でなければ (FNOP も含む)、-1 を返す。 +/*static*/ int +DebuggerMD_m680x0::IsFXcc(const std::vector& ir) +{ + if ((ir[0] & 0xfe00) != 0xf200) { + return -1; + } + if (ir.size() < 2) { + return -1; + } + + // FNOP は除く。 + if (ir[0] == 0xf280 && ir[1] == 0) { + return -1; + } + + uint type = (ir[0] >> 6) & 7; + if (type == 1) { // FScc/FDBcc/FTRAPcc + return 1; + } else if (type == 2) { // FBcc.W + return 0; + } else if (type == 3) { // FBcc.L + return 0; + } + return -1; +} + // op の cccc 条件が現在の CCR で成立するなら true を返す。 bool -DebuggerMD_m680x0::IsCond(uint16 op) +DebuggerMD_m680x0::IsCond(uint16 op) const { - 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 @@ -140,7 +155,7 @@ DebuggerMD_m680x0::IsCond(uint16 op) // Bcc, Scc, TRAPcc 命令なら、条件が成立するかどうか。 // DBcc 命令ならブランチするかどうか。 const char * -DebuggerMD_m680x0::CondStr(const std::vector& ir) +DebuggerMD_m680x0::CondStr(const std::vector& ir) const { uint16 op = ir[0]; @@ -155,7 +170,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)"; } // それ以外はブランチ @@ -171,6 +186,22 @@ DebuggerMD_m680x0::CondStr(const std::ve } } + // FXcc + int n = IsFXcc(ir); + if (n >= 0) { + struct fpemu fe0; + struct fpframe fpf0; + memset(&fe0, 0, sizeof(fe0)); + fe0.fe_fpframe = &fpf0; + fe0.fe_fpsr = cpu->reg.fpframe.fpf_fpsr; + int result = test_cc(&fe0, ir[n]); + if (result < 0) { + return " (will take)"; + } else if (result == 0) { + return " (will not take)"; + } + } + // (ここで知ってる)条件命令ではない return ""; } @@ -178,26 +209,29 @@ 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(uint32 op) +DebuggerMD_m680x0::IsOpStepIn(DebuggerMemoryStream& mem) { + uint32 op = mem.Read(inst_bytes); + if ((op & 0xfff0) == 0x4e40 // TRAP || (op == 0x4e76) // TRAPV || (op & 0xffc0) == 0x4e80 // JSR || (op & 0xf0f8) == 0x50f8 // TRAPcc || (op & 0xff00) == 0x6100 // BSR || (op & 0xfff8) == 0xf278 // FTRAPcc + || (op & 0xfe00) == 0xfe00 // DOS($FFxx), FPACK($FExx) ) { return true; } @@ -205,11 +239,7 @@ DebuggerMD_m680x0::IsOpStepIn(uint32 op) // IOCS コール(に逆アセンブラで見えるやつ)も一命令扱いにしておく。 // XXX 本当は X68k の時だけだが今の所副作用なさげなので if ((op & 0xff00) == 0x7000) { // MOVEQ to %d0 - saddr_t laddr; - laddr.addr = GetPC() + 2; - laddr.logical = true; - laddr.super = IsSuper(); - uint32 op2 = PeekFetch(laddr); + uint32 op2 = mem.Read(inst_bytes); if (op2 == 0x4e4f) { // TRAP #15 return true; } @@ -219,43 +249,83 @@ DebuggerMD_m680x0::IsOpStepIn(uint32 op) } // レジスタ名からそのレジスタ値を返す。 -// メモリダンプのような用途なのでアドレスとして使えるアドレスのみ。 +// メモリダンプのような用途なのでアドレスとして使うレジスタのみ。 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; + if (cpu->reg.s == false) { + addr = cpu->reg.A[7]; + } else { + addr = cpu->reg.usp; + } } else if (strcmp(name, "isp") == 0) { - addr = RegISP; + if (cpu->reg.s && cpu->reg.m == false) { + addr = cpu->reg.A[7]; + } else { + addr = cpu->reg.isp; + } } else if (strcmp(name, "msp") == 0) { - addr = RegMSP; -#endif + if (cpu->reg.s && cpu->reg.m) { + addr = cpu->reg.A[7]; + } else { + addr = cpu->reg.msp; + } + + } else if (strcmp(name, "ssp") == 0) { + if (cpu->reg.s) { + addr = cpu->reg.A[7]; + } else { + if (cpu->reg.m) { + addr = cpu->reg.msp; + } else { + addr = cpu->reg.isp; + } + } } 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(); + if (cpu->GetMPUType() == m680x0MPUType::M68030) { + auto cpu68030 = dynamic_cast(cpu); + addr = cpu68030->GetSRPl(); + } else { + auto cpu68040 = dynamic_cast(cpu); + addr = cpu68040->GetSRP(); + } } else if (strcmp(name, "crp") == 0) { - addr = cpu->GetCRPl(); + auto cpu68030 = dynamic_cast(cpu); + if (cpu68030) { + addr = cpu68030->GetCRPl(); + } else { + return (uint64)-1; + } + + } else if (strcmp(name, "urp") == 0) { + auto cpu68040 = dynamic_cast(cpu); + if (cpu68040) { + addr = cpu68040->GetURP(); + } else { + return (uint64)-1; + } } else { return (uint64)-1; @@ -265,7 +335,7 @@ DebuggerMD_m680x0::GetRegAddr(const char // レジスタ表示系コマンドのヘルプ /*static*/ const HelpMessages -DebuggerMD_m680x0::HelpMsgRegister = { +DebuggerMD_m680x0::HelpListReg = { { "r", "Show general registers" }, { "ra", "Show ATC" }, { "rf", "Show FPU registers" }, @@ -273,15 +343,61 @@ DebuggerMD_m680x0::HelpMsgRegister = { { "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::GetRegisterHelp() const +DebuggerMD_m680x0::GetHelpListReg() const { - return HelpMsgRegister; + return HelpListReg; +} + +const HelpMessages& +DebuggerMD_m680x0::GetHelpReg() const +{ + return HelpReg; } // レジスタ表示系コマンド bool -DebuggerMD_m680x0::ShowRegister(Console *cons, +DebuggerMD_m680x0::ShowRegister(FILE *cons, const std::vector& args) { // 余分な引数は無視する? @@ -291,7 +407,7 @@ DebuggerMD_m680x0::ShowRegister(Console return true; } if (args[0] == "ra") { - ShowRegATC(cons); + ShowRegATC(); return true; } if (args[0] == "rf") { @@ -299,11 +415,15 @@ DebuggerMD_m680x0::ShowRegister(Console return true; } if (args[0] == "rm") { - ShowRegMMU(cons); + if (cpu->GetMPUType() == m680x0MPUType::M68030) { + ShowRegMMU30(cons); + } else { + ShowRegMMU40(cons); + } return true; } if (args[0] == "ro") { - ShowRegOther(cons); + ShowRegOther(); return true; } @@ -314,7 +434,7 @@ DebuggerMD_m680x0::ShowRegister(Console // レジスタ表示 (基本セット) void -DebuggerMD_m680x0::ShowRegMain(Console *cons) +DebuggerMD_m680x0::ShowRegMain(FILE *cons) { /* D0:00000070 D4:CCCCCCCC A0:00FFAA32 A4:CCCCCCCC SR=F810(S I=0 X----) @@ -324,95 +444,72 @@ 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行目 - cons->Print("%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); + fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s ", + 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 は上位バイトと下位バイトが変化したくらいでいいか? - cons->Print(" SR:%s%02x%s%s%02x%s", + fprintf(cons, " SR:%s%02x%s%s%02x%s", BOLDIF((sr & 0xff00) != (prevsr & 0xff00)), sr >> 8, NORM, BOLDIF((sr & 0x00ff) != (prevsr & 0x00ff)), sr & 0xff, NORM); - cons->Print("(%c I=%d %c%c%c%c%c)\n", + 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行目 - cons->Print("%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); + fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n", + 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行目 - cons->Print("%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); + fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n", + 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行目 - cons->Print("%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); + fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n", + 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 レジスタ表示 void -DebuggerMD_m680x0::ShowRegFPU(Console *cons) +DebuggerMD_m680x0::ShowRegFPU(FILE *cons) { /* -FP0:0000_12345678_12345678 (-0.1234567890123456789) FPCR:1234 -FP1: BS,SN,OP,OV,UF,DZ,I2,I1 -FP2: RP=xx RM=xx -FP3: FPSR:12345678 -FP4: N,Z,Inf,NAN Q=$xx -FP5: BS,SN,OP,OV,UF,DZ,I2,I1 -FP6: AXEC -FP7: FPIAR:12345678 +FP0:0000_12345678_12345678 = -0.1234567890123456789) +FPCR: 1234 BS,SN,OE,OF,UF,DZ,X2,X1 RP=.X RM=Minus +FPSR: 12345678 N Z Inf NAN Q=$xx BS,SN,OE,OF,UF,DZ,X2,X1 AV AO AU AZ AX +FPIAR:12345678 */ -#define PUT_FP(n) do { \ - uint32 *c_ = cpu->reg.fpframe.fpf_regs + (n) * 3; \ - uint32 *p_ = prev.fpframe.fpf_regs + (n) * 3; \ - bool d = (c_[0] ^ p_[0]) | (c_[1] ^ p_[1]) | (c_[2] ^ p_[2]); \ - cons->Print("%sFP%d:%04xxxxx_%08x_%08x (%-20s)%s ", \ - BOLDIF(d), (n), c_[0] >> 16, c_[1], c_[2], "notyet", NORM); \ -} while (0) - uint32 fpcr, fpsr, fpiar; uint32 ppcr, ppsr, ppiar; - static const char * const rpstr[] = { - ".EXT", - ".SGL", - ".DBL", - ".???", - }; static const char * const rmstr[] = { "Near", "Zero", @@ -427,39 +524,39 @@ FP7: ppsr = prev.fpframe.fpf_fpsr; ppiar = prev.fpframe.fpf_fpiar; - PUT_FP(0); - cons->Print("%sFPCR:%04x%s\n", BOLDIF(fpcr != ppcr), fpcr, NORM); + for (uint n = 0; n < 8; n++) { + uint32 *c_ = cpu->reg.fpframe.fpf_regs + (n) * 3; + uint32 *p_ = prev.fpframe.fpf_regs + (n) * 3; + bool d = (c_[0] ^ p_[0]) | (c_[1] ^ p_[1]) | (c_[2] ^ p_[2]); + fprintf(cons, "%sFP%u:%04x_%08x_%08x%s = %s\n", + BOLDIF(d), n, c_[0] >> 16, c_[1], c_[2], NORM, + ExtToStr(c_).c_str()); + } - PUT_FP(1); - cons->Print(" %s %s %s %s %s %s %s %s\n", + fprintf(cons, "%sFPCR: %04x%s%20s", + BOLDIF(fpcr != ppcr), fpcr, NORM, ""); + fprintf(cons, "%s %s %s %s %s %s %s %s ", (fpcr & 0x8000) ? "BS" : "--", (fpcr & 0x4000) ? "SN" : "--", - (fpcr & 0x2000) ? "OP" : "--", - (fpcr & 0x1000) ? "OV" : "--", + (fpcr & 0x2000) ? "OE" : "--", + (fpcr & 0x1000) ? "OF" : "--", (fpcr & 0x0800) ? "UF" : "--", (fpcr & 0x0400) ? "DZ" : "--", - (fpcr & 0x0200) ? "I2" : "--", - (fpcr & 0x0100) ? "I1" : "--"); - - PUT_FP(2); - cons->Print(" RP=%s RM=%s\n", - rpstr[(fpcr >> 6) & 3], + (fpcr & 0x0200) ? "X2" : "--", + (fpcr & 0x0100) ? "X1" : "--"); + fprintf(cons, "RP=.%c RM=%s\n", + "XSD?"[(fpcr >> 6) & 3], rmstr[(fpcr >> 4) & 3]); - PUT_FP(3); - cons->Print("%sFPSR:%08x%s\n", BOLDIF(fpsr != ppsr), fpsr, NORM); - - PUT_FP(4); uint cc = fpsr >> 24; - cons->Print(" %c %c %s %s Q=$%02x\n", + fprintf(cons, "%sFPSR: %08x%s ", BOLDIF(fpsr != ppsr), fpsr, NORM); + fprintf(cons, "%c %c %s %s Q=$%02x ", (cc & 0x08) ? 'N' : '-', (cc & 0x04) ? 'Z' : '-', (cc & 0x02) ? "Inf" : "---", (cc & 0x01) ? "NAN" : "---", (fpsr >> 16) & 0xff); - - PUT_FP(5); - cons->Print(" %s %s %s %s %s %s %s %s\n", + fprintf(cons, "%s %s %s %s %s %s %s %s ", (fpsr & 0x8000) ? "BS" : "--", (fpsr & 0x4000) ? "SN" : "--", (fpsr & 0x2000) ? "OP" : "--", @@ -468,27 +565,25 @@ FP7: (fpsr & 0x0400) ? "DZ" : "--", (fpsr & 0x0200) ? "I2" : "--", (fpsr & 0x0100) ? "I1" : "--"); + fprintf(cons, "%s %s %s %s %s\n", + (fpsr & 0x80) ? "AV" : "--", + (fpsr & 0x40) ? "AO" : "--", + (fpsr & 0x20) ? "AU" : "--", + (fpsr & 0x10) ? "AZ" : "--", + (fpsr & 0x08) ? "AX" : "--"); - PUT_FP(6); - cons->Print(" %s %s %s %s %s\n", - (fpsr & 0x80) ? "IOP" : "---", - (fpsr & 0x40) ? "OVFL" : "----", - (fpsr & 0x20) ? "UNFL" : "----", - (fpsr & 0x10) ? "DZ" : "--", - (fpsr & 0x08) ? "INEX" : "----"); - - PUT_FP(7); - cons->Print("%sFPIAR:%08x%s\n", BOLDIF(fpiar != ppiar), fpiar, NORM); + fprintf(cons, "%sFPIAR:%08x%s\n", BOLDIF(fpiar != ppiar), fpiar, NORM); } -// MMU レジスタ表示 +// 68030 MMU レジスタ表示 void -DebuggerMD_m680x0::ShowRegMMU(Console *cons) +DebuggerMD_m680x0::ShowRegMMU30(FILE *cons) { /* SRP:00001111_22223333 TT0:00001111 TC:00001111 (---) CRP:00001111_22223333 TT1:00001111 MMUSR: 0011 ( */ + auto cpu68030 = dynamic_cast(cpu); uint64 srp, osrp; uint64 crp, ocrp; uint32 tt0, ott0; @@ -499,12 +594,12 @@ CRP:00001111_22223333 TT1:00001111 MMUSR bool t; bool c; - srp = cpu->GetSRP(); - crp = cpu->GetCRP(); - tt0 = cpu->GetTT(0); - tt1 = cpu->GetTT(1); - tc = cpu->GetTC(); - sr = cpu->GetMMUSR(); + srp = cpu68030->GetSRP(); + crp = cpu68030->GetCRP(); + tt0 = cpu68030->GetTT(0); + tt1 = cpu68030->GetTT(1); + tc = cpu68030->GetTC(); + sr = cpu68030->GetMMUSR(); osrp = prev.srp.q; ocrp = prev.crp.q; @@ -517,13 +612,13 @@ CRP:00001111_22223333 TT1:00001111 MMUSR p = (srp != osrp); t = (tt0 != ott0); c = (tc != otc); - cons->Print("%sSRP:%08x_%08x%s %sTT0:%08x%s(%c%c%c)", + fprintf(cons, "%sSRP:%08x_%08x%s %sTT0:%08x%s(%c%c%c)", BOLDIF(p), (uint32)(srp >> 32), (uint32)srp, NORM, BOLDIF(t), tt0, NORM, (tt0 & m68030TT::E) ? 'E' : '-', (tt0 & m68030TT::CI) ? 'C' : '-', (tt0 & m68030TT::RWM) ? '-' : ((tt0 & m68030TT::RW) ? 'R' : 'W')); - cons->Print(" %sTC:%08x%s(%c%c%c)\n", + fprintf(cons, " %sTC:%08x%s(%c%c%c)\n", BOLDIF(c), tc, NORM, (tc & m68030TC::TC_E) ? 'E' : '-', (tc & m68030TC::TC_SRE) ? 'S' : '-', @@ -533,13 +628,13 @@ CRP:00001111_22223333 TT1:00001111 MMUSR p = (crp != ocrp); t = (tt1 != ott1); c = (sr != osr); - cons->Print("%sCRP:%08x_%08x%s %sTT1:%08x%s(%c%c%c)", + fprintf(cons, "%sCRP:%08x_%08x%s %sTT1:%08x%s(%c%c%c)", BOLDIF(p), uint32(crp >> 32), (uint32)crp, NORM, BOLDIF(t), tt1, NORM, (tt1 & m68030TT::E) ? 'E' : '-', (tt1 & m68030TT::CI) ? 'C' : '-', (tt1 & m68030TT::RWM) ? '-' : ((tt1 & m68030TT::RW) ? 'R' : 'W')); - cons->Print(" %sMMUSR: %04x%s(%c%c%c%c%c%c%c N=%d)\n", + fprintf(cons, " %sMMUSR: %04x%s(%c%c%c%c%c%c%c N=%d)\n", BOLDIF(c), sr, NORM, (sr & m68030MMUSR::B) ? 'B' : '-', (sr & m68030MMUSR::L) ? 'L' : '-', @@ -551,16 +646,23 @@ CRP:00001111_22223333 TT1:00001111 MMUSR (sr & m68030MMUSR::N)); } +// 68040 MMU レジスタ表示 +void +DebuggerMD_m680x0::ShowRegMMU40(FILE *cons) +{ + fprintf(cons, "Not implemented\n"); +} + // ATC を表示 void -DebuggerMD_m680x0::ShowRegATC(Console *cons) +DebuggerMD_m680x0::ShowRegATC() { - parent->ShowMonitor(*gMPUATC); + parent->ShowMonitor(gMonitorManager->Get(ID_MONITOR_MPUATC)); } // その他のレジスタを表示 void -DebuggerMD_m680x0::ShowRegOther(Console *cons) +DebuggerMD_m680x0::ShowRegOther() { TextScreen s(80, 2); @@ -574,19 +676,19 @@ DebuggerMD_m680x0::ShowRegOther(Console 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); @@ -595,58 +697,33 @@ DebuggerMD_m680x0::ShowRegOther(Console parent->ShowTextScreen(s); } -// 逆アセンブル -bool -DebuggerMD_m680x0::Disassemble(saddr_t laddr, - std::string& mnemonic, std::vector& bin) +// オンライン用逆アセンブル +std::string +DebuggerMD_m680x0::Disassemble(DebuggerMemoryStream& mem) { - m680x0disasm dis(this); - if (dis.Exec(laddr) == 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 str = string_format("%-25s", dumpbuf.c_str()); + // ニーモニック + str += dis.text; + // (あれば) 条件判断 + str += CondStr(words); -// 逆アセンブルをフォーマット (オンライン版) -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); - - return str + condstr; -} - -// 例外のベクタ番号から名前を取得。 -const char * -DebuggerMD_m680x0::GetExceptionName(int vector) const -{ - return m68030_get_exception_name(vector); + return str; }