diff --git a/BizHawk.Emulation.DiscSystem/API/Disc.API.cs b/BizHawk.Emulation.DiscSystem/API/Disc.API.cs
index da1e5532c2..ba56d63283 100644
--- a/BizHawk.Emulation.DiscSystem/API/Disc.API.cs
+++ b/BizHawk.Emulation.DiscSystem/API/Disc.API.cs
@@ -25,16 +25,6 @@ namespace BizHawk.Emulation.DiscSystem
sealed public partial class Disc
{
- ///
- /// Returns a SectorEntry from which you can retrieve various interesting pieces of information about the sector.
- /// The SectorEntry's interface is not likely to be stable, though, but it may be more convenient.
- ///
- public SectorEntry ReadLBA_SectorEntry(int lba)
- {
- return Sectors[lba + 150];
- }
-
-
///
/// Main API to determine how many LBAs are available on the disc.
/// This counts from LBA 0 to the final sector available.
diff --git a/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs b/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs
index bf19a92c05..893e10b397 100644
--- a/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs
+++ b/BizHawk.Emulation.DiscSystem/API/DiscSectorReader.cs
@@ -94,7 +94,7 @@ namespace BizHawk.Emulation.DiscSystem
job.Parts = ESectorSynthPart.User2352;
job.Disc = disc;
- sector.SectorSynth.Synth(job);
+ sector.Synth(job);
Buffer.BlockCopy(buf2442, 0, buffer, offset, 2352);
@@ -116,7 +116,7 @@ namespace BizHawk.Emulation.DiscSystem
if (Policy.DeinterleavedSubcode)
job.Parts |= ESectorSynthPart.SubcodeDeinterleave;
- sector.SectorSynth.Synth(job);
+ sector.Synth(job);
//we went straight to the caller's buffer, so no need to copy
return 2442;
@@ -133,7 +133,7 @@ namespace BizHawk.Emulation.DiscSystem
job.DestOffset = 0;
job.Parts = ESectorSynthPart.User2048;
- sector.SectorSynth.Synth(job);
+ sector.Synth(job);
Buffer.BlockCopy(buf2442, 16, buffer, offset, 2048);
return 2048;
@@ -150,7 +150,7 @@ namespace BizHawk.Emulation.DiscSystem
job.DestOffset = 0;
job.Parts = ESectorSynthPart.User2336;
- sector.SectorSynth.Synth(job);
+ sector.Synth(job);
Buffer.BlockCopy(buf2442, 24, buffer, offset, 2048);
return 2048;
@@ -170,7 +170,7 @@ namespace BizHawk.Emulation.DiscSystem
job.DestOffset = 0;
job.Parts = ESectorSynthPart.SubchannelQ | ESectorSynthPart.SubcodeDeinterleave;
- sector.SectorSynth.Synth(job);
+ sector.Synth(job);
Buffer.BlockCopy(buf2442, 2352 + 12, buffer, offset, 12);
return 12;
@@ -201,7 +201,7 @@ namespace BizHawk.Emulation.DiscSystem
job.DestOffset = 0;
job.Parts = ESectorSynthPart.Header16 | ESectorSynthPart.User2048 | ESectorSynthPart.EDC12;
- sector.SectorSynth.Synth(job);
+ sector.Synth(job);
//now the inspection, based on the mode
byte mode = buf2442[15];
@@ -276,7 +276,7 @@ namespace BizHawk.Emulation.DiscSystem
job.Parts = ESectorSynthPart.Header16;
job.Disc = disc;
- sector.SectorSynth.Synth(job);
+ sector.Synth(job);
return buf2442[15];
}
diff --git a/BizHawk.Emulation.DiscSystem/CCD_format.cs b/BizHawk.Emulation.DiscSystem/CCD_format.cs
index 6b21ce11bc..6a475fedaa 100644
--- a/BizHawk.Emulation.DiscSystem/CCD_format.cs
+++ b/BizHawk.Emulation.DiscSystem/CCD_format.cs
@@ -470,7 +470,7 @@ namespace BizHawk.Emulation.DiscSystem
//subcode comes to us deinterleved; we may still need to interleave it
if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave)) == 0)
{
- SubcodeUtils.InterleaveInplace(job.DestBuffer2448, job.DestOffset + 2352);
+ SynthUtils.InterleaveSubcodeInplace(job.DestBuffer2448, job.DestOffset + 2352);
}
}
}
@@ -501,7 +501,6 @@ namespace BizHawk.Emulation.DiscSystem
//generate DiscTOCRaw items from the ones specified in the CCD file
//TODO - range validate these (too many truncations to byte)
disc.RawTOCEntries = new List();
- BufferedSubcodeSector bss = new BufferedSubcodeSector(); //TODO - its hacky that we need this..
foreach (var entry in ccdf.TOCEntries)
{
BCD2 tno, ino;
@@ -530,82 +529,27 @@ namespace BizHawk.Emulation.DiscSystem
ap_min = BCD2.FromDecimal(entry.PMin),
ap_sec = BCD2.FromDecimal(entry.PSec),
ap_frame = BCD2.FromDecimal(entry.PFrame),
+ q_crc = 0, //meainingless
};
- //CRC cant be calculated til we've got all the fields setup
- q.q_crc = bss.Synthesize_SubchannelQ(ref q, true);
-
disc.RawTOCEntries.Add(new RawTOCEntry { QData = q });
}
-
- //disc.Structure = new DiscStructure();
- //var ses = new DiscStructure.Session();
- //disc.Structure.Sessions.Add(ses);
-
- //for(int i=1;i<=99;i++)
- //{
- // if(!ccdf.TracksByNumber.ContainsKey(i))
- // continue;
- // var ccdt = ccdf.TracksByNumber[i];
-
- // DiscStructure.Track track = new DiscStructure.Track() { Number = i };
- // ses.Tracks.Add(track);
-
- // //if index 0 is missing, add it
- // if (!ccdt.Indexes.ContainsKey(0))
- // track.Indexes.Add(new DiscStructure.Index { Number = 0, LBA = ccdt.Indexes[1] });
- // for(int j=1;j<=99;j++)
- // if (ccdt.Indexes.ContainsKey(j))
- // track.Indexes.Add(new DiscStructure.Index { Number = j, LBA = ccdt.Indexes[j] });
-
- // //TODO - this should only be used in case the .sub needs reconstructing
- // //determination should be done from heuristics.
- // //if we keep this, it should just be as a memo that later heuristics can use. For example: 'use guidance from original disc image'
- // track.ModeHeuristic = ccdt.Mode;
-
- // //TODO - this should be deleted anyway (
- // switch (ccdt.Mode)
- // {
- // case 0:
- // track.TrackType = DiscStructure.ETrackType.Audio; //for CCD, this means audio, apparently.
- // break;
- // case 1:
- // case 2:
- // track.TrackType = DiscStructure.ETrackType.Data;
- // break;
- // default:
- // throw new InvalidOperationException("Unsupported CCD mode");
- // }
- //}
-
- //add sectors for the "mandatory track 1 pregap", which isn't stored in the CCD file
- //THIS IS JUNK. MORE CORRECTLY SYNTHESIZE IT
+ //add sectors for the mandatory track 1 pregap, which isn't stored in the CCD file
+ //TODO - THIS IS JUNK. MORE CORRECTLY SYNTHESIZE IT
var leadin_sector_zero = new Sector_Zero();
- var leadin_subcode_zero = new ZeroSubcodeSector();
for (int i = 0; i < 150; i++)
{
- var se = new SectorEntry(leadin_sector_zero);
- disc.Sectors.Add(se);
- se.SubcodeSector = leadin_subcode_zero;
+ //TODO - YIKES!
+ disc.Sectors.Add(null);
}
//build the sectors:
- //set up as many sectors as we have img/sub for, even if the TOC doesnt reference them (TOC is unreliable, although the tracks should have covered it all)
+ //set up as many sectors as we have img/sub for, even if the TOC doesnt reference them
+ //(TOC is unreliable, although the tracks should have covered it all)
for (int i = 0; i < loadResults.NumImgSectors; i++)
{
- var isec = new Sector_RawBlob();
- isec.Offset = ((long)i) * 2352;
- isec.Blob = imgBlob;
-
- var se = new SectorEntry(isec);
- disc.Sectors.Add(se);
-
- var scsec = new BlobSubcodeSectorPreDeinterleaved();
- scsec.Offset = ((long)i) * 96;
- scsec.Blob = subBlob;
- se.SubcodeSector = scsec;
- se.SectorSynth = synth;
+ disc.Sectors.Add(synth);
}
return disc;
diff --git a/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs b/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
index 73b3bc322c..78f02ea644 100644
--- a/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
+++ b/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
@@ -331,10 +331,7 @@ namespace BizHawk.Emulation.DiscSystem
if (curr_index == 0)
ss.Pause = true;
- //make the SectorEntry (some temporary bullshit here)
- var se = new SectorEntry(null);
- se.SectorSynth = ss;
- OUT_Disc.Sectors.Add(se);
+ OUT_Disc.Sectors.Add(ss);
relMSF++;
if (cct.IsFinalInFile)
@@ -360,7 +357,6 @@ namespace BizHawk.Emulation.DiscSystem
int specifiedPostgapLength = cct.PostgapLength.Sector;
for (int s = 0; s < specifiedPostgapLength; s++)
{
- var se= new SectorEntry(null);
var ss = new SS_Gap();
ss.TrackType = cct.TrackType; //TODO - old track type in some < -150 cases?
@@ -376,8 +372,7 @@ namespace BizHawk.Emulation.DiscSystem
//always paused--is this good enough?
ss.Pause = true;
- se.SectorSynth = ss;
- OUT_Disc.Sectors.Add(se);
+ OUT_Disc.Sectors.Add(ss);
relMSF++;
}
diff --git a/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs b/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
index 1c1b18e792..0e0c8aa7da 100644
--- a/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
+++ b/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
@@ -31,11 +31,10 @@ namespace BizHawk.Emulation.DiscSystem
}
//synth Q if needed
+ //TODO - why not already have it serialized? Into a disc resource, even.
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);
+ SynthUtils.SubQ_Serialize(job.DestBuffer2448, job.DestOffset + 2352 + 12, ref sq);
}
//clear R-W if needed
@@ -47,7 +46,7 @@ namespace BizHawk.Emulation.DiscSystem
//subcode has been generated deinterleaved; we may still need to interleave it
if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave)) == 0)
{
- SubcodeUtils.InterleaveInplace(job.DestBuffer2448, job.DestOffset + 2352);
+ SynthUtils.InterleaveSubcodeInplace(job.DestBuffer2448, job.DestOffset + 2352);
}
}
}
diff --git a/BizHawk.Emulation.DiscSystem/Disc.cs b/BizHawk.Emulation.DiscSystem/Disc.cs
index 30c75fb6e5..ee9258100c 100644
--- a/BizHawk.Emulation.DiscSystem/Disc.cs
+++ b/BizHawk.Emulation.DiscSystem/Disc.cs
@@ -118,7 +118,7 @@ namespace BizHawk.Emulation.DiscSystem
///
/// The sectors on the disc
///
- public List Sectors = new List();
+ internal List Sectors = new List();
internal SectorSynthParams SynthParams = new SectorSynthParams();
@@ -137,6 +137,7 @@ namespace BizHawk.Emulation.DiscSystem
///
/// generates lead-out sectors according to very crude approximations
+ /// TODO - this isnt being used right now
///
public class SynthesizeLeadoutJob
{
@@ -159,8 +160,8 @@ namespace BizHawk.Emulation.DiscSystem
for (int i = 0; i < Length; i++)
{
- var se = new SectorEntry(sz);
- Disc.Sectors.Add(se);
+ //var se = new SectorEntry(sz);
+ //Disc.Sectors.Add(se);
SubchannelQ sq = new SubchannelQ();
int track_relative_msf = i;
@@ -179,9 +180,7 @@ namespace BizHawk.Emulation.DiscSystem
byte ADR = 1;
sq.SetStatus(ADR, leadoutFlags);
- var subcode = new BufferedSubcodeSector();
- subcode.Synthesize_SubchannelQ(ref sq, true);
- se.SubcodeSector = subcode;
+ //TODO - actually stash the subQ
}
}
}
@@ -233,14 +232,14 @@ namespace BizHawk.Emulation.DiscSystem
int lba = sbi.ABAs[i] - 150;
//create a synthesizer which can return the patched data
- var ss_patchq = new SS_PatchQ() { Original = this.Sectors[lba+150].SectorSynth };
+ var ss_patchq = new SS_PatchQ() { Original = this.Sectors[lba+150] };
byte[] subQbuf = ss_patchq.Buffer_SubQ;
//read the old subcode
dsr.ReadLBA_SubQ(lba, subQbuf, 0);
//insert patch
- Sectors[lba + 150].SectorSynth = ss_patchq;
+ Sectors[lba + 150] = ss_patchq;
//apply SBI patch
for (int j = 0; j < 12; j++)
@@ -255,7 +254,7 @@ namespace BizHawk.Emulation.DiscSystem
//However, this seems senseless to me. The whole point of the SBI data is that it stores the patches needed to generate an acceptable subQ, right?
if (asMednafen)
{
- SynthUtils.SubQ_Checksum(subQbuf, 0);
+ SynthUtils.SubQ_SynthChecksum(subQbuf, 0);
subQbuf[10] ^= 0xFF;
subQbuf[11] ^= 0xFF;
}
@@ -422,73 +421,199 @@ namespace BizHawk.Emulation.DiscSystem
static class SynthUtils
{
-
///
- /// Calculates the checksum of the provided Q subchannel
+ /// Calculates the checksum of the provided Q subchannel buffer and emplaces it
///
- /// 12 byte Q subchannel: input and output buffer for operation
+ /// 12 byte Q subchannel buffer: input and output buffer for operation
/// location within buffer of Q subchannel
- public static void SubQ_Checksum(byte[] buffer, int offset)
+ public static ushort SubQ_SynthChecksum(byte[] buf12, int offset)
{
- ushort crc16 = CRC16_CCITT.Calculate(buffer, offset, 10);
+ ushort crc16 = CRC16_CCITT.Calculate(buf12, offset, 10);
//CRC is stored inverted and big endian
- buffer[offset + 10] = (byte)(~(crc16 >> 8));
- buffer[offset + 11] = (byte)(~(crc16));
+ buf12[offset + 10] = (byte)(~(crc16 >> 8));
+ buf12[offset + 11] = (byte)(~(crc16));
+
+ return crc16;
}
- public static void SubP(byte[] buffer, int offset, bool pause)
+ ///
+ /// Caclulates the checksum of the provided Q subchannel buffer
+ ///
+ public static ushort SubQ_CalcChecksum(byte[] buf12, int offset)
+ {
+ return CRC16_CCITT.Calculate(buf12, offset, 10);
+ }
+
+ ///
+ /// Serializes the provided SubchannelQ structure into a buffer
+ /// Returns the crc, calculated or otherwise.
+ ///
+ public static ushort SubQ_Serialize(byte[] buf12, int offset, ref SubchannelQ sq)
+ {
+ buf12[offset + 0] = sq.q_status;
+ buf12[offset + 1] = sq.q_tno.BCDValue;
+ buf12[offset + 2] = sq.q_index.BCDValue;
+ buf12[offset + 3] = sq.min.BCDValue;
+ buf12[offset + 4] = sq.sec.BCDValue;
+ buf12[offset + 5] = sq.frame.BCDValue;
+ buf12[offset + 6] = sq.zero;
+ buf12[offset + 7] = sq.ap_min.BCDValue;
+ buf12[offset + 8] = sq.ap_sec.BCDValue;
+ buf12[offset + 9] = sq.ap_frame.BCDValue;
+
+ return SubQ_SynthChecksum(buf12, offset);
+ }
+
+ ///
+ /// Synthesizes the typical subP data into the provided buffer depending on the indicated pause flag
+ ///
+ public static void SubP(byte[] buffer12, int offset, bool pause)
{
byte val = (byte)(pause ? 0xFF : 0x00);
for (int i = 0; i < 12; i++)
- buffer[offset + i] = val;
+ buffer12[offset + i] = val;
}
- public static void SectorHeader(byte[] buffer, int offset, int LBA, byte mode)
+ ///
+ /// Synthesizes a data sector header
+ ///
+ public static void SectorHeader(byte[] buffer16, 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;
+ buffer16[offset + 0] = 0x00;
+ for (int i = 1; i < 11; i++) buffer16[offset + i] = 0xFF;
+ buffer16[offset + 11] = 0x00;
Timestamp ts = new Timestamp(LBA + 150);
- buffer[offset + 12] = BCD2.IntToBCD(ts.MIN);
- buffer[offset + 13] = BCD2.IntToBCD(ts.SEC);
- buffer[offset + 14] = BCD2.IntToBCD(ts.FRAC);
- buffer[offset + 15] = mode;
+ buffer16[offset + 12] = BCD2.IntToBCD(ts.MIN);
+ buffer16[offset + 13] = BCD2.IntToBCD(ts.SEC);
+ buffer16[offset + 14] = BCD2.IntToBCD(ts.FRAC);
+ buffer16[offset + 15] = mode;
}
- public static void EDC_Mode2_Form1(byte[] buffer, int offset)
+ ///
+ /// Synthesizes the EDC checksum for a Mode 2 Form 1 data sector (and puts it in place)
+ ///
+ public static void EDC_Mode2_Form1(byte[] buf2352, int offset)
{
- uint edc = ECM.EDC_Calc(buffer, offset + 16, 2048 + 8);
- ECM.PokeUint(buffer, offset + 2072, edc);
+ uint edc = ECM.EDC_Calc(buf2352, offset + 16, 2048 + 8);
+ ECM.PokeUint(buf2352, offset + 2072, edc);
}
- public static void EDC_Mode2_Form2(byte[] buffer, int offset)
+ ///
+ /// Synthesizes the EDC checksum for a Mode 2 Form 2 data sector (and puts it in place)
+ ///
+ public static void EDC_Mode2_Form2(byte[] buf2352, int offset)
{
- uint edc = ECM.EDC_Calc(buffer, offset + 16, 2324 + 8);
- ECM.PokeUint(buffer, offset + 2348, edc);
+ uint edc = ECM.EDC_Calc(buf2352, offset + 16, 2324 + 8);
+ ECM.PokeUint(buf2352, offset + 2348, edc);
}
///
+ /// Synthesizes the complete ECM data (EDC + ECC) for a Mode 1 data sector (and puts it in place)
/// Make sure everything else in the sector userdata is done before calling this
///
- public static void ECM_Mode1(byte[] buffer, int offset, int LBA)
+ public static void ECM_Mode1(byte[] buf2352, int offset, int LBA)
{
//EDC
- uint edc = ECM.EDC_Calc(buffer, offset, 2064);
- ECM.PokeUint(buffer, offset + 2064, edc);
+ uint edc = ECM.EDC_Calc(buf2352, offset, 2064);
+ ECM.PokeUint(buf2352, offset + 2064, edc);
//reserved, zero
- for (int i = 0; i < 8; i++) buffer[offset + 2068 + i] = 0;
+ for (int i = 0; i < 8; i++) buf2352[offset + 2068 + i] = 0;
//ECC
- ECM.ECC_Populate(buffer, offset, buffer, offset, false);
+ ECM.ECC_Populate(buf2352, offset, buf2352, offset, false);
+ }
+
+ ///
+ /// Converts the useful (but unrealistic) deinterleaved subchannel data into the useless (but realistic) interleaved format.
+ /// in_buf and out_buf should not overlap
+ ///
+ public static void InterleaveSubcode(byte[] in_buf, int in_buf_index, byte[] out_buf, int out_buf_index)
+ {
+ for (int d = 0; d < 12; d++)
+ {
+ for (int bitpoodle = 0; bitpoodle < 8; bitpoodle++)
+ {
+ int rawb = 0;
+
+ for (int ch = 0; ch < 8; ch++)
+ {
+ rawb |= ((in_buf[ch * 12 + d + in_buf_index] >> (7 - bitpoodle)) & 1) << (7 - ch);
+ }
+ out_buf[(d << 3) + bitpoodle + out_buf_index] = (byte)rawb;
+ }
+ }
+ }
+
+ ///
+ /// Converts the useless (but realistic) interleaved subchannel data into a useful (but unrealistic) deinterleaved format.
+ /// in_buf and out_buf should not overlap
+ ///
+ public static void DeinterleaveSubcode(byte[] in_buf, int in_buf_index, byte[] out_buf, int out_buf_index)
+ {
+ for (int i = 0; i < 96; i++)
+ out_buf[i] = 0;
+
+ for (int ch = 0; ch < 8; ch++)
+ {
+ for (int i = 0; i < 96; i++)
+ {
+ out_buf[(ch * 12) + (i >> 3) + out_buf_index] |= (byte)(((in_buf[i + in_buf_index] >> (7 - ch)) & 0x1) << (7 - (i & 0x7)));
+ }
+ }
+ }
+
+ ///
+ /// Converts the useful (but unrealistic) deinterleaved data into the useless (but realistic) interleaved subchannel format.
+ ///
+ public unsafe static void InterleaveSubcodeInplace(byte[] buf, int buf_index)
+ {
+ byte* out_buf = stackalloc byte[96];
+
+ for (int i = 0; i < 96; i++)
+ out_buf[i] = 0;
+
+ for (int d = 0; d < 12; d++)
+ {
+ for (int bitpoodle = 0; bitpoodle < 8; bitpoodle++)
+ {
+ int rawb = 0;
+
+ for (int ch = 0; ch < 8; ch++)
+ {
+ rawb |= ((buf[ch * 12 + d + buf_index] >> (7 - bitpoodle)) & 1) << (7 - ch);
+ }
+ out_buf[(d << 3) + bitpoodle] = (byte)rawb;
+ }
+ }
+
+ for (int i = 0; i < 96; i++)
+ buf[i + buf_index] = out_buf[i];
+ }
+
+ ///
+ /// Converts the useless (but realistic) interleaved subchannel data into a useful (but unrealistic) deinterleaved format.
+ ///
+ public unsafe static void DeinterleaveSubcodeInplace(byte[] buf, int buf_index)
+ {
+ byte* out_buf = stackalloc byte[96];
+
+ for (int i = 0; i < 96; i++)
+ out_buf[i] = 0;
+
+ for (int ch = 0; ch < 8; ch++)
+ {
+ for (int i = 0; i < 96; i++)
+ {
+ out_buf[(ch * 12) + (i >> 3)] |= (byte)(((buf[i + buf_index] >> (7 - ch)) & 0x1) << (7 - (i & 0x7)));
+ }
+ }
+
+ for (int i = 0; i < 96; i++)
+ buf[i + buf_index] = out_buf[i];
}
}
- //not being used yet
- class DiscPreferences
- {
-
- }
}
\ No newline at end of file
diff --git a/BizHawk.Emulation.DiscSystem/DiscTypes.cs b/BizHawk.Emulation.DiscSystem/DiscTypes.cs
index 49ae05f19d..9d502a58ad 100644
--- a/BizHawk.Emulation.DiscSystem/DiscTypes.cs
+++ b/BizHawk.Emulation.DiscSystem/DiscTypes.cs
@@ -19,29 +19,4 @@ namespace BizHawk.Emulation.DiscSystem
{
BizHawk, MednaDisc, LibMirage
}
-
-
-
- ///
- /// Main unit of organization for reading data from the disc. Represents one physical disc sector.
- ///
- public class SectorEntry
- {
- public SectorEntry(ISector sec) { Sector = sec; }
-
- internal ISectorSynthJob2448 SectorSynth;
-
- ///
- /// Access the --whatsitcalled-- normal data for the sector with this
- ///
- public ISector Sector;
-
- ///
- /// Access the subcode data for the sector
- ///
- public ISubcodeSector SubcodeSector;
-
- //todo - add a PARAMETER fields to this (a long, maybe) so that the ISector can use them (so that each ISector doesnt have to be constructed also)
- //also then, maybe this could be a struct
- }
}
\ No newline at end of file
diff --git a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs
index 85f0a6d109..2a2a57b243 100644
--- a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs
+++ b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs
@@ -18,7 +18,7 @@ namespace BizHawk.Emulation.DiscSystem
//we may still need to deinterleave it if subcode was requested and it needs deinterleaving
if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave | ESectorSynthPart.SubcodeAny)) != 0)
{
- SubcodeUtils.DeinterleaveInplace(job.DestBuffer2448, 2352);
+ SynthUtils.DeinterleaveSubcodeInplace(job.DestBuffer2448, 2352);
}
}
}
@@ -26,6 +26,7 @@ namespace BizHawk.Emulation.DiscSystem
void RunMednaDisc()
{
var disc = new Disc();
+ OUT_Disc = disc;
//create a MednaDisc and give it to the disc for ownership
var md = new MednaDisc(IN_FromPath);
@@ -43,27 +44,17 @@ namespace BizHawk.Emulation.DiscSystem
//make sector interfaces:
var pregap_sector_zero = new Sector_Zero();
- var pregap_subcode_zero = new ZeroSubcodeSector();
for (int i = 0; i < 150; i++)
{
- var se = new SectorEntry(pregap_sector_zero);
- se.SectorSynth = synth;
- disc.Sectors.Add(se);
- se.SubcodeSector = pregap_subcode_zero;
+ disc.Sectors.Add(synth);
}
//2. actual sectors
for (int i = 0; i < nSectors; i++)
{
- //var sectorInterface = new MednaDiscSectorInterface() { LBA = i, md = md };
- var se = new SectorEntry(null);
- //se.SubcodeSector = new MednaDiscSubcodeSectorInterface() { LBA = i, md = md };
- se.SectorSynth = synth;
- disc.Sectors.Add(se);
+ disc.Sectors.Add(synth);
}
- BufferedSubcodeSector bss = new BufferedSubcodeSector(); //TODO - its hacky that we need this..
-
//ADR (q-Mode) is necessarily 0x01 for a RawTOCEntry
const int kADR = 1;
const int kUnknownControl = 0;
@@ -96,15 +87,13 @@ namespace BizHawk.Emulation.DiscSystem
ap_min = BCD2.FromDecimal(m_ts.MIN),
ap_sec = BCD2.FromDecimal(m_ts.SEC),
ap_frame = BCD2.FromDecimal(m_ts.FRAC),
+ q_crc = 0 //meaningless
};
//a special fixup: mednafen's entry 100 is the lead-out track
if (i == 100)
q.q_index.BCDValue = 0xA2;
- //CRC cant be calculated til we've got all the fields setup
- q.q_crc = bss.Synthesize_SubchannelQ(ref q, true);
-
disc.RawTOCEntries.Add(new RawTOCEntry { QData = q });
}
@@ -121,8 +110,8 @@ namespace BizHawk.Emulation.DiscSystem
ap_min = BCD2.FromDecimal(md.TOC.first_track),
ap_sec = BCD2.FromDecimal(0),
ap_frame = BCD2.FromDecimal(0),
+ q_crc = 0, //meaningless
};
- qA1.q_crc = bss.Synthesize_SubchannelQ(ref qA1, true);
disc.RawTOCEntries.Add(new RawTOCEntry { QData = qA1 });
var qA2 = new SubchannelQ
{
@@ -136,44 +125,10 @@ namespace BizHawk.Emulation.DiscSystem
ap_min = BCD2.FromDecimal(md.TOC.last_track),
ap_sec = BCD2.FromDecimal(0),
ap_frame = BCD2.FromDecimal(0),
+ q_crc = 0, //meaningless
};
- qA2.q_crc = bss.Synthesize_SubchannelQ(ref qA2, true);
disc.RawTOCEntries.Add(new RawTOCEntry { QData = qA2 });
- //generate the toc from the entries. still not sure we're liking this idea
- var tocSynth = new DiscTOCRaw.SynthesizeFromRawTOCEntriesJob() { Entries = disc.RawTOCEntries };
- tocSynth.Run();
- disc.TOCRaw = tocSynth.Result;
-
- //DO THIS IN A MORE UNIFORM WAY PLEASE
- //setup the DiscStructure
- //disc.Structure = new DiscStructure();
- //var ses = new DiscStructure.Session();
- //disc.Structure.Sessions.Add(ses);
- //for (int i = 1; i < 100; i++)
- //{
- // var m_te = md.TOCTracks[i];
- // if (!m_te.Valid) continue;
-
- // DiscStructure.Track track = new DiscStructure.Track() { Number = i };
- // ses.Tracks.Add(track);
- // if ((m_te.control & (int)EControlQ.DATA) == 0)
- // track.IsData = false;
- // else
- // track.IsData = true;
-
- // track.Start_LBA = (int)m_te.lba;
- // track.
-
- // //from mednafen, we couldnt build the index 0, and that's OK, since that's not really a sensible thing in CD terms anyway.
- // //I need to refactor this thing to oblivion
- // //track.Indexes.Add(new DiscStructure.Index { Number = 0, LBA = (int)m_te.lba }); //<-- not accurate, but due for deletion
- // //track.Indexes.Add(new DiscStructure.Index { Number = 1, LBA = (int)m_te.lba });
- //}
-
- //NOT FULLY COMPLETE
-
- OUT_Disc = disc;
}
}
}
\ No newline at end of file
diff --git a/BizHawk.Emulation.DiscSystem/Jobs/Synthesize_A0A1A2_Job.cs b/BizHawk.Emulation.DiscSystem/Jobs/Synthesize_A0A1A2_Job.cs
index 0a038cfb53..275d81c5a5 100644
--- a/BizHawk.Emulation.DiscSystem/Jobs/Synthesize_A0A1A2_Job.cs
+++ b/BizHawk.Emulation.DiscSystem/Jobs/Synthesize_A0A1A2_Job.cs
@@ -41,8 +41,6 @@ namespace BizHawk.Emulation.DiscSystem
{
SubchannelQ sq = new SubchannelQ();
- BufferedSubcodeSector bss = new BufferedSubcodeSector(); //TODO - its hacky that we need this.. (NOT USED YET)
-
//ADR (q-Mode) is necessarily 0x01 for a RawTOCEntry
const int kADR = 1;
const int kUnknownControl = 0;
diff --git a/BizHawk.Emulation.DiscSystem/Subcode.cs b/BizHawk.Emulation.DiscSystem/Subcode.cs
index 45ba1bebb5..c138ac5be7 100644
--- a/BizHawk.Emulation.DiscSystem/Subcode.cs
+++ b/BizHawk.Emulation.DiscSystem/Subcode.cs
@@ -17,224 +17,6 @@
namespace BizHawk.Emulation.DiscSystem
{
- //YET ANOTHER BAD IDEA
- public interface ISubcodeSector
- {
- ///
- /// reads 96 bytes of subcode data (deinterleaved) for this sector into the supplied buffer
- ///
- void ReadSubcodeDeinterleaved(byte[] buffer, int offset);
-
- ///
- /// Reads just one of the channels. p=0, q=1, etc.
- ///
- void ReadSubcodeChannel(int number, byte[] buffer, int offset);
- }
-
- public static class SubcodeUtils
- {
- ///
- /// Converts the useful (but unrealistic) deinterleaved data into the useless (but realistic) interleaved subchannel format.
- /// in_buf and out_buf should not overlap
- ///
- public static void Interleave(byte[] in_buf, int in_buf_index, byte[] out_buf, int out_buf_index)
- {
- for (int d = 0; d < 12; d++)
- {
- for (int bitpoodle = 0; bitpoodle < 8; bitpoodle++)
- {
- int rawb = 0;
-
- for (int ch = 0; ch < 8; ch++)
- {
- rawb |= ((in_buf[ch * 12 + d + in_buf_index] >> (7 - bitpoodle)) & 1) << (7 - ch);
- }
- out_buf[(d << 3) + bitpoodle + out_buf_index] = (byte)rawb;
- }
- }
- }
-
- ///
- /// Converts the useless (but realistic) interleaved subchannel data into a useful (but unrealistic) deinterleaved format.
- /// in_buf and out_buf should not overlap
- ///
- public static void Deinterleave(byte[] in_buf, int in_buf_index, byte[] out_buf, int out_buf_index)
- {
- for (int i = 0; i < 96; i++)
- out_buf[i] = 0;
-
- for (int ch = 0; ch < 8; ch++)
- {
- for (int i = 0; i < 96; i++)
- {
- out_buf[(ch * 12) + (i >> 3) + out_buf_index] |= (byte)(((in_buf[i + in_buf_index] >> (7 - ch)) & 0x1) << (7 - (i & 0x7)));
- }
- }
- }
-
- ///
- /// Converts the useful (but unrealistic) deinterleaved data into the useless (but realistic) interleaved subchannel format.
- ///
- public unsafe static void InterleaveInplace(byte[] buf, int buf_index)
- {
- byte* out_buf = stackalloc byte[96];
-
- for (int i = 0; i < 96; i++)
- out_buf[i] = 0;
-
- for (int d = 0; d < 12; d++)
- {
- for (int bitpoodle = 0; bitpoodle < 8; bitpoodle++)
- {
- int rawb = 0;
-
- for (int ch = 0; ch < 8; ch++)
- {
- rawb |= ((buf[ch * 12 + d + buf_index] >> (7 - bitpoodle)) & 1) << (7 - ch);
- }
- out_buf[(d << 3) + bitpoodle] = (byte)rawb;
- }
- }
-
- for (int i = 0; i < 96; i++)
- buf[i + buf_index] = out_buf[i];
- }
-
- ///
- /// Converts the useless (but realistic) interleaved subchannel data into a useful (but unrealistic) deinterleaved format.
- ///
- public unsafe static void DeinterleaveInplace(byte[] buf, int buf_index)
- {
- byte* out_buf = stackalloc byte[96];
-
- for (int i = 0; i < 96; i++)
- out_buf[i] = 0;
-
- for (int ch = 0; ch < 8; ch++)
- {
- for (int i = 0; i < 96; i++)
- {
- out_buf[(ch * 12) + (i >> 3)] |= (byte)(((buf[i + buf_index] >> (7 - ch)) & 0x1) << (7 - (i & 0x7)));
- }
- }
-
- for (int i = 0; i < 96; i++)
- buf[i + buf_index] = out_buf[i];
- }
- }
-
-
- ///
- /// Reads subcode from an internally-managed buffer
- ///
- class BufferedSubcodeSector : ISubcodeSector
- {
- public void Synthesize_SubchannelP(bool pause)
- {
- byte val = pause ? (byte)0xFF : (byte)0x00;
- for (int i = 0; i < 12; i++)
- SubcodeDeinterleaved[i] = val;
- }
-
- ///
- /// Fills this subcode buffer with subchannel Q data. calculates the required CRC, as well.
- /// Returns the crc, calculated or otherwise.
- ///
- public ushort Synthesize_SubchannelQ(ref SubchannelQ sq, bool calculateCRC)
- {
- int offset = 12; //Q subchannel begins after P, 12 bytes in
- SubcodeDeinterleaved[offset + 0] = sq.q_status;
- SubcodeDeinterleaved[offset + 1] = sq.q_tno.BCDValue;
- SubcodeDeinterleaved[offset + 2] = sq.q_index.BCDValue;
- SubcodeDeinterleaved[offset + 3] = sq.min.BCDValue;
- SubcodeDeinterleaved[offset + 4] = sq.sec.BCDValue;
- SubcodeDeinterleaved[offset + 5] = sq.frame.BCDValue;
- SubcodeDeinterleaved[offset + 6] = sq.zero;
- SubcodeDeinterleaved[offset + 7] = sq.ap_min.BCDValue;
- SubcodeDeinterleaved[offset + 8] = sq.ap_sec.BCDValue;
- SubcodeDeinterleaved[offset + 9] = sq.ap_frame.BCDValue;
-
- ushort crc16;
- if (calculateCRC)
- crc16 = CRC16_CCITT.Calculate(SubcodeDeinterleaved, offset, 10);
- else crc16 = sq.q_crc;
-
- //CRC is stored inverted and big endian
- SubcodeDeinterleaved[offset + 10] = (byte)(~(crc16 >> 8));
- SubcodeDeinterleaved[offset + 11] = (byte)(~(crc16));
-
- return crc16;
- }
-
- public void Synthesize_SunchannelQ_Checksum()
- {
- int offset = 12; //Q subchannel begins after P, 12 bytes in
-
- ushort crc16 = CRC16_CCITT.Calculate(SubcodeDeinterleaved, offset, 10);
-
- //CRC is stored inverted and big endian
- SubcodeDeinterleaved[offset + 10] = (byte)(~(crc16 >> 8));
- SubcodeDeinterleaved[offset + 11] = (byte)(~(crc16));
- }
-
- public void ReadSubcodeDeinterleaved(byte[] buffer, int offset)
- {
- Buffer.BlockCopy(SubcodeDeinterleaved, 0, buffer, offset, 96);
- }
-
- public void ReadSubcodeChannel(int number, byte[] buffer, int offset)
- {
- Buffer.BlockCopy(SubcodeDeinterleaved, number * 12, buffer, offset, 12);
- }
-
- public BufferedSubcodeSector()
- {
- SubcodeDeinterleaved = new byte[96];
- }
-
- public static BufferedSubcodeSector CloneFromBytesDeinterleaved(byte[] buffer)
- {
- var ret = new BufferedSubcodeSector();
- Buffer.BlockCopy(buffer, 0, ret.SubcodeDeinterleaved, 0, 96);
- return ret;
- }
-
- public byte[] SubcodeDeinterleaved;
- }
-
- public class ZeroSubcodeSector : ISubcodeSector
- {
- public void ReadSubcodeDeinterleaved(byte[] buffer, int offset)
- {
- for (int i = 0; i < 96; i++) buffer[i + offset] = 0;
- }
-
- public void ReadSubcodeChannel(int number, byte[] buffer, int offset)
- {
- for (int i = 0; i < 12; i++)
- buffer[i + offset] = 0;
- }
- }
-
- ///
- /// Reads subcode data from a blob, assuming it was already stored in deinterleaved format
- ///
- public class BlobSubcodeSectorPreDeinterleaved : ISubcodeSector
- {
- public void ReadSubcodeDeinterleaved(byte[] buffer, int offset)
- {
- Blob.Read(Offset, buffer, offset, 96);
- }
-
- public void ReadSubcodeChannel(int number, byte[] buffer, int offset)
- {
- Blob.Read(Offset + number * 12, buffer, offset, 12);
- }
-
- public IBlob Blob;
- public long Offset;
- }
-
///
/// Control bit flags for the Q Subchannel.
///
@@ -277,8 +59,8 @@ namespace BizHawk.Emulation.DiscSystem
///
/// These are the initial set of timestamps. Meaning varies:
/// check yellowbook 22.3.3 and 22.3.4
- /// normal track: relative timestamp
/// leadin track: unknown
+ /// user information track: relative timestamp
/// leadout: relative timestamp
/// TODO - why are these BCD2? having things in BCD2 is freaking annoying, I should only make them BCD2 when serializing into a subchannel Q buffer
/// EDIT - elsewhere I rambled "why not BCD2?". geh. need to make a final organized approach
@@ -293,17 +75,16 @@ namespace BizHawk.Emulation.DiscSystem
///
/// These are the second set of timestamps. Meaning varies:
/// check yellowbook 22.3.3 and 22.3.4
- /// normal track: absolute timestamp
/// leadin track q-mode 1: TOC entry, absolute MSF of track
+ /// user information track: absolute timestamp
/// leadout: absolute timestamp
///
public BCD2 ap_min, ap_sec, ap_frame;
///
- /// The CRC. This is the actual CRC value as would be calculated from our library (it is inverted and written big endian to the disc)
- /// Don't assume this CRC is correct-- If this SubchannelQ was read from a dumped disc, the CRC might be wrong.
- /// CCD doesnt specify this for TOC entries, so it will be wrong. It may or may not be right for data track sectors from a CCD file.
- /// Or we may have computed this SubchannelQ data and generated the correct CRC at that time.
+ /// Don't assume this CRC is correct, in the case of some copy protections it is intended to be wrong.
+ /// Furthermore, it is meaningless (and in BizHawk, unpopulated) for a TOC Entry
+ /// (since an invalid CRC on a [theyre redundantly/duplicately stored] toc entry would cause it to get discarded in favor of another one with a correct CRC)
///
public ushort q_crc;
@@ -390,24 +171,4 @@ namespace BizHawk.Emulation.DiscSystem
}
}
- public class SubcodeDataDecoder
- {
- ///
- /// This seems to deinterleave Q from a subcode buffer? Not sure.. it isn't getting used anywhere right now, as you can see.
- ///
- public static void Unpack_Q(byte[] output, int out_ofs, byte[] input, int in_ofs)
- {
- for (int i = 0; i < 12; i++)
- output[out_ofs + i] = 0;
- for (int i = 0; i < 96; i++)
- {
- int bytenum = i >> 3;
- int bitnum = i & 7;
- bitnum = 7 - bitnum;
- int bitval = (byte)((input[in_ofs + i] >> 6) & 1);
- bitval <<= bitnum;
- output[out_ofs + bytenum] |= (byte)bitval;
- }
- }
- }
}