117 lines
4.2 KiB
C#
117 lines
4.2 KiB
C#
namespace BizHawk.Emulation.DiscSystem
|
|
{
|
|
partial class DiscMountJob
|
|
{
|
|
class SS_MednaDisc : ISectorSynthJob2448
|
|
{
|
|
public void Synth(SectorSynthJob job)
|
|
{
|
|
//mednafen is always synthesizing everything, no need to worry about flags.. mostly./
|
|
job.Params.MednaDisc.Read_2442(job.LBA, job.DestBuffer2448, job.DestOffset);
|
|
|
|
//we may still need to deinterleave it if subcode was requested and it needs deinterleaving
|
|
if ((job.Parts & (ESectorSynthPart.SubcodeDeinterleave | ESectorSynthPart.SubcodeAny)) != 0)
|
|
{
|
|
SynthUtils.DeinterleaveSubcodeInplace(job.DestBuffer2448, 2352);
|
|
}
|
|
}
|
|
}
|
|
|
|
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);
|
|
disc.DisposableResources.Add(md);
|
|
|
|
//"length of disc" for BizHawk's purposes (NOT a robust concept!) is determined by beginning of leadout track
|
|
var m_leadoutTrack = md.TOCTracks[100];
|
|
int nSectors = (int)m_leadoutTrack.lba;
|
|
|
|
//make synth param memos
|
|
disc.SynthParams.MednaDisc = md;
|
|
|
|
//this is the sole sector synthesizer we'll need
|
|
var synth = new SS_MednaDisc();
|
|
OUT_Disc.SynthProvider = new SimpleSectorSynthProvider { SS = synth };
|
|
|
|
//ADR (q-Mode) is necessarily 0x01 for a RawTOCEntry
|
|
const int kADR = 1;
|
|
const int kUnknownControl = 0;
|
|
|
|
//mednafen delivers us what is essentially but not exactly (or completely) a TOCRaw.
|
|
//we need to synth RawTOCEntries from this and then turn it into a proper TOCRaw
|
|
//when coming from mednafen, there are 101 entries.
|
|
//entry[0] is placeholder junk, not to be used
|
|
//entry[100] is the leadout track (A0)
|
|
//A1 and A2 are in the form of FirstRecordedTrackNumber and LastRecordedTrackNumber
|
|
for (int i = 1; i < 101; i++)
|
|
{
|
|
var m_te = md.TOCTracks[i];
|
|
|
|
//don't add invalid (absent) items
|
|
if (!m_te.Valid)
|
|
continue;
|
|
|
|
var m_ts = new Timestamp((int)m_te.lba + 150); //these are supposed to be absolute timestamps
|
|
|
|
var q = new SubchannelQ
|
|
{
|
|
q_status = SubchannelQ.ComputeStatus(kADR, (EControlQ)m_te.control),
|
|
q_tno = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
q_index = BCD2.FromDecimal(i),
|
|
min = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
sec = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
frame = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
zero = 0, //unknown with mednadisc
|
|
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, so change it into the A2 raw toc entry
|
|
if (i == 100)
|
|
{
|
|
q.q_index.BCDValue = 0xA2;
|
|
}
|
|
|
|
disc.RawTOCEntries.Add(new RawTOCEntry { QData = q });
|
|
}
|
|
|
|
// synth A0 and A1 entries (indicating first and last recorded tracks and also session type)
|
|
var qA0 = new SubchannelQ
|
|
{
|
|
q_status = SubchannelQ.ComputeStatus(kADR, kUnknownControl),
|
|
q_tno = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
q_index = BCD2.FromBCD(0xA0),
|
|
min = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
sec = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
frame = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
zero = 0, //unknown with mednadisc
|
|
ap_min = BCD2.FromDecimal(md.TOC.first_track),
|
|
ap_sec = BCD2.FromDecimal(md.TOC.disc_type),
|
|
ap_frame = BCD2.FromDecimal(0),
|
|
q_crc = 0, //meaningless
|
|
};
|
|
disc.RawTOCEntries.Add(new RawTOCEntry { QData = qA0 });
|
|
var qA1 = new SubchannelQ
|
|
{
|
|
q_status = SubchannelQ.ComputeStatus(kADR, kUnknownControl),
|
|
q_tno = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
q_index = BCD2.FromBCD(0xA1),
|
|
min = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
sec = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
frame = BCD2.FromDecimal(0), //unknown with mednadisc
|
|
zero = 0, //unknown with mednadisc
|
|
ap_min = BCD2.FromDecimal(md.TOC.last_track),
|
|
ap_sec = BCD2.FromDecimal(0),
|
|
ap_frame = BCD2.FromDecimal(0),
|
|
q_crc = 0, //meaningless
|
|
};
|
|
disc.RawTOCEntries.Add(new RawTOCEntry { QData = qA1 });
|
|
}
|
|
}
|
|
} |