Implemented a very basic form of GD-ROM Sense. Only disc swap related Sense currently works. Added some very basic disc swap handling on x86/Windows (press "0">Cancel to remove disc, then "0" again and select the new disc).
Notes: Disc swapping should work on .gdi files (probably .chd files too). Swapping with .cdi files is not currently supported because we currently create inaccurate TOC for them. Only x86/Windows has a disc swap handler right now (ie: you can't swap on Android).
This commit is contained in:
parent
e6ac0e4918
commit
6b4deb4b16
|
@ -19,6 +19,11 @@
|
||||||
|
|
||||||
int gdrom_schid;
|
int gdrom_schid;
|
||||||
|
|
||||||
|
//Sense: ASC - ASCQ - Key
|
||||||
|
signed int sns_asc=0;
|
||||||
|
signed int sns_ascq=0;
|
||||||
|
signed int sns_key=0;
|
||||||
|
|
||||||
enum gd_states
|
enum gd_states
|
||||||
{
|
{
|
||||||
//Generic
|
//Generic
|
||||||
|
@ -447,7 +452,11 @@ void gd_process_ata_cmd()
|
||||||
{
|
{
|
||||||
//Any ATA command clears these bits, unless aborted/error :p
|
//Any ATA command clears these bits, unless aborted/error :p
|
||||||
Error.ABRT=0;
|
Error.ABRT=0;
|
||||||
GDStatus.CHECK=0;
|
|
||||||
|
if (sns_key==0x0 || sns_key==0xB)
|
||||||
|
GDStatus.CHECK=0;
|
||||||
|
else
|
||||||
|
GDStatus.CHECK=1;
|
||||||
|
|
||||||
switch(ata_cmd.command)
|
switch(ata_cmd.command)
|
||||||
{
|
{
|
||||||
|
@ -464,7 +473,7 @@ void gd_process_ata_cmd()
|
||||||
//the above comment is from a wrong place in the docs ...
|
//the above comment is from a wrong place in the docs ...
|
||||||
|
|
||||||
Error.ABRT=1;
|
Error.ABRT=1;
|
||||||
//Error.Sense=0x00; //fixme ?
|
Error.Sense=sns_key;
|
||||||
GDStatus.BSY=0;
|
GDStatus.BSY=0;
|
||||||
GDStatus.CHECK=1;
|
GDStatus.CHECK=1;
|
||||||
|
|
||||||
|
@ -519,12 +528,18 @@ void gd_process_ata_cmd()
|
||||||
|
|
||||||
void gd_process_spi_cmd()
|
void gd_process_spi_cmd()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
printf_spi("Sense: %02x %02x %02x \n", sns_asc, sns_ascq, sns_key);
|
||||||
|
|
||||||
printf_spi("SPI command %02x;",packet_cmd.data_8[0]);
|
printf_spi("SPI command %02x;",packet_cmd.data_8[0]);
|
||||||
printf_spi("Params: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n",
|
printf_spi("Params: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x \n",
|
||||||
packet_cmd.data_8[0], packet_cmd.data_8[1], packet_cmd.data_8[2], packet_cmd.data_8[3], packet_cmd.data_8[4], packet_cmd.data_8[5],
|
packet_cmd.data_8[0], packet_cmd.data_8[1], packet_cmd.data_8[2], packet_cmd.data_8[3], packet_cmd.data_8[4], packet_cmd.data_8[5],
|
||||||
packet_cmd.data_8[6], packet_cmd.data_8[7], packet_cmd.data_8[8], packet_cmd.data_8[9], packet_cmd.data_8[10], packet_cmd.data_8[11] );
|
packet_cmd.data_8[6], packet_cmd.data_8[7], packet_cmd.data_8[8], packet_cmd.data_8[9], packet_cmd.data_8[10], packet_cmd.data_8[11] );
|
||||||
|
|
||||||
GDStatus.CHECK=0;
|
if (sns_key==0x0 || sns_key==0xB)
|
||||||
|
GDStatus.CHECK=0;
|
||||||
|
else
|
||||||
|
GDStatus.CHECK=1;
|
||||||
|
|
||||||
switch(packet_cmd.data_8[0])
|
switch(packet_cmd.data_8[0])
|
||||||
{
|
{
|
||||||
|
@ -672,18 +687,22 @@ void gd_process_spi_cmd()
|
||||||
|
|
||||||
case SPI_REQ_ERROR:
|
case SPI_REQ_ERROR:
|
||||||
printf_spicmd("SPI_REQ_ERROR\n");
|
printf_spicmd("SPI_REQ_ERROR\n");
|
||||||
printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_ERROR\n");
|
//printf("GDROM: Unhandled Sega SPI frame: SPI_REQ_ERROR\n");
|
||||||
|
|
||||||
u8 resp[10];
|
u8 resp[10];
|
||||||
resp[0]=0xF0;
|
resp[0]=0xF0;
|
||||||
resp[1]=0;
|
resp[1]=0;
|
||||||
resp[2]= SecNumber.Status==GD_BUSY ? 2:0;//sense
|
resp[2]=sns_key;//sense
|
||||||
resp[3]=0;
|
resp[3]=0;
|
||||||
resp[4]=resp[5]=resp[6]=resp[7]=0; //Command Specific Information
|
resp[4]=resp[5]=resp[6]=resp[7]=0; //Command Specific Information
|
||||||
resp[8]=0;//Additional Sense Code
|
resp[8]=sns_asc;//Additional Sense Code
|
||||||
resp[9]=0;//Additional Sense Code Qualifier
|
resp[9]=sns_ascq;//Additional Sense Code Qualifier
|
||||||
|
|
||||||
gd_spi_pio_end(resp,packet_cmd.data_8[4]);
|
gd_spi_pio_end(resp,packet_cmd.data_8[4]);
|
||||||
|
sns_key=0;
|
||||||
|
sns_asc=0;
|
||||||
|
sns_ascq=0;
|
||||||
|
//GDStatus.CHECK=0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPI_REQ_SES:
|
case SPI_REQ_SES:
|
||||||
|
@ -915,8 +934,8 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
|
||||||
if(2!=sz)
|
if(2!=sz)
|
||||||
printf("GDROM: Bad size on DATA REG Read\n");
|
printf("GDROM: Bad size on DATA REG Read\n");
|
||||||
|
|
||||||
if (gd_state == gds_pio_send_data)
|
//if (gd_state == gds_pio_send_data)
|
||||||
{
|
//{
|
||||||
if (pio_buff.index == pio_buff.size)
|
if (pio_buff.index == pio_buff.size)
|
||||||
{
|
{
|
||||||
printf("GDROM: Illegal Read From DATA (underflow)\n");
|
printf("GDROM: Illegal Read From DATA (underflow)\n");
|
||||||
|
@ -935,9 +954,9 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
printf("GDROM: Illegal Read From DATA (wrong mode)\n");
|
// printf("GDROM: Illegal Read From DATA (wrong mode)\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -947,6 +966,7 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
|
||||||
|
|
||||||
case GD_ERROR_Read:
|
case GD_ERROR_Read:
|
||||||
printf_rm("GDROM: Read from ERROR Register\n");
|
printf_rm("GDROM: Read from ERROR Register\n");
|
||||||
|
Error.Sense=sns_key;
|
||||||
return Error.full;
|
return Error.full;
|
||||||
|
|
||||||
case GD_IREASON_Read:
|
case GD_IREASON_Read:
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
|
||||||
Disc* chd_parse(wchar* file);
|
Disc* chd_parse(wchar* file);
|
||||||
Disc* gdi_parse(wchar* file);
|
Disc* gdi_parse(wchar* file);
|
||||||
Disc* cdi_parse(wchar* file);
|
Disc* cdi_parse(wchar* file);
|
||||||
|
@ -169,6 +168,10 @@ bool InitDrive(u32 fileflags)
|
||||||
if (gfrv == 0)
|
if (gfrv == 0)
|
||||||
{
|
{
|
||||||
NullDriveDiscType=NoDisk;
|
NullDriveDiscType=NoDisk;
|
||||||
|
gd_setdisc();
|
||||||
|
sns_asc=0x29;
|
||||||
|
sns_ascq=0x00;
|
||||||
|
sns_key=0x6;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (gfrv == -1)
|
else if (gfrv == -1)
|
||||||
|
@ -182,6 +185,11 @@ bool InitDrive(u32 fileflags)
|
||||||
if (!InitDrive_(fn))
|
if (!InitDrive_(fn))
|
||||||
{
|
{
|
||||||
//msgboxf("Selected image failed to load",MBX_ICONERROR);
|
//msgboxf("Selected image failed to load",MBX_ICONERROR);
|
||||||
|
NullDriveDiscType=NoDisk;
|
||||||
|
gd_setdisc();
|
||||||
|
sns_asc=0x29;
|
||||||
|
sns_ascq=0x00;
|
||||||
|
sns_key=0x6;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -190,6 +198,66 @@ bool InitDrive(u32 fileflags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TermDrive()
|
void TermDrive()
|
||||||
{
|
{
|
||||||
if (disc!=0)
|
if (disc!=0)
|
||||||
|
|
|
@ -82,6 +82,11 @@ bool ConvertSector(u8* in_buff , u8* out_buff , int from , int to,int sector);
|
||||||
|
|
||||||
bool InitDrive(u32 fileflags=0);
|
bool InitDrive(u32 fileflags=0);
|
||||||
void TermDrive();
|
void TermDrive();
|
||||||
|
bool DiscSwap(u32 fileflags=0);
|
||||||
|
extern signed int sns_asc;
|
||||||
|
extern signed int sns_ascq;
|
||||||
|
extern signed int sns_key;
|
||||||
|
|
||||||
|
|
||||||
void PatchRegion_0(u8* sector,int size);
|
void PatchRegion_0(u8* sector,int size);
|
||||||
void PatchRegion_6(u8* sector,int size);
|
void PatchRegion_6(u8* sector,int size);
|
||||||
|
@ -292,4 +297,6 @@ struct RawTrackFile : TrackFile
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DiscType GuessDiscType(bool m1, bool m2, bool da);
|
DiscType GuessDiscType(bool m1, bool m2, bool da);
|
||||||
|
|
||||||
|
extern void gd_setdisc()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "oslib\oslib.h"
|
#include "oslib\oslib.h"
|
||||||
#include "oslib\audiostream_rif.h"
|
#include "oslib\audiostream_rif.h"
|
||||||
|
#include "imgread\common.h"
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0500
|
#define _WIN32_WINNT 0x0500
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -229,6 +230,9 @@ void UpdateInputState(u32 port)
|
||||||
|
|
||||||
if (GetAsyncKeyState('2'))
|
if (GetAsyncKeyState('2'))
|
||||||
settings.pvr.ta_skip = 0;
|
settings.pvr.ta_skip = 0;
|
||||||
|
|
||||||
|
if (GetAsyncKeyState('0'))
|
||||||
|
DiscSwap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue