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

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

unix.superglobalmegacorp.com

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