cue postgap subQ. print negative Timestamps, even though I'm becoming less and less a fan of that class

This commit is contained in:
zeromus 2015-07-01 05:26:10 -05:00
parent 4e8f649512
commit 5bb7d5e707
8 changed files with 83 additions and 48 deletions

View File

@ -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);
}
}
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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.