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