121 lines
3.4 KiB
C#
121 lines
3.4 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
|
|
using BizHawk.Emulation.DiscSystem;
|
|
|
|
class MednadiscTester
|
|
{
|
|
[DllImport("mednadisc.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern IntPtr mednadisc_LoadCD(string path);
|
|
|
|
[DllImport("mednadisc.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern int mednadisc_ReadSector(IntPtr disc, int lba, byte[] buf2448);
|
|
|
|
[DllImport("mednadisc.dll", CallingConvention = CallingConvention.Cdecl)]
|
|
public static extern void mednadisc_CloseCD(IntPtr disc);
|
|
|
|
|
|
public class QuickSubcodeReader
|
|
{
|
|
public QuickSubcodeReader(byte[] buffer)
|
|
{
|
|
this.buffer = buffer;
|
|
}
|
|
|
|
public void ReadLBA_SubchannelQ(int offset, ref SubchannelQ sq)
|
|
{
|
|
sq.q_status = buffer[offset + 0];
|
|
sq.q_tno = buffer[offset + 1];
|
|
sq.q_index = buffer[offset + 2];
|
|
sq.min.BCDValue = buffer[offset + 3];
|
|
sq.sec.BCDValue = buffer[offset + 4];
|
|
sq.frame.BCDValue = buffer[offset + 5];
|
|
//nothing in byte[6]
|
|
sq.ap_min.BCDValue = buffer[offset + 7];
|
|
sq.ap_sec.BCDValue = buffer[offset + 8];
|
|
sq.ap_frame.BCDValue = buffer[offset + 9];
|
|
|
|
//CRC is stored inverted and big endian.. so... do the opposite
|
|
byte hibyte = (byte)(~buffer[offset + 10]);
|
|
byte lobyte = (byte)(~buffer[offset + 11]);
|
|
sq.q_crc = (ushort)((hibyte << 8) | lobyte);
|
|
}
|
|
|
|
byte[] buffer;
|
|
}
|
|
|
|
public void TestDirectory(string dpTarget)
|
|
{
|
|
foreach (var fi in new DirectoryInfo(dpTarget).GetFiles())
|
|
{
|
|
if (fi.Extension.ToLower() == ".cue") { }
|
|
else if (fi.Extension.ToLower() == ".ccd") { }
|
|
else continue;
|
|
|
|
NewTest(fi.FullName);
|
|
}
|
|
}
|
|
|
|
static bool NewTest(string path)
|
|
{
|
|
bool ret = false;
|
|
|
|
Disc disc;
|
|
if (Path.GetExtension(path).ToLower() == ".cue") disc = Disc.FromCuePath(path, new CueBinPrefs());
|
|
else disc = Disc.FromCCDPath(path);
|
|
IntPtr mednadisc = mednadisc_LoadCD(path);
|
|
|
|
//TODO - test leadout a bit, or determine length some superior way
|
|
//TODO - check length against mednadisc
|
|
|
|
int nSectors = (int)(disc.Structure.BinarySize / 2352) - 150;
|
|
var subbuf = new byte[96];
|
|
var discbuf = new byte[2352 + 96];
|
|
var monkeybuf = new byte[2352 + 96];
|
|
var disc_qbuf = new byte[96];
|
|
var monkey_qbuf = new byte[96];
|
|
|
|
for (int i = 0; i < nSectors; i++)
|
|
{
|
|
mednadisc_ReadSector(mednadisc, i, monkeybuf);
|
|
disc.ReadLBA_2352(i, discbuf, 0);
|
|
disc.ReadLBA_SectorEntry(i).SubcodeSector.ReadSubcodeDeinterleaved(subbuf, 0);
|
|
SubcodeUtils.Interleave(subbuf, 0, discbuf, 2352);
|
|
//remove P
|
|
for (int q = 2352; q < 2352 + 96; q++)
|
|
{
|
|
discbuf[q] &= 0x7F;
|
|
monkeybuf[q] &= 0x7F;
|
|
}
|
|
for (int q = 0; q < 2352 + 96; q++)
|
|
{
|
|
if (discbuf[q] != monkeybuf[q])
|
|
{
|
|
Console.WriteLine("MISMATCH: " + Path.GetFileName(path));
|
|
|
|
//decode Q subchannels for manual investigation
|
|
SubcodeUtils.Deinterleave(discbuf, 2352, disc_qbuf, 0);
|
|
var asr = new QuickSubcodeReader(disc_qbuf);
|
|
SubchannelQ disc_q = new SubchannelQ();
|
|
asr.ReadLBA_SubchannelQ(12, ref disc_q);
|
|
|
|
SubcodeUtils.Deinterleave(monkeybuf, 2352, monkey_qbuf, 0);
|
|
asr = new QuickSubcodeReader(monkey_qbuf);
|
|
SubchannelQ monkey_q = new SubchannelQ();
|
|
asr.ReadLBA_SubchannelQ(12, ref monkey_q);
|
|
|
|
goto END;
|
|
}
|
|
}
|
|
}
|
|
|
|
ret = true;
|
|
|
|
END:
|
|
disc.Dispose();
|
|
mednadisc_CloseCD(mednadisc);
|
|
|
|
return ret;
|
|
}
|
|
} |