Annotation of nono/vm/spc.h, revision 1.1.1.12

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.12! root        7: //
        !             8: // SPC (MB89352)
        !             9: //
        !            10: 
1.1       root       11: #pragma once
                     12: 
                     13: #include "device.h"
1.1.1.12! root       14: #include "event.h"
1.1       root       15: #include "fixedqueue.h"
1.1.1.10  root       16: #include "monitor.h"
1.1.1.4   root       17: #include "scsidev.h"
1.1       root       18: 
                     19: struct SPC
                     20: {
                     21:        static const int BDID = 0x0;    // $E96021 RW  $E100_0000
                     22:        static const int SCTL = 0x1;    // $E96023 RW  $E100_0004
                     23:        static const int SCMD = 0x2;    // $E96025 RW  $E100_0008
                     24:        static const int TMOD = 0x3;    // (MB89352 にはない)
                     25:        static const int INTS = 0x4;    // $E96029 RW  $E100_0010
                     26:        static const int PSNS = 0x5;    // $E9602B R-  $E100_0014
                     27:        static const int SDGC = 0x5;    // $E9602B -W  $E100_0014
                     28:        static const int SSTS = 0x6;    // $E9602D R-  $E100_0018
                     29:        static const int SERR = 0x7;    // $E9602F R-  $E100_001C
                     30:        static const int PCTL = 0x8;    // $E96031 RW  $E100_0020
                     31:        static const int MBC  = 0x9;    // $E96033 R-  $E100_0024
                     32:        static const int DREG = 0xa;    // $E96035 RW  $E100_0028
                     33:        static const int TEMP = 0xb;    // $E96037 RW  $E100_002C
                     34:        static const int TCH  = 0xc;    // $E96039 RW  $E100_0030
                     35:        static const int TCM  = 0xd;    // $E9603B RW  $E100_0034
                     36:        static const int TCL  = 0xe;    // $E9603D RW  $E100_0038
                     37:        static const int EXBF = 0xf;    // (MB89352 にはない)
                     38: 
                     39: 
                     40:        // SCTL レジスタ
                     41:        // 全ビットを保持。
                     42:        uint8 sctl;
                     43:        static const int SCTL_RESET                     = 0x80; // Reset & Disable
                     44:        static const int SCTL_CTL_RESET         = 0x40; // Control Reset
                     45:        static const int SCTL_DIAG_MODE         = 0x20; // Diag Mode
                     46:        static const int SCTL_ARBIT_EN          = 0x10; // Arbitration Enable
                     47:        static const int SCTL_PARITY_EN         = 0x08; // Parity Enable
                     48:        static const int SCTL_SEL_EN            = 0x04; // Select Enable
                     49:        static const int SCTL_RESEL_EN          = 0x02; // Reselect Enable
                     50:        static const int SCTL_INTR_EN           = 0x01; // Interrupt Enable
                     51: 
                     52:        // SCMD レジスタ
1.1.1.2   root       53:        // 全ビットを保持。
1.1       root       54:        uint8 scmd;
                     55:        static const int SCMD_CMD_MASK          = 0xe0; // Command code
                     56:        static const int SCMD_RST_OUT           = 0x10; // RST Out
                     57:        static const int SCMD_INTERCEPT         = 0x08; // Intersept Transfer
                     58:        static const int SCMD_PROGRAM           = 0x04; // Program Transfer
                     59:        static const int SCMD_TERM_MODE         = 0x01; // Termination Mode
                     60: 
                     61:        // INTS レジスタ
1.1.1.7   root       62:        //
                     63:        // 内部変数 ints は割り込み状態を一度に判別するため SERR レジスタの
                     64:        // xfer ビット(SERR_XFER_OUT) もここの bit8 に含めている。
                     65:        // 残りの下位8ビットは INTS と同じ。
                     66:        //
                     67:        //               | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
                     68:        // INTS          |SEL |RESL|DIS |CMPL|SERV|TOUT|HERR|REST|
                     69:        //            b8
                     70:        // ints変数 |xfer|SEL |RESL|DIS |CMPL|SERV|TOUT|HERR|REST|
                     71:        //
                     72:        uint16 ints;
1.1       root       73:        static const int INTS_SELECTED          = 0x80; // Selected
                     74:        static const int INTS_RESELECTED        = 0x40; // Reselected
                     75:        static const int INTS_DISCONNECTED      = 0x20; // Disconnected
                     76:        static const int INTS_COMPLETE          = 0x10; // Command Complete
                     77:        static const int INTS_SERV_REQ          = 0x08; // Service Required
                     78:        static const int INTS_TIMEOUT           = 0x04; // Time Out
                     79:        static const int INTS_HARD_ERR          = 0x02; // SPC Hard Error
                     80:        static const int INTS_RESET_COND        = 0x01; // Reset Condition
                     81: 
1.1.1.7   root       82:        static const int INTS_XFER_OUT          = 0x100;        // SERR_XFER_OUT
                     83: 
                     84:        // 割り込みマスク (INTS_RESET_COND はノンマスカブル割り込み)
                     85:        uint16 ints_mask;
                     86:        static const int INTS_ENABLE_MASK       = 0x01ff;
                     87:        static const int INTS_DISABLE_MASK      = 0x0001;
                     88: 
1.1       root       89:        // PSNS レジスタ
                     90:        uint8 psns;
                     91:        static const int PSNS_REQ                       = 0x80;
                     92:        static const int PSNS_ACK                       = 0x40;
                     93:        static const int PSNS_ATN                       = 0x20;
                     94:        static const int PSNS_SEL                       = 0x10;
                     95:        static const int PSNS_BSY                       = 0x08;
                     96:        static const int PSNS_MSG                       = 0x04;
                     97:        static const int PSNS_CD                        = 0x02;
                     98:        static const int PSNS_IO                        = 0x01;
                     99: 
                    100:        // SDGC レジスタ
                    101:        uint8 sdgc;
                    102:        static const int SDGC_XFER_ENABLE       = 0x20;
                    103: 
                    104:        // SSTS レジスタ
                    105:        // 上位4ビットを保持。下位4ビットは読み出し時に生成。
                    106:        uint8 ssts;
                    107:        static const int SSTS_CONN_INIT         = 0x80; // Connected (Initiator)
                    108:        static const int SSTS_CONN_TARG         = 0x40; // Connected (Target)
                    109:        static const int SSTS_SPC_BUSY          = 0x20; // SPC Busy
                    110:        static const int SSTS_IN_PROGRESS       = 0x10; // Transfer in Progress
                    111:        static const int SSTS_RST_IN            = 0x08; // SCSI RST In
                    112:        static const int SSTS_TC_ZERO           = 0x04; // TC=0
                    113:        static const int SSTS_DREG_FULL         = 0x02; // DREG Status (Full)
                    114:        static const int SSTS_DREG_EMPTY        = 0x01; // DREG Status (Empty)
                    115: 
                    116:        // SERR レジスタ
1.1.1.7   root      117:        // XFER_OUT 以外の4つの有効ビットを保持。
                    118:        // XFER_OUT は ints が担当している。
1.1       root      119:        uint8 serr;
                    120:        static const int SERR_DATAERR_SCSI      = 0x80; // Data Error: SCSI
                    121:        static const int SERR_DATAERR_SPC       = 0x40; // Data Error: SPC
                    122:        static const int SERR_XFER_OUT          = 0x20; // Xfer Out
                    123:        static const int SERR_TC_PARITY_ERR     = 0x08; // TC Parity Error
                    124:        static const int SERR_SHORT_XFER        = 0x02; // Short Transfer Period
                    125: 
                    126:        // PCTL レジスタ
1.1.1.11  root      127:        // BusFree INT Enable は独立して保持。
                    128:        // MSG, CD, IO の3ビットは pctl_out で保持。
1.1       root      129:        bool busfree_intr_enable;
1.1.1.11  root      130:        uint8 pctl_out;
1.1       root      131:        static const int PCTL_MASK                      = 0x87; // 書き込みマスク
                    132:        static const int PCTL_BFINT_EN          = 0x80; // BusFree INT Enable
                    133:        static const int PCTL_MSG                       = 0x04;
                    134:        static const int PCTL_CD                        = 0x02;
                    135:        static const int PCTL_IO                        = 0x01;
                    136: 
                    137:        FixedQueue<uint8, 8> dreg;      // DREG レジスタ
                    138: 
                    139:        uint8 temp_in;  // TEMP レジスタ (SCSI -> MPU)
                    140:        uint8 temp_out; // TEMP レジスタ (MPU -> SCSI)
                    141:        uint32 tc;              // TC
                    142: 
                    143:        uint32 GetTCL() const { return tc & 0x0000ff; } // TCL
                    144: 
                    145:        // MBC (内部の読み込み専用レジスタ)
                    146:        // TC の下位4ビットが読めるらしい
                    147:        uint8 mbc() const {
                    148:                return tc & 15;
                    149:        }
                    150: };
                    151: 
                    152: class SPCDevice : public SCSIHostDevice
                    153: {
1.1.1.4   root      154:        using inherited = SCSIHostDevice;
1.1       root      155:  public:
1.1.1.3   root      156:        SPCDevice();
1.1.1.7   root      157:        virtual ~SPCDevice() override;
1.1       root      158: 
1.1.1.4   root      159:        bool Init() override;
1.1.1.12! root      160:        void ResetHard(bool poweron) override;
1.1       root      161: 
1.1.1.2   root      162:        // SCSIBus コールバック
                    163: 
                    164:        // バスフリーになった (全員に通知される)
1.1.1.4   root      165:        void BusFreeCB(int id) override;
1.1       root      166: 
1.1.1.2   root      167:        // ターゲットがセレクションに応答した (イニシエータのみ通知される)
1.1.1.4   root      168:        void SelectionAckCB() override;
1.1.1.2   root      169: 
                    170:        // 情報転送フェーズで REQ を立てた (イニシエータのみ通知される)
1.1.1.4   root      171:        void TransferReqCB() override;
1.1       root      172: 
1.1.1.8   root      173:        // BusIO インタフェース
                    174:        // (内蔵 ROM からのアクセス用に特別に public にしてある)
                    175:        uint64 Write(uint32 offset, uint32 data);
                    176: 
1.1.1.3   root      177:  protected:
                    178:        // BusIO インタフェース
                    179:        static const uint32 NPORT = 16;
1.1.1.8   root      180:        uint64 Read(uint32 offset);
                    181:        uint64 Peek(uint32 offset);
1.1.1.3   root      182: 
1.1       root      183:  private:
1.1.1.10  root      184:        DECLARE_MONITOR_CALLBACK(MonitorUpdate);
                    185: 
1.1.1.5   root      186:        void MonitorReg(TextScreen&,
                    187:                int x, int y, uint32 reg, const char * const *names);
1.1       root      188: 
                    189:        // SCTL レジスタへの書き込み
                    190:        void WriteSCTL(uint32);
1.1.1.7   root      191:        // 割り込みマスクの再構成
                    192:        void MakeIntsMask();
1.1       root      193: 
                    194:        // SCMD レジスタへの書き込み
                    195:        void WriteSCMD(uint32);
                    196: 
                    197:        // INTS レジスタへの書き込み
                    198:        void WriteINTS(uint32);
1.1.1.3   root      199:        // 表示のための前回値
                    200:        uint32 prev_ints {};
1.1       root      201: 
                    202:        // INTS 設定
                    203:        void SetINTS(uint32);
1.1.1.7   root      204:        // INTS レジスタ値の取得
                    205:        uint32 GetINTS() const;
                    206:        // 割り込み信号線の状態を変える
                    207:        void ChangeInterrupt();
1.1       root      208: 
                    209:        // PSNS レジスタ値の取得
                    210:        uint32 GetPSNS() const;
                    211: 
                    212:        // SSTS レジスタ値の取得
                    213:        uint32 GetSSTS() const;
1.1.1.3   root      214:        // 表示のための前回値
                    215:        uint32 prev_ssts {};
1.1       root      216: 
1.1.1.7   root      217:        // SERR レジスタ値の取得
                    218:        uint32 GetSERR() const;
                    219: 
1.1.1.11  root      220:        // PCTL レジスタへの書き込み
                    221:        void WritePCTL(uint32);
1.1       root      222:        // PCTL レジスタ値の取得
                    223:        uint32 GetPCTL() const;
                    224: 
1.1.1.3   root      225:        // DREG レジスタアクセス
                    226:        uint64 ReadDREG();
                    227:        uint64 WriteDREG(uint32 data);
                    228: 
1.1       root      229:        // バスフリーフェーズに移行する
                    230:        void BusFree();
1.1.1.2   root      231:        // 直近のバスフリーフェーズになった時刻
                    232:        // (アービトレーション/セレクション開始時に使う)
                    233:        uint64 last_busfree_time {};
                    234:        // バスをリリースする
                    235:        void BusRelease();
1.1       root      236: 
                    237:        // Select コマンド実行
                    238:        void SelectCommand();
1.1.1.6   root      239:        void Arbitration1(Event& ev);
                    240:        void Arbitration2(Event& ev);
                    241:        void Selection1(Event& ev);
                    242:        void SelectionTimeout(Event& ev);
1.1.1.2   root      243: 
                    244:        // SetATN コマンド実行
                    245:        void SetATNCommand();
                    246:        // セレクションフェーズで ATN を立てる
1.1.1.6   root      247:        bool set_atn_in_selection {};
1.1       root      248: 
                    249:        // Transfer コマンド実行
                    250:        void TransferCommand();
1.1.1.6   root      251:        void HardwareTransfer(Event& ev);
1.1.1.3   root      252:        void TransferComplete();
1.1.1.2   root      253:        // Transfer コマンド実行中なら true
1.1.1.6   root      254:        bool transfer_command_running {};
1.1       root      255: 
                    256:        // SCSI コマンド
                    257:        void ExecCommand();
                    258: 
                    259:        // レジスタ
                    260:        struct SPC spc {};
                    261: 
1.1.1.3   root      262:        // VM 種別
                    263:        vmtype_t vmtype {};
1.1       root      264: 
                    265:        // SPC に入力されるクロック周期 [nsec]
1.1.1.6   root      266:        int t_CLF {};
                    267: 
                    268:        // アクセスウェイト
                    269:        uint32 read_wait {};
                    270:        uint32 write_wait {};
                    271: 
1.1.1.7   root      272:        // 割り込み信号線の接続先デバイス
                    273:        InterruptDevice *interrupt {};
                    274: 
1.1       root      275:        // イベント
1.1.1.10  root      276:        Event event { this };
                    277:        Event event_tc { this };
                    278: 
                    279:        Monitor monitor { this };
1.1       root      280: };
                    281: 
1.1.1.12! root      282: extern SPCDevice *gSPC;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.