BizHawk/BizHawk.Emulation.DiscSystem/Internal/SectorSynth.cs

149 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
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
{
/// <summary>
/// The data sector header is required. There's no header for audio tracks/sectors.
/// </summary>
Header16 = 1,
/// <summary>
/// The main 2048 user data bytes are required
/// </summary>
User2048 = 2,
/// <summary>
/// The 276 bytes of error correction are required
/// </summary>
ECC276 = 4,
/// <summary>
/// The 12 bytes preceding the ECC section are required (usually EDC and zero but also userdata sometimes)
/// </summary>
EDC12 = 8,
/// <summary>
/// The entire possible 276+12=288 bytes of ECM data is required (ECC276|EDC12)
/// </summary>
ECM288Complete = (ECC276 | EDC12),
/// <summary>
/// An alias for ECM288Complete
/// </summary>
ECMAny = ECM288Complete,
/// <summary>
/// A mode2 userdata section is required: the main 2048 user bytes AND the ECC and EDC areas
/// </summary>
User2336 = (User2048 | ECM288Complete),
/// <summary>
/// The complete sector userdata (2352 bytes) is required
/// </summary>
UserComplete = 15,
/// <summary>
/// An alias for UserComplete
/// </summary>
UserAny = UserComplete,
/// <summary>
/// An alias for UserComplete
/// </summary>
User2352 = UserComplete,
/// <summary>
/// SubP is required
/// </summary>
SubchannelP = 16,
/// <summary>
/// SubQ is required
/// </summary>
SubchannelQ = 32,
/// <summary>
/// Subchannels R-W (all except for P and Q)
/// </summary>
Subchannel_RSTUVW = (64|128|256|512|1024|2048),
/// <summary>
/// Complete subcode is required
/// </summary>
SubcodeComplete = (SubchannelP | SubchannelQ | Subchannel_RSTUVW),
/// <summary>
/// Any of the subcode might be required (just another way of writing SubcodeComplete)
/// </summary>
SubcodeAny = SubcodeComplete,
/// <summary>
/// The subcode should be deinterleaved
/// </summary>
SubcodeDeinterleave = 4096,
/// <summary>
/// The 100% complete sector is required including 2352 bytes of userdata and 96 bytes of subcode
/// </summary>
Complete2448 = SubcodeComplete | User2352,
}
interface ISectorSynthJob2448
{
void Synth(SectorSynthJob job);
}
/// <summary>
/// Not a proper job? maybe with additional flags, it could be
/// </summary>
class SectorSynthJob
{
public int LBA;
public ESectorSynthPart Parts;
public byte[] DestBuffer2448;
public int DestOffset;
public SectorSynthParams Params;
public Disc Disc;
}
/// <summary>
/// Generic parameters for sector synthesis.
/// To cut down on resource utilization, these can be stored in a disc and are tightly coupled to
/// the SectorSynths that have been setup for it
/// </summary>
struct SectorSynthParams
{
public long[] BlobOffsets;
public MednaDisc MednaDisc;
}
class SS_PatchQ : ISectorSynthJob2448
{
public ISectorSynthJob2448 Original;
public byte[] Buffer_SubQ = new byte[12];
public void Synth(SectorSynthJob job)
{
Original.Synth(job);
if ((job.Parts & ESectorSynthPart.SubchannelQ) == 0)
return;
//apply patched subQ
for (int i = 0; i < 12; i++)
job.DestBuffer2448[2352 + 12 + i] = Buffer_SubQ[i];
}
}
}