|
|
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: // コンストラクタ
1.1.1.2 ! root 20: VectorTable::VectorTable(VMType vmtype)
1.1 root 21: : inherited("(VectorTable)")
22: {
23: // ログは不要
24: ClearAlias();
25:
26: // 表示名を作成。それぞれ微妙に処理が違う…
27: switch (vmtype) {
1.1.1.2 ! root 28: case VMType::X68030:
! 29: case VMType::LUNA1:
1.1 root 30: InitTableM68030(vmtype);
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:
39: monitor.func = ToMonitorCallback(&VectorTable::MonitorUpdate);
1.1.1.2 ! root 40: monitor.SetSize(49, 1 + 32); // ヘッダの1行と全エントリ数
! 41: monitor.SetMaxHeight(1 + Size());
1.1 root 42: monitor.Regist(ID_SUBWIN_VECTOR);
43: }
44:
45: // デストラクタ
46: VectorTable::~VectorTable()
47: {
48: gVectorTable = NULL;
49: }
50:
51: // X68030、LUNA-I の表示名テーブル初期化
52: void
1.1.1.2 ! root 53: VectorTable::InitTableM68030(VMType vmtype)
1.1 root 54: {
55: nametable.clear();
56: nametable.resize(256);
57:
58: // まず m68k 標準の名称で埋める
59: for (int v = 0; v < 64; v++) {
60: if (name_m68030[v]) {
61: nametable[v] = name_m68030[v];
62: }
63: }
64:
1.1.1.2 ! root 65: if (vmtype == VMType::X68030) {
1.1 root 66: // X68030 なら、
67: // 全域で、あれば X68030 用の名前で上書き
68: for (int v = 0; v < nametable.size(); v++) {
69: if (name_x68030[v]) {
70: nametable[v] = name_x68030[v];
71: }
72: }
73: } else {
74: // LUNA-I なら、
75: // レベル割り込み名だけ上書き
76: for (int i = 0; i < countof(name_luna1); i++) {
77: nametable[0x19 + i] = name_luna1[i];
78: }
79: }
80: }
81:
82: // LUNA-88K の表示名テーブルを初期化
83: void
84: VectorTable::InitTableLuna88k()
85: {
86: nametable.clear();
87: nametable.resize(512);
88:
89: // 先頭から10個くらいだけ連続しているのでテーブルからコピー
90: for (int i = 0; i < countof(name_luna88k); i++) {
91: nametable[i] = name_luna88k[i];
92: }
93:
94: // 以降は不連続で、間が空きすぎているので、ここで代入
95:
96: // SFU
97: // (SFU2〜7 はいいか…)
98: // 01234567890123456789012 <- 例外履歴欄の横幅
99: nametable[114] = "SFU1 Precise Exception";
100: nametable[115] = "SFU1 ImpreciseException";
101:
102: // OpenBSD
103: // XXX 本来は OpenBSD 稼働時に限定すべきだろうけど、そうする意味もない
104: // 01234567890123456789012
105: nametable[450] = "OpenBSD System Call";
106: nametable[451] = "OpenBSD Cache Flush";
107: nametable[503] = "Division by Zero(GCC)";
108: nametable[504] = "OpenBSD stepbpt";
109: nametable[511] = "OpenBSD userbpt";
110: }
111:
112: // 例外名を返す (ベクタテーブル用)。
113: // 名前がなければ "" を返す。
114: const char *
115: VectorTable::GetTableName(int vector) const
116: {
117: assertmsg(0 <= vector && vector < nametable.size(), "vector=%d", vector);
118:
119: return nametable[vector] ?: "";
120: }
121:
122: // 例外名を返す (例外履歴用)。
123: // 名前がなければ NULL を返す。
124: const char *
125: VectorTable::GetExceptionName(int vector) const
126: {
127: assertmsg(0 <= vector && vector < nametable.size(), "vector=%d", vector);
128:
129: if (__predict_false(vector < 2)) {
1.1.1.2 ! root 130: if (gMainApp.Has(VMCap::M68K)) {
1.1 root 131: // ベクタテーブル的には 0:"Reset(SP)"、1:"Reset(PC)" のほうが
132: // 分かりやすいが、例外の名前は 0 が "Reset Exception" で
133: // 1 は存在しない。
134: if (vector == 0) {
135: return "Reset Exception";
136: } else {
137: return "(vector 1?)";
138: }
139: }
140: }
141:
142: if (__predict_true(nametable[vector] != NULL)) {
143: return nametable[vector];
144: } else {
145: return NULL;
146: }
147: }
148:
149: // モニタ更新
150: void
151: VectorTable::MonitorUpdate(Monitor *, TextScreen& screen)
152: {
153: // 0 1 2 3 4 5 6
154: // 0123456789012345678901234567890123456789012345678901234567890123456789
155: // No. Offset Address Name Count
156: // $02( 2) $0008 $12345678 01234567890123456789012 0123456789
157:
158: uint32 vbr = gMPU->GetVBR();
159:
160: // userdata が表示開始位置
161: int v = (int)screen.userdata;
162: int row = screen.GetRow();
163: int vend = v + row - 1;
164:
165: screen.Clear();
166:
167: // 最初の1行は常にヘッダ
168: screen.Print(0, 0, "No. Offset Address Name");
169: //screen.Print(57, 0, "Count");
170:
171: for (int y = 1; v < vend; v++, y++) {
172: screen.Print(0, y, "$%02x(%3d) $%04x", v, v, v * 4);
173: uint64 addr = vm_phys_peek_32(vbr + v * 4);
174: if (__predict_false((int64)addr < 0)) {
175: screen.Print(16, y, "BusErr");
176: } else {
177: screen.Print(16, y, "$%08x", (uint32)addr);
178: }
179: screen.Print(26, y, "%-23s", GetTableName(v));
180: }
181: }
182:
183: // ベクタ名 (MC68030 共通)
184: /*static*/ std::array<const char * const, 64> VectorTable::name_m68030 = {
185: // 0123456789012345678 <- 例外履歴欄の横幅
186: /* 0 */ "Reset (SP)",
187: /* 1 */ "Reset (PC)",
188: /* 2 */ "Bus Error",
189: /* 3 */ "Address Error",
190: /* 4 */ "Illegal Instruction",
191: /* 5 */ "Zero Divide",
192: /* 6 */ "CHK/CHK2 Insn",
193: /* 7 */ "TRAPV, *TRAPcc Insn",
194: /* 8 */ "PriviledgeViolation",
195: /* 9 */ "Trace",
196: /* 10 */ "Line 1010 emulator",
197: /* 11 */ "Line 1111 emulator",
198: /* 12 */ NULL,
199: /* 13 */ "CoproProtoViolation",
200: /* 14 */ "Format Error",
201: /* 15 */ "Uninitialized Intr",
202: /* 16 */ NULL, NULL, NULL, NULL,
203: /* 20 */ NULL, NULL, NULL, NULL,
204: /* 24 */ "Spurious Interrupt",
205: /* 25 */ "Level 1 Interrupt",
206: /* 26 */ "Level 2 Interrupt",
207: /* 27 */ "Level 3 Interrupt",
208: /* 28 */ "Level 4 Interrupt",
209: /* 29 */ "Level 5 Interrupt",
210: /* 30 */ "Level 6 Interrupt",
211: /* 31 */ "Level 7 Interrupt",
212: /* 32 */ "Trap #0",
213: /* 33 */ "Trap #1",
214: /* 34 */ "Trap #2",
215: /* 35 */ "Trap #3",
216: /* 36 */ "Trap #4",
217: /* 37 */ "Trap #5",
218: /* 38 */ "Trap #6",
219: /* 39 */ "Trap #7",
220: /* 40 */ "Trap #8",
221: /* 41 */ "Trap #9",
222: /* 42 */ "Trap #10",
223: /* 43 */ "Trap #11",
224: /* 44 */ "Trap #12",
225: /* 45 */ "Trap #13",
226: /* 46 */ "Trap #14",
227: /* 47 */ "Trap #15",
228: // 0123456789012345678
229: /* 48 */ "FPCP Branch",
230: /* 49 */ "FPCP InexcactResult",
231: /* 50 */ "FPCP Divide by Zero",
232: /* 51 */ "FPCP UnderFlow",
233: /* 52 */ "FPCP Operand Error",
234: /* 53 */ "FPCP OverFlow",
235: /* 54 */ "FPCP Signaling NAN",
236: /* 55 */ NULL,
237: /* 56 */ "MMU Config Error",
238: /* 57 */ NULL,
239: /* 58 */ NULL,
240: /* 59 */ NULL,
241: /* 60 */ NULL,
242: /* 61 */ NULL,
243: /* 62 */ NULL,
244: /* 63 */ NULL,
245: };
246:
247: // ベクタ名 (X68030)
248: /*static*/ std::array<const char * const, 256> VectorTable::name_x68030 = {
249: /* $00 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
250: /* $08 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
251: /* $10 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
252: /* $18 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
253: /* $20 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
254: /* $28 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
255: /* $30 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
256: /* $38 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
257:
258: // 0123456789012345678
259: /* $40 */ "MFP Alarm",
260: /* $41 */ "MFP EXPON",
261: /* $42 */ "MFP POWSW",
262: /* $43 */ "MFP FM IRQ",
263: /* $44 */ "MFP Timer-D",
264: /* $45 */ "MFP Timer-C",
265: /* $46 */ "MFP V-Disp",
266: /* $47 */ "MFP GPIP5",
267: /* $48 */ "MFP Timer-B",
268: /* $49 */ "MFP TX Error",
269: /* $4a */ "MFP TX Empty",
270: /* $4b */ "MFP RX Error",
271: /* $4c */ "MFP RX Full",
272: /* $4d */ "MFP Timer-A",
273: /* $4e */ "MFP CRTC IRQ",
274: /* $4f */ "MFP H-Sync",
275: /* $50 */ "SCC#B TX Empty",
276: /* $51 */ NULL,
277: /* $52 */ "SCC#B E/S",
278: /* $53 */ NULL,
279: /* $54 */ "SCC#B RX Intr",
280: /* $55 */ NULL,
281: /* $56 */ "SCC#B SpCond",
282: /* $57 */ NULL,
283: /* $58 */ "SCC#A TX Empty",
284: /* $59 */ NULL,
285: /* $5a */ "SCC#A E/S",
286: /* $5b */ NULL,
287: /* $5c */ "SCC#A RX Intr",
288: /* $5d */ NULL,
289: /* $5e */ "SCC#A SpCond",
290: /* $5f */ NULL,
291:
292: // 0123456789012345678
293: /* $60 */ "I/O FDC Intr",
294: /* $61 */ "I/O FDD Intr",
295: /* $62 */ "I/O HDC Intr",
296: /* $63 */ "I/O PRN Intr",
297: /* $64 */ "DMAC#0 Complete",
298: /* $65 */ "DMAC#0 Error",
299: /* $66 */ "DMAC#1 Complete",
300: /* $67 */ "DMAC#1 Error",
301: /* $68 */ "DMAC#2 Complete",
302: /* $69 */ "DMAC#2 Error",
303: /* $6a */ "DMAC#3 Complete",
304: /* $6b */ "DMAC#3 Error",
305: /* $6c */ "SPC Interrupt",
306: /* $6d */ NULL,
307: /* $6e */ NULL,
308: /* $6f */ NULL,
309:
310: /* $70 */ NULL, NULL, NULL, NULL,
311: /* $74 */ NULL, NULL, NULL, NULL,
312: /* $78 */ NULL, NULL, NULL, NULL,
313: /* $7c */ NULL, NULL, NULL, NULL,
314: /* $80 */ NULL, NULL, NULL, NULL, // MIDI
315: /* $84 */ NULL, NULL, NULL, NULL, // MIDI
316: /* $88 */ NULL, NULL, NULL, NULL, // MIDI
317: /* $8c */ NULL, NULL, NULL, NULL, // MIDI
318: /* $90 */ NULL, NULL, NULL, NULL,
319: /* $94 */ NULL, NULL, NULL, NULL,
320: /* $98 */ NULL, NULL, NULL, NULL,
321: /* $9c */ NULL, NULL, NULL, NULL,
322: /* $a0 */ NULL, NULL, NULL, NULL, // MIDI
323: /* $a4 */ NULL, NULL, NULL, NULL, // MIDI
324: /* $a8 */ NULL, NULL, NULL, NULL, // MIDI
325: /* $ac */ NULL, NULL, NULL, NULL, // MIDI
326: /* $b0 */ NULL, NULL, NULL, NULL, // RS-232C
327: /* $b4 */ NULL, NULL, NULL, NULL, // RS-232C
328: /* $b8 */ NULL, NULL, NULL, NULL, // RS-232C
329: /* $bc */ NULL, NULL, NULL, NULL, // RS-232C
330: /* $c0 */ NULL, NULL, NULL, NULL, // RS-232C
331: /* $c4 */ NULL, NULL, NULL, NULL, // RS-232C
332: /* $c8 */ NULL, NULL, NULL, NULL, // RS-232C
333: /* $cc */ NULL, NULL, NULL, NULL, // RS-232C
334: /* $d0 */ NULL, NULL, NULL, NULL,
335: /* $d4 */ NULL, NULL, NULL, NULL,
336: /* $d8 */ NULL, NULL, NULL, NULL,
337: /* $dc */ NULL, NULL, NULL, NULL,
338: /* $e0 */ NULL, NULL, NULL, NULL,
339: /* $e4 */ NULL, NULL, NULL, NULL,
340: /* $e8 */ NULL, NULL, NULL, NULL,
341: /* $ec */ NULL, NULL, NULL, NULL,
342:
343: // 0123456789012345678
344: /* $f0 */ "PSX16x50 Interrupt",
345: /* $f1 */ NULL,
346: /* $f2 */ NULL,
347: /* $f3 */ NULL,
348: /* $f4 */ NULL,
349: /* $f5 */ NULL,
350: /* $f6 */ "ExSPC Interrupt",
351: /* $f7 */ NULL, // TS-6BSI
352: /* $f8 */ "Nereid#1 Interrupt",
353: /* $f9 */ "Neptune-X Interrupt",
354: /* $fa */ "Nereid#1 USB",
355: /* $fb */ "Nereid#0 USB",
356: /* $fc */ NULL,
357: /* $fd */ NULL,
358: /* $fe */ NULL,
359: /* $ff */ NULL,
360: };
361:
362: // LUNA-I はレベル割り込みのみ
363: /*static*/ std::array<const char * const, 7> VectorTable::name_luna1 = {
364: // 0123456789012345678 <- 例外履歴欄の横幅
365: /* $19 */ "Lv1 Intr (XP Low)",
366: /* $1a */ "Lv2 Intr (SPC)",
367: /* $1b */ "Lv3 Intr (Lance)",
368: /* $1c */ "Lv4 Intr (XP High)",
369: /* $1d */ "Lv5 Intr (SysClk)",
370: /* $1e */ "Lv6 Intr (SIO)",
371: /* $1f */ "Lv7 Intr (NMI)",
372: };
373:
374: // LUNA-88K は先頭11個のみ (残りはコードで処理)
375: /*static*/ std::array<const char * const, 11> VectorTable::name_luna88k = {
376: // 01234567890123456789012 <- 例外履歴欄の横幅
377: /* 0 */ "Reset Exception",
378: /* 1 */ "Interrupt Exception",
379: /* 2 */ "Inst Access Exception",
380: /* 3 */ "Data Access Exception",
381: /* 4 */ "Misaligned Access Excep",
382: /* 5 */ "Unimplemented Opcode",
383: /* 6 */ "Priv. Violation Excep.",
384: /* 7 */ "Bounds Check Violation",
385: /* 8 */ "Illegal Integer Divide",
386: /* 9 */ "Int Overflow Exception",
387: /* 10 */ "Error Exception",
388: // 01234567890123456789012
389: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.