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