summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/nscsi/s1410.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/nscsi/s1410.cpp')
-rw-r--r--src/devices/bus/nscsi/s1410.cpp70
1 files changed, 62 insertions, 8 deletions
diff --git a/src/devices/bus/nscsi/s1410.cpp b/src/devices/bus/nscsi/s1410.cpp
index 4667ce04b98..52358d7e851 100644
--- a/src/devices/bus/nscsi/s1410.cpp
+++ b/src/devices/bus/nscsi/s1410.cpp
@@ -3,7 +3,8 @@
#include "emu.h"
#include "bus/nscsi/s1410.h"
-#define LOG_GENERAL (1U << 0)
+#include "multibyte.h"
+
#define LOG_COMMAND (1U << 1)
#define LOG_DATA (1U << 2)
@@ -33,22 +34,50 @@ void nscsi_s1410_device::device_reset()
params[7] = 11;
}
+bool nscsi_s1410_device::scsi_command_done(uint8_t command, uint8_t length)
+{
+ if(!length)
+ return false;
+ switch(command >> 5) {
+ case 0: return length == 6;
+ case 1: return true;
+ case 2: return true;
+ case 3: return true;
+ case 4: return true;
+ case 5: return true;
+ case 6: return true;
+ case 7: return length == 6;
+ }
+ return true;
+}
+
void nscsi_s1410_device::scsi_command()
{
+ memset(scsi_sense_buffer, 0, sizeof(scsi_sense_buffer));
+
switch(scsi_cmdbuf[0]) {
case SC_TEST_UNIT_READY:
- case SC_REZERO:
+ case SC_REZERO_UNIT:
case SC_REASSIGN_BLOCKS:
case SC_READ:
case SC_WRITE:
- case SC_SEEK:
if (scsi_cmdbuf[1] >> 5) {
scsi_status_complete(SS_NOT_READY);
+ scsi_sense_buffer[0] = SK_DRIVE_NOT_READY;
} else {
nscsi_harddisk_device::scsi_command();
}
break;
+ case SC_SEEK:
+ if (scsi_cmdbuf[1] >> 5) {
+ scsi_status_complete(SS_NOT_READY);
+ scsi_sense_buffer[0] = SK_DRIVE_NOT_READY;
+ } else {
+ scsi_status_complete(SS_GOOD);
+ }
+ break;
+
case SC_REQUEST_SENSE:
scsi_data_in(SBUF_SENSE, 4);
scsi_status_complete(SS_GOOD);
@@ -57,12 +86,12 @@ void nscsi_s1410_device::scsi_command()
case SC_FORMAT_UNIT:
LOG("command FORMAT UNIT\n");
{
- const auto &info = harddisk->get_info();
+ const auto &info = image->get_info();
auto block = std::make_unique<uint8_t[]>(info.sectorbytes);
memset(&block[0], 0x6c, info.sectorbytes);
- lba = ((scsi_cmdbuf[1] & 0x1f)<<16) | (scsi_cmdbuf[2]<<8) | scsi_cmdbuf[3];
+ lba = get_u24be(&scsi_cmdbuf[1]) & 0x1fffff;
for(; lba < (info.cylinders * info.heads * info.sectors); lba++) {
- harddisk->write(lba, block.get());
+ image->write(lba, block.get());
}
}
scsi_status_complete(SS_GOOD);
@@ -71,19 +100,21 @@ void nscsi_s1410_device::scsi_command()
case SC_FORMAT_TRACK: {
if (scsi_cmdbuf[1] >> 5) {
scsi_status_complete(SS_NOT_READY);
+ scsi_sense_buffer[0] = SK_DRIVE_NOT_READY;
return;
}
- lba = ((scsi_cmdbuf[1] & 0x1f)<<16) | (scsi_cmdbuf[2]<<8) | scsi_cmdbuf[3];
+ lba = get_u24be(&scsi_cmdbuf[1]) & 0x1fffff;
blocks = (bytes_per_sector == 256) ? 32 : 17;
int track_length = blocks*bytes_per_sector;
auto block = std::make_unique<uint8_t[]>(track_length);
memset(&block[0], 0x6c, track_length);
- if(!harddisk->write(lba, &block[0])) {
+ if(!image->write(lba, &block[0])) {
logerror("%s: HD WRITE ERROR !\n", tag());
scsi_status_complete(SS_FORMAT_ERROR);
+ scsi_sense_buffer[0] = SK_FORMAT_ERROR;
} else {
scsi_status_complete(SS_GOOD);
}
@@ -93,6 +124,7 @@ void nscsi_s1410_device::scsi_command()
case SC_FORMAT_ALT_TRACK:
if (scsi_cmdbuf[1] >> 5) {
scsi_status_complete(SS_NOT_READY);
+ scsi_sense_buffer[0] = SK_DRIVE_NOT_READY;
return;
}
@@ -118,6 +150,7 @@ void nscsi_s1410_device::scsi_command()
case SC_CHECK_TRACK_FORMAT:
if (scsi_cmdbuf[1] >> 5) {
scsi_status_complete(SS_NOT_READY);
+ scsi_sense_buffer[0] = SK_DRIVE_NOT_READY;
return;
}
scsi_status_complete(SS_GOOD);
@@ -174,3 +207,24 @@ void nscsi_s1410_device::scsi_put_data(int id, int pos, uint8_t data)
return nscsi_harddisk_device::scsi_put_data(id, pos, data);
}
}
+
+// Byte transfer rate (5Mb/s)
+attotime nscsi_s1410_device::scsi_data_byte_period()
+{
+ return attotime::from_nsec(1600);
+}
+
+// Command execution delay
+attotime nscsi_s1410_device::scsi_data_command_delay()
+{
+ switch(scsi_cmdbuf[0]) {
+ case SC_READ:
+ case SC_WRITE:
+ case SC_SEEK:
+ // average seek time of NEC D5126A hard disk
+ return attotime::from_msec(85);
+
+ default:
+ return attotime::zero;
+ }
+}