diff --git a/core/hw/gdrom/gdromv3.cpp b/core/hw/gdrom/gdromv3.cpp index c5374ffea..463d4f91e 100644 --- a/core/hw/gdrom/gdromv3.cpp +++ b/core/hw/gdrom/gdromv3.cpp @@ -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; diff --git a/core/hw/gdrom/gdromv3.h b/core/hw/gdrom/gdromv3.h index 5e2aa63a6..e76005a97 100644 --- a/core/hw/gdrom/gdromv3.h +++ b/core/hw/gdrom/gdromv3.h @@ -200,7 +200,7 @@ struct ata_cmd_t struct cdda_t { - bool playing; + enum { NoInfo, Playing, Paused, Terminated } status; u32 repeats; union { diff --git a/core/imgread/gdi.cpp b/core/imgread/gdi.cpp index b5acc5ca2..6038c652e 100644 --- a/core/imgread/gdi.cpp +++ b/core/imgread/gdi.cpp @@ -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); } diff --git a/core/reios/descrambl.cpp b/core/reios/descrambl.cpp index bbd3f0e3d..f860d38a3 100644 --- a/core/reios/descrambl.cpp +++ b/core/reios/descrambl.cpp @@ -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; -} \ No newline at end of file +} diff --git a/core/reios/descrambl.h b/core/reios/descrambl.h index 4bbaddd43..77b02c013 100644 --- a/core/reios/descrambl.h +++ b/core/reios/descrambl.h @@ -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 diff --git a/core/reios/gdrom_hle.cpp b/core/reios/gdrom_hle.cpp index cef3c9546..d95b7d06d 100644 --- a/core/reios/gdrom_hle.cpp +++ b/core/reios/gdrom_hle.cpp @@ -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; diff --git a/core/serialize.cpp b/core/serialize.cpp index 4363dfd09..3bc508571 100644 --- a/core/serialize.cpp +++ b/core/serialize.cpp @@ -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); diff --git a/core/types.h b/core/types.h index 033425e98..85e70fdc3 100644 --- a/core/types.h +++ b/core/types.h @@ -606,4 +606,5 @@ enum serialize_version_enum { V7 = 802, V8 = 803, V9 = 804, + V10 = 805, } ; diff --git a/tests/src/serialize_test.cpp b/tests/src/serialize_test.cpp index ec6be3790..64a6b8c3e 100644 --- a/tests/src/serialize_test.cpp +++ b/tests/src/serialize_test.cpp @@ -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); }