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

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #include "console.h"
                      8: #include "debugger_private.h"
                      9: #include "debugger_m680x0.h"
                     10: #include "m68030disasm.h"
                     11: #include "mpu.h"
                     12: 
1.1.1.2   root       13: // コンストラクタ
                     14: DebuggerMD_m680x0::DebuggerMD_m680x0(Debugger *parent_, m68kcpu *cpu_)
1.1.1.5   root       15:        : inherited(parent_, Debugger::Arch::M680x0)
1.1.1.2   root       16: {
                     17:        cpu = cpu_;
                     18: 
1.1.1.3   root       19:        // 機種依存変数
                     20:        vector_max = 256;
1.1.1.4   root       21:        inst_bytes = 2;
                     22:        inst_bytes_fixed = 0;
1.1.1.2   root       23: }
                     24: 
                     25: // デストラクタ
                     26: DebuggerMD_m680x0::~DebuggerMD_m680x0()
                     27: {
                     28: }
                     29: 
1.1       root       30: // アドレス変換
                     31: uint64
1.1.1.5   root       32: DebuggerMD_m680x0::TranslateAddr(saddr_t laddr, bool lookup) const
1.1       root       33: {
1.1.1.5   root       34:        uint fc;
1.1       root       35: 
1.1.1.5   root       36:        fc = laddr.IsData() ? FC_DATA : FC_PROG;
                     37:        if (laddr.IsSuper()) {
                     38:                fc |= FC_SUPER;
1.1       root       39:        }
1.1.1.5   root       40: 
                     41:        return m68030_mmu_translate_peek(cpu, (uint32)laddr, fc, lookup);
1.1       root       42: }
                     43: 
                     44: // op が 68030 の条件命令 Bcc, Scc, TRAPcc, DBcc なら true を返す。
                     45: bool
                     46: DebuggerMD_m680x0::IsOPcc(uint16 op)
                     47: {
                     48:        uint16 cc;
                     49: 
                     50:        if ((op & 0xf000) == 0x6000) {
                     51:                cc = (op >> 8) & 0xf;
                     52:                if (cc == 0 || cc == 1) {               // BRA, BSR
                     53:                        return false;
                     54:                } else {
                     55:                        return true;                            // Bcc
                     56:                }
                     57:        }
                     58: 
                     59:        if ((op & 0xf0c0) == 0x50c0) {          // Scc, TRAPcc, DBcc
                     60:                return true;
                     61:        }
                     62: 
                     63:        return false;
                     64: }
                     65: 
                     66: // op が DBcc 命令なら true を返す。
                     67: bool
                     68: DebuggerMD_m680x0::IsDBcc(uint16 op)
                     69: {
                     70:        if ((op & 0xf0f8) == 0x50c8) {          // DBcc
                     71:                return true;
                     72:        }
                     73:        return false;
                     74: }
                     75: 
                     76: // op の cccc 条件が現在の CCR で成立するなら true を返す。
                     77: bool
                     78: DebuggerMD_m680x0::IsCond(uint16 op)
                     79: {
                     80:        bool N = RegIsN;
                     81:        bool Z = RegIsZ;
                     82:        bool V = RegIsV;
                     83:        bool C = RegIsC;
                     84: 
                     85:        switch ((op >> 8) & 0x0f) {
                     86:         case 0:        // T
                     87:                return true;
                     88:         case 1:        // F
                     89:                return false;
                     90:         case 2:        // HI
                     91:                return (!C) && (!Z);
                     92:         case 3:        // LS
                     93:                return C || Z;
                     94:         case 4:        // CC
                     95:                return !C;
                     96:         case 5:        // CS
                     97:                return C;
                     98:         case 6:        // NE
                     99:                return !Z;
                    100:         case 7:        // EQ
                    101:                return Z;
                    102:         case 8:        // VC
                    103:                return !V;
                    104:         case 9:        // VS
                    105:                return V;
                    106:         case 10:       // PL
                    107:                return !N;
                    108:         case 11:       // MI
                    109:                return N;
                    110:         case 12:       // GE
                    111:                return (N && V) || ((!N) && (!V));
                    112:         case 13:       // LT
                    113:                return (N && (!V)) || ((!N) && V);
                    114:         case 14:       // GT
                    115:                return (N && V && (!Z)) || ((!N) && (!V) && (!Z));
                    116:         case 15:       // LE
                    117:                return Z || (N && (!V)) || ((!N) && V);
                    118:         default:
                    119:                __unreachable();
                    120:        }
                    121: }
                    122: 
                    123: // addr 位置の命令が条件命令なら、成立可否などの文字列を返す。
                    124: // Bcc, Scc, TRAPcc 命令なら、条件が成立するかどうか。
                    125: // DBcc 命令ならブランチするかどうか。
                    126: const char *
                    127: DebuggerMD_m680x0::CondStr(const std::vector<uint16>& ir)
                    128: {
                    129:        uint16 op = ir[0];
                    130: 
                    131:        // DBcc 命令なら、ブランチするかどうか
                    132:        // IsOPcc() は DBcc も含んでいるため、IsDBcc() の判定のほうが先。
                    133:        // DBcc は内部でカウンタレジスタを減算してから比較するため、
                    134:        // 命令実行前のカウンタが 0 の時点でループ終了となることに注意。
                    135:        if (IsDBcc(op)) {
                    136:                // 成立したら何もしない
                    137:                if (IsCond(op)) {
                    138:                        return " (will fall)";
                    139:                }
                    140:                // カウンタが -1 なら何もしない
                    141:                uint rr = op & 7;
                    142:                if ((RegD(rr) & 0xffff) == 0) {
                    143:                        return " (will expire)";
                    144:                }
                    145:                // それ以外はブランチ
                    146:                return " (will take)";
                    147:        }
                    148: 
                    149:        // Bcc, Scc, TRAPcc 命令なら条件が成立するかどうか
                    150:        if (IsOPcc(op)) {
                    151:                if (IsCond(op)) {
                    152:                        return " (will take)";
                    153:                } else {
                    154:                        return " (will not take)";
                    155:                }
                    156:        }
                    157: 
                    158:        // (ここで知ってる)条件命令ではない
                    159:        return "";
                    160: }
                    161: 
                    162: void
                    163: DebuggerMD_m680x0::SetStepOut()
                    164: {
                    165:        so_a7 = RegA(7);
                    166:        so_sr = RegSR & 0x3000;
                    167: }
                    168: 
                    169: bool
                    170: DebuggerMD_m680x0::IsStepOut() const
                    171: {
                    172:        return (RegA(7) > so_a7 || (RegSR & 0x3000) != so_sr);
                    173: }
                    174: 
1.1.1.4   root      175: // この命令がステップイン出来るなら true を返す
                    176: bool
1.1.1.5   root      177: DebuggerMD_m680x0::IsOpStepIn(DebuggerMemoryStream& mem)
1.1.1.4   root      178: {
1.1.1.5   root      179:        uint32 op = mem.FetchInst();
                    180: 
1.1.1.4   root      181:        if ((op & 0xfff0) == 0x4e40             // TRAP
                    182:         || (op == 0x4e76)                              // TRAPV
                    183:         || (op & 0xffc0) == 0x4e80             // JSR
                    184:         || (op & 0xf0f8) == 0x50f8             // TRAPcc
                    185:         || (op & 0xff00) == 0x6100             // BSR
                    186:         || (op & 0xfff8) == 0xf278             // FTRAPcc
                    187:        ) {
                    188:                return true;
                    189:        }
                    190: 
                    191:        // IOCS コール(に逆アセンブラで見えるやつ)も一命令扱いにしておく。
                    192:        // XXX 本当は X68k の時だけだが今の所副作用なさげなので
                    193:        if ((op & 0xff00) == 0x7000) {  // MOVEQ to %d0
1.1.1.5   root      194:                uint32 op2 = mem.FetchInst();
1.1.1.4   root      195:                if (op2 == 0x4e4f) {            // TRAP #15
                    196:                        return true;
                    197:                }
                    198:        }
                    199: 
                    200:        return false;
                    201: }
                    202: 
1.1       root      203: // レジスタ名からそのレジスタ値を返す。
                    204: // メモリダンプのような用途なのでアドレスとして使えるアドレスのみ。
                    205: uint64
                    206: DebuggerMD_m680x0::GetRegAddr(const char *name) const
                    207: {
                    208:        uint32 addr;
                    209: 
                    210:        if ((*name | 0x20) == 'a') {
                    211:                addr = RegA(name[1] - '0');
                    212: 
                    213:        } else if ((*name | 0x20) == 'd') {
                    214:                addr = RegD(name[1] - '0');
                    215: 
                    216:        } else if (strcmp(name, "sp") == 0) {
                    217:                addr = RegA(7);
                    218: 
                    219: #if 0
                    220:        } else if (strcmp(name, "usp") == 0) {
                    221:                addr = RegUSP;
                    222: 
                    223:        } else if (strcmp(name, "isp") == 0) {
                    224:                addr = RegISP;
                    225: 
                    226:        } else if (strcmp(name, "msp") == 0) {
                    227:                addr = RegMSP;
                    228: #endif
                    229: 
                    230:        } else if (strcmp(name, "pc") == 0) {
                    231:                addr = RegPC;
                    232: 
                    233:        } else if (strcmp(name, "vbr") == 0) {
                    234:                addr = RegVBR;
                    235: 
                    236:        } else if (strcmp(name, "srp") == 0) {
                    237:                addr = cpu->GetSRPl();
                    238: 
                    239:        } else if (strcmp(name, "crp") == 0) {
                    240:                addr = cpu->GetCRPl();
                    241: 
                    242:        } else {
                    243:                return (uint64)-1;
                    244:        }
                    245:        return addr;
                    246: }
                    247: 
1.1.1.2   root      248: // レジスタ表示系コマンドのヘルプ
                    249: /*static*/ const HelpMessages
1.1.1.5   root      250: DebuggerMD_m680x0::HelpListReg = {
1.1.1.4   root      251:        { "r",          "Show general registers" },
                    252:        { "ra",         "Show ATC" },
                    253:        { "rf",         "Show FPU registers" },
                    254:        { "rm",         "Show MMU registers" },
                    255:        { "ro",         "Show other registers" },
1.1.1.2   root      256: };
                    257: 
1.1.1.5   root      258: /*static*/ const HelpMessages
                    259: DebuggerMD_m680x0::HelpReg = {
                    260:        //-----
                    261:        { "r", R"**(
                    262:        Command: r
                    263: 
                    264:        Shows main registers.
                    265:        )**" },
                    266: 
                    267:        //-----
                    268:        { "ra", R"**(
                    269:        Command: ra
                    270: 
                    271:        Shows m68030 ATC(Address Translation Cache) information.  Note that
                    272:        nono's ATC implementation is very different from the real one (to
                    273:        improve performance).
                    274:        )**" },
                    275: 
                    276:        //-----
                    277:        { "rf", R"**(
                    278:        Command: rf
                    279: 
                    280:        Shows 68881/68882's FPU registers.
                    281:        )**" },
                    282: 
                    283:        //-----
                    284:        { "rm", R"**(
                    285:        Command: rm
                    286: 
                    287:        Shows registers related to MMU and cache.
                    288:        )**" },
                    289: 
                    290:        //-----
                    291:        { "ro", R"**(
                    292:        Command: ro
                    293: 
                    294:        Shows other registers.
                    295:        )**" },
                    296: };
                    297: 
                    298: const HelpMessages&
                    299: DebuggerMD_m680x0::GetHelpListReg() const
                    300: {
                    301:        return HelpListReg;
                    302: }
                    303: 
1.1.1.2   root      304: const HelpMessages&
1.1.1.5   root      305: DebuggerMD_m680x0::GetHelpReg() const
1.1.1.2   root      306: {
1.1.1.5   root      307:        return HelpReg;
1.1.1.2   root      308: }
                    309: 
                    310: // レジスタ表示系コマンド
                    311: bool
                    312: DebuggerMD_m680x0::ShowRegister(Console *cons,
                    313:        const std::vector<std::string>& args)
                    314: {
                    315:        // 余分な引数は無視する?
                    316: 
                    317:        if (args[0] == "r") {
                    318:                ShowRegMain(cons);
                    319:                return true;
                    320:        }
                    321:        if (args[0] == "ra") {
                    322:                ShowRegATC(cons);
                    323:                return true;
                    324:        }
                    325:        if (args[0] == "rf") {
                    326:                ShowRegFPU(cons);
                    327:                return true;
                    328:        }
                    329:        if (args[0] == "rm") {
                    330:                ShowRegMMU(cons);
                    331:                return true;
                    332:        }
                    333:        if (args[0] == "ro") {
                    334:                ShowRegOther(cons);
                    335:                return true;
                    336:        }
                    337: 
                    338:        // 該当なし
                    339:        return false;
                    340: }
                    341: 
                    342: 
1.1       root      343: // レジスタ表示 (基本セット)
                    344: void
                    345: DebuggerMD_m680x0::ShowRegMain(Console *cons)
                    346: {
                    347: /*
                    348: D0:00000070 D4:CCCCCCCC  A0:00FFAA32 A4:CCCCCCCC  SR=F810(S I=0 X----)
                    349: D1:0000FFFF D5:00000000  A1:00000A7A A5:00000A7A
                    350: D2:00FF0000 D6:00000000  A2:CCCCCCCC A6:CCCCCCCC
                    351: D3:CCCCCCCC D7:00000003  A3:CCCCCCCC A7:00001FD8
                    352: */
                    353:        bool vr[16];
                    354: 
                    355:        for (int i = 0; i < 16; i++) {
                    356:                vr[i] = (cpu->reg.da[i] != prev.da[i]);
                    357:        }
                    358: 
                    359:        // 1行目
                    360:        cons->Print("%sD%d:%08x%s %sD%d:%08x%s  %sA%d:%08x%s %sA%d:%08x%s ",
                    361:                BOLDIF(vr[ 0]),  0, RegR( 0), NORM,
                    362:                BOLDIF(vr[ 4]),  4, RegR( 4), NORM,
                    363:                BOLDIF(vr[ 8]),  0, RegR( 8), NORM,
                    364:                BOLDIF(vr[12]),  4, RegR(12), NORM);
                    365: 
                    366:        // 1行目 SR
                    367:        uint16 sr = RegSR;
                    368:        uint16 prevsr = prev.sr_h()
                    369:                | (prev.ccr.IsX() ? M68K_CCR_X : 0)
                    370:                | (prev.ccr.IsN() ? M68K_CCR_N : 0)
                    371:                | (prev.ccr.IsZ() ? M68K_CCR_Z : 0)
                    372:                | (prev.ccr.IsV() ? M68K_CCR_V : 0)
                    373:                | (prev.ccr.IsC() ? M68K_CCR_C : 0);
                    374:        // SR は上位バイトと下位バイトが変化したくらいでいいか?
                    375:        cons->Print(" SR:%s%02x%s%s%02x%s",
                    376:                BOLDIF((sr & 0xff00) != (prevsr & 0xff00)),
                    377:                sr >> 8,
                    378:                NORM,
                    379:                BOLDIF((sr & 0x00ff) != (prevsr & 0x00ff)),
                    380:                sr & 0xff,
                    381:                NORM);
                    382:        cons->Print("(%c I=%d %c%c%c%c%c)\n",
                    383:                (sr & 0x2000) ? 'S' : '-',
                    384:                (sr >> 8) & 7,
                    385:                (sr & M68K_CCR_X) ? 'X' : '-',
                    386:                (sr & M68K_CCR_N) ? 'N' : '-',
                    387:                (sr & M68K_CCR_Z) ? 'Z' : '-',
                    388:                (sr & M68K_CCR_V) ? 'V' : '-',
                    389:                (sr & M68K_CCR_C) ? 'C' : '-');
                    390: 
                    391:        // 2行目
                    392:        cons->Print("%sD%d:%08x%s %sD%d:%08x%s  %sA%d:%08x%s %sA%d:%08x%s\n",
                    393:                BOLDIF(vr[ 1]),  1, RegR( 1), NORM,
                    394:                BOLDIF(vr[ 5]),  5, RegR( 5), NORM,
                    395:                BOLDIF(vr[ 9]),  1, RegR( 9), NORM,
                    396:                BOLDIF(vr[13]),  5, RegR(13), NORM);
                    397: 
                    398:        // 3行目
                    399:        cons->Print("%sD%d:%08x%s %sD%d:%08x%s  %sA%d:%08x%s %sA%d:%08x%s\n",
                    400:                BOLDIF(vr[ 2]),  2, RegR( 2), NORM,
                    401:                BOLDIF(vr[ 6]),  6, RegR( 6), NORM,
                    402:                BOLDIF(vr[10]),  2, RegR(10), NORM,
                    403:                BOLDIF(vr[14]),  6, RegR(14), NORM);
                    404: 
                    405:        // 4行目
                    406:        cons->Print("%sD%d:%08x%s %sD%d:%08x%s  %sA%d:%08x%s %sA%d:%08x%s\n",
                    407:                BOLDIF(vr[ 3]),  3, RegR( 3), NORM,
                    408:                BOLDIF(vr[ 7]),  7, RegR( 7), NORM,
                    409:                BOLDIF(vr[11]),  3, RegR(11), NORM,
                    410:                BOLDIF(vr[15]),  7, RegR(15), NORM);
                    411: }
                    412: 
                    413: // FPU レジスタ表示
                    414: void
                    415: DebuggerMD_m680x0::ShowRegFPU(Console *cons)
                    416: {
                    417: /*
                    418: FP0:0000_12345678_12345678 (-0.1234567890123456789)   FPCR:1234
                    419: FP1:                                                    BS,SN,OP,OV,UF,DZ,I2,I1
                    420: FP2:                                                    RP=xx  RM=xx
                    421: FP3:                                                  FPSR:12345678
                    422: FP4:                                                    N,Z,Inf,NAN Q=$xx
                    423: FP5:                                                    BS,SN,OP,OV,UF,DZ,I2,I1
                    424: FP6:                                                    AXEC
                    425: FP7:                                                  FPIAR:12345678
                    426: */
                    427: 
                    428: #define PUT_FP(n)      do { \
                    429:        uint32 *c_ = cpu->reg.fpframe.fpf_regs + (n) * 3; \
                    430:        uint32 *p_ = prev.fpframe.fpf_regs + (n) * 3; \
                    431:        bool d = (c_[0] ^ p_[0]) | (c_[1] ^ p_[1]) | (c_[2] ^ p_[2]); \
                    432:        cons->Print("%sFP%d:%04xxxxx_%08x_%08x (%-20s)%s ", \
                    433:                BOLDIF(d), (n), c_[0] >> 16, c_[1], c_[2], "notyet", NORM); \
                    434: } while (0)
                    435: 
                    436:        uint32 fpcr, fpsr, fpiar;
                    437:        uint32 ppcr, ppsr, ppiar;
                    438:        static const char * const rpstr[] = {
                    439:                ".EXT",
                    440:                ".SGL",
                    441:                ".DBL",
                    442:                ".???",
                    443:        };
                    444:        static const char * const rmstr[] = {
                    445:                "Near",
                    446:                "Zero",
                    447:                "Minus",
                    448:                "Plus",
                    449:        };
                    450: 
                    451:        fpcr  = cpu->reg.fpframe.fpf_fpcr;
                    452:        fpsr  = cpu->reg.fpframe.fpf_fpsr;
                    453:        fpiar = cpu->reg.fpframe.fpf_fpiar;
                    454:        ppcr  = prev.fpframe.fpf_fpcr;
                    455:        ppsr  = prev.fpframe.fpf_fpsr;
                    456:        ppiar = prev.fpframe.fpf_fpiar;
                    457: 
                    458:        PUT_FP(0);
                    459:        cons->Print("%sFPCR:%04x%s\n", BOLDIF(fpcr != ppcr), fpcr, NORM);
                    460: 
                    461:        PUT_FP(1);
                    462:        cons->Print("  %s %s %s %s %s %s %s %s\n",
                    463:                (fpcr & 0x8000) ? "BS" : "--",
                    464:                (fpcr & 0x4000) ? "SN" : "--",
                    465:                (fpcr & 0x2000) ? "OP" : "--",
                    466:                (fpcr & 0x1000) ? "OV" : "--",
                    467:                (fpcr & 0x0800) ? "UF" : "--",
                    468:                (fpcr & 0x0400) ? "DZ" : "--",
                    469:                (fpcr & 0x0200) ? "I2" : "--",
                    470:                (fpcr & 0x0100) ? "I1" : "--");
                    471: 
                    472:        PUT_FP(2);
                    473:        cons->Print("  RP=%s RM=%s\n",
                    474:                rpstr[(fpcr >> 6) & 3],
                    475:                rmstr[(fpcr >> 4) & 3]);
                    476: 
                    477:        PUT_FP(3);
                    478:        cons->Print("%sFPSR:%08x%s\n", BOLDIF(fpsr != ppsr), fpsr, NORM);
                    479: 
                    480:        PUT_FP(4);
                    481:        uint cc = fpsr >> 24;
                    482:        cons->Print("  %c %c %s %s Q=$%02x\n",
                    483:                (cc & 0x08) ? 'N' : '-',
                    484:                (cc & 0x04) ? 'Z' : '-',
                    485:                (cc & 0x02) ? "Inf" : "---",
                    486:                (cc & 0x01) ? "NAN" : "---",
                    487:                (fpsr >> 16) & 0xff);
                    488: 
                    489:        PUT_FP(5);
                    490:        cons->Print("  %s %s %s %s %s %s %s %s\n",
                    491:                (fpsr & 0x8000) ? "BS" : "--",
                    492:                (fpsr & 0x4000) ? "SN" : "--",
                    493:                (fpsr & 0x2000) ? "OP" : "--",
                    494:                (fpsr & 0x1000) ? "OV" : "--",
                    495:                (fpsr & 0x0800) ? "UF" : "--",
                    496:                (fpsr & 0x0400) ? "DZ" : "--",
                    497:                (fpsr & 0x0200) ? "I2" : "--",
                    498:                (fpsr & 0x0100) ? "I1" : "--");
                    499: 
                    500:        PUT_FP(6);
                    501:        cons->Print("  %s %s %s %s %s\n",
                    502:                (fpsr & 0x80) ? "IOP"  : "---",
                    503:                (fpsr & 0x40) ? "OVFL" : "----",
                    504:                (fpsr & 0x20) ? "UNFL" : "----",
                    505:                (fpsr & 0x10) ? "DZ"   : "--",
                    506:                (fpsr & 0x08) ? "INEX" : "----");
                    507: 
                    508:        PUT_FP(7);
                    509:        cons->Print("%sFPIAR:%08x%s\n", BOLDIF(fpiar != ppiar), fpiar, NORM);
                    510: }
                    511: 
                    512: // MMU レジスタ表示
                    513: void
                    514: DebuggerMD_m680x0::ShowRegMMU(Console *cons)
                    515: {
                    516: /*
                    517: SRP:00001111_22223333 TT0:00001111 TC:00001111 (---)
                    518: CRP:00001111_22223333 TT1:00001111 MMUSR: 0011 (
                    519: */
                    520:        uint64 srp, osrp;
                    521:        uint64 crp, ocrp;
                    522:        uint32 tt0, ott0;
                    523:        uint32 tt1, ott1;
                    524:        uint32 tc,  otc;
                    525:        uint16 sr,  osr;
                    526:        bool p;
                    527:        bool t;
                    528:        bool c;
                    529: 
                    530:        srp = cpu->GetSRP();
                    531:        crp = cpu->GetCRP();
                    532:        tt0 = cpu->GetTT(0);
                    533:        tt1 = cpu->GetTT(1);
                    534:        tc  = cpu->GetTC();
                    535:        sr  = cpu->GetMMUSR();
                    536: 
                    537:        osrp = prev.srp.q;
                    538:        ocrp = prev.crp.q;
                    539:        ott0 = prev.tt[0];
                    540:        ott1 = prev.tt[1];
                    541:        otc  = prev.tc;
                    542:        osr  = prev.mmusr;
                    543: 
                    544:        // 1行目
                    545:        p = (srp != osrp);
                    546:        t = (tt0 != ott0);
                    547:        c = (tc  != otc);
                    548:        cons->Print("%sSRP:%08x_%08x%s  %sTT0:%08x%s(%c%c%c)",
                    549:                BOLDIF(p), (uint32)(srp >> 32), (uint32)srp, NORM,
                    550:                BOLDIF(t), tt0, NORM,
                    551:                (tt0 & m68030TT::E)   ? 'E' : '-',
                    552:                (tt0 & m68030TT::CI)  ? 'C' : '-',
                    553:                (tt0 & m68030TT::RWM) ? '-' : ((tt0 & m68030TT::RW)  ? 'R' : 'W'));
                    554:        cons->Print("  %sTC:%08x%s(%c%c%c)\n",
                    555:                BOLDIF(c), tc, NORM,
                    556:                (tc & m68030TC::TC_E)   ? 'E' : '-',
                    557:                (tc & m68030TC::TC_SRE) ? 'S' : '-',
                    558:                (tc & m68030TC::TC_FCL) ? 'F' : '-');
                    559: 
                    560:        // 2行目
                    561:        p = (crp != ocrp);
                    562:        t = (tt1 != ott1);
                    563:        c = (sr  != osr);
                    564:        cons->Print("%sCRP:%08x_%08x%s  %sTT1:%08x%s(%c%c%c)",
                    565:                BOLDIF(p), uint32(crp >> 32), (uint32)crp, NORM,
                    566:                BOLDIF(t), tt1, NORM,
                    567:                (tt1 & m68030TT::E)   ? 'E' : '-',
                    568:                (tt1 & m68030TT::CI)  ? 'C' : '-',
                    569:                (tt1 & m68030TT::RWM) ? '-' : ((tt1 & m68030TT::RW)  ? 'R' : 'W'));
                    570:        cons->Print("  %sMMUSR: %04x%s(%c%c%c%c%c%c%c N=%d)\n",
                    571:                BOLDIF(c), sr,  NORM,
                    572:                (sr & m68030MMUSR::B) ? 'B' : '-',
                    573:                (sr & m68030MMUSR::L) ? 'L' : '-',
                    574:                (sr & m68030MMUSR::S) ? 'S' : '-',
                    575:                (sr & m68030MMUSR::W) ? 'W' : '-',
                    576:                (sr & m68030MMUSR::I) ? 'I' : '-',
                    577:                (sr & m68030MMUSR::M) ? 'M' : '-',
                    578:                (sr & m68030MMUSR::T) ? 'T' : '-',
                    579:                (sr & m68030MMUSR::N));
                    580: }
                    581: 
                    582: // ATC を表示
                    583: void
                    584: DebuggerMD_m680x0::ShowRegATC(Console *cons)
                    585: {
1.1.1.2   root      586:        parent->ShowMonitor(*gMPUATC);
1.1       root      587: }
                    588: 
                    589: // その他のレジスタを表示
                    590: void
                    591: DebuggerMD_m680x0::ShowRegOther(Console *cons)
                    592: {
                    593:        TextScreen s(80, 2);
                    594: 
                    595:        // 0         1         2         3         4         5         6
                    596:        // 012345678901234567890123456789012345678901234567890123456789012345
                    597:        // CACR:01234567  VBR:01234567  USP:01234567
                    598:        // CAAR:01234567  SFC:0  DFC:0  MSP:01234567
                    599: 
                    600: #define EM(name) ((cpu->reg.name != prev.name) ? TA::Em : TA::Normal)
                    601:        s.Print(0, 0, EM(cacr), "CACR:%08x", cpu->reg.cacr);
                    602:        s.Print(0, 1, EM(caar), "CAAR:%08x", cpu->reg.caar);
                    603: 
                    604:        s.Print(15, 0, EM(vbr), "VBR:%08x", cpu->reg.vbr);
                    605:        s.Print(15, 1, EM(sfc), "SFC:%d", cpu->reg.sfc);
                    606:        s.Print(22, 1, EM(dfc), "DFC:%d", cpu->reg.dfc);
                    607: 
                    608:        // スタック欄はモードによって表示を変える。
                    609:        //              ユーザ       割り込み    マスタ
                    610:        // 1行目      ISP             USP                     USP
                    611:        // 2行目      MSP             MSP                     ISP
                    612:        if (!cpu->reg.s) {
                    613:                s.Print(29, 0, EM(isp), "ISP:%08x", cpu->reg.isp);
                    614:        } else {
                    615:                s.Print(29, 0, EM(usp), "USP:%08x", cpu->reg.usp);
                    616:        }
                    617:        if (!cpu->reg.m) {
                    618:                s.Print(29, 1, EM(msp), "MSP:%08x", cpu->reg.msp);
                    619:        } else {
                    620:                s.Print(29, 1, EM(isp), "ISP:%08x", cpu->reg.isp);
                    621:        }
                    622: 
1.1.1.2   root      623:        parent->ShowTextScreen(s);
1.1       root      624: }
                    625: 
                    626: // 逆アセンブル
                    627: bool
1.1.1.5   root      628: DebuggerMD_m680x0::Disassemble(DebuggerMemoryStream& mem,
1.1       root      629:        std::string& mnemonic, std::vector<uint8>& bin)
                    630: {
1.1.1.5   root      631:        m680x0disasm dis(mem);
                    632:        if (dis.Exec() == false) {
1.1       root      633:                return false;
                    634:        }
                    635:        mnemonic = dis.text;
                    636:        bin = dis.bin;
                    637:        return true;
                    638: }
                    639: 
                    640: // 逆アセンブルをフォーマット (オフライン版)
                    641: std::string
                    642: DebuggerMD_m680x0::FormatDisasm(const std::string& mnemonic,
                    643:        const std::vector<uint8>& bin)
                    644: {
                    645:        // 16進ダンプ
                    646:        std::string dumpbuf;
                    647:        for (int i = 0; i < bin.size(); i += 2) {
                    648:                dumpbuf += string_format("%02x%02x ", bin[i], bin[i + 1]);
                    649:        }
                    650: 
                    651:        // ダンプは5ワード分 (越えたら知らん)
                    652:        return string_format("%-25s%s", dumpbuf.c_str(), mnemonic.c_str());
                    653: }
                    654: 
                    655: // 逆アセンブルをフォーマット (オンライン版)
                    656: std::string
                    657: DebuggerMD_m680x0::FormatDisasmLive(const std::string& mnemonic,
                    658:        const std::vector<uint8>& bin)
                    659: {
                    660:        // オフライン文字列
                    661:        std::string str = FormatDisasm(mnemonic, bin);
                    662: 
                    663:        // bin は uint8 列だが ir は uint16 列なので変換
                    664:        std::vector<uint16> ir;
                    665:        for (int i = 0; i < bin.size(); i += 2) {
                    666:                ir.push_back((bin[i] << 8) | bin[i + 1]);
                    667:        }
                    668: 
                    669:        // 条件判断をする
                    670:        std::string condstr = CondStr(ir);
                    671: 
                    672:        return str + condstr;
                    673: }
1.1.1.4   root      674: 
                    675: // 例外のベクタ番号から名前を取得。
                    676: const char *
                    677: DebuggerMD_m680x0::GetExceptionName(int vector) const
                    678: {
                    679:        return m68030_get_exception_name(vector);
                    680: }

unix.superglobalmegacorp.com

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