|
|
nono 0.0.1
//
// nono
// Copyright (C) 2018 [email protected]
//
#pragma once
#include "device.h"
#include "scsi.h"
// 前方参照 (scsitarget.cpp 内だけで使われている)
// friend class に書くクラス名は前方参照なくても大丈夫らしい。
class SCSICmd;
class SCSITarget : public Device
{
typedef Device inherited;
friend class SCSICmdModeSelect6;
friend class SCSICmdRead6;
friend class SCSICmdWrite6;
friend class SCSICmdRead10;
public:
SCSITarget(SCSIHostDevice *host, int id, SCSI::DevType type);
virtual ~SCSITarget();
// SCSI デバイス種別を取得
SCSI::DevType GetDevType() const { return devtype; }
void Selected();
void Ack();
// コマンドフェーズの処理。
void ExecCommand(const std::vector<uint8>& cmds);
// デバイス固有のコマンドの処理。(派生クラスで用意)
virtual SCSICmd *ExecDeviceCommand();
// データインフェーズを開始。
uint ExecDataIn(const uint8 **ptr);
// データアウトフェーズを開始。
uint ExecDataOut(uint8 **ptr);
// ステータスバイトを取得 (およびデータアウトフェーズ完了処理)。
uint8 GetStatusByte();
// メッセージバイトを取得。
uint8 GetMessageByte();
protected:
SCSIHostDevice *host = NULL; // ホストアダプタ
SCSI::DevType devtype {}; // デバイス種別
int ID = 0; // 自分の SCSI ID
// SCSI バス信号は SCSIHost が管理
uint8 GetDATA() { return host->GetDATA(); }
void SetDATA(uint8 val) { host->SetDATA(val); }
bool GetACK() const { return host->GetACK(); }
void SetACK(bool val) { host->SetACK(val); }
bool GetREQ() const { return host->GetREQ(); }
void SetREQ(bool val) { host->SetREQ(val); }
bool GetSEL() const { return host->GetSEL(); }
void AssertSEL(int id) { host->AssertSEL(id); }
void NegateSEL(int id) { host->NegateSEL(id); }
bool GetBSY() const { return host->GetBSY(); }
void AssertBSY(int id) { host->AssertBSY(id); }
void NegateBSY(int id) { host->NegateBSY(id); }
bool GetMSG() const { return host->GetMSG(); }
void SetMSG(bool val) { host->SetMSG(val); }
bool GetCD() const { return host->GetCD(); }
void SetCD(bool val) { host->SetCD(val); }
bool GetIO() const { return host->GetIO(); }
void SetIO(bool val) { host->SetIO(val); }
bool GetATN() const { return host->GetATN(); }
void BusFreePhase();
void DataOutPhase();
void DataInPhase();
void CommandPhase();
void StatusPhase();
void MsgOutPhase();
void MsgInPhase();
uint phase = 0; // ターゲットの状態
uint nextphase = 0; // ATN による MsgOut の次の本来のフェーズ
// ターゲットの現在のフェーズを取得
uint GetPhase() const { return phase; }
// ターゲットのフェーズを newphase に移行
void SetPhase(uint newphase);
// コマンド
std::vector<uint8> cmds {};
SCSICmd *cmd = NULL;
uint8 lastdata = 0;
uint8 lastmsg = 0; // 前回の MsgOut のメッセージ
// 論理ブロック長 (ModeSelect コマンドでホストから指定される)
uint32 blocksize = 0;
};
// SCSI HD
class SCSIHD : public SCSITarget
{
typedef SCSITarget inherited;
friend class SCSICmdRead6;
friend class SCSICmdWrite6;
friend class SCSICmdReadCapacity;
friend class SCSICmdRead10;
public:
SCSIHD(SCSIHostDevice *host, int id);
virtual ~SCSIHD();
virtual bool Init();
// デバイス固有のコマンドの処理。
virtual SCSICmd *ExecDeviceCommand();
private:
int fd = 0;
uint8 *mem = NULL;
size_t memlen = 0;
bool writeprotect = false;
static const uint8 inquiry_data[36];
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.