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:
MrPsyMan 2014-03-15 13:42:17 +02:00
parent e6ac0e4918
commit 6b4deb4b16
4 changed files with 113 additions and 14 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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()

View File

@ -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();
} }