C64: Discover file formats heuristically instead of by filename.

This commit is contained in:
Anthony Konzel 2016-03-05 15:23:22 -06:00
parent 57676608d0
commit 8fd552274e
10 changed files with 108 additions and 28 deletions

View File

@ -776,7 +776,7 @@ namespace BizHawk.Client.Common
nextEmulator = new Atari7800(nextComm, game, rom.RomData, gamedbpath);
break;
case "C64":
var c64 = new C64(nextComm, game, rom.RomData, rom.Extension, GetCoreSettings<C64>(), GetCoreSyncSettings<C64>());
var c64 = new C64(nextComm, game, rom.RomData, GetCoreSettings<C64>(), GetCoreSyncSettings<C64>());
nextEmulator = c64;
break;
case "GBA":

View File

@ -205,6 +205,7 @@
</Compile>
<Compile Include="Computers\Commodore64\C64.Motherboard.cs" />
<Compile Include="Computers\Commodore64\C64.MotherboardInterface.cs" />
<Compile Include="Computers\Commodore64\C64Format.cs" />
<Compile Include="Computers\Commodore64\C64Util.cs" />
<Compile Include="Computers\Commodore64\Cartridge\Mapper0000.cs" />
<Compile Include="Computers\Commodore64\C64.Input.cs" />
@ -218,6 +219,7 @@
<Compile Include="Computers\Commodore64\Cartridge\Mapper0020.cs" />
<Compile Include="Computers\Commodore64\Cassette\CassettePortDevice.cs" />
<Compile Include="Computers\Commodore64\Cassette\TapeDrive.cs" />
<Compile Include="Computers\Commodore64\C64FormatFinder.cs" />
<Compile Include="Computers\Commodore64\Media\Tape.cs" />
<Compile Include="Computers\Commodore64\Media\PRG.cs" />
<Compile Include="Computers\Commodore64\Cartridge\CartridgeDevice.cs" />

View File

@ -115,7 +115,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
public enum DiskDriveType
{
None, Commodore1541, Commodore1541II
None, Commodore1541, Commodore1541II, Commodore1571
}
}
}

View File

@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
public sealed partial class C64 : IEmulator, IRegionable
{
// framework
public C64(CoreComm comm, GameInfo game, byte[] rom, string extension, object settings, object syncSettings)
public C64(CoreComm comm, GameInfo game, byte[] rom, object settings, object syncSettings)
{
PutSyncSettings((C64SyncSettings)syncSettings ?? new C64SyncSettings());
PutSettings((C64Settings)settings ?? new C64Settings());
@ -31,7 +31,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
InputCallbacks = new InputCallbackSystem();
CoreComm = comm;
Roms = new Dictionary<string, byte[]> { { "rom" + extension.ToUpper(), rom } };
Roms = new List<byte[]> { rom };
Init(SyncSettings.VicType, Settings.BorderType, SyncSettings.SidType, SyncSettings.TapeDriveType, SyncSettings.DiskDriveType);
_cyclesPerFrame = _board.Vic.CyclesPerFrame;
SetupMemoryDomains(_board.DiskDrive != null);
@ -88,7 +88,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
// controller
[SaveState.DoNotSave] public ControllerDefinition ControllerDefinition { get { return C64ControllerDefinition; } }
[SaveState.DoNotSave] public IController Controller { get { return _board.Controller; } set { _board.Controller = value; } }
[SaveState.DoNotSave] public IDictionary<string, byte[]> Roms { get; private set; }
[SaveState.DoNotSave] public IEnumerable<byte[]> Roms { get; private set; }
[SaveState.DoNotSave]
private static readonly ControllerDefinition C64ControllerDefinition = new ControllerDefinition
@ -204,16 +204,20 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
// Force certain drive types to be available depending on ROM type
foreach (var rom in Roms)
{
switch (Path.GetExtension(rom.Key).ToUpper())
switch (C64FormatFinder.GetFormat(rom))
{
case @".D64":
case @".G64":
case C64Format.D64:
case C64Format.G64:
case C64Format.X64:
if (diskDriveType == DiskDriveType.None)
{
diskDriveType = DiskDriveType.Commodore1541;
}
break;
case @".TAP":
case C64Format.D71:
if (diskDriveType == DiskDriveType.None)
diskDriveType = DiskDriveType.Commodore1571;
break;
case C64Format.T64:
case C64Format.TAP:
if (tapeDriveType == TapeDriveType.None)
{
tapeDriveType = TapeDriveType.Commodore1530;
@ -235,41 +239,41 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
{
foreach (var rom in Roms)
{
switch (Path.GetExtension(rom.Key).ToUpper())
switch (C64FormatFinder.GetFormat(rom))
{
case @".D64":
var d64 = D64.Read(rom.Value);
case C64Format.D64:
var d64 = D64.Read(rom);
if (d64 != null)
{
_board.DiskDrive.InsertMedia(d64);
}
break;
case @".G64":
var g64 = G64.Read(rom.Value);
case C64Format.G64:
var g64 = G64.Read(rom);
if (g64 != null)
{
_board.DiskDrive.InsertMedia(g64);
}
break;
case @".CRT":
var cart = CartridgeDevice.Load(rom.Value);
case C64Format.CRT:
var cart = CartridgeDevice.Load(rom);
if (cart != null)
{
_board.CartPort.Connect(cart);
}
break;
case @".TAP":
var tape = Tape.Load(rom.Value);
case C64Format.TAP:
var tape = Tape.Load(rom);
if (tape != null)
{
_board.TapeDrive.Insert(tape);
}
break;
case @".PRG":
if (rom.Value.Length > 2)
default:
if (rom.Length > 2)
{
_loadPrg = true;
_prgFile = rom.Value;
_prgFile = rom;
}
break;
}
@ -290,8 +294,11 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
case DiskDriveType.Commodore1541II:
_board.DiskDrive.DriveRom.Flash(GetFirmware(0x4000, "Drive1541II"));
break;
case DiskDriveType.Commodore1571:
_board.DiskDrive.DriveRom.Flash(GetFirmware(0x8000, "Drive1571"));
break;
}
}
}
// ------------------------------------

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Cores.Computers.Commodore64
{
public enum C64Format
{
Unknown,
D64,
D71,
D81,
X64,
G64,
T64,
TAP,
CRT,
P64,
P00,
D82,
D80,
}
}

View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Cores.Computers.Commodore64
{
public static class C64FormatFinder
{
public static C64Format GetFormat(byte[] data)
{
if (data == null || data.Length < 0x10)
return C64Format.Unknown;
using (var mem = new MemoryStream(data))
{
var reader = new BinaryReader(mem);
var header = Encoding.GetEncoding(437).GetString(reader.ReadBytes(0x10));
if (header.StartsWith("C64 CARTRIDGE "))
return C64Format.CRT;
if (header.StartsWith("GCR-1541"))
return C64Format.G64;
if (header.StartsWith("C64S tape image "))
return C64Format.T64;
if (header.StartsWith("C64-TAPE-RAW"))
return C64Format.TAP;
if (header.StartsWith("C64File"))
return C64Format.P00;
if (header.StartsWith("P64-1541"))
return C64Format.P64;
if (data[0] == 0x43 && data[1] == 0x15 && data[2] == 0x41 && data[3] == 0x64)
return C64Format.X64;
if (data.Length == 174848 || data.Length == 175531 || data.Length == 196608 || data.Length == 197376)
return C64Format.D64;
if (data.Length == 349696 || data.Length == 351062)
return C64Format.D71;
if (data.Length == 533248)
return C64Format.D80;
if (data.Length == 819200 || data.Length == 822400)
return C64Format.D81;
if (data.Length == 1066496)
return C64Format.D82;
}
return C64Format.Unknown;
}
}
}

View File

@ -202,7 +202,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media
}
}
return new Disk(trackDatas, trackNumbers, trackDensities, trackLengths, 84);
return new Disk(trackDatas, trackNumbers, trackDensities, 84);
}
}
}

View File

@ -35,7 +35,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media
/// <param name="trackDensities">Density zones for the raw bit data.</param>
/// <param name="trackLengths">Length, in bits, of each raw bit data.</param>
/// <param name="trackCapacity">Total number of tracks on the media.</param>
public Disk(IList<byte[]> trackData, IList<int> trackNumbers, IList<int> trackDensities, IList<int> trackLengths, int trackCapacity)
public Disk(IList<byte[]> trackData, IList<int> trackNumbers, IList<int> trackDensities, int trackCapacity)
{
WriteProtected = true;
_tracks = new int[trackCapacity][];

View File

@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media
throw new Exception("Byte-level speeds are not yet supported in the G64 loader.");
}
return new Disk(trackDatas, trackNumbers, trackDensities, trackLengths, 84);
return new Disk(trackDatas, trackNumbers, trackDensities, 84);
}
return new Disk(84);

View File

@ -119,7 +119,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
if (_ledEnabled)
{
_driveLightOffTime = 1000000;
_driveLightOffTime = 25000;
}
else if (_driveLightOffTime > 0)
{