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

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 "bus.h"
                     13: #include "mainapp.h"
                     14: #include "mpu.h"
                     15: 
                     16: // グローバル参照用
                     17: VectorTable *gVectorTable;
                     18: 
                     19: // コンストラクタ
1.1.1.2 ! root       20: VectorTable::VectorTable(VMType vmtype)
1.1       root       21:        : inherited("(VectorTable)")
                     22: {
                     23:        // ログは不要
                     24:        ClearAlias();
                     25: 
                     26:        // 表示名を作成。それぞれ微妙に処理が違う…
                     27:        switch (vmtype) {
1.1.1.2 ! root       28:         case VMType::X68030:
        !            29:         case VMType::LUNA1:
1.1       root       30:                InitTableM68030(vmtype);
                     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: 
                     39:        monitor.func = ToMonitorCallback(&VectorTable::MonitorUpdate);
1.1.1.2 ! root       40:        monitor.SetSize(49, 1 + 32);    // ヘッダの1行と全エントリ数
        !            41:        monitor.SetMaxHeight(1 + Size());
1.1       root       42:        monitor.Regist(ID_SUBWIN_VECTOR);
                     43: }
                     44: 
                     45: // デストラクタ
                     46: VectorTable::~VectorTable()
                     47: {
                     48:        gVectorTable = NULL;
                     49: }
                     50: 
                     51: // X68030、LUNA-I の表示名テーブル初期化
                     52: void
1.1.1.2 ! root       53: VectorTable::InitTableM68030(VMType vmtype)
1.1       root       54: {
                     55:        nametable.clear();
                     56:        nametable.resize(256);
                     57: 
                     58:        // まず m68k 標準の名称で埋める
                     59:        for (int v = 0; v < 64; v++) {
                     60:                if (name_m68030[v]) {
                     61:                        nametable[v] = name_m68030[v];
                     62:                }
                     63:        }
                     64: 
1.1.1.2 ! root       65:        if (vmtype == VMType::X68030) {
1.1       root       66:                // X68030 なら、
                     67:                // 全域で、あれば X68030 用の名前で上書き
                     68:                for (int v = 0; v < nametable.size(); v++) {
                     69:                        if (name_x68030[v]) {
                     70:                                nametable[v] = name_x68030[v];
                     71:                        }
                     72:                }
                     73:        } else {
                     74:                // LUNA-I なら、
                     75:                // レベル割り込み名だけ上書き
                     76:                for (int i = 0; i < countof(name_luna1); i++) {
                     77:                        nametable[0x19 + i] = name_luna1[i];
                     78:                }
                     79:        }
                     80: }
                     81: 
                     82: // LUNA-88K の表示名テーブルを初期化
                     83: void
                     84: VectorTable::InitTableLuna88k()
                     85: {
                     86:        nametable.clear();
                     87:        nametable.resize(512);
                     88: 
                     89:        // 先頭から10個くらいだけ連続しているのでテーブルからコピー
                     90:        for (int i = 0; i < countof(name_luna88k); i++) {
                     91:                nametable[i] = name_luna88k[i];
                     92:        }
                     93: 
                     94:        // 以降は不連続で、間が空きすぎているので、ここで代入
                     95: 
                     96:        // SFU
                     97:        // (SFU2〜7 はいいか…)
                     98:        //                01234567890123456789012 <- 例外履歴欄の横幅
                     99:        nametable[114] = "SFU1 Precise Exception";
                    100:        nametable[115] = "SFU1 ImpreciseException";
                    101: 
                    102:        // OpenBSD
                    103:        // XXX 本来は OpenBSD 稼働時に限定すべきだろうけど、そうする意味もない
                    104:        //                01234567890123456789012
                    105:        nametable[450] = "OpenBSD System Call";
                    106:        nametable[451] = "OpenBSD Cache Flush";
                    107:        nametable[503] = "Division by Zero(GCC)";
                    108:        nametable[504] = "OpenBSD stepbpt";
                    109:        nametable[511] = "OpenBSD userbpt";
                    110: }
                    111: 
                    112: // 例外名を返す (ベクタテーブル用)。
                    113: // 名前がなければ "" を返す。
                    114: const char *
                    115: VectorTable::GetTableName(int vector) const
                    116: {
                    117:        assertmsg(0 <= vector && vector < nametable.size(), "vector=%d", vector);
                    118: 
                    119:        return nametable[vector] ?: "";
                    120: }
                    121: 
                    122: // 例外名を返す (例外履歴用)。
                    123: // 名前がなければ NULL を返す。
                    124: const char *
                    125: VectorTable::GetExceptionName(int vector) const
                    126: {
                    127:        assertmsg(0 <= vector && vector < nametable.size(), "vector=%d", vector);
                    128: 
                    129:        if (__predict_false(vector < 2)) {
1.1.1.2 ! root      130:                if (gMainApp.Has(VMCap::M68K)) {
1.1       root      131:                        // ベクタテーブル的には 0:"Reset(SP)"、1:"Reset(PC)" のほうが
                    132:                        // 分かりやすいが、例外の名前は 0 が "Reset Exception" で
                    133:                        // 1 は存在しない。
                    134:                        if (vector == 0) {
                    135:                                return "Reset Exception";
                    136:                        } else {
                    137:                                return "(vector 1?)";
                    138:                        }
                    139:                }
                    140:        }
                    141: 
                    142:        if (__predict_true(nametable[vector] != NULL)) {
                    143:                return nametable[vector];
                    144:        } else {
                    145:                return NULL;
                    146:        }
                    147: }
                    148: 
                    149: // モニタ更新
                    150: void
                    151: VectorTable::MonitorUpdate(Monitor *, TextScreen& screen)
                    152: {
                    153:        // 0         1         2         3         4         5         6
                    154:        // 0123456789012345678901234567890123456789012345678901234567890123456789
                    155:        // No.      Offset Address   Name                         Count
                    156:        // $02(  2) $0008  $12345678 01234567890123456789012 0123456789
                    157: 
                    158:        uint32 vbr = gMPU->GetVBR();
                    159: 
                    160:        // userdata が表示開始位置
                    161:        int v = (int)screen.userdata;
                    162:        int row = screen.GetRow();
                    163:        int vend = v + row - 1;
                    164: 
                    165:        screen.Clear();
                    166: 
                    167:        // 最初の1行は常にヘッダ
                    168:        screen.Print(0, 0, "No.      Offset Address   Name");
                    169:        //screen.Print(57, 0, "Count");
                    170: 
                    171:        for (int y = 1; v < vend; v++, y++) {
                    172:                screen.Print(0, y, "$%02x(%3d) $%04x", v, v, v * 4);
                    173:                uint64 addr = vm_phys_peek_32(vbr + v * 4);
                    174:                if (__predict_false((int64)addr < 0)) {
                    175:                        screen.Print(16, y, "BusErr");
                    176:                } else {
                    177:                        screen.Print(16, y, "$%08x", (uint32)addr);
                    178:                }
                    179:                screen.Print(26, y, "%-23s", GetTableName(v));
                    180:        }
                    181: }
                    182: 
                    183: // ベクタ名 (MC68030 共通)
                    184: /*static*/ std::array<const char * const, 64> VectorTable::name_m68030 = {
                    185:                        //   0123456789012345678 <- 例外履歴欄の横幅
                    186:        /*  0 */        "Reset (SP)",
                    187:        /*  1 */        "Reset (PC)",
                    188:        /*  2 */        "Bus Error",
                    189:        /*  3 */        "Address Error",
                    190:        /*  4 */        "Illegal Instruction",
                    191:        /*  5 */        "Zero Divide",
                    192:        /*  6 */        "CHK/CHK2 Insn",
                    193:        /*  7 */        "TRAPV, *TRAPcc Insn",
                    194:        /*  8 */        "PriviledgeViolation",
                    195:        /*  9 */        "Trace",
                    196:        /* 10 */        "Line 1010 emulator",
                    197:        /* 11 */        "Line 1111 emulator",
                    198:        /* 12 */        NULL,
                    199:        /* 13 */        "CoproProtoViolation",
                    200:        /* 14 */        "Format Error",
                    201:        /* 15 */        "Uninitialized Intr",
                    202:        /* 16 */        NULL, NULL, NULL, NULL,
                    203:        /* 20 */        NULL, NULL, NULL, NULL,
                    204:        /* 24 */        "Spurious Interrupt",
                    205:        /* 25 */        "Level 1 Interrupt",
                    206:        /* 26 */        "Level 2 Interrupt",
                    207:        /* 27 */        "Level 3 Interrupt",
                    208:        /* 28 */        "Level 4 Interrupt",
                    209:        /* 29 */        "Level 5 Interrupt",
                    210:        /* 30 */        "Level 6 Interrupt",
                    211:        /* 31 */        "Level 7 Interrupt",
                    212:        /* 32 */        "Trap #0",
                    213:        /* 33 */        "Trap #1",
                    214:        /* 34 */        "Trap #2",
                    215:        /* 35 */        "Trap #3",
                    216:        /* 36 */        "Trap #4",
                    217:        /* 37 */        "Trap #5",
                    218:        /* 38 */        "Trap #6",
                    219:        /* 39 */        "Trap #7",
                    220:        /* 40 */        "Trap #8",
                    221:        /* 41 */        "Trap #9",
                    222:        /* 42 */        "Trap #10",
                    223:        /* 43 */        "Trap #11",
                    224:        /* 44 */        "Trap #12",
                    225:        /* 45 */        "Trap #13",
                    226:        /* 46 */        "Trap #14",
                    227:        /* 47 */        "Trap #15",
                    228:                        //   0123456789012345678
                    229:        /* 48 */        "FPCP Branch",
                    230:        /* 49 */        "FPCP InexcactResult",
                    231:        /* 50 */        "FPCP Divide by Zero",
                    232:        /* 51 */        "FPCP UnderFlow",
                    233:        /* 52 */        "FPCP Operand Error",
                    234:        /* 53 */        "FPCP OverFlow",
                    235:        /* 54 */        "FPCP Signaling NAN",
                    236:        /* 55 */        NULL,
                    237:        /* 56 */        "MMU Config Error",
                    238:        /* 57 */        NULL,
                    239:        /* 58 */        NULL,
                    240:        /* 59 */        NULL,
                    241:        /* 60 */        NULL,
                    242:        /* 61 */        NULL,
                    243:        /* 62 */        NULL,
                    244:        /* 63 */        NULL,
                    245: };
                    246: 
                    247: // ベクタ名 (X68030)
                    248: /*static*/ std::array<const char * const, 256> VectorTable::name_x68030 = {
                    249:        /* $00 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    250:        /* $08 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    251:        /* $10 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    252:        /* $18 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    253:        /* $20 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    254:        /* $28 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    255:        /* $30 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    256:        /* $38 */       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                    257: 
                    258:                        //   0123456789012345678
                    259:        /* $40 */       "MFP Alarm",
                    260:        /* $41 */       "MFP EXPON",
                    261:        /* $42 */       "MFP POWSW",
                    262:        /* $43 */       "MFP FM IRQ",
                    263:        /* $44 */       "MFP Timer-D",
                    264:        /* $45 */       "MFP Timer-C",
                    265:        /* $46 */       "MFP V-Disp",
                    266:        /* $47 */       "MFP GPIP5",
                    267:        /* $48 */       "MFP Timer-B",
                    268:        /* $49 */       "MFP TX Error",
                    269:        /* $4a */       "MFP TX Empty",
                    270:        /* $4b */       "MFP RX Error",
                    271:        /* $4c */       "MFP RX Full",
                    272:        /* $4d */       "MFP Timer-A",
                    273:        /* $4e */       "MFP CRTC IRQ",
                    274:        /* $4f */       "MFP H-Sync",
                    275:        /* $50 */       "SCC#B TX Empty",
                    276:        /* $51 */       NULL,
                    277:        /* $52 */       "SCC#B E/S",
                    278:        /* $53 */       NULL,
                    279:        /* $54 */       "SCC#B RX Intr",
                    280:        /* $55 */       NULL,
                    281:        /* $56 */       "SCC#B SpCond",
                    282:        /* $57 */       NULL,
                    283:        /* $58 */       "SCC#A TX Empty",
                    284:        /* $59 */       NULL,
                    285:        /* $5a */       "SCC#A E/S",
                    286:        /* $5b */       NULL,
                    287:        /* $5c */       "SCC#A RX Intr",
                    288:        /* $5d */       NULL,
                    289:        /* $5e */       "SCC#A SpCond",
                    290:        /* $5f */       NULL,
                    291: 
                    292:                        //   0123456789012345678
                    293:        /* $60 */       "I/O FDC Intr",
                    294:        /* $61 */       "I/O FDD Intr",
                    295:        /* $62 */       "I/O HDC Intr",
                    296:        /* $63 */       "I/O PRN Intr",
                    297:        /* $64 */       "DMAC#0 Complete",
                    298:        /* $65 */       "DMAC#0 Error",
                    299:        /* $66 */       "DMAC#1 Complete",
                    300:        /* $67 */       "DMAC#1 Error",
                    301:        /* $68 */       "DMAC#2 Complete",
                    302:        /* $69 */       "DMAC#2 Error",
                    303:        /* $6a */       "DMAC#3 Complete",
                    304:        /* $6b */       "DMAC#3 Error",
                    305:        /* $6c */       "SPC Interrupt",
                    306:        /* $6d */       NULL,
                    307:        /* $6e */       NULL,
                    308:        /* $6f */       NULL,
                    309: 
                    310:        /* $70 */       NULL, NULL, NULL, NULL,
                    311:        /* $74 */       NULL, NULL, NULL, NULL,
                    312:        /* $78 */       NULL, NULL, NULL, NULL,
                    313:        /* $7c */       NULL, NULL, NULL, NULL,
                    314:        /* $80 */       NULL, NULL, NULL, NULL, // MIDI
                    315:        /* $84 */       NULL, NULL, NULL, NULL, // MIDI
                    316:        /* $88 */       NULL, NULL, NULL, NULL, // MIDI
                    317:        /* $8c */       NULL, NULL, NULL, NULL, // MIDI
                    318:        /* $90 */       NULL, NULL, NULL, NULL,
                    319:        /* $94 */       NULL, NULL, NULL, NULL,
                    320:        /* $98 */       NULL, NULL, NULL, NULL,
                    321:        /* $9c */       NULL, NULL, NULL, NULL,
                    322:        /* $a0 */       NULL, NULL, NULL, NULL, // MIDI
                    323:        /* $a4 */       NULL, NULL, NULL, NULL, // MIDI
                    324:        /* $a8 */       NULL, NULL, NULL, NULL, // MIDI
                    325:        /* $ac */       NULL, NULL, NULL, NULL, // MIDI
                    326:        /* $b0 */       NULL, NULL, NULL, NULL, // RS-232C
                    327:        /* $b4 */       NULL, NULL, NULL, NULL, // RS-232C
                    328:        /* $b8 */       NULL, NULL, NULL, NULL, // RS-232C
                    329:        /* $bc */       NULL, NULL, NULL, NULL, // RS-232C
                    330:        /* $c0 */       NULL, NULL, NULL, NULL, // RS-232C
                    331:        /* $c4 */       NULL, NULL, NULL, NULL, // RS-232C
                    332:        /* $c8 */       NULL, NULL, NULL, NULL, // RS-232C
                    333:        /* $cc */       NULL, NULL, NULL, NULL, // RS-232C
                    334:        /* $d0 */       NULL, NULL, NULL, NULL,
                    335:        /* $d4 */       NULL, NULL, NULL, NULL,
                    336:        /* $d8 */       NULL, NULL, NULL, NULL,
                    337:        /* $dc */       NULL, NULL, NULL, NULL,
                    338:        /* $e0 */       NULL, NULL, NULL, NULL,
                    339:        /* $e4 */       NULL, NULL, NULL, NULL,
                    340:        /* $e8 */       NULL, NULL, NULL, NULL,
                    341:        /* $ec */       NULL, NULL, NULL, NULL,
                    342: 
                    343:                        //   0123456789012345678
                    344:        /* $f0 */       "PSX16x50 Interrupt",
                    345:        /* $f1 */       NULL,
                    346:        /* $f2 */       NULL,
                    347:        /* $f3 */       NULL,
                    348:        /* $f4 */       NULL,
                    349:        /* $f5 */       NULL,
                    350:        /* $f6 */       "ExSPC Interrupt",
                    351:        /* $f7 */       NULL,   // TS-6BSI
                    352:        /* $f8 */       "Nereid#1 Interrupt",
                    353:        /* $f9 */       "Neptune-X Interrupt",
                    354:        /* $fa */       "Nereid#1 USB",
                    355:        /* $fb */       "Nereid#0 USB",
                    356:        /* $fc */       NULL,
                    357:        /* $fd */       NULL,
                    358:        /* $fe */       NULL,
                    359:        /* $ff */       NULL,
                    360: };
                    361: 
                    362: // LUNA-I はレベル割り込みのみ
                    363: /*static*/ std::array<const char * const, 7> VectorTable::name_luna1 = {
                    364:        //               0123456789012345678 <- 例外履歴欄の横幅
                    365:        /* $19 */       "Lv1 Intr (XP Low)",
                    366:        /* $1a */       "Lv2 Intr (SPC)",
                    367:        /* $1b */       "Lv3 Intr (Lance)",
                    368:        /* $1c */       "Lv4 Intr (XP High)",
                    369:        /* $1d */       "Lv5 Intr (SysClk)",
                    370:        /* $1e */       "Lv6 Intr (SIO)",
                    371:        /* $1f */       "Lv7 Intr (NMI)",
                    372: };
                    373: 
                    374: // LUNA-88K は先頭11個のみ (残りはコードで処理)
                    375: /*static*/ std::array<const char * const, 11> VectorTable::name_luna88k = {
                    376:                        //   01234567890123456789012 <- 例外履歴欄の横幅
                    377:        /*  0 */        "Reset Exception",
                    378:        /*  1 */        "Interrupt Exception",
                    379:        /*  2 */        "Inst Access Exception",
                    380:        /*  3 */        "Data Access Exception",
                    381:        /*  4 */        "Misaligned Access Excep",
                    382:        /*  5 */        "Unimplemented Opcode",
                    383:        /*  6 */        "Priv. Violation Excep.",
                    384:        /*  7 */        "Bounds Check Violation",
                    385:        /*  8 */        "Illegal Integer Divide",
                    386:        /*  9 */        "Int Overflow Exception",
                    387:        /* 10 */        "Error Exception",
                    388:                        //   01234567890123456789012
                    389: };

unix.superglobalmegacorp.com

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