|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
1.1.1.6 root 7: //
8: // 割り込みコントローラ
9: //
10:
11: // IODevice
12: // |
13: // | +-----------------+
14: // +--| InterruptDevice | (割り込みコントローラの共通部)
15: // +-----------------+
16: // | +-----------------+
17: // +--| M680x0Interrupt | (m68k 割り込みコントローラの共通部)
18: // | +-----------------+
19: // | |
20: // | | +-----------------+
21: // | +--| X68030Interrupt | (X68030 の割り込みコントローラ)
22: // | | +-----------------+
23: // | |
24: // | | +---------------+
25: // | +--| LunaInterrupt | (LUNA-I の割り込みコントローラ)
1.1.1.9 root 26: // | | +---------------+
27: // | |
28: // | | +---------------+
29: // | +--| NewsInterrupt | (NEWS の割り込みコントローラ)
30: // | | +---------------+
31: // | |
32: // | | +------------------+
1.1.1.10 root 33: // | +--| Virt68kInterrupt | (virt-m68k の割り込みコントローラ)
1.1.1.9 root 34: // | +------------------+
1.1.1.6 root 35: // |
36: // +-- PEDECDevice (X68030 の Lv1 担当コントローラ)
1.1.1.7 root 37: // +-- SysCtlrDevice (LUNA-88K の割り込みコントローラ)
1.1.1.10 root 38: // +-- GFPICDevice (virt-m68k の各レベル担当コントローラ)
1.1.1.6 root 39:
1.1 root 40: #include "interrupt.h"
41: #include "dmac.h"
1.1.1.9 root 42: #include "goldfish_pic.h"
1.1 root 43: #include "lance.h"
44: #include "pedec.h"
1.1.1.11! root 45: #include "m680x0.h"
1.1 root 46: #include "mfp.h"
1.1.1.11! root 47: #include "monitor.h"
1.1 root 48: #include "mpu680x0.h"
1.1.1.7 root 49: #include "newsctlr.h"
1.1.1.6 root 50: #include "nmi.h"
1.1.1.8 root 51: #include "rtl8019as.h"
1.1 root 52: #include "scc.h"
53: #include "sio.h"
54: #include "spc.h"
55: #include "sysclk.h"
56:
57: //
1.1.1.9 root 58: // 割り込みコントローラ (共通部)
1.1 root 59: //
60:
1.1.1.7 root 61: // コンストラクタ(オブジェクト名指定なし)
62: InterruptDevice::InterruptDevice()
63: : InterruptDevice(OBJ_INTERRUPT) // 移譲
1.1.1.4 root 64: {
65: }
66:
1.1.1.7 root 67: // コンストラクタ(オブジェクト名指定あり)
1.1.1.10 root 68: InterruptDevice::InterruptDevice(uint objid_)
1.1.1.7 root 69: : inherited(objid_)
1.1 root 70: {
71: }
72:
73: // デストラクタ
74: InterruptDevice::~InterruptDevice()
75: {
76: }
77:
1.1.1.5 root 78: // リセット
79: void
1.1.1.6 root 80: InterruptDevice::ResetHard(bool poweron)
1.1.1.5 root 81: {
82: memset(&counter, 0, sizeof(counter));
83: }
84:
1.1.1.9 root 85: // 子デバイスを登録する。
86: void
87: InterruptDevice::RegistINT(uint32 intmap_, const char *name_, Device *source_)
88: {
89: for (const auto& m : intmap_list) {
90: assertmsg(m.intmap != intmap_,
91: "intmap=%08x already registered", intmap_);
92: if (source_ != NULL) {
93: assertmsg(m.source != source_,
94: "source=%p already registered", source_);
95: }
96: }
97: intmap_list.emplace_back(intmap_, name_, source_);
98:
99: // 登録された intmap の和
100: intmap_avail |= intmap_;
101: }
102:
103: // デバイスから Intmap 値を引く
104: uint32
105: InterruptDevice::GetIntmap(const Device *source) const
106: {
107: for (const auto& m : intmap_list) {
108: if (m.source == source) {
109: return m.intmap;
110: }
111: }
112:
113: VMPANIC("Unknown interrupt source?");
114: }
115:
116: // Intmap 値から名前を引く
117: const char *
118: InterruptDevice::GetIntName(uint32 intmap_) const
119: {
120: for (const auto& m : intmap_list) {
121: if (m.intmap == intmap_) {
122: return m.name;
123: }
124: }
125:
126: return "???";
127: }
128:
1.1.1.5 root 129: // 子デバイスが割り込み信号線をアサートした
130: void
131: InterruptDevice::AssertINT(Device *source)
132: {
133: uint32 oldmap;
134: uint32 srcmap;
135:
1.1.1.9 root 136: oldmap = intmap_status;
1.1.1.5 root 137: srcmap = GetIntmap(source);
1.1.1.9 root 138: intmap_status |= srcmap;
1.1.1.5 root 139:
1.1.1.9 root 140: if ((oldmap ^ intmap_status) != 0) {
1.1.1.5 root 141: // 立ち上がりエッジでカウント
142: counter[__builtin_clz(srcmap)]++;
143: ChangeInterrupt();
144: }
145: }
146:
147: // 子デバイスが割り込み信号線をネゲートした
148: void
149: InterruptDevice::NegateINT(Device *source)
150: {
151: uint32 oldmap;
152: uint32 srcmap;
153:
1.1.1.9 root 154: oldmap = intmap_status;
1.1.1.5 root 155: srcmap = GetIntmap(source);
1.1.1.9 root 156: intmap_status &= ~srcmap;
1.1.1.5 root 157:
1.1.1.9 root 158: if ((oldmap ^ intmap_status) != 0) {
1.1.1.5 root 159: ChangeInterrupt();
160: }
161: }
1.1 root 162:
1.1.1.8 root 163: // 割り込み信号線の状態を取得
164: bool
165: InterruptDevice::GetINT(const Device *source) const
166: {
167: uint32 srcmap;
168:
169: srcmap = GetIntmap(source);
170:
1.1.1.9 root 171: return (intmap_status & srcmap);
1.1.1.8 root 172: }
173:
174:
1.1 root 175: //
176: // 仮想割り込みコントローラ (m680x0 共通部)
177: //
178:
179: // コンストラクタ
180: M680x0Interrupt::M680x0Interrupt()
181: {
1.1.1.9 root 182: intmap_status = IntmapSentinel;
183: // m680x0 仮想割り込みコントローラにはマスクがないので使わない。
184: // 念のためそれっぽい値を入れておく。
185: intmap_enable = 0xfffffff0;
1.1 root 186: }
187:
188: // デストラクタ
189: M680x0Interrupt::~M680x0Interrupt()
190: {
191: }
192:
1.1.1.7 root 193: // 初期化
194: bool
195: M680x0Interrupt::Init()
196: {
197: if (inherited::Init() == false) {
198: return false;
199: }
200:
1.1.1.9 root 201: mpu680x0 = GetMPU680x0Device(mpu);
202:
1.1.1.7 root 203: return true;
204: }
205:
1.1 root 206: // リセット
207: void
1.1.1.6 root 208: M680x0Interrupt::ResetHard(bool poweron)
1.1 root 209: {
1.1.1.6 root 210: inherited::ResetHard(poweron);
1.1 root 211: }
212:
213: void
1.1.1.5 root 214: M680x0Interrupt::ChangeInterrupt()
1.1 root 215: {
1.1.1.10 root 216: uint newipl;
1.1 root 217:
1.1.1.9 root 218: // intmap_status は最下位ビットを常に立ててあるので 0 にならない
219: newipl = (uint)(31 - __builtin_clz(intmap_status)) / 4;
1.1 root 220:
1.1.1.5 root 221: // 割り込みレベルが変わったら、新しいレベルを通知
222: if (newipl != ipl) {
1.1 root 223: ipl = newipl;
1.1.1.7 root 224: mpu->Interrupt(ipl);
1.1 root 225: }
226: }
227:
228:
229: //
230: // X68030 仮想割り込みコントローラ
231: //
232:
233: // コンストラクタ
234: X68030Interrupt::X68030Interrupt()
235: {
1.1.1.11! root 236: monitor = gMonitorManager->Regist(ID_MONITOR_INTERRUPT, this);
! 237: monitor->func = ToMonitorCallback(&X68030Interrupt::MonitorUpdate);
1.1 root 238: }
239:
240: // デストラクタ
241: X68030Interrupt::~X68030Interrupt()
242: {
243: }
244:
1.1.1.7 root 245: // 初期化
246: bool
247: X68030Interrupt::Init()
248: {
249: if (inherited::Init() == false) {
250: return false;
251: }
252:
253: dmac = GetDMACDevice();
254: mfp = GetMFPDevice();
255: nmi = GetNMIDevice();
256: pedec = GetPEDECDevice();
257: scc = GetSCCDevice();
1.1.1.9 root 258: for (int i = 0; i < 2; i++) {
259: net[i] = gMainApp.FindObject<RTL8019ASDevice>(OBJ_ETHERNET(i));
1.1 root 260: }
1.1.1.9 root 261:
262: // 検索順
263: RegistINT(IntmapMFP, "MFP", mfp);
264: RegistINT(IntmapDMAC, "DMAC", dmac);
265: RegistINT(IntmapPEDEC, "PEDEC", pedec);
266: RegistINT(IntmapSCC, "SCC", scc);
267: if (net[0]) {
268: RegistINT(IntmapNereid0,"Nereid0", net[0]);
269: }
270: if (net[1]) {
271: RegistINT(IntmapNereid1,"Nereid1", net[1]);
272: }
273: RegistINT(IntmapNMI, "NMI", nmi);
274:
275: // 表示順
276: // XXX const uint32 がそのまま push_back() 出来ないようだ
277: disp_list.clear();
278: disp_list.push_back((uint32)IntmapNMI);
279: disp_list.push_back((uint32)IntmapMFP);
280: disp_list.push_back((uint32)IntmapSCC);
281: if (net[0]) {
282: disp_list.push_back((uint32)IntmapNereid0);
1.1 root 283: }
1.1.1.9 root 284: if (net[1]) {
285: disp_list.push_back((uint32)IntmapNereid1);
1.1 root 286: }
1.1.1.9 root 287: disp_list.push_back((uint32)IntmapDMAC);
288: disp_list.push_back((uint32)IntmapPEDEC);
289:
290: // 行数が確定したのでサイズ設定
1.1.1.11! root 291: monitor->SetSize(41, 1 + disp_list.size() + 5/*PEDEC*/);
1.1.1.9 root 292:
293: return true;
1.1 root 294: }
295:
296: // 割り込みアクノリッジに応答する
1.1.1.9 root 297: busdata
1.1 root 298: X68030Interrupt::InterruptAcknowledge(int lv)
299: {
300: switch (lv) {
1.1.1.6 root 301: case 7:
302: return AutoVector;
303:
1.1 root 304: case 6:
1.1.1.7 root 305: return mfp->InterruptAcknowledge();
1.1 root 306:
307: case 5:
1.1.1.7 root 308: return scc->InterruptAcknowledge();
1.1 root 309:
1.1.1.8 root 310: case 4:
1.1.1.9 root 311: if ((intmap_status & IntmapNereid0)) {
312: return net[0]->InterruptAcknowledge();
313: }
314: if ((intmap_status & IntmapNereid1)) {
315: return net[1]->InterruptAcknowledge();
1.1.1.8 root 316: }
317: break;
318:
1.1 root 319: case 3:
1.1.1.7 root 320: return dmac->InterruptAcknowledge();
1.1 root 321:
322: case 1:
1.1.1.7 root 323: return pedec->InterruptAcknowledge(lv);
1.1 root 324:
325: default:
326: break;
327: }
1.1.1.9 root 328:
1.1.1.10 root 329: return BusData::BusErr;
1.1 root 330: }
331:
332: void
1.1.1.4 root 333: X68030Interrupt::MonitorUpdate(Monitor *, TextScreen& screen)
1.1 root 334: {
335: int y;
336:
337: // CPU の割り込み可否は本当は関係ないけど、便宜的に一緒に表示したい
1.1.1.7 root 338: uint intr_mask = mpu680x0->reg.intr_mask;
1.1 root 339:
1.1.1.4 root 340: screen.Clear();
1.1 root 341:
1.1.1.7 root 342: // 0 1 2 3 4
343: // 01234567890123456789012345678901234567890
1.1.1.8 root 344: // Lv Device IM=7 Count
345: // 1 Nereid0 01234567890123456789012345
346: // SPC Mask
1.1.1.7 root 347:
1.1 root 348: y = 0;
1.1.1.10 root 349: screen.Print(0, y, "Lv Device IM=%u", intr_mask);
1.1.1.8 root 350: screen.Puts(36, y, "Count");
1.1.1.7 root 351: y++;
1.1.1.9 root 352: for (uint32 map : disp_list) {
1.1 root 353: int clz = __builtin_clz(map);
354: int lv = (31 - clz) / 4;
1.1.1.10 root 355: screen.Print(0, y, "%u", lv);
1.1.1.9 root 356: screen.Puts(3, y, TA::OnOff(intmap_status & map), GetIntName(map));
1.1.1.6 root 357: if (lv <= intr_mask) {
1.1.1.8 root 358: screen.Puts(11, y, "Mask");
1.1 root 359: }
1.1.1.8 root 360: screen.Print(15, y, "%26s", format_number(counter[clz]).c_str());
1.1 root 361: y++;
362: }
1.1.1.2 root 363:
1.1.1.5 root 364: // PEDEC 分も一緒に表示したい
1.1.1.7 root 365: pedec->MonitorUpdate(screen, intr_mask, y);
1.1 root 366: }
367:
1.1.1.6 root 368:
1.1 root 369: //
370: // LUNA-I 仮想割り込みコントローラ
371: //
372:
373: // コンストラクタ
374: LunaInterrupt::LunaInterrupt()
375: {
1.1.1.11! root 376: monitor = gMonitorManager->Regist(ID_MONITOR_INTERRUPT, this);
! 377: monitor->func = ToMonitorCallback(&LunaInterrupt::MonitorUpdate);
1.1 root 378: }
379:
380: // デストラクタ
381: LunaInterrupt::~LunaInterrupt()
382: {
383: }
384:
1.1.1.7 root 385: // 初期化
386: bool
387: LunaInterrupt::Init()
388: {
389: if (inherited::Init() == false) {
390: return false;
391: }
392:
1.1.1.9 root 393: // 検索順
394: RegistINT(IntmapSysClk, "Clock", GetSysClkDevice());
395: RegistINT(IntmapSPC, "SPC", GetSPCDevice());
396: RegistINT(IntmapSIO, "SIO", GetSIODevice());
397: RegistINT(IntmapLance, "Lance", GetLanceDevice());
398: RegistINT(IntmapXPHigh, "XP(Hi)", DEVICE_XPINT_HIGH);
399: RegistINT(IntmapXPLow, "XP(Lo)", DEVICE_XPINT_LOW);
400: RegistINT(IntmapNMI, "NMI", GetNMIDevice());
401:
402: // 表示順
403: disp_list = {
404: IntmapNMI,
405: IntmapSIO,
406: IntmapSysClk,
407: IntmapXPHigh,
408: IntmapLance,
409: IntmapSPC,
410: IntmapXPLow,
411: };
1.1.1.7 root 412:
1.1.1.9 root 413: // 行数が確定したのでサイズ設定
1.1.1.11! root 414: monitor->SetSize(40, 1 + disp_list.size());
1.1.1.7 root 415:
1.1.1.9 root 416: return true;
1.1 root 417: }
418:
419: // 割り込みアクノリッジに応答する
1.1.1.9 root 420: busdata
1.1 root 421: LunaInterrupt::InterruptAcknowledge(int lv)
422: {
423: // LUNA は全てオートベクタ
424: return AutoVector;
425: }
426:
427: void
1.1.1.4 root 428: LunaInterrupt::MonitorUpdate(Monitor *, TextScreen& screen)
1.1 root 429: {
430: int y;
1.1.1.7 root 431:
432: // CPU の割り込み可否は本当は関係ないけど、便宜的に一緒に表示したい
433: uint intr_mask = mpu680x0->reg.intr_mask;
434:
435: screen.Clear();
436:
437: // 0 1 2 3 4
438: // 01234567890123456789012345678901234567890
439: // Lv Device IM=7 Count
440: // 1 XP(Hi) Mask01234567890123456789012345
441:
442: y = 0;
1.1.1.10 root 443: screen.Print(0, y, "Lv Device IM=%u", intr_mask);
1.1.1.7 root 444: screen.Puts(35, y, "Count");
445: y++;
1.1.1.9 root 446: for (uint32 map : disp_list) {
1.1.1.7 root 447: int clz = __builtin_clz(map);
448: int lv = (31 - clz) / 4;
1.1.1.10 root 449: screen.Print(0, y, "%u", lv);
1.1.1.9 root 450: screen.Puts(3, y, TA::OnOff(intmap_status & map), GetIntName(map));
1.1.1.7 root 451: if (lv <= intr_mask) {
452: screen.Puts(10, y, "Mask");
453: }
454: screen.Print(14, y, "%26s", format_number(counter[clz]).c_str());
455: y++;
456: }
457: }
458:
459:
460: //
461: // NEWS 仮想割り込みコントローラ
462: //
463:
464: // コンストラクタ
465: NewsInterrupt::NewsInterrupt()
466: {
1.1.1.11! root 467: monitor = gMonitorManager->Regist(ID_MONITOR_INTERRUPT, this);
! 468: monitor->func = ToMonitorCallback(&NewsInterrupt::MonitorUpdate);
1.1.1.7 root 469: }
470:
471: // デストラクタ
472: NewsInterrupt::~NewsInterrupt()
473: {
474: }
475:
476: // 初期化
477: bool
478: NewsInterrupt::Init()
479: {
480: if (inherited::Init() == false) {
481: return false;
482: }
483:
1.1.1.9 root 484: // 割り込みアクノリッジで使う
1.1.1.7 root 485: scc = GetSCCDevice();
486:
1.1.1.9 root 487: // 検索順
488: RegistINT(IntmapTimer, "Timer", GetNewsCtlrDevice());
489: RegistINT(IntmapLance, "Lance", GetLanceDevice());
490: RegistINT(IntmapSCC, "SCC", scc);
491:
492: // 表示順
493: disp_list = {
494: IntmapTimer,
495: IntmapSCC,
496: IntmapLance,
497: };
1.1.1.7 root 498:
1.1.1.9 root 499: // 行数が確定したのでサイズ設定
1.1.1.11! root 500: monitor->SetSize(40, 1 + disp_list.size());
1.1.1.9 root 501:
502: return true;
1.1.1.7 root 503: }
504:
505: // 割り込みアクノリッジに応答する
1.1.1.9 root 506: busdata
1.1.1.7 root 507: NewsInterrupt::InterruptAcknowledge(int lv)
508: {
509: // NEWS では 5 の SCC だけベクタで、他はオートベクタ?
510: switch (lv) {
511: case 5:
512: return scc->InterruptAcknowledge();
513:
514: default:
515: return AutoVector;
516: }
517: }
518:
519: // ステータスバイトを読み出す。NewsCtlr から呼ばれる。
520: uint8
521: NewsInterrupt::PeekStatus() const
522: {
523: uint8 data = 0;
524:
1.1.1.9 root 525: if ((intmap_status & IntmapSIC)) {
1.1.1.7 root 526: data |= 0x80;
527: }
1.1.1.9 root 528: if ((intmap_status & IntmapLance)) {
1.1.1.7 root 529: data |= 0x04;
530: }
531:
532: return data;
533: }
534:
535: void
536: NewsInterrupt::MonitorUpdate(Monitor *, TextScreen& screen)
537: {
538: int y;
1.1 root 539:
540: // CPU の割り込み可否は本当は関係ないけど、便宜的に一緒に表示したい
1.1.1.7 root 541: uint intr_mask = mpu680x0->reg.intr_mask;
1.1 root 542:
1.1.1.4 root 543: screen.Clear();
1.1 root 544:
1.1.1.7 root 545: // 0 1 2 3 4
546: // 01234567890123456789012345678901234567890
547: // Lv Device IM=7 Count
548: // 1 XP(Hi) Mask01234567890123456789012345
549:
1.1 root 550: y = 0;
1.1.1.10 root 551: screen.Print(0, y, "Lv Device IM=%u", intr_mask);
1.1.1.7 root 552: screen.Puts(35, y, "Count");
553: y++;
1.1.1.9 root 554: for (uint32 map : disp_list) {
1.1 root 555: int clz = __builtin_clz(map);
556: int lv = (31 - clz) / 4;
1.1.1.10 root 557: screen.Print(0, y, "%u", lv);
1.1.1.9 root 558: screen.Puts(3, y, TA::OnOff(intmap_status & map), GetIntName(map));
1.1.1.6 root 559: if (lv <= intr_mask) {
1.1.1.7 root 560: screen.Puts(10, y, "Mask");
1.1 root 561: }
1.1.1.7 root 562: screen.Print(14, y, "%26s", format_number(counter[clz]).c_str());
1.1 root 563: y++;
564: }
565: }
1.1.1.9 root 566:
567:
568: //
1.1.1.10 root 569: // virt-m68k 仮想割り込みコントローラ
1.1.1.9 root 570: //
571:
572: // コンストラクタ
573: Virt68kInterrupt::Virt68kInterrupt()
574: {
1.1.1.11! root 575: monitor = gMonitorManager->Regist(ID_MONITOR_INTERRUPT, this);
! 576: monitor->func = ToMonitorCallback(&Virt68kInterrupt::MonitorUpdate);
1.1.1.9 root 577: }
578:
579: // デストラクタ
580: Virt68kInterrupt::~Virt68kInterrupt()
581: {
582: }
583:
584: // 初期化
585: bool
586: Virt68kInterrupt::Init()
587: {
588: if (inherited::Init() == false) {
589: return false;
590: }
591:
592: // [0] は無視。
593: gfpic[6] = GetGFPICDevice(6);
594: gfpic[5] = GetGFPICDevice(5);
595: gfpic[4] = GetGFPICDevice(4);
596: gfpic[3] = GetGFPICDevice(3);
597: gfpic[2] = GetGFPICDevice(2);
598: gfpic[1] = GetGFPICDevice(1);
599:
600: // 検索順
601: RegistINT(IntmapGFPIC6, "GFPIC6", gfpic[6]);
602: RegistINT(IntmapGFPIC5, "GFPIC5", gfpic[5]);
603: RegistINT(IntmapGFPIC4, "GFPIC4", gfpic[4]);
604: RegistINT(IntmapGFPIC3, "GFPIC3", gfpic[3]);
605: RegistINT(IntmapGFPIC2, "GFPIC2", gfpic[2]);
606: RegistINT(IntmapGFPIC1, "GFPIC1", gfpic[1]);
607:
608: // 表示順
609: disp_list = {
610: IntmapGFPIC6,
611: IntmapGFPIC5,
612: IntmapGFPIC4,
613: IntmapGFPIC3,
614: IntmapGFPIC2,
615: IntmapGFPIC1,
616: };
617:
618: // ここまでの行数でサイズ設定。
619: // この後各割り込みソースの Init() から GFPIC への RegistIRQ() する
620: // たびに増やされていく。
1.1.1.11! root 621: monitor->SetSize(77, 2 + disp_list.size() + 1);
1.1.1.9 root 622:
623: return true;
624: }
625:
626: void
627: Virt68kInterrupt::IncMonitorHeight()
628: {
1.1.1.11! root 629: auto size = monitor->GetSize();
! 630: monitor->SetSize(size.width, size.height + 1);
1.1.1.9 root 631: }
632:
633: // 割り込みアクノリッジに応答する
634: busdata
635: Virt68kInterrupt::InterruptAcknowledge(int lv)
636: {
637: // ?
638: return AutoVector;
639: }
640:
641: void
642: Virt68kInterrupt::MonitorUpdate(Monitor *, TextScreen& screen)
643: {
644: int y;
645:
646: // CPU の割り込み可否は本当は関係ないけど、便宜的に一緒に表示したい
647: uint intr_mask = mpu680x0->reg.intr_mask;
648: // 各 PIC の状況も一緒に表示したい。picmap の添字はレベル(1-6)
649: std::array<uint32, 7> picmap;
650: for (int lv = 1; lv < picmap.size(); lv++) {
651: picmap[lv] = gfpic[lv]->intmap_status;
652: }
653:
654: screen.Clear();
655:
656: // 0 1 2 3 4 5 6 7
657: // 01234567890123456789012345678901234567890123456789012345678901234567890123456
658: // Lv Device IM=7 IRQ 20 10 1 Count
659: // 1 GFPIC1 Mask 21098765 43210987 65432109 87654321 01234567890123456789012345
660: // E:Enable D:Disable .:NotConnected
661:
662: y = 0;
1.1.1.10 root 663: screen.Print(0, y, "Lv Device IM=%u IRQ 20 10 1",
1.1.1.9 root 664: intr_mask);
665: screen.Puts(72, y, "Count");
666: y++;
667: for (uint32 map : disp_list) {
1.1.1.10 root 668: uint clz = __builtin_clz(map);
669: uint lv = (uint)(31 - clz) / 4;
670: screen.Print(0, y, "%u", lv);
1.1.1.9 root 671: screen.Puts(3, y, TA::OnOff(intmap_status & map), GetIntName(map));
672: if (lv <= intr_mask) {
673: screen.Puts(10, y, "Mask");
674: }
675:
676: // 各入力ピンの状態も表示しないと何も分からない。
677: gfpic[lv]->MonitorUpdateSummary(screen, 15, y);
678:
679: screen.Print(51, y, "%26s", format_number(counter[clz]).c_str());
680: y++;
681: }
682: screen.Puts(15, y, "E:Enable D:Disable .:NotConnected");
683: y++;
684: y++;
685:
686: for (uint32 map : disp_list) {
687: int clz = __builtin_clz(map);
688: int lv = (31 - clz) / 4;
689: y = gfpic[lv]->MonitorUpdateDetail(screen, y, lv);
690: }
691: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.