|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2017 [email protected] ! 4: // ! 5: ! 6: #pragma once ! 7: ! 8: #include "device.h" ! 9: #include "scsi.h" ! 10: #include "scheduler.h" ! 11: #include "fixedqueue.h" ! 12: ! 13: struct SPC ! 14: { ! 15: static const int BDID = 0x0; // $E96021 RW $E100_0000 ! 16: static const int SCTL = 0x1; // $E96023 RW $E100_0004 ! 17: static const int SCMD = 0x2; // $E96025 RW $E100_0008 ! 18: static const int TMOD = 0x3; // (MB89352 にはない) ! 19: static const int INTS = 0x4; // $E96029 RW $E100_0010 ! 20: static const int PSNS = 0x5; // $E9602B R- $E100_0014 ! 21: static const int SDGC = 0x5; // $E9602B -W $E100_0014 ! 22: static const int SSTS = 0x6; // $E9602D R- $E100_0018 ! 23: static const int SERR = 0x7; // $E9602F R- $E100_001C ! 24: static const int PCTL = 0x8; // $E96031 RW $E100_0020 ! 25: static const int MBC = 0x9; // $E96033 R- $E100_0024 ! 26: static const int DREG = 0xa; // $E96035 RW $E100_0028 ! 27: static const int TEMP = 0xb; // $E96037 RW $E100_002C ! 28: static const int TCH = 0xc; // $E96039 RW $E100_0030 ! 29: static const int TCM = 0xd; // $E9603B RW $E100_0034 ! 30: static const int TCL = 0xe; // $E9603D RW $E100_0038 ! 31: static const int EXBF = 0xf; // (MB89352 にはない) ! 32: ! 33: ! 34: // SCTL レジスタ ! 35: // 全ビットを保持。 ! 36: uint8 sctl; ! 37: static const int SCTL_RESET = 0x80; // Reset & Disable ! 38: static const int SCTL_CTL_RESET = 0x40; // Control Reset ! 39: static const int SCTL_DIAG_MODE = 0x20; // Diag Mode ! 40: static const int SCTL_ARBIT_EN = 0x10; // Arbitration Enable ! 41: static const int SCTL_PARITY_EN = 0x08; // Parity Enable ! 42: static const int SCTL_SEL_EN = 0x04; // Select Enable ! 43: static const int SCTL_RESEL_EN = 0x02; // Reselect Enable ! 44: static const int SCTL_INTR_EN = 0x01; // Interrupt Enable ! 45: ! 46: // SCMD レジスタ ! 47: // RST は読み出し時に GetRST() から生成。 ! 48: uint8 scmd; ! 49: static const int SCMD_CMD_MASK = 0xe0; // Command code ! 50: static const int SCMD_RST_OUT = 0x10; // RST Out ! 51: static const int SCMD_INTERCEPT = 0x08; // Intersept Transfer ! 52: static const int SCMD_PROGRAM = 0x04; // Program Transfer ! 53: static const int SCMD_TERM_MODE = 0x01; // Termination Mode ! 54: ! 55: // INTS レジスタ ! 56: // 全ビットを保持。 ! 57: uint8 ints; ! 58: static const int INTS_SELECTED = 0x80; // Selected ! 59: static const int INTS_RESELECTED = 0x40; // Reselected ! 60: static const int INTS_DISCONNECTED = 0x20; // Disconnected ! 61: static const int INTS_COMPLETE = 0x10; // Command Complete ! 62: static const int INTS_SERV_REQ = 0x08; // Service Required ! 63: static const int INTS_TIMEOUT = 0x04; // Time Out ! 64: static const int INTS_HARD_ERR = 0x02; // SPC Hard Error ! 65: static const int INTS_RESET_COND = 0x01; // Reset Condition ! 66: ! 67: // PSNS レジスタ ! 68: // REQ, ACK, ATN は今のところ保持? ! 69: uint8 psns; ! 70: static const int PSNS_REQ = 0x80; ! 71: static const int PSNS_ACK = 0x40; ! 72: static const int PSNS_ATN = 0x20; ! 73: static const int PSNS_SEL = 0x10; ! 74: static const int PSNS_BSY = 0x08; ! 75: static const int PSNS_MSG = 0x04; ! 76: static const int PSNS_CD = 0x02; ! 77: static const int PSNS_IO = 0x01; ! 78: ! 79: // SDGC レジスタ ! 80: uint8 sdgc; ! 81: static const int SDGC_XFER_ENABLE = 0x20; ! 82: ! 83: // SSTS レジスタ ! 84: // 上位4ビットを保持。下位4ビットは読み出し時に生成。 ! 85: uint8 ssts; ! 86: static const int SSTS_CONN_INIT = 0x80; // Connected (Initiator) ! 87: static const int SSTS_CONN_TARG = 0x40; // Connected (Target) ! 88: static const int SSTS_SPC_BUSY = 0x20; // SPC Busy ! 89: static const int SSTS_IN_PROGRESS = 0x10; // Transfer in Progress ! 90: static const int SSTS_RST_IN = 0x08; // SCSI RST In ! 91: static const int SSTS_TC_ZERO = 0x04; // TC=0 ! 92: static const int SSTS_DREG_FULL = 0x02; // DREG Status (Full) ! 93: static const int SSTS_DREG_EMPTY = 0x01; // DREG Status (Empty) ! 94: ! 95: // SERR レジスタ ! 96: uint8 serr; ! 97: static const int SERR_DATAERR_SCSI = 0x80; // Data Error: SCSI ! 98: static const int SERR_DATAERR_SPC = 0x40; // Data Error: SPC ! 99: static const int SERR_XFER_OUT = 0x20; // Xfer Out ! 100: static const int SERR_TC_PARITY_ERR = 0x08; // TC Parity Error ! 101: static const int SERR_SHORT_XFER = 0x02; // Short Transfer Period ! 102: ! 103: // PCTL レジスタ ! 104: // ここでは BusFree INT Enable ビットだけを保持。 ! 105: // 残りの MSG, C/D, I/O は親クラスの信号線フラグから生成。 ! 106: bool busfree_intr_enable; ! 107: static const int PCTL_MASK = 0x87; // 書き込みマスク ! 108: static const int PCTL_BFINT_EN = 0x80; // BusFree INT Enable ! 109: static const int PCTL_MSG = 0x04; ! 110: static const int PCTL_CD = 0x02; ! 111: static const int PCTL_IO = 0x01; ! 112: ! 113: FixedQueue<uint8, 8> dreg; // DREG レジスタ ! 114: ! 115: uint8 temp_in; // TEMP レジスタ (SCSI -> MPU) ! 116: uint8 temp_out; // TEMP レジスタ (MPU -> SCSI) ! 117: uint32 tc; // TC ! 118: ! 119: uint32 GetTCL() const { return tc & 0x0000ff; } // TCL ! 120: ! 121: // MBC (内部の読み込み専用レジスタ) ! 122: // TC の下位4ビットが読めるらしい ! 123: uint8 mbc() const { ! 124: return tc & 15; ! 125: } ! 126: ! 127: // Set/Reset ACK/REQ 内部状態 ! 128: bool ackreq; ! 129: }; ! 130: ! 131: class SPCDevice : public SCSIHostDevice ! 132: { ! 133: typedef SCSIHostDevice inherited; ! 134: private: ! 135: // X680x0 では $E96000〜 ! 136: // LUNA では $E100_0000〜 ! 137: ! 138: public: ! 139: SPCDevice(uint32); ! 140: virtual ~SPCDevice(); ! 141: ! 142: virtual bool Init(); ! 143: virtual void ResetHard(); ! 144: virtual void ResetSoft(); ! 145: void Reset(); ! 146: ! 147: virtual uint64 Read8(uint32 addr); ! 148: virtual uint64 Read16(uint32 addr); ! 149: virtual uint64 Write8(uint32 addr, uint32 data); ! 150: virtual uint64 Write16(uint32 addr, uint32 data); ! 151: virtual uint64 Peek8(uint32 addr); ! 152: virtual bool MonitorUpdate(); ! 153: ! 154: // イベントコールバック ! 155: void BusFreeCallback(int); ! 156: void SelectionCompleteCallback(int); ! 157: void SelectionFailedCallback(int); ! 158: ! 159: // ターゲットがバスフリーフェーズに移行した ! 160: virtual void BusRelease(); ! 161: ! 162: private: ! 163: void MonitorReg(int x, int y, uint32 reg, const char * const *names); ! 164: ! 165: // SCTL レジスタへの書き込み ! 166: void WriteSCTL(uint32); ! 167: ! 168: // SCMD レジスタ値の取得 ! 169: uint32 GetSCMD() const; ! 170: ! 171: // SCMD レジスタへの書き込み ! 172: void WriteSCMD(uint32); ! 173: ! 174: // INTS レジスタへの書き込み ! 175: void WriteINTS(uint32); ! 176: ! 177: // INTS 設定 ! 178: void SetINTS(uint32); ! 179: ! 180: // PSNS レジスタ値の取得 ! 181: uint32 GetPSNS() const; ! 182: ! 183: // SSTS レジスタ値の取得 ! 184: uint32 GetSSTS() const; ! 185: ! 186: // PCTL レジスタ値の取得 ! 187: uint32 GetPCTL() const; ! 188: ! 189: // バスフリーフェーズに移行する ! 190: void BusFree(); ! 191: ! 192: // Select コマンド実行 ! 193: void SelectCommand(); ! 194: ! 195: // Transfer コマンド実行 ! 196: void TransferCommand(); ! 197: ! 198: // DREG へのデータの充填 ! 199: void EnqueueToDREG(); ! 200: ! 201: // SCSI コマンド ! 202: void ExecCommand(); ! 203: ! 204: // レジスタ ! 205: struct SPC spc {}; ! 206: ! 207: uint32 regbase = 0; // レジスタの先頭アドレス ! 208: int regstride = 0; // レジスタ間の距離 ! 209: ! 210: // SPC に入力されるクロック周期 [nsec] ! 211: int t_CLF = 0; ! 212: ! 213: // 現在のフェーズ ! 214: uint phase = 0; ! 215: ! 216: // Command フェーズで受け取ったコマンド列 ! 217: std::vector<uint8> cmds {}; ! 218: ! 219: // Data{In,Out} フェーズのバッファ ! 220: uint8 *dataptr = NULL; ! 221: uint datalen = 0; ! 222: ! 223: // イベント ! 224: Event event {}; ! 225: }; ! 226: ! 227: extern SPCDevice *gSPC;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.