generate sector headers for mode1/2048

This commit is contained in:
zeromus 2015-07-01 04:18:48 -05:00
parent 017397d91a
commit aa50d28346
4 changed files with 72 additions and 33 deletions

View File

@ -49,7 +49,7 @@ namespace BizHawk.Emulation.DiscSystem
/// <summary>
/// Indicates whether the output buffer should be cleared before returning any data.
/// This will involve clearing sections you didn't ask for, and clearing sections about to be filled with data from the disc.
/// This will unfortunately involve clearing sections you didn't ask for, and clearing sections about to be filled with data from the disc.
/// It is a waste of performance, but it will ensure reliability.
/// </summary>
public bool DeterministicClearBuffer = true;

View File

@ -24,7 +24,7 @@ namespace BizHawk.Emulation.DiscSystem
long end = byte_pos + todo;
if (end > srcBlobLength)
{
long temp = (int)(srcBlobLength - end);
long temp = (int)(srcBlobLength - byte_pos);
if (temp > int.MaxValue)
throw new InvalidOperationException();
todo = (int)temp;

View File

@ -201,7 +201,9 @@ namespace BizHawk.Emulation.DiscSystem
//per "Example 05" on digitalx.org, pregap can come from index specification and pregap command
int specifiedPregapLength = cct.PregapLength.Sector;
int impliedPregapLength = cct.Indexes[1].FileMSF.Sector - cct.Indexes[0].FileMSF.Sector;
//total pregap is needed for subQ addressing of the entire pregap area
//total pregap is needed for subQ addressing of the entire pregap area (pregap + distinct index0)
//during generating userdata sectors this is already handled
//we just need to know the difference for when we generate a better subQ here
int totalPregapLength = specifiedPregapLength + impliedPregapLength;
for (int s = 0; s < specifiedPregapLength; s++)
{
@ -260,6 +262,11 @@ namespace BizHawk.Emulation.DiscSystem
SS_Base ss = null;
switch (cct.TrackType)
{
case CueFile.TrackType.Mode1_2048:
ss = new SS_Mode1_2048() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset };
curr_blobOffset += 2048;
break;
case CueFile.TrackType.Mode2_2352:
case CueFile.TrackType.Audio:
ss = new SS_2352() { Blob = curr_blobInfo.Blob, BlobOffset = curr_blobOffset };
@ -329,7 +336,22 @@ namespace BizHawk.Emulation.DiscSystem
break;
}
//TODO - POSTGAP
//---------------------------------
//gen postgap sectors
int specifiedPostgapLength = cct.PostgapLength.Sector;
for (int s = 0; s < specifiedPostgapLength; s++)
{
//TODO - do a better job synthesizing Q
var se_pregap = new SectorEntry(null);
var ss_pregap = new SS_Pregap();
//postgaps set pause flag. is this good enough?
ss_pregap.Pause = true;
se_pregap.SectorSynth = ss_pregap;
OUT_Disc.Sectors.Add(se_pregap);
}
} //end track loop

View File

@ -14,17 +14,24 @@ namespace BizHawk.Emulation.DiscSystem
public bool Pause;
public abstract void Synth(SectorSynthJob job);
}
class SS_Mode1_2048 : SS_Base
{
public override void Synth(SectorSynthJob job)
protected void SynthSubcode(SectorSynthJob job)
{
if ((job.Parts & ESectorSynthPart.SubchannelP) != 0)
{
SynthUtils.P(job.DestBuffer2448, job.DestOffset + 2352, Pause);
}
if ((job.Parts & ESectorSynthPart.SubchannelQ) != 0)
{
var subcode = new BufferedSubcodeSector();
subcode.Synthesize_SubchannelQ(ref sq, true);
Buffer.BlockCopy(subcode.SubcodeDeinterleaved, 12, job.DestBuffer2448, job.DestOffset + 2352 + 12, 12);
}
}
}
static class SubSynth
static class SynthUtils
{
public static void P(byte[] buffer, int offset, bool pause)
{
@ -32,6 +39,18 @@ namespace BizHawk.Emulation.DiscSystem
for (int i = 0; i < 12; i++)
buffer[offset + i] = val;
}
public static void Header(byte[] buffer, int offset, int LBA, byte mode)
{
buffer[offset + 0] = 0x00;
for (int i = 1; i < 11; i++) buffer[offset + i] = 0xFF;
buffer[offset + 11] = 0x00;
Timestamp ts = new Timestamp(LBA + 150);
buffer[offset + 12] = ts.MIN;
buffer[offset + 13] = ts.SEC;
buffer[offset + 14] = ts.FRAC;
buffer[offset + 15] = mode;
}
}
/// <summary>
@ -42,20 +61,29 @@ namespace BizHawk.Emulation.DiscSystem
{
public override void Synth(SectorSynthJob job)
{
if ((job.Parts & ESectorSynthPart.SubchannelP) != 0)
{
SubSynth.P(job.DestBuffer2448, job.DestOffset + 2352, Pause);
}
if ((job.Parts & ESectorSynthPart.SubchannelQ) != 0)
{
var subcode = new BufferedSubcodeSector();
subcode.Synthesize_SubchannelQ(ref sq, true);
Buffer.BlockCopy(subcode.SubcodeDeinterleaved, 12, job.DestBuffer2448, job.DestOffset + 2352 + 12, 12);
}
}
}
/// <summary>
/// Represents a Mode1 2048-byte sector
/// </summary>
class SS_Mode1_2048 : SS_Base
{
public override void Synth(SectorSynthJob job)
{
//read the sector user data
if((job.Parts & ESectorSynthPart.User2048) != 0)
Blob.Read(BlobOffset, job.DestBuffer2448, job.DestOffset + 16, 2048);
if ((job.Parts & ESectorSynthPart.Header16) != 0)
SynthUtils.Header(job.DestBuffer2448, job.DestOffset + 0, job.LBA, 1);
SynthSubcode(job);
}
}
/// <summary>
/// Represents a Mode1 or Mode2 2352-byte sector
/// </summary>
@ -67,18 +95,7 @@ namespace BizHawk.Emulation.DiscSystem
Blob.Read(BlobOffset, job.DestBuffer2448, job.DestOffset, 2352);
//if subcode is needed, synthesize it
if ((job.Parts & ESectorSynthPart.SubchannelP) != 0)
{
SubSynth.P(job.DestBuffer2448, job.DestOffset + 2352, Pause); //for now....
}
if ((job.Parts & ESectorSynthPart.SubchannelQ) != 0)
{
var subcode = new BufferedSubcodeSector();
subcode.Synthesize_SubchannelQ(ref sq, true);
Buffer.BlockCopy(subcode.SubcodeDeinterleaved, 12, job.DestBuffer2448, job.DestOffset + 2352 + 12, 12);
}
SynthSubcode(job);
}
}