--- nono/vm/spc.cpp 2026/04/29 17:05:49 1.1.1.20 +++ nono/vm/spc.cpp 2026/04/29 17:05:59 1.1.1.21 @@ -21,7 +21,7 @@ // time 時間後に呼び出すコールバックをセットする。 // func の書式が面倒なのを省略して書きたいため。 #define CallAfter(func_, name_, time_) do { \ - phase_event->func = ToEventCallback(&SPCDevice::func_); \ + phase_event->SetCallback(&SPCDevice::func_); \ phase_event->time = time_; \ phase_event->SetName(name_); \ scheduler->RestartEvent(phase_event); \ @@ -29,13 +29,13 @@ // コンストラクタ SPCDevice::SPCDevice() - : inherited(OBJ_SPC) + : inherited(OBJ_SPC0) { // 初期値は不定だが表示上困るのでとりあえず。 myid = 7; monitor = gMonitorManager->Regist(ID_MONITOR_SPC, this); - monitor->func = ToMonitorCallback(&SPCDevice::MonitorUpdate); + monitor->SetCallback(&SPCDevice::MonitorScreen); // サイズは Init で決まる } @@ -60,7 +60,7 @@ SPCDevice::Create() { // ドメイン。 try { - domain.reset(new SCSIDomain(this, "spc0")); + domain.reset(new SCSIDomain(this, "SPC0", "spc0")); } catch (...) { } if ((bool)domain == false) { warnx("Failed to initialize SCSIDomain at %s", __method__); @@ -99,8 +99,11 @@ SPCDevice::Init() // 入力クロックは機種によって異なる。 // X68k は 5MHz が入っている。 // LUNA-I はおそらく 6.144MHz だと思われる。LUNA-88K は未確認。 - const ConfigItem& item = gConfig->Find("!spc-tCLF"); - t_CLF = item.AsInt(); + if (vmtype == VMType::X68030) { + t_CLF = 200_nsec; + } else { + t_CLF = 163_nsec; + } // アクセスウェイト if (vmtype == VMType::X68030) { @@ -488,7 +491,7 @@ SPCDevice::PokePort(uint32 offset, uint3 } void -SPCDevice::MonitorUpdate(Monitor *, TextScreen& screen) +SPCDevice::MonitorScreen(Monitor *, TextScreen& screen) { int x; int y; @@ -651,9 +654,10 @@ SPCDevice::MonitorUpdate(Monitor *, Text y = 2; screen.Puts(x + 4, y++, "(________)"); screen.Puts(x + 4, y++, "(________)"); - screen.Puts(x + 4, y++, "+"); - screen.Puts(x + 4, y++, "|"); - screen.Puts(x + 4, y++, "+"); + // Shift-JIS は手動で置く必要がある。 + screen.Puts(x + 4, y++, "\x84\xa2"); // "┐" + screen.Puts(x + 4, y++, "\x84\xa0"); // "│" + screen.Puts(x + 4, y++, "\x84\xa3"); // "┘" // BSY, SEL の内訳。"(76543210)" の順。 y = 2; @@ -675,9 +679,9 @@ SPCDevice::MonitorUpdate(Monitor *, Text // 転送フェーズ中なら現在の XferPhase y += 2; - if (ph == SCSI::Phase::Transfer) { - screen.Puts(x + 5, y, SCSI::GetXferPhaseName(GetXfer())); - } + TA attrxfer = (ph == SCSI::Phase::Transfer) ? TA::Normal : TA::Disable; + screen.Puts(x + 6, y++, attrxfer, "XferPhase:"); + screen.Puts(x + 6, y, attrxfer, SCSI::GetXferPhaseName(GetXfer())); // デバイス一覧 // 0 1 @@ -733,7 +737,7 @@ SPCDevice::MonitorUpdate(Monitor *, Text } } -// レジスタをビットごとに表示する。MonitorUpdate の下請け。 +// レジスタをビットごとに表示する。MonitorScreen の下請け。 void SPCDevice::MonitorReg(TextScreen& screen, int x, int y, uint32 reg, const char * const *names) @@ -890,8 +894,7 @@ SPCDevice::WriteINTS(uint32 data) if (spc.tc == 0) { BusFree(); } else { - timer_event->func = - ToEventCallback(&SPCDevice::SelectionTimeout); + timer_event->SetCallback(&SPCDevice::SelectionTimeout); timer_event->time = spc.tc * t_CLF * 2; scheduler->RestartEvent(timer_event); } @@ -1264,7 +1267,7 @@ SPCDevice::SelectCommand() // N が 0 なら無限大なのでタイマーは動かさない。 uint32 N = (spc.tc >> 8) << 8; if (N != 0) { - timer_event->func = ToEventCallback(&SPCDevice::SelectionTimeout); + timer_event->SetCallback(&SPCDevice::SelectionTimeout); timer_event->time = (N + 15) * t_CLF * 2; scheduler->RestartEvent(timer_event); } @@ -1277,14 +1280,14 @@ SPCDevice::SelectCommand() // 必ずバスの使用権を得る。 // バスフリーから規定時間後に SEL (と DB* と ATN) を上げる。 - uint64 t_ARB = 32 * t_CLF - 60; - uint64 t_AWSL = 40; // 適当に中間 + uint64 t_ARB = 32 * t_CLF - 60_nsec; + uint64 t_AWSL = 40_nsec; // 適当に中間 CallAfter(Arbitration1, "SPC Arbitration", wait + t_ARB + t_AWSL); } else { // アービトレーションなしの場合 // バスフリーから規定時間後に SEL (と DB*) を上げる。 - uint64 t_IDSL = 11 * t_CLF - 80; + uint64 t_IDSL = 11 * t_CLF - 80_nsec; CallAfter(Selection1, "SPC Selection", wait + t_IDSL); } } @@ -1311,8 +1314,8 @@ SPCDevice::Arbitration1(Event *ev) } AssertSEL(); - uint64 t_SIDA = 11 * t_CLF - 30; - uint64 t_IDBH = 2 * t_CLF - 80; + uint64 t_SIDA = 11 * t_CLF - 30_nsec; + uint64 t_IDBH = 2 * t_CLF - 80_nsec; CallAfter(Arbitration2, "SPC Arbitration2", t_SIDA + t_IDBH); }