--- nono/vm/spc.h 2026/04/29 17:04:29 1.1.1.2 +++ nono/vm/spc.h 2026/04/29 17:04:42 1.1.1.6 @@ -1,14 +1,16 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #pragma once #include "device.h" -#include "scsidev.h" -#include "scheduler.h" #include "fixedqueue.h" +#include "scheduler.h" +#include "scsidev.h" +#include "vm.h" struct SPC { @@ -126,48 +128,51 @@ struct SPC class SPCDevice : public SCSIHostDevice { - typedef SCSIHostDevice inherited; + using inherited = SCSIHostDevice; public: - SPCDevice(uint32); - virtual ~SPCDevice(); + SPCDevice(); + ~SPCDevice() override; - virtual bool Init(); - virtual void ResetHard(); - virtual void ResetSoft(); - void Reset(); + bool Init() override; + void ResetHard() override; + void ResetSoft() override; - virtual uint64 Read8(uint32 addr); - virtual uint64 Read16(uint32 addr); - virtual uint64 Write8(uint32 addr, uint32 data); - virtual uint64 Write16(uint32 addr, uint32 data); - virtual uint64 Peek8(uint32 addr); - virtual bool MonitorUpdate(); + void MonitorUpdate(TextScreen&) override; // SCSIBus コールバック // バスフリーになった (全員に通知される) - virtual void BusFreeCB(int id); + void BusFreeCB(int id) override; // ターゲットがセレクションに応答した (イニシエータのみ通知される) - virtual void SelectionAckCB(); + void SelectionAckCB() override; // 情報転送フェーズで REQ を立てた (イニシエータのみ通知される) - virtual void TransferReqCB(); + void TransferReqCB() override; + + protected: + // BusIO インタフェース + static const uint32 NPORT = 16; + uint64 Read(uint32 addr); + uint64 Write(uint32 addr, uint32 data); + uint64 Peek(uint32 addr); private: - void MonitorReg(int x, int y, uint32 reg, const char * const *names); + void Reset(); + + void MonitorReg(TextScreen&, + int x, int y, uint32 reg, const char * const *names); // SCTL レジスタへの書き込み void WriteSCTL(uint32); - // SCMD レジスタ値の取得 - uint32 GetSCMD() const; - // SCMD レジスタへの書き込み void WriteSCMD(uint32); // INTS レジスタへの書き込み void WriteINTS(uint32); + // 表示のための前回値 + uint32 prev_ints {}; // INTS 設定 void SetINTS(uint32); @@ -177,10 +182,16 @@ class SPCDevice : public SCSIHostDevice // SSTS レジスタ値の取得 uint32 GetSSTS() const; + // 表示のための前回値 + uint32 prev_ssts {}; // PCTL レジスタ値の取得 uint32 GetPCTL() const; + // DREG レジスタアクセス + uint64 ReadDREG(); + uint64 WriteDREG(uint32 data); + // バスフリーフェーズに移行する void BusFree(); // 直近のバスフリーフェーズになった時刻 @@ -191,22 +202,23 @@ class SPCDevice : public SCSIHostDevice // Select コマンド実行 void SelectCommand(); - void Arbitration1(int code); - void Arbitration2(int code); - void Selection1(int code); - void SelectionTimeout(int code); + void Arbitration1(Event& ev); + void Arbitration2(Event& ev); + void Selection1(Event& ev); + void SelectionTimeout(Event& ev); // SetATN コマンド実行 void SetATNCommand(); // セレクションフェーズで ATN を立てる - bool set_atn_in_selection = false; + bool set_atn_in_selection {}; // Transfer コマンド実行 void TransferCommand(); - void TransferCommandStart(int code); - void ProgramTransfer(int code); + void TransferCommandStart(Event& ev); + void HardwareTransfer(Event& ev); + void TransferComplete(); // Transfer コマンド実行中なら true - bool transfer_command_running = false; + bool transfer_command_running {}; // SCSI コマンド void ExecCommand(); @@ -214,15 +226,22 @@ class SPCDevice : public SCSIHostDevice // レジスタ struct SPC spc {}; - uint32 regbase = 0; // レジスタの先頭アドレス - int regstride = 0; // レジスタ間の距離 + // VM 種別 + vmtype_t vmtype {}; // SPC に入力されるクロック周期 [nsec] - int t_CLF = 0; + int t_CLF {}; + + // アクセスウェイト + uint32 read_wait {}; + uint32 write_wait {}; + + // 接続中のデバイス(イニシエータ含む)を ID 順に並べたリスト (モニタ用) + std::vector connected_devices {}; // イベント Event event {}; Event event_tc {}; }; -extern SPCDevice *gSPC; +extern std::unique_ptr gSPC;