Ver código fonte

Initial tape and magneto-optical support

Michael McMaster 10 anos atrás
pai
commit
aad3018779

+ 32 - 39
lib/SCSI2SD/software/SCSI2SD/src/cdrom.c

@@ -277,50 +277,43 @@ int scsiCDRomCommand()
 	int commandHandled = 1;
 
 	uint8 command = scsiDev.cdb[0];
-	if (scsiDev.target->cfg->deviceType == CONFIG_OPTICAL)
+	if (command == 0x43)
 	{
-		if (command == 0x43)
-		{
-			// CD-ROM Read TOC
-			int MSF = scsiDev.cdb[1] & 0x02 ? 1 : 0;
-			uint8_t track = scsiDev.cdb[6];
-			uint16_t allocationLength =
-				(((uint32_t) scsiDev.cdb[7]) << 8) +
-				scsiDev.cdb[8];
+		// CD-ROM Read TOC
+		int MSF = scsiDev.cdb[1] & 0x02 ? 1 : 0;
+		uint8_t track = scsiDev.cdb[6];
+		uint16_t allocationLength =
+			(((uint32_t) scsiDev.cdb[7]) << 8) +
+			scsiDev.cdb[8];
 
-			// Reject MMC commands for now, otherwise the TOC data format
-			// won't be understood.
-			// The "format" field is reserved for SCSI-2
-			uint8_t format = scsiDev.cdb[2] & 0x0F;
-			switch (format)
+		// Reject MMC commands for now, otherwise the TOC data format
+		// won't be understood.
+		// The "format" field is reserved for SCSI-2
+		uint8_t format = scsiDev.cdb[2] & 0x0F;
+		switch (format)
+		{
+			case 0: doReadTOC(MSF, track, allocationLength); break; // SCSI-2
+			case 1: doReadSessionInfo(MSF, allocationLength); break; // MMC2
+			case 2: doReadFullTOC(0, track, allocationLength); break; // MMC2
+			case 3: doReadFullTOC(1, track, allocationLength); break; // MMC2
+			default:
 			{
-				case 0: doReadTOC(MSF, track, allocationLength); break; // SCSI-2
-				case 1: doReadSessionInfo(MSF, allocationLength); break; // MMC2
-				case 2: doReadFullTOC(0, track, allocationLength); break; // MMC2
-				case 3: doReadFullTOC(1, track, allocationLength); break; // MMC2
-				default:
-				{
-					scsiDev.status = CHECK_CONDITION;
-					scsiDev.target->sense.code = ILLEGAL_REQUEST;
-					scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
-					scsiDev.phase = STATUS;
-				}
+				scsiDev.status = CHECK_CONDITION;
+				scsiDev.target->sense.code = ILLEGAL_REQUEST;
+				scsiDev.target->sense.asc = INVALID_FIELD_IN_CDB;
+				scsiDev.phase = STATUS;
 			}
 		}
-		else if (command == 0x44)
-		{
-			// CD-ROM Read Header
-			int MSF = scsiDev.cdb[1] & 0x02 ? 1 : 0;
-			uint32_t lba = 0; // IGNORED for now
-			uint16_t allocationLength =
-				(((uint32_t) scsiDev.cdb[7]) << 8) +
-				scsiDev.cdb[8];
-			doReadHeader(MSF, lba, allocationLength);
-		}
-		else
-		{
-			commandHandled = 0;
-		}
+	}
+	else if (command == 0x44)
+	{
+		// CD-ROM Read Header
+		int MSF = scsiDev.cdb[1] & 0x02 ? 1 : 0;
+		uint32_t lba = 0; // IGNORED for now
+		uint16_t allocationLength =
+			(((uint32_t) scsiDev.cdb[7]) << 8) +
+			scsiDev.cdb[8];
+		doReadHeader(MSF, lba, allocationLength);
 	}
 	else
 	{

+ 10 - 0
lib/SCSI2SD/software/SCSI2SD/src/inquiry.c

@@ -203,6 +203,16 @@ void scsiInquiry()
 			scsiDev.data[1] |= 0x80; // Removable bit.
 			break;
 
+		case CONFIG_SEQUENTIAL:
+			scsiDev.data[0] = 0x01; // device type
+			scsiDev.data[1] |= 0x80; // Removable bit.
+			break;
+			
+		case CONFIG_MO:
+			scsiDev.data[0] = 0x07; // device type
+			scsiDev.data[1] |= 0x80; // Removable bit.
+			break;
+
 		case CONFIG_FLOPPY_14MB:
 		case CONFIG_REMOVEABLE:
 			scsiDev.data[1] |= 0x80; // Removable bit.

+ 43 - 0
lib/SCSI2SD/software/SCSI2SD/src/mo.c

@@ -0,0 +1,43 @@
+//	Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
+//
+//	This file is part of SCSI2SD.
+//
+//	SCSI2SD is free software: you can redistribute it and/or modify
+//	it under the terms of the GNU General Public License as published by
+//	the Free Software Foundation, either version 3 of the License, or
+//	(at your option) any later version.
+//
+//	SCSI2SD is distributed in the hope that it will be useful,
+//	but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//	GNU General Public License for more details.
+//
+//	You should have received a copy of the GNU General Public License
+//	along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+#pragma GCC push_options
+#pragma GCC optimize("-flto")
+
+#include "device.h"
+#include "scsi.h"
+#include "config.h"
+#include "mo.h"
+
+
+// Handle magneto-optical scsi device commands
+int scsiMOCommand()
+{
+	int commandHandled = 0;
+
+	uint8 command = scsiDev.cdb[0];
+	if ((command == 0x2C) || // ERASE(10)
+		(command == 0xAC)) // ERASE(12)
+	{
+		// TODO consider sending an erase command to the SD card.
+
+		commandHandled = 1;
+	}
+
+	return commandHandled;
+}
+
+#pragma GCC pop_options

+ 22 - 0
lib/SCSI2SD/software/SCSI2SD/src/mo.h

@@ -0,0 +1,22 @@
+//	Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
+//
+//	This file is part of SCSI2SD.
+//
+//	SCSI2SD is free software: you can redistribute it and/or modify
+//	it under the terms of the GNU General Public License as published by
+//	the Free Software Foundation, either version 3 of the License, or
+//	(at your option) any later version.
+//
+//	SCSI2SD is distributed in the hope that it will be useful,
+//	but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//	GNU General Public License for more details.
+//
+//	You should have received a copy of the GNU General Public License
+//	along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+#ifndef MO_H
+#define MO_H
+
+int scsiMOCommand(void);
+
+#endif

+ 39 - 0
lib/SCSI2SD/software/SCSI2SD/src/mode.c

@@ -161,6 +161,22 @@ static const uint8 ControlModePage[] =
 0x00, 0x00 // AEN holdoff period.
 };
 
+static const uint8_t SequentialDeviceConfigPage[] =
+{
+0x10, // page code
+0x0E, // Page length
+0x00, // CAP, CAF, Active Format
+0x00, // Active partition
+0x00, // Write buffer full ratio
+0x00, // Read buffer empty ratio
+0x00,0x01, // Write delay time, in 100ms units
+0x00, // Default gap size
+0x10, // auto-generation of default eod (end of data)
+0x00,0x00,0x00 // buffer-size at early warning
+0x00, // No data compression
+0x00 // reserved
+};
+
 // Allow Apple 68k Drive Setup to format this drive.
 // Code
 static const uint8 AppleVendorPage[] =
@@ -218,6 +234,17 @@ static void doModeSense(
 		density = 0x01; // User data only, 2048bytes per sector.
 		break;
 
+	case CONFIG_SEQUENTIAL:
+		mediumType = 0; // reserved
+		deviceSpecificParam =
+			(blockDev.state & DISK_WP) ? 0x80 : 0;
+		density = 0x13; // DAT Data Storage, X3B5/88-185A 
+		break;
+
+	case CONFIG_MO:
+		TODO
+		break;
+
 	};
 
 	scsiDev.data[idx++] = mediumType;
@@ -400,6 +427,18 @@ static void doModeSense(
 		idx += sizeof(ControlModePage);
 	}
 
+	if ((scsiDev.target->cfg->deviceType == CONFIG_SEQUENTIAL) &&
+		(pageCode == 0x10 || pageCode == 0x3F))
+	{
+		pageFound = 1;
+		pageIn(
+			pc,
+			idx,
+			SequentialDeviceConfigPage,
+			sizeof(SequentialDeviceConfigPage));
+		idx += sizeof(SequentialDeviceConfigPage);
+	}
+
 	if ((
 			(scsiDev.target->cfg->quirks == CONFIG_QUIRKS_APPLE) ||
 			(idx + sizeof(AppleVendorPage) <= allocLength)

+ 12 - 5
lib/SCSI2SD/software/SCSI2SD/src/scsi.c

@@ -264,6 +264,7 @@ static void process_Command()
 	control = scsiDev.cdb[scsiDev.cdbLen - 1];
 
 	scsiDev.cmdCount++;
+	TargetConfig* cfg = scsiDev.target->cfg;
 
 	if (unlikely(scsiDev.resetFlag))
 	{
@@ -273,7 +274,7 @@ static void process_Command()
 		return;
 	}
 	else if (scsiDev.parityError &&
-		(scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&
+		(cfg->flags & CONFIG_ENABLE_PARITY) &&
 		(scsiDev.compatMode >= COMPAT_SCSI2))
 	{
 		scsiDev.target->sense.code = ABORTED_COMMAND;
@@ -326,7 +327,7 @@ static void process_Command()
 	// on receiving the unit attention response on boot, thus
 	// triggering another unit attention condition.
 	else if (scsiDev.target->unitAttention &&
-		(scsiDev.target->cfg->flags & CONFIG_ENABLE_UNIT_ATTENTION))
+		(cfg->flags & CONFIG_ENABLE_UNIT_ATTENTION))
 	{
 		scsiDev.target->sense.code = UNIT_ATTENTION;
 		scsiDev.target->sense.asc = scsiDev.target->unitAttention;
@@ -352,6 +353,14 @@ static void process_Command()
 	{
 		enter_Status(CONFLICT);
 	}
+	// Handle odd device types first that may override basic read and
+	// write commands. Will fall-through to generic disk handling.
+	else if (((cfg->deviceType == CONFIG_OPTICAL) && scsiCDRomCommand()) ||
+		((cfg->deviceType == CONFIG_SEQUENTIAL) && scsiTapeCommand()) ||
+		((cfg->deviceType == CONFIG_MO) && scsiMOCommand()))
+	{
+		// Already handled.
+	}
 	else if (scsiDiskCommand())
 	{
 		// Already handled.
@@ -374,9 +383,7 @@ static void process_Command()
 	{
 		scsiReadBuffer();
 	}
-	else if (
-		!scsiCDRomCommand() &&
-		!scsiModeCommand())
+	else if (!scsiModeCommand())
 	{
 		scsiDev.target->sense.code = ILLEGAL_REQUEST;
 		scsiDev.target->sense.asc = INVALID_COMMAND_OPERATION_CODE;

+ 33 - 0
lib/SCSI2SD/software/SCSI2SD/src/tape.c

@@ -0,0 +1,33 @@
+//	Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
+//
+//	This file is part of SCSI2SD.
+//
+//	SCSI2SD is free software: you can redistribute it and/or modify
+//	it under the terms of the GNU General Public License as published by
+//	the Free Software Foundation, either version 3 of the License, or
+//	(at your option) any later version.
+//
+//	SCSI2SD is distributed in the hope that it will be useful,
+//	but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//	GNU General Public License for more details.
+//
+//	You should have received a copy of the GNU General Public License
+//	along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+#pragma GCC push_options
+#pragma GCC optimize("-flto")
+
+#include "device.h"
+#include "scsi.h"
+#include "config.h"
+#include "tape.h"
+
+// Handle sequential scsi device commands
+int scsiTapeCommand()
+{
+	// TODO handle tape-specific read/write commands and return 1
+
+	return 0;
+}
+
+#pragma GCC pop_options

+ 22 - 0
lib/SCSI2SD/software/SCSI2SD/src/tape.h

@@ -0,0 +1,22 @@
+//	Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
+//
+//	This file is part of SCSI2SD.
+//
+//	SCSI2SD is free software: you can redistribute it and/or modify
+//	it under the terms of the GNU General Public License as published by
+//	the Free Software Foundation, either version 3 of the License, or
+//	(at your option) any later version.
+//
+//	SCSI2SD is distributed in the hope that it will be useful,
+//	but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//	GNU General Public License for more details.
+//
+//	You should have received a copy of the GNU General Public License
+//	along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
+#ifndef TAPE_H
+#define TAPE_H
+
+int scsiTapeCommand(void);
+
+#endif

+ 4 - 1
lib/SCSI2SD/software/include/scsi2sd.h

@@ -93,7 +93,10 @@ typedef enum
 	CONFIG_FIXED,
 	CONFIG_REMOVEABLE,
 	CONFIG_OPTICAL,
-	CONFIG_FLOPPY_14MB
+	CONFIG_FLOPPY_14MB,
+	CONFIG_MO,
+	CONFIG_SEQUENTIAL
+
 } CONFIG_TYPE;
 
 typedef enum

+ 2 - 1
lib/SCSI2SD/software/scsi2sd-util/TargetPanel.cc

@@ -109,7 +109,8 @@ TargetPanel::TargetPanel(wxWindow* parent, const TargetConfig& initialConfig) :
 		wxT("Hard Drive"),
 		wxT("Removable"),
 		wxT("CDROM"),
-		wxT("3.5\" Floppy")
+		wxT("3.5\" Floppy"),
+		wxT("Magneto optical")
 	};
 	myDeviceTypeCtrl =
 		new wxChoice(