Skip to content

Commit b139468

Browse files
authored
Merge pull request #144 from mynameistroy/iomega_zip_support
Implement Iomega ZIP100 support
2 parents c7486e4 + b497517 commit b139468

File tree

9 files changed

+141
-5
lines changed

9 files changed

+141
-5
lines changed

lib/SCSI2SD/include/scsi2sd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ typedef enum
7575
S2S_CFG_MO,
7676
S2S_CFG_SEQUENTIAL,
7777
S2S_CFG_NETWORK,
78+
S2S_CFG_ZIP100,
7879
} S2S_CFG_TYPE;
7980

8081
typedef enum

lib/SCSI2SD/src/firmware/mode.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,20 @@ static const uint8_t BlueSCSIVendorPage[] =
254254
'S','T','O','L','E','N',' ','F','R','O','M',' ','B','L','U','E','S','C','S','I',0x00
255255
};
256256

257+
static const uint8_t IomegaZip100VendorPage[] =
258+
{
259+
0x2f, // Page Code
260+
4, // Page Length
261+
0x5c, 0xf, 0xff, 0xf
262+
};
263+
264+
static const uint8_t IomegaZip250VendorPage[] =
265+
{
266+
0x2f, // Page Code
267+
4, // Page Length
268+
0x5c, 0xf, 0x3c, 0xf
269+
};
270+
257271
static void pageIn(int pc, int dataIdx, const uint8_t* pageData, int pageLen)
258272
{
259273
memcpy(&scsiDev.data[dataIdx], pageData, pageLen);
@@ -510,6 +524,14 @@ static void doModeSense(
510524
idx += modeSenseCDDevicePage(pc, idx, pageCode, &pageFound);
511525
idx += modeSenseCDAudioControlPage(pc, idx, pageCode, &pageFound);
512526

527+
if ((scsiDev.target->cfg->deviceType == S2S_CFG_ZIP100) &&
528+
(pageCode == 0x2f || pageCode == 0x3f))
529+
{
530+
pageFound = 1;
531+
pageIn(pc, idx, IomegaZip100VendorPage, sizeof(IomegaZip100VendorPage));
532+
idx += sizeof(IomegaZip100VendorPage);
533+
}
534+
513535
if ((scsiDev.target->cfg->deviceType == S2S_CFG_SEQUENTIAL) &&
514536
(pageCode == 0x10 || pageCode == 0x3F))
515537
{

lib/SCSI2SD/src/firmware/scsi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "geometry.h"
2121
#include "sense.h"
22+
#include "vendor.h"
2223

2324
#include <stdint.h>
2425

lib/SCSI2SD/src/firmware/vendor.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "vendor.h"
2020
#include "diagnostic.h"
2121

22+
#include <string.h>
23+
2224
// Callback after the DATA OUT phase is complete.
2325
static void doAssignDiskParameters(void)
2426
{
@@ -45,8 +47,83 @@ int scsiVendorCommand()
4547
int commandHandled = 1;
4648

4749
uint8_t command = scsiDev.cdb[0];
50+
uint8_t alloc_length = scsiDev.cdb[4];
51+
52+
// iomega sense command
53+
if (command == 0x06 && scsiDev.target->cfg->deviceType == S2S_CFG_ZIP100)
54+
{
55+
int subcommand = scsiDev.cdb[2];
56+
scsiDev.phase = DATA_IN;
57+
58+
// byte 0 is the page
59+
scsiDev.data[0] = subcommand;
60+
61+
if (subcommand == 0x1)
62+
{
63+
// page is 86 bytes in length
64+
scsiDev.dataLen = alloc_length < 0x58 ? alloc_length : 0x58;
65+
memset(&scsiDev.data[1], 0xff, scsiDev.dataLen);
66+
// byte 1 is the page length minus pagecode and length
67+
scsiDev.data[1] = scsiDev.dataLen - 2;
68+
69+
scsiDev.data[2] = 1;
70+
scsiDev.data[3] = 0;
71+
scsiDev.data[4] = 0;
72+
scsiDev.data[5] = 0;
73+
scsiDev.data[6] = 0x5;
74+
scsiDev.data[7] = 0xdc;
75+
scsiDev.data[8] = 0x6;
76+
scsiDev.data[9] = 0xc;
77+
scsiDev.data[10] = 0x5;
78+
scsiDev.data[11] = 0xdc;
79+
scsiDev.data[12] = 0x6;
80+
scsiDev.data[13] = 0xc;
81+
scsiDev.data[14] = 0;
82+
}
83+
else if (subcommand == 0x2) {
84+
// page is 61 bytes in length
85+
scsiDev.dataLen = alloc_length < 0x3f ? alloc_length : 0x3f;
86+
memset(&scsiDev.data[1], 0, scsiDev.dataLen);
87+
// byte 1 is the page length minus pagecode and length
88+
scsiDev.data[1] = scsiDev.dataLen - 2;
89+
90+
scsiDev.data[3] = 2;
91+
scsiDev.data[6] = 0x2;
92+
scsiDev.data[7] = 0xff;
93+
scsiDev.data[8] = 0xff;
94+
scsiDev.data[11] = 0x2;
4895

49-
if (command == 0xC0)
96+
// this has something to do with the format/disk life
97+
// currently this makes it 100%
98+
scsiDev.data[14] = 0x7e;
99+
scsiDev.data[18] = 0x7e;
100+
101+
// byte 21 is the read/write/password settings
102+
// 5 = password for R/W
103+
// 3 = password for W
104+
// 2 = RO
105+
// 0 = RW
106+
scsiDev.data[20] = 0;
107+
108+
// set a serial number ABCDEFGHIJKLMNO
109+
// starts at byte 25 and is 15 bytes long
110+
for(int i = 0; i < 20; i++) {
111+
scsiDev.data[25 + i] = i + 0x41;
112+
}
113+
114+
scsiDev.data[0x3e] = 1;
115+
}
116+
else
117+
{
118+
// anything else is an illegal command
119+
scsiDev.status = CHECK_CONDITION;
120+
scsiDev.target->sense.code = ILLEGAL_REQUEST;
121+
scsiDev.target->sense.asc = LOGICAL_UNIT_NOT_SUPPORTED;
122+
scsiDev.phase = STATUS;
123+
}
124+
125+
}
126+
else if (command == 0xC0)
50127
{
51128
// Define flexible disk format
52129
// OMTI-5204 controller

lib/SCSI2SD/src/firmware/vendor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#ifndef S2S_VENDOR_H
1818
#define S2S_VENDOR_H
1919

20+
#define ZIP100_DISC_SIZE 100663296 // bytes
21+
#define ZIP250_DISC_SIZE 250640384 // bytes
22+
2023
int scsiVendorCommand(void);
2124

2225
#endif

src/BlueSCSI.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,14 +284,15 @@ bool findHDDImages()
284284
bool is_ne = (tolower(name[0]) == 'n' && tolower(name[1]) == 'e');
285285
bool is_re = (tolower(name[0]) == 'r' && tolower(name[1]) == 'e');
286286
bool is_tp = (tolower(name[0]) == 't' && tolower(name[1]) == 'p');
287+
bool is_zp = (tolower(name[0]) == 'z' && tolower(name[1]) == 'p');
287288

288289
if(strcasecmp(name, "CLEAR_ROM") == 0)
289290
{
290291
romDriveClear();
291292
continue;
292293
}
293294

294-
if (is_hd || is_cd || is_fd || is_mo || is_ne || is_re || is_tp)
295+
if (is_hd || is_cd || is_fd || is_mo || is_ne || is_re || is_tp || is_zp)
295296
{
296297
// Check if the image should be loaded to microcontroller flash ROM drive
297298
bool is_romdrive = false;
@@ -371,6 +372,7 @@ bool findHDDImages()
371372
if (is_ne) type = S2S_CFG_NETWORK;
372373
if (is_re) type = S2S_CFG_REMOVEABLE;
373374
if (is_tp) type = S2S_CFG_SEQUENTIAL;
375+
if (is_zp) type = S2S_CFG_ZIP100;
374376

375377
// Open the image file
376378
if (id < NUM_SCSIID && is_romdrive)

src/BlueSCSI_config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@
6767
#define APPLE_DRIVEINFO_NETWORK {"Dayna", "SCSI/Link", "2.0f", ""}
6868
#define APPLE_DRIVEINFO_TAPE {"BlueSCSI", "APPLE_TAPE", "", ""}
6969

70+
// Default Iomega ZIP drive information
71+
#define IOMEGA_DRIVEINFO_ZIP100 {"IOMEGA", "ZIP 100", "E.08", ""}
72+
#define IOMEGA_DRIVEINFO_ZIP250 {"IOMEGA", "ZIP 250", "42.S", ""}
73+
#define IOMEGA_DRIVEINFO_JAZ {"iomega", "jaz", "", ""}
74+
7075
// Default delay for SCSI phases.
7176
// Can be adjusted in ini file
7277
#define DEFAULT_SCSI_DELAY_US 10

src/BlueSCSI_disk.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ static void setDefaultDriveInfo(int target_idx)
273273
static const char *apl_driveinfo_network[4] = APPLE_DRIVEINFO_NETWORK;
274274
static const char *apl_driveinfo_tape[4] = APPLE_DRIVEINFO_TAPE;
275275

276+
static const char *iomega_driveinfo_removeable[4] = IOMEGA_DRIVEINFO_ZIP100;
277+
276278
const char **driveinfo = NULL;
277279

278280
if (img.quirks == S2S_CFG_QUIRKS_APPLE)
@@ -302,6 +304,7 @@ static void setDefaultDriveInfo(int target_idx)
302304
case S2S_CFG_MO: driveinfo = driveinfo_magopt; break;
303305
case S2S_CFG_NETWORK: driveinfo = driveinfo_network; break;
304306
case S2S_CFG_SEQUENTIAL: driveinfo = driveinfo_tape; break;
307+
case S2S_CFG_ZIP100: driveinfo = iomega_driveinfo_removeable; break;
305308
default: driveinfo = driveinfo_fixed; break;
306309
}
307310
}
@@ -429,6 +432,18 @@ bool scsiDiskOpenHDDImage(int target_idx, const char *filename, int scsi_id, int
429432
log("---- Configuring as tape drive based on image name");
430433
img.deviceType = S2S_CFG_SEQUENTIAL;
431434
}
435+
else if (type == S2S_CFG_ZIP100)
436+
{
437+
log("---- Configuration as Iomega ZIP100 drive based on image name");
438+
img.deviceType = S2S_CFG_ZIP100;
439+
if(img.file.size() != ZIP100_DISC_SIZE)
440+
{
441+
log("---- ZIP100 disc (", (int)img.file.size(), " bytes) is not exactly ", ZIP100_DISC_SIZE, " bytes, drive is ignored");
442+
img.file.close();
443+
img.clear();
444+
return false;
445+
}
446+
}
432447

433448
if (img.prefetchbytes != PREFETCH_BUFFER_SIZE)
434449
{
@@ -1864,13 +1879,22 @@ int scsiDiskCommand()
18641879
//int immed = scsiDev.cdb[1] & 1;
18651880
int start = scsiDev.cdb[4] & 1;
18661881

1867-
if (start)
1882+
if (scsiDev.target->cfg->deviceType == S2S_CFG_ZIP100)
18681883
{
1869-
scsiDev.target->started = 1;
1884+
// If it's a ZIP drive, it likes to eject all the time so this
1885+
// little dance helps keep a disc loaded
1886+
if (start)
1887+
{
1888+
scsiDev.target->started = 1;
1889+
}
1890+
else
1891+
{
1892+
scsiDev.target->started = 0;
1893+
}
18701894
}
18711895
else
18721896
{
1873-
scsiDev.target->started = 0;
1897+
scsiDev.target->started = 1;
18741898
}
18751899
}
18761900
else if (unlikely(command == 0x00))

src/BlueSCSI_log_trace.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static const char *getCommandName(uint8_t cmd)
2828
case 0x03: return "RequestSense";
2929
case 0x04: return "FormatUnit";
3030
case 0x05: return "ReadBlockLimits";
31+
case 0x06: return "IomegaVendorCommand";
3132
case 0x08: return "Read6";
3233
case 0x0A: return "Write6";
3334
case 0x0B: return "Seek6";

0 commit comments

Comments
 (0)