gdrom: fix cd_read2, req_error, req_stat and more

This commit is contained in:
Flyinghead 2020-06-17 22:58:26 +02:00
parent 15a99aeebe
commit 959b6344b3
9 changed files with 291 additions and 224 deletions

View File

@ -18,7 +18,6 @@ signed int sns_asc=0;
signed int sns_ascq=0;
signed int sns_key=0;
u32 set_mode_offset;
read_params_t read_params ;
packet_cmd_t packet_cmd ;
@ -63,7 +62,7 @@ GD_HardwareInfo_t GD_HardwareInfo;
void libCore_CDDA_Sector(s16* sector)
{
//silence ! :p
if (cdda.playing)
if (cdda.status == cdda_t::Playing)
{
libGDR_ReadSector((u8*)sector,cdda.CurrAddr.FAD,1,2352);
cdda.CurrAddr.FAD++;
@ -72,8 +71,8 @@ void libCore_CDDA_Sector(s16* sector)
if (cdda.repeats==0)
{
//stop
cdda.playing=false;
SecNumber.Status=GD_STANDBY;
cdda.status = cdda_t::Terminated;
SecNumber.Status = GD_PAUSE;
}
else
{
@ -98,13 +97,9 @@ static void FillReadBuffer()
{
read_buff.cache_index=0;
u32 count = read_params.remaining_sectors;
u32 hint=0;
if (count > 32)
{
hint = std::max(count - 32, (u32)32);
count = 32;
}
read_buff.cache_size=count*read_params.sector_type;
@ -250,7 +245,8 @@ void gd_set_state(gd_states state)
void gd_setdisc()
{
cdda.playing = false;
cdda.status = cdda_t::NoInfo;
DiscType newd = (DiscType)libGDR_GetDiscType();
switch(newd)
@ -264,7 +260,7 @@ void gd_setdisc()
case Open:
SecNumber.Status = GD_OPEN;
//GDStatus.BSY=0;
//GDStatus.DRDY=1;
GDStatus.DRDY=1;
break;
case Busy:
@ -293,23 +289,20 @@ void gd_setdisc()
SecNumber.DiscFormat=gd_disk_type>>4;
}
void gd_reset()
{
//Reset the drive
gd_setdisc();
gd_set_state(gds_waitcmd);
}
u32 GetFAD(u8* data, bool msf)
static u32 GetFAD(u8* data, bool msf)
{
if(msf)
{
INFO_LOG(GDROM, "GDROM: MSF FORMAT");
return ((data[0]*60*75) + (data[1]*75) + (data[2]));
}
if (msf)
return data[0] * 60 * 75 + data[1] * 75 + data[2];
else
{
return (data[0]<<16) | (data[1]<<8) | (data[2]);
}
return (data[0] << 16) | (data[1] << 8) | data[2];
}
//disk changes etc
@ -322,7 +315,7 @@ void libCore_gdrom_disc_change()
memset(&read_buff, 0, sizeof(read_buff));
pio_buff = { gds_waitcmd, 0 };
ata_cmd = { 0 };
cdda = { 0 };
cdda = { cdda_t::NoInfo, 0 };
}
//This handles the work of setting up the pio regs/state :)
@ -358,7 +351,9 @@ void gd_process_ata_cmd()
//Any ATA command clears these bits, unless aborted/error :p
Error.ABRT=0;
if (sns_key==0x0 || sns_key==0xB)
if (sns_key == 0x0 // No sense
|| sns_key == 0xB // Aborted
|| sns_key == 6) // Unit attention
GDStatus.CHECK=0;
else
GDStatus.CHECK=1;
@ -373,14 +368,11 @@ void gd_process_ata_cmd()
Clearing "busy" in the status register
Asserting the INTRQ signal
*/
//this is all very hacky, I don't know if the abort is correct actually
//the above comment is from a wrong place in the docs ...
Error.ABRT=1;
Error.Sense=sns_key;
GDStatus.BSY=0;
GDStatus.CHECK=1;
Error.ABRT = 1;
Error.Sense = sns_key;
GDStatus.BSY = 0;
GDStatus.CHECK = 1;
asic_RaiseInterrupt(holly_GDROM_CMD);
gd_set_state(gds_waitcmd);
@ -389,13 +381,27 @@ void gd_process_ata_cmd()
case ATA_SOFT_RESET:
{
printf_ata("ATA_SOFT_RESET");
//DRV -> preserved -> wtf is it anyway ?
gd_reset();
GDStatus.full = 0;
Error.full = 1;
sns_key = 0;
SecNumber.Status = GD_PAUSE;
IntReason.full = 1;
// DC Checker expects these values
ByteCount.low = 0x14;
ByteCount.hi = 0xEB;
}
break;
case ATA_EXEC_DIAG:
printf_ata("ATA_EXEC_DIAG -- not implemented");
printf_ata("ATA_EXEC_DIAG");
Error.full = 1; // No error
sns_key = 0;
GDStatus.BSY = 0;
GDStatus.CHECK = 1;
asic_RaiseInterrupt(holly_GDROM_CMD);
gd_set_state(gds_waitcmd);
break;
case ATA_SPI_PACKET:
@ -404,8 +410,9 @@ void gd_process_ata_cmd()
break;
case ATA_IDENTIFY_DEV:
printf_ata("ATA_IDENTIFY_DEV");
gd_spi_pio_end((const u8*)&reply_a1[packet_cmd.data_8[2] >> 1], packet_cmd.data_8[4]);
printf_ata("ATA_IDENTIFY_DEV: offset %d len %d", packet_cmd.data_8[2], packet_cmd.data_8[4]);
GDStatus.BSY = 0;
gd_spi_pio_end((const u8*)&reply_a1[0], 0x50);
break;
case ATA_SET_FEATURES:
@ -419,8 +426,8 @@ void gd_process_ata_cmd()
//DRDY is set on state change
GDStatus.DSC=0;
GDStatus.DF=0;
GDStatus.CHECK=0;
asic_RaiseInterrupt(holly_GDROM_CMD); //???
GDStatus.DRQ = 0;
asic_RaiseInterrupt(holly_GDROM_CMD);
gd_set_state(gds_waitcmd);
break;
@ -435,9 +442,6 @@ void gd_process_ata_cmd()
ByteCount.low = 0x14;
ByteCount.hi = 0xeb;
// where did this come from?
//GDStatus.DRQ = 0;
// ABORT command
Error.full = 0x4;
@ -458,46 +462,90 @@ void gd_process_ata_cmd()
u32 gd_get_subcode(u32 format, u32 fad, u8 *subc_info)
{
subc_info[0] = 0;
subc_info[1] = 0x15; // no audio status info
if (format == 0)
switch (cdda.status)
{
case cdda_t::NoInfo:
default:
subc_info[1] = 0x15; // No audio status info
break;
case cdda_t::Playing:
subc_info[1] = 0x11; // Audio playback in progress
break;
case cdda_t::Paused:
subc_info[1] = 0x12; // Audio playback paused
break;
case cdda_t::Terminated:
subc_info[1] = 0x13; // Audio playback ended normally
break;
}
switch (format)
{
case 0: // Raw subcode
subc_info[2] = 0;
subc_info[3] = 100;
libGDR_ReadSubChannel(subc_info + 4, 0, 100 - 4);
}
else
{
u32 elapsed;
u32 tracknum = libGDR_GetTrackNumber(fad, elapsed);
break;
//2 DATA Length MSB (0 = 0h)
subc_info[2] = 0;
//3 DATA Length LSB (14 = Eh)
subc_info[3] = 0xE;
//4 Control ADR
subc_info[4] = (SecNumber.DiscFormat == 0 ? 0 : 0x40) | 1; // Control = 4 for data track
//5-13 DATA-Q
u8* data_q = &subc_info[5 - 1];
//-When ADR = 1
//1 TNO - track number
data_q[1] = tracknum;
//2 X - index within track
data_q[2] = 1;
//3-5 Elapsed FAD within track
data_q[3] = elapsed >> 16;
data_q[4] = elapsed >> 8;
data_q[5] = elapsed;
//6 ZERO
data_q[6] = 0;
//7-9 FAD
data_q[7] = fad >> 16;
data_q[8] = fad >> 8;
data_q[9] = fad;
DEBUG_LOG(GDROM, "gd_get_subcode: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
subc_info[0], subc_info[1], subc_info[2], subc_info[3],
subc_info[4], subc_info[5], subc_info[6], subc_info[7],
subc_info[8], subc_info[9], subc_info[10], subc_info[11],
subc_info[12], subc_info[13]);
case 1: // Q data only
default:
{
u32 elapsed;
u32 tracknum = libGDR_GetTrackNumber(fad, elapsed);
//2 DATA Length MSB (0 = 0h)
subc_info[2] = 0;
//3 DATA Length LSB (14 = Eh)
subc_info[3] = 0xE;
//4 Control ADR
subc_info[4] = (SecNumber.DiscFormat == 0 ? 0 : 0x40) | 1; // Control = 4 for data track
//5-13 DATA-Q
u8* data_q = &subc_info[5 - 1];
//-When ADR = 1
//1 TNO - track number
data_q[1] = tracknum;
//2 X - index within track
data_q[2] = 1;
//3-5 Elapsed FAD within track
data_q[3] = elapsed >> 16;
data_q[4] = elapsed >> 8;
data_q[5] = elapsed;
//6 ZERO
data_q[6] = 0;
//7-9 FAD
data_q[7] = fad >> 16;
data_q[8] = fad >> 8;
data_q[9] = fad;
DEBUG_LOG(GDROM, "gd_get_subcode: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
subc_info[0], subc_info[1], subc_info[2], subc_info[3],
subc_info[4], subc_info[5], subc_info[6], subc_info[7],
subc_info[8], subc_info[9], subc_info[10], subc_info[11],
subc_info[12], subc_info[13]);
}
break;
case 2: // Media catalog number (UPC/bar code)
{
//2 DATA Length MSB (0 = 0h)
subc_info[2] = 0;
//3 DATA Length LSB (24 = 18h)
subc_info[3] = 0x18;
//4 Format Code
subc_info[4] = 2;
//5-7 reserved
subc_info[5] = 0;
subc_info[6] = 0;
subc_info[7] = 0;
//8 MCVal (bit 7)
subc_info[8] = 0; // not valid
//9-21 Media catalog number
memcpy(&subc_info[9], "0000000000000", 13);
//22-23 reserved
subc_info[22] = 0;
subc_info[23] = 0;
DEBUG_LOG(GDROM, "gd_get_subcode: format 2 (Media catalog number). audio %x", subc_info[1]);
}
break;
}
return subc_info[3];
}
@ -512,7 +560,9 @@ void gd_process_spi_cmd()
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] );
if (sns_key==0x0 || sns_key==0xB)
if (sns_key == 0x0 // No sense
|| sns_key == 0xB // Aborted
|| sns_key == 6) // Unit attention
GDStatus.CHECK=0;
else
GDStatus.CHECK=1;
@ -523,23 +573,30 @@ void gd_process_spi_cmd()
printf_spicmd("SPI_TEST_UNIT");
GDStatus.CHECK=SecNumber.Status==GD_BUSY; // Drive is ready ;)
cdda.playing = false;
gd_set_state(gds_procpacketdone);
break;
case SPI_REQ_MODE:
printf_spicmd("SPI_REQ_MODE");
GD_HardwareInfo.speed = 0; // doesn't seem to be settable, or perhaps not for GD-Roms
GD_HardwareInfo._res0[0] = 0;
GD_HardwareInfo._res0[1] = 0;
GD_HardwareInfo._res1 = 0;
GD_HardwareInfo._res2[0] = 0;
GD_HardwareInfo._res2[1] = 0;
GD_HardwareInfo.read_flags &= 0x39;
printf_spicmd("SPI_REQ_MODE cd-rom speed %d flags %x retry %x", GD_HardwareInfo.speed, GD_HardwareInfo.read_flags, GD_HardwareInfo.read_retry);
gd_spi_pio_end((u8*)&GD_HardwareInfo + packet_cmd.data_8[2], packet_cmd.data_8[4]);
break;
/////////////////////////////////////////////////
// *FIXME* CHECK FOR DMA, Diff Settings !?!@$#!@%
case SPI_CD_READ:
case SPI_CD_READ2:
{
#define readcmd packet_cmd.GDReadBlock
cdda.playing = false;
cdda.status = cdda_t::NoInfo;
u32 sector_type=2048;
if (readcmd.head ==1 && readcmd.subh==1 && readcmd.data==1 && readcmd.expdtype==3 && readcmd.other==0)
sector_type=2340;
@ -547,7 +604,10 @@ void gd_process_spi_cmd()
WARN_LOG(GDROM, "GDROM: *FIXME* ADD MORE CD READ SETTINGS %d %d %d %d 0x%01X",readcmd.head,readcmd.subh,readcmd.other,readcmd.data,readcmd.expdtype);
read_params.start_sector = GetFAD(&readcmd.b[2], readcmd.prmtype);
read_params.remaining_sectors = (readcmd.b[8] << 16) | (readcmd.b[9] << 8) | (readcmd.b[10]);
if (packet_cmd.data_8[0] == SPI_CD_READ)
read_params.remaining_sectors = (readcmd.b[8] << 16) | (readcmd.b[9] << 8) | (readcmd.b[10]);
else
read_params.remaining_sectors = (readcmd.b[6] << 8) | readcmd.b[7];
read_params.sector_type = sector_type;//yeah i know , not really many types supported...
printf_spicmd("SPI_CD_READ - Sector=%d Size=%d/%d DMA=%d",read_params.start_sector,read_params.remaining_sectors,read_params.sector_type,Features.CDRead.DMA);
@ -611,24 +671,18 @@ void gd_process_spi_cmd()
{
printf_spicmd("SPI_SET_MODE");
u32 Offset = packet_cmd.data_8[2];
u32 Count = packet_cmd.data_8[4];
verify((Offset+Count)<11); //cant set write olny things :P
u32 Count = std::min((u32)packet_cmd.data_8[4], 10 - Offset); // limit to writable area
set_mode_offset=Offset;
gd_spi_pio_read_end(Count,gds_process_set_mode);
}
break;
case SPI_CD_READ2:
printf_spicmd("SPI_CD_READ2 Unhandled");
gd_set_state(gds_procpacketdone);
break;
case SPI_REQ_STAT:
{
printf_spicmd("SPI_REQ_STAT");
u32 elapsed;
u32 tracknum = libGDR_GetTrackNumber(cdda.CurrAddr.FAD, elapsed);
u8 stat[10];
//0 0 0 0 0 STATUS
@ -636,11 +690,11 @@ void gd_process_spi_cmd()
//1 Disc Format Repeat Count
stat[1]=(u8)(SecNumber.DiscFormat<<4) | (cdda.repeats);
//2 Address Control
stat[2]=0x4;
stat[2] = (SecNumber.DiscFormat == 0 ? 0 : 0x40) | 1; // Control = 4 for data track
//3 TNO
stat[3]=2;
stat[3] = tracknum;
//4 X
stat[4]=0;
stat[4] = 1;
//5 FAD
stat[5]=cdda.CurrAddr.B0;
//6 FAD
@ -659,31 +713,34 @@ void gd_process_spi_cmd()
break;
case SPI_REQ_ERROR:
printf_spicmd("SPI_REQ_ERROR");
u8 resp[10];
resp[0]=0xF0;
resp[1]=0;
resp[2]=sns_key;//sense
resp[3]=0;
resp[4]=resp[5]=resp[6]=resp[7]=0; //Command Specific Information
resp[8]=sns_asc;//Additional Sense Code
resp[9]=sns_ascq;//Additional Sense Code Qualifier
{
printf_spicmd("SPI_REQ_ERROR");
u8 resp[10];
resp[0]=0xF0;
resp[1]=0;
resp[2]=sns_key;//sense
resp[3]=0;
resp[4]=resp[5]=resp[6]=resp[7]=0; //Command Specific Information
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;
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:
printf_spicmd("SPI_REQ_SES");
{
printf_spicmd("SPI_REQ_SES");
u8 ses_inf[6];
libGDR_GetSessionInfo(ses_inf,packet_cmd.data_8[2]);
ses_inf[0]=SecNumber.Status;
gd_spi_pio_end((u8*)&ses_inf[0],packet_cmd.data_8[4]);
u8 ses_inf[6];
libGDR_GetSessionInfo(ses_inf,packet_cmd.data_8[2]);
ses_inf[0]=SecNumber.Status;
gd_spi_pio_end((u8*)&ses_inf[0],packet_cmd.data_8[4]);
}
break;
case SPI_CD_OPEN:
@ -694,45 +751,50 @@ void gd_process_spi_cmd()
case SPI_CD_PLAY:
{
printf_spicmd("SPI_CD_PLAY");
//cdda.CurrAddr.FAD=60000;
const u32 param_type = packet_cmd.data_8[1] & 7;
printf_spicmd("SPI_CD_PLAY param_type=%d", param_type);
cdda.playing=true;
SecNumber.Status=GD_PLAY;
if (param_type == 1 || param_type == 2)
{
cdda.status = cdda_t::Playing;
SecNumber.Status = GD_PLAY;
u32 param_type=packet_cmd.data_8[1]&0x7;
DEBUG_LOG(GDROM, "param_type=%d", param_type);
if (param_type==1)
{
cdda.StartAddr.FAD=cdda.CurrAddr.FAD=GetFAD(&packet_cmd.data_8[2],0);
cdda.EndAddr.FAD=GetFAD(&packet_cmd.data_8[8],0);
GDStatus.DSC=1; //we did the seek xD lol
}
else if (param_type==2)
{
cdda.StartAddr.FAD=cdda.CurrAddr.FAD=GetFAD(&packet_cmd.data_8[2],1);
cdda.EndAddr.FAD=GetFAD(&packet_cmd.data_8[8],1);
GDStatus.DSC=1; //we did the seek xD lol
}
else if (param_type==7)
{
// Resume from previous pos unless we're at the end
if (cdda.CurrAddr.FAD > cdda.EndAddr.FAD)
bool min_sec_frame = param_type == 2;
cdda.StartAddr.FAD = cdda.CurrAddr.FAD = GetFAD(&packet_cmd.data_8[2], min_sec_frame);
cdda.EndAddr.FAD = GetFAD(&packet_cmd.data_8[8], min_sec_frame);
if (cdda.EndAddr.FAD == 0)
{
cdda.playing = false;
SecNumber.Status = GD_STANDBY;
// Get the last sector of the disk
u8 ses_inf[6] = {};
libGDR_GetSessionInfo(ses_inf, 0);
cdda.EndAddr.FAD = ses_inf[3] << 16 | ses_inf[4] << 8 | ses_inf[5];
}
cdda.repeats = packet_cmd.data_8[6] & 0xF;
GDStatus.DSC = 1;
}
else if (param_type == 7)
{
if (cdda.status == cdda_t::Paused)
{
// Resume from previous pos unless we're at the end
if (cdda.CurrAddr.FAD > cdda.EndAddr.FAD)
{
cdda.status = cdda_t::Terminated;
SecNumber.Status = GD_STANDBY;
}
else
{
cdda.status = cdda_t::Playing;
SecNumber.Status = GD_PLAY;
}
}
}
else
{
die("SPI_CD_PLAY : not known parameter..");
}
cdda.repeats=packet_cmd.data_8[6]&0xF;
DEBUG_LOG(GDROM, "cdda.StartAddr=%d",cdda.StartAddr.FAD);
DEBUG_LOG(GDROM, "cdda.EndAddr=%d",cdda.EndAddr.FAD);
DEBUG_LOG(GDROM, "cdda.repeats=%d",cdda.repeats);
DEBUG_LOG(GDROM, "cdda.playing=%d",cdda.playing);
DEBUG_LOG(GDROM, "cdda.CurrAddr=%d",cdda.CurrAddr.FAD);
die("SPI_CD_PLAY: unknown parameter");
DEBUG_LOG(GDROM, "CDDA StartAddr=%d EndAddr=%d repeats=%d status=%d CurrAddr=%d",cdda.StartAddr.FAD,
cdda.EndAddr.FAD, cdda.repeats, cdda.status, cdda.CurrAddr.FAD);
gd_set_state(gds_procpacketdone);
}
@ -740,45 +802,48 @@ void gd_process_spi_cmd()
case SPI_CD_SEEK:
{
printf_spicmd("SPI_CD_SEEK");
const u32 param_type = packet_cmd.data_8[1] & 7;
printf_spicmd("SPI_CD_SEEK param_type=%d", param_type);
SecNumber.Status=GD_PAUSE;
cdda.playing=false;
SecNumber.Status = GD_PAUSE;
if (cdda.status == cdda_t::Playing)
cdda.status = cdda_t::Paused;
u32 param_type=packet_cmd.data_8[1]&0x7;
DEBUG_LOG(GDROM, "param_type=%d",param_type);
if (param_type==1)
if (param_type == 1 || param_type == 2)
{
cdda.StartAddr.FAD=cdda.CurrAddr.FAD=GetFAD(&packet_cmd.data_8[2],0);
GDStatus.DSC=1; //we did the seek xD lol
bool min_sec_frame = param_type == 2;
cdda.StartAddr.FAD = cdda.CurrAddr.FAD = GetFAD(&packet_cmd.data_8[2], min_sec_frame);
#ifdef STRICT_MODE
SecNumber.Status = GD_SEEK;
GDStatus.DSC = 0;
sh4_sched_request(gdrom_schid, SH4_MAIN_CLOCK / 50); // 20 ms
#else
GDStatus.DSC = 1;
#endif
}
else if (param_type==2)
{
cdda.StartAddr.FAD=cdda.CurrAddr.FAD=GetFAD(&packet_cmd.data_8[2],1);
GDStatus.DSC=1; //we did the seek xD lol
}
else if (param_type==3)
else if (param_type == 3)
{
//stop audio , goto home
SecNumber.Status=GD_STANDBY;
cdda.StartAddr.FAD=cdda.CurrAddr.FAD=150;
GDStatus.DSC=1; //we did the seek xD lol
cdda.StartAddr.FAD = cdda.CurrAddr.FAD = 150;
cdda.status = cdda_t::NoInfo;
#ifdef STRICT_MODE
SecNumber.Status = GD_BUSY;
GDStatus.DSC = 0;
sh4_sched_request(gdrom_schid, SH4_MAIN_CLOCK / 50); // 20 ms
#else
SecNumber.Status = GD_STANDBY;
GDStatus.DSC = 1;
#endif
}
else if (param_type==4)
else if (param_type == 4)
{
//pause audio -- nothing more
}
else
{
die("SPI_CD_SEEK : not known parameter..");
}
DEBUG_LOG(GDROM, "cdda.StartAddr=%d",cdda.StartAddr.FAD);
DEBUG_LOG(GDROM, "cdda.EndAddr=%d",cdda.EndAddr.FAD);
DEBUG_LOG(GDROM, "cdda.repeats=%d",cdda.repeats);
DEBUG_LOG(GDROM, "cdda.playing=%d",cdda.playing);
DEBUG_LOG(GDROM, "cdda.CurrAddr=%d",cdda.CurrAddr.FAD);
DEBUG_LOG(GDROM, "CDDA StartAddr=%d EndAddr=%d repeats=%d status=%d CurrAddr=%d",cdda.StartAddr.FAD,
cdda.EndAddr.FAD, cdda.repeats, cdda.status, cdda.CurrAddr.FAD);
gd_set_state(gds_procpacketdone);
}
@ -795,16 +860,20 @@ void gd_process_spi_cmd()
{
printf_spicmd("SPI_GET_SCD");
u32 format = packet_cmd.data_8[1] & 0xF;
const u32 format = packet_cmd.data_8[1] & 0xF;
const u32 alloc_len = (packet_cmd.data_8[3] << 8) | packet_cmd.data_8[4];
u8 subc_info[100];
u32 size = gd_get_subcode(format, read_params.start_sector - 1, subc_info);
gd_spi_pio_end(subc_info, size);
gd_spi_pio_end(subc_info, std::min(size, alloc_len));
}
break;
default:
INFO_LOG(GDROM, "GDROM: Unhandled Sega SPI frame: %X", packet_cmd.data_8[0]);
GDStatus.CHECK = 1;
sns_key = 5; // Illegal request
sns_asc = 0x20; // Unsupported command was received
sns_ascq = 0;
gd_set_state(gds_procpacketdone);
break;
}
@ -818,11 +887,11 @@ u32 ReadMem_gdrom(u32 Addr, u32 sz)
case GD_STATUS_Read :
asic_CancelInterrupt(holly_GDROM_CMD); //Clear INTRQ signal
printf_rm("GDROM: STATUS [cancel int](v=%X)",GDStatus.full);
return GDStatus.full | (1<<4);
return GDStatus.full;
case GD_ALTSTAT_Read:
// printf_rm("GDROM: Read From AltStatus (v=%X)",GDStatus.full);
return GDStatus.full | (1<<4);
//printf_rm("GDROM: AltStatus (v=%X)",GDStatus.full);
return GDStatus.full;
case GD_BYCTLLO :
printf_rm("GDROM: Read From GD_BYCTLLO");
@ -991,11 +1060,19 @@ static int getGDROMTicks()
//is this needed ?
int GDRomschd(int i, int c, int j)
{
if (SecNumber.Status == GD_SEEK)
{
SecNumber.Status = GD_PAUSE;
GDStatus.DSC = 1;
}
else if (SecNumber.Status == GD_BUSY)
{
SecNumber.Status = GD_STANDBY;
GDStatus.DSC = 1;
}
if(!(SB_GDST&1) || !(SB_GDEN &1) || (read_buff.cache_size==0 && read_params.remaining_sectors==0))
return 0;
//SB_GDST=0;
//TODO : Fix dmaor
u32 dmaor = DMAC_DMAOR.full;

View File

@ -200,7 +200,7 @@ struct ata_cmd_t
struct cdda_t
{
bool playing;
enum { NoInfo, Playing, Paused, Terminated } status;
u32 repeats;
union
{

View File

@ -144,6 +144,8 @@ Disc* load_gdi(const char* file)
std::string path = basepath + normalize_path_separator(track_filename);
t.file = new RawTrackFile(core_fopen(path.c_str()),OFFSET,t.StartFAD,SSIZE);
}
if (!disc->tracks.empty())
disc->tracks.back().EndFAD = t.StartFAD - 1;
disc->tracks.push_back(t);
}

View File

@ -13,45 +13,32 @@
static unsigned int seed;
void my_srand(unsigned int n)
static void my_srand(unsigned int n)
{
seed = n & 0xffff;
}
unsigned int my_rand()
static unsigned int my_rand()
{
seed = (seed * 2109 + 9273) & 0x7fff;
return (seed + 0xc000) & 0xffff;
}
/*
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
{
if (fread(ptr, 1, sz, fh) != sz)
{
fprintf(stderr, "Read error!\n");
exit(1);
}
}
*/
void load_chunk(u8* &src, unsigned char *ptr, unsigned long sz)
static void load_chunk(u8* &src, unsigned char *ptr, unsigned long sz)
{
verify(sz <= MAXCHUNK);
static int idx[MAXCHUNK / 32];
int i;
/* Convert chunk size to number of slices */
sz /= 32;
/* Initialize index table with unity,
so that each slice gets loaded exactly once */
for (i = 0; i < sz; i++)
for (u32 i = 0; i < sz; i++)
idx[i] = i;
for (i = sz - 1; i >= 0; --i)
for (int i = sz - 1; i >= 0; --i)
{
/* Select a replacement index */
int x = (my_rand() * i) >> 16;
@ -59,20 +46,13 @@ void load_chunk(u8* &src, unsigned char *ptr, unsigned long sz)
/* Swap */
std::swap(idx[i], idx[x]);
/*
int tmp = idx[i];
idx[i] = idx[x];
idx[x] = tmp;
*/
/* Load resulting slice */
//load(fh, ptr + 32 * idx[i], 32);
memcpy(ptr + 32 * idx[i], src, 32);
src += 32;
}
}
void descrambl_buffer(u8* src, unsigned char *dst, unsigned long filesz)
static void descrambl_buffer(u8* src, unsigned char *dst, unsigned long filesz)
{
unsigned long chunksz;
@ -100,4 +80,4 @@ void descrambl_file(u32 FAD, u32 file_size, u8* dst) {
descrambl_buffer(temp_file, dst, file_size);
delete[] temp_file;
}
}

View File

@ -1,8 +1,4 @@
#ifndef DESCRAMBL_H
#define DESCRAMBL_H
#pragma once
#include "types.h"
void descrambl_file(u32 FAD, u32 file_size, u8* dst);
#endif //DESCRAMBL_H

View File

@ -167,7 +167,7 @@ static void GDCC_HLE_GETSCD() {
sns_ascq = 0;
return;
}
if (cdda.playing)
if (cdda.status == cdda_t::Playing)
gd_hle_state.cur_sector = cdda.CurrAddr.FAD;
u8 scd[100];
gd_get_subcode(format, gd_hle_state.cur_sector, scd);
@ -283,17 +283,17 @@ static void GD_HLE_Command(u32 cc)
DEBUG_LOG(REIOS, "GDROM: CMD INIT");
gd_hle_state.multi_callback = 0;
gd_hle_state.multi_read_count = 0;
cdda.playing = false;
cdda.status = cdda_t::NoInfo;
break;
case GDCC_PIOREAD:
GDROM_HLE_ReadPIO();
SecNumber.Status = GD_STANDBY;
cdda.playing = false;
cdda.status = cdda_t::NoInfo;
break;
case GDCC_DMAREAD:
cdda.playing = false;
cdda.status = cdda_t::NoInfo;
if (gd_hle_state.xfer_end_time == 0)
GDROM_HLE_ReadDMA();
if (gd_hle_state.xfer_end_time > 0)
@ -313,7 +313,7 @@ static void GD_HLE_Command(u32 cc)
u32 start_fad = gd_hle_state.params[0];
u32 end_fad = gd_hle_state.params[1];
DEBUG_LOG(REIOS, "GDROM: CMD PLAYSEC from %d to %d repeats %d", start_fad, end_fad, gd_hle_state.params[2]);
cdda.playing = true;
cdda.status = cdda_t::Playing;
cdda.StartAddr.FAD = start_fad;
cdda.EndAddr.FAD = end_fad;
cdda.repeats = gd_hle_state.params[2];
@ -324,19 +324,20 @@ static void GD_HLE_Command(u32 cc)
case GDCC_RELEASE:
DEBUG_LOG(REIOS, "GDROM: CMD RELEASE");
cdda.playing = true;
if (cdda.status == cdda_t::Paused)
cdda.status = cdda_t::Playing;
SecNumber.Status = GD_PLAY;
break;
case GDCC_STOP:
DEBUG_LOG(REIOS, "GDROM: CMD STOP");
cdda.playing = false;
cdda.status = cdda_t::NoInfo;
SecNumber.Status = GD_STANDBY;
break;
case GDCC_SEEK:
DEBUG_LOG(REIOS, "GDROM: CMD SEEK");
cdda.playing = false;
cdda.status = cdda_t::Paused;
SecNumber.Status = GD_PAUSE;
break;
@ -350,7 +351,7 @@ static void GD_HLE_Command(u32 cc)
libGDR_GetTrack(last_track, dummy, end_fad);
DEBUG_LOG(REIOS, "GDROM: CMD PLAY first_track %x last_track %x repeats %x start_fad %x end_fad %x param4 %x", first_track, last_track, repeats,
start_fad, end_fad, gd_hle_state.params[3]);
cdda.playing = true;
cdda.status = cdda_t::Playing;
cdda.StartAddr.FAD = start_fad;
cdda.EndAddr.FAD = end_fad;
cdda.repeats = repeats;
@ -362,7 +363,8 @@ static void GD_HLE_Command(u32 cc)
case GDCC_PAUSE:
DEBUG_LOG(REIOS, "GDROM: CMD PAUSE");
cdda.playing = false;
if (cdda.status == cdda_t::Playing)
cdda.status = cdda_t::Paused;
SecNumber.Status = GD_PAUSE;
break;
@ -476,8 +478,8 @@ static void GD_HLE_Command(u32 cc)
// 0-2 | fad (little-endian)
// ------------------------------------------------------
// 3 | address | control
// FIXME address/control
u32 out = ((0x4) << 28) | ((0x1) << 24) | (gd_hle_state.cur_sector & 0x00ffffff);
u32 out = (((SecNumber.DiscFormat == 0 ? 0 : 0x40) | 1) << 24)
| (gd_hle_state.cur_sector & 0x00ffffff);
WriteMem32(dst2, out);
// bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
@ -571,7 +573,7 @@ void gdrom_hle_op()
}
}
memset(gd_hle_state.result, 0, sizeof(gd_hle_state.result));
if (gd_hle_state.next_request_id == -1 || gd_hle_state.next_request_id == 0)
if (gd_hle_state.next_request_id == ~0u || gd_hle_state.next_request_id == 0)
gd_hle_state.next_request_id = 1;
gd_hle_state.last_request_id = r[0] = gd_hle_state.next_request_id++;
gd_hle_state.status = BIOS_ACTIVE;

View File

@ -277,7 +277,7 @@ bool dc_serialize(void **data, unsigned int *total_size)
{
int i = 0;
serialize_version_enum version = V9;
serialize_version_enum version = V10;
*total_size = 0 ;
@ -396,6 +396,7 @@ bool dc_serialize(void **data, unsigned int *total_size)
register_serialize(SCI, data, total_size) ;
register_serialize(SCIF, data, total_size) ;
icache.Serialize(data, total_size);
ocache.Serialize(data, total_size);
REICAST_SA(mem_b.data, mem_b.size);
@ -616,6 +617,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size)
REICAST_US(set_mode_offset);
REICAST_US(ata_cmd);
REICAST_US(cdda);
cdda.status = (bool)cdda.status ? cdda_t::Playing : cdda_t::NoInfo;
REICAST_US(gd_state);
REICAST_US(gd_disk_type);
REICAST_US(data_write_mode);
@ -669,6 +671,7 @@ static bool dc_unserialize_libretro(void **data, unsigned int *total_size)
register_unserialize(SCI, data, total_size, V9_LIBRETRO) ;
register_unserialize(SCIF, data, total_size, V9_LIBRETRO) ;
icache.Reset(true);
ocache.Reset(true);
REICAST_USA(mem_b.data, mem_b.size);
REICAST_USA(InterruptEnvId,32);
@ -912,6 +915,8 @@ bool dc_unserialize(void **data, unsigned int *total_size)
REICAST_US(set_mode_offset);
REICAST_US(ata_cmd);
REICAST_US(cdda);
if (version < V10)
cdda.status = (bool)cdda.status ? cdda_t::Playing : cdda_t::NoInfo;
REICAST_US(gd_state);
REICAST_US(gd_disk_type);
REICAST_US(data_write_mode);
@ -998,6 +1003,10 @@ bool dc_unserialize(void **data, unsigned int *total_size)
icache.Unserialize(data, total_size);
else
icache.Reset(true);
if (version >= V10)
ocache.Unserialize(data, total_size);
else
ocache.Reset(true);
REICAST_USA(mem_b.data, mem_b.size);

View File

@ -606,4 +606,5 @@ enum serialize_version_enum {
V7 = 802,
V8 = 803,
V9 = 804,
V10 = 805,
} ;

View File

@ -28,7 +28,7 @@ TEST_F(SerializeTest, SizeTest)
unsigned int total_size = 0;
void *data = nullptr;
ASSERT_TRUE(dc_serialize(&data, &total_size));
ASSERT_EQ(28124715u, total_size);
ASSERT_EQ(28145195u, total_size);
}