Created
December 12, 2020 07:06
-
-
Save lpproj/48088be056e3fe5f0bd86f26cf8bac3d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
patch against RaSCSI 1.47 | |
to (minimal) support of Old 5.25" 650M double-sided MO drive (NEC PC-OD101) | |
usage: | |
rasctl -i 1 -c attach -t mo650 | |
rasctl -i 1 -c insert -f /home/pi/single_sided_mo_flat_image | |
size of image: 305135616 bytes (297984sectors * 1024bytes) | |
revision: | |
* 2020-12-12 lpproj initial patch | |
diff --git a/src/raspberrypi/disk.cpp b/src/raspberrypi/disk.cpp | |
--- a/src/raspberrypi/disk.cpp | |
+++ b/src/raspberrypi/disk.cpp | |
@@ -3467,6 +3467,204 @@ int FASTCALL SCSIMO::AddVendor(int page, BOOL change, BYTE *buf) | |
return 12; | |
} | |
+ | |
+//=========================================================================== | |
+// | |
+// SCSI 光磁気ディスク - Old 5.25" 650M drive (as WORM) | |
+// | |
+//=========================================================================== | |
+ | |
+//--------------------------------------------------------------------------- | |
+// | |
+// コンストラクタ | |
+// | |
+//--------------------------------------------------------------------------- | |
+SCSIMO_WORM650::SCSIMO_WORM650() : SCSIMO() | |
+{ | |
+ // SCSI 光磁気ディスク | |
+ disk.id = MAKEID('S', 'C', 'M', 'W'); | |
+ | |
+ // リムーバブル | |
+ disk.removable = TRUE; | |
+} | |
+ | |
+//--------------------------------------------------------------------------- | |
+// | |
+// オープン | |
+// | |
+//--------------------------------------------------------------------------- | |
+BOOL FASTCALL SCSIMO_WORM650::Open(const Filepath& path, BOOL attn) | |
+{ | |
+ Fileio fio; | |
+ off64_t size; | |
+ | |
+ ASSERT(this); | |
+ ASSERT(!disk.ready); | |
+ | |
+ // 読み込みオープンが必要 | |
+ if (!fio.Open(path, Fileio::ReadOnly)) { | |
+ return FALSE; | |
+ } | |
+ | |
+ // ファイルサイズの取得 | |
+ size = fio.GetFileSize(); | |
+ fio.Close(); | |
+ | |
+ switch (size) { | |
+ // 300MB (single-side of '650M' medium) | |
+ case 305135616: | |
+ disk.size = 10; | |
+ disk.blocks = 297984; | |
+ break; | |
+ | |
+ // その他(エラー) | |
+ default: | |
+ return FALSE; | |
+ } | |
+ | |
+ // 基本クラス | |
+ Disk::Open(path); | |
+ | |
+ // レディならアテンション | |
+ if (disk.ready && attn) { | |
+ disk.attn = TRUE; | |
+ } | |
+ | |
+ return TRUE; | |
+} | |
+ | |
+#ifndef RASCSI | |
+//--------------------------------------------------------------------------- | |
+// | |
+// ロード | |
+// | |
+//--------------------------------------------------------------------------- | |
+// BOOL FASTCALL SCSIMO_WORM650::Load(Fileio *fio, int ver) | |
+#endif // RASCSI | |
+ | |
+//--------------------------------------------------------------------------- | |
+// | |
+// INQUIRY | |
+// | |
+//--------------------------------------------------------------------------- | |
+int FASTCALL SCSIMO_WORM650::Inquiry( | |
+ const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor) | |
+{ | |
+ const char VENDOR_ID[] = "NEC"; | |
+ const char PRODUCT_ID[] = "ODC141 -151"; | |
+ // const char REVISION_LEVEL[] = "0001"; | |
+ int size; | |
+ char rev[32]; | |
+ | |
+ ASSERT(this); | |
+ ASSERT(cdb); | |
+ ASSERT(buf); | |
+ ASSERT(cdb[0] == 0x12); | |
+ | |
+ // EVPDチェック | |
+ if (cdb[1] & 0x01) { | |
+ disk.code = DISK_INVALIDCDB; | |
+ return FALSE; | |
+ } | |
+ | |
+ // 基本データ | |
+ // NEC PC-OD101 | |
+ // thank UME-3 for the report (https://twitter.com/ume3fmp/status/1337035804737032194) | |
+ // buf[0] ... 0x84 (WORM, Vendor-specific) | |
+ // buf[1] ... 0x80 (Removable) | |
+ // buf[2] ... 0x01 (SCSI-1) | |
+ // buf[3] ... 0x01 (SCSI-1 CCS) | |
+ // buf[4] ... 0x1f (Additional length) | |
+ memset(buf, 0, 8); | |
+ buf[0] = 0x84; | |
+ buf[1] = 0x80; | |
+ buf[2] = 0x01; | |
+ buf[3] = 0x01; | |
+ buf[4] = 36 - 5; // 必須 | |
+ | |
+ // 空白で埋める | |
+ memset(&buf[8], 0x20, buf[4] - 3); | |
+ | |
+ // ベンダ | |
+ memcpy(&buf[8], VENDOR_ID, strlen(VENDOR_ID)); | |
+ | |
+ // 製品名 | |
+ memcpy(&buf[16], PRODUCT_ID, strlen(PRODUCT_ID)); | |
+ | |
+ // リビジョン(XM6のバージョンNo) | |
+ sprintf(rev, "0%01d%01d%01d", | |
+ (int)major, (int)(minor >> 4), (int)(minor & 0x0f)); | |
+ memcpy(&buf[32], rev, 4); | |
+ | |
+ // 返却できるデータのサイズ | |
+ size = (buf[4] + 5); | |
+ | |
+ // 相手のバッファが少なければ制限する | |
+ if (size > (int)cdb[4]) { | |
+ size = (int)cdb[4]; | |
+ } | |
+ | |
+ // 成功 | |
+ disk.code = DISK_NOERROR; | |
+ return size; | |
+} | |
+ | |
+//--------------------------------------------------------------------------- | |
+// | |
+// MODE SELECT | |
+// | |
+//--------------------------------------------------------------------------- | |
+BOOL FASTCALL SCSIMO_WORM650::ModeSelect(const DWORD *cdb, const BYTE *buf, int length) | |
+{ | |
+// int page; | |
+// int size; | |
+ | |
+ ASSERT(this); | |
+ ASSERT(buf); | |
+ ASSERT(length >= 0); | |
+ | |
+ disk.code = DISK_INVALIDCMD; | |
+ return FALSE; | |
+} | |
+ | |
+//--------------------------------------------------------------------------- | |
+// | |
+// Vendor Unique Format Page 20h (MO) | |
+// | |
+//--------------------------------------------------------------------------- | |
+int FASTCALL SCSIMO_WORM650::AddVendor(int page, BOOL change, BYTE *buf) | |
+{ | |
+ ASSERT(this); | |
+ ASSERT(buf); | |
+ | |
+ return 0; | |
+} | |
+ | |
+//--------------------------------------------------------------------------- | |
+// | |
+// MODE SENSE | |
+// | |
+//--------------------------------------------------------------------------- | |
+int FASTCALL SCSIMO_WORM650::ModeSense(const DWORD *cdb, BYTE *buf) | |
+{ | |
+ ASSERT(this); | |
+ ASSERT(buf); | |
+ ASSERT(length >= 0); | |
+ | |
+ disk.code = DISK_INVALIDCMD; | |
+ return FALSE; | |
+} | |
+ | |
+int FASTCALL SCSIMO_WORM650::ModeSense10(const DWORD *cdb, BYTE *buf) | |
+{ | |
+ ASSERT(this); | |
+ ASSERT(buf); | |
+ ASSERT(length >= 0); | |
+ | |
+ disk.code = DISK_INVALIDCMD; | |
+ return FALSE; | |
+} | |
+ | |
//=========================================================================== | |
// | |
// CDトラック | |
diff --git a/src/raspberrypi/disk.h b/src/raspberrypi/disk.h | |
--- a/src/raspberrypi/disk.h | |
+++ b/src/raspberrypi/disk.h | |
@@ -491,6 +491,41 @@ public: | |
// ベンダ特殊ページ追加 | |
}; | |
+ | |
+//=========================================================================== | |
+// | |
+// SCSI 光磁気ディスク - Old 5.25" 650M MO drive (as WORM) | |
+// | |
+//=========================================================================== | |
+class SCSIMO_WORM650 : public SCSIMO | |
+{ | |
+public: | |
+ // 基本ファンクション | |
+ SCSIMO_WORM650(); | |
+ // コンストラクタ | |
+ BOOL FASTCALL Open(const Filepath& path, BOOL attn = TRUE); | |
+ // オープン | |
+#ifndef RASCSI | |
+ BOOL FASTCALL Load(Fileio *fio, int ver); | |
+ // ロード | |
+#endif // RASCSI | |
+ | |
+ // コマンド | |
+ int FASTCALL Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); | |
+ // INQUIRYコマンド | |
+ BOOL FASTCALL ModeSelect(const DWORD *cdb, const BYTE *buf, int length); | |
+ // MODE SELECT(6)コマンド | |
+ virtual int FASTCALL ModeSense(const DWORD *cdb, BYTE *buf); | |
+ // MODE SENSEコマンド | |
+ virtual int FASTCALL ModeSense10(const DWORD *cdb, BYTE *buf); | |
+ // MODE SENSE(10)コマンド | |
+ | |
+ // サブ処理 | |
+ int FASTCALL AddVendor(int page, BOOL change, BYTE *buf); | |
+ // ベンダ特殊ページ追加 | |
+}; | |
+ | |
+ | |
//--------------------------------------------------------------------------- | |
// | |
// クラス先行定義 | |
diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp | |
--- a/src/raspberrypi/rascsi.cpp | |
+++ b/src/raspberrypi/rascsi.cpp | |
@@ -503,6 +503,9 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) | |
case 2: // MO | |
pUnit = new SCSIMO(); | |
break; | |
+ case 0x82: // Old 5.25" 650M MO, single-sided (as WORM) | |
+ pUnit = new SCSIMO_WORM650(); | |
+ break; | |
case 3: // CD | |
pUnit = new SCSICD(); | |
break; | |
@@ -569,6 +572,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) | |
// MOかCDの場合だけ有効 | |
if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O') && | |
+ pUnit->GetID() != MAKEID('S', 'C', 'M', 'W') && | |
pUnit->GetID() != MAKEID('S', 'C', 'C', 'D')) { | |
FPRT(fp, "Error : Operation denied(Deveice isn't removable)\n"); | |
return FALSE; | |
@@ -580,7 +584,7 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) | |
filepath.SetPath(file); | |
// オープン | |
- if (pUnit->Open(filepath)) { | |
+ if (!pUnit->Open(filepath)) { | |
FPRT(fp, "Error : File open error [%s]\n", file); | |
return FALSE; | |
} | |
@@ -591,7 +595,8 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file) | |
break; | |
case 4: // PROTECT | |
- if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O')) { | |
+ if (pUnit->GetID() != MAKEID('S', 'C', 'M', 'O') && | |
+ pUnit->GetID() != MAKEID('S', 'C', 'M', 'W')) { | |
FPRT(fp, "Error : Operation denied(Deveice isn't MO)\n"); | |
return FALSE; | |
} | |
@@ -792,6 +797,9 @@ BOOL ParseArgument(int argc, char* argv[]) | |
} else if (strcasecmp(ext, "mos") == 0) { | |
// MO | |
type = 2; | |
+ } else if (strcasecmp(ext, "mow") == 0) { | |
+ // Old 5.25" 650M MO, single-sided | |
+ type = 0x82; | |
} else if (strcasecmp(ext, "iso") == 0) { | |
// CD | |
type = 3; | |
diff --git a/src/raspberrypi/rasctl.cpp b/src/raspberrypi/rasctl.cpp | |
--- a/src/raspberrypi/rasctl.cpp | |
+++ b/src/raspberrypi/rasctl.cpp | |
@@ -90,7 +90,7 @@ int main(int argc, char* argv[]) | |
fprintf(stderr, " where ID := {0|1|2|3|4|5|6|7}\n"); | |
fprintf(stderr, " UNIT := {0|1} default setting is 0.\n"); | |
fprintf(stderr, " CMD := {attach|detach|insert|eject|protect}\n"); | |
- fprintf(stderr, " TYPE := {hd|mo|cd|bridge}\n"); | |
+ fprintf(stderr, " TYPE := {hd|mo|mo650|cd|bridge}\n"); | |
fprintf(stderr, " FILE := image file path\n"); | |
fprintf(stderr, " CMD is 'attach' or 'insert' and FILE parameter is required.\n"); | |
fprintf(stderr, "Usage: %s -l\n", argv[0]); | |
@@ -146,6 +146,11 @@ int main(int argc, char* argv[]) | |
case 'm': // MO | |
case 'M': | |
type = 2; | |
+ if (xstrcasecmp(optarg, "mo5")==0 || | |
+ xstrcasecmp(optarg, "mo650")==0 || | |
+ xstrcasecmp(optarg, "mow")==0) { | |
+ type = 0x82; // Old 5.25" 650M MO, single-sided | |
+ } | |
break; | |
case 'c': // CD | |
case 'C': |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment