|
|
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.2 root 39: monitor.SetSize(49, 1 + 32); // ヘッダの1行と全エントリ数
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: {
167: // 0 1 2 3 4 5 6
168: // 0123456789012345678901234567890123456789012345678901234567890123456789
169: // No. Offset Address Name Count
170: // $02( 2) $0008 $12345678 01234567890123456789012 0123456789
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");
183: //screen.Print(57, 0, "Count");
184:
185: for (int y = 1; v < vend; v++, y++) {
186: screen.Print(0, y, "$%02x(%3d) $%04x", v, v, v * 4);
1.1.1.4 ! root 187: busdata addr = mainbus->Peek32(vbr + v * 4);
! 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));
194: }
195: }
196:
197: // ベクタ名 (MC68030 共通)
198: /*static*/ std::array<const char * const, 64> VectorTable::name_m68030 = {
199: // 0123456789012345678 <- 例外履歴欄の横幅
200: /* 0 */ "Reset (SP)",
201: /* 1 */ "Reset (PC)",
202: /* 2 */ "Bus Error",
203: /* 3 */ "Address Error",
204: /* 4 */ "Illegal Instruction",
205: /* 5 */ "Zero Divide",
206: /* 6 */ "CHK/CHK2 Insn",
207: /* 7 */ "TRAPV, *TRAPcc Insn",
208: /* 8 */ "PriviledgeViolation",
209: /* 9 */ "Trace",
210: /* 10 */ "Line 1010 emulator",
211: /* 11 */ "Line 1111 emulator",
212: /* 12 */ NULL,
213: /* 13 */ "CoproProtoViolation",
214: /* 14 */ "Format Error",
215: /* 15 */ "Uninitialized Intr",
216: /* 16 */ NULL, NULL, NULL, NULL,
217: /* 20 */ NULL, NULL, NULL, NULL,
218: /* 24 */ "Spurious Interrupt",
219: /* 25 */ "Level 1 Interrupt",
220: /* 26 */ "Level 2 Interrupt",
221: /* 27 */ "Level 3 Interrupt",
222: /* 28 */ "Level 4 Interrupt",
223: /* 29 */ "Level 5 Interrupt",
224: /* 30 */ "Level 6 Interrupt",
225: /* 31 */ "Level 7 Interrupt",
226: /* 32 */ "Trap #0",
227: /* 33 */ "Trap #1",
228: /* 34 */ "Trap #2",
229: /* 35 */ "Trap #3",
230: /* 36 */ "Trap #4",
231: /* 37 */ "Trap #5",
232: /* 38 */ "Trap #6",
233: /* 39 */ "Trap #7",
234: /* 40 */ "Trap #8",
235: /* 41 */ "Trap #9",
236: /* 42 */ "Trap #10",
237: /* 43 */ "Trap #11",
238: /* 44 */ "Trap #12",
239: /* 45 */ "Trap #13",
240: /* 46 */ "Trap #14",
241: /* 47 */ "Trap #15",
242: // 0123456789012345678
243: /* 48 */ "FPCP Branch",
244: /* 49 */ "FPCP InexcactResult",
245: /* 50 */ "FPCP Divide by Zero",
246: /* 51 */ "FPCP UnderFlow",
247: /* 52 */ "FPCP Operand Error",
248: /* 53 */ "FPCP OverFlow",
249: /* 54 */ "FPCP Signaling NAN",
250: /* 55 */ NULL,
251: /* 56 */ "MMU Config Error",
252: /* 57 */ NULL,
253: /* 58 */ NULL,
254: /* 59 */ NULL,
255: /* 60 */ NULL,
256: /* 61 */ NULL,
257: /* 62 */ NULL,
258: /* 63 */ NULL,
259: };
260:
261: // ベクタ名 (X68030)
1.1.1.3 root 262: /*static*/ std::map<int, const char * const> VectorTable::name_x68030 = {
263: // 0123456789012345678
264: { 0x40, "MFP Alarm" },
265: { 0x41, "MFP EXPON" },
266: { 0x42, "MFP POWSW" },
267: { 0x43, "MFP FM IRQ" },
268: { 0x44, "MFP Timer-D" },
269: { 0x45, "MFP Timer-C" },
270: { 0x46, "MFP V-Disp" },
271: { 0x47, "MFP GPIP5" },
272: { 0x48, "MFP Timer-B" },
273: { 0x49, "MFP TX Error" },
274: { 0x4a, "MFP TX Empty" },
275: { 0x4b, "MFP RX Error" },
276: { 0x4c, "MFP RX Full" },
277: { 0x4d, "MFP Timer-A" },
278: { 0x4e, "MFP CRTC IRQ" },
279: { 0x4f, "MFP H-Sync" },
280:
281: { 0x50, "SCC#B TX Empty" },
282: { 0x52, "SCC#B E/S" },
283: { 0x54, "SCC#B RX Intr" },
284: { 0x56, "SCC#B SpCond" },
285: { 0x58, "SCC#A TX Empty" },
286: { 0x5a, "SCC#A E/S" },
287: { 0x5c, "SCC#A RX Intr" },
288: { 0x5e, "SCC#A SpCond" },
289:
290: // 0123456789012345678
291: { 0x60, "I/O FDC Intr" },
292: { 0x61, "I/O FDD Intr" },
293: { 0x62, "I/O HDC Intr" },
294: { 0x63, "I/O PRN Intr" },
295: { 0x64, "DMAC#0 Complete" },
296: { 0x65, "DMAC#0 Error" },
297: { 0x66, "DMAC#1 Complete" },
298: { 0x67, "DMAC#1 Error" },
299: { 0x68, "DMAC#2 Complete" },
300: { 0x69, "DMAC#2 Error" },
301: { 0x6a, "DMAC#3 Complete" },
302: { 0x6b, "DMAC#3 Error" },
303: { 0x6c, "SPC Interrupt" },
304:
305: // 0123456789012345678
306: { 0xf0, "PSX16x50 Interrupt" },
307: { 0xf6, "ExSPC Interrupt" },
308: //0xf7, TS-6BSI
309: { 0xf8, "Nereid#1 Interrupt" },
310: { 0xf9, "Neptune-X Interrupt" },
311: { 0xfa, "Nereid#1 USB" },
312: { 0xfb, "Nereid#0 USB" },
313: };
1.1 root 314:
1.1.1.3 root 315: // LUNA-I
316: /*static*/ std::map<int, const char * const> VectorTable::name_luna1 = {
317: // 0123456789012345678 <- 例外履歴欄の横幅
318: { 0x19, "Lv1 Intr (XP Low)" },
319: { 0x1a, "Lv2 Intr (SPC)" },
320: { 0x1b, "Lv3 Intr (Lance)" },
321: { 0x1c, "Lv4 Intr (XP High)" },
322: { 0x1d, "Lv5 Intr (SysClk)" },
323: { 0x1e, "Lv6 Intr (SIO)" },
324: { 0x1f, "Lv7 Intr (NMI)" },
1.1 root 325: };
326:
1.1.1.3 root 327: // NEWS はレベル割り込みと、一部が vectored */
328: /*static*/ std::map<int, const char * const> VectorTable::name_news = {
1.1 root 329: // 0123456789012345678 <- 例外履歴欄の横幅
1.1.1.3 root 330: { 0x19, "Lv1 Intr (AST)" },
331: { 0x1a, "Lv2 Intr" },
332: { 0x1b, "Lv3 Intr" },
333: { 0x1c, "Lv4 Intr (SIC/LAN)" },
334: { 0x1d, "Lv5 Intr (SCC)" },
335: { 0x1e, "Lv6 Intr (SysTimer)" },
336: { 0x1f, "Lv7 Intr" },
337:
338: { 0x40, "SCC" },
1.1 root 339: };
340:
341: // LUNA-88K は先頭11個のみ (残りはコードで処理)
342: /*static*/ std::array<const char * const, 11> VectorTable::name_luna88k = {
1.1.1.3 root 343: // 01234567890123456789012 <- 例外履歴欄の横幅
1.1 root 344: /* 0 */ "Reset Exception",
345: /* 1 */ "Interrupt Exception",
346: /* 2 */ "Inst Access Exception",
347: /* 3 */ "Data Access Exception",
348: /* 4 */ "Misaligned Access Excep",
349: /* 5 */ "Unimplemented Opcode",
350: /* 6 */ "Priv. Violation Excep.",
351: /* 7 */ "Bounds Check Violation",
352: /* 8 */ "Illegal Integer Divide",
353: /* 9 */ "Int Overflow Exception",
354: /* 10 */ "Error Exception",
1.1.1.3 root 355: // 01234567890123456789012
1.1 root 356: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.