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