diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp index cee77c3f9..f231adbe8 100644 --- a/core/hw/gdrom/gdromv3.cpp +++ b/core/hw/gdrom/gdromv3.cpp @@ -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; diff --git a/core/imgread/ImgReader.cpp b/core/imgread/ImgReader.cpp index 0a34c7122..c82ecbe8a 100644 --- a/core/imgread/ImgReader.cpp +++ b/core/imgread/ImgReader.cpp @@ -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; + } +} diff --git a/core/imgread/cdi.cpp b/core/imgread/cdi.cpp index 5116a037a..371f11d71 100644 --- a/core/imgread/cdi.cpp +++ b/core/imgread/cdi.cpp @@ -105,7 +105,7 @@ Disc* cdi_parse(const char* file, std::vector *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 *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; diff --git a/core/imgread/common.cpp b/core/imgread/common.cpp index a63f87f0a..dbe500f0a 100644 --- a/core/imgread/common.cpp +++ b/core/imgread/common.cpp @@ -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; diff --git a/core/imgread/common.h b/core/imgread/common.h index c6cad9744..38b377776 100644 --- a/core/imgread/common.h +++ b/core/imgread/common.h @@ -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 { diff --git a/core/imgread/cue.cpp b/core/imgread/cue.cpp index 43f4d61f3..2b90a84c3 100644 --- a/core/imgread/cue.cpp +++ b/core/imgread/cue.cpp @@ -232,7 +232,7 @@ Disc* cue_parse(const char* file, std::vector *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; } diff --git a/core/imgread/ioctl.cpp b/core/imgread/ioctl.cpp index 20a632fa5..1ed8fdf05 100644 --- a/core/imgread/ioctl.cpp +++ b/core/imgread/ioctl.cpp @@ -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; } diff --git a/core/reios/gdrom_hle.cpp b/core/reios/gdrom_hle.cpp index 1e03bb6af..12033d26e 100644 --- a/core/reios/gdrom_hle.cpp +++ b/core/reios/gdrom_hle.cpp @@ -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 diff --git a/gdtool/src/main.cpp b/gdtool/src/main.cpp index ba0ae0635..aad75c975 100644 --- a/gdtool/src/main.cpp +++ b/gdtool/src/main.cpp @@ -142,7 +142,7 @@ bool extract_info(FILE* w, bool first, Disc* d, const string& basename) { fprintf(w,",\n\"tracks\": ["); { for (int i=0; itracks.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]");