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

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

unix.superglobalmegacorp.com

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