--- nono/vm/spc.cpp 2026/04/29 17:05:41 1.1.1.19 +++ nono/vm/spc.cpp 2026/04/29 17:05:49 1.1.1.20 @@ -10,6 +10,7 @@ #include "spc.h" #include "config.h" +#include "event.h" #include "mainapp.h" #include "monitor.h" #include "pedec.h" @@ -20,9 +21,9 @@ // time 時間後に呼び出すコールバックをセットする。 // func の書式が面倒なのを省略して書きたいため。 #define CallAfter(func_, name_, time_) do { \ - phase_event.func = ToEventCallback(&SPCDevice::func_); \ - phase_event.time = time_; \ - phase_event.SetName(name_); \ + phase_event->func = ToEventCallback(&SPCDevice::func_); \ + phase_event->time = time_; \ + phase_event->SetName(name_); \ scheduler->RestartEvent(phase_event); \ } while (0) @@ -121,15 +122,9 @@ SPCDevice::Init() interrupt = GetInterruptDevice(); } - // 汎用イベント - // 名前とコールバック関数は都度セットする。 - phase_event.SetName("SPC Phase"); - scheduler->RegistEvent(phase_event); - - // TC カウンタイベント - timer_event.code = 0; - timer_event.SetName("SPC Timer"); - scheduler->RegistEvent(timer_event); + auto evman = GetEventManager(); + phase_event = evman->Regist(this, NULL, "SPC Phase"); + timer_event = evman->Regist(this, NULL, "SPC Timer"); // モニタに表示するアドレス if (vmtype == VMType::X68030) { @@ -189,7 +184,7 @@ SPCDevice::ReadPort(uint32 offset) switch (offset) { case SPC::BDID: - data = 1 << myid; + data = 1U << myid; putlog(3, "BDID -> $%02x", data.Data()); break; @@ -213,7 +208,7 @@ SPCDevice::ReadPort(uint32 offset) data = GetINTS(); if (loglevel >= 3) { uint32 new_ints = data.Data(); - if (timer_event.IsRunning()) { + if (timer_event->IsRunning()) { // イベント中は値が変わった時だけ表示 if (prev_ints != new_ints) { putlogn("INTS -> $%02x", new_ints); @@ -235,7 +230,7 @@ SPCDevice::ReadPort(uint32 offset) data = GetSSTS(); if (loglevel >= 3) { uint32 new_ssts = data.Data(); - if (timer_event.IsRunning()) { + if (timer_event->IsRunning()) { // イベント中は値が変わった時だけ表示 if (prev_ssts != new_ssts) { putlogn("SSTS -> $%02x", new_ssts); @@ -423,7 +418,7 @@ SPCDevice::PeekPort(uint32 offset) { switch (offset) { case SPC::BDID: - return 1 << myid; + return 1U << myid; case SPC::SCTL: return spc.sctl; @@ -522,7 +517,7 @@ SPCDevice::MonitorUpdate(Monitor *, Text #define A(n) (baseaddr + (n) * regoffset) y = 0; - screen.Print(0, y++, "$%08x BDID: $%02x (ID=%u)", A(0), (1 << myid), myid); + screen.Print(0, y++, "$%08x BDID: $%02x (ID=%u)", A(0), (1U << myid), myid); screen.Print(0, y++, "$%08x SCTL: $%02x", A(1), sctl); screen.Print(0, y++, "$%08x SCMD: $%02x", A(2), scmd); screen.Print(0, y++, "$%08x INTS: $%02x", A(4), ints); @@ -663,7 +658,7 @@ SPCDevice::MonitorUpdate(Monitor *, Text // BSY, SEL の内訳。"(76543210)" の順。 y = 2; for (int i = 0; i < 8; i++) { - if ((bsy & (1 << i))) { + if ((bsy & (1U << i))) { screen.Print(x + 4 + 8 - i, y, "%u", i); } else { screen.Print(x + 4 + 8 - i, y, "_"); @@ -671,7 +666,7 @@ SPCDevice::MonitorUpdate(Monitor *, Text } y++; for (int i = 0; i < 8; i++) { - if ((sel & (1 << i))) { + if ((sel & (1U << i))) { screen.Print(x + 4 + 8 - i, y, "%u", i); } else { screen.Print(x + 4 + 8 - i, y, "_"); @@ -747,7 +742,7 @@ SPCDevice::MonitorReg(TextScreen& screen if (names[i][0] == '-') { screen.Puts(x + i * 5, y, TA::Disable, "----"); } else { - bool b = reg & (1 << (7 - i)); + bool b = reg & (1U << (7 - i)); screen.Puts(x + i * 5, y, TA::OnOff(b), names[i]); } } @@ -895,9 +890,9 @@ SPCDevice::WriteINTS(uint32 data) if (spc.tc == 0) { BusFree(); } else { - timer_event.func = + timer_event->func = ToEventCallback(&SPCDevice::SelectionTimeout); - timer_event.time = spc.tc * t_CLF * 2; + timer_event->time = spc.tc * t_CLF * 2; scheduler->RestartEvent(timer_event); } } @@ -1198,12 +1193,12 @@ SPCDevice::SelectCommand() if (data == 0) { // ID が一切立ってない? idstr = "TEMP==0; No IDs?"; - } else if ((data & (1 << myid)) == 0) { + } else if ((data & (1U << myid)) == 0) { // 自 ID が立ってない? idstr = string_format("TEMP=$%02x; No BDID?", data); } else { // ここで少なくとも自 ID は立っている - data &= ~(1 << myid); + data &= ~(1U << myid); if (data == 0) { // ターゲット ID がない @@ -1269,8 +1264,8 @@ SPCDevice::SelectCommand() // N が 0 なら無限大なのでタイマーは動かさない。 uint32 N = (spc.tc >> 8) << 8; if (N != 0) { - timer_event.func = ToEventCallback(&SPCDevice::SelectionTimeout); - timer_event.time = (N + 15) * t_CLF * 2; + timer_event->func = ToEventCallback(&SPCDevice::SelectionTimeout); + timer_event->time = (N + 15) * t_CLF * 2; scheduler->RestartEvent(timer_event); } @@ -1296,7 +1291,7 @@ SPCDevice::SelectCommand() // アービトレーションフェーズ開始後、規定時間経過したので SEL を立てるところ。 void -SPCDevice::Arbitration1(Event& ev) +SPCDevice::Arbitration1(Event *ev) { putlog(3, "Arbitration1"); @@ -1324,7 +1319,7 @@ SPCDevice::Arbitration1(Event& ev) // アービトレーションフェーズ中、SEL を立ててから規定時間経過したので BSY を // 下げるところ。 void -SPCDevice::Arbitration2(Event& ev) +SPCDevice::Arbitration2(Event *ev) { putlog(3, "Arbitration2"); @@ -1334,7 +1329,7 @@ SPCDevice::Arbitration2(Event& ev) // アービトレーションフェーズを使わない場合のセレクションフェーズで、 // 規定時間経過したので SEL を立てるところ。 void -SPCDevice::Selection1(Event& ev) +SPCDevice::Selection1(Event *ev) { putlog(3, "Selection1"); @@ -1351,12 +1346,12 @@ SPCDevice::Selection1(Event& ev) // セレクションコマンドがタイムアウトした時に呼ばれるコールバック。 void -SPCDevice::SelectionTimeout(Event& ev) +SPCDevice::SelectionTimeout(Event *ev) { if (loglevel >= 3) { int tgtid; uint8 data = GetData(); - data &= ~(1 << myid); + data &= ~(1U << myid); tgtid = SCSIBus::DecodeID(data); if (tgtid == -1) { putlogn("Selection timeout"); @@ -1500,7 +1495,7 @@ SPCDevice::TransferReqCallback() // (1バイト送信するとターゲットが再び REQ を上げるなどしてくるので、 // OnTransferReq() か DREG 書き込みから再びここが呼ばれる) void -SPCDevice::HardwareTransfer(Event& ev) +SPCDevice::HardwareTransfer(Event *ev) { // SDGC_XFER_ENABLE は転送要求ごとに割り込みを上げる。 // (SPC から見て) 入力操作時は読み込めるデータがある場合、出力操作時は