|
|
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"
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: // コンストラクタ(オブジェクト名指定あり)
1.1.1.10! root 67: InterruptDevice::InterruptDevice(uint objid_)
1.1.1.7 root 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: {
1.1.1.10! root 215: uint newipl;
1.1 root 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:
1.1.1.10! root 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.10! root 348: screen.Print(0, y, "Lv Device IM=%u", intr_mask);
1.1.1.8 root 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.10! root 354: screen.Print(0, y, "%u", 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;
1.1.1.10! root 442: screen.Print(0, y, "Lv Device IM=%u", intr_mask);
1.1.1.7 root 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;
1.1.1.10! root 448: screen.Print(0, y, "%u", 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.10! root 550: screen.Print(0, y, "Lv Device IM=%u", intr_mask);
1.1.1.7 root 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.10! root 556: screen.Print(0, y, "%u", 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: //
1.1.1.10! root 568: // virt-m68k 仮想割り込みコントローラ
1.1.1.9 root 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;
1.1.1.10! root 662: screen.Print(0, y, "Lv Device IM=%u IRQ 20 10 1",
1.1.1.9 root 663: intr_mask);
664: screen.Puts(72, y, "Count");
665: y++;
666: for (uint32 map : disp_list) {
1.1.1.10! root 667: uint clz = __builtin_clz(map);
! 668: uint lv = (uint)(31 - clz) / 4;
! 669: screen.Print(0, y, "%u", lv);
1.1.1.9 root 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.