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

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2022 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // ベクタテーブル (モニタ)
                      9: //
                     10: 
                     11: #include "vectortable.h"
                     12: #include "mainapp.h"
1.1.1.3   root       13: #include "mainbus.h"
1.1.1.6 ! root       14: #include "monitor.h"
1.1       root       15: #include "mpu.h"
                     16: 
                     17: // コンストラクタ
1.1.1.2   root       18: VectorTable::VectorTable(VMType vmtype)
1.1.1.3   root       19:        : inherited(OBJ_VECTOR_TABLE)
1.1       root       20: {
                     21:        // ログは不要
                     22:        ClearAlias();
                     23: 
                     24:        // 表示名を作成。それぞれ微妙に処理が違う…
                     25:        switch (vmtype) {
1.1.1.2   root       26:         case VMType::X68030:
                     27:         case VMType::LUNA1:
1.1.1.3   root       28:         case VMType::NEWS:
1.1.1.4   root       29:         case VMType::VIRT68K:
1.1.1.6 ! root       30:                InitTableM680x0(vmtype);
1.1       root       31:                break;
1.1.1.2   root       32:         case VMType::LUNA88K:
1.1       root       33:                InitTableLuna88k();
                     34:                break;
1.1.1.2   root       35:         default:
                     36:                PANIC("invalid vmtype %d", (int)vmtype);
1.1       root       37:        }
                     38: 
1.1.1.6 ! root       39:        monitor = gMonitorManager->Regist(ID_SUBWIN_VECTOR, this);
        !            40:        monitor->func = ToMonitorCallback(&VectorTable::MonitorUpdate);
        !            41:        monitor->SetSize(75, 1 + 32);   // ヘッダの1行と全エントリ数
        !            42:        monitor->SetMaxHeight(1 + Size());
1.1       root       43: }
                     44: 
1.1.1.6 ! root       45: // m68k 機種の表示名テーブル初期化。コンストラクタの一部。
1.1       root       46: void
1.1.1.6 ! root       47: VectorTable::InitTableM680x0(VMType vmtype)
1.1       root       48: {
                     49:        nametable.clear();
                     50:        nametable.resize(256);
                     51: 
1.1.1.6 ! root       52:        // まず m680x0 標準の名称で埋める
1.1       root       53:        for (int v = 0; v < 64; v++) {
1.1.1.6 ! root       54:                if (name_m680x0[v]) {
        !            55:                        nametable[v] = name_m680x0[v];
1.1       root       56:                }
                     57:        }
                     58: 
1.1.1.3   root       59:        // 機種ごとに必要なところだけ上書き
                     60:        const std::map<int, const char * const> *names;
1.1.1.6 ! root       61:        switch (vmtype) {
        !            62:         case VMType::X68030:
1.1.1.3   root       63:                names = &name_x68030;
1.1.1.6 ! root       64:                break;
        !            65:         case VMType::LUNA1:
1.1.1.3   root       66:                names = &name_luna1;
1.1.1.6 ! root       67:                break;
        !            68:         case VMType::NEWS:
1.1.1.3   root       69:                names = &name_news;
1.1.1.6 ! root       70:                break;
        !            71:         case VMType::VIRT68K:
        !            72:                names = &name_virt68k;
        !            73:                break;
        !            74:         default:
        !            75:                names = NULL;
        !            76:                break;
1.1.1.3   root       77:        }
1.1.1.6 ! root       78:        if (names) {
        !            79:                for (const auto& p : *names) {
        !            80:                        int v = p.first;
        !            81:                        const char *name = p.second;
        !            82:                        nametable[v] = name;
        !            83:                }
1.1       root       84:        }
                     85: }
                     86: 
1.1.1.3   root       87: // LUNA-88K の表示名テーブルを初期化。コンストラクタの一部。
1.1       root       88: void
                     89: VectorTable::InitTableLuna88k()
                     90: {
                     91:        nametable.clear();
                     92:        nametable.resize(512);
                     93: 
                     94:        // 先頭から10個くらいだけ連続しているのでテーブルからコピー
                     95:        for (int i = 0; i < countof(name_luna88k); i++) {
                     96:                nametable[i] = name_luna88k[i];
                     97:        }
                     98: 
                     99:        // 以降は不連続で、間が空きすぎているので、ここで代入
                    100: 
                    101:        // SFU
                    102:        // (SFU2〜7 はいいか…)
                    103:        //                01234567890123456789012 <- 例外履歴欄の横幅
                    104:        nametable[114] = "SFU1 Precise Exception";
                    105:        nametable[115] = "SFU1 ImpreciseException";
                    106: 
1.1.1.3   root      107:        // NetBSD/luna88k
                    108:        nametable[128] = "NetBSD System Call";
                    109: 
1.1       root      110:        // OpenBSD
                    111:        // XXX 本来は OpenBSD 稼働時に限定すべきだろうけど、そうする意味もない
                    112:        //                01234567890123456789012
                    113:        nametable[450] = "OpenBSD System Call";
                    114:        nametable[451] = "OpenBSD Cache Flush";
                    115:        nametable[503] = "Division by Zero(GCC)";
                    116:        nametable[504] = "OpenBSD stepbpt";
                    117:        nametable[511] = "OpenBSD userbpt";
                    118: }
                    119: 
1.1.1.3   root      120: // デストラクタ
                    121: VectorTable::~VectorTable()
                    122: {
                    123: }
                    124: 
                    125: // 初期化
                    126: bool
                    127: VectorTable::Init()
                    128: {
                    129:        if (inherited::Init() == false) {
                    130:                return false;
                    131:        }
                    132: 
                    133:        mainbus = GetMainbusDevice();
                    134:        mpu = GetMPUDevice();
                    135: 
                    136:        return true;
                    137: }
                    138: 
1.1       root      139: // 例外名を返す (ベクタテーブル用)。
                    140: // 名前がなければ "" を返す。
                    141: const char *
                    142: VectorTable::GetTableName(int vector) const
                    143: {
                    144:        assertmsg(0 <= vector && vector < nametable.size(), "vector=%d", vector);
                    145: 
                    146:        return nametable[vector] ?: "";
                    147: }
                    148: 
                    149: // 例外名を返す (例外履歴用)。
                    150: // 名前がなければ NULL を返す。
                    151: const char *
                    152: VectorTable::GetExceptionName(int vector) const
                    153: {
                    154:        assertmsg(0 <= vector && vector < nametable.size(), "vector=%d", vector);
                    155: 
                    156:        if (__predict_false(vector < 2)) {
1.1.1.2   root      157:                if (gMainApp.Has(VMCap::M68K)) {
1.1       root      158:                        // ベクタテーブル的には 0:"Reset(SP)"、1:"Reset(PC)" のほうが
                    159:                        // 分かりやすいが、例外の名前は 0 が "Reset Exception" で
                    160:                        // 1 は存在しない。
                    161:                        if (vector == 0) {
                    162:                                return "Reset Exception";
                    163:                        } else {
                    164:                                return "(vector 1?)";
                    165:                        }
                    166:                }
                    167:        }
                    168: 
                    169:        if (__predict_true(nametable[vector] != NULL)) {
                    170:                return nametable[vector];
                    171:        } else {
                    172:                return NULL;
                    173:        }
                    174: }
                    175: 
                    176: // モニタ更新
                    177: void
                    178: VectorTable::MonitorUpdate(Monitor *, TextScreen& screen)
                    179: {
1.1.1.5   root      180: // 0         1         2         3         4         5         6         7
                    181: // 012345678901234567890123456789012345678901234567890123456789012345678901234
                    182: // No.      Offset Address   Name                  ><                    Count
                    183: // $02(  2) $0008  $12345678 0123456789012345678901201234567890123456789012345
1.1       root      184: 
1.1.1.3   root      185:        uint32 vbr = mpu->GetVBR();
1.1       root      186: 
                    187:        // userdata が表示開始位置
                    188:        int v = (int)screen.userdata;
                    189:        int row = screen.GetRow();
                    190:        int vend = v + row - 1;
                    191: 
                    192:        screen.Clear();
                    193: 
                    194:        // 最初の1行は常にヘッダ
                    195:        screen.Print(0, 0, "No.      Offset Address   Name");
1.1.1.5   root      196:        screen.Print(70, 0, "Count");
1.1       root      197: 
                    198:        for (int y = 1; v < vend; v++, y++) {
1.1.1.5   root      199:                screen.Print(0, y, "$%02x(%3u) $%04x", v, v, v * 4);
                    200:                busdata addr = mainbus->Peek4(vbr + v * 4);
1.1.1.4   root      201:                if (__predict_false(addr.IsBusErr())) {
1.1       root      202:                        screen.Print(16, y, "BusErr");
                    203:                } else {
1.1.1.4   root      204:                        screen.Print(16, y, "$%08x", addr.Data());
1.1       root      205:                }
                    206:                screen.Print(26, y, "%-23s", GetTableName(v));
1.1.1.5   root      207:                screen.Print(49, y, "%26s",
                    208:                        format_number(mpu->excep_counter[v]).c_str());
1.1       root      209:        }
                    210: }
                    211: 
1.1.1.6 ! root      212: // ベクタ名 (MC680x0)。
        !           213: // とりあえず CPU の区別はないことにする。
        !           214: /*static*/ std::array<const char * const, 64> VectorTable::name_m680x0 = {
1.1       root      215:                        //   0123456789012345678 <- 例外履歴欄の横幅
                    216:        /*  0 */        "Reset (SP)",
                    217:        /*  1 */        "Reset (PC)",
                    218:        /*  2 */        "Bus Error",
                    219:        /*  3 */        "Address Error",
                    220:        /*  4 */        "Illegal Instruction",
                    221:        /*  5 */        "Zero Divide",
                    222:        /*  6 */        "CHK/CHK2 Insn",
1.1.1.6 ! root      223:        /*  7 */        "TRAPV/*TRAPcc Insn",
        !           224:        /*  8 */        "Privilege Violation",
1.1       root      225:        /*  9 */        "Trace",
1.1.1.6 ! root      226:        /* 10 */        "Line A emulator",
        !           227:        /* 11 */        "Line F emulator",
1.1       root      228:        /* 12 */        NULL,
1.1.1.6 ! root      229:        /* 13 */        "CoproProtoViolation",  // 68030 only
1.1       root      230:        /* 14 */        "Format Error",
                    231:        /* 15 */        "Uninitialized Intr",
                    232:        /* 16 */        NULL, NULL, NULL, NULL,
                    233:        /* 20 */        NULL, NULL, NULL, NULL,
                    234:        /* 24 */        "Spurious Interrupt",
                    235:        /* 25 */        "Level 1 Interrupt",
                    236:        /* 26 */        "Level 2 Interrupt",
                    237:        /* 27 */        "Level 3 Interrupt",
                    238:        /* 28 */        "Level 4 Interrupt",
                    239:        /* 29 */        "Level 5 Interrupt",
                    240:        /* 30 */        "Level 6 Interrupt",
                    241:        /* 31 */        "Level 7 Interrupt",
                    242:        /* 32 */        "Trap #0",
                    243:        /* 33 */        "Trap #1",
                    244:        /* 34 */        "Trap #2",
                    245:        /* 35 */        "Trap #3",
                    246:        /* 36 */        "Trap #4",
                    247:        /* 37 */        "Trap #5",
                    248:        /* 38 */        "Trap #6",
                    249:        /* 39 */        "Trap #7",
                    250:        /* 40 */        "Trap #8",
                    251:        /* 41 */        "Trap #9",
                    252:        /* 42 */        "Trap #10",
                    253:        /* 43 */        "Trap #11",
                    254:        /* 44 */        "Trap #12",
                    255:        /* 45 */        "Trap #13",
                    256:        /* 46 */        "Trap #14",
                    257:        /* 47 */        "Trap #15",
                    258:                        //   0123456789012345678
                    259:        /* 48 */        "FPCP Branch",
                    260:        /* 49 */        "FPCP InexcactResult",
                    261:        /* 50 */        "FPCP Divide by Zero",
                    262:        /* 51 */        "FPCP UnderFlow",
                    263:        /* 52 */        "FPCP Operand Error",
                    264:        /* 53 */        "FPCP OverFlow",
                    265:        /* 54 */        "FPCP Signaling NAN",
1.1.1.6 ! root      266:        /* 55 */        "FPCP UnsuppDataType",  // 68040 only
        !           267:        /* 56 */        "MMU Config Error",             // 68030 only
1.1       root      268:        /* 57 */        NULL,
                    269:        /* 58 */        NULL,
                    270:        /* 59 */        NULL,
                    271:        /* 60 */        NULL,
                    272:        /* 61 */        NULL,
                    273:        /* 62 */        NULL,
                    274:        /* 63 */        NULL,
                    275: };
                    276: 
                    277: // ベクタ名 (X68030)
1.1.1.3   root      278: /*static*/ std::map<int, const char * const> VectorTable::name_x68030 = {
                    279:        //           0123456789012345678
                    280:        { 0x40,         "MFP Alarm" },
                    281:        { 0x41,         "MFP EXPON" },
                    282:        { 0x42,         "MFP POWSW" },
                    283:        { 0x43,         "MFP FM IRQ" },
                    284:        { 0x44,         "MFP Timer-D" },
                    285:        { 0x45,         "MFP Timer-C" },
                    286:        { 0x46,         "MFP V-Disp" },
                    287:        { 0x47,         "MFP GPIP5" },
                    288:        { 0x48,         "MFP Timer-B" },
                    289:        { 0x49,         "MFP TX Error" },
                    290:        { 0x4a,         "MFP TX Empty" },
                    291:        { 0x4b,         "MFP RX Error" },
                    292:        { 0x4c,         "MFP RX Full" },
                    293:        { 0x4d,         "MFP Timer-A" },
                    294:        { 0x4e,         "MFP CRTC IRQ" },
                    295:        { 0x4f,         "MFP H-Sync" },
                    296: 
                    297:        { 0x50,         "SCC#B TX Empty" },
                    298:        { 0x52,         "SCC#B E/S" },
                    299:        { 0x54,         "SCC#B RX Intr" },
                    300:        { 0x56,         "SCC#B SpCond" },
                    301:        { 0x58,         "SCC#A TX Empty" },
                    302:        { 0x5a,         "SCC#A E/S" },
                    303:        { 0x5c,         "SCC#A RX Intr" },
                    304:        { 0x5e,         "SCC#A SpCond" },
                    305: 
                    306:        //           0123456789012345678
                    307:        { 0x60,         "I/O FDC Intr" },
                    308:        { 0x61,         "I/O FDD Intr" },
                    309:        { 0x62,         "I/O HDC Intr" },
                    310:        { 0x63,         "I/O PRN Intr" },
                    311:        { 0x64,         "DMAC#0 Complete" },
                    312:        { 0x65,         "DMAC#0 Error" },
                    313:        { 0x66,         "DMAC#1 Complete" },
                    314:        { 0x67,         "DMAC#1 Error" },
                    315:        { 0x68,         "DMAC#2 Complete" },
                    316:        { 0x69,         "DMAC#2 Error" },
                    317:        { 0x6a,         "DMAC#3 Complete" },
                    318:        { 0x6b,         "DMAC#3 Error" },
                    319:        { 0x6c,         "SPC Interrupt" },
                    320: 
                    321:        //           0123456789012345678
                    322:        { 0xf0,         "PSX16x50 Interrupt" },
                    323:        { 0xf6,         "ExSPC Interrupt" },
                    324:        //0xf7,         TS-6BSI
                    325:        { 0xf8,         "Nereid#1 Interrupt" },
                    326:        { 0xf9,         "Neptune-X Interrupt" },
                    327:        { 0xfa,         "Nereid#1 USB" },
                    328:        { 0xfb,         "Nereid#0 USB" },
                    329: };
1.1       root      330: 
1.1.1.3   root      331: // LUNA-I
                    332: /*static*/ std::map<int, const char * const> VectorTable::name_luna1 = {
                    333:        //               0123456789012345678 <- 例外履歴欄の横幅
                    334:        { 0x19,         "Lv1 Intr (XP Low)" },
                    335:        { 0x1a,         "Lv2 Intr (SPC)" },
                    336:        { 0x1b,         "Lv3 Intr (Lance)" },
                    337:        { 0x1c,         "Lv4 Intr (XP High)" },
                    338:        { 0x1d,         "Lv5 Intr (SysClk)" },
                    339:        { 0x1e,         "Lv6 Intr (SIO)" },
                    340:        { 0x1f,         "Lv7 Intr (NMI)" },
1.1       root      341: };
                    342: 
1.1.1.3   root      343: // NEWS はレベル割り込みと、一部が vectored */
                    344: /*static*/ std::map<int, const char * const> VectorTable::name_news = {
1.1       root      345:        //               0123456789012345678 <- 例外履歴欄の横幅
1.1.1.3   root      346:        { 0x19,         "Lv1 Intr (AST)" },
                    347:        { 0x1a,         "Lv2 Intr" },
                    348:        { 0x1b,         "Lv3 Intr" },
                    349:        { 0x1c,         "Lv4 Intr (SIC/LAN)" },
                    350:        { 0x1d,         "Lv5 Intr (SCC)" },
                    351:        { 0x1e,         "Lv6 Intr (SysTimer)" },
                    352:        { 0x1f,         "Lv7 Intr" },
                    353: 
                    354:        { 0x40,         "SCC" },
1.1       root      355: };
                    356: 
1.1.1.6 ! root      357: // virt-m68k
        !           358: /*static*/ std::map<int, const char * const> VectorTable::name_virt68k = {
        !           359:        //               0123456789012345678 <- 例外履歴欄の横幅
        !           360:        { 0x19,         "Lv1 Intr (GFPIC1)" },
        !           361:        { 0x1a,         "Lv2 Intr (GFPIC2)" },
        !           362:        { 0x1b,         "Lv3 Intr (GFPIC3)" },
        !           363:        { 0x1c,         "Lv4 Intr (GFPIC4)" },
        !           364:        { 0x1d,         "Lv5 Intr (GFPIC5)" },
        !           365:        { 0x1e,         "Lv6 Intr (GFPIC6)" },
        !           366:        { 0x1f,         "Lv7 Intr" },
        !           367: };
        !           368: 
1.1       root      369: // LUNA-88K は先頭11個のみ (残りはコードで処理)
                    370: /*static*/ std::array<const char * const, 11> VectorTable::name_luna88k = {
1.1.1.3   root      371:        //           01234567890123456789012 <- 例外履歴欄の横幅
1.1       root      372:        /*  0 */        "Reset Exception",
                    373:        /*  1 */        "Interrupt Exception",
                    374:        /*  2 */        "Inst Access Exception",
                    375:        /*  3 */        "Data Access Exception",
                    376:        /*  4 */        "Misaligned Access Excep",
                    377:        /*  5 */        "Unimplemented Opcode",
                    378:        /*  6 */        "Priv. Violation Excep.",
                    379:        /*  7 */        "Bounds Check Violation",
                    380:        /*  8 */        "Illegal Integer Divide",
                    381:        /*  9 */        "Int Overflow Exception",
                    382:        /* 10 */        "Error Exception",
1.1.1.3   root      383:        //           01234567890123456789012
1.1       root      384: };

unix.superglobalmegacorp.com

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