mirror of
https://github.com/holub/mame
synced 2025-06-07 05:13:46 +03:00
Fixed ATAPI Mode Sense and Mode Select for MSCDEX Mode 2 Form 1 support [smf, windyfairy]
This commit is contained in:
parent
607153c23c
commit
0e5c892ac1
@ -1493,61 +1493,88 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
|
|||||||
memset(data, 0, SCSILengthFromUINT16( &command[ 7 ] ));
|
memset(data, 0, SCSILengthFromUINT16( &command[ 7 ] ));
|
||||||
|
|
||||||
const uint8_t page = command[2] & 0x3f;
|
const uint8_t page = command[2] & 0x3f;
|
||||||
int ptr = 0;
|
int ptr = (command[0] == T10SPC_CMD_MODE_SENSE_6) ? 4 : 8;
|
||||||
|
|
||||||
if ((page == 0xe) || (page == 0x3f))
|
if ((page == 0xe) || (page == 0x3f))
|
||||||
{ // CD Audio control page
|
{
|
||||||
data[ptr++] = 0x8e; // page E, parameter is savable
|
// CD Audio control page
|
||||||
data[ptr++] = 0x0e; // page length
|
data[ptr++] = 0x8e; // page E, parameter is savable
|
||||||
data[ptr++] = (1 << 2) | (m_sotc << 1); // IMMED = 1
|
data[ptr++] = 0x0e; // page length
|
||||||
ptr += 5; // skip reserved bytes
|
data[ptr++] = (1 << 2) | (m_sotc << 1); // IMMED = 1
|
||||||
// connect each audio channel to 1 output port and indicate max volume
|
// reserved
|
||||||
data[ptr++] = 1;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0xff;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 2;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0xff;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 4;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0xff;
|
// connect each audio channel to 1 output port and indicate max volume
|
||||||
data[ptr++] = 8;
|
data[ptr++] = 1;
|
||||||
data[ptr++] = 0xff;
|
data[ptr++] = 0xff;
|
||||||
|
data[ptr++] = 2;
|
||||||
|
data[ptr++] = 0xff;
|
||||||
|
data[ptr++] = 4;
|
||||||
|
data[ptr++] = 0xff;
|
||||||
|
data[ptr++] = 8;
|
||||||
|
data[ptr++] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((page == 0x0d) || (page == 0x3f))
|
if ((page == 0x0d) || (page == 0x3f))
|
||||||
{ // CD page
|
{
|
||||||
data[ptr++] = 0x0d;
|
// CD page
|
||||||
data[ptr++] = 6; // page length
|
data[ptr++] = 0x0d;
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 6; // page length
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 60;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 60;
|
||||||
data[ptr++] = 75;
|
data[ptr++] = 0;
|
||||||
|
data[ptr++] = 75;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((page == 0x2a) || (page == 0x3f))
|
if ((page == 0x2a) || (page == 0x3f))
|
||||||
{ // Page capabilities
|
{
|
||||||
data[ptr++] = 0x2a;
|
// Page capabilities
|
||||||
data[ptr++] = 0x14; // page length
|
data[ptr++] = 0x2a;
|
||||||
data[ptr++] = 0x00;
|
data[ptr++] = 0x14; // page length
|
||||||
data[ptr++] = 0x00; // CD-R only
|
data[ptr++] = 0x00;
|
||||||
data[ptr++] = 0x01; // can play audio
|
data[ptr++] = 0x00; // CD-R only
|
||||||
data[ptr++] = 0;
|
data[ptr++] =
|
||||||
data[ptr++] = 0;
|
(1 << 4) | // Mode 2 Form 1
|
||||||
data[ptr++] = 0;
|
(1 << 1) | // XA Cmds Supported
|
||||||
data[ptr++] = 0x02;
|
(1 << 0); // AudioPlay
|
||||||
data[ptr++] = 0xc0; // 4x speed
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0x01;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0x00; // 256 volume levels supported
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0x00;
|
data[ptr++] = 0x02;
|
||||||
data[ptr++] = 0x00; // buffer
|
data[ptr++] = 0xc0; // 4x speed
|
||||||
data[ptr++] = 0x02;
|
data[ptr++] = 0x01;
|
||||||
data[ptr++] = 0xc0; // 4x read speed
|
data[ptr++] = 0x00; // 256 volume levels supported
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0x00;
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0x00; // buffer
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0x02;
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0xc0; // 4x read speed
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0;
|
||||||
data[ptr++] = 0;
|
data[ptr++] = 0;
|
||||||
|
data[ptr++] = 0;
|
||||||
|
data[ptr++] = 0;
|
||||||
|
data[ptr++] = 0;
|
||||||
|
data[ptr++] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command[0] == T10SPC_CMD_MODE_SENSE_6)
|
||||||
|
{
|
||||||
|
data[0] = ptr - 1; // Mode Data Length
|
||||||
|
data[1] = 0x70; // Medium Type
|
||||||
|
data[2] = 0x00; // Device-Specific Parameter
|
||||||
|
data[3] = 0x00; // Block Descriptor Length
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
put_u16be(&data[0], ptr - 2); // Mode Data Length
|
||||||
|
data[2] = 0x70; // Medium Type
|
||||||
|
data[3] = 0x00; // Device-Specific Parameter
|
||||||
|
put_u16be(&data[4], 0); // Reserved
|
||||||
|
put_u16be(&data[6], 0); // Block Descriptor Length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1560,7 +1587,7 @@ void t10mmc::ReadData( uint8_t *data, int dataLength )
|
|||||||
if((command[1] & 0x0f) == 0 && command[7] == 0x04) // DVD / DVD disc manufacturing information
|
if((command[1] & 0x0f) == 0 && command[7] == 0x04) // DVD / DVD disc manufacturing information
|
||||||
{
|
{
|
||||||
data[1] = 0xe;
|
data[1] = 0xe;
|
||||||
for(int i=4; i != 0xe; i++)
|
for (int i = 4; i != 0xe; i++)
|
||||||
data[i] = 0;
|
data[i] = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1581,42 +1608,64 @@ void t10mmc::WriteData( uint8_t *data, int dataLength )
|
|||||||
{
|
{
|
||||||
case T10SPC_CMD_MODE_SELECT_6:
|
case T10SPC_CMD_MODE_SELECT_6:
|
||||||
case T10SPC_CMD_MODE_SELECT_10:
|
case T10SPC_CMD_MODE_SELECT_10:
|
||||||
m_device->logerror("T10MMC: MODE SELECT page %x\n", data[0] & 0x3f);
|
{
|
||||||
|
int len = (command[0] == T10SPC_CMD_MODE_SELECT_6) ? data[0] : get_u16be(&data[0]);
|
||||||
|
int bdlen = (command[0] == T10SPC_CMD_MODE_SELECT_6) ? data[3] : get_u16be(&data[6]);
|
||||||
|
int ptr = (command[0] == T10SPC_CMD_MODE_SELECT_6) ? 4 : 8;
|
||||||
|
|
||||||
switch (data[0] & 0x3f)
|
if (bdlen == 8)
|
||||||
{
|
{
|
||||||
case 0x0: // vendor-specific
|
int blen = get_u24be(&data[ptr + 5]);
|
||||||
// check for SGI extension to force 512-byte blocks
|
if (blen == 512)
|
||||||
if ((data[3] == 8) && (data[10] == 2))
|
{
|
||||||
{
|
m_device->logerror("T10MMC: Experimental SGI 512-byte block extension enabled\n");
|
||||||
m_device->logerror("T10MMC: Experimental SGI 512-byte block extension enabled\n");
|
|
||||||
|
|
||||||
m_sector_bytes = 512;
|
m_sector_bytes = 512;
|
||||||
m_num_subblocks = 4;
|
m_num_subblocks = 4;
|
||||||
}
|
}
|
||||||
else
|
else if (blen == 2048)
|
||||||
{
|
{
|
||||||
m_device->logerror("T10MMC: Unknown vendor-specific page!\n");
|
m_sector_bytes = 2048;
|
||||||
}
|
m_num_subblocks = 1;
|
||||||
break;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_device->logerror("T10MMC: Unsupported block length %d\n", blen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bdlen)
|
||||||
|
m_device->logerror("T10MMC: MODE SELECT Invalid Block Descriptor Length %d\n", bdlen);
|
||||||
|
|
||||||
|
ptr += bdlen;
|
||||||
|
|
||||||
|
while (ptr < len)
|
||||||
|
{
|
||||||
|
m_device->logerror("T10MMC: MODE SELECT page %x\n", data[ptr + 0] & 0x3f);
|
||||||
|
|
||||||
|
switch (data[ptr + 0] & 0x3f)
|
||||||
|
{
|
||||||
case 0xe: // audio page
|
case 0xe: // audio page
|
||||||
m_sotc = (data[2] >> 1) & 1;
|
m_sotc = (data[ptr + 2] >> 1) & 1;
|
||||||
m_device->logerror("Ch 0 route: %x vol: %x\n", data[8], data[9]);
|
m_device->logerror("Ch 0 route: %x vol: %x\n", data[ptr + 8], data[ptr + 9]);
|
||||||
m_device->logerror("Ch 1 route: %x vol: %x\n", data[10], data[11]);
|
m_device->logerror("Ch 1 route: %x vol: %x\n", data[ptr + 10], data[ptr + 11]);
|
||||||
m_device->logerror("Ch 2 route: %x vol: %x\n", data[12], data[13]);
|
m_device->logerror("Ch 2 route: %x vol: %x\n", data[ptr + 12], data[ptr + 13]);
|
||||||
m_device->logerror("Ch 3 route: %x vol: %x\n", data[14], data[15]);
|
m_device->logerror("Ch 3 route: %x vol: %x\n", data[ptr + 14], data[ptr + 15]);
|
||||||
|
|
||||||
// TODO: CDDA audio channels and output port should be separate
|
// TODO: CDDA audio channels and output port should be separate
|
||||||
// The actual audio channel that gets sent to the output port is configurable and more than one audio channel can go to an output port
|
// The actual audio channel that gets sent to the output port is configurable and more than one audio channel can go to an output port
|
||||||
m_cdda->set_output_gain(0, data[9] / 255.0f);
|
m_cdda->set_output_gain(0, data[ptr + 9] / 255.0f);
|
||||||
m_cdda->set_output_gain(1, data[11] / 255.0f);
|
m_cdda->set_output_gain(1, data[ptr + 11] / 255.0f);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr += data[ptr + 1] + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t10spc::WriteData( data, dataLength );
|
t10spc::WriteData( data, dataLength );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user