--- nono/vm/pedec.cpp 2026/04/29 17:04:55 1.1.1.3 +++ nono/vm/pedec.cpp 2026/04/29 17:05:06 1.1.1.4 @@ -24,8 +24,9 @@ PEDECDevice::~PEDECDevice() void PEDECDevice::ResetHard() { - int_asserted = 0; - int_enabled = IntmapSPC; + inherited::ResetHard(); + + intmap_enabled = IntmapSPC; // XXX vector } @@ -50,17 +51,17 @@ PEDECDevice::Write(uint32 offset, uint32 { switch (offset) { case 0: // $E9C001 割り込みマスク - int_enabled = IntmapSPC; - int_enabled |= (data & 0x08) ? IntmapHDD : 0; - int_enabled |= (data & 0x04) ? IntmapFDC : 0; - int_enabled |= (data & 0x02) ? IntmapFDD : 0; - int_enabled |= (data & 0x01) ? IntmapPRT : 0; + intmap_enabled = IntmapSPC; + intmap_enabled |= (data & 0x08) ? IntmapHDD : 0; + intmap_enabled |= (data & 0x04) ? IntmapFDC : 0; + intmap_enabled |= (data & 0x02) ? IntmapFDD : 0; + intmap_enabled |= (data & 0x01) ? IntmapPRT : 0; putlog(1, "割り込みマスク設定 HDD=%d FDC=%d FDD=%d PRT=%d", - ((int_enabled & IntmapHDD) ? 1 : 0), - ((int_enabled & IntmapFDC) ? 1 : 0), - ((int_enabled & IntmapFDD) ? 1 : 0), - ((int_enabled & IntmapPRT) ? 1 : 0)); + ((intmap_enabled & IntmapHDD) ? 1 : 0), + ((intmap_enabled & IntmapFDC) ? 1 : 0), + ((intmap_enabled & IntmapFDD) ? 1 : 0), + ((intmap_enabled & IntmapPRT) ? 1 : 0)); return 0; case 1: // $E9C003 割り込みベクタ @@ -89,66 +90,64 @@ PEDECDevice::Peek(uint32 offset) } } +void +PEDECDevice::MonitorUpdate(TextScreen& screen, uint intr_level, int y) +{ + struct { + const char *name; + uint32 map; + } table[] = { + { "SPC", IntmapSPC }, + { "FDC", IntmapFDC }, + { "FDD", IntmapFDD }, + { "HDD", IntmapHDD }, + { "PRT", IntmapPRT }, + }; + + for (int i = 0; i < countof(table); i++) { + uint32 map = table[i].map; + int clz = __builtin_clz(map); + screen.Puts(3, y, TA::OnOff(intmap & map), table[i].name); + screen.Print(8, y, "%11" PRIu64, counter[clz]); + + if (intr_level >= 1 || (intmap_enabled & map) == 0) { + screen.Puts(21, y, "Mask"); + } + y++; + } +} + // 割り込みステータスレジスタの値を取得。 // (Peek からも呼ばれるので副作用を持たせてはいけない) uint32 PEDECDevice::GetStat() const { uint32 data = 0; - data |= (int_asserted & IntmapFDC) ? 0x80 : 0; - data |= (int_asserted & IntmapFDD) ? 0x40 : 0; - data |= (int_asserted & IntmapPRT) ? 0x20 : 0; - data |= (int_asserted & IntmapHDD) ? 0x10 : 0; - data |= (int_enabled & IntmapHDD) ? 0x08 : 0; - data |= (int_enabled & IntmapFDC) ? 0x04 : 0; - data |= (int_enabled & IntmapFDD) ? 0x02 : 0; - data |= (int_enabled & IntmapPRT) ? 0x01 : 0; + data |= (intmap & IntmapFDC) ? 0x80 : 0; + data |= (intmap & IntmapFDD) ? 0x40 : 0; + data |= (intmap & IntmapPRT) ? 0x20 : 0; + data |= (intmap & IntmapHDD) ? 0x10 : 0; + data |= (intmap_enabled & IntmapHDD) ? 0x08 : 0; + data |= (intmap_enabled & IntmapFDC) ? 0x04 : 0; + data |= (intmap_enabled & IntmapFDD) ? 0x02 : 0; + data |= (intmap_enabled & IntmapPRT) ? 0x01 : 0; return data; } -// 子デバイスが割り込み信号線をアサートした +// 割り込み信号線の状態を変える void -PEDECDevice::AssertINT(Device *source) +PEDECDevice::ChangeInterrupt() { - if (__predict_true(source == gSPC.get())) { - int_asserted |= IntmapSPC; - - } else if (__predict_true(source == gFDC.get())) { - int_asserted |= IntmapFDC; +#if 0 // こんなログ出したいかも // ログ表示のためだけ - if ((int_enabled & IntmapFDC)) { + if ((intmap_enabled & IntmapFDC)) { putlog(1, "FDC からの割り込み要求"); } else { putlog(2, "FDC からの割り込み要求(マスク)"); } +#endif - } else { - PANIC("Unknown interrupt source"); - } - - ChangeInterrupt(); -} - -// 子デバイスが割り込み信号線をネゲートした -void -PEDECDevice::NegateINT(Device *source) -{ - if (__predict_true(source == gSPC.get())) { - int_asserted &= ~IntmapSPC; - } else if (__predict_true(source == gFDC.get())) { - int_asserted &= ~IntmapFDC; - } else { - PANIC("Unknown interrupt source"); - } - - ChangeInterrupt(); -} - -// 割り込み信号線の状態を変える -void -PEDECDevice::ChangeInterrupt() -{ - uint32 stat = (int_asserted & int_enabled); + uint32 stat = (intmap & intmap_enabled); gInterrupt->ChangeINT(this, stat); } @@ -156,7 +155,7 @@ PEDECDevice::ChangeInterrupt() int PEDECDevice::InterruptAcknowledge(int lv) { - uint32 stat = (int_asserted & int_enabled); + uint32 stat = (intmap & intmap_enabled); // SPC と I/O コントローラ担当の4本どっちが優先かは分からないので // SPC を優先しておくのでいいだろう。 @@ -171,3 +170,16 @@ PEDECDevice::InterruptAcknowledge(int lv PANIC("Unknown interrupt acknowledge"); } } + +// デバイスから Intmap 値を引く +uint32 +PEDECDevice::GetIntmap(Device *source) const +{ + if (__predict_true(source == gSPC.get())) { + return IntmapSPC; + } + if (__predict_true(source == gFDC.get())) { + return IntmapFDC; + } + PANIC("Unsupported interrupt device"); +}