c# to previous commit

This commit is contained in:
CasualPokePlayer 2022-11-27 23:29:54 -08:00
parent 8818f79bb0
commit 8667dd9ee7
2 changed files with 204 additions and 4 deletions

View File

@ -66,13 +66,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
return ninLogoSha1 == SHA1Checksum.ComputeDigestHex(new ReadOnlySpan<byte>(rom).Slice(0x104, 48));
}
var gbRoms = lp.Roms.FindAll(r => IsGBRom(r.FileData)).Select(r => r.FileData).ToList();
var gbRoms = lp.Roms.FindAll(r => IsGBRom(r.FileData)).Select(r => r.FileData).ToArray();
var rom = lp.Roms.Find(r => !gbRoms.Contains(r.FileData) && (char)r.RomData[0x3B] is 'N' or 'C')?.RomData;
var disk = lp.Roms.Find(r => !gbRoms.Contains(r.FileData) && (char)r.RomData[0x3B] is 'D' or 'E')?.RomData;
var (disk, error) = TransformDisk(lp.Roms.Find(r => !gbRoms.Contains(r.FileData) && r.RomData != rom)?.FileData);
if (rom is null && disk is null)
{
if (gbRoms.Count == 0 && lp.Roms.Count == 1) // let's just assume it's an N64 ROM then
if (gbRoms.Length == 0 && lp.Roms.Count == 1) // let's just assume it's an N64 ROM then
{
rom = lp.Roms[0].RomData;
}
@ -113,7 +113,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
}
byte[] GetGBRomOrNull(int n)
=> n < gbRoms.Count ? gbRoms[n] : null;
=> n < gbRoms.Length ? gbRoms[n] : null;
unsafe
{
@ -122,6 +122,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
iplPtr = ipl,
romPtr = rom,
diskPtr = disk,
diskErrorPtr = error,
gb1RomPtr = GetGBRomOrNull(0),
gb2RomPtr = GetGBRomOrNull(1),
gb3RomPtr = GetGBRomOrNull(2),
@ -137,6 +138,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
RomLen = rom?.Length ?? 0,
DiskData = (IntPtr)diskPtr,
DiskLen = disk?.Length ?? 0,
DiskErrorData = (IntPtr)diskErrorPtr,
DiskErrorLen = error?.Length ?? 0,
Gb1RomData = (IntPtr)gb1RomPtr,
Gb1RomLen = GetGBRomOrNull(0)?.Length ?? 0,
Gb2RomData = (IntPtr)gb2RomPtr,
@ -284,5 +287,200 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
Power = controller.IsPressed("Power"),
};
}
// creates an "error table" for the disk
// see https://github.com/ares-emulator/ares/blob/09aa6346c71a770fc68e9540d86156dd4769d677/mia/medium/nintendo-64dd.cpp#L102-L189
private static byte[] CreateErrorTable(byte[] disk)
{
static bool RepeatCheck(ReadOnlySpan<byte> slice, int size, int repeat)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < repeat; j++)
{
if (slice[i] != slice[(j * size) + i])
{
return false;
}
}
}
return true;
}
var ret = new byte[1175 * 2 * 2];
ret[12] = 0;
var systemBlocks = new[] { 0, 1, 8, 9 };
for (int i = 0; i < 4; i++)
{
var systemOffset = systemBlocks[i] * 0x4D08;
if (disk[systemOffset + 0x00] is not 0xE8 and not 0x22) continue;
if (disk[systemOffset + 0x01] is not 0x48 and not 0x63) continue;
if (disk[systemOffset + 0x02] is not 0xD3 and not 0xEE) continue;
if (disk[systemOffset + 0x03] is not 0x16 and not 0x56) continue;
if (disk[systemOffset + 0x04] != 0x10) continue;
if (disk[systemOffset + 0x05] <= 0x0F) continue;
if (disk[systemOffset + 0x05] >= 0x17) continue;
if (disk[systemOffset + 0x18] != 0xFF) continue;
if (disk[systemOffset + 0x19] != 0xFF) continue;
if (disk[systemOffset + 0x1A] != 0xFF) continue;
if (disk[systemOffset + 0x1B] != 0xFF) continue;
if (disk[systemOffset + 0x1C] != 0x80) continue;
if (!RepeatCheck(new(disk, systemOffset, 0xE8 * 0x55), 0xE8, 0x55)) continue;
ret[systemBlocks[i]] = 0;
ret[12] = 1;
}
if (ret[12] == 0)
{
for (int i = 0; i < 4; i++)
{
var systemBlock = disk.Length == 0x3DEC800 ? (systemBlocks[i] + 2) ^ 1 : (systemBlocks[i] + 2);
var systemOffset = systemBlock * 0x4D08;
ret[systemBlocks[i] + 2] = 1;
if (disk[systemOffset + 0x00] != 0x00) continue;
if (disk[systemOffset + 0x01] != 0x00) continue;
if (disk[systemOffset + 0x02] != 0x00) continue;
if (disk[systemOffset + 0x03] != 0x00) continue;
if (disk[systemOffset + 0x04] != 0x10) continue;
if (disk[systemOffset + 0x05] <= 0x0F) continue;
if (disk[systemOffset + 0x05] >= 0x17) continue;
if (disk[systemOffset + 0x18] != 0xFF) continue;
if (disk[systemOffset + 0x19] != 0xFF) continue;
if (disk[systemOffset + 0x1A] != 0xFF) continue;
if (disk[systemOffset + 0x1B] != 0xFF) continue;
if (disk[systemOffset + 0x1C] != 0x80) continue;
if (!RepeatCheck(new(disk, systemOffset, 0xC0 * 0x55), 0xC0, 0x55)) continue;
ret[systemBlocks[i] + 2] = 0;
}
}
for (int i = 0; i < 2; i++)
{
var diskIdOffset = (14 + i) * 0x4D08;
ret[14 + i] = 1;
if (!RepeatCheck(new(disk, diskIdOffset, 0xE8 * 0x55), 0xE8, 0x55)) continue;
ret[14 + i] = 0;
}
return ret;
}
private static readonly int[] _blockSizeTable = new[] { 0x4D08, 0x47B8, 0x4510, 0x3FC0, 0x3A70, 0x3520, 0x2FD0, 0x2A80, 0x2530 };
private static readonly int[,] _vzoneLbaTable = new[,]
{
{ 0x0124, 0x0248, 0x035A, 0x047E, 0x05A2, 0x06B4, 0x07C6, 0x08D8, 0x09EA, 0x0AB6, 0x0B82, 0x0C94, 0x0DA6, 0x0EB8, 0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x06A2, 0x07C6, 0x08D8, 0x09EA, 0x0AFC, 0x0BC8, 0x0C94, 0x0DA6, 0x0EB8, 0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08C6, 0x09EA, 0x0AFC, 0x0C0E, 0x0CDA, 0x0DA6, 0x0EB8, 0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08B4, 0x09C6, 0x0AEA, 0x0C0E, 0x0D20, 0x0DEC, 0x0EB8, 0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x08B4, 0x09C6, 0x0AD8, 0x0BEA, 0x0D0E, 0x0E32, 0x0EFE, 0x0FCA, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x086E, 0x0980, 0x0A92, 0x0BA4, 0x0CB6, 0x0DC8, 0x0EEC, 0x1010, 0x10DC },
{ 0x0124, 0x0248, 0x035A, 0x046C, 0x057E, 0x0690, 0x07A2, 0x086E, 0x093A, 0x0A4C, 0x0B5E, 0x0C70, 0x0D82, 0x0E94, 0x0FB8, 0x10DC },
};
private static readonly int[,] _vzone2pzoneTable = new[,]
{
{ 0x0, 0x1, 0x2, 0x9, 0x8, 0x3, 0x4, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC, 0xB, 0xA },
{ 0x0, 0x1, 0x2, 0x3, 0xA, 0x9, 0x8, 0x4, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC, 0xB },
{ 0x0, 0x1, 0x2, 0x3, 0x4, 0xB, 0xA, 0x9, 0x8, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC },
{ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0xC, 0xB, 0xA, 0x9, 0x8, 0x6, 0x7, 0xF, 0xE, 0xD },
{ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, 0x7, 0xF, 0xE },
{ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, 0xF },
{ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8 },
};
private static readonly int[] _trackPhysicalTable = new[] { 0x000, 0x09E, 0x13C, 0x1D1, 0x266, 0x2FB, 0x390, 0x425, 0x091, 0x12F, 0x1C4, 0x259, 0x2EE, 0x383, 0x418, 0x48A };
private static readonly int[] _startOffsetTable = new[] { 0x0, 0x5F15E0, 0xB79D00, 0x10801A0, 0x1523720, 0x1963D80, 0x1D414C0, 0x20BBCE0, 0x23196E0, 0x28A1E00, 0x2DF5DC0, 0x3299340, 0x36D99A0, 0x3AB70E0, 0x3E31900, 0x4149200 };
// converts ndd to "mame format" (which ares uses)
// see https://github.com/ares-emulator/ares/blob/09aa6346c71a770fc68e9540d86156dd4769d677/mia/medium/nintendo-64dd.cpp#L191-L302
private static (byte[] Disk, byte[] Error) TransformDisk(byte[] disk)
{
if (disk is null) return default;
// already in mame format
if (disk.Length == 0x435B0C0) return (disk, CreateErrorTable(disk));
// ndd is always 0x3DEC800 bytes apparently?
if (disk.Length != 0x3DEC800) return default;
// need the error table for this
var errorTable = CreateErrorTable(disk);
// "system area check"
var systemCheck = false;
var systemBlocks = new[] { 9, 8, 1, 0 };
var systemOffset = 0;
for (int i = 0; i < 4; i++)
{
if (errorTable[12] == 0)
{
var systemBlock = systemBlocks[i] + 2;
if (errorTable[systemBlock] == 0)
{
systemCheck = true;
systemOffset = (systemBlock ^ 1) * 0x4D08;
}
}
else
{
var systemBlock = systemBlocks[i];
if (errorTable[systemBlock] == 0)
{
systemCheck = true;
systemOffset = systemBlock * 0x4D08;
}
}
}
if (!systemCheck) return default;
var dataFormat = new ReadOnlySpan<byte>(disk, systemOffset, 0xE8);
var diskIndex = 0;
var ret = new byte[0x435B0C0];
var type = dataFormat[5] & 0xF;
var vzone = 0;
for (int lba = 0; lba < 0x10DC; lba++)
{
if (lba >= _vzoneLbaTable[type, vzone]) vzone++;
var pzoneCalc = _vzone2pzoneTable[type, vzone];
var headCalc = pzoneCalc > 7;
var lba_vzone = lba;
if (vzone > 0) lba_vzone -= _vzoneLbaTable[type, vzone - 1];
var trackStart = _trackPhysicalTable[headCalc ? pzoneCalc - 8 : pzoneCalc];
var trackCalc = _trackPhysicalTable[pzoneCalc];
if (headCalc) trackCalc -= (lba_vzone >> 1);
else trackCalc += (lba_vzone >> 1);
var defectOffset = 0;
if (pzoneCalc > 0) defectOffset = dataFormat[8 + pzoneCalc - 1];
var defectAmount = dataFormat[8 + pzoneCalc] - defectOffset;
while ((defectAmount != 0) && ((dataFormat[0x20 + defectOffset] + trackStart) <= trackCalc))
{
trackCalc++;
defectOffset++;
defectAmount--;
}
var blockCalc = ((lba & 3) == 0 || (lba & 3) == 3) ? 0 : 1;
var offsetCalc = _startOffsetTable[pzoneCalc];
offsetCalc += (trackCalc - trackStart) * _blockSizeTable[headCalc ? pzoneCalc - 7 : pzoneCalc] * 2;
offsetCalc += _blockSizeTable[headCalc ? pzoneCalc - 7 : pzoneCalc] * blockCalc;
var blockSize = _blockSizeTable[headCalc ? pzoneCalc - 7 : pzoneCalc];
for (int i = 0; i < blockSize; i++)
{
ret[offsetCalc + i] = disk[diskIndex++];
}
}
return (ret, errorTable);
}
}
}

View File

@ -87,6 +87,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Ares64
public long RomLen;
public IntPtr DiskData;
public long DiskLen;
public IntPtr DiskErrorData;
public long DiskErrorLen;
public IntPtr Gb1RomData;
public long Gb1RomLen;
public IntPtr Gb2RomData;