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