diff options
Diffstat (limited to 'src/devices/bus/nscsi/hd.cpp')
-rw-r--r-- | src/devices/bus/nscsi/hd.cpp | 163 |
1 files changed, 79 insertions, 84 deletions
diff --git a/src/devices/bus/nscsi/hd.cpp b/src/devices/bus/nscsi/hd.cpp index f4c74962d20..8e210e22d10 100644 --- a/src/devices/bus/nscsi/hd.cpp +++ b/src/devices/bus/nscsi/hd.cpp @@ -4,9 +4,11 @@ #include "bus/nscsi/hd.h" #include "imagedev/harddriv.h" -#define LOG_GENERAL (1U << 0) -#define LOG_COMMAND (1U << 1) -#define LOG_DATA (1U << 2) +#include "multibyte.h" + +#define LOG_COMMAND (1U << 1) +#define LOG_DATA (1U << 2) +#define LOG_UNSUPPORTED (1U << 3) #define VERBOSE 0 @@ -20,7 +22,7 @@ nscsi_harddisk_device::nscsi_harddisk_device(const machine_config &mconfig, cons } nscsi_harddisk_device::nscsi_harddisk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - nscsi_full_device(mconfig, type, tag, owner, clock), image(*this, "image"), harddisk(nullptr), lba(0), cur_lba(0), blocks(0), bytes_per_sector(0) + nscsi_full_device(mconfig, type, tag, owner, clock), image(*this, "image"), lba(0), cur_lba(0), blocks(0), bytes_per_sector(0) { } @@ -37,24 +39,20 @@ void nscsi_harddisk_device::device_start() void nscsi_harddisk_device::device_reset() { nscsi_full_device::device_reset(); - harddisk = image->get_hard_disk_file(); - if(!harddisk) { + if(!image->exists()) { scsi_id = -1; bytes_per_sector = 0; } else { - const hard_disk_info *hdinfo = hard_disk_get_info(harddisk); - bytes_per_sector = hdinfo->sectorbytes; - - chd_file *chd = image->get_chd_file(); - if(chd != nullptr) - chd->read_metadata(HARD_DISK_IDENT_METADATA_TAG, 0, m_inquiry_data); + const auto &hdinfo = image->get_info(); + bytes_per_sector = hdinfo.sectorbytes; + image->get_inquiry_data(m_inquiry_data); } cur_lba = -1; } void nscsi_harddisk_device::device_add_mconfig(machine_config &config) { - HARDDISK(config, image).set_interface("scsi_hdd"); + HARDDISK(config, image).set_interface("scsi_hdd,hdd"); } uint8_t nscsi_harddisk_device::scsi_get_data(int id, int pos) @@ -69,7 +67,7 @@ uint8_t nscsi_harddisk_device::scsi_get_data(int id, int pos) int clba = lba + pos / bytes_per_sector; if(clba != cur_lba) { cur_lba = clba; - if(!hard_disk_read(harddisk, cur_lba, block)) { + if(!image->read(cur_lba, block)) { LOG("HD READ ERROR !\n"); memset(block, 0, sizeof(block)); } @@ -92,7 +90,7 @@ void nscsi_harddisk_device::scsi_put_data(int id, int pos, uint8_t data) block[offset] = data; cur_lba = lba + pos / bytes_per_sector; if(offset == bytes_per_sector-1) { - if(!hard_disk_write(harddisk, cur_lba, block)) + if(!image->write(cur_lba, block)) LOG("HD WRITE ERROR !\n"); } } @@ -112,14 +110,14 @@ void nscsi_harddisk_device::scsi_command() break; case SC_READ_6: - lba = ((scsi_cmdbuf[1] & 0x1f)<<16) | (scsi_cmdbuf[2]<<8) | scsi_cmdbuf[3]; + lba = get_u24be(&scsi_cmdbuf[1]) & 0x1fffff; blocks = scsi_cmdbuf[4]; if(!blocks) blocks = 256; LOG("command READ start=%08x blocks=%04x\n", lba, blocks); - if(hard_disk_read(harddisk, lba, block)) { + if(image->read(lba, block)) { scsi_data_in(2, blocks*bytes_per_sector); scsi_status_complete(SS_GOOD); } @@ -131,7 +129,7 @@ void nscsi_harddisk_device::scsi_command() break; case SC_WRITE_6: - lba = ((scsi_cmdbuf[1] & 0x1f)<<16) | (scsi_cmdbuf[2]<<8) | scsi_cmdbuf[3]; + lba = get_u24be(&scsi_cmdbuf[1]) & 0x1fffff; blocks = scsi_cmdbuf[4]; if(!blocks) blocks = 256; @@ -221,17 +219,15 @@ void nscsi_harddisk_device::scsi_command() scsi_cmdbuf[pos++] = 0x00; // medium type scsi_cmdbuf[pos++] = 0x00; // WP, cache - hard_disk_info *info = hard_disk_get_info(harddisk); - uint32_t dsize = info->cylinders * info->heads * info->sectors - 1; + const auto &info = image->get_info(); + uint32_t dsize = info.cylinders * info.heads * info.sectors - 1; scsi_cmdbuf[pos++] = 0x08; // Block descriptor length scsi_cmdbuf[pos++] = 0x00; - scsi_cmdbuf[pos++] = (dsize>>16) & 0xff; - scsi_cmdbuf[pos++] = (dsize>>8) & 0xff; - scsi_cmdbuf[pos++] = (dsize & 0xff); + put_u24be(&scsi_cmdbuf[pos], dsize); + pos += 3; scsi_cmdbuf[pos++] = 0x00; - scsi_cmdbuf[pos++] = (info->sectorbytes>>16)&0xff; - scsi_cmdbuf[pos++] = (info->sectorbytes>>8)&0xff; - scsi_cmdbuf[pos++] = (info->sectorbytes & 0xff); + put_u24be(&scsi_cmdbuf[pos], info.sectorbytes); + pos += 3; int pmax = page == 0x3f ? 0x3e : page; int pmin = page == 0x3f ? 0x00 : page; @@ -283,18 +279,18 @@ void nscsi_harddisk_device::scsi_command() case 0x03: { // Format parameters page scsi_cmdbuf[pos++] = 0x83; // PS, page id scsi_cmdbuf[pos++] = 0x16; // Page length - scsi_cmdbuf[pos++] = (info->cylinders * info->heads) >> 8; // Track/zone - scsi_cmdbuf[pos++] = info->cylinders * info->heads; // Track/zone + put_u16be(&scsi_cmdbuf[pos], info.cylinders * info.heads); // Track/zone + pos += 2; scsi_cmdbuf[pos++] = 0x00; // Alt sect/zone scsi_cmdbuf[pos++] = 0x00; // Alt sect/zone scsi_cmdbuf[pos++] = 0x00; // Alt track/zone scsi_cmdbuf[pos++] = 0x00; // Alt track/zone scsi_cmdbuf[pos++] = 0x00; // Alt track/volume scsi_cmdbuf[pos++] = 0x00; // Alt track/volume - scsi_cmdbuf[pos++] = info->sectors >> 8; // Sectors/track - scsi_cmdbuf[pos++] = info->sectors; // Sectors/track - scsi_cmdbuf[pos++] = info->sectorbytes >> 8; // Bytes/sector - scsi_cmdbuf[pos++] = info->sectorbytes; // Bytes/sector + put_u16be(&scsi_cmdbuf[pos], info.sectors); // Sectors/track + pos += 2; + put_u16be(&scsi_cmdbuf[pos], info.sectorbytes); // Bytes/sector + pos += 2; scsi_cmdbuf[pos++] = 0x00; // Interleave scsi_cmdbuf[pos++] = 0x00; // Interleave scsi_cmdbuf[pos++] = 0x00; // Track skew @@ -311,28 +307,27 @@ void nscsi_harddisk_device::scsi_command() case 0x04: { // Rigid drive geometry page scsi_cmdbuf[pos++] = 0x84; // PS, page id scsi_cmdbuf[pos++] = 0x16; // Page length - scsi_cmdbuf[pos++] = info->cylinders >> 16; // Cylinders - scsi_cmdbuf[pos++] = info->cylinders >> 8; // Cylinders - scsi_cmdbuf[pos++] = info->cylinders; // Cylinders - scsi_cmdbuf[pos++] = info->heads; // Heads - scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - write precomp - scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - write precomp - scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - write precomp - scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - reduced write current - scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - reduced write current - scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - reduced write current - scsi_cmdbuf[pos++] = 0x00; // Drive step rate - scsi_cmdbuf[pos++] = 0x00; // Drive step rate - scsi_cmdbuf[pos++] = 0x00; // Landing zone cylinder - scsi_cmdbuf[pos++] = 0x00; // Landing zone cylinder - scsi_cmdbuf[pos++] = 0x00; // Landing zone cylinder - scsi_cmdbuf[pos++] = 0x00; // RPL - scsi_cmdbuf[pos++] = 0x00; // Rotational offset - scsi_cmdbuf[pos++] = 0x00; // Reserved - scsi_cmdbuf[pos++] = uint8_t(10000 >> 8); // Medium rotation rate - scsi_cmdbuf[pos++] = uint8_t(10000); // Medium rotation rate - scsi_cmdbuf[pos++] = 0x00; // Reserved - scsi_cmdbuf[pos++] = 0x00; // Reserved + put_u24be(&scsi_cmdbuf[pos], info.cylinders); // Cylinders + pos += 3; + scsi_cmdbuf[pos++] = info.heads; // Heads + scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - write precomp + scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - write precomp + scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - write precomp + scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - reduced write current + scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - reduced write current + scsi_cmdbuf[pos++] = 0x00; // Starting cylinder - reduced write current + scsi_cmdbuf[pos++] = 0x00; // Drive step rate + scsi_cmdbuf[pos++] = 0x00; // Drive step rate + scsi_cmdbuf[pos++] = 0x00; // Landing zone cylinder + scsi_cmdbuf[pos++] = 0x00; // Landing zone cylinder + scsi_cmdbuf[pos++] = 0x00; // Landing zone cylinder + scsi_cmdbuf[pos++] = 0x00; // RPL + scsi_cmdbuf[pos++] = 0x00; // Rotational offset + scsi_cmdbuf[pos++] = 0x00; // Reserved + put_u16be(&scsi_cmdbuf[pos], 10000); // Medium rotation rate + pos += 2; + scsi_cmdbuf[pos++] = 0x00; // Reserved + scsi_cmdbuf[pos++] = 0x00; // Reserved break; } @@ -407,9 +402,9 @@ void nscsi_harddisk_device::scsi_command() scsi_status_complete(SS_GOOD); break; - case SC_RECIEVE_DIAG_RES: { - LOG("command RECIEVE DIAGNOSTICS RESULTS\n"); - int size = (scsi_cmdbuf[3] << 8) | scsi_cmdbuf[4]; + case SC_RECEIVE_DIAGNOSTIC_RESULTS: { + LOG("command RECEIVE DIAGNOSTIC RESULTS\n"); + int size = get_u16be(&scsi_cmdbuf[3]); int pos = 0; scsi_cmdbuf[pos++] = 0; scsi_cmdbuf[pos++] = 6; @@ -425,9 +420,9 @@ void nscsi_harddisk_device::scsi_command() break; } - case SC_SEND_DIAGNOSTICS: { - LOG("command SEND DIAGNOSTICS\n"); - int size = (scsi_cmdbuf[3] << 8) | scsi_cmdbuf[4]; + case SC_SEND_DIAGNOSTIC: { + LOG("command SEND DIAGNOSTIC\n"); + int size = get_u16be(&scsi_cmdbuf[3]); if(scsi_cmdbuf[1] & 4) { // Self-test scsi_status_complete(SS_GOOD); @@ -452,17 +447,11 @@ void nscsi_harddisk_device::scsi_command() case SC_READ_CAPACITY: { LOG("command READ CAPACITY\n"); - hard_disk_info *info = hard_disk_get_info(harddisk); - uint32_t size = info->cylinders * info->heads * info->sectors - 1; + const auto &info = image->get_info(); + uint32_t size = info.cylinders * info.heads * info.sectors - 1; - scsi_cmdbuf[0] = (size>>24) & 0xff; - scsi_cmdbuf[1] = (size>>16) & 0xff; - scsi_cmdbuf[2] = (size>>8) & 0xff; - scsi_cmdbuf[3] = (size & 0xff); - scsi_cmdbuf[4] = (info->sectorbytes>>24)&0xff; - scsi_cmdbuf[5] = (info->sectorbytes>>16)&0xff; - scsi_cmdbuf[6] = (info->sectorbytes>>8)&0xff; - scsi_cmdbuf[7] = (info->sectorbytes & 0xff); + put_u32be(&scsi_cmdbuf[0], size); + put_u32be(&scsi_cmdbuf[4], info.sectorbytes); scsi_data_in(0, 8); scsi_status_complete(SS_GOOD); @@ -470,12 +459,12 @@ void nscsi_harddisk_device::scsi_command() } case SC_READ_10: - lba = (scsi_cmdbuf[2]<<24) | (scsi_cmdbuf[3]<<16) | (scsi_cmdbuf[4]<<8) | scsi_cmdbuf[5]; - blocks = (scsi_cmdbuf[7] << 8) | scsi_cmdbuf[8]; + lba = get_u32be(&scsi_cmdbuf[2]); + blocks = get_u16be(&scsi_cmdbuf[7]); LOG("command READ EXTENDED start=%08x blocks=%04x\n",lba, blocks); - if(hard_disk_read(harddisk, lba, block)) { + if(image->read(lba, block)) { scsi_data_in(2, blocks*bytes_per_sector); scsi_status_complete(SS_GOOD); } @@ -487,8 +476,8 @@ void nscsi_harddisk_device::scsi_command() break; case SC_WRITE_10: - lba = (scsi_cmdbuf[2]<<24) | (scsi_cmdbuf[3]<<16) | (scsi_cmdbuf[4]<<8) | scsi_cmdbuf[5]; - blocks = (scsi_cmdbuf[7] << 8) | scsi_cmdbuf[8]; + lba = get_u32be(&scsi_cmdbuf[2]); + blocks = get_u16be(&scsi_cmdbuf[7]); LOG("command WRITE EXTENDED start=%08x blocks=%04x\n", lba, blocks); @@ -504,12 +493,12 @@ void nscsi_harddisk_device::scsi_command() (scsi_cmdbuf[1] & 0x10) ? " FMTDATA" : "", (scsi_cmdbuf[1] & 0x08) ? " CMPLIST" : ""); { - hard_disk_info *info = hard_disk_get_info(harddisk); - auto block = std::make_unique<uint8_t[]>(info->sectorbytes); - for(int cyl = 0; cyl < info->cylinders; cyl++) { - for(int head = 0; head < info->heads; head++) { - for(int sector = 0; sector < info->sectors; sector++) { - hard_disk_write(harddisk, cyl * head * sector, block.get()); + const auto &info = image->get_info(); + auto block = std::make_unique<uint8_t[]>(info.sectorbytes); + for(int cyl = 0; cyl < info.cylinders; cyl++) { + for(int head = 0; head < info.heads; head++) { + for(int sector = 0; sector < info.sectors; sector++) { + image->write(cyl * head * sector, block.get()); } } } @@ -518,11 +507,16 @@ void nscsi_harddisk_device::scsi_command() break; case SC_MODE_SELECT_6: - LOG("command MODE SELECT\n"); + LOG("command MODE SELECT 6 length %d\n", scsi_cmdbuf[4]); + + // accept mode select parameter data + if(scsi_cmdbuf[4]) + scsi_data_out(2, scsi_cmdbuf[4]); + scsi_status_complete(SS_GOOD); break; - case SC_VERIFY: + case SC_VERIFY_10: LOG("command VERIFY BytChk %d\n", !!(scsi_cmdbuf[1] & 0x02)); if (!(scsi_cmdbuf[1] & 0x02)) scsi_status_complete(SS_GOOD); @@ -531,7 +525,8 @@ void nscsi_harddisk_device::scsi_command() break; default: - LOG("command %02x ***UNKNOWN***\n", scsi_cmdbuf[0]); + LOGMASKED(LOG_UNSUPPORTED, "command %02x ***UNKNOWN***\n", scsi_cmdbuf[0]); + // Parent may handle this nscsi_full_device::scsi_command(); break; } |