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

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:        mainbus = GetMainbusDevice();
                    130:        mpu = GetMPUDevice();
                    131: 
                    132:        return true;
                    133: }
                    134: 
1.1       root      135: // 例外名を返す (例外履歴用)。
                    136: // 名前がなければ NULL を返す。
                    137: const char *
                    138: VectorTable::GetExceptionName(int vector) const
                    139: {
                    140:        assertmsg(0 <= vector && vector < nametable.size(), "vector=%d", vector);
                    141: 
                    142:        if (__predict_false(vector < 2)) {
1.1.1.2   root      143:                if (gMainApp.Has(VMCap::M68K)) {
1.1       root      144:                        // ベクタテーブル的には 0:"Reset(SP)"、1:"Reset(PC)" のほうが
                    145:                        // 分かりやすいが、例外の名前は 0 が "Reset Exception" で
                    146:                        // 1 は存在しない。
                    147:                        if (vector == 0) {
                    148:                                return "Reset Exception";
                    149:                        } else {
                    150:                                return "(vector 1?)";
                    151:                        }
                    152:                }
                    153:        }
                    154: 
1.1.1.7 ! root      155:        return nametable[vector];
1.1       root      156: }
                    157: 
                    158: // モニタ更新
                    159: void
                    160: VectorTable::MonitorUpdate(Monitor *, TextScreen& screen)
                    161: {
1.1.1.5   root      162: // 0         1         2         3         4         5         6         7
                    163: // 012345678901234567890123456789012345678901234567890123456789012345678901234
                    164: // No.      Offset Address   Name                  ><                    Count
                    165: // $02(  2) $0008  $12345678 0123456789012345678901201234567890123456789012345
1.1       root      166: 
1.1.1.3   root      167:        uint32 vbr = mpu->GetVBR();
1.1       root      168: 
                    169:        // userdata が表示開始位置
                    170:        int v = (int)screen.userdata;
                    171:        int row = screen.GetRow();
                    172:        int vend = v + row - 1;
                    173: 
                    174:        screen.Clear();
                    175: 
                    176:        // 最初の1行は常にヘッダ
                    177:        screen.Print(0, 0, "No.      Offset Address   Name");
1.1.1.5   root      178:        screen.Print(70, 0, "Count");
1.1       root      179: 
                    180:        for (int y = 1; v < vend; v++, y++) {
1.1.1.5   root      181:                screen.Print(0, y, "$%02x(%3u) $%04x", v, v, v * 4);
                    182:                busdata addr = mainbus->Peek4(vbr + v * 4);
1.1.1.4   root      183:                if (__predict_false(addr.IsBusErr())) {
1.1       root      184:                        screen.Print(16, y, "BusErr");
                    185:                } else {
1.1.1.4   root      186:                        screen.Print(16, y, "$%08x", addr.Data());
1.1       root      187:                }
1.1.1.7 ! root      188:                screen.Print(26, y, "%-23s", nametable[v] ?: "");
1.1.1.5   root      189:                screen.Print(49, y, "%26s",
                    190:                        format_number(mpu->excep_counter[v]).c_str());
1.1       root      191:        }
                    192: }
                    193: 
1.1.1.6   root      194: // ベクタ名 (MC680x0)。
                    195: // とりあえず CPU の区別はないことにする。
                    196: /*static*/ std::array<const char * const, 64> VectorTable::name_m680x0 = {
1.1.1.7 ! root      197:        //           01234567890123456789012
1.1       root      198:        /*  0 */        "Reset (SP)",
                    199:        /*  1 */        "Reset (PC)",
                    200:        /*  2 */        "Bus Error",
                    201:        /*  3 */        "Address Error",
                    202:        /*  4 */        "Illegal Instruction",
                    203:        /*  5 */        "Zero Divide",
1.1.1.7 ! root      204:        /*  6 */        "CHK/CHK2 Instruction",
        !           205:        /*  7 */        "TRAP* Instruction",
1.1.1.6   root      206:        /*  8 */        "Privilege Violation",
1.1       root      207:        /*  9 */        "Trace",
1.1.1.6   root      208:        /* 10 */        "Line A emulator",
                    209:        /* 11 */        "Line F emulator",
1.1       root      210:        /* 12 */        NULL,
1.1.1.7 ! root      211:        /* 13 */        "Copro Proto Violation",        // 68030 only
1.1       root      212:        /* 14 */        "Format Error",
1.1.1.7 ! root      213:        /* 15 */        "Uninitialized Interrupt",
1.1       root      214:        /* 16 */        NULL, NULL, NULL, NULL,
                    215:        /* 20 */        NULL, NULL, NULL, NULL,
                    216:        /* 24 */        "Spurious Interrupt",
                    217:        /* 25 */        "Level 1 Interrupt",
                    218:        /* 26 */        "Level 2 Interrupt",
                    219:        /* 27 */        "Level 3 Interrupt",
                    220:        /* 28 */        "Level 4 Interrupt",
                    221:        /* 29 */        "Level 5 Interrupt",
                    222:        /* 30 */        "Level 6 Interrupt",
                    223:        /* 31 */        "Level 7 Interrupt",
                    224:        /* 32 */        "Trap #0",
                    225:        /* 33 */        "Trap #1",
                    226:        /* 34 */        "Trap #2",
                    227:        /* 35 */        "Trap #3",
                    228:        /* 36 */        "Trap #4",
                    229:        /* 37 */        "Trap #5",
                    230:        /* 38 */        "Trap #6",
                    231:        /* 39 */        "Trap #7",
                    232:        /* 40 */        "Trap #8",
                    233:        /* 41 */        "Trap #9",
                    234:        /* 42 */        "Trap #10",
                    235:        /* 43 */        "Trap #11",
                    236:        /* 44 */        "Trap #12",
                    237:        /* 45 */        "Trap #13",
                    238:        /* 46 */        "Trap #14",
                    239:        /* 47 */        "Trap #15",
1.1.1.7 ! root      240:        //           01234567890123456789012
1.1       root      241:        /* 48 */        "FPCP Branch",
1.1.1.7 ! root      242:        /* 49 */        "FPCP Inexcact Result",
1.1       root      243:        /* 50 */        "FPCP Divide by Zero",
                    244:        /* 51 */        "FPCP UnderFlow",
                    245:        /* 52 */        "FPCP Operand Error",
                    246:        /* 53 */        "FPCP OverFlow",
                    247:        /* 54 */        "FPCP Signaling NAN",
1.1.1.7 ! root      248:        /* 55 */        "FPCP Unsupp Data Type",        // 68040 only
        !           249:        /* 56 */        "MMU Configuration Error",      // 68030 only
1.1       root      250:        /* 57 */        NULL,
                    251:        /* 58 */        NULL,
                    252:        /* 59 */        NULL,
                    253:        /* 60 */        NULL,
                    254:        /* 61 */        NULL,
                    255:        /* 62 */        NULL,
                    256:        /* 63 */        NULL,
                    257: };
                    258: 
                    259: // ベクタ名 (X68030)
1.1.1.3   root      260: /*static*/ std::map<int, const char * const> VectorTable::name_x68030 = {
1.1.1.7 ! root      261:        //           01234567890123456789012
1.1.1.3   root      262:        { 0x40,         "MFP Alarm" },
                    263:        { 0x41,         "MFP EXPON" },
                    264:        { 0x42,         "MFP POWSW" },
                    265:        { 0x43,         "MFP FM IRQ" },
                    266:        { 0x44,         "MFP Timer-D" },
                    267:        { 0x45,         "MFP Timer-C" },
                    268:        { 0x46,         "MFP V-Disp" },
                    269:        { 0x47,         "MFP GPIP5" },
                    270:        { 0x48,         "MFP Timer-B" },
                    271:        { 0x49,         "MFP TX Error" },
                    272:        { 0x4a,         "MFP TX Empty" },
                    273:        { 0x4b,         "MFP RX Error" },
                    274:        { 0x4c,         "MFP RX Full" },
                    275:        { 0x4d,         "MFP Timer-A" },
                    276:        { 0x4e,         "MFP CRTC IRQ" },
                    277:        { 0x4f,         "MFP H-Sync" },
                    278: 
                    279:        { 0x50,         "SCC#B TX Empty" },
                    280:        { 0x52,         "SCC#B E/S" },
                    281:        { 0x54,         "SCC#B RX Intr" },
1.1.1.7 ! root      282:        { 0x56,         "SCC#B Special Condition" },
1.1.1.3   root      283:        { 0x58,         "SCC#A TX Empty" },
                    284:        { 0x5a,         "SCC#A E/S" },
                    285:        { 0x5c,         "SCC#A RX Intr" },
1.1.1.7 ! root      286:        { 0x5e,         "SCC#A Special Condition" },
1.1.1.3   root      287: 
1.1.1.7 ! root      288:        //           01234567890123456789012
        !           289:        { 0x60,         "I/O FDC Interrupt" },
        !           290:        { 0x61,         "I/O FDD Interrupt" },
        !           291:        { 0x62,         "I/O HDC Interrupt" },
        !           292:        { 0x63,         "I/O PRN Interrupt" },
1.1.1.3   root      293:        { 0x64,         "DMAC#0 Complete" },
                    294:        { 0x65,         "DMAC#0 Error" },
                    295:        { 0x66,         "DMAC#1 Complete" },
                    296:        { 0x67,         "DMAC#1 Error" },
                    297:        { 0x68,         "DMAC#2 Complete" },
                    298:        { 0x69,         "DMAC#2 Error" },
                    299:        { 0x6a,         "DMAC#3 Complete" },
                    300:        { 0x6b,         "DMAC#3 Error" },
                    301:        { 0x6c,         "SPC Interrupt" },
                    302: 
1.1.1.7 ! root      303:        //           01234567890123456789012
1.1.1.3   root      304:        { 0xf0,         "PSX16x50 Interrupt" },
                    305:        { 0xf6,         "ExSPC Interrupt" },
                    306:        //0xf7,         TS-6BSI
                    307:        { 0xf8,         "Nereid#1 Interrupt" },
                    308:        { 0xf9,         "Neptune-X Interrupt" },
                    309:        { 0xfa,         "Nereid#1 USB" },
                    310:        { 0xfb,         "Nereid#0 USB" },
                    311: };
1.1       root      312: 
1.1.1.3   root      313: // LUNA-I
                    314: /*static*/ std::map<int, const char * const> VectorTable::name_luna1 = {
1.1.1.7 ! root      315:        //           01234567890123456789012
1.1.1.3   root      316:        { 0x19,         "Lv1 Intr (XP Low)" },
                    317:        { 0x1a,         "Lv2 Intr (SPC)" },
                    318:        { 0x1b,         "Lv3 Intr (Lance)" },
                    319:        { 0x1c,         "Lv4 Intr (XP High)" },
1.1.1.7 ! root      320:        { 0x1d,         "Lv5 Intr (System Clock)" },
1.1.1.3   root      321:        { 0x1e,         "Lv6 Intr (SIO)" },
                    322:        { 0x1f,         "Lv7 Intr (NMI)" },
1.1       root      323: };
                    324: 
1.1.1.3   root      325: // NEWS はレベル割り込みと、一部が vectored */
                    326: /*static*/ std::map<int, const char * const> VectorTable::name_news = {
1.1.1.7 ! root      327:        //           01234567890123456789012
1.1.1.3   root      328:        { 0x19,         "Lv1 Intr (AST)" },
                    329:        { 0x1a,         "Lv2 Intr" },
                    330:        { 0x1b,         "Lv3 Intr" },
                    331:        { 0x1c,         "Lv4 Intr (SIC/LAN)" },
                    332:        { 0x1d,         "Lv5 Intr (SCC)" },
1.1.1.7 ! root      333:        { 0x1e,         "Lv6 Intr (System Timer)" },
1.1.1.3   root      334:        { 0x1f,         "Lv7 Intr" },
                    335: 
                    336:        { 0x40,         "SCC" },
1.1       root      337: };
                    338: 
1.1.1.6   root      339: // virt-m68k
                    340: /*static*/ std::map<int, const char * const> VectorTable::name_virt68k = {
1.1.1.7 ! root      341:        //           01234567890123456789012
1.1.1.6   root      342:        { 0x19,         "Lv1 Intr (GFPIC1)" },
                    343:        { 0x1a,         "Lv2 Intr (GFPIC2)" },
                    344:        { 0x1b,         "Lv3 Intr (GFPIC3)" },
                    345:        { 0x1c,         "Lv4 Intr (GFPIC4)" },
                    346:        { 0x1d,         "Lv5 Intr (GFPIC5)" },
                    347:        { 0x1e,         "Lv6 Intr (GFPIC6)" },
                    348:        { 0x1f,         "Lv7 Intr" },
                    349: };
                    350: 
1.1       root      351: // LUNA-88K は先頭11個のみ (残りはコードで処理)
                    352: /*static*/ std::array<const char * const, 11> VectorTable::name_luna88k = {
1.1.1.3   root      353:        //           01234567890123456789012 <- 例外履歴欄の横幅
1.1       root      354:        /*  0 */        "Reset Exception",
                    355:        /*  1 */        "Interrupt Exception",
                    356:        /*  2 */        "Inst Access Exception",
                    357:        /*  3 */        "Data Access Exception",
                    358:        /*  4 */        "Misaligned Access Excep",
                    359:        /*  5 */        "Unimplemented Opcode",
                    360:        /*  6 */        "Priv. Violation Excep.",
                    361:        /*  7 */        "Bounds Check Violation",
                    362:        /*  8 */        "Illegal Integer Divide",
                    363:        /*  9 */        "Int Overflow Exception",
                    364:        /* 10 */        "Error Exception",
1.1.1.3   root      365:        //           01234567890123456789012
1.1       root      366: };

unix.superglobalmegacorp.com

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