Annotation of nono/debugger/debugger_hd64180.cpp, revision 1.1.1.6

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2022 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // デバッガ (HD64180 依存部分)
                      9: //
                     10: 
                     11: #include "debugger_hd64180.h"
                     12: #include "debugger_memory.h"
                     13: #include "xpbus.h"
                     14: 
                     15: // コンストラクタ
                     16: DebuggerMD_hd64180::DebuggerMD_hd64180(Debugger *parent_)
                     17:        : inherited(parent_, CPUArch::HD64180)
                     18: {
                     19:        // この時点で Get*Device() は使える
                     20:        cpu = GetMPU64180Device();
                     21:        bus = GetXPbusDevice();
                     22: 
                     23:        // 機種依存変数
                     24:        inst_bytes = 1;
                     25:        lasize = 16;
                     26:        pasize = 20;
                     27:        name = "xp";
                     28: }
                     29: 
                     30: // デストラクタ
                     31: DebuggerMD_hd64180::~DebuggerMD_hd64180()
                     32: {
                     33: }
                     34: 
                     35: // 動作状態を返す
                     36: CPUState
                     37: DebuggerMD_hd64180::GetCPUState() const
                     38: {
                     39:        // HD64180::OpMode を CPUState に変換
                     40:        auto opmode = cpu->GetOpMode();
                     41:        switch (opmode) {
                     42:         case HD64180::OpMode::Normal:
                     43:                return CPUState::Normal;
                     44: 
                     45:         case HD64180::OpMode::Reset:
                     46:         case HD64180::OpMode::Halt:
                     47:         case HD64180::OpMode::Sleep:
                     48:                return CPUState::Halt;
                     49: 
                     50:         default:
                     51:                PANIC("corrupted opmode=%d", (int)opmode);
                     52:        }
                     53: }
                     54: 
1.1.1.2   root       55: // アドレス変換
                     56: busaddr
                     57: DebuggerMD_hd64180::TranslateAddr(busaddr laddr) const
1.1       root       58: {
1.1.1.3   root       59:        uint32 paddr = cpu->TranslatePeek(laddr.Addr());
                     60:        return busaddr(paddr);
1.1       root       61: }
                     62: 
                     63: // ステップアウトを設定する
                     64: void
                     65: DebuggerMD_hd64180::SetStepOut()
                     66: {
                     67:        so_sp = cpu->reg.sp;
                     68: }
                     69: 
                     70: bool
                     71: DebuggerMD_hd64180::IsStepOut() const
                     72: {
                     73:        return (cpu->reg.sp > so_sp);
                     74: }
                     75: 
                     76: // この命令がステップイン出来るなら true を返す
                     77: bool
                     78: DebuggerMD_hd64180::IsOpStepIn(DebuggerMemoryStream& mem)
                     79: {
                     80:        uint8 op = mem.Read(inst_bytes);
                     81: 
                     82:        if ( op == 0xcd                         // CALL
                     83:         || (op & 0xc7) == 0xc4         // CALL cc
                     84:        ) {
                     85:                return true;
                     86:        }
                     87: 
                     88:        // LD*R, CP*R, IN*R, OT*R, OT*MR もステップイン扱いにしてみる。
                     89:        if (op == 0xed) {
                     90:                uint8 op2 = mem.Read(inst_bytes);
                     91:                if ((op2 & 0xd0) == 0x90) {
                     92:                        return true;
                     93:                }
                     94:        }
                     95: 
                     96:        return false;
                     97: }
                     98: 
                     99: // name で示されるレジスタの値を返す。
                    100: // メモリダンプのような用途なので主にアドレスとして使うレジスタのみ。
                    101: uint64
                    102: DebuggerMD_hd64180::GetRegAddr(const char *name) const
                    103: {
                    104:        uint32 addr;
                    105: 
                    106:        if (strcmp(name, "pc") == 0) {
                    107:                addr = cpu->GetPPC();
                    108: 
                    109:        } else if (strcmp(name, "sp") == 0) {
                    110:                addr = cpu->reg.sp;
                    111: 
                    112:        } else if (strcmp(name, "bc") == 0) {
                    113:                addr = cpu->reg.GetBC();
                    114: 
                    115:        } else if (strcmp(name, "de") == 0) {
                    116:                addr = cpu->reg.GetDE();
                    117: 
                    118:        } else if (strcmp(name, "hl") == 0) {
                    119:                addr = cpu->reg.GetHL();
                    120: 
                    121:        } else if (strcmp(name, "ix") == 0) {
                    122:                addr = cpu->reg.ix;
                    123: 
                    124:        } else if (strcmp(name, "iy") == 0) {
                    125:                addr = cpu->reg.iy;
                    126: 
                    127:        } else {
                    128:                return (uint64)-1;
                    129:        }
                    130:        return addr;
                    131: }
                    132: 
                    133: void
                    134: DebuggerMD_hd64180::BackupRegs()
                    135: {
                    136:        prev = cpu->reg;
                    137:        prev_i = cpu->GetI();
                    138: }
                    139: 
                    140: // レジスタ表示系コマンド
                    141: bool
                    142: DebuggerMD_hd64180::ShowRegister(FILE *cons,
                    143:        const std::vector<std::string>& args)
                    144: {
                    145:        // 余分な引数は無視する?
                    146: 
                    147:        if (args[0] == "r") {
                    148:                ShowRegMain(cons);
                    149:                return true;
                    150:        }
                    151:        if (args[0] == "ro") {
                    152:                ShowRegOther(cons);
                    153:                return true;
                    154:        }
                    155: 
                    156:        // 該当なし
                    157:        return false;
                    158: }
                    159: 
                    160: bool
                    161: DebuggerMD_hd64180::ShowRegMain(FILE *cons)
                    162: {
1.1.1.4   root      163:        // AF:00 00 (------)  PC:0000   AF':00 00
1.1       root      164:        // BC:00 00           SP:0000   BC':00 00
1.1.1.4   root      165:        // DE:00 00  IX:0000   I:00     DE':00 00
                    166:        // HL:00 00  IY:0000   R:00     HL':00 00
1.1       root      167: 
                    168:        uint8 reg_i = cpu->GetI();
                    169:        uint8 reg_r = cpu->GetR();
                    170: 
                    171:        bool va = (cpu->reg.a != prev.a);
                    172:        bool vf = (cpu->reg.f.Get() != prev.f.Get());
                    173:        bool vb = (cpu->reg.b != prev.b);
                    174:        bool vc = (cpu->reg.c != prev.c);
                    175:        bool vd = (cpu->reg.d != prev.d);
                    176:        bool ve = (cpu->reg.e != prev.e);
                    177:        bool vh = (cpu->reg.h != prev.h);
                    178:        bool vl = (cpu->reg.l != prev.l);
                    179:        bool vix = (cpu->reg.ix != prev.ix);
                    180:        bool viy = (cpu->reg.iy != prev.iy);
                    181:        bool vsp = (cpu->reg.sp != prev.sp);
                    182: 
                    183:        bool vxa = (cpu->reg.ex.a != prev.ex.a);
                    184:        bool vxf = (cpu->reg.ex.f.Get() != prev.ex.f.Get());
                    185:        bool vxb = (cpu->reg.ex.b != prev.ex.b);
                    186:        bool vxc = (cpu->reg.ex.c != prev.ex.c);
                    187:        bool vxd = (cpu->reg.ex.d != prev.ex.d);
                    188:        bool vxe = (cpu->reg.ex.e != prev.ex.e);
                    189:        bool vxh = (cpu->reg.ex.h != prev.ex.h);
                    190:        bool vxl = (cpu->reg.ex.l != prev.ex.l);
                    191: 
                    192:        bool vi = (reg_i != prev_i);
                    193: 
                    194:        std::string fstr1 = FlagStr(cpu->reg.f);
                    195:        fprintf(cons, "AF:%s%02x%s %s%02x%s (%s)  PC:%04x   "
1.1.1.4   root      196:                        "AF':%s%02x%s %s%02x%s\n",
1.1       root      197:                BOLDIF(va), cpu->reg.a, NORM,
                    198:                BOLDIF(vf), cpu->reg.f.Get(), NORM,
                    199:                fstr1.c_str(),
                    200:                cpu->reg.pc,
                    201:                BOLDIF(vxa), cpu->reg.ex.a, NORM,
1.1.1.4   root      202:                BOLDIF(vxf), cpu->reg.ex.f.Get(), NORM);
1.1       root      203:        fprintf(cons, "BC:%s%02x%s %s%02x%s           SP:%s%04x%s   "
                    204:                        "BC':%s%02x%s %s%02x%s\n",
                    205:                BOLDIF(vb),  cpu->reg.b,        NORM,
                    206:                BOLDIF(vc),  cpu->reg.c,        NORM,
                    207:                BOLDIF(vsp), cpu->reg.sp,       NORM,
                    208:                BOLDIF(vxb), cpu->reg.ex.b,     NORM,
                    209:                BOLDIF(vxc), cpu->reg.ex.c,     NORM);
                    210:        fprintf(cons, "DE:%s%02x%s %s%02x%s  IX:%s%04x%s   I:%s%02x%s     "
                    211:                        "DE':%s%02x%s %s%02x%s\n",
                    212:                BOLDIF(vd),    cpu->reg.d,              NORM,
                    213:                BOLDIF(ve),    cpu->reg.e,              NORM,
                    214:                BOLDIF(vix),   cpu->reg.ix,             NORM,
                    215:                BOLDIF(vi),    reg_i,                   NORM,
                    216:                BOLDIF(vxe),   cpu->reg.ex.d,   NORM,
                    217:                BOLDIF(vxd),   cpu->reg.ex.e,   NORM);
                    218:        fprintf(cons, "HL:%s%02x%s %s%02x%s  IY:%s%04x%s   R:%02x     "
                    219:                        "HL':%s%02x%s %s%02x%s\n",
                    220:                BOLDIF(vh),    cpu->reg.h,              NORM,
                    221:                BOLDIF(vl),    cpu->reg.l,              NORM,
                    222:                BOLDIF(viy),   cpu->reg.iy,             NORM,
                    223:                reg_r,
                    224:                BOLDIF(vxh),   cpu->reg.ex.h,   NORM,
                    225:                BOLDIF(vxl),   cpu->reg.ex.l,   NORM);
                    226: 
                    227:        return true;
                    228: }
                    229: 
                    230: std::string
                    231: DebuggerMD_hd64180::FlagStr(const hd64180flag& f)
                    232: {
                    233:        std::string buf;
                    234: 
                    235:        buf += f.IsS() ? 'S' : '-';
                    236:        buf += f.IsZ() ? 'Z' : '-';
                    237:        buf += f.IsH() ? 'H' : '-';
                    238:        buf += f.IsV() ? 'V' : (f.IsP() ? 'P' : '-');
                    239:        buf += f.IsN() ? 'N' : '-';
                    240:        buf += f.IsC() ? 'C' : '-';
                    241: 
                    242:        return buf;
                    243: }
                    244: 
                    245: bool
                    246: DebuggerMD_hd64180::ShowRegOther(FILE *cons)
                    247: {
                    248:        fprintf(cons, "IEF1: %s\n", cpu->GetIEF1() ? "Enable" : "Disable");
                    249:        fprintf(cons, "IEF2: %s\n", cpu->GetIEF2() ? "Enable" : "Disable");
                    250:        return true;
                    251: }
                    252: 
                    253: // レジスタ表示系コマンドのヘルプ
                    254: /*static*/ const HelpMessages
                    255: DebuggerMD_hd64180::HelpListReg = {
                    256:        { "r",          "Show general registers" },
                    257:        { "ro",         "Show some internal statuses" },
                    258: };
                    259: 
                    260: /*static*/ const HelpMessages
                    261: DebuggerMD_hd64180::HelpReg = {
                    262:        //-----
                    263:        { "r", R"**(
                    264:        Command: r
                    265: 
                    266:        Shows general registers.
                    267:        )**" },
                    268: 
                    269:        //-----
                    270:        { "ro", R"**(
                    271:        Command: ro
                    272: 
                    273:        Show some internal statuses.
                    274:        )**" },
                    275: };
                    276: 
                    277: const HelpMessages&
                    278: DebuggerMD_hd64180::GetHelpListReg() const
                    279: {
                    280:        return HelpListReg;
                    281: }
                    282: 
                    283: const HelpMessages&
                    284: DebuggerMD_hd64180::GetHelpReg() const
                    285: {
                    286:        return HelpReg;
                    287: }
                    288: 
                    289: std::string
                    290: DebuggerMD_hd64180::Disassemble(DebuggerMemoryStream& mem)
                    291: {
                    292:        hd64180disasm dis;
                    293:        if (dis.Exec(&mem) == false) {
1.1.1.5   root      294:                return "dis.Exec() failed.";
1.1       root      295:        }
                    296: 
                    297:        // dis.bin は uint8 列なのでそのままダンプ。
                    298:        std::string str;
                    299:        for (auto v : dis.bin) {
                    300:                str += string_format("%02x ", v);
                    301:        }
                    302:        // ダンプは最長5バイト分
                    303:        str += std::string((5 - dis.bin.size()) * 3, ' ');
                    304: 
                    305:        // ニーモニック
                    306:        str += dis.text;
                    307:        // (あれば) 条件判断
                    308:        str += CondStr(dis.bin);
                    309: 
                    310:        return str;
                    311: }
                    312: 
                    313: // ops が条件命令なら、成立可否などの文字列を返す。
                    314: const char *
                    315: DebuggerMD_hd64180::CondStr(const std::vector<uint8>& ops) const
                    316: {
                    317:        if (ops[0] == 0x10) {   // DJNZ
                    318:                if (cpu->reg.b == 0) {
                    319:                        return " (will expire)";
                    320:                } else {
                    321:                        return " (will take)";
                    322:                }
                    323:        }
                    324: 
                    325:        if ((ops[0] & 0xc7) == 0xc0             // RET f
                    326:         || (ops[0] & 0xc7) == 0xc2             // JP f
                    327:         || (ops[0] & 0xc7) == 0xc4)    // CALL f
                    328:        {
                    329:                if (cpu->reg.f.IsCond((ops[0] >> 3) & 7)) {
                    330:                        return " (will take)";
                    331:                } else {
                    332:                        return " (will not take)";
                    333:                }
                    334:        }
                    335: 
                    336:        // JR は f と同じ形式だが1ビット少ないだけ
                    337:        if ((ops[0] & 0xe7) == 0x20) {
                    338:                if (cpu->reg.f.IsCond((ops[0] >> 3) & 3)) {
                    339:                        return " (will take)";
                    340:                } else {
                    341:                        return " (will not take)";
                    342:                }
                    343:        }
                    344: 
                    345:        // 条件命令ではない
                    346:        return "";
                    347: }
1.1.1.5   root      348: 
                    349: // 命令ニーモニックに対するバイナリを文字列形式で返す。
                    350: // 対応しない場合は "" を返す。cmd_bi 用。
                    351: std::string
                    352: DebuggerMD_hd64180::ParseInst(const std::string& inst) const
                    353: {
                    354:        return "";
                    355: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.