fix Disc/Disc name collision

add function to disc-api to get game-ID hash from 1st data track
This commit is contained in:
beirich 2011-08-03 00:57:01 +00:00
parent adc0bf83bb
commit 74a58186df
13 changed files with 368 additions and 350 deletions

View File

@ -4,382 +4,378 @@ using System.Globalization;
using System.IO; using System.IO;
using BizHawk.Emulation.CPUs.H6280; using BizHawk.Emulation.CPUs.H6280;
using BizHawk.Emulation.Sound; using BizHawk.Emulation.Sound;
using BizHawk.Disc; using BizHawk.DiscSystem;
namespace BizHawk.Emulation.Consoles.TurboGrafx namespace BizHawk.Emulation.Consoles.TurboGrafx
{ {
public enum NecSystemType public enum NecSystemType
{ {
TurboGrafx, TurboGrafx,
TurboCD, TurboCD,
SuperGrafx SuperGrafx
} }
public sealed partial class PCEngine : IEmulator public sealed partial class PCEngine : IEmulator
{ {
// ROM // ROM
public byte[] RomData; public byte[] RomData;
public int RomLength; public int RomLength;
// Machine // Machine
public NecSystemType Type; public NecSystemType Type;
public HuC6280 Cpu; public HuC6280 Cpu;
public VDC VDC1, VDC2; public VDC VDC1, VDC2;
public VCE VCE; public VCE VCE;
public HuC6280PSG PSG; public HuC6280PSG PSG;
public VPC VPC; public VPC VPC;
private bool TurboGrafx { get { return Type == NecSystemType.TurboGrafx; } } private bool TurboGrafx { get { return Type == NecSystemType.TurboGrafx; } }
private bool SuperGrafx { get { return Type == NecSystemType.SuperGrafx; } } private bool SuperGrafx { get { return Type == NecSystemType.SuperGrafx; } }
private bool TurboCD { get { return Type == NecSystemType.TurboCD; } } private bool TurboCD { get { return Type == NecSystemType.TurboCD; } }
// BRAM
private bool BramEnabled = false;
private bool BramLocked = true;
private byte[] BRAM;
// BRAM // Memory system
private bool BramEnabled = false; public byte[] Ram;
private bool BramLocked = true;
private byte[] BRAM;
// Memory system // Disc
public byte[] Ram; //private Disc disc = Disc.FromCuePath("D:/lib/roms/Turbo CD/Terra Forming/Syd Mead's Terra Forming [U][CD.SCD][TGXCD1040][Syd Mead][1993][PCE][rigg].cue");
// Disc // PC Engine timings:
//private Disc.Disc disc = Disc.Disc.FromCuePath("d:/lib/roms/Turbo CD/Cosmic Fantasy II/Cosmic Fantasy II [U][CD][WTG990301][Telenet Japan][1992][PCE][thx-1138-darkwater].cue"); // 21,477,270 Machine clocks / sec
// 7,159,090 Cpu cycles / sec
// PC Engine timings: public PCEngine(NecSystemType type)
// 21,477,270 Machine clocks / sec {
// 7,159,090 Cpu cycles / sec //scsi.disc = disc;
//Console.WriteLine(disc.GetHash());
CoreOutputComm = new CoreOutputComm();
Type = type;
Controller = NullController.GetNullController();
Cpu = new HuC6280();
VCE = new VCE();
VDC1 = new VDC(Cpu, VCE);
PSG = new HuC6280PSG();
public PCEngine(NecSystemType type) if (TurboGrafx || TurboCD)
{ {
CoreOutputComm = new CoreOutputComm(); Ram = new byte[0x2000];
Type = type; Cpu.ReadMemory21 = ReadMemory;
Controller = NullController.GetNullController(); Cpu.WriteMemory21 = WriteMemory;
Cpu = new HuC6280(); Cpu.WriteVDC = VDC1.WriteVDC;
VCE = new VCE(); }
VDC1 = new VDC(Cpu, VCE);
PSG = new HuC6280PSG();
if (TurboGrafx || TurboCD) if (SuperGrafx)
{ {
Ram = new byte[0x2000]; VDC2 = new VDC(Cpu, VCE);
Cpu.ReadMemory21 = ReadMemory; VPC = new VPC(VDC1, VDC2, VCE, Cpu);
Cpu.WriteMemory21 = WriteMemory; Ram = new byte[0x8000];
Cpu.WriteVDC = VDC1.WriteVDC; Cpu.ReadMemory21 = ReadMemorySGX;
} Cpu.WriteMemory21 = WriteMemorySGX;
Cpu.WriteVDC = VDC1.WriteVDC;
}
}
if (SuperGrafx) public void LoadGame(IGame game)
{ {
VDC2 = new VDC(Cpu, VCE); if (game.GetRomData().Length == 0x60000)
VPC = new VPC(VDC1, VDC2, VCE, Cpu); {
Ram = new byte[0x8000]; // 384k roms require special loading code. Why ;_;
Cpu.ReadMemory21 = ReadMemorySGX; // In memory, 384k roms look like [1st 256k][Then full 384k]
Cpu.WriteMemory21 = WriteMemorySGX; RomData = new byte[0xA0000];
Cpu.WriteVDC = VDC1.WriteVDC; var origRom = game.GetRomData();
} for (int i=0; i<0x40000; i++)
} RomData[i] = origRom[i];
for (int i = 0; i < 0x60000; i++)
RomData[i+0x40000] = origRom[i];
RomLength = RomData.Length;
} else if (game.GetRomData().Length > 1024 * 1024) {
// If the rom is bigger than 1 megabyte, switch to Street Fighter 2 mapper
Cpu.ReadMemory21 = ReadMemorySF2;
Cpu.WriteMemory21 = WriteMemorySF2;
RomData = game.GetRomData();
RomLength = RomData.Length;
} else {
// normal rom.
RomData = game.GetRomData();
RomLength = RomData.Length;
}
public void LoadGame(IGame game) if (game.GetOptions().Contains("BRAM"))
{ {
if (game.GetRomData().Length == 0x60000) BramEnabled = true;
{ BRAM = new byte[2048];
// 384k roms require special loading code. Why ;_; Console.WriteLine("ENABLE BRAM!");
// In memory, 384k roms look like [1st 256k][Then full 384k]
RomData = new byte[0xA0000];
var origRom = game.GetRomData();
for (int i = 0; i < 0x40000; i++)
RomData[i] = origRom[i];
for (int i = 0; i < 0x60000; i++)
RomData[i + 0x40000] = origRom[i];
RomLength = RomData.Length;
}
else if (game.GetRomData().Length > 1024 * 1024)
{
// If the rom is bigger than 1 megabyte, switch to Street Fighter 2 mapper
Cpu.ReadMemory21 = ReadMemorySF2;
Cpu.WriteMemory21 = WriteMemorySF2;
RomData = game.GetRomData();
RomLength = RomData.Length;
}
else
{
// normal rom.
RomData = game.GetRomData();
RomLength = RomData.Length;
}
if (game.GetOptions().Contains("BRAM")) // pre-format BRAM
{ BRAM[0] = 0x48; BRAM[1] = 0x55; BRAM[2] = 0x42; BRAM[3] = 0x4D;
BramEnabled = true; BRAM[4] = 0x00; BRAM[5] = 0x88; BRAM[6] = 0x10; BRAM[7] = 0x80;
BRAM = new byte[2048]; }
Console.WriteLine("ENABLE BRAM!");
// pre-format BRAM if (game.GetOptions().Contains("PopulousSRAM"))
BRAM[0] = 0x48; BRAM[1] = 0x55; BRAM[2] = 0x42; BRAM[3] = 0x4D; {
BRAM[4] = 0x00; BRAM[5] = 0x88; BRAM[6] = 0x10; BRAM[7] = 0x80; PopulousRAM = new byte[0x8000];
} Cpu.ReadMemory21 = ReadMemoryPopulous;
Cpu.WriteMemory21 = WriteMemoryPopulous;
}
if (game.GetOptions().Contains("PopulousSRAM")) if (game.GetOptions().Contains("ForceSpriteLimit") || game.GetOptions().Contains("NotInDatabase"))
{ {
PopulousRAM = new byte[0x8000]; VDC1.PerformSpriteLimit = true;
Cpu.ReadMemory21 = ReadMemoryPopulous; if (VDC2 != null)
Cpu.WriteMemory21 = WriteMemoryPopulous; VDC2.PerformSpriteLimit = true;
} }
if (game.GetOptions().Contains("ForceSpriteLimit") || game.GetOptions().Contains("NotInDatabase")) // Ok, yes, HBlankPeriod's only purpose is game-specific hax.
{ // 1) At least they're not coded directly into the emulator, but instead data-driven.
VDC1.PerformSpriteLimit = true; // 2) The games which have custom HBlankPeriods work without it, the override only
if (VDC2 != null) // serves to clean up minor gfx anomalies.
VDC2.PerformSpriteLimit = true; // 3) There's no point in haxing the timing with incorrect values in an attempt to avoid this.
} // The proper fix is cycle-accurate/bus-accurate timing. That isn't coming to the C#
// version of this core. Let's just acknolwedge that the timing is imperfect and fix
// it in the least intrusive and most honest way we can.
// Ok, yes, HBlankPeriod's only purpose is game-specific hax. if (game.GetOptions().ContainsStartsWith("HBlankPeriod"))
// 1) At least they're not coded directly into the emulator, but instead data-driven. VDC1.HBlankCycles = int.Parse(game.GetOptions().GetOptionValue("HBlankPeriod"));
// 2) The games which have custom HBlankPeriods work without it, the override only
// serves to clean up minor gfx anomalies.
// 3) There's no point in haxing the timing with incorrect values in an attempt to avoid this.
// The proper fix is cycle-accurate/bus-accurate timing. That isn't coming to the C#
// version of this core. Let's just acknolwedge that the timing is imperfect and fix
// it in the least intrusive and most honest way we can.
if (game.GetOptions().ContainsStartsWith("HBlankPeriod")) // This is also a hack. Proper multi-res/TV emulation will be a native-code core feature.
VDC1.HBlankCycles = int.Parse(game.GetOptions().GetOptionValue("HBlankPeriod"));
if (game.GetOptions().ContainsStartsWith("MultiResHack"))
{
VDC1.MultiResHack = int.Parse(game.GetOptions().GetOptionValue("MultiResHack"));
}
// This is also a hack. Proper multi-res/TV emulation will be a native-code core feature. Cpu.ResetPC();
SetupMemoryDomains();
}
if (game.GetOptions().ContainsStartsWith("MultiResHack")) private int _lagcount = 0;
{ private bool lagged = true;
VDC1.MultiResHack = int.Parse(game.GetOptions().GetOptionValue("MultiResHack")); private bool islag = false;
} public int Frame { get; set; }
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
public bool IsLagFrame { get { return islag; } }
Cpu.ResetPC(); public void ResetFrameCounter()
SetupMemoryDomains(); {
} // this should just be a public setter instead of a new method.
Frame = 0;
}
private int _lagcount = 0; public void FrameAdvance(bool render)
private bool lagged = true; {
private bool islag = false; lagged = true;
public int Frame { get; set; } Controller.UpdateControls(Frame++);
public void ResetFrameCounter()
{
Frame = 0;
}
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
public bool IsLagFrame { get { return islag; } }
public void FrameAdvance(bool render) PSG.BeginFrame(Cpu.TotalExecutedCycles);
{
lagged = true;
Controller.UpdateControls(Frame++);
PSG.BeginFrame(Cpu.TotalExecutedCycles); if (SuperGrafx)
VPC.ExecFrame(render);
else
VDC1.ExecFrame(render);
if (SuperGrafx) PSG.EndFrame(Cpu.TotalExecutedCycles);
VPC.ExecFrame(render); if (lagged)
else {
VDC1.ExecFrame(render); _lagcount++;
islag = true;
PSG.EndFrame(Cpu.TotalExecutedCycles); }
if (lagged) else
{ islag = false;
_lagcount++; }
islag = true;
}
else
islag = false;
}
public CoreInputComm CoreInputComm { get; set; } public CoreInputComm CoreInputComm { get; set; }
public CoreOutputComm CoreOutputComm { get; private set; } public CoreOutputComm CoreOutputComm { get; private set; }
public IVideoProvider VideoProvider public IVideoProvider VideoProvider
{ {
get { return (IVideoProvider)VPC ?? VDC1; } get { return (IVideoProvider) VPC ?? VDC1; }
} }
public ISoundProvider SoundProvider public ISoundProvider SoundProvider
{ {
get { return PSG; } get { return PSG; }
} }
public string SystemId { get { return "PCE"; } }
public string Region { get; set; }
public bool DeterministicEmulation { get; set; }
public string SystemId { get { return "PCE"; } } public byte[] SaveRam
public string Region { get; set; } {
public bool DeterministicEmulation { get; set; } get { return BRAM; }
}
public byte[] SaveRam public bool SaveRamModified { get; set; }
{
get { return BRAM; }
}
public bool SaveRamModified { get; set; } public void SaveStateText(TextWriter writer)
{
writer.WriteLine("[PCEngine]");
writer.Write("RAM ");
Ram.SaveAsHex(writer);
if (PopulousRAM != null)
{
writer.Write("PopulousRAM ");
PopulousRAM.SaveAsHex(writer);
}
writer.WriteLine("Frame " + Frame);
writer.WriteLine("Lag " + _lagcount);
if (Cpu.ReadMemory21 == ReadMemorySF2)
writer.WriteLine("SF2MapperLatch " + SF2MapperLatch);
writer.WriteLine("IOBuffer {0:X2}", IOBuffer);
writer.WriteLine();
public void SaveStateText(TextWriter writer) if (SuperGrafx)
{ {
writer.WriteLine("[PCEngine]"); Cpu.SaveStateText(writer);
writer.Write("RAM "); VPC.SaveStateText(writer);
Ram.SaveAsHex(writer); VCE.SaveStateText(writer);
if (PopulousRAM != null) VDC1.SaveStateText(writer, 1);
{ VDC2.SaveStateText(writer, 2);
writer.Write("PopulousRAM "); PSG.SaveStateText(writer);
PopulousRAM.SaveAsHex(writer); }
} else
writer.WriteLine("Frame " + Frame); {
writer.WriteLine("Lag " + _lagcount); Cpu.SaveStateText(writer);
if (Cpu.ReadMemory21 == ReadMemorySF2) VCE.SaveStateText(writer);
writer.WriteLine("SF2MapperLatch " + SF2MapperLatch); VDC1.SaveStateText(writer, 1);
writer.WriteLine("IOBuffer {0:X2}", IOBuffer); PSG.SaveStateText(writer);
writer.WriteLine(); }
writer.WriteLine("[/PCEngine]");
}
if (SuperGrafx) public void LoadStateText(TextReader reader)
{ {
Cpu.SaveStateText(writer); while (true)
VPC.SaveStateText(writer); {
VCE.SaveStateText(writer); string[] args = reader.ReadLine().Split(' ');
VDC1.SaveStateText(writer, 1); if (args[0].Trim() == "") continue;
VDC2.SaveStateText(writer, 2); if (args[0] == "[PCEngine]") continue;
PSG.SaveStateText(writer); if (args[0] == "[/PCEngine]") break;
} if (args[0] == "Frame")
else Frame = int.Parse(args[1]);
{ else if (args[0] == "Lag")
Cpu.SaveStateText(writer); _lagcount = int.Parse(args[1]);
VCE.SaveStateText(writer); else if (args[0] == "SF2MapperLatch")
VDC1.SaveStateText(writer, 1); SF2MapperLatch = byte.Parse(args[1]);
PSG.SaveStateText(writer); else if (args[0] == "IOBuffer")
} IOBuffer = byte.Parse(args[1], NumberStyles.HexNumber);
writer.WriteLine("[/PCEngine]"); else if (args[0] == "RAM")
} Ram.ReadFromHex(args[1]);
else if (args[0] == "PopulousRAM" && PopulousRAM != null)
PopulousRAM.ReadFromHex(args[1]);
else if (args[0] == "[HuC6280]")
Cpu.LoadStateText(reader);
else if (args[0] == "[PSG]")
PSG.LoadStateText(reader);
else if (args[0] == "[VCE]")
VCE.LoadStateText(reader);
else if (args[0] == "[VPC]")
VPC.LoadStateText(reader);
else if (args[0] == "[VDC1]")
VDC1.LoadStateText(reader, 1);
else if (args[0] == "[VDC2]")
VDC2.LoadStateText(reader, 2);
else
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
}
}
public void LoadStateText(TextReader reader) public void SaveStateBinary(BinaryWriter writer)
{ {
while (true) if (SuperGrafx == false)
{ {
string[] args = reader.ReadLine().Split(' '); writer.Write(Ram);
if (args[0].Trim() == "") continue; if (PopulousRAM != null)
if (args[0] == "[PCEngine]") continue; writer.Write(PopulousRAM);
if (args[0] == "[/PCEngine]") break; writer.Write(Frame);
if (args[0] == "Frame") writer.Write(_lagcount);
Frame = int.Parse(args[1]); writer.Write(SF2MapperLatch);
else if (args[0] == "Lag") writer.Write(IOBuffer);
_lagcount = int.Parse(args[1]); Cpu.SaveStateBinary(writer);
else if (args[0] == "SF2MapperLatch") VCE.SaveStateBinary(writer);
SF2MapperLatch = byte.Parse(args[1]); VDC1.SaveStateBinary(writer);
else if (args[0] == "IOBuffer") PSG.SaveStateBinary(writer);
IOBuffer = byte.Parse(args[1], NumberStyles.HexNumber); } else {
else if (args[0] == "RAM") writer.Write(Ram);
Ram.ReadFromHex(args[1]); writer.Write(Frame);
else if (args[0] == "PopulousRAM" && PopulousRAM != null) writer.Write(_lagcount);
PopulousRAM.ReadFromHex(args[1]); writer.Write(IOBuffer);
else if (args[0] == "[HuC6280]") Cpu.SaveStateBinary(writer);
Cpu.LoadStateText(reader); VCE.SaveStateBinary(writer);
else if (args[0] == "[PSG]") VPC.SaveStateBinary(writer);
PSG.LoadStateText(reader); VDC1.SaveStateBinary(writer);
else if (args[0] == "[VCE]") VDC2.SaveStateBinary(writer);
VCE.LoadStateText(reader); PSG.SaveStateBinary(writer);
else if (args[0] == "[VPC]") }
VPC.LoadStateText(reader); }
else if (args[0] == "[VDC1]")
VDC1.LoadStateText(reader, 1);
else if (args[0] == "[VDC2]")
VDC2.LoadStateText(reader, 2);
else
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
}
}
public void SaveStateBinary(BinaryWriter writer) public void LoadStateBinary(BinaryReader reader)
{ {
if (SuperGrafx == false) if (SuperGrafx == false)
{ {
writer.Write(Ram); Ram = reader.ReadBytes(0x2000);
if (PopulousRAM != null) if (PopulousRAM != null)
writer.Write(PopulousRAM); PopulousRAM = reader.ReadBytes(0x8000);
writer.Write(Frame); Frame = reader.ReadInt32();
writer.Write(_lagcount); _lagcount = reader.ReadInt32();
writer.Write(SF2MapperLatch); SF2MapperLatch = reader.ReadByte();
writer.Write(IOBuffer); IOBuffer = reader.ReadByte();
Cpu.SaveStateBinary(writer); Cpu.LoadStateBinary(reader);
VCE.SaveStateBinary(writer); VCE.LoadStateBinary(reader);
VDC1.SaveStateBinary(writer); VDC1.LoadStateBinary(reader);
PSG.SaveStateBinary(writer); PSG.LoadStateBinary(reader);
} } else {
else Ram = reader.ReadBytes(0x8000);
{ Frame = reader.ReadInt32();
writer.Write(Ram); _lagcount = reader.ReadInt32();
writer.Write(Frame); IOBuffer = reader.ReadByte();
writer.Write(_lagcount); Cpu.LoadStateBinary(reader);
writer.Write(IOBuffer); VCE.LoadStateBinary(reader);
Cpu.SaveStateBinary(writer); VPC.LoadStateBinary(reader);
VCE.SaveStateBinary(writer); VDC1.LoadStateBinary(reader);
VPC.SaveStateBinary(writer); VDC2.LoadStateBinary(reader);
VDC1.SaveStateBinary(writer); PSG.LoadStateBinary(reader);
VDC2.SaveStateBinary(writer); }
PSG.SaveStateBinary(writer); }
}
}
public void LoadStateBinary(BinaryReader reader) public byte[] SaveStateBinary()
{ {
if (SuperGrafx == false) int buflen = 75866;
{ if (SuperGrafx) buflen += 90698;
Ram = reader.ReadBytes(0x2000); if (BramEnabled) buflen += 2048;
if (PopulousRAM != null) if (PopulousRAM != null) buflen += 0x8000;
PopulousRAM = reader.ReadBytes(0x8000);
Frame = reader.ReadInt32();
_lagcount = reader.ReadInt32();
SF2MapperLatch = reader.ReadByte();
IOBuffer = reader.ReadByte();
Cpu.LoadStateBinary(reader);
VCE.LoadStateBinary(reader);
VDC1.LoadStateBinary(reader);
PSG.LoadStateBinary(reader);
}
else
{
Ram = reader.ReadBytes(0x8000);
Frame = reader.ReadInt32();
_lagcount = reader.ReadInt32();
IOBuffer = reader.ReadByte();
Cpu.LoadStateBinary(reader);
VCE.LoadStateBinary(reader);
VPC.LoadStateBinary(reader);
VDC1.LoadStateBinary(reader);
VDC2.LoadStateBinary(reader);
PSG.LoadStateBinary(reader);
}
}
public byte[] SaveStateBinary() var buf = new byte[buflen];
{ var stream = new MemoryStream(buf);
int buflen = 75866; var writer = new BinaryWriter(stream);
if (SuperGrafx) buflen += 90698; SaveStateBinary(writer);
if (BramEnabled) buflen += 2048; //Console.WriteLine("LENGTH " + stream.Position);
if (PopulousRAM != null) buflen += 0x8000; writer.Close();
return buf;
}
var buf = new byte[buflen]; private void SetupMemoryDomains()
var stream = new MemoryStream(buf); {
var writer = new BinaryWriter(stream); var domains = new List<MemoryDomain>(1);
SaveStateBinary(writer); var MainMemoryDomain = new MemoryDomain("Main Memory", Ram.Length, Endian.Little,
//Console.WriteLine("LENGTH " + stream.Position); addr => Ram[addr & 0x7FFF],
writer.Close(); (addr, value) => Ram[addr & 0x7FFF] = value);
return buf; var SystemBusDomain = new MemoryDomain("System Bus", 0x2F0000, Endian.Little,
} addr => Cpu.ReadMemory21(addr),
(addr, value) => Cpu.WriteMemory21(addr, value));
domains.Add(MainMemoryDomain);
domains.Add(SystemBusDomain);
memoryDomains = domains.AsReadOnly();
}
private void SetupMemoryDomains() private IList<MemoryDomain> memoryDomains;
{ public IList<MemoryDomain> MemoryDomains { get { return memoryDomains; } }
var domains = new List<MemoryDomain>(1); public MemoryDomain MainMemory { get { return memoryDomains[0]; } }
var MainMemoryDomain = new MemoryDomain("Main Memory", Ram.Length, Endian.Little,
addr => Ram[addr & 0x7FFF],
(addr, value) => Ram[addr & 0x7FFF] = value);
var SystemBusDomain = new MemoryDomain("System Bus", 0x2F0000, Endian.Little,
addr => Cpu.ReadMemory21(addr),
(addr, value) => Cpu.WriteMemory21(addr, value));
domains.Add(MainMemoryDomain);
domains.Add(SystemBusDomain);
memoryDomains = domains.AsReadOnly();
}
private IList<MemoryDomain> memoryDomains; public void Dispose() {}
public IList<MemoryDomain> MemoryDomains { get { return memoryDomains; } } }
public MemoryDomain MainMemory { get { return memoryDomains[0]; } }
public void Dispose() { }
}
} }

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
//TBD CCD format //TBD CCD format
public class CCDFormat public class CCDFormat

View File

@ -6,7 +6,7 @@ using System.Collections.Generic;
//this rule is not supported correctly: `The first track number can be greater than one, but all track numbers after the first must be sequential.` //this rule is not supported correctly: `The first track number can be greater than one, but all track numbers after the first must be sequential.`
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
partial class Disc partial class Disc
{ {

View File

@ -3,9 +3,8 @@ using System.Collections.Generic;
//main apis for emulator core routine use //main apis for emulator core routine use
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
public class DiscHopper public class DiscHopper
{ {
public Disc CurrentDisc; public Disc CurrentDisc;
@ -83,11 +82,31 @@ namespace BizHawk.Disc
return TOC; return TOC;
} }
// converts LBA to minute:second:frame format.
public static void ConvertLBAtoMSF(int lba, out byte m, out byte s, out byte f) public static void ConvertLBAtoMSF(int lba, out byte m, out byte s, out byte f)
{ {
m = (byte) (lba / 75 / 60); m = (byte) (lba / 75 / 60);
s = (byte) ((lba - (m * 75 * 60)) / 75); s = (byte) ((lba - (m * 75 * 60)) / 75);
f = (byte) (lba - (m * 75 * 60) - (s * 75)); f = (byte) (lba - (m * 75 * 60) - (s * 75));
} }
// gets an identifying hash. hashes the first 512 sectors of
// the first data track on the disc.
public string GetHash()
{
byte[] buffer = new byte[512*2353];
foreach (var track in TOC.Sessions[0].Tracks)
{
if (track.TrackType == ETrackType.Audio)
continue;
int lba_len = Math.Min(track.length_lba, 512);
for (int s=0; s<512 && s<track.length_lba; s++)
ReadLBA_2352(track.Indexes[1].lba + s, buffer, s*2352);
return Util.Hash_MD5(buffer, 0, lba_len*2352);
}
return "no data track found";
}
} }
} }

View File

@ -66,7 +66,7 @@ using System.Collections.Generic;
//mode2_2352 is the only kind of mode2, by necessity //mode2_2352 is the only kind of mode2, by necessity
//audio is a different mode, seems to be just 2352 bytes with no sync, header or error correction. i guess the CIRC error correction is still there //audio is a different mode, seems to be just 2352 bytes with no sync, header or error correction. i guess the CIRC error correction is still there
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
public partial class Disc public partial class Disc
{ {

View File

@ -4,7 +4,7 @@ using System.Text.RegularExpressions;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
public class DiscTOC public class DiscTOC

View File

@ -1,4 +1,4 @@
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
static class ECM static class ECM
{ {

View File

@ -7,7 +7,7 @@ using System.Collections.Generic;
//a decent little subcode reference //a decent little subcode reference
//http://www.jbum.com/cdg_revealed.html //http://www.jbum.com/cdg_revealed.html
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
public class SubcodeStream public class SubcodeStream
{ {

View File

@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace BizHawk.Disc namespace BizHawk.DiscSystem
{ {
//TBD TOC format //TBD TOC format
public class TOCFormat public class TOCFormat

View File

@ -10,6 +10,7 @@ using System.Reflection;
using System.Text; using System.Text;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Threading; using System.Threading;
using BizHawk.DiscSystem;
namespace BizHawk namespace BizHawk
{ {
@ -40,7 +41,7 @@ namespace BizHawk
base.Dispose(); base.Dispose();
} }
public Disc.DiscHopper DiscHopper; public DiscHopper DiscHopper;
void SetFp(string name, Delegate del) void SetFp(string name, Delegate del)
{ {
@ -49,7 +50,7 @@ namespace BizHawk
struct TrackInfo struct TrackInfo
{ {
public Disc.ETrackType TrackType; public ETrackType TrackType;
public int length_lba; public int length_lba;
public int start_lba; public int start_lba;
} }

View File

@ -5,6 +5,7 @@ using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.DiscSystem;
namespace BizHawk namespace BizHawk
{ {
@ -29,7 +30,7 @@ namespace BizHawk
} }
DiscInterface mDiscInterface; DiscInterface mDiscInterface;
public void SetDiscHopper(Disc.DiscHopper hopper) public void SetDiscHopper(DiscHopper hopper)
{ {
mDiscInterface.DiscHopper = hopper; mDiscInterface.DiscHopper = hopper;
} }

View File

@ -1,4 +1,5 @@
using SlimDX.Direct3D9; using BizHawk.DiscSystem;
using SlimDX.Direct3D9;
using SlimDX.DirectSound; using SlimDX.DirectSound;
namespace BizHawk.MultiClient namespace BizHawk.MultiClient
@ -74,7 +75,7 @@ namespace BizHawk.MultiClient
return mg.GetControllersAsMnemonic(); return mg.GetControllersAsMnemonic();
} }
public static Disc.DiscHopper DiscHopper = new BizHawk.Disc.DiscHopper(); public static DiscHopper DiscHopper = new DiscHopper();
public static CoreAccessor PsxCoreLibrary = new CoreAccessor(new Win32LibAccessor("PsxHawk.Core.dll")); public static CoreAccessor PsxCoreLibrary = new CoreAccessor(new Win32LibAccessor("PsxHawk.Core.dll"));

View File

@ -4,9 +4,9 @@ using System.Threading;
using System.Drawing; using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Core; using BizHawk.Core;
using BizHawk.DiscSystem;
using BizHawk.Emulation.Consoles.Sega; using BizHawk.Emulation.Consoles.Sega;
using BizHawk.Emulation.Consoles.TurboGrafx; using BizHawk.Emulation.Consoles.TurboGrafx;
using BizHawk.Emulation.Consoles.Calculator; using BizHawk.Emulation.Consoles.Calculator;
@ -847,7 +847,7 @@ namespace BizHawk.MultiClient
PsxCore psx = new PsxCore(Global.PsxCoreLibrary); PsxCore psx = new PsxCore(Global.PsxCoreLibrary);
nextEmulator = psx; nextEmulator = psx;
game = new RomGame(); game = new RomGame();
var disc = Disc.Disc.FromIsoPath(path); var disc = Disc.FromIsoPath(path);
Global.DiscHopper.Clear(); Global.DiscHopper.Clear();
Global.DiscHopper.Enqueue(disc); Global.DiscHopper.Enqueue(disc);
Global.DiscHopper.Insert(); Global.DiscHopper.Insert();