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:
smf- 2013-10-08 11:42:56 +00:00
parent 5b6fad772c
commit a5808eaca7
2 changed files with 68 additions and 88 deletions

View File

@ -1,11 +1,12 @@
#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);
phys_frame -= (*m * 60 * 75);
*s = phys_frame / 75;
*f = phys_frame % 75;
int m = frame / (75 * 60);
int s = (frame / 75) % 60;
int f = frame % 75;
return (m << 16) | (s << 8) | f;
}
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.
@ -139,29 +161,13 @@ void t10mmc::ExecCommand()
case 0x43: // READ TOC
{
int start_trk = command[6];
int end_trk = cdrom_get_last_track(cdrom);
int length;
int length = 4 + ( 8 * toc_tracks() );
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 )
{
length = allocation_length;
}
else if( length < 4 )
{
length = 4;
}
abort_audio();
@ -337,8 +343,6 @@ void t10mmc::ExecCommand()
void t10mmc::ReadData( UINT8 *data, int dataLength )
{
int i;
UINT32 last_phys_frame;
UINT32 temp;
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]);
bool msf = (command[1] & 0x2) != 0;
int audio_active = m_cdda->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[7] = 0; // index
last_phys_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);
UINT32 frame = last_lba;
if (msf)
{
int m,s,f;
phys_frame_to_msf(last_phys_frame, &m, &s, &f);
data[12] = 0;
data[13] = m;
data[14] = s;
data[15] = f;
frame = to_msf(frame);
}
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;
data[13] = (last_phys_frame>>16)&0xff;
data[14] = (last_phys_frame>>8)&0xff;
data[15] = last_phys_frame&0xff;
frame = to_msf(frame);
}
data[12] = (frame>>24)&0xff;
data[13] = (frame>>16)&0xff;
data[14] = (frame>>8)&0xff;
data[15] = frame&0xff;
break;
}
default:
@ -509,58 +500,45 @@ void t10mmc::ReadData( UINT8 *data, int dataLength )
{
case 0: // normal
{
int start_trk;
int end_trk;
int len;
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;
int tracks = toc_tracks();
int len = 2 + (tracks * 8);
bool msf = (command[1] & 0x2) != 0;
// the returned TOC DATA LENGTH must be the full amount,
// 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 & 0xff);
data[dptr++] = 1;
data[dptr++] = end_trk;
data[dptr++] = cdrom_get_last_track(cdrom);
if( start_trk == 0xaa )
{
end_trk = 0xaa;
}
in_len = command[7]<<8 | command[8];
for (i = start_trk; i <= end_trk; i++)
for (int i = 0; i < tracks; i++)
{
int track = i + 1;
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;
}
data[dptr++] = 0;
data[dptr++] = cdrom_get_adr_control(cdrom, cdrom_track);
data[dptr++] = i;
data[dptr++] = track;
data[dptr++] = 0;
tstart = cdrom_get_track_start(cdrom, cdrom_track);
if ((command[1]&2)>>1)
tstart = lba_to_msf(tstart);
UINT32 tstart = cdrom_get_track_start(cdrom, cdrom_track);
if (msf)
{
tstart = to_msf(tstart+150);
}
data[dptr++] = (tstart>>24) & 0xff;
data[dptr++] = (tstart>>16) & 0xff;
data[dptr++] = (tstart>>8) & 0xff;
@ -568,6 +546,7 @@ void t10mmc::ReadData( UINT8 *data, int dataLength )
}
}
break;
default:
logerror("T10MMC: Unhandled READ TOC format %d\n", command[2]&0xf);
break;

View File

@ -25,6 +25,7 @@ protected:
virtual void t10_reset();
void abort_audio();
int toc_tracks();
cdrom_image_device *m_image;
cdda_device *m_cdda;