--- nono/vm/scsidev.cpp 2026/04/29 17:04:45 1.1.1.6 +++ nono/vm/scsidev.cpp 2026/04/29 17:04:50 1.1.1.8 @@ -9,7 +9,6 @@ #include "scsidev.h" #include "config.h" #include "mainapp.h" -#include "mystring.h" // // SCSI デバイス @@ -114,7 +113,7 @@ SCSIHostDevice::Init() } } if (!typestr.empty()) { - putmsg("%s target #%d %s", GetConfigName(), id, + putmsgn("%s target #%d %s", GetConfigName(), id, typestr.c_str()); } } @@ -334,7 +333,7 @@ class SCSICmdRead6 : public SCSICmd if (blks == 0) { blks = 256; } - parent->putlog(1, "READ6 LBA=0x%x blks=0x%x", lba, blks); + parent->putlogf(1, lstr("READ6 LBA=0x%x blks=0x%x", lba, blks)); if (((uint64)lba + (uint64)blks) * parent->GetBlocksize() > hdparent->GetSize()) @@ -398,7 +397,7 @@ class SCSICmdWrite6 : public SCSICmd } SCSI::XferPhase DoneDataOut() override { - parent->putlog(1, "WRITE6 LBA=0x%x blks=0x%x", lba, blks); + parent->putlogf(1, lstr("WRITE6 LBA=0x%x blks=0x%x", lba, blks)); if (hdparent->writeprotect == false) { memcpy(hdparent->mem + (lba * parent->GetBlocksize()), buf.data(), buf.size()); @@ -500,7 +499,8 @@ class SCSICmdModeSense6 : public SCSICmd parent->ClearSense(); // 未実装 (XXX センスデータは適当) - parent->putlog(1, "ModeSense(6) PageCode $%02x 未実装", pagecode); + parent->putlogf(1, lstr("ModeSense(6) PageCode $%02x 未実装", + pagecode)); parent->sensekey = SCSI::SenseKey::IllegalRequest; parent->senseasc = SCSI::ASC::InvalidFieldInCDB; status_byte = SCSI::StatusByte::CheckCondition; @@ -524,7 +524,7 @@ class SCSICmdStartStopUnit : public SCSI // XXX それっぽい時間待つくらいはしてもいいかも知れない SCSI::XferPhase Command(std::vector& cmdseq) override { - parent->putlog(1, "StartStopUnit"); + parent->putlogf(1, lstr("StartStopUnit")); return inherited::Command(cmdseq); } }; @@ -547,7 +547,7 @@ class SCSICmdReadCapacity : public SCSIC // PMI=1 は未サポート if ((cmdseq[8] & 0x01) != 0) { - parent->putmsg("SCSI ReadCapacity PMI=1 not supported"); + parent->putlogf(0, lstr("SCSI ReadCapacity PMI=1 not supported")); } // 応答データは @@ -588,7 +588,7 @@ class SCSICmdRead10 : public SCSICmd parent->ClearSense(); if ((cmdseq[1] & 0x01)) { - parent->putmsg("SCSI Read(10) RelAdr not supported"); + parent->putlogf(0, lstr("SCSI Read(10) RelAdr not supported")); } lba = cmdseq[2] << 24; @@ -597,7 +597,7 @@ class SCSICmdRead10 : public SCSICmd lba |= cmdseq[5]; blks = cmdseq[7] << 8; blks |= cmdseq[8]; - parent->putlog(1, "READ10 LBA=0x%x blks=0x%x", lba, blks); + parent->putlogf(1, lstr("READ10 LBA=0x%x blks=0x%x", lba, blks)); if (((uint64)lba + (uint64)blks) * parent->GetBlocksize() > hdparent->GetSize()) @@ -620,6 +620,60 @@ class SCSICmdRead10 : public SCSICmd }; // +// SCSI コマンド 0x2a Write(10) (ダイレクトアクセスデバイス) +// +class SCSICmdWrite10 : public SCSICmd +{ + using inherited = SCSICmd; + public: + SCSICmdWrite10(SCSITarget *p) : inherited(p) { + hdparent = dynamic_cast(parent); + } + virtual ~SCSICmdWrite10() override { } + + SCSI::XferPhase Command(std::vector& cmdseq) override { + // センスデータをクリア + parent->ClearSense(); + + lba = cmdseq[2] << 24; + lba |= cmdseq[3] << 16; + lba |= cmdseq[4] << 8; + lba |= cmdseq[5]; + blks = cmdseq[7] << 8; + blks |= cmdseq[8]; + + if (((uint64)lba + (uint64)blks) * parent->GetBlocksize() > + hdparent->GetSize()) + { + parent->sensekey = SCSI::SenseKey::IllegalRequest; + parent->senseasc = SCSI::ASC::InvalidFieldInCDB; + status_byte = SCSI::StatusByte::CheckCondition; + return SCSI::XferPhase::Status; + } + + // 平均シークタイム + optime = hdparent->seektime; + + recvbytes = blks * parent->GetBlocksize(); + return SCSI::XferPhase::DataOut; + } + + SCSI::XferPhase DoneDataOut() override { + parent->putlogf(1, lstr("WRITE10 LBA=0x%x blks=0x%x", lba, blks)); + if (hdparent->writeprotect == false) { + memcpy(hdparent->mem + (lba * parent->GetBlocksize()), + buf.data(), buf.size()); + } + return SCSI::XferPhase::Status; + } + + private: + SCSIHD *hdparent; + uint32 lba; + uint32 blks; +}; + +// // SCSI コマンド サポートしていないコマンド // class SCSICmdNotSupportedCommand : public SCSICmd @@ -785,7 +839,7 @@ SCSITarget::TransferCB() for (const auto& v : cmdseq) { cmdbuf += string_format(" $%02x", v); } - putlog("%s", cmdbuf.c_str()); + putlogn("%s", cmdbuf.c_str()); } // 最終バイトを受信したらコマンドを選択 DispatchCmd(); @@ -1043,6 +1097,10 @@ SCSIHD::DispatchCmd() cmd.reset(new SCSICmdRead10(this)); break; + case SCSI::Command::Write10: // 0x2a + cmd.reset(new SCSICmdWrite10(this)); + break; + default: // 見付からなければ基本クラス側に任せる inherited::DispatchCmd();