|
|
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.