mirror of
https://github.com/holub/mame
synced 2025-07-03 17:08:39 +03:00
Merge pull request #3780 from pmackinlay/nscsi
nscsi_cd: support media changes (nw)
This commit is contained in:
commit
315fe9ef97
@ -2,7 +2,6 @@
|
|||||||
// copyright-holders:Olivier Galibert
|
// copyright-holders:Olivier Galibert
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "machine/nscsi_cd.h"
|
#include "machine/nscsi_cd.h"
|
||||||
#include "imagedev/chd_cd.h"
|
|
||||||
|
|
||||||
#define VERBOSE 1
|
#define VERBOSE 1
|
||||||
#include "logmacro.h"
|
#include "logmacro.h"
|
||||||
@ -10,7 +9,7 @@
|
|||||||
DEFINE_DEVICE_TYPE(NSCSI_CDROM, nscsi_cdrom_device, "scsi_cdrom", "SCSI CD-ROM")
|
DEFINE_DEVICE_TYPE(NSCSI_CDROM, nscsi_cdrom_device, "scsi_cdrom", "SCSI CD-ROM")
|
||||||
|
|
||||||
nscsi_cdrom_device::nscsi_cdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
nscsi_cdrom_device::nscsi_cdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
nscsi_full_device(mconfig, NSCSI_CDROM, tag, owner, clock), cdrom(nullptr), bytes_per_block(bytes_per_sector), lba(0), cur_sector(0)
|
nscsi_full_device(mconfig, NSCSI_CDROM, tag, owner, clock), cdrom(nullptr), bytes_per_block(bytes_per_sector), lba(0), cur_sector(0), image(*this, "image")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ void nscsi_cdrom_device::device_start()
|
|||||||
void nscsi_cdrom_device::device_reset()
|
void nscsi_cdrom_device::device_reset()
|
||||||
{
|
{
|
||||||
nscsi_full_device::device_reset();
|
nscsi_full_device::device_reset();
|
||||||
cdrom = subdevice<cdrom_image_device>("image")->get_cdrom_file();
|
cdrom = image->get_cdrom_file();
|
||||||
lba = 0;
|
lba = 0;
|
||||||
cur_sector = -1;
|
cur_sector = -1;
|
||||||
}
|
}
|
||||||
@ -49,7 +48,7 @@ uint8_t nscsi_cdrom_device::scsi_get_data(int id, int pos)
|
|||||||
{
|
{
|
||||||
if(id != 2)
|
if(id != 2)
|
||||||
return nscsi_full_device::scsi_get_data(id, pos);
|
return nscsi_full_device::scsi_get_data(id, pos);
|
||||||
int sector = (lba * bytes_per_block + pos) / bytes_per_sector;
|
const int sector = (lba * bytes_per_block + pos) / bytes_per_sector;
|
||||||
if(sector != cur_sector) {
|
if(sector != cur_sector) {
|
||||||
cur_sector = sector;
|
cur_sector = sector;
|
||||||
if(!cdrom_read_data(cdrom, sector, sector_buffer, CD_TRACK_MODE1)) {
|
if(!cdrom_read_data(cdrom, sector, sector_buffer, CD_TRACK_MODE1)) {
|
||||||
@ -70,6 +69,19 @@ void nscsi_cdrom_device::scsi_command()
|
|||||||
{
|
{
|
||||||
int blocks;
|
int blocks;
|
||||||
|
|
||||||
|
// check for media change
|
||||||
|
if((cdrom != image->get_cdrom_file()) && (scsi_cmdbuf[0] != SC_INQUIRY))
|
||||||
|
{
|
||||||
|
// clear media change condition
|
||||||
|
cdrom = image->get_cdrom_file();
|
||||||
|
cur_sector = -1;
|
||||||
|
|
||||||
|
// report unit attention condition
|
||||||
|
sense(false, 6);
|
||||||
|
scsi_status_complete(SS_CHECK_CONDITION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch(scsi_cmdbuf[0]) {
|
switch(scsi_cmdbuf[0]) {
|
||||||
case SC_TEST_UNIT_READY:
|
case SC_TEST_UNIT_READY:
|
||||||
LOG("command TEST UNIT READY\n");
|
LOG("command TEST UNIT READY\n");
|
||||||
@ -109,7 +121,7 @@ void nscsi_cdrom_device::scsi_command()
|
|||||||
int size = scsi_cmdbuf[4];
|
int size = scsi_cmdbuf[4];
|
||||||
switch(page) {
|
switch(page) {
|
||||||
case 0:
|
case 0:
|
||||||
std::fill_n(scsi_cmdbuf, 148, 0);
|
std::fill_n(scsi_cmdbuf, 36, 0);
|
||||||
|
|
||||||
// vendor and product information must be padded with spaces
|
// vendor and product information must be padded with spaces
|
||||||
std::fill_n(&scsi_cmdbuf[8], 28, 0x20);
|
std::fill_n(&scsi_cmdbuf[8], 28, 0x20);
|
||||||
@ -118,13 +130,14 @@ void nscsi_cdrom_device::scsi_command()
|
|||||||
scsi_cmdbuf[1] = 0x80; // media is removable
|
scsi_cmdbuf[1] = 0x80; // media is removable
|
||||||
scsi_cmdbuf[2] = 0x05; // device complies with SPC-3 standard
|
scsi_cmdbuf[2] = 0x05; // device complies with SPC-3 standard
|
||||||
scsi_cmdbuf[3] = 0x02; // response data format = SPC-3 standard
|
scsi_cmdbuf[3] = 0x02; // response data format = SPC-3 standard
|
||||||
|
scsi_cmdbuf[4] = 32; // additional length
|
||||||
// some Konami games freak out if this isn't "Sony", so we'll lie
|
// some Konami games freak out if this isn't "Sony", so we'll lie
|
||||||
// this is the actual drive on my Nagano '98 board
|
// this is the actual drive on my Nagano '98 board
|
||||||
strncpy((char *)&scsi_cmdbuf[8], "Sony", 4);
|
strncpy((char *)&scsi_cmdbuf[8], "Sony", 4);
|
||||||
strncpy((char *)&scsi_cmdbuf[16], "CDU-76S", 7);
|
strncpy((char *)&scsi_cmdbuf[16], "CDU-76S", 7);
|
||||||
strncpy((char *)&scsi_cmdbuf[32], "1.0", 3);
|
strncpy((char *)&scsi_cmdbuf[32], "1.0", 3);
|
||||||
if(size > 148)
|
if(size > 36)
|
||||||
size = 148;
|
size = 36;
|
||||||
scsi_data_in(SBUF_MAIN, size);
|
scsi_data_in(SBUF_MAIN, size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -133,7 +146,8 @@ void nscsi_cdrom_device::scsi_command()
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SC_START_STOP_UNIT:
|
case SC_START_STOP_UNIT:
|
||||||
LOG("command START STOP UNIT\n");
|
LOG("command %s UNIT%s\n", (scsi_cmdbuf[4] & 0x1) ? "START" : "STOP",
|
||||||
|
(scsi_cmdbuf[4] & 0x2) ? (scsi_cmdbuf[4] & 0x1) ? " (LOAD)" : " (EJECT)" : "");
|
||||||
scsi_status_complete(SS_GOOD);
|
scsi_status_complete(SS_GOOD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -196,7 +210,7 @@ void nscsi_cdrom_device::scsi_command()
|
|||||||
const uint32_t temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
|
const uint32_t temp = cdrom_get_track_start(cdrom, 0xaa) * (bytes_per_sector / bytes_per_block) - 1;
|
||||||
scsi_cmdbuf[pos++] = 0x08; // Block descriptor length
|
scsi_cmdbuf[pos++] = 0x08; // Block descriptor length
|
||||||
|
|
||||||
scsi_cmdbuf[pos++] = (temp>>24) & 0xff;
|
scsi_cmdbuf[pos++] = 0x00; // density code
|
||||||
scsi_cmdbuf[pos++] = (temp>>16) & 0xff;
|
scsi_cmdbuf[pos++] = (temp>>16) & 0xff;
|
||||||
scsi_cmdbuf[pos++] = (temp>>8) & 0xff;
|
scsi_cmdbuf[pos++] = (temp>>8) & 0xff;
|
||||||
scsi_cmdbuf[pos++] = (temp & 0xff);
|
scsi_cmdbuf[pos++] = (temp & 0xff);
|
||||||
@ -251,7 +265,7 @@ void nscsi_cdrom_device::scsi_command()
|
|||||||
|
|
||||||
case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
case SC_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||||
// TODO: support eject prevention
|
// TODO: support eject prevention
|
||||||
LOG("command PREVENT ALLOW MEDIUM REMOVAL\n");
|
LOG("command %s MEDIUM REMOVAL\n", (scsi_cmdbuf[4] & 0x1) ? "PREVENT" : "ALLOW");
|
||||||
scsi_status_complete(SS_GOOD);
|
scsi_status_complete(SS_GOOD);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "machine/nscsi_bus.h"
|
#include "machine/nscsi_bus.h"
|
||||||
|
#include "imagedev/chd_cd.h"
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
|
|
||||||
class nscsi_cdrom_device : public nscsi_full_device
|
class nscsi_cdrom_device : public nscsi_full_device
|
||||||
@ -30,6 +31,7 @@ private:
|
|||||||
cdrom_file *cdrom;
|
cdrom_file *cdrom;
|
||||||
uint32_t bytes_per_block;
|
uint32_t bytes_per_block;
|
||||||
int lba, cur_sector;
|
int lba, cur_sector;
|
||||||
|
required_device<cdrom_image_device> image;
|
||||||
|
|
||||||
void return_no_cd();
|
void return_no_cd();
|
||||||
};
|
};
|
||||||
|
@ -1173,6 +1173,10 @@ chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry
|
|||||||
|
|
||||||
void rom_load_manager::process_disk_entries(const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag)
|
void rom_load_manager::process_disk_entries(const char *regiontag, const rom_entry *parent_region, const rom_entry *romp, const char *locationtag)
|
||||||
{
|
{
|
||||||
|
/* remove existing disk entries for this region */
|
||||||
|
m_chd_list.erase(std::remove_if(m_chd_list.begin(), m_chd_list.end(),
|
||||||
|
[regiontag](std::unique_ptr<open_chd> &chd){ return !strcmp(chd->region(), regiontag); }), m_chd_list.end());
|
||||||
|
|
||||||
/* loop until we hit the end of this region */
|
/* loop until we hit the end of this region */
|
||||||
for ( ; !ROMENTRY_ISREGIONEND(romp); romp++)
|
for ( ; !ROMENTRY_ISREGIONEND(romp); romp++)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user