--- nono/vm/sysctlr.cpp 2026/04/29 17:05:24 1.1.1.12 +++ nono/vm/sysctlr.cpp 2026/04/29 17:05:37 1.1.1.15 @@ -84,17 +84,18 @@ // 想定される回路 // // [割り込みソース] -// 1:(XP低レベル|SOFTINT レジスタ $6900000n) -// | 2: -// | | 3:SPC -// | | | 4:(LANCE|拡張スロット?) -// | | | | 5:(XP高レベル|拡張PC98?|シリアル?) -// | | | | | 6:システムクロック -// | | | | | | 7:ABRTスイッチ -// V V V V V V | -// +---------------------+ | -// | 割り込みマスク | | (R:bit23-18, W:bit31-26) -// +---------------------+ | +// 7:ABRT スイッチ +// | 6:システムクロック +// | | 5:(シリアル | XP 高レベル | 拡張 PC-98?) +// | | | 4:(LANCE | 拡張スロット?) +// | | | | 3:SPC +// | | | | | 2:(未使用?) +// | | | | | | 1:(XP 低レベル | SOFTINT レジスタ $6900000n) +// | | | | | | | +// | V V V V V V +// | +---------------------+ +// | | 割り込みマスク | (R:bit23-18, W:bit31-26) +// | +---------------------+ // | | | | | | | // V V V V V V V // +-------------------------+ @@ -167,8 +168,8 @@ SysCtlrDevice::SysCtlrDevice() intmap_status = IntmapSentinel; - monitor.func = ToMonitorCallback(&SysCtlrDevice::MonitorUpdate); - monitor.Regist(ID_MONITOR_INTERRUPT); + monitor = gMonitorManager->Regist(ID_MONITOR_INTERRUPT, this); + monitor->func = ToMonitorCallback(&SysCtlrDevice::MonitorUpdate); } // デストラクタ @@ -180,10 +181,6 @@ SysCtlrDevice::~SysCtlrDevice() bool SysCtlrDevice::Init() { - if (inherited::Init() == false) { - return false; - } - mpu88xx0 = GetMPU88xx0Device(mpu); // 検索順 @@ -209,7 +206,7 @@ SysCtlrDevice::Init() }; // 行数が確定したのでサイズ設定 - monitor.SetSize(41, 1 + disp_list.size()); + monitor->SetSize(41, 1 + disp_list.size()); return true; } @@ -233,67 +230,70 @@ SysCtlrDevice::ResetHard(bool poweron) } busdata -SysCtlrDevice::Read32(uint32 addr) +SysCtlrDevice::Read(busaddr addr) { - int n = (addr >> 2) & 3; + uint32 paddr = addr.Addr(); + uint n = (paddr >> 2) & 3; + busdata data; - if (0x65000000 <= addr && addr < 0x65000010) { + // XXX バイト/ワードアクセスは未対応 + if (addr.GetSize() < 4) { + putlog(0, "Read $%08x size=%u (NOT IMPLEMENTED)", + paddr, addr.GetSize()); + } + + if (0x65000000 <= paddr && paddr < 0x65000010) { // bit31-29 に発生している最上位の割り込みレベル // bit23-18 に設定したレベル 6-1 の割り込みマスク - uint32 data = (cpu[n].ipl << 29) | (cpu[n].maskval >> 8); - putlog(2, "割り込み保持読み出し(CPU#%d) -> $%08x", n, data); - return data; - } + data = (cpu[n].ipl << 29) | (cpu[n].maskval >> 8); + putlog(2, "割り込み保持読み出し(CPU#%u) -> $%08x", n, data.Data()); - if (0x69000000 <= addr && addr < 0x69000010) { + } else if (0x69000000 <= paddr && paddr < 0x69000010) { // 読み出しで SOFTINT ネゲート (値は関係ない) if (cpu[n].softint) { - putlog(1, "Softint(CPU#%d) Negate", n); + putlog(1, "Softint(CPU#%u) Negate", n); cpu[n].softint = 0; ChangeInterrupt(); } - return 0xffffffff; - } + data = 0xffffffff; - if (0x6d000000 <= addr && addr < 0x6d000010) { - putlog(0, "Read CPU%d reset (NOT IMPLEMENTED)", n); - return 0xffffffff; - } - if (addr == 0x6d000010) { + } else if (0x6d000000 <= paddr && paddr < 0x6d000010) { + putlog(0, "Read CPU%u reset (NOT IMPLEMENTED)", n); + data = 0xffffffff; + + } else if (paddr == 0x6d000010) { putlog(0, "Read All CPU reset (NOT IMPLEMENTED)"); - return 0xffffffff; + data = 0xffffffff; + + } else { + putlog(0, "Read $%08x (NOT IMPLEMENTED)", paddr); + data.SetBusErr(); } - putlog(0, "Read $%08x (NOT IMPLEMENTED)", addr); - return 0xffffffff; + data |= BusData::Size4; + return data; } busdata -SysCtlrDevice::Write32(uint32 addr, uint32 data) +SysCtlrDevice::Write(busaddr addr, uint32 data) { - int n = (addr & 15) >> 2; - - if (0x65000000 <= addr && addr < 0x65000010) { - data &= 0xfc000000; - // 割り込みレベル変えるたびに表示されるのですごく多い。 - // さらに同レベルが書き込まれることも多い…。 - if (cpu[n].maskval != data) { - putlog(2, "Interrupt Mask(CPU#%d) <- $%08x", n, data); - } else { - putlog(3, "Interrupt Mask(CPU#%d) <- $%08x", n, data); - } + uint32 paddr = addr.Addr(); + uint n = (paddr >> 2) & 3U; - // 設定値を保存 - cpu[n].maskval = data; - // 内部マスクを書き換えて割り込み状態を更新 - cpu[n].intmask = MakeIntMask(data, n); - ChangeInterrupt(); - return 0; + // XXX バイト/ワードアクセスは未対応 + if (addr.GetSize() < 4) { + putlog(0, "Write $%08x size=%u (NOT IMPLEMENTED)", + paddr, addr.GetSize()); } - if (0x69000000 <= addr && addr < 0x69000010) { + + if (0x65000000 <= paddr && paddr < 0x65000010) { + // 割り込みマスクを設定。 + WriteIntMask(n, data); + + } else if (0x69000000 <= paddr && paddr < 0x69000010) { // 書き込みで SOFTINT アサート (値は関係ない) if (cpu[n].softint == false) { - putlog(1, "Softint(CPU#%d) Assert", n); + putlog(1, "Softint(CPU#%u) Assert", n); cpu[n].softint = IntmapSoft; cpu[n].softint_count++; // 親クラスのカウンタも上げる (4つの和になる) @@ -301,13 +301,11 @@ SysCtlrDevice::Write32(uint32 addr, uint counter[clz]++; ChangeInterrupt(); } - return 0; - } - if (0x6d000000 <= addr && addr < 0x6d000010) { - putlog(0, "Write CPU%d reset (NOT IMPLEMENTED)", n); - return 0; - } - if (addr == 0x6d000010) { + + } else if (0x6d000000 <= paddr && paddr < 0x6d000010) { + putlog(0, "Write CPU%u reset (NOT IMPLEMENTED)", n); + + } else if (paddr == 0x6d000010) { putlog(1, "Reset All CPUs"); // XXX このあたりもう少し整理する必要がある // 今は MPU.ResetHard() が func を ResetCallback に、time をリセット @@ -317,17 +315,19 @@ SysCtlrDevice::Write32(uint32 addr, uint GetPROM0Device()->ResetHard(false); mpu->ResetHard(false); ResetHard(false); - return 0; + + } else { + putlog(0, "Write $%08x <- $%08x (NOT IMPLEMENTED)", paddr, data); } - putlog(0, "Write $%08x <- $%08x (NOT IMPLEMENTED)", addr, data); - return 0; + busdata r = BusData::Size4; + return r; } busdata -SysCtlrDevice::Peek8(uint32 addr) +SysCtlrDevice::Peek1(uint32 addr) { - int n = (addr >> 2) & 3; + uint n = (addr >> 2) & 3; uint32 data; if (0x65000000 <= addr && addr < 0x65000010) { @@ -369,9 +369,9 @@ SysCtlrDevice::MonitorUpdate(Monitor *, screen.Puts(36, y, "Count"); y++; for (uint32 map : disp_list) { - int clz = __builtin_clz(map); - int lv = (31 - clz) / 4; - screen.Print(0, y, "%d", lv); + uint clz = __builtin_clz(map); + uint lv = (31 - clz) / 4; + screen.Print(0, y, "%u", lv); screen.Puts(3, y, TA::OnOff(intmap_status & map), GetIntName(map)); screen.Print(15, y, "%26s", format_number(counter[clz]).c_str()); @@ -394,6 +394,28 @@ SysCtlrDevice::MonitorUpdate(Monitor *, // ソフトウェア割り込みの CPU ごとのカウンタいる? } +// 割り込みマスクを設定する。 +// data はロングワードレジスタの書き込み値 (bit31-26 のみ有効)。 +void +SysCtlrDevice::WriteIntMask(uint32 n, uint32 data) +{ + data &= 0xfc000000; + + // 割り込みレベル変えるたびに表示されるのですごく多い。 + // さらに同レベルが書き込まれることも多い…。 + if (cpu[n].maskval != data) { + putlog(2, "Interrupt Mask(CPU#%u) <- $%08x", n, data); + } else { + putlog(3, "Interrupt Mask(CPU#%u) <- $%08x", n, data); + } + + // 設定値を保存 + cpu[n].maskval = data; + // 内部マスクを書き換えて割り込み状態を更新 + cpu[n].intmask = MakeIntMask(data, n); + ChangeInterrupt(); +} + // 割り込みアクノリッジはない busdata SysCtlrDevice::InterruptAcknowledge(int lv) @@ -410,7 +432,7 @@ SysCtlrDevice::ChangeInterrupt() uint32 localmap = (intmap_status | cpu[i].softint) & cpu[i].intmask; // intmap_status の最下位ビットは常に立ててあり localmap は 0 にならない - int newipl = (uint)(31 - __builtin_clz(localmap)) / 4; + uint newipl = (uint)(31 - __builtin_clz(localmap)) / 4; // 割り込みレベルが変わったら、新しいレベルを通知 if (newipl != cpu[i].ipl) { @@ -425,7 +447,7 @@ SysCtlrDevice::ChangeInterrupt() // data は bit31-26 のみ使用。他のビットは不問。 // n は CPU# (Softint 用)。 /*static*/ uint32 -SysCtlrDevice::MakeIntMask(uint32 data, int n) +SysCtlrDevice::MakeIntMask(uint32 data, uint n) { uint32 val = 0xf0000001; // Lv7 は NMI、最下位は番兵用