gdrom: fix cdda restart. revert previous change. fix hle pause/release

Revert changes from Issue #690
Fixes cdda restart in Mr.Driller, Bust-a-move 4, Wetrix+ and Reel
fishing. Issue #1019
hle: returning current cdda information fixes the pause/release issue
This commit is contained in:
Flyinghead 2023-05-16 14:33:33 +02:00
parent c07f862ef2
commit e5344d37d0
9 changed files with 73 additions and 48 deletions

View file

@ -553,7 +553,9 @@ u32 gd_get_subcode(u32 format, u32 fad, u8 *subc_info)
u32 elapsed;
u32 tracknum = libGDR_GetTrackNumber(curFad, elapsed);
u8 Qch[12];
Qch[0] = (SecNumber.DiscFormat == 0 ? 0 : 0x40) | 1;
u8 adr, ctrl;
libGDR_GetTrackAdrAndControl(tracknum, adr, ctrl);
Qch[0] = (ctrl << 4) | adr;
Qch[1] = bin2bcd(tracknum);
Qch[2] = bin2bcd(1); // index
Qch[3] = bin2bcd(elapsed / 60 / 75); // min
@ -578,15 +580,18 @@ u32 gd_get_subcode(u32 format, u32 fad, u8 *subc_info)
case 1: // Q data only
default:
{
u32 curFad = cdda.status == cdda_t::Playing || cdda.status == cdda_t::Paused ? cdda.CurrAddr.FAD : fad;
u32 elapsed;
u32 tracknum = libGDR_GetTrackNumber(fad, elapsed);
u32 tracknum = libGDR_GetTrackNumber(curFad, 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
u8 adr, ctrl;
libGDR_GetTrackAdrAndControl(tracknum, adr, ctrl);
subc_info[4] = (ctrl << 4) | adr;
//5-13 DATA-Q
u8* data_q = &subc_info[5 - 1];
//-When ADR = 1
@ -601,9 +606,9 @@ u32 gd_get_subcode(u32 format, u32 fad, u8 *subc_info)
//6 ZERO
data_q[6] = 0;
//7-9 FAD
data_q[7] = fad >> 16;
data_q[8] = fad >> 8;
data_q[9] = fad;
data_q[7] = curFad >> 16;
data_q[8] = curFad >> 8;
data_q[9] = curFad;
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],
@ -768,34 +773,37 @@ void gd_process_spi_cmd()
case SPI_REQ_STAT:
{
printf_spicmd("SPI_REQ_STAT");
u32 curFad = cdda.status == cdda_t::Playing || cdda.status == cdda_t::Paused ? cdda.CurrAddr.FAD : read_params.start_sector - 1;
u32 elapsed;
u32 tracknum = libGDR_GetTrackNumber(cdda.CurrAddr.FAD, elapsed);
u32 tracknum = libGDR_GetTrackNumber(curFad, elapsed);
u8 stat[10];
//0 0 0 0 0 STATUS
stat[0]=SecNumber.Status; //low nibble
stat[0] = SecNumber.Status; //low nibble
//1 Disc Format Repeat Count
stat[1]=(u8)(SecNumber.DiscFormat<<4) | (cdda.repeats);
//2 Address Control
stat[2] = (SecNumber.DiscFormat == 0 ? 0 : 0x40) | 1; // Control = 4 for data track
//3 TNO
stat[1] = (u8)(SecNumber.DiscFormat << 4) | cdda.repeats;
//2 Control ADR
u8 adr, ctrl;
libGDR_GetTrackAdrAndControl(tracknum, adr, ctrl);
stat[2] = (ctrl << 4) | adr;
//3 Track #
stat[3] = tracknum;
//4 X
//4 Index #
stat[4] = 1;
//5 FAD
stat[5]=cdda.CurrAddr.B0;
stat[5] = curFad >> 16;
//6 FAD
stat[6]=cdda.CurrAddr.B1;
stat[6] = curFad >> 8;
//7 FAD
stat[7]=cdda.CurrAddr.B2;
stat[7] = curFad;
//8 Max Read Error Retry Times
stat[8]=0;
stat[8] = 0;
//9 0 0 0 0 0 0 0 0
stat[9]=0;
stat[9] = 0;
verify((packet_cmd.data_8[2]+packet_cmd.data_8[4])<11);
gd_spi_pio_end(&stat[packet_cmd.data_8[2]],packet_cmd.data_8[4]);
verify(packet_cmd.data_8[2] + packet_cmd.data_8[4] < 11);
gd_spi_pio_end(&stat[packet_cmd.data_8[2]], packet_cmd.data_8[4]);
}
break;
@ -844,7 +852,7 @@ void gd_process_spi_cmd()
if (param_type == 1 || param_type == 2)
{
bool min_sec_frame = param_type == 2;
cdda.StartAddr.FAD = GetFAD(&packet_cmd.data_8[2], min_sec_frame);
cdda.CurrAddr.FAD = cdda.StartAddr.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)
{
@ -855,10 +863,6 @@ void gd_process_spi_cmd()
cdda.EndAddr.FAD = ses_inf[3] << 16 | ses_inf[4] << 8 | ses_inf[5];
}
cdda.repeats = packet_cmd.data_8[6] & 0xF;
if ((cdda.status != cdda_t::Playing && cdda.status != cdda_t::Paused)
|| cdda.CurrAddr.FAD < cdda.StartAddr.FAD
|| cdda.CurrAddr.FAD > cdda.EndAddr.FAD)
cdda.CurrAddr.FAD = cdda.StartAddr.FAD;
cdda.status = cdda_t::Playing;
SecNumber.Status = GD_PLAY;

View file

@ -48,3 +48,18 @@ std::string libGDR_GetTrackIsrc(u32 trackNum)
return "";
return disc->tracks[trackNum - 1].isrc;
}
void libGDR_GetTrackAdrAndControl(u32 trackNum, u8& adr, u8& ctrl)
{
if (trackNum == 0 || disc == nullptr || trackNum > disc->tracks.size())
{
adr = 0;
ctrl = 0;
}
else
{
const Track& track = disc->tracks[trackNum - 1];
adr = track.ADR | !track.isDataTrack(); // Force subcode Q data type 1 for audio tracks
ctrl = track.CTRL;
}
}

View file

@ -105,7 +105,7 @@ Disc* cdi_parse(const char* file, std::vector<u8> *digest)
if (track.mode==0)
CD_DA=true;
t.ADDR=1;//hmm is that ok ?
t.ADR=1;//hmm is that ok ?
t.CTRL=track.mode==0?0:4;
t.StartFAD=track.start_lba+track.pregap_length;
@ -156,7 +156,7 @@ Disc* cdi_parse(const char* file, std::vector<u8> *digest)
rv->type=GuessDiscType(CD_M1,CD_M2,CD_DA);
rv->LeadOut.StartFAD=rv->EndFAD;
rv->LeadOut.ADDR=0;
rv->LeadOut.ADR=0;
rv->LeadOut.CTRL=0;
return rv;

View file

@ -175,7 +175,7 @@ void TermDrive()
static u32 createTrackInfo(const Track& track, u32 fad)
{
u32 addr = track.ADDR;
u32 addr = track.ADR;
if (!track.isDataTrack())
// audio tracks: sub-q channel indicates current position
addr |= 1;

View file

@ -83,7 +83,7 @@ struct Track
u32 StartFAD = 0; // Start FAD
u32 EndFAD = 0; // End FAD
u8 CTRL = 0;
u8 ADDR = 0;
u8 ADR = 0;
std::string isrc;
bool Read(u32 FAD, u8 *dst, SectorFormat *sector_type, u8 *subcode, SubcodeFormat *subcode_type)
@ -148,7 +148,7 @@ struct Disc
//this isn't always true for gdroms, depends on area look @ the get-toc code
type=GdRom;
LeadOut.ADDR=0;
LeadOut.ADR=0;
LeadOut.CTRL=0;
LeadOut.StartFAD=549300;
@ -272,6 +272,7 @@ u32 libGDR_GetTrackNumber(u32 sector, u32& elapsed);
bool libGDR_GetTrack(u32 track_num, u32& start_fad, u32& end_fad);
std::string libGDR_GetDiskCatalog();
std::string libGDR_GetTrackIsrc(u32 trackNum);
void libGDR_GetTrackAdrAndControl(u32 trackNum, u8& adr, u8& ctrl);
namespace flycast
{

View file

@ -232,7 +232,7 @@ Disc* cue_parse(const char* file, std::vector<u8> *digest)
else
{
disc->type = CdRom_XA;
disc->LeadOut.ADDR = 0;
disc->LeadOut.ADR = 0;
disc->LeadOut.CTRL = 0;
disc->EndFAD = disc->LeadOut.StartFAD = current_fad;
}

View file

@ -222,7 +222,7 @@ struct PhysicalDrive:Disc
verify(trackn==tracks.size());
Track t;
t.ADDR=ftd->Descriptors[i].Adr;
t.ADR=ftd->Descriptors[i].Adr;
t.CTRL=ftd->Descriptors[i].Control;
t.StartFAD=msf2fad(ftd->Descriptors[i].Msf);
t.file = new PhysicalTrack(this);
@ -242,7 +242,7 @@ struct PhysicalDrive:Disc
}
}
LeadOut.StartFAD=EndFAD;
LeadOut.ADDR=0;
LeadOut.ADR=0;
LeadOut.CTRL=0;
}

View file

@ -287,7 +287,7 @@ static void GD_HLE_Command(gd_command cc)
case GDCC_PIOREAD:
GDROM_HLE_ReadPIO();
SecNumber.Status = GD_STANDBY;
SecNumber.Status = GD_PAUSE;
cdda.status = cdda_t::NoInfo;
break;
@ -303,7 +303,7 @@ static void GD_HLE_Command(gd_command cc)
}
gd_hle_state.result[2] = gd_hle_state.params[1] * 2048;
gd_hle_state.result[3] = 0;
SecNumber.Status = GD_STANDBY;
SecNumber.Status = GD_PAUSE;
break;
@ -322,7 +322,7 @@ static void GD_HLE_Command(gd_command cc)
case GDCC_RELEASE:
DEBUG_LOG(REIOS, "GDROM: CMD RELEASE");
cdda.repeats = gd_hle_state.params[0];
// params[0] reptime (ignored)
// params[1] debug (0)
if (cdda.status == cdda_t::Paused)
cdda.status = cdda_t::Playing;
@ -350,16 +350,19 @@ static void GD_HLE_Command(gd_command cc)
u32 last_track = gd_hle_state.params[1];
cdda.repeats = gd_hle_state.params[2];
// params[3] debug (0)
u32 dummy;
libGDR_GetTrack(first_track, cdda.StartAddr.FAD, dummy);
libGDR_GetTrack(last_track, dummy, cdda.EndAddr.FAD);
if (first_track == last_track) {
libGDR_GetTrack(first_track, cdda.StartAddr.FAD, cdda.EndAddr.FAD);
}
else
{
u32 dummy;
libGDR_GetTrack(first_track, cdda.StartAddr.FAD, dummy);
libGDR_GetTrack(last_track, dummy, cdda.EndAddr.FAD);
}
DEBUG_LOG(REIOS, "GDROM: CMD PLAY first_track %x last_track %x repeats %x start_fad %x end_fad %x", first_track, last_track, cdda.repeats,
cdda.StartAddr.FAD, cdda.EndAddr.FAD);
cdda.status = cdda_t::Playing;
if ((SecNumber.Status != GD_PLAY && SecNumber.Status != GD_PAUSE)
|| cdda.CurrAddr.FAD < cdda.StartAddr.FAD
|| cdda.CurrAddr.FAD > cdda.EndAddr.FAD)
cdda.CurrAddr.FAD = cdda.StartAddr.FAD;
cdda.CurrAddr.FAD = cdda.StartAddr.FAD;
SecNumber.Status = GD_PLAY;
}
else
@ -474,8 +477,9 @@ static void GD_HLE_Command(gd_command cc)
// 0 | subcode q track number
// ------------------------------------------------------
// 1-3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
const u32 fad = cdda.status == cdda_t::Paused || cdda.status == cdda_t::Playing ? cdda.CurrAddr.FAD : gd_hle_state.cur_sector;
u32 elapsed;
u32 tracknum = libGDR_GetTrackNumber(gd_hle_state.cur_sector, elapsed);
u32 tracknum = libGDR_GetTrackNumber(fad, elapsed);
WriteMem32(dst1, tracknum);
// bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
@ -483,9 +487,10 @@ static void GD_HLE_Command(gd_command cc)
// ------------------------------------------------------
// 0-2 | fad (little-endian)
// ------------------------------------------------------
// 3 | address | control
u32 out = (((SecNumber.DiscFormat == 0 ? 0 : 0x40) | 1) << 24)
| (gd_hle_state.cur_sector & 0x00ffffff);
// 3 | ADR | Control
u8 adr, ctrl;
libGDR_GetTrackAdrAndControl(tracknum, adr, ctrl);
u32 out = (adr << 28) | (ctrl << 24) | (fad & 0x00ffffff);
WriteMem32(dst2, out);
// bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0

View file

@ -142,7 +142,7 @@ bool extract_info(FILE* w, bool first, Disc* d, const string& basename) {
fprintf(w,",\n\"tracks\": [");
{
for (int i=0; i<d->tracks.size(); i++) {
fprintf(w, "%s{ \"startFAD\":%d, \"endFAD\":%d, \"ctrl\":%d, \"addr\":%d }", i ==0 ? "\n":",\n", d->tracks[i].StartFAD, d->tracks[i].EndFAD, d->tracks[i].CTRL, d->tracks[i].ADDR);
fprintf(w, "%s{ \"startFAD\":%d, \"endFAD\":%d, \"ctrl\":%d, \"addr\":%d }", i ==0 ? "\n":",\n", d->tracks[i].StartFAD, d->tracks[i].EndFAD, d->tracks[i].CTRL, d->tracks[i].ADR);
}
}
fprintf(w,"\n]");