diff --git a/BizHawk.Emulation.DiscSystem/CCD_format.cs b/BizHawk.Emulation.DiscSystem/CCD_format.cs
index 0deac090cf..5bb6cd2be8 100644
--- a/BizHawk.Emulation.DiscSystem/CCD_format.cs
+++ b/BizHawk.Emulation.DiscSystem/CCD_format.cs
@@ -462,10 +462,10 @@ namespace BizHawk.Emulation.DiscSystem
long ofs = job.LBA * 96;
subBlob.Read(ofs, job.DestBuffer2448, 2352, 96);
- //sub data comes to us deinterleved; we may still need to interleave it
+ //subcode comes to us deinterleved; we may still need to interleave it
if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave)) == 0)
{
- SubcodeUtils.InterleaveInplace(job.DestBuffer2448, 2352);
+ SubcodeUtils.InterleaveInplace(job.DestBuffer2448, job.DestOffset + 2352);
}
}
}
diff --git a/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs b/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
index 1d2fa3234e..230ea8d415 100644
--- a/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
+++ b/BizHawk.Emulation.DiscSystem/CUE/CUE_Load.cs
@@ -219,6 +219,9 @@ namespace BizHawk.Emulation.DiscSystem
OUT_Disc.Sectors.Add(se_pregap);
}
+ //TODO - build track relative timestamp now and increment it continually
+
+
//after this, pregap sectors are generated like a normal sector, but the subQ is specified as a pregap instead of a normal track (actually, TBD)
//---------------------------------
@@ -274,19 +277,7 @@ namespace BizHawk.Emulation.DiscSystem
break;
}
- //make the subcode
- //TODO - according to policies, or better yet, defer this til it's needed (user delivers a policies object to disc reader apis)
- //at any rate, we'd paste this logic into there so let's go ahead and write it here
- var subcode = new BufferedSubcodeSector(); //(its lame that we have to use this; make a static method when we delete this class)
- SubchannelQ sq = new SubchannelQ();
- byte ADR = 1; //absent some kind of policy for how to set it, this is a safe assumption:
- sq.SetStatus(ADR, (EControlQ)(int)cct.Flags);
- sq.q_tno = BCD2.FromDecimal(cct.Number);
- sq.q_index = BCD2.FromDecimal(curr_index);
- int LBA = OUT_Disc.Sectors.Count;
- sq.ap_min = BCD2.FromDecimal(new Timestamp(LBA).MIN);
- sq.ap_sec = BCD2.FromDecimal(new Timestamp(LBA).SEC);
- sq.ap_frame = BCD2.FromDecimal(new Timestamp(LBA).FRAC);
+ //prepare fields for subQ
int track_relative_msf = curr_blobMSF - cct.Indexes[1].FileMSF.Sector;
//for index 0, negative MSF required and encoded oppositely. Read more at Policies declaration
@@ -301,20 +292,21 @@ namespace BizHawk.Emulation.DiscSystem
else
if (track_relative_msf < 0) throw new InvalidOperationException("Severe error generating cue subQ (negative relMSF for non-pregap)");
- sq.min = BCD2.FromDecimal(new Timestamp(track_relative_msf).MIN);
- sq.sec = BCD2.FromDecimal(new Timestamp(track_relative_msf).SEC);
- sq.frame = BCD2.FromDecimal(new Timestamp(track_relative_msf).FRAC);
- //finally we're done: synthesize subchannel
- subcode.Synthesize_SubchannelQ(ref sq, true);
+ //setup subQ
+ byte ADR = 1; //absent some kind of policy for how to set it, this is a safe assumption:
+ ss.sq.SetStatus(ADR, (EControlQ)(int)cct.Flags);
+ ss.sq.q_tno = BCD2.FromDecimal(cct.Number);
+ ss.sq.q_index = BCD2.FromDecimal(curr_index);
+ ss.sq.AP_Timestamp = new Timestamp(OUT_Disc.Sectors.Count);
+ ss.sq.Timestamp = new Timestamp(track_relative_msf);
- //generate subP
+ //setup subP
if (curr_index == 0)
ss.Pause = true;
//make the SectorEntry (some temporary bullshit here)
var se = new SectorEntry(null);
se.SectorSynth = ss;
- ss.sq = sq;
OUT_Disc.Sectors.Add(se);
curr_blobMSF++;
@@ -342,14 +334,26 @@ namespace BizHawk.Emulation.DiscSystem
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_Gap();
+ var se= new SectorEntry(null);
+ var ss = new SS_Gap();
- //postgaps set pause flag. is this good enough?
- ss_pregap.Pause = true;
+ //-subq-
+ //postgap addressing continues from
+ int lastSectorRelMSF = curr_blobMSF - cct.Indexes[1].FileMSF.Sector - 1;
+ int postgapSectorRelMSF = lastSectorRelMSF + s + 1;
+ byte ADR = 1;
+ ss.sq.SetStatus(ADR, (EControlQ)(int)cct.Flags);
+ ss.sq.q_tno = BCD2.FromDecimal(cct.Number);
+ ss.sq.q_index = BCD2.FromDecimal(curr_index);
+ ss.sq.AP_Timestamp = new Timestamp(OUT_Disc.Sectors.Count);
+ ss.sq.Timestamp = new Timestamp(postgapSectorRelMSF);
- se_pregap.SectorSynth = ss_pregap;
- OUT_Disc.Sectors.Add(se_pregap);
+ //-subP-
+ //always paused--is this good enough?
+ ss.Pause = true;
+
+ se.SectorSynth = ss;
+ OUT_Disc.Sectors.Add(se);
}
@@ -370,13 +374,9 @@ namespace BizHawk.Emulation.DiscSystem
tocSynth.Run();
OUT_Disc.TOCRaw = tocSynth.Result;
- ////generate lead-out track with some canned number of sectors
- ////TODO - move this somewhere else and make it controllable depending on which console is loading up the disc
- ////TODO - we're not doing this yet
- ////var synthLeadoutJob = new Disc.SynthesizeLeadoutJob { Disc = disc, Length = 150 };
- ////synthLeadoutJob.Run();
+ //TODO - generate leadout, or delegates at least
- ////blech, old crap, maybe
+ //blech, old crap, maybe
//OUT_Disc.Structure.Synthesize_TOCPointsFromSessions();
//FinishLog();
diff --git a/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs b/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
index 8d3477b08b..080b3e08e5 100644
--- a/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
+++ b/BizHawk.Emulation.DiscSystem/CUE/CUE_Synths.cs
@@ -6,6 +6,7 @@ namespace BizHawk.Emulation.DiscSystem
{
partial class CUE_Format2
{
+
abstract class SS_Base : ISectorSynthJob2448
{
public IBlob Blob;
@@ -17,17 +18,31 @@ namespace BizHawk.Emulation.DiscSystem
protected void SynthSubcode(SectorSynthJob job)
{
+ //synth P if needed
if ((job.Parts & ESectorSynthPart.SubchannelP) != 0)
{
SynthUtils.SubP(job.DestBuffer2448, job.DestOffset + 2352, Pause);
}
+ //synth Q if needed
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);
}
+
+ //clear R-W if needed
+ if ((job.Parts & ESectorSynthPart.Subchannel_RSTUVW) != 0)
+ {
+ Array.Clear(job.DestBuffer2448, job.DestOffset + 2352 + 12 + 12, (12 * 6));
+ }
+
+ //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);
+ }
}
}
@@ -46,9 +61,9 @@ namespace BizHawk.Emulation.DiscSystem
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 + 12] = BCD2.IntToBCD(ts.MIN);
+ buffer[offset + 13] = BCD2.IntToBCD(ts.SEC);
+ buffer[offset + 14] = BCD2.IntToBCD(ts.FRAC);
buffer[offset + 15] = mode;
}
diff --git a/BizHawk.Emulation.DiscSystem/Disc.cs b/BizHawk.Emulation.DiscSystem/Disc.cs
index 2e8d598d43..50032b65dd 100644
--- a/BizHawk.Emulation.DiscSystem/Disc.cs
+++ b/BizHawk.Emulation.DiscSystem/Disc.cs
@@ -425,10 +425,12 @@ namespace BizHawk.Emulation.DiscSystem
SEC = (byte)((str[3] - '0') * 10 + (str[4] - '0'));
FRAC = (byte)((str[6] - '0') * 10 + (str[7] - '0'));
Valid = true;
+ Negative = false;
return;
BOGUS:
MIN = SEC = FRAC = 0;
Valid = false;
+ Negative = false;
return;
}
@@ -440,12 +442,12 @@ namespace BizHawk.Emulation.DiscSystem
get
{
if (!Valid) return "--:--:--";
- return string.Format("{0:D2}:{1:D2}:{2:D2}", MIN, SEC, FRAC);
+ return string.Format("{0}{1:D2}:{2:D2}:{3:D2}", Negative?'-':'+',MIN, SEC, FRAC);
}
}
public readonly byte MIN, SEC, FRAC;
- public readonly bool Valid;
+ public readonly bool Valid, Negative;
///
/// The fully multiplied out flat-address Sector number
@@ -461,6 +463,7 @@ namespace BizHawk.Emulation.DiscSystem
SEC = (byte)s;
FRAC = (byte)f;
Valid = true;
+ Negative = false;
}
///
@@ -468,6 +471,12 @@ namespace BizHawk.Emulation.DiscSystem
///
public Timestamp(int SectorNumber)
{
+ if (SectorNumber < 0)
+ {
+ SectorNumber = -SectorNumber;
+ Negative = true;
+ }
+ else Negative = false;
MIN = (byte)(SectorNumber / (60 * 75));
SEC = (byte)((SectorNumber / 75) % 60);
FRAC = (byte)(SectorNumber % 75);
diff --git a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs
index 6864c84356..ef58bfb819 100644
--- a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs
+++ b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.MednaDisc.cs
@@ -42,14 +42,14 @@ namespace BizHawk.Emulation.DiscSystem
var synth = new SS_MednaDisc();
//make sector interfaces:
- //1. right now for dumb reasons we have 150 lead-in sectors. I want to get rid of this crap.
- var leadin_sector_zero = new Sector_Zero();
- var leadin_subcode_zero = new ZeroSubcodeSector();
+ var pregap_sector_zero = new Sector_Zero();
+ var pregap_subcode_zero = new ZeroSubcodeSector();
for (int i = 0; i < 150; i++)
{
- var se = new SectorEntry(leadin_sector_zero);
+ var se = new SectorEntry(pregap_sector_zero);
+ se.SectorSynth = synth;
disc.Sectors.Add(se);
- se.SubcodeSector = leadin_subcode_zero;
+ se.SubcodeSector = pregap_subcode_zero;
}
//2. actual sectors
diff --git a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs
index adbaf394fc..b3effbe596 100644
--- a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs
+++ b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs
@@ -19,8 +19,10 @@ namespace BizHawk.Emulation.DiscSystem
/// During the Pause this relative time decreases and
/// --B-- equals zero in the last Section"
/// This is a contradiction.
- /// By choosing true, mode A is selected, and the final sector of the pause is -1. I like this better. Defaulting until proven otherwise (write test case here)
- /// By choosing false, mode B is selected, and the final sector of the pause is 0. Mednafen does it this way.
+ /// By choosing true, mode A is selected, and the final sector of the pause is -1.
+ /// (I like this better. Defaulting until proven otherwise [write test case here])
+ /// By choosing false, mode B is selected, and the final sector of the pause is 0.
+ /// (Mednafen does it this way)
/// Discs (including PSX) exist using A, or B, or possibly (reference please) neither.
///
public bool CUE_PauseContradictionModeA = true;
diff --git a/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs b/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs
index 4d04aed806..6ed5c54f7f 100644
--- a/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs
+++ b/BizHawk.Emulation.DiscSystem/SectorInterfaces.cs
@@ -88,10 +88,15 @@ namespace BizHawk.Emulation.DiscSystem
///
SubchannelQ = 32,
+ ///
+ /// Subchannels R-W (all except for P and Q)
+ ///
+ Subchannel_RSTUVW = (64|128|256|512|1024|2048),
+
///
/// Complete subcode is required
///
- SubcodeComplete = (16|32|64|128|256|512|1024|2048),
+ SubcodeComplete = (SubchannelP | SubchannelQ | Subchannel_RSTUVW),
///
/// Any of the subcode might be required (just another way of writing SubcodeComplete)
diff --git a/BizHawk.Emulation.DiscSystem/Subcode.cs b/BizHawk.Emulation.DiscSystem/Subcode.cs
index 1b60755aa1..45ba1bebb5 100644
--- a/BizHawk.Emulation.DiscSystem/Subcode.cs
+++ b/BizHawk.Emulation.DiscSystem/Subcode.cs
@@ -310,7 +310,11 @@ namespace BizHawk.Emulation.DiscSystem
///
/// Retrieves the initial set of timestamps (min,sec,frac) as a convenient Timestamp
///
- public Timestamp Timestamp { get { return new Timestamp(min.DecimalValue, sec.DecimalValue, frame.DecimalValue); } }
+ public Timestamp Timestamp
+ {
+ get { return new Timestamp(min.DecimalValue, sec.DecimalValue, frame.DecimalValue); }
+ set { min.DecimalValue = value.MIN; sec.DecimalValue = value.SEC; frame.DecimalValue = value.FRAC; }
+ }
///
/// Retrieves the second set of timestamps (ap_min, ap_sec, ap_frac) as a convenient Timestamp.