|
|
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.