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

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

unix.superglobalmegacorp.com

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