mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +03:00
Fixed read toc to always return the lead out & return the correct results for msf requests. Mounting the same iso in Windows 8 produces a slightly different result, but it's enough to make windows 2000 recovery console and windows 95a work. [smf]
This commit is contained in:
parent
5b6fad772c
commit
a5808eaca7
@ -1,11 +1,12 @@
|
|||||||
#include "t10mmc.h"
|
#include "t10mmc.h"
|
||||||
|
|
||||||
static void phys_frame_to_msf(int phys_frame, int *m, int *s, int *f)
|
static int to_msf(int frame)
|
||||||
{
|
{
|
||||||
*m = phys_frame / (60*75);
|
int m = frame / (75 * 60);
|
||||||
phys_frame -= (*m * 60 * 75);
|
int s = (frame / 75) % 60;
|
||||||
*s = phys_frame / 75;
|
int f = frame % 75;
|
||||||
*f = phys_frame % 75;
|
|
||||||
|
return (m << 16) | (s << 8) | f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void t10mmc::t10_start(device_t &device)
|
void t10mmc::t10_start(device_t &device)
|
||||||
@ -50,6 +51,27 @@ void t10mmc::abort_audio()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int t10mmc::toc_tracks()
|
||||||
|
{
|
||||||
|
int start_track = command[6];
|
||||||
|
int end_track = cdrom_get_last_track(cdrom);
|
||||||
|
|
||||||
|
if (start_track == 0)
|
||||||
|
{
|
||||||
|
return end_track + 1;
|
||||||
|
}
|
||||||
|
else if (start_track <= end_track)
|
||||||
|
{
|
||||||
|
return ( end_track - start_track ) + 2;
|
||||||
|
}
|
||||||
|
else if (start_track < 0xaa)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Execute a SCSI command.
|
// Execute a SCSI command.
|
||||||
|
|
||||||
@ -139,29 +161,13 @@ void t10mmc::ExecCommand()
|
|||||||
|
|
||||||
case 0x43: // READ TOC
|
case 0x43: // READ TOC
|
||||||
{
|
{
|
||||||
int start_trk = command[6];
|
int length = 4 + ( 8 * toc_tracks() );
|
||||||
int end_trk = cdrom_get_last_track(cdrom);
|
|
||||||
int length;
|
|
||||||
int allocation_length = SCSILengthFromUINT16( &command[ 7 ] );
|
int allocation_length = SCSILengthFromUINT16( &command[ 7 ] );
|
||||||
|
|
||||||
if( start_trk == 0 )
|
|
||||||
{
|
|
||||||
start_trk = 1;
|
|
||||||
}
|
|
||||||
if( start_trk == 0xaa )
|
|
||||||
{
|
|
||||||
end_trk = start_trk;
|
|
||||||
}
|
|
||||||
|
|
||||||
length = 4 + ( 8 * ( ( end_trk - start_trk ) + 1 ) );
|
|
||||||
if( length > allocation_length )
|
if( length > allocation_length )
|
||||||
{
|
{
|
||||||
length = allocation_length;
|
length = allocation_length;
|
||||||
}
|
}
|
||||||
else if( length < 4 )
|
|
||||||
{
|
|
||||||
length = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
abort_audio();
|
abort_audio();
|
||||||
|
|
||||||
@ -337,8 +343,6 @@ void t10mmc::ExecCommand()
|
|||||||
|
|
||||||
void t10mmc::ReadData( UINT8 *data, int dataLength )
|
void t10mmc::ReadData( UINT8 *data, int dataLength )
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
UINT32 last_phys_frame;
|
|
||||||
UINT32 temp;
|
UINT32 temp;
|
||||||
UINT8 tmp_buffer[2048];
|
UINT8 tmp_buffer[2048];
|
||||||
|
|
||||||
@ -417,6 +421,8 @@ void t10mmc::ReadData( UINT8 *data, int dataLength )
|
|||||||
|
|
||||||
logerror("T10MMC: READ SUB-CHANNEL Time = %x, SUBQ = %x\n", command[1], command[2]);
|
logerror("T10MMC: READ SUB-CHANNEL Time = %x, SUBQ = %x\n", command[1], command[2]);
|
||||||
|
|
||||||
|
bool msf = (command[1] & 0x2) != 0;
|
||||||
|
|
||||||
int audio_active = m_cdda->audio_active();
|
int audio_active = m_cdda->audio_active();
|
||||||
if (audio_active)
|
if (audio_active)
|
||||||
{
|
{
|
||||||
@ -452,44 +458,29 @@ void t10mmc::ReadData( UINT8 *data, int dataLength )
|
|||||||
data[6] = cdrom_get_track(cdrom, last_lba) + 1; // track
|
data[6] = cdrom_get_track(cdrom, last_lba) + 1; // track
|
||||||
data[7] = 0; // index
|
data[7] = 0; // index
|
||||||
|
|
||||||
last_phys_frame = last_lba;
|
UINT32 frame = last_lba;
|
||||||
|
|
||||||
int msf = command[1] & 0x2;
|
|
||||||
if (msf)
|
|
||||||
{
|
|
||||||
int m,s,f;
|
|
||||||
phys_frame_to_msf(last_phys_frame, &m, &s, &f);
|
|
||||||
data[8] = 0;
|
|
||||||
data[9] = m;
|
|
||||||
data[10] = s;
|
|
||||||
data[11] = f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
data[8] = last_phys_frame>>24;
|
|
||||||
data[9] = (last_phys_frame>>16)&0xff;
|
|
||||||
data[10] = (last_phys_frame>>8)&0xff;
|
|
||||||
data[11] = last_phys_frame&0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_phys_frame -= cdrom_get_track_start(cdrom, data[6] - 1);
|
|
||||||
|
|
||||||
if (msf)
|
if (msf)
|
||||||
{
|
{
|
||||||
int m,s,f;
|
frame = to_msf(frame);
|
||||||
phys_frame_to_msf(last_phys_frame, &m, &s, &f);
|
|
||||||
data[12] = 0;
|
|
||||||
data[13] = m;
|
|
||||||
data[14] = s;
|
|
||||||
data[15] = f;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
data[8] = (frame>>24)&0xff;
|
||||||
|
data[9] = (frame>>16)&0xff;
|
||||||
|
data[10] = (frame>>8)&0xff;
|
||||||
|
data[11] = frame&0xff;
|
||||||
|
|
||||||
|
frame -= cdrom_get_track_start(cdrom, data[6] - 1);
|
||||||
|
|
||||||
|
if (msf)
|
||||||
{
|
{
|
||||||
data[12] = last_phys_frame>>24;
|
frame = to_msf(frame);
|
||||||
data[13] = (last_phys_frame>>16)&0xff;
|
|
||||||
data[14] = (last_phys_frame>>8)&0xff;
|
|
||||||
data[15] = last_phys_frame&0xff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data[12] = (frame>>24)&0xff;
|
||||||
|
data[13] = (frame>>16)&0xff;
|
||||||
|
data[14] = (frame>>8)&0xff;
|
||||||
|
data[15] = frame&0xff;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -509,58 +500,45 @@ void t10mmc::ReadData( UINT8 *data, int dataLength )
|
|||||||
{
|
{
|
||||||
case 0: // normal
|
case 0: // normal
|
||||||
{
|
{
|
||||||
int start_trk;
|
int tracks = toc_tracks();
|
||||||
int end_trk;
|
int len = 2 + (tracks * 8);
|
||||||
int len;
|
bool msf = (command[1] & 0x2) != 0;
|
||||||
int in_len;
|
|
||||||
int dptr;
|
|
||||||
UINT32 tstart;
|
|
||||||
|
|
||||||
start_trk = command[6];
|
|
||||||
if( start_trk == 0 )
|
|
||||||
{
|
|
||||||
start_trk = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
end_trk = cdrom_get_last_track(cdrom);
|
|
||||||
len = (end_trk * 8) + 2;
|
|
||||||
|
|
||||||
// the returned TOC DATA LENGTH must be the full amount,
|
// the returned TOC DATA LENGTH must be the full amount,
|
||||||
// regardless of how much we're able to pass back due to in_len
|
// regardless of how much we're able to pass back due to in_len
|
||||||
dptr = 0;
|
int dptr = 0;
|
||||||
data[dptr++] = (len>>8) & 0xff;
|
data[dptr++] = (len>>8) & 0xff;
|
||||||
data[dptr++] = (len & 0xff);
|
data[dptr++] = (len & 0xff);
|
||||||
data[dptr++] = 1;
|
data[dptr++] = 1;
|
||||||
data[dptr++] = end_trk;
|
data[dptr++] = cdrom_get_last_track(cdrom);
|
||||||
|
|
||||||
if( start_trk == 0xaa )
|
for (int i = 0; i < tracks; i++)
|
||||||
{
|
|
||||||
end_trk = 0xaa;
|
|
||||||
}
|
|
||||||
|
|
||||||
in_len = command[7]<<8 | command[8];
|
|
||||||
|
|
||||||
for (i = start_trk; i <= end_trk; i++)
|
|
||||||
{
|
{
|
||||||
|
int track = i + 1;
|
||||||
int cdrom_track = i;
|
int cdrom_track = i;
|
||||||
if( cdrom_track != 0xaa )
|
if( i == tracks - 1 )
|
||||||
{
|
{
|
||||||
cdrom_track--;
|
track = 0xaa;
|
||||||
|
cdrom_track = 0xaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( dptr >= in_len )
|
if( dptr >= dataLength )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
data[dptr++] = 0;
|
data[dptr++] = 0;
|
||||||
data[dptr++] = cdrom_get_adr_control(cdrom, cdrom_track);
|
data[dptr++] = cdrom_get_adr_control(cdrom, cdrom_track);
|
||||||
data[dptr++] = i;
|
data[dptr++] = track;
|
||||||
data[dptr++] = 0;
|
data[dptr++] = 0;
|
||||||
|
|
||||||
tstart = cdrom_get_track_start(cdrom, cdrom_track);
|
UINT32 tstart = cdrom_get_track_start(cdrom, cdrom_track);
|
||||||
if ((command[1]&2)>>1)
|
|
||||||
tstart = lba_to_msf(tstart);
|
if (msf)
|
||||||
|
{
|
||||||
|
tstart = to_msf(tstart+150);
|
||||||
|
}
|
||||||
|
|
||||||
data[dptr++] = (tstart>>24) & 0xff;
|
data[dptr++] = (tstart>>24) & 0xff;
|
||||||
data[dptr++] = (tstart>>16) & 0xff;
|
data[dptr++] = (tstart>>16) & 0xff;
|
||||||
data[dptr++] = (tstart>>8) & 0xff;
|
data[dptr++] = (tstart>>8) & 0xff;
|
||||||
@ -568,6 +546,7 @@ void t10mmc::ReadData( UINT8 *data, int dataLength )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logerror("T10MMC: Unhandled READ TOC format %d\n", command[2]&0xf);
|
logerror("T10MMC: Unhandled READ TOC format %d\n", command[2]&0xf);
|
||||||
break;
|
break;
|
||||||
|
@ -25,6 +25,7 @@ protected:
|
|||||||
virtual void t10_reset();
|
virtual void t10_reset();
|
||||||
|
|
||||||
void abort_audio();
|
void abort_audio();
|
||||||
|
int toc_tracks();
|
||||||
|
|
||||||
cdrom_image_device *m_image;
|
cdrom_image_device *m_image;
|
||||||
cdda_device *m_cdda;
|
cdda_device *m_cdda;
|
||||||
|
Loading…
Reference in New Issue
Block a user