422 lines
7.9 KiB
C++
422 lines
7.9 KiB
C++
#include "common.h"
|
|
|
|
Disc* chd_parse(const wchar* file);
|
|
Disc* gdi_parse(const wchar* file);
|
|
Disc* cdi_parse(const wchar* file);
|
|
#if HOST_OS==OS_WINDOWS
|
|
Disc* ioctl_parse(const wchar* file);
|
|
#endif
|
|
|
|
u32 NullDriveDiscType;
|
|
Disc* disc;
|
|
|
|
Disc*(*drivers[])(const wchar* path)=
|
|
{
|
|
chd_parse,
|
|
gdi_parse,
|
|
cdi_parse,
|
|
#if HOST_OS==OS_WINDOWS
|
|
ioctl_parse,
|
|
#endif
|
|
0
|
|
};
|
|
|
|
u8 q_subchannel[96];
|
|
|
|
void PatchRegion_0(u8* sector,int size)
|
|
{
|
|
#ifndef NOT_REICAST
|
|
if (settings.imgread.PatchRegion==0)
|
|
return;
|
|
#else
|
|
return;
|
|
#endif
|
|
|
|
u8* usersect=sector;
|
|
|
|
if (size!=2048)
|
|
{
|
|
printf("PatchRegion_0 -> sector size %d , skipping patch\n",size);
|
|
}
|
|
|
|
//patch meta info
|
|
u8* p_area_symbol=&usersect[0x30];
|
|
memcpy(p_area_symbol,"JUE ",8);
|
|
}
|
|
void PatchRegion_6(u8* sector,int size)
|
|
{
|
|
#ifndef NOT_REICAST
|
|
if (settings.imgread.PatchRegion==0)
|
|
return;
|
|
#else
|
|
return;
|
|
#endif
|
|
|
|
u8* usersect=sector;
|
|
|
|
if (size!=2048)
|
|
{
|
|
printf("PatchRegion_6 -> sector size %d , skipping patch\n",size);
|
|
}
|
|
|
|
//patch area symbols
|
|
u8* p_area_text=&usersect[0x700];
|
|
memcpy(&p_area_text[4],"For JAPAN,TAIWAN,PHILIPINES.",28);
|
|
memcpy(&p_area_text[4 + 32],"For USA and CANADA. ",28);
|
|
memcpy(&p_area_text[4 + 32 + 32],"For EUROPE. ",28);
|
|
}
|
|
bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector)
|
|
{
|
|
//get subchannel data, if any
|
|
if (from==2448)
|
|
{
|
|
memcpy(q_subchannel,in_buff+2352,96);
|
|
from-=96;
|
|
}
|
|
//if no conversion
|
|
if (to==from)
|
|
{
|
|
memcpy(out_buff,in_buff,to);
|
|
return true;
|
|
}
|
|
switch (to)
|
|
{
|
|
case 2340:
|
|
{
|
|
verify((from==2352));
|
|
memcpy(out_buff,&in_buff[12],2340);
|
|
}
|
|
break;
|
|
case 2328:
|
|
{
|
|
verify((from==2352));
|
|
memcpy(out_buff,&in_buff[24],2328);
|
|
}
|
|
break;
|
|
case 2336:
|
|
verify(from>=2336);
|
|
verify((from==2352));
|
|
memcpy(out_buff,&in_buff[0x10],2336);
|
|
break;
|
|
case 2048:
|
|
{
|
|
verify(from>=2048);
|
|
verify((from==2448) || (from==2352) || (from==2336));
|
|
if ((from == 2352) || (from == 2448))
|
|
{
|
|
if (in_buff[15]==1)
|
|
{
|
|
memcpy(out_buff,&in_buff[0x10],2048); //0x10 -> mode1
|
|
}
|
|
else
|
|
memcpy(out_buff,&in_buff[0x18],2048); //0x18 -> mode2 (all forms ?)
|
|
}
|
|
else
|
|
memcpy(out_buff,&in_buff[0x8],2048); //hmm only possible on mode2.Skip the mode2 header
|
|
}
|
|
break;
|
|
case 2352:
|
|
//if (from >= 2352)
|
|
{
|
|
memcpy(out_buff,&in_buff[0],2352);
|
|
}
|
|
break;
|
|
default :
|
|
printf("Sector conversion from %d to %d not supported \n", from , to);
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Disc* OpenDisc(const wchar* fn)
|
|
{
|
|
Disc* rv;
|
|
|
|
for (int i=0;drivers[i] && !(rv=drivers[i](fn));i++) ;
|
|
|
|
return rv;
|
|
}
|
|
|
|
bool InitDrive_(wchar* fn)
|
|
{
|
|
TermDrive();
|
|
|
|
//try all drivers
|
|
disc = OpenDisc(fn);
|
|
|
|
if (disc!=0)
|
|
{
|
|
printf("gdrom: Opened image \"%s\"\n",fn);
|
|
NullDriveDiscType=Busy;
|
|
#ifndef NOT_REICAST
|
|
libCore_gdrom_disc_change();
|
|
#endif
|
|
// Sleep(400); //busy for a bit // what, really ?
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
printf("gdrom: Failed to open image \"%s\"\n",fn);
|
|
NullDriveDiscType=NoDisk; //no disc :)
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#ifndef NOT_REICAST
|
|
bool InitDrive(u32 fileflags)
|
|
{
|
|
if (settings.imgread.LoadDefaultImage)
|
|
{
|
|
printf("Loading default image \"%s\"\n",settings.imgread.DefaultImage);
|
|
if (!InitDrive_(settings.imgread.DefaultImage))
|
|
{
|
|
msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR);
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
wchar fn[512];
|
|
strcpy(fn,settings.imgread.LastImage);
|
|
#ifdef BUILD_DREAMCAST
|
|
int gfrv=GetFile(fn,0,fileflags);
|
|
#else
|
|
int gfrv=0;
|
|
#endif
|
|
if (gfrv == 0)
|
|
{
|
|
NullDriveDiscType=NoDisk;
|
|
gd_setdisc();
|
|
sns_asc=0x29;
|
|
sns_ascq=0x00;
|
|
sns_key=0x6;
|
|
return true;
|
|
}
|
|
else if (gfrv == -1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
strcpy(settings.imgread.LastImage,fn);
|
|
SaveSettings();
|
|
|
|
if (!InitDrive_(fn))
|
|
{
|
|
//msgboxf("Selected image failed to load",MBX_ICONERROR);
|
|
NullDriveDiscType=NoDisk;
|
|
gd_setdisc();
|
|
sns_asc=0x29;
|
|
sns_ascq=0x00;
|
|
sns_key=0x6;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool DiscSwap(u32 fileflags)
|
|
{
|
|
if (settings.imgread.LoadDefaultImage)
|
|
{
|
|
printf("Loading default image \"%s\"\n",settings.imgread.DefaultImage);
|
|
if (!InitDrive_(settings.imgread.DefaultImage))
|
|
{
|
|
msgboxf("Default image \"%s\" failed to load",MBX_ICONERROR);
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
|
|
wchar fn[512];
|
|
strcpy(fn,settings.imgread.LastImage);
|
|
#ifdef BUILD_DREAMCAST
|
|
int gfrv=GetFile(fn,0,fileflags);
|
|
#else
|
|
int gfrv=0;
|
|
#endif
|
|
if (gfrv == 0)
|
|
{
|
|
NullDriveDiscType=Open;
|
|
gd_setdisc();
|
|
sns_asc=0x28;
|
|
sns_ascq=0x00;
|
|
sns_key=0x6;
|
|
return true;
|
|
}
|
|
else if (gfrv == -1)
|
|
{
|
|
sns_asc=0x28;
|
|
sns_ascq=0x00;
|
|
sns_key=0x6;
|
|
return false;
|
|
}
|
|
|
|
strcpy(settings.imgread.LastImage,fn);
|
|
SaveSettings();
|
|
|
|
if (!InitDrive_(fn))
|
|
{
|
|
//msgboxf("Selected image failed to load",MBX_ICONERROR);
|
|
NullDriveDiscType=Open;
|
|
gd_setdisc();
|
|
sns_asc=0x28;
|
|
sns_ascq=0x00;
|
|
sns_key=0x6;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
sns_asc=0x28;
|
|
sns_ascq=0x00;
|
|
sns_key=0x6;
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void TermDrive()
|
|
{
|
|
if (disc!=0)
|
|
delete disc;
|
|
|
|
disc=0;
|
|
}
|
|
|
|
|
|
//
|
|
//convert our nice toc struct to dc's native one :)
|
|
|
|
u32 CreateTrackInfo(u32 ctrl,u32 addr,u32 fad)
|
|
{
|
|
u8 p[4];
|
|
p[0]=(ctrl<<4)|(addr<<0);
|
|
p[1]=fad>>16;
|
|
p[2]=fad>>8;
|
|
p[3]=fad>>0;
|
|
|
|
return *(u32*)p;
|
|
}
|
|
u32 CreateTrackInfo_se(u32 ctrl,u32 addr,u32 tracknum)
|
|
{
|
|
u8 p[4];
|
|
p[0]=(ctrl<<4)|(addr<<0);
|
|
p[1]=tracknum;
|
|
p[2]=0;
|
|
p[3]=0;
|
|
return *(u32*)p;
|
|
}
|
|
|
|
|
|
void GetDriveSector(u8 * buff,u32 StartSector,u32 SectorCount,u32 secsz)
|
|
{
|
|
//printf("GD: read %08X, %d\n",StartSector,SectorCount);
|
|
if (disc)
|
|
{
|
|
disc->ReadSectors(StartSector,SectorCount,buff,secsz);
|
|
if (disc->type == GdRom && StartSector==45150 && SectorCount==7)
|
|
{
|
|
PatchRegion_0(buff,secsz);
|
|
PatchRegion_6(buff+2048*6,secsz);
|
|
}
|
|
}
|
|
}
|
|
void GetDriveToc(u32* to,DiskArea area)
|
|
{
|
|
if (!disc)
|
|
return;
|
|
memset(to,0xFFFFFFFF,102*4);
|
|
|
|
//can't get toc on the second area on discs that don't have it
|
|
verify(area != DoubleDensity || disc->type == GdRom);
|
|
|
|
//normal CDs: 1 .. tc
|
|
//GDROM: area0 is 1 .. 2, area1 is 3 ... tc
|
|
|
|
u32 first_track=1;
|
|
u32 last_track=disc->tracks.size();
|
|
if (area==DoubleDensity)
|
|
first_track=3;
|
|
else if (disc->type==GdRom)
|
|
{
|
|
last_track=2;
|
|
}
|
|
|
|
//Generate the TOC info
|
|
|
|
//-1 for 1..99 0 ..98
|
|
to[99]=CreateTrackInfo_se(disc->tracks[first_track-1].CTRL,disc->tracks[first_track-1].ADDR,first_track);
|
|
to[100]=CreateTrackInfo_se(disc->tracks[last_track-1].CTRL,disc->tracks[last_track-1].ADDR,last_track);
|
|
|
|
if (disc->type==GdRom)
|
|
{
|
|
//use smaller LEADOUT
|
|
if (area==SingleDensity)
|
|
to[101]=CreateTrackInfo(disc->LeadOut.CTRL,disc->LeadOut.ADDR,13085);
|
|
}
|
|
else
|
|
{
|
|
to[101] = CreateTrackInfo(disc->LeadOut.CTRL, disc->LeadOut.ADDR, disc->LeadOut.StartFAD);
|
|
}
|
|
|
|
for (u32 i=first_track-1;i<last_track;i++)
|
|
{
|
|
to[i]=CreateTrackInfo(disc->tracks[i].CTRL,disc->tracks[i].ADDR,disc->tracks[i].StartFAD);
|
|
}
|
|
}
|
|
|
|
void GetDriveSessionInfo(u8* to,u8 session)
|
|
{
|
|
if (!disc)
|
|
return;
|
|
to[0]=2;//status, will get overwritten anyway
|
|
to[1]=0;//0's
|
|
|
|
if (session==0)
|
|
{
|
|
to[2]=disc->sessions.size();//count of sessions
|
|
to[3]=disc->EndFAD>>16;//fad is sessions end
|
|
to[4]=disc->EndFAD>>8;
|
|
to[5]=disc->EndFAD>>0;
|
|
}
|
|
else
|
|
{
|
|
to[2]=disc->sessions[session-1].FirstTrack;//start track of this session
|
|
to[3]=disc->sessions[session-1].StartFAD>>16;//fad is session start
|
|
to[4]=disc->sessions[session-1].StartFAD>>8;
|
|
to[5]=disc->sessions[session-1].StartFAD>>0;
|
|
}
|
|
}
|
|
|
|
void printtoc(TocInfo* toc,SessionInfo* ses)
|
|
{
|
|
printf("Sessions %d\n",ses->SessionCount);
|
|
for (u32 i=0;i<ses->SessionCount;i++)
|
|
{
|
|
printf("Session %d: FAD %d,First Track %d\n",i+1,ses->SessionFAD[i],ses->SessionStart[i]);
|
|
for (u32 t=toc->FistTrack-1;t<=toc->LastTrack;t++)
|
|
{
|
|
if (toc->tracks[t].Session==i+1)
|
|
{
|
|
printf("\tTrack %d : FAD %d CTRL %d ADR %d\n",t,toc->tracks[t].FAD,toc->tracks[t].Control,toc->tracks[t].Addr);
|
|
}
|
|
}
|
|
}
|
|
printf("Session END: FAD END %d\n",ses->SessionsEndFAD);
|
|
}
|
|
|
|
DiscType GuessDiscType(bool m1, bool m2, bool da)
|
|
{
|
|
if ((m1==true) && (da==false) && (m2==false))
|
|
return CdRom;
|
|
else if (m2)
|
|
return CdRom_XA;
|
|
else if (da && m1)
|
|
return CdRom_Extra;
|
|
else
|
|
return CdRom;
|
|
} |