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"
|
||||
|
||||
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;
|
||||
|
@ -25,6 +25,7 @@ protected:
|
||||
virtual void t10_reset();
|
||||
|
||||
void abort_audio();
|
||||
int toc_tracks();
|
||||
|
||||
cdrom_image_device *m_image;
|
||||
cdda_device *m_cdda;
|
||||
|
Loading…
Reference in New Issue
Block a user