File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / scsi.h
Revision 1.1.1.11 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:49 2026 UTC (3 months ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, HEAD
nono 1.5.0

//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//

//
// SCSI (定数等)
//

#pragma once

#include "device.h"

// このクラスは SCSI プロトコル上の定数などだけを持つ。
class SCSI
{
 public:
	enum {
		IO		= 0x01,
		CD		= 0x02,
		MSG		= 0x04,
		BSY		= 0x08,
		SEL		= 0x10,
	};

	// SCSI のフェーズを表す。
	// フェーズは概ね BSY と SEL の状態遷移によって決まる。
	// 情報転送フェーズの内訳は XferPhase 側で区別する。
	enum Phase {
		BusFree		= 0,
		Arbitration	= 1,
		Selection	= 2,
		Reselection	= 3,
		Transfer	= 4,
	};

	// 情報転送フェーズを表す。
	// この値は MSG,CD,IO で表現できる値をそのまま流用して表現する。
	enum XferPhase {    	// MSG CD IO
		DataOut		= 0,	//   0  0  0
		DataIn		= 1,	//   0  0  1
		Command		= 2,	//   0  1  0
		Status		= 3,	//   0  1  1
		MsgOut		= 6,	//   1  1  0
		MsgIn		= 7,	//   1  1  1

		End			= -1,	// SCSICmd 内でフェーズ遷移を表現するために使う
	};

	// フェーズ文字列を返す
	static const char *GetPhaseName(Phase phase);
	static const char *GetPhaseName(int phase) {
		return GetPhaseName((Phase)phase);
	}

	// 情報転送フェーズ文字列を返す
	static const char *GetXferPhaseName(XferPhase xfer);
	static const char *GetXferPhaseName(int xfer) {
		return GetXferPhaseName((XferPhase)xfer);
	}

	// デバイス種別
	enum class DevType {
		None = 0,
		Initiator,
		HD,
		CD,
		MO,
	};

	// デバイス種別文字列を返す
	static const char *GetDevTypeName(DevType type);

	// コマンド。
	// ダイレクトアクセスデバイスのコマンドを元にしている。
	// シーケンシャルアクセスデバイスでは 0x01 が Rewind だったり
	// 同じコードで違うコマンドのようだが、とりあえずそれは放置。
	struct Command {
		// Group0
		static const uint TestUnitReady		= 0x00;		// 共通
		static const uint RezeroUnit		= 0x01;
		static const uint RequestSense		= 0x03;		// 共通
		static const uint FormatUnit		= 0x04;
		static const uint ReassignBlocks	= 0x07;
		static const uint Read6				= 0x08;
		static const uint Write6			= 0x0a;
		static const uint Seek6				= 0x0b;
		static const uint Inquiry			= 0x12;		// 共通
		static const uint ModeSelect6		= 0x15;		// 共通
		static const uint Reserve			= 0x16;
		static const uint Release			= 0x17;
		static const uint Copy				= 0x18;		// 共通
		static const uint ModeSense6		= 0x1a;
		static const uint StartStopUnit		= 0x1b;
		static const uint ReceiveDiagnosticResults	= 0x1c;	// 共通
		static const uint SendDiagnostic	= 0x1d;		// 共通
		static const uint PreventAllowMediumRemoval	= 0x1e;
		// Group1
		static const uint ReadFormatCapacities		= 0x23;
		static const uint ReadCapacity		= 0x25;		// Direct Access
		static const uint ReadCDROMCapacity	= 0x25;		// CD-ROM
		static const uint Read10			= 0x28;
		static const uint Write10			= 0x2a;
		static const uint Seek10			= 0x2b;
		// Group1
		static const uint WriteAndVerify10	= 0x2e;
		static const uint Verify10			= 0x2f;
		static const uint SearchDataHigh10	= 0x30;
		static const uint SearchDataEqual10	= 0x31;
		static const uint SearchDataLow10	= 0x32;
		static const uint SetLimits			= 0x33;
		static const uint PreFetch			= 0x34;
		static const uint SynchronizeCache	= 0x35;
		static const uint LockUnlockCache	= 0x36;
		static const uint ReadDefectData10	= 0x37;
		static const uint Compare			= 0x39;		// 共通
		static const uint CopyAndVerify		= 0x3a;		// 共通
		static const uint WriteBuffer		= 0x3b;		// 共通
		static const uint ReadBuffer		= 0x3c;		// 共通
		static const uint ReadLong			= 0x3e;
		static const uint WriteLong			= 0x3f;
		// Group2
		static const uint ChangeDefinition	= 0x40;
		static const uint WriteSame			= 0x41;
		static const uint ReadTOC			= 0x43;		// CD-ROM
		static const uint ReadHeader		= 0x44;		// CD-ROM
		static const uint LogSelect			= 0x4c;		// 共通
		static const uint LogSense			= 0x4d;		// 共通
		static const uint ReadDiscInformation	= 0x51;	// ?
		static const uint ModeSelect10		= 0x55;		// 共通
		static const uint ModeSense10		= 0x5a;		// 共通

		// SCSI-3(?)
		static const uint ReportLUNs		= 0xa0;
	};
	// SCSI コマンド名を返す
	static const char *GetCommandName(uint8 cmd);

	// ステータスバイト
	struct StatusByte {
		static const uint8 Good					= (0x00U << 1);
		static const uint8 CheckCondition		= (0x01U << 1);
		static const uint8 ConditionMet			= (0x02U << 1);
		static const uint8 Busy					= (0x04U << 1);
		static const uint8 Intermediate			= (0x08U << 1);
		static const uint8 IntermediateCondMet	= (0x0aU << 1);
		static const uint8 ReservationConflict	= (0x0cU << 1);
		static const uint8 CommandTerminated	= (0x11U << 1);
		static const uint8 QueueFull			= (0x14U << 1);
	};

	// メッセージバイト
	struct MsgByte {
		static const uint8 CommandComplete			= 0x00;
		static const uint8 ExtendMessage			= 0x01;
		static const uint8 SaveDataPointer			= 0x02;
		static const uint8 RestorePointers			= 0x03;
		static const uint8 Disconnect				= 0x04;
		static const uint8 InitiatorDetectedError	= 0x05;
		static const uint8 Abort					= 0x06;
		static const uint8 MessageReject			= 0x07;
		static const uint8 NoOperation				= 0x08;
		static const uint8 MessageParityError		= 0x09;
		static const uint8 LinkedCommandComplete	= 0x0a;
		static const uint8 LinkedCommandCompleteWithFlag = 0x0b;
		static const uint8 BusDeviceReset			= 0x0c;
		static const uint8 AbortTag					= 0x0d;
		static const uint8 ClearQueue				= 0x0e;
		static const uint8 InitiateRecovery			= 0x0f;
		static const uint8 ReleaseRecovery			= 0x10;
		static const uint8 TerminateIOProcess		= 0x11;
		static const uint8 SimpleQueueTag			= 0x20;
		static const uint8 HeadOfQueueTag			= 0x21;
		static const uint8 OrderedQueueTag			= 0x22;
		static const uint8 IgnoreWideResidue		= 0x23;
		static const uint8 Identify					= 0x80;	// 0x80..0xff
	};

	// Inquiry コマンドの Peripheral Qualifier フィールド
	struct InquiryQualifier {
		static const uint8 LU_Present		= 0x00;
		static const uint8 LU_NotPreseted	= 0x20;
		static const uint8 Reserved			= 0x40;
		static const uint8 LU_NotSupported	= 0x60;
		static const uint8 Mask				= 0xe0;
	};
	// Inquiry コマンドの Peripheral Device Type フィールド
	struct InquiryDeviceType {
		static const uint8 DirectAccess		= 0x00;
		static const uint8 SequentialAccess	= 0x01;
		static const uint8 Printer			= 0x02;
		static const uint8 Processor		= 0x03;
		static const uint8 WriteOnce		= 0x04;
		static const uint8 CDROM			= 0x05;
		static const uint8 Scanner			= 0x06;
		static const uint8 MO				= 0x07;
		static const uint8 MediaChanger		= 0x08;
		static const uint8 Communication	= 0x09;
		static const uint8 Unknown			= 0x1f;
	};

	// センスキー
	struct SenseKey {
		static const uint8 NoSense			= 0x0;
		static const uint8 RecoveredError	= 0x1;
		static const uint8 NotReady			= 0x2;
		static const uint8 MediumError		= 0x3;
		static const uint8 HardwareError	= 0x4;
		static const uint8 IllegalRequest	= 0x5;
		static const uint8 UnitAttention	= 0x6;
		static const uint8 DataProtect		= 0x7;
		static const uint8 BlankCheck		= 0x8;
		static const uint8 VendorSpecific	= 0x9;
		static const uint8 CopyAborted		= 0xa;
		static const uint8 AbortedCommand	= 0xb;
		static const uint8 Equal			= 0xc;
		static const uint8 VolumeOverflow	= 0xd;
		static const uint8 Miscompare		= 0xe;
		static const uint8 Reserved			= 0xf;
	};
	// センスキーコードとキー名を表示用に整形したものを返す
	static std::string GetSenseKeyDisp(uint8 key);

	// ASC/ASCQ
	// 上位バイトが ASC、下位バイトが ASCQ を示す。
	struct ASC {
		static const uint16 NoAdditionalSenseInformation	= 0x0000;
		static const uint16 PeripheralDeviceWriteFault		= 0x0300;
		static const uint16 InvalidCommandOperationCode		= 0x2000;
		static const uint16 InvalidFieldInCDB				= 0x2400;
		static const uint16 LogicalUnitNotSupported			= 0x2500;
		static const uint16 MediumNotPresent				= 0x3a00;
	};

	// Mode Select/Sense のページ
	// - 詳細解説本の日本語訳が微妙に遠い…。
	//   Rigid Disk Geometry Page は「ドライブ・パラメータ」、
	//   Flexible Disk Page は「フロッピ・ディスク・パラメータ」、
	//   Caching Page は「キャッシュ・コントロール・パラメータ」としてある。
	//   ページコード(番号)を軸に読み替えること。
	// - ReadWriteErrorRecovery は CD-ROM クラスではページ番号同じで
	//   ReadErrorRecovery だがそれはもう区別しない。
	// - 名前の後ろの Page は基本省略しているが、Caching Page は省略すると
	//   訳分からんことになるので。
	enum ModePage : uint8 {
		VendorSpecific			= 0x00,
		ReadWriteErrorRecovery	= 0x01,
		DisconnectReconnect		= 0x02,
		FormatDevice			= 0x03,
		RigidDiskGeometry		= 0x04,
		FlexibleDisk			= 0x05,
		OpticalMemory			= 0x06,
		VerifyErrorRecovery		= 0x07,
		CachingPage				= 0x08,
		PeripheralDevice		= 0x09,
		ControlMode				= 0x0a,
		MediumTypeSupported		= 0x0b,
		NotchAndPartition		= 0x0c,
		CDROM					= 0x0d,
		CDROMAudioControl		= 0x0e,

		AllPages				= 0x3f,
	};
	// ページ番号とページ名を表示用に整形したものを返す
	static std::string GetModePageDisp(uint8 page);

 private:
	static const std::vector<const char *> commandname;
	static const std::vector<const char *> sensekeyname;
	static const std::vector<const char *> modepagename;
};

unix.superglobalmegacorp.com

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