--- nono/vm/spc.h 2026/04/29 17:04:45 1.1.1.7 +++ nono/vm/spc.h 2026/04/29 17:05:25 1.1.1.15 @@ -4,13 +4,19 @@ // Licensed under nono-license.txt // +// +// SPC (MB89352) +// + #pragma once #include "device.h" +#include "event.h" #include "fixedqueue.h" -#include "scheduler.h" +#include "monitor.h" #include "scsidev.h" -#include "vm.h" + +class InterruptDevice; struct SPC { @@ -120,9 +126,10 @@ struct SPC static const int SERR_SHORT_XFER = 0x02; // Short Transfer Period // PCTL レジスタ - // ここでは BusFree INT Enable ビットだけを保持。 - // 残りの MSG, C/D, I/O は親クラスの信号線フラグから生成。 + // BusFree INT Enable は独立して保持。 + // MSG, CD, IO の3ビットは pctl_out で保持。 bool busfree_intr_enable; + uint8 pctl_out; static const int PCTL_MASK = 0x87; // 書き込みマスク static const int PCTL_BFINT_EN = 0x80; // BusFree INT Enable static const int PCTL_MSG = 0x04; @@ -149,13 +156,10 @@ class SPCDevice : public SCSIHostDevice using inherited = SCSIHostDevice; public: SPCDevice(); - virtual ~SPCDevice() override; + ~SPCDevice() override; bool Init() override; - void ResetHard() override; - void ResetSoft() override; - - void MonitorUpdate(TextScreen&) override; + void ResetHard(bool poweron) override; // SCSIBus コールバック @@ -168,15 +172,18 @@ class SPCDevice : public SCSIHostDevice // 情報転送フェーズで REQ を立てた (イニシエータのみ通知される) void TransferReqCB() override; + // BusIO インタフェース + // (内蔵 ROM からのアクセス用に特別に public にしてある) + busdata Write(uint32 offset, uint32 data); + protected: // BusIO インタフェース static const uint32 NPORT = 16; - uint64 Read(uint32 addr); - uint64 Write(uint32 addr, uint32 data); - uint64 Peek(uint32 addr); + busdata Read(uint32 offset); + busdata Peek(uint32 offset); private: - void Reset(); + DECLARE_MONITOR_CALLBACK(MonitorUpdate); void MonitorReg(TextScreen&, int x, int y, uint32 reg, const char * const *names); @@ -212,12 +219,14 @@ class SPCDevice : public SCSIHostDevice // SERR レジスタ値の取得 uint32 GetSERR() const; + // PCTL レジスタへの書き込み + void WritePCTL(uint32); // PCTL レジスタ値の取得 uint32 GetPCTL() const; // DREG レジスタアクセス - uint64 ReadDREG(); - uint64 WriteDREG(uint32 data); + busdata ReadDREG(); + busdata WriteDREG(uint32 data); // バスフリーフェーズに移行する void BusFree(); @@ -241,7 +250,6 @@ class SPCDevice : public SCSIHostDevice // Transfer コマンド実行 void TransferCommand(); - void TransferCommandStart(Event& ev); void HardwareTransfer(Event& ev); void TransferComplete(); // Transfer コマンド実行中なら true @@ -254,24 +262,25 @@ class SPCDevice : public SCSIHostDevice struct SPC spc {}; // VM 種別 - vmtype_t vmtype {}; + VMType vmtype {}; // SPC に入力されるクロック周期 [nsec] int t_CLF {}; // アクセスウェイト - uint32 read_wait {}; - uint32 write_wait {}; + busdata read_wait {}; + busdata write_wait {}; // 割り込み信号線の接続先デバイス InterruptDevice *interrupt {}; - // 接続中のデバイス(イニシエータ含む)を ID 順に並べたリスト (モニタ用) - std::vector connected_devices {}; - // イベント - Event event {}; - Event event_tc {}; + Event event { this }; + Event event_tc { this }; + + Monitor monitor { this }; }; -extern std::unique_ptr gSPC; +static inline SPCDevice *GetSPCDevice() { + return Object::GetObject(OBJ_SPC); +}