C64: Internal support for multiple files and Epyx Fastload support.

This commit is contained in:
Anthony Konzel 2016-03-03 21:14:19 -06:00
parent a435cc912c
commit 87200593b6
10 changed files with 181 additions and 89 deletions

View File

@ -209,6 +209,7 @@
<Compile Include="Computers\Commodore64\Cartridge\Mapper0000.cs" />
<Compile Include="Computers\Commodore64\C64.Input.cs" />
<Compile Include="Computers\Commodore64\Cartridge\Mapper0005.cs" />
<Compile Include="Computers\Commodore64\Cartridge\Mapper000A.cs" />
<Compile Include="Computers\Commodore64\Cartridge\Mapper000B.cs" />
<Compile Include="Computers\Commodore64\Cartridge\Mapper000F.cs" />
<Compile Include="Computers\Commodore64\Cartridge\Mapper0011.cs" />
@ -218,7 +219,6 @@
<Compile Include="Computers\Commodore64\Cassette\CassettePortDevice.cs" />
<Compile Include="Computers\Commodore64\Cassette\TapeDrive.cs" />
<Compile Include="Computers\Commodore64\Media\Tape.cs" />
<Compile Include="Computers\Commodore64\InputFileInfo.cs" />
<Compile Include="Computers\Commodore64\Media\PRG.cs" />
<Compile Include="Computers\Commodore64\Cartridge\CartridgeDevice.cs" />
<Compile Include="Computers\Commodore64\Cartridge\CartridgePort.cs" />

View File

@ -159,6 +159,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
_vicBank = (0x3 - ((Cia1.PrA | ~Cia1.DdrA) & 0x3)) << 14;
Vic.ExecutePhase();
CartPort.ExecutePhase();
Cassette.ExecutePhase();
Serial.ExecutePhase();
Sid.ExecutePhase();
@ -190,6 +191,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
Cassette.HardReset();
Serial.HardReset();
Cpu.HardReset();
CartPort.HardReset();
}
public void Init()

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 romextension, object settings, object syncSettings)
public C64(CoreComm comm, GameInfo game, byte[] rom, string extension, object settings, object syncSettings)
{
PutSyncSettings((C64SyncSettings)syncSettings ?? new C64SyncSettings());
PutSettings((C64Settings)settings ?? new C64Settings());
@ -30,14 +30,9 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
ServiceProvider = new BasicServiceProvider(this);
InputCallbacks = new InputCallbackSystem();
_inputFileInfo = new InputFileInfo
{
Data = rom,
Extension = romextension
};
CoreComm = comm;
Init(SyncSettings.VicType, Settings.BorderType, SyncSettings.SidType, SyncSettings.TapeDriveType, SyncSettings.DiskDriveType);
Roms = new Dictionary<string, byte[]> { { "rom" + extension.ToUpper(), rom } };
Init(SyncSettings.VicType, Settings.BorderType, SyncSettings.SidType, SyncSettings.TapeDriveType, SyncSettings.DiskDriveType);
_cyclesPerFrame = _board.Vic.CyclesPerFrame;
SetupMemoryDomains(_board.DiskDrive != null);
_memoryCallbacks = new MemoryCallbackSystem();
@ -62,7 +57,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
// internal variables
private int _frame;
[SaveState.DoNotSave] private readonly int _cyclesPerFrame;
[SaveState.DoNotSave] private InputFileInfo _inputFileInfo;
private bool _driveLed;
// bizhawk I/O
@ -94,6 +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]
private static readonly ControllerDefinition C64ControllerDefinition = new ControllerDefinition
@ -155,7 +150,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
// check to see if cpu PC is at the BASIC warm start vector
if (_board.Cpu.Pc != 0 && _board.Cpu.Pc == ((_board.Ram.Peek(0x0303) << 8) | _board.Ram.Peek(0x0302)))
{
Prg.Load(_board.Pla, _inputFileInfo.Data);
Prg.Load(_board.Pla, _prgFile);
_loadPrg = false;
}
}
@ -182,6 +177,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
private Motherboard _board;
private bool _loadPrg;
[SaveState.DoNotSave] private byte[] _prgFile;
private byte[] GetFirmware(int length, params string[] names)
{
@ -194,29 +190,29 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
private void Init(VicType initRegion, BorderType borderType, SidType sidType, TapeDriveType tapeDriveType, DiskDriveType diskDriveType)
{
// Force certain drive types to be available depending on ROM type
switch (_inputFileInfo.Extension.ToUpper())
foreach (var rom in Roms)
{
case @".D64":
case @".G64":
if (diskDriveType == DiskDriveType.None)
{
diskDriveType = DiskDriveType.Commodore1541;
}
break;
case @".TAP":
if (tapeDriveType == TapeDriveType.None)
{
tapeDriveType = TapeDriveType.Commodore1530;
}
break;
}
switch (Path.GetExtension(rom.Key).ToUpper())
{
case @".D64":
case @".G64":
if (diskDriveType == DiskDriveType.None)
{
diskDriveType = DiskDriveType.Commodore1541;
}
break;
case @".TAP":
if (tapeDriveType == TapeDriveType.None)
{
tapeDriveType = TapeDriveType.Commodore1530;
}
break;
}
}
_board = new Motherboard(this, initRegion, borderType, sidType, tapeDriveType, diskDriveType);
InitRoms(diskDriveType);
_board.Init();
InitMedia();
// configure video
CoreComm.VsyncDen = _board.Vic.CyclesPerFrame;
@ -225,42 +221,48 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
private void InitMedia()
{
switch (_inputFileInfo.Extension.ToUpper())
{
case @".D64":
var d64 = D64.Read(_inputFileInfo.Data);
if (d64 != null)
{
_board.DiskDrive.InsertMedia(d64);
}
break;
case @".G64":
var g64 = G64.Read(_inputFileInfo.Data);
if (g64 != null)
{
_board.DiskDrive.InsertMedia(g64);
}
break;
case @".CRT":
var cart = CartridgeDevice.Load(_inputFileInfo.Data);
if (cart != null)
{
_board.CartPort.Connect(cart);
}
break;
case @".TAP":
var tape = Tape.Load(_inputFileInfo.Data);
if (tape != null)
{
_board.TapeDrive.Insert(tape);
}
break;
case @".PRG":
if (_inputFileInfo.Data.Length > 2)
_loadPrg = true;
break;
}
}
foreach (var rom in Roms)
{
switch (Path.GetExtension(rom.Key).ToUpper())
{
case @".D64":
var d64 = D64.Read(rom.Value);
if (d64 != null)
{
_board.DiskDrive.InsertMedia(d64);
}
break;
case @".G64":
var g64 = G64.Read(rom.Value);
if (g64 != null)
{
_board.DiskDrive.InsertMedia(g64);
}
break;
case @".CRT":
var cart = CartridgeDevice.Load(rom.Value);
if (cart != null)
{
_board.CartPort.Connect(cart);
}
break;
case @".TAP":
var tape = Tape.Load(rom.Value);
if (tape != null)
{
_board.TapeDrive.Insert(tape);
}
break;
case @".PRG":
if (rom.Value.Length > 2)
{
_loadPrg = true;
_prgFile = rom.Value;
}
break;
}
}
}
private void InitRoms(DiskDriveType diskDriveType)
{
@ -274,7 +276,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
if (diskDriveType == DiskDriveType.Commodore1541)
{
var diskRom = GetFirmware(0x4000, "Drive1541II", "Drive1541");
var diskRom = GetFirmware(0x4000, "Drive1541", "Drive1541II");
_board.DiskDrive.DriveRom.Flash(diskRom);
}
}
@ -283,7 +285,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
public void HardReset()
{
_board.HardReset();
InitMedia();
_board.HardReset();
}
}
}

View File

@ -74,7 +74,10 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge
case 0x0005:
result = new Mapper0005(chipAddress, chipBank, chipData);
break;
case 0x000B:
case 0x000A:
result = new Mapper000A(chipAddress, chipBank, chipData);
break;
case 0x000B:
result = new Mapper000B(chipAddress, chipData);
break;
case 0x000F:
@ -127,11 +130,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge
[SaveState.DoNotSave]
protected bool validCartridge;
public virtual void ExecutePhase1()
{
}
public virtual void ExecutePhase2()
public virtual void ExecutePhase()
{
}

View File

@ -89,6 +89,12 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge
_connected = false;
}
public void ExecutePhase()
{
if (_connected)
_cartridgeDevice.ExecutePhase();
}
public void HardReset()
{
// note: this will not disconnect any attached media

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge
{
//792
// Epyx Fastload. Uppermost page is always visible at DFxx.
// They use a capacitor that is recharged by accesses to DExx
// to pull down EXROM.
public abstract partial class CartridgeDevice
{
private class Mapper000A : CartridgeDevice
{
// This constant differs depending on whose research you reference. TODO: Verify.
[SaveState.DoNotSave]
private const int RESET_CAPACITOR_CYCLES = 512;
[SaveState.SaveWithName("CapacitorCycles")]
private int _capacitorCycles;
[SaveState.DoNotSave]
private readonly int[] _rom;
public Mapper000A(IList<int> newAddresses, IList<int> newBanks, IList<int[]> newData)
{
_rom = new int[0x2000];
Array.Copy(newData.First(), _rom, 0x2000);
pinGame = true;
}
public override void ExecutePhase()
{
pinExRom = !(_capacitorCycles > 0);
if (!pinExRom)
{
_capacitorCycles--;
}
}
public override void HardReset()
{
_capacitorCycles = RESET_CAPACITOR_CYCLES;
base.HardReset();
}
public override int Peek8000(int addr)
{
return _rom[addr & 0x1FFF];
}
public override int PeekDE00(int addr)
{
return 0x00;
}
public override int PeekDF00(int addr)
{
return _rom[(addr & 0xFF) | 0x1F00];
}
public override int Read8000(int addr)
{
_capacitorCycles = RESET_CAPACITOR_CYCLES;
return _rom[addr & 0x1FFF];
}
public override int ReadDE00(int addr)
{
_capacitorCycles = RESET_CAPACITOR_CYCLES;
return 0x00;
}
public override int ReadDF00(int addr)
{
return _rom[(addr & 0xFF) | 0x1F00];
}
}
}
}

View File

@ -1,8 +0,0 @@
namespace BizHawk.Emulation.Cores.Computers.Commodore64
{
public struct InputFileInfo
{
public byte[] Data;
public string Extension;
}
}

View File

@ -72,7 +72,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media
paddedBytes[i] = 0xAA;
}
var result = new int[FluxEntriesPerTrack];
var length = paddedLength;
var lengthBits = (paddedLength * 8) - 7;
var offsets = new List<long>();
var remainingBits = lengthBits;

View File

@ -48,15 +48,23 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
// rotate disk
if (_motorEnabled)
{
if (_diskBitsLeft <= 0)
if (_disk == null)
{
_diskByteOffset++;
if (_diskByteOffset == Disk.FluxEntriesPerTrack)
_diskBitsLeft = 1;
_diskBits = 0;
}
else
{
if (_diskBitsLeft <= 0)
{
_diskByteOffset = 0;
_diskByteOffset++;
if (_diskByteOffset == Disk.FluxEntriesPerTrack)
{
_diskByteOffset = 0;
}
_diskBits = _trackImageData[_diskByteOffset];
_diskBitsLeft = Disk.FluxBitsPerEntry;
}
_diskBits = _trackImageData[_diskByteOffset];
_diskBitsLeft = Disk.FluxBitsPerEntry;
}
if ((_diskBits & 1) != 0)
{

View File

@ -218,7 +218,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Serial
public void RemoveMedia()
{
_trackImageData = new int[1];
_disk = null;
}
public int Peek(int addr)