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;
//Sense: ASC - ASCQ - Key
signed int sns_asc=0;
signed int sns_ascq=0;
signed int sns_key=0;
enum gd_states
{
//Generic
@ -447,7 +452,11 @@ void gd_process_ata_cmd()
{
//Any ATA command clears these bits, unless aborted/error :p
Error.ABRT=0;
GDStatus.CHECK=0;
if (sns_key==0x0 || sns_key==0xB)
GDStatus.CHECK=0;
else
GDStatus.CHECK=1;
switch(ata_cmd.command)
{
@ -464,7 +473,7 @@ void gd_process_ata_cmd()
//the above comment is from a wrong place in the docs ...
Error.ABRT=1;
//Error.Sense=0x00; //fixme ?
Error.Sense=sns_key;
GDStatus.BSY=0;
GDStatus.CHECK=1;
@ -519,12 +528,18 @@ void gd_process_ata_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("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[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])
{
@ -672,18 +687,22 @@ void gd_process_spi_cmd()
case SPI_REQ_ERROR:
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];
resp[0]=0xF0;
resp[1]=0;
resp[2]= SecNumber.Status==GD_BUSY ? 2:0;//sense
resp[2]=sns_key;//sense
resp[3]=0;
resp[4]=resp[5]=resp[6]=resp[7]=0; //Command Specific Information
resp[8]=0;//Additional Sense Code
resp[9]=0;//Additional Sense Code Qualifier
resp[8]=sns_asc;//Additional Sense Code
resp[9]=sns_ascq;//Additional Sense Code Qualifier
gd_spi_pio_end(resp,packet_cmd.data_8[4]);
sns_key=0;
sns_asc=0;
sns_ascq=0;
//GDStatus.CHECK=0;
break;
case SPI_REQ_SES:
@ -915,8 +934,8 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
if(2!=sz)
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)
{
printf("GDROM: Illegal Read From DATA (underflow)\n");
@ -935,9 +954,9 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
return rv;
}
}
else
printf("GDROM: Illegal Read From DATA (wrong mode)\n");
//}
//else
// printf("GDROM: Illegal Read From DATA (wrong mode)\n");
return 0;
@ -947,6 +966,7 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
case GD_ERROR_Read:
printf_rm("GDROM: Read from ERROR Register\n");
Error.Sense=sns_key;
return Error.full;
case GD_IREASON_Read:

View File

@ -1,6 +1,5 @@
#include "common.h"
Disc* chd_parse(wchar* file);
Disc* gdi_parse(wchar* file);
Disc* cdi_parse(wchar* file);
@ -169,6 +168,10 @@ bool InitDrive(u32 fileflags)
if (gfrv == 0)
{
NullDriveDiscType=NoDisk;
gd_setdisc();
sns_asc=0x29;
sns_ascq=0x00;
sns_key=0x6;
return true;
}
else if (gfrv == -1)
@ -182,6 +185,11 @@ bool InitDrive(u32 fileflags)
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
@ -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()
{
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);
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_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\audiostream_rif.h"
#include "imgread\common.h"
#define _WIN32_WINNT 0x0500
#include <windows.h>
@ -229,6 +230,9 @@ void UpdateInputState(u32 port)
if (GetAsyncKeyState('2'))
settings.pvr.ta_skip = 0;
if (GetAsyncKeyState('0'))
DiscSwap();
}