cue postgap subQ. print negative Timestamps, even though I'm becoming less and less a fan of that class
This commit is contained in:
parent
4e8f649512
commit
5bb7d5e707
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -468,6 +471,12 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
/// </summary>
|
||||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
/// </summary>
|
||||
public bool CUE_PauseContradictionModeA = true;
|
||||
|
|
|
@ -88,10 +88,15 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
/// </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 = (16|32|64|128|256|512|1024|2048),
|
||||
SubcodeComplete = (SubchannelP | SubchannelQ | Subchannel_RSTUVW),
|
||||
|
||||
/// <summary>
|
||||
/// Any of the subcode might be required (just another way of writing SubcodeComplete)
|
||||
|
|
|
@ -310,7 +310,11 @@ namespace BizHawk.Emulation.DiscSystem
|
|||
/// <summary>
|
||||
/// Retrieves the initial set of timestamps (min,sec,frac) as a convenient Timestamp
|
||||
/// </summary>
|
||||
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; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the second set of timestamps (ap_min, ap_sec, ap_frac) as a convenient Timestamp.
|
||||
|
|
Loading…
Reference in New Issue