This commit is contained in:
adelikat 2015-07-19 10:38:55 -04:00
commit 73bd94e09b
15 changed files with 94 additions and 55 deletions

View File

@ -366,7 +366,7 @@ namespace BizHawk.Client.DiscoHawk
if (!item.Exists)
sw.Write("(---missing---)");
else
sw.Write("({0:X2} - {1})", (byte)item.Control, item.LBATimestamp);
sw.Write("({0:X2} - {1})", (byte)item.Control, item.LBA);
};
@ -399,7 +399,7 @@ namespace BizHawk.Client.DiscoHawk
{
if (src_toc.TOCItems[t].Exists != dst_toc.TOCItems[t].Exists
|| src_toc.TOCItems[t].Control != dst_toc.TOCItems[t].Control
|| src_toc.TOCItems[t].LBATimestamp.Sector != dst_toc.TOCItems[t].LBATimestamp.Sector
|| src_toc.TOCItems[t].LBA != dst_toc.TOCItems[t].LBA
)
{
sw.WriteLine("Mismatch in TOCItem");

View File

@ -422,7 +422,7 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn
rTOC[99] = (int)(rTOC[0] & 0xff000000 | 0x010000);
rTOC[100] = (int)(rTOC[ntrk - 1] & 0xff000000 | (uint)(ntrk << 16));
rTOC[101] = (int)(rTOC[ntrk - 1] & 0xff000000 | (uint)(CD.TOC.LeadoutLBA.Sector)); //zero 03-jul-2014 - maybe off by 150
rTOC[101] = (int)(rTOC[ntrk - 1] & 0xff000000 | (uint)(CD.TOC.LeadoutLBA)); //zero 03-jul-2014 - maybe off by 150
Marshal.Copy(rTOC, 0, dest, 102);

View File

@ -178,14 +178,14 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
{
var item = Disc.TOC.TOCItems[i];
tracks101[i].adr = (byte)(item.Exists ? 1 : 0);
tracks101[i].lba = (uint)item.LBATimestamp.Sector;
tracks101[i].lba = (uint)item.LBA;
tracks101[i].control = (byte)item.Control;
}
////the lead-out track is to be synthesized
tracks101[read_target->last_track + 1].adr = 1;
tracks101[read_target->last_track + 1].control = 0;
tracks101[read_target->last_track + 1].lba = (uint)Disc.TOC.LeadoutLBA.Sector;
tracks101[read_target->last_track + 1].lba = (uint)Disc.TOC.LeadoutLBA;
//element 100 is to be copied as the lead-out track
tracks101[100] = tracks101[read_target->last_track + 1];

View File

@ -326,7 +326,6 @@ namespace BizHawk.Emulation.DiscSystem
public string ImgPath;
public string SubPath;
public string CcdPath;
public int NumImgSectors;
}
public static LoadResults LoadCCDPath(string path)
@ -337,17 +336,8 @@ namespace BizHawk.Emulation.DiscSystem
ret.SubPath = Path.ChangeExtension(path, ".sub");
try
{
if(!File.Exists(path)) throw new CCDParseException("Malformed CCD format: nonexistent CCD file!");
if (!File.Exists(ret.ImgPath)) throw new CCDParseException("Malformed CCD format: nonexistent IMG file!");
if (!File.Exists(ret.SubPath)) throw new CCDParseException("Malformed CCD format: nonexistent SUB file!");
if (!File.Exists(path)) throw new CCDParseException("Malformed CCD format: nonexistent CCD file!");
//quick check of .img and .sub sizes
long imgLen = new FileInfo(ret.ImgPath).Length;
long subLen = new FileInfo(ret.SubPath).Length;
if(imgLen % 2352 != 0) throw new CCDParseException("Malformed CCD format: IMG file length not multiple of 2352");
ret.NumImgSectors = (int)(imgLen / 2352);
if (subLen != ret.NumImgSectors * 96) throw new CCDParseException("Malformed CCD format: SUB file length not matching IMG");
CCDFile ccdf;
using (var infCCD = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
ccdf = new CCD_Format().ParseFrom(infCCD);
@ -403,12 +393,12 @@ namespace BizHawk.Emulation.DiscSystem
sw.WriteLine("AMin={0}", entry.QData.min.DecimalValue);
sw.WriteLine("ASec={0}", entry.QData.sec.DecimalValue);
sw.WriteLine("AFrame={0}", entry.QData.frame.DecimalValue);
sw.WriteLine("ALBA={0}", entry.QData.Timestamp.Sector - 150); //remember to adapt the absolute MSF to an LBA (this field is redundant...)
sw.WriteLine("ALBA={0}", entry.QData.Timestamp - 150); //remember to adapt the absolute MSF to an LBA (this field is redundant...)
sw.WriteLine("Zero={0}", entry.QData.zero);
sw.WriteLine("PMin={0}", entry.QData.ap_min.DecimalValue);
sw.WriteLine("PSec={0}", entry.QData.ap_sec.DecimalValue);
sw.WriteLine("PFrame={0}", entry.QData.ap_frame.DecimalValue);
sw.WriteLine("PLBA={0}", entry.QData.AP_Timestamp.Sector - 150); //remember to adapt the absolute MSF to an LBA (this field is redundant...)
sw.WriteLine("PLBA={0}", entry.QData.AP_Timestamp - 150); //remember to adapt the absolute MSF to an LBA (this field is redundant...)
sw.WriteLine();
}
@ -454,9 +444,9 @@ namespace BizHawk.Emulation.DiscSystem
{
public void Synth(SectorSynthJob job)
{
//CCD is always containing everything we'd need (unless a .sub is missing?) so don't about flags
var imgBlob = job.Disc.DisposableResources[0] as Disc.Blob_RawFile;
var subBlob = job.Disc.DisposableResources[1] as Disc.Blob_RawFile;
//CCD is always containing everything we'd need (unless a .sub is missing?) so don't worry about flags
var imgBlob = job.Disc.DisposableResources[0] as IBlob;
var subBlob = job.Disc.DisposableResources[1] as IBlob;
//Read_2442(job.LBA, job.DestBuffer2448, job.DestOffset);
//read the IMG data if needed
@ -493,12 +483,48 @@ namespace BizHawk.Emulation.DiscSystem
Disc disc = new Disc();
//mount the IMG and SUB files
var ccdf = loadResults.ParsedCCDFile;
var imgBlob = new Disc.Blob_RawFile() { PhysicalPath = loadResults.ImgPath };
var subBlob = new Disc.Blob_RawFile() { PhysicalPath = loadResults.SubPath };
IBlob imgBlob = null, subBlob = null;
long imgLen = -1, subLen;
//mount the IMG file
//first check for a .ecm in place of the img
var imgPath = loadResults.ImgPath;
if (!File.Exists(imgPath))
{
var ecmPath = Path.ChangeExtension(imgPath, ".img.ecm");
if (File.Exists(ecmPath))
{
if (Disc.Blob_ECM.IsECM(ecmPath))
{
var ecm = new Disc.Blob_ECM();
ecm.Load(ecmPath);
imgBlob = ecm;
imgLen = ecm.Length;
}
}
}
if (imgBlob == null)
{
if (!File.Exists(loadResults.ImgPath)) throw new CCDParseException("Malformed CCD format: nonexistent IMG file!");
var imgFile = new Disc.Blob_RawFile() { PhysicalPath = loadResults.ImgPath };
imgLen = imgFile.Length;
imgBlob = imgFile;
}
disc.DisposableResources.Add(imgBlob);
//mount the SUB file
if (!File.Exists(loadResults.SubPath)) throw new CCDParseException("Malformed CCD format: nonexistent SUB file!");
var subFile = new Disc.Blob_RawFile() { PhysicalPath = loadResults.SubPath };
subBlob = subFile;
disc.DisposableResources.Add(subBlob);
subLen = subFile.Length;
//quick integrity check of file sizes
if (imgLen % 2352 != 0) throw new CCDParseException("Malformed CCD format: IMG file length not multiple of 2352");
int NumImgSectors = (int)(imgLen / 2352);
if (subLen != NumImgSectors * 96) throw new CCDParseException("Malformed CCD format: SUB file length not matching IMG");
var ccdf = loadResults.ParsedCCDFile;
//the only instance of a sector synthesizer we'll need
SS_CCD synth = new SS_CCD();
@ -534,7 +560,7 @@ 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
q_crc = 0, //meaningless
};
disc.RawTOCEntries.Add(new RawTOCEntry { QData = q });
@ -578,8 +604,8 @@ namespace BizHawk.Emulation.DiscSystem
ss_gap.sq.SetStatus(ADR, tocSynth.Result.TOCItems[1].Control);
ss_gap.sq.q_tno = BCD2.FromDecimal(1);
ss_gap.sq.q_index = BCD2.FromDecimal(0);
ss_gap.sq.AP_Timestamp = new Timestamp(i);
ss_gap.sq.Timestamp = new Timestamp(qRelMSF);
ss_gap.sq.AP_Timestamp = i;
ss_gap.sq.Timestamp = qRelMSF;
//setup subP
ss_gap.Pause = true;
@ -588,7 +614,7 @@ namespace BizHawk.Emulation.DiscSystem
//build the sectors:
//set up as many sectors as we have img/sub for, even if the TOC doesnt reference them
//(the TOC is unreliable, and the Track records are redundant)
for (int i = 0; i < loadResults.NumImgSectors; i++)
for (int i = 0; i < NumImgSectors; i++)
{
disc._Sectors.Add(synth);
}

View File

@ -162,7 +162,7 @@ namespace BizHawk.Emulation.DiscSystem.CUE
toc_sq.min = BCD2.FromDecimal(0);
toc_sq.sec = BCD2.FromDecimal(0);
toc_sq.frame = BCD2.FromDecimal(0);
toc_sq.AP_Timestamp = new Timestamp(OUT_Disc._Sectors.Count);
toc_sq.AP_Timestamp = OUT_Disc._Sectors.Count;
OUT_Disc.RawTOCEntries.Add(new RawTOCEntry { QData = toc_sq });
}
@ -322,8 +322,8 @@ namespace BizHawk.Emulation.DiscSystem.CUE
ss.sq.SetStatus(ADR, (EControlQ)(int)qTrack.CompiledCueTrack.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(qRelMSF);
ss.sq.AP_Timestamp = OUT_Disc._Sectors.Count;
ss.sq.Timestamp = qRelMSF;
//setup subP
if (curr_index == 0)
@ -363,8 +363,8 @@ namespace BizHawk.Emulation.DiscSystem.CUE
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(relMSF);
ss.sq.AP_Timestamp = OUT_Disc._Sectors.Count;
ss.sq.Timestamp = relMSF;
//-subP-
//always paused--is this good enough?
@ -383,7 +383,7 @@ namespace BizHawk.Emulation.DiscSystem.CUE
IN_FirstRecordedTrackNumber = IN_CompileJob.OUT_CompiledDiscInfo.FirstRecordedTrackNumber,
IN_LastRecordedTrackNumber = IN_CompileJob.OUT_CompiledDiscInfo.LastRecordedTrackNumber,
IN_Session1Format = IN_CompileJob.OUT_CompiledDiscInfo.SessionFormat,
IN_LeadoutTimestamp = new Timestamp(OUT_Disc._Sectors.Count) //do we need a +150?
IN_LeadoutTimestamp = OUT_Disc._Sectors.Count
};
TOCMiscInfo.Run(OUT_Disc.RawTOCEntries);

View File

@ -41,7 +41,7 @@ namespace BizHawk.Emulation.DiscSystem
//if (disc.TOC.TOCItems[i].Exists) Console.WriteLine("{0:X8} {1:X2} {2:X2} {3:X8}", crc.Current, (int)disc.TOC.TOCItems[i].Control, disc.TOC.TOCItems[i].Exists ? 1 : 0, disc.TOC.TOCItems[i].LBATimestamp.Sector); //a little debugging
crc.Add((int)disc.TOC.TOCItems[i].Control);
crc.Add(disc.TOC.TOCItems[i].Exists ? 1 : 0);
crc.Add((int)disc.TOC.TOCItems[i].LBATimestamp.Sector);
crc.Add((int)disc.TOC.TOCItems[i].LBA);
}
//hash first 26 sectors

View File

@ -72,7 +72,7 @@ namespace BizHawk.Emulation.DiscSystem
//check track 1's data type. if it's an audio track, further data-track testing is useless
//furthermore, it's probably senseless (no binary data there to read)
//however a sector could mark itself as audio without actually being.. we'll just wait for that one.
if (dsr.ReadLBA_Mode(disc.TOC.TOCItems[1].LBATimestamp.Sector) == 0) return DiscType.AudioDisc;
if (dsr.ReadLBA_Mode(disc.TOC.TOCItems[1].LBA) == 0) return DiscType.AudioDisc;
//sega doesnt put anything identifying in the cdfs volume info. but its consistent about putting its own header here in sector 0
if (DetectSegaSaturn()) return DiscType.SegaSaturn;

View File

@ -91,19 +91,24 @@ 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); }
set { min.DecimalValue = value.MIN; sec.DecimalValue = value.SEC; frame.DecimalValue = value.FRAC; }
public int Timestamp {
get { return MSF.ToInt(min.DecimalValue, sec.DecimalValue, frame.DecimalValue); }
set {
var ts = new Timestamp(value);
min.DecimalValue = ts.MIN; sec.DecimalValue = ts.SEC; frame.DecimalValue = ts.FRAC;
}
}
/// <summary>
/// Retrieves the second set of timestamps (ap_min, ap_sec, ap_frac) as a convenient Timestamp.
/// TODO - rename everything AP here, it's nonsense. (the P is)
/// </summary>
public Timestamp AP_Timestamp {
get { return new Timestamp(ap_min.DecimalValue, ap_sec.DecimalValue, ap_frame.DecimalValue); }
set { ap_min.DecimalValue = value.MIN; ap_sec.DecimalValue = value.SEC; ap_frame.DecimalValue = value.FRAC; }
public int AP_Timestamp {
get { return MSF.ToInt(ap_min.DecimalValue, ap_sec.DecimalValue, ap_frame.DecimalValue); }
set {
var ts = new Timestamp(value);
ap_min.DecimalValue = ts.MIN; ap_sec.DecimalValue = ts.SEC; ap_frame.DecimalValue = ts.FRAC;
}
}
/// <summary>

View File

@ -45,7 +45,7 @@ namespace BizHawk.Emulation.DiscSystem
/// <summary>
/// The location of the track (Index 1)
/// </summary>
public Timestamp LBATimestamp;
public int LBA;
/// <summary>
/// Whether this entry exists (since the table is 101 entries long always)
@ -63,7 +63,7 @@ namespace BizHawk.Emulation.DiscSystem
/// <summary>
/// The timestamp of the leadout track. In other words, the end of the user area.
/// </summary>
public Timestamp LeadoutLBA { get { return TOCItems[100].LBATimestamp; } }
public int LeadoutLBA { get { return TOCItems[100].LBA; } }
}

View File

@ -81,6 +81,14 @@ namespace BizHawk.Emulation.DiscSystem
}
}
public static class MSF
{
public static int ToInt(int m, int s, int f)
{
return m * 60 * 75 + s * 75 + f;
}
}
/// <summary>
/// todo - rename to MSF? It can specify durations, so maybe it should be not suggestive of timestamp
/// TODO - can we maybe use BCD2 in here

View File

@ -27,7 +27,7 @@ namespace BizHawk.Emulation.DiscSystem
/// <summary>
/// The absolute timestamp of the lead-out track
/// </summary>
public Timestamp IN_LeadoutTimestamp;
public int IN_LeadoutTimestamp;
/// <summary>
/// The session format for this TOC

View File

@ -40,7 +40,7 @@ namespace BizHawk.Emulation.DiscSystem
{
Number = i + 1,
Control = item.Control,
LBA = item.LBATimestamp.Sector
LBA = item.LBA
};
session.Tracks.Add(track);
@ -66,7 +66,7 @@ namespace BizHawk.Emulation.DiscSystem
//kind of a guess, but not completely
Control = session.Tracks[session.Tracks.Count -1 ].Control,
Mode = session.Tracks[session.Tracks.Count - 1].Mode,
LBA = TOCRaw.LeadoutLBA.Sector
LBA = TOCRaw.LeadoutLBA
});
//link track list

View File

@ -20,7 +20,7 @@ namespace BizHawk.Emulation.DiscSystem
DiscTOC ret = new DiscTOC();
//this is a dummy, for convenience in array indexing, so that track 1 is at array index 1
ret.TOCItems[0].LBATimestamp = new Timestamp(0); //arguably could be -150, but let's not just yet
ret.TOCItems[0].LBA = 0; //arguably could be -150, but let's not just yet
ret.TOCItems[0].Control = 0;
ret.TOCItems[0].Exists = false;
@ -44,7 +44,7 @@ namespace BizHawk.Emulation.DiscSystem
else if (point <= 99)
{
maxFoundTrack = Math.Max(maxFoundTrack, point);
ret.TOCItems[point].LBATimestamp = new Timestamp(q.AP_Timestamp.Sector - 150); //RawTOCEntries contained an absolute time
ret.TOCItems[point].LBA = q.AP_Timestamp - 150; //RawTOCEntries contained an absolute time
ret.TOCItems[point].Control = q.CONTROL;
ret.TOCItems[point].Exists = true;
}
@ -65,7 +65,7 @@ namespace BizHawk.Emulation.DiscSystem
}
else if (point == 102) //0xA2 bcd
{
ret.TOCItems[100].LBATimestamp = new Timestamp(q.AP_Timestamp.Sector - 150); //RawTOCEntries contained an absolute time
ret.TOCItems[100].LBA = q.AP_Timestamp - 150; //RawTOCEntries contained an absolute time
ret.TOCItems[100].Control = 0; //not clear what this should be
ret.TOCItems[100].Exists = true;
}

View File

@ -42,7 +42,7 @@ namespace BizHawk.Emulation.DiscSystem
sq.sec = BCD2.FromDecimal(new Timestamp(track_relative_msf).SEC);
sq.frame = BCD2.FromDecimal(new Timestamp(track_relative_msf).FRAC);
int absolute_msf = i + leadoutTs.Sector;
int absolute_msf = i + leadoutTs;
sq.ap_min = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).MIN);
sq.ap_sec = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).SEC);
sq.ap_frame = BCD2.FromDecimal(new Timestamp(absolute_msf + 150).FRAC);

View File

@ -229,8 +229,8 @@ namespace BizHawk.Emulation.DiscSystem
//data is zero
Timestamp ts = new Timestamp(lba_relative);
Timestamp ats = new Timestamp(job.LBA);
int ts = lba_relative;
int ats = job.LBA;
const int ADR = 0x1; // Q channel data encodes position
EControlQ control = ses.LeadoutTrack.Control;