generate pregap XA headers same way as mednafen

This commit is contained in:
zeromus 2015-07-01 20:28:02 -05:00
parent 79c8f43279
commit 9b8486a2d1
4 changed files with 101 additions and 13 deletions

View File

@ -282,6 +282,8 @@ namespace BizHawk.Emulation.DiscSystem
{
qFlags = (EControlQ)(int)TrackInfos[t - 1].CompiledCueTrack.Flags;
audioGap = true;
//TODO - actually generate the entire sector like the track before, including audio vs data encoding
//that means, dont get qFlags here, but instead reference a track to pull flags +and other data+ from
}
}
}
@ -296,23 +298,23 @@ namespace BizHawk.Emulation.DiscSystem
switch (cct.TrackType)
{
case CueFile.TrackType.Audio:
ss = new SS_2352() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset, Mode = 0 };
ss = new SS_2352();
sectorSize = 2352;
break;
case CueFile.TrackType.CDI_2352:
case CueFile.TrackType.Mode1_2352:
ss = new SS_2352() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset, Mode = 1 };
ss = new SS_2352();
sectorSize = 2352;
break;
case CueFile.TrackType.Mode2_2352:
ss = new SS_2352() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset, Mode = 2 };
ss = new SS_2352();
sectorSize = 2352;
break;
case CueFile.TrackType.Mode1_2048:
ss = new SS_Mode1_2048() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset, Mode = 1 };
ss = new SS_Mode1_2048();
sectorSize = 2048;
break;
@ -324,17 +326,23 @@ namespace BizHawk.Emulation.DiscSystem
//if we were supposed to generate a gap, replace it with a new sector synth and feed it zeros
if (generateGap)
{
if (audioGap) ss = new SS_AudioGap();
else ss = new SS_DataGap() { Mode = ss.Mode };
ss = new SS_Gap();
ss.Blob = zeroBlob;
ss.TrackType = cct.TrackType;
ss.Gap = true; //not used...
}
else
{
//otherwise we consumed data from the blob
ss.Blob = curr_blobInfo.Blob;
ss.BlobOffset = curr_blobOffset;
ss.TrackType = cct.TrackType;
curr_blobOffset += sectorSize;
curr_blobMSF++;
}
ss.Policy = context.DiscMountPolicy;
//setup subQ
byte ADR = 1; //absent some kind of policy for how to set it, this is a safe assumption:
ss.sq.SetStatus(ADR, qFlags);

View File

@ -12,11 +12,13 @@ namespace BizHawk.Emulation.DiscSystem
public IBlob Blob;
public long BlobOffset;
public SubchannelQ sq;
public bool Pause;
public byte Mode;
public bool Pause, Gap;
public CueFile.TrackType TrackType;
public DiscMountPolicy Policy;
public abstract void Synth(SectorSynthJob job);
//"as needed"
protected void SynthSubcode(SectorSynthJob job)
{
//synth P if needed
@ -68,6 +70,19 @@ namespace BizHawk.Emulation.DiscSystem
buffer[offset + 15] = mode;
}
public static void EDC_Mode2_Form1(byte[] buffer, int offset)
{
uint edc = ECM.EDC_Calc(buffer, offset + 16, 2048 + 8);
ECM.PokeUint(buffer, offset + 2072, edc);
}
public static void EDC_Mode2_Form2(byte[] buffer, int offset)
{
uint edc = ECM.EDC_Calc(buffer, offset + 16, 2324+8);
ECM.PokeUint(buffer, offset + 2348, edc);
}
/// <summary>
/// Make sure everything else in the sector userdata is done before calling this
/// </summary>
@ -75,7 +90,7 @@ namespace BizHawk.Emulation.DiscSystem
{
//EDC
uint edc = ECM.EDC_Calc(buffer, offset, 2064);
ECM.PokeUint(buffer, 2064, edc);
ECM.PokeUint(buffer, offset + 2064, edc);
//reserved, zero
for (int i = 0; i < 8; i++) buffer[offset + 2068 + i] = 0;
@ -97,7 +112,7 @@ namespace BizHawk.Emulation.DiscSystem
Blob.Read(BlobOffset, job.DestBuffer2448, job.DestOffset + 16, 2048);
if ((job.Parts & ESectorSynthPart.Header16) != 0)
SynthUtils.SectorHeader(job.DestBuffer2448, job.DestOffset + 0, job.LBA, Mode);
SynthUtils.SectorHeader(job.DestBuffer2448, job.DestOffset + 0, job.LBA, 1);
if ((job.Parts & ESectorSynthPart.ECMAny) != 0)
SynthUtils.ECM_Mode1(job.DestBuffer2448, job.DestOffset + 0, job.LBA);
@ -132,8 +147,65 @@ namespace BizHawk.Emulation.DiscSystem
}
}
class SS_Gap : SS_Base
{
//public CueFile.TrackType TrackType; //shouldnt be in base class...
public override void Synth(SectorSynthJob job)
{
//this isn't fully analyzed/optimized
Array.Clear(job.DestBuffer2448, job.DestOffset, 2352);
byte mode = 255;
int form = -1;
switch (TrackType)
{
case CueFile.TrackType.Audio:
mode = 0;
break;
case CueFile.TrackType.CDI_2352:
case CueFile.TrackType.Mode1_2352:
mode = 1;
break;
case CueFile.TrackType.Mode2_2352:
mode = 2;
if (Policy.CUE_PregapMode2_As_XA_Form2)
{
job.DestBuffer2448[job.DestOffset + 12 + 6] = 0x20;
job.DestBuffer2448[job.DestOffset + 12 + 10] = 0x20;
}
form = 2; //no other choice right now really
break;
case CueFile.TrackType.Mode1_2048:
mode = 1;
break;
case CueFile.TrackType.Mode2_2336:
default:
throw new InvalidOperationException("Not supported: " + TrackType);
}
if ((job.Parts & ESectorSynthPart.Header16) != 0)
SynthUtils.SectorHeader(job.DestBuffer2448, job.DestOffset + 0, job.LBA, mode);
if (mode == 1)
{
if ((job.Parts & ESectorSynthPart.ECMAny) != 0)
SynthUtils.ECM_Mode1(job.DestBuffer2448, job.DestOffset + 0, job.LBA);
}
if (mode == 2 && form == 2)
{
SynthUtils.EDC_Mode2_Form2(job.DestBuffer2448, job.DestOffset);
}
SynthSubcode(job);
}
}
/// <summary>
/// Represents a Mode1 or Mode2 2352-byte sector
/// Represents a 2352-byte sector of any sort
/// </summary>
class SS_2352 : SS_Base
{

View File

@ -27,9 +27,16 @@ namespace BizHawk.Emulation.DiscSystem
/// </summary>
public bool CUE_PregapContradictionModeA = true;
/// <summary>
/// Mednafen sets mode2 pregap sectors as XA Form2 sectors.
/// This is almost surely not right in every case.
/// </summary>
public bool CUE_PregapMode2_As_XA_Form2 = true;
public void SetForPlaystation()
{
//probably set CUE_PauseContradictionModeA to follow mednafen, but not proven yet
//almost surely set CUE_PregapMode2_As_XA_Form2 to follow mednafen
}
}
@ -144,7 +151,7 @@ namespace BizHawk.Emulation.DiscSystem
ConcatenateJobLog(loadJob);
OUT_Disc = loadJob.OUT_Disc;
//OUT_Disc.DiscMountPolicy = IN_DiscMountPolicy; //NOT SURE WE NEED THIS
//OUT_Disc.DiscMountPolicy = IN_DiscMountPolicy; //NOT SURE WE NEED THIS (only makes sense for cue probably)
//apply SBI if it exists (TODO - for formats other than cue?)
var sbiPath = Path.ChangeExtension(IN_FromPath, ".sbi");

View File

@ -24,6 +24,8 @@ namespace BizHawk.Emulation.DiscSystem
/// <summary>
/// Indicates which part of a sector are needing to be synthesized.
/// Sector synthesis may create too much data, but this is a hint as to what's needed
/// TODO - add a flag indicating whether clearing has happened
/// TODO - add output to the job indicating whether interleaving has happened. let the sector reader be responsible
/// </summary>
[Flags] enum ESectorSynthPart
{
@ -77,7 +79,6 @@ namespace BizHawk.Emulation.DiscSystem
/// </summary>
User2352 = UserComplete,
/// <summary>
/// SubP is required
/// </summary>