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
{
scsiDev.data[1] |= 0x80; // Removable bit.\r
break;\r
\r
+ case CONFIG_SEQUENTIAL:\r
+ scsiDev.data[0] = 0x01; // device type\r
+ scsiDev.data[1] |= 0x80; // Removable bit.\r
+ break;\r
+ \r
+ case CONFIG_MO:\r
+ scsiDev.data[0] = 0x07; // device type\r
+ scsiDev.data[1] |= 0x80; // Removable bit.\r
+ break;\r
+\r
case CONFIG_FLOPPY_14MB:\r
case CONFIG_REMOVEABLE:\r
scsiDev.data[1] |= 0x80; // Removable bit.\r
--- /dev/null
+// 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
--- /dev/null
+// 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
0x00, 0x00 // AEN holdoff period.\r
};\r
\r
+static const uint8_t SequentialDeviceConfigPage[] =\r
+{\r
+0x10, // page code\r
+0x0E, // Page length\r
+0x00, // CAP, CAF, Active Format\r
+0x00, // Active partition\r
+0x00, // Write buffer full ratio\r
+0x00, // Read buffer empty ratio\r
+0x00,0x01, // Write delay time, in 100ms units\r
+0x00, // Default gap size\r
+0x10, // auto-generation of default eod (end of data)\r
+0x00,0x00,0x00 // buffer-size at early warning\r
+0x00, // No data compression\r
+0x00 // reserved\r
+};\r
+\r
// Allow Apple 68k Drive Setup to format this drive.\r
// Code\r
static const uint8 AppleVendorPage[] =\r
density = 0x01; // User data only, 2048bytes per sector.\r
break;\r
\r
+ case CONFIG_SEQUENTIAL:\r
+ mediumType = 0; // reserved\r
+ deviceSpecificParam =\r
+ (blockDev.state & DISK_WP) ? 0x80 : 0;\r
+ density = 0x13; // DAT Data Storage, X3B5/88-185A \r
+ break;\r
+\r
+ case CONFIG_MO:\r
+ TODO\r
+ break;\r
+\r
};\r
\r
scsiDev.data[idx++] = mediumType;\r
idx += sizeof(ControlModePage);\r
}\r
\r
+ if ((scsiDev.target->cfg->deviceType == CONFIG_SEQUENTIAL) &&\r
+ (pageCode == 0x10 || pageCode == 0x3F))\r
+ {\r
+ pageFound = 1;\r
+ pageIn(\r
+ pc,\r
+ idx,\r
+ SequentialDeviceConfigPage,\r
+ sizeof(SequentialDeviceConfigPage));\r
+ idx += sizeof(SequentialDeviceConfigPage);\r
+ }\r
+\r
if ((\r
(scsiDev.target->cfg->quirks == CONFIG_QUIRKS_APPLE) ||\r
(idx + sizeof(AppleVendorPage) <= allocLength)\r
control = scsiDev.cdb[scsiDev.cdbLen - 1];\r
\r
scsiDev.cmdCount++;\r
+ TargetConfig* cfg = scsiDev.target->cfg;\r
\r
if (unlikely(scsiDev.resetFlag))\r
{\r
return;\r
}\r
else if (scsiDev.parityError &&\r
- (scsiDev.target->cfg->flags & CONFIG_ENABLE_PARITY) &&\r
+ (cfg->flags & CONFIG_ENABLE_PARITY) &&\r
(scsiDev.compatMode >= COMPAT_SCSI2))\r
{\r
scsiDev.target->sense.code = ABORTED_COMMAND;\r
// on receiving the unit attention response on boot, thus\r
// triggering another unit attention condition.\r
else if (scsiDev.target->unitAttention &&\r
- (scsiDev.target->cfg->flags & CONFIG_ENABLE_UNIT_ATTENTION))\r
+ (cfg->flags & CONFIG_ENABLE_UNIT_ATTENTION))\r
{\r
scsiDev.target->sense.code = UNIT_ATTENTION;\r
scsiDev.target->sense.asc = scsiDev.target->unitAttention;\r
{\r
enter_Status(CONFLICT);\r
}\r
+ // Handle odd device types first that may override basic read and\r
+ // write commands. Will fall-through to generic disk handling.\r
+ else if (((cfg->deviceType == CONFIG_OPTICAL) && scsiCDRomCommand()) ||\r
+ ((cfg->deviceType == CONFIG_SEQUENTIAL) && scsiTapeCommand()) ||\r
+ ((cfg->deviceType == CONFIG_MO) && scsiMOCommand()))\r
+ {\r
+ // Already handled.\r
+ }\r
else if (scsiDiskCommand())\r
{\r
// Already handled.\r
{\r
scsiReadBuffer();\r
}\r
- else if (\r
- !scsiCDRomCommand() &&\r
- !scsiModeCommand())\r
+ else if (!scsiModeCommand())\r
{\r
scsiDev.target->sense.code = ILLEGAL_REQUEST;\r
scsiDev.target->sense.asc = INVALID_COMMAND_OPERATION_CODE;\r
--- /dev/null
+// 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
--- /dev/null
+// 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
CONFIG_FIXED,
CONFIG_REMOVEABLE,
CONFIG_OPTICAL,
- CONFIG_FLOPPY_14MB
+ CONFIG_FLOPPY_14MB,
+ CONFIG_MO,
+ CONFIG_SEQUENTIAL
+
} CONFIG_TYPE;
typedef enum
wxT("Hard Drive"),
wxT("Removable"),
wxT("CDROM"),
- wxT("3.5\" Floppy")
+ wxT("3.5\" Floppy"),
+ wxT("Magneto optical")
};
myDeviceTypeCtrl =
new wxChoice(