--- nono/debugger/debugger_m88xx0.cpp 2026/04/29 17:04:40 1.1.1.4 +++ nono/debugger/debugger_m88xx0.cpp 2026/04/29 17:05:41 1.1.1.14 @@ -4,38 +4,48 @@ // Licensed under nono-license.txt // -#include "console.h" -#include "debugger_private.h" +// +// デバッガ (M88xx0 依存部分) +// + #include "debugger_m88xx0.h" +#include "debugger_memory.h" +#include "debugger.h" #include "m88100disasm.h" #include "m88100acc.h" -#include "mystring.h" // newval が oldval から変化していれば太字属性にするマクロ #define TSBOLD(newval, oldval) (((newval) != (oldval)) ? TA::Em : TA::Off) -// cpu->name が変化していれば太字属性にするマクロ -#define TSBOLDC(name) TSBOLD(cpu->name, prev.name) +// cpu->reg.name が変化していれば太字属性にするマクロ +#define TSBOLDC(name) TSBOLD(cpu->reg.name, prev.name) // name の mask で示される部分が変化していれば太字属性にする -#define TSBOLDM(name, mask) TSBOLD((cpu->name & (mask)), (prev.name & (mask))) +#define TSBOLDM(name, mask) TSBOLD((cpu->reg.name & (mask)), (prev.name & (mask))) // コンストラクタ -DebuggerMD_m88xx0::DebuggerMD_m88xx0(Debugger *parent_, m88kcpu *cpu_) - : inherited(parent_) +DebuggerMD_m88xx0::DebuggerMD_m88xx0(Debugger *parent_) + : inherited(parent_, CPUArch::M88xx0) { - cpu = cpu_; + // この時点で Get*Device() は使える + cpu = GetMPU88xx0Device(parent->mpu); + bus = GetMainbusDevice(); // 機種依存変数 - vector_max = 512; inst_bytes = 4; inst_bytes_fixed = 4; - - // 奇数にしておくことで初回に必ずアドレス変換を起こさせる。 - last_lpage[0].addr = 0xffffffff; - last_lpage[1].addr = 0xffffffff; + lasize = 32; + pasize = 32; + name = "mpu"; cmp_rd = -1; + + // 今の所 CPU は1つしかないので決め打ち + cmmu0 = gMainApp.GetObject(OBJ_M88200_7); + cmmu1 = gMainApp.GetObject(OBJ_M88200_6); + + // 逆アセンブラで使う + brhist = gMainApp.GetObject(OBJ_MPU_BRHIST); } // デストラクタ @@ -47,43 +57,24 @@ bool DebuggerMD_m88xx0::MMUEnabled() const { // XXX 命令/データの区別がまだないので、とりあえず命令のほうだけ見る - uint32 xapr = cpu->cmmu[0].GetAPR(IsSuper() ? 1 : 0); + uint32 xapr = cmmu0->GetAPR(IsSuper() ? 1 : 0); return (xapr & m88200::APR_TE); } // アドレス変換 -uint64 -DebuggerMD_m88xx0::TranslateAddr(saddr_t laddr) +busaddr +DebuggerMD_m88xx0::TranslateAddr(busaddr laddr) const { - uint64 paddr; - int isdata; m88200 *cmmu; // XXX とりあえずね - isdata = (laddr.data) ? 1 : 0; - if (isdata == 0) { - cmmu = &cpu->cmmu[0]; + if (laddr.IsData() == false) { + cmmu = cmmu0; } else { - cmmu = &cpu->cmmu[1]; + cmmu = cmmu1; } - // ページ境界(と初回)でアドレス変換 - saddr_t lpage; - lpage.addr = laddr.addr & 0xfffff000; - lpage.super = laddr.super; - if (lpage.GetSaddr() != last_lpage[isdata].GetSaddr()) { - last_lpage[isdata] = lpage; - - bool do_search = laddr.IsSearch(); - paddr = cmmu->TranslatePeek(laddr.addr, laddr.super, do_search); - if ((int64)paddr < 0) { - last_lpage[isdata].addr = 0xffffffff; - } - last_ppage[isdata] = paddr & 0xfffff000; - } else { - paddr = last_ppage[isdata] | (laddr.addr & 0x00000fff); - } - return paddr; + return cmmu->TranslatePeek(laddr); } // op が bb0 命令なら true を返す @@ -131,25 +122,27 @@ DebuggerMD_m88xx0::IsBBTB1(uint32 op) void DebuggerMD_m88xx0::BackupRegs() { - prev = (m88100reg)*cpu; + prev = cpu->reg; } void DebuggerMD_m88xx0::SetStepOut() { - so_r1 = cpu->r[1]; + so_r1 = cpu->reg.r[1]; } bool DebuggerMD_m88xx0::IsStepOut() const { - return (cpu->xip == so_r1); + return (cpu->reg.xip == so_r1); } // この命令がステップイン出来るなら true を返す bool -DebuggerMD_m88xx0::IsOpStepIn(uint32 op) +DebuggerMD_m88xx0::IsOpStepIn(DebuggerMemoryStream& mem) { + uint32 op = mem.Read(inst_bytes); + if ((op & 0xf800'0000) == 0xc800'0000 // bsr || IsTB0(op) // tb0 || (IsTB1(op) && ((op >> 16) & 0x1f) != 0) // tb1 (except r0) @@ -165,43 +158,43 @@ DebuggerMD_m88xx0::IsOpStepIn(uint32 op) } // レジスタ名からそのレジスタ値を返す。 -// メモリダンプのような用途なのでアドレスとして使えるアドレスのみ。 +// メモリダンプのような用途なのでアドレスとして使うレジスタのみ。 uint64 DebuggerMD_m88xx0::GetRegAddr(const char *name) const { char buf[8]; - if (strcmp(name, "xip") == 0) return cpu->xip; - if (strcmp(name, "nip") == 0) return cpu->nip; - if (strcmp(name, "fip") == 0) return cpu->fip; + if (strcmp(name, "xip") == 0) return cpu->reg.xip; + if (strcmp(name, "nip") == 0) return cpu->reg.nip; + if (strcmp(name, "fip") == 0) return cpu->reg.fip; // 制御レジスタ - //if (strcmp(name, "pid") == 0) return cpu->pid; - //if (strcmp(name, "psr") == 0) return cpu->psr; - //if (strcmp(name, "epsr") == 0) return cpu->epsr; - //if (strcmp(name, "ssbr") == 0) return cpu->ssbr; - if (strcmp(name, "sxip") == 0) return cpu->sxip & m88100reg::SIP_MASK; - if (strcmp(name, "snip") == 0) return cpu->snip & m88100reg::SIP_MASK; - if (strcmp(name, "sfip") == 0) return cpu->sfip & m88100reg::SIP_MASK; - if (strcmp(name, "vbr") == 0) return cpu->vbr; - //if (strcmp(name, "dmt0") == 0) return cpu->dmt0; - if (strcmp(name, "dmd0") == 0) return cpu->dmd0; - if (strcmp(name, "dma0") == 0) return cpu->dma0; - //if (strcmp(name, "dmt1") == 0) return cpu->dmt1; - if (strcmp(name, "dmd1") == 0) return cpu->dmd1; - if (strcmp(name, "dma1") == 0) return cpu->dma1; - //if (strcmp(name, "dmt2") == 0) return cpu->dmt2; - if (strcmp(name, "dmd2") == 0) return cpu->dmd2; - if (strcmp(name, "dma2") == 0) return cpu->dma2; - if (strcmp(name, "sr0") == 0) return cpu->sr[0]; - if (strcmp(name, "sr1") == 0) return cpu->sr[1]; - if (strcmp(name, "sr2") == 0) return cpu->sr[2]; - if (strcmp(name, "sr3") == 0) return cpu->sr[3]; + //if (strcmp(name, "pid") == 0) return cpu->reg.pid; + //if (strcmp(name, "psr") == 0) return cpu->reg.psr; + //if (strcmp(name, "epsr") == 0) return cpu->reg.epsr; + //if (strcmp(name, "ssbr") == 0) return cpu->reg.ssbr; + if (strcmp(name, "sxip") == 0) return cpu->reg.sxip & M88100::SIP_MASK; + if (strcmp(name, "snip") == 0) return cpu->reg.snip & M88100::SIP_MASK; + if (strcmp(name, "sfip") == 0) return cpu->reg.sfip & M88100::SIP_MASK; + if (strcmp(name, "vbr") == 0) return cpu->reg.vbr; + //if (strcmp(name, "dmt0") == 0) return cpu->reg.dmt0; + if (strcmp(name, "dmd0") == 0) return cpu->reg.dmd0; + if (strcmp(name, "dma0") == 0) return cpu->reg.dma0; + //if (strcmp(name, "dmt1") == 0) return cpu->reg.dmt1; + if (strcmp(name, "dmd1") == 0) return cpu->reg.dmd1; + if (strcmp(name, "dma1") == 0) return cpu->reg.dma1; + //if (strcmp(name, "dmt2") == 0) return cpu->reg.dmt2; + if (strcmp(name, "dmd2") == 0) return cpu->reg.dmd2; + if (strcmp(name, "dma2") == 0) return cpu->reg.dma2; + if (strcmp(name, "sr0") == 0) return cpu->reg.sr[0]; + if (strcmp(name, "sr1") == 0) return cpu->reg.sr[1]; + if (strcmp(name, "sr2") == 0) return cpu->reg.sr[2]; + if (strcmp(name, "sr3") == 0) return cpu->reg.sr[3]; - for (int i = 0; i < countof(cpu->cr); i++) { - snprintf(buf, sizeof(buf), "cr%d", i); + for (int i = 0; i < countof(cpu->reg.cr); i++) { + snprintf(buf, sizeof(buf), "cr%u", i); if (strcmp(name, buf) == 0) { - return cpu->cr[i]; + return cpu->reg.cr[i]; } } @@ -209,10 +202,10 @@ DebuggerMD_m88xx0::GetRegAddr(const char // XXX not implement // 通常レジスタ - for (int i = 0; i < countof(cpu->r); i++) { - snprintf(buf, sizeof(buf), "r%d", i); + for (int i = 0; i < countof(cpu->reg.r); i++) { + snprintf(buf, sizeof(buf), "r%u", i); if (strcmp(name, buf) == 0) { - return cpu->r[i]; + return cpu->reg.r[i]; } } @@ -221,7 +214,7 @@ DebuggerMD_m88xx0::GetRegAddr(const char // レジスタ表示系コマンドのヘルプ /*static*/ const HelpMessages -DebuggerMD_m88xx0::HelpMsgRegister = { +DebuggerMD_m88xx0::HelpListReg = { { "r", "Show general registers" }, { "rc", "Show (integer) control registers" }, { "rf", "Show floating point control registers" }, @@ -231,15 +224,85 @@ DebuggerMD_m88xx0::HelpMsgRegister = { { "rm", "Show CMMU registers" }, }; +/*static*/ const HelpMessages +DebuggerMD_m88xx0::HelpReg = { + //----- + { "r", R"**( + Command: r + + Shows general registers. + )**" }, + + //----- + { "rc", R"**( + Command: rc + + Shows the (integer) control registers. + )**" }, + + //----- + { "rf", R"**( + Command: rf + + Shows the floating point control registers. + )**" }, + + //----- + { "ro", R"**( + Command: ro + + Shows the other registers. + )**" }, + + //----- + { "ra", R"**( + Command: ra := 7, 6 + + Shows BATC/PATC on CMMU. + CMMU7 is instruction CMMU of CPU#0. + CMMU6 is data CMMU of CPU#0. + )**" }, + { "ra6", "=ra" }, + { "ra7", "=ra" }, + + //----- + { "rd", R"**( + Command: rd := 7, 6 + + Shows data cache on CMMU. + CMMU7 is instruction CMMU of CPU#0. + CMMU6 is data CMMU of CPU#0. + )**" }, + { "rd6", "=rd" }, + { "rd7", "=rd" }, + + //----- + { "rm", R"**( + Command: rm := 7, 6 + + Shows CMMU registers. + CMMU7 is instruction CMMU of CPU#0. + CMMU6 is data CMMU of CPU#0. + )**" }, + { "rm6", "=rm" }, + { "rm7", "=rm" }, +}; + +const HelpMessages& +DebuggerMD_m88xx0::GetHelpListReg() const +{ + return HelpListReg; +} + const HelpMessages& -DebuggerMD_m88xx0::GetRegisterHelp() const +DebuggerMD_m88xx0::GetHelpReg() const { - return HelpMsgRegister; + return HelpReg; } // レジスタ表示系コマンド bool -DebuggerMD_m88xx0::ShowRegister(Console *cons, +DebuggerMD_m88xx0::ShowRegister(FILE *cons, const std::vector& args) { int cmmu_id; @@ -247,42 +310,51 @@ DebuggerMD_m88xx0::ShowRegister(Console // 余分な引数は無視する? if (args[0] == "r") { - ShowRegMain(cons); + ShowRegMain(); return true; } if (args[0] == "rc") { - ShowRegCtrl(cons); + ShowRegCtrl(); return true; } if (args[0] == "rf") { - ShowRegFPU(cons); + ShowRegFPU(); return true; } if (args[0] == "ro") { - ShowRegOther(cons); + ShowRegOther(); return true; } if (MatchCMMUCmd(args[0], "ra", &cmmu_id)) { - parent->ShowMonitor(*gMPU88200ATC[7 - cmmu_id]); - return true; + Monitor *mon = gMonitorManager->Find(ID_MONITOR_ATC(cmmu_id)); + if (mon) { + parent->ShowMonitor(mon); + return true; + } + goto notfound; } if (MatchCMMUCmd(args[0], "rd", &cmmu_id)) { - ShowRegCache(cons, args, cmmu_id); - return true; + return ShowRegCache(cons, args, cmmu_id); } if (MatchCMMUCmd(args[0], "rm", &cmmu_id)) { - ShowRegMMU(cons, cmmu_id); - return true; + Monitor *mon = gMonitorManager->Find(ID_MONITOR_CMMU(cmmu_id)); + if (mon) { + parent->ShowMonitor(mon); + return true; + } + goto notfound; } // 該当なし + notfound: return false; } // CMMU ID 入りコマンド名を照合する。 // cmdname が basename + の時、*idp に id を格納して true を返す。 -// 一致しないか id が不正なら false を返す。 +// 一致しないか id が(数値でないなど)不正なら false を返す。 +// 実際にその id の CMMU が存在するかはここではチェックしない。 bool DebuggerMD_m88xx0::MatchCMMUCmd(const std::string& cmdname, const char *basename, int *idp) @@ -308,7 +380,7 @@ DebuggerMD_m88xx0::MatchCMMUCmd(const st } void -DebuggerMD_m88xx0::ShowRegMain(Console *cons) +DebuggerMD_m88xx0::ShowRegMain() { TextScreen s(80, 8); @@ -318,24 +390,25 @@ r1 :00700000 r9 :00000000 r17:00000000 r2 :0070e1a0 r10:00000000 r18:00000000 r26:00000000 */ - for (int i = 0; i < countof(cpu->r); i++) { - s.Print((i / 8) * 14, i % 8, TSBOLDC(r[i]), "r%-2d:%08x", i, cpu->r[i]); + for (int i = 0; i < countof(cpu->reg.r); i++) { + s.Print((i / 8) * 14, i % 8, TSBOLDC(r[i]), "r%-2d:%08x", + i, cpu->reg.r[i]); } // cmp 以降最初の分岐命令で結果レジスタの条件ビットマップを表示する。 // 分岐命令は bb1 #3 みたいな形式なのでそれだけでは条件演算子が分からない // のと、bb1 #n 自体は cmp 以外に対しても使えるので、cmp 命令以降最初の // 分岐命令でのみ表示してみる。 - if (cmp_rd >= 0 && (IsBBTB0(cpu->opX) || IsBBTB1(cpu->opX))) { + if (cmp_rd >= 0 && (IsBBTB0(cpu->reg.opX) || IsBBTB1(cpu->reg.opX))) { static const char * const cmpstr[] = { NULL, NULL, "eq", "ne", "gt", "le", "lt", "ge", "hi", "ls", "lo", "hs", }; int x = 0; int y = 0; - uint32 res = cpu->r[cmp_rd]; + uint32 res = cpu->reg.r[cmp_rd]; for (int b = 11; b >= 2; b--) { - s.Print(57 + x * 7, y, "%x:%s=%d", b, cmpstr[b], + s.Print(57 + x * 7, y, "%x:%s=%u", b, cmpstr[b], (res & (1 << b)) ? 1 : 0); x++; if (x > 2) { @@ -349,7 +422,7 @@ r2 :0070e1a0 r10:00000000 r18:00000000 } void -DebuggerMD_m88xx0::ShowRegCtrl(Console *cons) +DebuggerMD_m88xx0::ShowRegCtrl() { TextScreen s(80, 6); int x; @@ -366,70 +439,68 @@ nip:00000000 opF:00000000(--) snip(cr5 fip:00000000 sfip(cr6):00000000:VE vbr (cr7):00000000 */ -#define PRINT_B(x, y, reg, mask, fmt, arg) do { \ - uint32 _new = cpu->reg & (mask); \ - uint32 _old = prev.reg & (mask); \ +#define PRINT_B(x, y, r, mask, fmt, arg) do { \ + uint32 _new = cpu->reg.r & (mask); \ + uint32 _old = prev.r & (mask); \ s.Print((x), (y), TSBOLD(_new, _old), fmt, (arg)); \ } while (0) // pid(cr0) x = 0; y = 0; - s.Print(x, y, TSBOLDC(pid), "pid (cr0):%08x(", cpu->pid); - PRINT_B(x + 19, y, pid, m88100reg::PID_REV_MASK, "Arch=$%02x", + s.Print(x, y, TSBOLDC(pid), "pid (cr0):%08x(", cpu->reg.pid); + PRINT_B(x + 19, y, pid, M88100::PID_REV_MASK, "Arch=$%02x", (_new >> 8) & 0xff); - PRINT_B(x + 28, y, pid, m88100reg::PID_VER_MASK, "Ver=$%02x", + PRINT_B(x + 28, y, pid, M88100::PID_VER_MASK, "Ver=$%02x", (_new >> 1) & 0x7f); - PRINT_B(x + 36, y, pid, m88100reg::PID_MASTER, "M/C=%s)", - (_new & m88100reg::PID_MASTER) ? "Master" : "Checker"); + PRINT_B(x + 36, y, pid, M88100::PID_MASTER, "M/C=%s)", + (_new & M88100::PID_MASTER) ? "Master" : "Checker"); // psr(cr1) y++; - s.Print(x, y, TSBOLDC(psr), "psr (cr1):%08x", cpu->psr); + s.Print(x, y, TSBOLDC(psr), "psr (cr1):%08x", cpu->reg.psr); s.Print(x + 18, y, "(s,le,ser,cy sfd1,mxm,ind,sfrz)"); - PRINT_B(x + 19, y, psr, m88100reg::PSR_SUPER, "%c", _new ? 'S' : '-'); - PRINT_B(x + 21, y, psr, m88100reg::PSR_BO_LE, "%s", _new ? "LE" : "BE"); - PRINT_B(x + 24, y, psr, m88100reg::PSR_SER, "%s", _new ? "CON" : "SER"); - PRINT_B(x + 28, y, psr, m88100reg::PSR_C, "%s", _new ? "Cy" : "--"); - PRINT_B(x + 31, y, psr, m88100reg::PSR_SFD1, "%s", _new ? "SFD1" : "----"); - PRINT_B(x + 36, y, psr, m88100reg::PSR_MXM, "%s", _new ? "MXM" : "---"); - PRINT_B(x + 40, y, psr, m88100reg::PSR_IND, "%s", _new ? "IND" : "---"); - PRINT_B(x + 44, y, psr, m88100reg::PSR_SFRZ, "%s", _new ? "SFRZ" : "----"); + PRINT_B(x + 19, y, psr, M88100::PSR_SUPER, "%c", _new ? 'S' : '-'); + PRINT_B(x + 21, y, psr, M88100::PSR_BO_LE, "%s", _new ? "LE" : "BE"); + PRINT_B(x + 24, y, psr, M88100::PSR_SER, "%s", _new ? "CON" : "SER"); + PRINT_B(x + 28, y, psr, M88100::PSR_C, "%s", _new ? "Cy" : "--"); + PRINT_B(x + 31, y, psr, M88100::PSR_SFD1, "%s", _new ? "SFD1" : "----"); + PRINT_B(x + 36, y, psr, M88100::PSR_MXM, "%s", _new ? "MXM" : "---"); + PRINT_B(x + 40, y, psr, M88100::PSR_IND, "%s", _new ? "IND" : "---"); + PRINT_B(x + 44, y, psr, M88100::PSR_SFRZ, "%s", _new ? "SFRZ" : "----"); // epsr(cr2) y++; - s.Print(x, y, TSBOLDC(epsr), "epsr(cr2):%08x", cpu->epsr); + s.Print(x, y, TSBOLDC(epsr), "epsr(cr2):%08x", cpu->reg.epsr); s.Print(x + 18, y, "(s,le,ser,cy sfd1,mxm,ind,sfrz)"); - PRINT_B(x + 19, y, epsr, m88100reg::PSR_SUPER, "%c", _new ? 'S' : '-'); - PRINT_B(x + 21, y, epsr, m88100reg::PSR_BO_LE, "%s", _new ? "LE" : "BE"); - PRINT_B(x + 24, y, epsr, m88100reg::PSR_SER, "%s", _new ? "CON" : "SER"); - PRINT_B(x + 28, y, epsr, m88100reg::PSR_C, "%s", _new ? "Cy" : "--"); - PRINT_B(x + 31, y, epsr, m88100reg::PSR_SFD1, "%s", _new ? "SFD1":"----"); - PRINT_B(x + 36, y, epsr, m88100reg::PSR_MXM, "%s", _new ? "MXM" : "---"); - PRINT_B(x + 40, y, epsr, m88100reg::PSR_IND, "%s", _new ? "IND" : "---"); - PRINT_B(x + 44, y, epsr, m88100reg::PSR_SFRZ, "%s", _new ? "SFRZ":"----"); + PRINT_B(x + 19, y, epsr, M88100::PSR_SUPER, "%c", _new ? 'S' : '-'); + PRINT_B(x + 21, y, epsr, M88100::PSR_BO_LE, "%s", _new ? "LE" : "BE"); + PRINT_B(x + 24, y, epsr, M88100::PSR_SER, "%s", _new ? "CON" : "SER"); + PRINT_B(x + 28, y, epsr, M88100::PSR_C, "%s", _new ? "Cy" : "--"); + PRINT_B(x + 31, y, epsr, M88100::PSR_SFD1, "%s", _new ? "SFD1":"----"); + PRINT_B(x + 36, y, epsr, M88100::PSR_MXM, "%s", _new ? "MXM" : "---"); + PRINT_B(x + 40, y, epsr, M88100::PSR_IND, "%s", _new ? "IND" : "---"); + PRINT_B(x + 44, y, epsr, M88100::PSR_SFRZ, "%s", _new ? "SFRZ":"----"); // *IP x = 0; y = 3; - s.Print(x, y, "xip:%08x opX:%08x(%c%c)", - cpu->xip, (uint32)cpu->opX, - cpu->OpIsBusErr(cpu->opX) ? 'B' : '-', - cpu->OpIsDelay(cpu->opX) ? 'D' : '-'); - s.Print(x, y + 1, "nip:%08x opF:%08x(%c%c)", - cpu->nip, (uint32)cpu->opF, - cpu->OpIsBusErr(cpu->opF) ? 'B' : '-', - cpu->OpIsDelay(cpu->opX) ? 'D' : '-'); - s.Print(x, y + 2, "fip:%08x", cpu->fip); + s.Print(x, y, "xip:%08x opX:%08x(%c)", + cpu->reg.xip, (uint32)cpu->reg.opX, + cpu->OpIsBusErr(cpu->reg.opX) ? 'B' : '-'); + s.Print(x, y + 1, "nip:%08x opF:%08x(%c)", + cpu->reg.nip, (uint32)cpu->reg.opF, + cpu->OpIsBusErr(cpu->reg.opF) ? 'B' : '-'); + s.Print(x, y + 2, "fip:%08x", cpu->reg.fip); // S*IP x = 32; for (int i = 0; i < 3; i++) { - s.Print(x, y + i, TSBOLDC(cr[4 + i]), "%s(cr%d):%08x:%c%c", + s.Print(x, y + i, TSBOLDC(cr[4 + i]), "%s(cr%u):%08x:%c%c", m88100reg::sipname[i], 4 + i, - (cpu->cr[4 + i] & m88100reg::SIP_MASK), - (cpu->cr[4 + i] & m88100reg::SIP_V) ? 'V' : '-', - (cpu->cr[4 + i] & m88100reg::SIP_E) ? 'E' : '-'); + (cpu->reg.cr[4 + i] & M88100::SIP_MASK), + (cpu->reg.cr[4 + i] & M88100::SIP_V) ? 'V' : '-', + (cpu->reg.cr[4 + i] & M88100::SIP_E) ? 'E' : '-'); } x = 55; @@ -437,13 +508,13 @@ fip:00000000 sfip(cr6 // SR* for (int i = 0; i < 4; i++) { int rn = 17 + i; - s.Print(x, y++, TSBOLDC(cr[rn]), "sr%d(cr%d):%08x", - i, rn, cpu->cr[rn]); + s.Print(x, y++, TSBOLDC(cr[rn]), "sr%u(cr%u):%08x", + i, rn, cpu->reg.cr[rn]); } // ssbr(cr3) - s.Print(x, y++, TSBOLDC(ssbr), "ssbr(cr3):%08x", cpu->ssbr); + s.Print(x, y++, TSBOLDC(ssbr), "ssbr(cr3):%08x", cpu->reg.ssbr); // vbr(cr7) - s.Print(x, y++, TSBOLDC(vbr), "vbr (cr7):%08x", cpu->vbr); + s.Print(x, y++, TSBOLDC(vbr), "vbr (cr7):%08x", cpu->reg.vbr); parent->ShowTextScreen(s); } @@ -451,65 +522,61 @@ fip:00000000 sfip(cr6 // CMMU のデータキャッシュを表示 // rd なら概要表示。 // rd なら個別セットの詳細表示。 -void -DebuggerMD_m88xx0::ShowRegCache(Console *cons, +// id を受け付ければ true を、そうでなければ false を返す。 +bool +DebuggerMD_m88xx0::ShowRegCache(FILE *cons, const std::vector& args, int id) { + m88200 *cmmu; + + cmmu = gMainApp.FindObject(OBJ_M88200(id)); + if (cmmu == NULL) { + return false; + } + if (args.size() < 2) { - ShowRegCacheOverview(cons, id); + ShowRegCacheOverview(cmmu); } else { int set; char *end; errno = 0; set = strtol(args[1].c_str(), &end, 16); if (end == &args[1][0] || *end != '\0' || errno == ERANGE) { - cons->Print(" must be a number\n"); - return; + fprintf(cons, " must be a number\n"); + goto done; } if (set < 0 || set > 256) { - cons->Print(" must be in 00..ff\n"); - return; + fprintf(cons, " must be in 00..ff\n"); + goto done; } - ShowRegCacheSet(cons, id, set); + ShowRegCacheSet(cmmu, set); } + done: + return true; } // CMMU データキャッシュの概要表示 void -DebuggerMD_m88xx0::ShowRegCacheOverview(Console *cons, int id) +DebuggerMD_m88xx0::ShowRegCacheOverview(m88200 *cmmu) { TextScreen s(70, 17); - m88200 *cmmu; - // まだ今の所決め打ち - if (id == 7) { - cmmu = &cpu->cmmu[0]; - } else { - cmmu = &cpu->cmmu[1]; - } cmmu->MonitorCacheOverview(s, 0, false); parent->ShowTextScreen(s); } // CMMU データキャッシュの指定セットの詳細表示 void -DebuggerMD_m88xx0::ShowRegCacheSet(Console *cons, int id, int setidx) +DebuggerMD_m88xx0::ShowRegCacheSet(m88200 *cmmu, int setidx) { TextScreen s(70, 5); - m88200 *cmmu; - // まだ今の所決め打ち - if (id == 7) { - cmmu = &cpu->cmmu[0]; - } else { - cmmu = &cpu->cmmu[1]; - } cmmu->MonitorCacheSet(s, 0, setidx); parent->ShowTextScreen(s); } void -DebuggerMD_m88xx0::ShowRegFPU(Console *cons) +DebuggerMD_m88xx0::ShowRegFPU() { static const char * const fcrname[] = { "fpecr", @@ -526,33 +593,19 @@ DebuggerMD_m88xx0::ShowRegFPU(Console *c }; TextScreen s(80, 4); - for (int i = 0; i < 9; i++) { + for (uint i = 0; i < 9; i++) { s.Print((i / 4) * 22, i % 4, TSBOLDC(fcr[i]), - "%-5s(fcr%d):%08x", fcrname[i], i, cpu->fcr[i]); + "%-5s(fcr%u):%08x", fcrname[i], i, cpu->reg.fcr[i]); } - s.Print(44, 2, TSBOLDC(fpsr), "fpsr(fcr62):%08x", cpu->fpsr); - s.Print(44, 3, TSBOLDC(fpcr), "fpcr(fcr63):%08x", cpu->fpcr); + s.Print(44, 2, TSBOLDC(fpsr), "fpsr(fcr62):%08x", cpu->reg.fpsr); + s.Print(44, 3, TSBOLDC(fpcr), "fpcr(fcr63):%08x", cpu->reg.fpcr); parent->ShowTextScreen(s); } void -DebuggerMD_m88xx0::ShowRegMMU(Console *cons, int id) -{ - m88200 *cmmu; - - // まだ今の所決め打ち - if (id == 7) { - cmmu = &cpu->cmmu[0]; - } else { - cmmu = &cpu->cmmu[1]; - } - parent->ShowMonitor(*cmmu); -} - -void -DebuggerMD_m88xx0::ShowRegOther(Console *cons) +DebuggerMD_m88xx0::ShowRegOther() { TextScreen s(80, 3); /* @@ -562,84 +615,86 @@ dmt0(cr8) :0000(B,S,D,L,Rxx,S,---B,W,V) dmt0(cr11):0000(B,U,D,L,Rxx,S,HH--,W,V) dmd0(cr9) :00000000 dma0(cr10):00000000 dmt0(cr14):0000(B, ,D,L,Rxx,S,LLLL,W,V) dmd0(cr9) :00000000 dma0(cr10):00000000 */ - for (int i = 0; i <= 2; i++) { - int dt = 8 + i * 3; - int dd = 9 + i * 3; - int da = 10 + i * 3; + for (uint i = 0; i <= 2; i++) { + uint dt = 8 + i * 3; + uint dd = 9 + i * 3; + uint da = 10 + i * 3; - s.Print(0, i, TSBOLDC(cr[dt]), "dmt%d(cr%-2d):%04x", - i, dt, (cpu->cr[dt] & 0xffff)); + s.Print(0, i, TSBOLDC(cr[dt]), "dmt%u(cr%-2u):%04x", + i, dt, (cpu->reg.cr[dt] & 0xffff)); s.Print(15, i, "(b,s,d,l,rx, s,en ,w,v)"); - PRINT_B(16, i, cr[dt], m88100reg::DM_BO, "%c", _new ? 'B' : '-'); - PRINT_B(18, i, cr[dt], m88100reg::DM_DAS, "%c", _new ? 'S' : 'U'); - PRINT_B(20, i, cr[dt], m88100reg::DM_DOUB1, "%c", _new ? 'D' : '-'); - PRINT_B(22, i, cr[dt], m88100reg::DM_LOCK, "%c", _new ? 'L' : '-'); + PRINT_B(16, i, cr[dt], M88100::DM_BO, "%c", _new ? 'B' : '-'); + PRINT_B(18, i, cr[dt], M88100::DM_DAS, "%c", _new ? 'S' : 'U'); + PRINT_B(20, i, cr[dt], M88100::DM_DOUB1, "%c", _new ? 'D' : '-'); + PRINT_B(22, i, cr[dt], M88100::DM_LOCK, "%c", _new ? 'L' : '-'); // カンマを前詰め。かつ DREG がボールドでもカンマはボールドにしない - PRINT_B(24, i, cr[dt], m88100reg::DM_DREG_MASK, "r%d", _new >> 7); + PRINT_B(24, i, cr[dt], M88100::DM_DREG_MASK, "r%u", _new >> 7); s.Puts(","); - PRINT_B(28, i, cr[dt], m88100reg::DM_SIGNED, "%c", _new ? 'S' : '-'); - PRINT_B(30, i, cr[dt], m88100reg::DM_EN_MASK,"%s", + PRINT_B(28, i, cr[dt], M88100::DM_SIGNED, "%c", _new ? 'S' : '-'); + PRINT_B(30, i, cr[dt], M88100::DM_EN_MASK,"%s", m88100reg::dmt_en_str[(_new >> 2) & 0xf]); - PRINT_B(35, i, cr[dt], m88100reg::DM_WRITE, "%c", _new ? 'W' : '-'); - PRINT_B(37, i, cr[dt], m88100reg::DM_VALID, "%c", _new ? 'V' : '-'); + PRINT_B(35, i, cr[dt], M88100::DM_WRITE, "%c", _new ? 'W' : '-'); + PRINT_B(37, i, cr[dt], M88100::DM_VALID, "%c", _new ? 'V' : '-'); - s.Print(40, i, TSBOLDC(cr[dd]), "dmd%d(cr%-2d):%08x", - i, dd, cpu->cr[dd]); - s.Print(60, i, TSBOLDC(cr[dd]), "dma%d(cr%2d):%08x", - i, da, cpu->cr[da]); + s.Print(40, i, TSBOLDC(cr[dd]), "dmd%u(cr%-2u):%08x", + i, dd, cpu->reg.cr[dd]); + s.Print(60, i, TSBOLDC(cr[dd]), "dma%u(cr%2u):%08x", + i, da, cpu->reg.cr[da]); } parent->ShowTextScreen(s); } -// 逆アセンブル -bool -DebuggerMD_m88xx0::Disassemble(saddr_t laddr, - std::string& mnemonic, std::vector& bin) -{ - m88100disasm dis(this); - if (dis.Exec(laddr) == false) { - return false; - } - mnemonic = dis.text; - bin = dis.bin; - return true; -} - -// 逆アセンブルをフォーマット (オフライン版) +// オンライン用逆アセンブル std::string -DebuggerMD_m88xx0::FormatDisasm(const std::string& mnemonic, - const std::vector& bin) +DebuggerMD_m88xx0::Disassemble(DebuggerMemoryStream& mem) { - // 命令はすべて32ビット固定長 - uint32 op = (bin[0] << 24) | (bin[1] << 16) | (bin[2] << 8) | bin[3]; - return string_format("%08x %s", op, mnemonic.c_str()); -} + m88100disasm dis; + if (dis.Exec(&mem) == false) { + return "dis.Exec() failed"; + } -// 逆アセンブルをフォーマット (オンライン版) -std::string -DebuggerMD_m88xx0::FormatDisasmLive(const std::string& mnemonic, - const std::vector& bin) -{ - // 命令はすべて32ビット固定長 - uint32 op = (bin[0] << 24) | (bin[1] << 16) | (bin[2] << 8) | bin[3]; + // ニーモニック + std::string mnemonic = dis.text; + // 別名追加 + if (!dis.alttext.empty()) { + int len = mnemonic.length() % 8; + mnemonic += std::string(8 - len, ' '); + mnemonic += dis.alttext; + } // 遅延スロットは分かりやすく表示したい - std::string delay; - if (cpu->OpIsDelay(cpu->opX)) { - delay = "(delayed) "; + bool delay = false; + if (cpu->reg.xip + 4 != cpu->reg.nip) { + delay = true; + } else { + const auto& e = brhist->entry[brhist->top]; + if (e.from + 4 == cpu->reg.xip) { + // 直前の位置にあるブランチが遅延ブランチかどうか調べる + if ((e.info & 0xfc000000) == 0xf4000000) { + // jmp, jsr + delay = (e.info >> 10) & 1; + } else if (0xc0000000 <= e.info && e.info < 0xfc000000) { + // br, bsr, bcnd + delay = (e.info >> 26) & 1; + } + } } + // 条件判断 + auto bin = dis.bin; + uint32 op = (bin[0] << 24) | (bin[1] << 16) | (bin[2] << 8) | bin[3]; const char *cond = CondStr(op); - return string_format("%08x %s%s%s", - op, delay.c_str(), mnemonic.c_str(), cond); -} -// 例外のベクタ番号から名前を取得。 -const char * -DebuggerMD_m88xx0::GetExceptionName(int vector) const -{ - return m88kcpu::GetExceptionName(vector); + std::string str; + str = string_format("%08x ", op); + if (delay) { + str += "(delayed) "; + } + str += mnemonic; + str += cond; + + return str; } #define TAKE_IF(expr) do { \ @@ -661,7 +716,7 @@ DebuggerMD_m88xx0::CondStr(uint32 op) // rS の bit B が %0 ならブランチ/トラップ cmp_rd = -1; uint32 b = m88100opf_B5(op); - TAKE_IF((cpu->r[s] & (1 << b)) == 0); + TAKE_IF((cpu->reg.r[s] & (1 << b)) == 0); } if (IsBB1(op)) { // 11011N BBBBB SSSSS dddddd dd dddddddd bb1 @@ -672,7 +727,7 @@ DebuggerMD_m88xx0::CondStr(uint32 op) return " (nop)"; } uint32 b = m88100opf_B5(op); - TAKE_IF((cpu->r[s] & (1 << b)) != 0); + TAKE_IF((cpu->reg.r[s] & (1 << b)) != 0); } if (IsTB1(op)) { // 111100 BBBBB SSSSS 110110 0V VVVVVVVV tb1 @@ -684,7 +739,7 @@ DebuggerMD_m88xx0::CondStr(uint32 op) return ""; } uint32 b = m88100opf_B5(op); - TAKE_IF((cpu->r[s] & (1 << b)) != 0); + TAKE_IF((cpu->reg.r[s] & (1 << b)) != 0); } if ((op & 0xf8000000) == 0xe8000000 || // bcnd (op & 0xfc00fe00) == 0xf000e800) // tcnd @@ -694,12 +749,12 @@ DebuggerMD_m88xx0::CondStr(uint32 op) cmp_rd = -1; uint32 m5 = m88100opf_M5(op); TAKE_IF( - (m5 == 0x2 && cpu->r[s] == 0) || // eq0 - (m5 == 0xd && cpu->r[s] != 0) || // ne0 - (m5 == 0x1 && (int32)cpu->r[s] > 0) || // gt0 - (m5 == 0xc && (int32)cpu->r[s] < 0) || // lt0 - (m5 == 0x3 && (int32)cpu->r[s] >= 0) || // ge0 - (m5 == 0xe && (int32)cpu->r[s] <= 0) // le0 + (m5 == 0x2 && cpu->reg.r[s] == 0) || // eq0 + (m5 == 0xd && cpu->reg.r[s] != 0) || // ne0 + (m5 == 0x1 && (int32)cpu->reg.r[s] > 0) || // gt0 + (m5 == 0xc && (int32)cpu->reg.r[s] < 0) || // lt0 + (m5 == 0x3 && (int32)cpu->reg.r[s] >= 0) || // ge0 + (m5 == 0xe && (int32)cpu->reg.r[s] <= 0) // le0 ); }