From: Michael McMaster Date: Sun, 6 Sep 2015 05:15:41 +0000 (+1000) Subject: Initial tape and magneto-optical support X-Git-Tag: v4.05.00~12 X-Git-Url: http://git.codesrc.com/gitweb.cgi?a=commitdiff_plain;h=6a7207c0922e6297ce9bda8fce008c8060eac63f;p=SCSI2SD.git Initial tape and magneto-optical support --- diff --git a/software/SCSI2SD/src/cdrom.c b/software/SCSI2SD/src/cdrom.c index 18ed321..1c9305f 100755 --- a/software/SCSI2SD/src/cdrom.c +++ b/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 { diff --git a/software/SCSI2SD/src/inquiry.c b/software/SCSI2SD/src/inquiry.c index cf9bab7..1a88f5c 100755 --- a/software/SCSI2SD/src/inquiry.c +++ b/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. diff --git a/software/SCSI2SD/src/mo.c b/software/SCSI2SD/src/mo.c new file mode 100644 index 0000000..e13acc5 --- /dev/null +++ b/software/SCSI2SD/src/mo.c @@ -0,0 +1,43 @@ +// Copyright (C) 2015 Michael McMaster +// +// 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 . +#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 diff --git a/software/SCSI2SD/src/mo.h b/software/SCSI2SD/src/mo.h new file mode 100644 index 0000000..fe996d2 --- /dev/null +++ b/software/SCSI2SD/src/mo.h @@ -0,0 +1,22 @@ +// Copyright (C) 2015 Michael McMaster +// +// 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 . +#ifndef MO_H +#define MO_H + +int scsiMOCommand(void); + +#endif diff --git a/software/SCSI2SD/src/mode.c b/software/SCSI2SD/src/mode.c index 2eb3c50..b7bd9c0 100755 --- a/software/SCSI2SD/src/mode.c +++ b/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) diff --git a/software/SCSI2SD/src/scsi.c b/software/SCSI2SD/src/scsi.c index d8f5d7c..48b4c6d 100755 --- a/software/SCSI2SD/src/scsi.c +++ b/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; diff --git a/software/SCSI2SD/src/tape.c b/software/SCSI2SD/src/tape.c new file mode 100644 index 0000000..9416a95 --- /dev/null +++ b/software/SCSI2SD/src/tape.c @@ -0,0 +1,33 @@ +// Copyright (C) 2015 Michael McMaster +// +// 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 . +#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 diff --git a/software/SCSI2SD/src/tape.h b/software/SCSI2SD/src/tape.h new file mode 100644 index 0000000..1249731 --- /dev/null +++ b/software/SCSI2SD/src/tape.h @@ -0,0 +1,22 @@ +// Copyright (C) 2015 Michael McMaster +// +// 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 . +#ifndef TAPE_H +#define TAPE_H + +int scsiTapeCommand(void); + +#endif diff --git a/software/include/scsi2sd.h b/software/include/scsi2sd.h index 22202cf..71d50f6 100755 --- a/software/include/scsi2sd.h +++ b/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 diff --git a/software/scsi2sd-util/TargetPanel.cc b/software/scsi2sd-util/TargetPanel.cc index ecbdf51..afd9480 100644 --- a/software/scsi2sd-util/TargetPanel.cc +++ b/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(