--- nono/vm/scsi.cpp 2026/04/29 17:04:36 1.1.1.3 +++ nono/vm/scsi.cpp 2026/04/29 17:05:28 1.1.1.6 @@ -3,16 +3,62 @@ // Copyright (C) 2020 nono project // Licensed under nono-license.txt // -// SCSI + +// +// SCSI (定数等) // -#include "scsibus.h" +#include "scsi.h" + +// フェーズ文字列を返す +/*static*/ const char * +SCSI::GetPhaseName(Phase phase) +{ + switch (phase) { + case BusFree: return "BusFree"; + case Arbitration: return "Arbitration"; + case Selection: return "Selection"; + case Reselection: return "Reselection"; + case Transfer: return "Transfer"; + default: return "Phase?"; + } +} + +// 情報転送フェーズ文字列を返す +/*static*/ const char * +SCSI::GetXferPhaseName(XferPhase xfer) +{ + switch (xfer) { + case DataOut: return "DataOut"; + case DataIn: return "DataIn"; + case Command: return "Command"; + case Status: return "Status"; + case MsgOut: return "MsgOut"; + case MsgIn: return "MsgIn"; + case End: return "End"; + default: return "XferPhase?"; + } +} + +// デバイス種別文字列を返す +/*static*/ const char * +SCSI::GetDevTypeName(DevType type) +{ + switch (type) { + case DevType::None: return "None"; + case DevType::Initiator: return "Initiator"; + case DevType::HD: return "HD"; + case DevType::CD: return "CD"; + case DevType::MO: return "MO"; + default: return "DevType?"; + } +} // cmd に対応するコマンド名を返す。 -const char * +/*static*/ const char * SCSI::GetCommandName(uint8 cmd) { - if (cmd < countof(commandname)) { + if (cmd < commandname.size()) { return commandname[cmd]; } else { return NULL; @@ -20,8 +66,8 @@ SCSI::GetCommandName(uint8 cmd) } // コマンド名 -/*static*/ const char * const -SCSI::commandname[Command::MAX] = +/*static*/ const std::vector +SCSI::commandname = { "TestUnitReady", // 00 "RezeroUnit", // 01 @@ -60,7 +106,7 @@ SCSI::commandname[Command::MAX] = NULL, // 20 NULL, // 21 NULL, // 22 - NULL, // 23 + "ReadFormatCapacities", // 23 NULL, // 24 "ReadCapacity", // 25 NULL, // 26 @@ -94,8 +140,8 @@ SCSI::commandname[Command::MAX] = "ChangeDefinition", // 40 "WriteSame", // 41 NULL, // 42 - NULL, // 43 - NULL, // 44 + "ReadTOC", // 43 + "ReadHeader", // 44 NULL, // 45 NULL, // 46 NULL, // 47 @@ -108,7 +154,7 @@ SCSI::commandname[Command::MAX] = NULL, // 4e NULL, // 4f NULL, // 50 - NULL, // 51 + "ReadDiscInformation", // 51 NULL, // 52 NULL, // 53 NULL, // 54 @@ -119,3 +165,72 @@ SCSI::commandname[Command::MAX] = NULL, // 59 "ModeSense(10)", // 5a }; + +// センスキーとその名前を表示用に整形したものを返す +/*static*/ std::string +SCSI::GetSenseKeyDisp(uint8 key) +{ + if (__predict_true(key < sensekeyname.size())) { + return string_format("%s($%x)",sensekeyname[key], key); + } else { + return string_format("$%x", key); + } +} + +/*static*/ const std::vector +SCSI::sensekeyname = +{ + "NoSense", // 0x0 + "RecoveredError", // 0x1 + "NotReady", // 0x2 + "MediumError", // 0x3 + "HardwareError", // 0x4 + "IllegalRequest", // 0x5 + "UnitAttention", // 0x6 + "DataProtect", // 0x7 + "BlankCheck", // 0x8 + "VendorSpecific", // 0x9 + "CopyAborted", // 0xa + "AbortedCommand", // 0xb + "Equal", // 0xc + "VolumeOverflow", // 0xd + "Miscompare", // 0xe + "Reserved", // 0xf +}; + +// Mode Select/Sense のページ番号とページ名を表示用に整形したものを返す +/*static*/ std::string +SCSI::GetModePageDisp(uint8 page) +{ + const char *name; + + if (__predict_true(page < modepagename.size())) { + name = modepagename[page]; + } else if (page == 0x3f) { + name = "AllPages"; + } else { + return string_format("$%02x", page); + } + + return string_format("$%02x(%s)", page, name); +} + +/*static*/ const std::vector +SCSI::modepagename = +{ + "VendorSpecific", // 00 + "ReadWriteErrorRecovery", // 01 + "DisconnectReconnect", // 02 + "FormatDevice", // 03 + "RigidDiskGeometry", // 04 + "FlexibleDisk", // 05 + "OpticalMemory", // 06 + "VerifyErrorRecovery", // 07 + "CachingPage", // 08 + "PeripheralDevice", // 09 + "ControlMode", // 0a + "MediumTypeSupported", // 0b + "NotchAndPartition", // 0c + "CDROM", // 0d + "CDROMAudioControl", // 0e +};