Add files via upload
This commit is contained in:
parent
1e29c7d955
commit
38bae4b419
|
@ -54,11 +54,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMemoryCallbackSystem MemoryCallbacks
|
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
|
||||||
{
|
|
||||||
[FeatureNotImplemented]
|
|
||||||
get { throw new NotImplementedException(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CanStep(StepType type)
|
public bool CanStep(StepType type)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
{
|
{
|
||||||
|
@ -6,15 +7,29 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
{
|
{
|
||||||
public IEmulatorServiceProvider ServiceProvider { get; }
|
public IEmulatorServiceProvider ServiceProvider { get; }
|
||||||
|
|
||||||
public ControllerDefinition ControllerDefinition { get; private set; }
|
public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;
|
||||||
|
|
||||||
//Maria related variables
|
//Maria related variables
|
||||||
public int cycle;
|
public int cycle;
|
||||||
public int cpu_cycle;
|
public int cpu_cycle;
|
||||||
public int scanline;
|
public int scanline;
|
||||||
|
|
||||||
|
// there are 4 maria cycles in a CPU cycle (fast access, both NTSC and PAL)
|
||||||
|
// if the 6532 or TIA are accessed (PC goes to one of those addresses) the next access will be slower by 1/2 a CPU cycle
|
||||||
|
// i.e. it will take 6 Maria cycles instead of 4
|
||||||
|
public bool slow_access = false;
|
||||||
|
|
||||||
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
public void FrameAdvance(IController controller, bool render, bool rendersound)
|
||||||
{
|
{
|
||||||
|
if (_tracer.Enabled)
|
||||||
|
{
|
||||||
|
cpu.TraceCallback = s => _tracer.Put(s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cpu.TraceCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
_frame++;
|
_frame++;
|
||||||
|
|
||||||
if (controller.IsPressed("Power"))
|
if (controller.IsPressed("Power"))
|
||||||
|
@ -29,6 +44,9 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
_lagcount++;
|
_lagcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read the controller state here for now
|
||||||
|
GetControllerState(controller);
|
||||||
|
|
||||||
scanline = 0;
|
scanline = 0;
|
||||||
|
|
||||||
// actually execute the frame
|
// actually execute the frame
|
||||||
|
@ -37,18 +55,61 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
maria.Execute(cycle, scanline);
|
maria.Execute(cycle, scanline);
|
||||||
cycle++;
|
cycle++;
|
||||||
cpu_cycle++;
|
cpu_cycle++;
|
||||||
|
tia._hsyncCnt++;
|
||||||
|
|
||||||
|
// the time a cpu cycle takes depends on the status of the address bus
|
||||||
|
// any address in range of the TIA or m6532 takes an extra cycle to complete
|
||||||
|
if (cpu_cycle==(4 + (slow_access ? 2 : 0)))
|
||||||
|
{
|
||||||
|
cpu.ExecuteOne();
|
||||||
|
cpu_cycle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine if the next access will be fast or slow
|
||||||
|
if (cpu.PC < 0x0400)
|
||||||
|
{
|
||||||
|
if ((cpu.PC & 0xFF) < 0x20)
|
||||||
|
{
|
||||||
|
if ((A7800_control_register & 0x1) == 0 && (cpu.PC < 0x20))
|
||||||
|
{
|
||||||
|
slow_access = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slow_access = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (cpu.PC < 0x300)
|
||||||
|
{
|
||||||
|
slow_access = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slow_access = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (cycle == 454)
|
if (cycle == 454)
|
||||||
{
|
{
|
||||||
scanline++;
|
scanline++;
|
||||||
cycle = 0;
|
cycle = 0;
|
||||||
|
tia._hsyncCnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void GetControllerState(IController controller)
|
||||||
|
{
|
||||||
|
InputCallbacks.Call();
|
||||||
|
|
||||||
|
ushort port1 = _controllerDeck.ReadPort1(controller);
|
||||||
|
|
||||||
|
ushort port2 = _controllerDeck.ReadPort2(controller);
|
||||||
|
}
|
||||||
|
|
||||||
public int Frame => _frame;
|
public int Frame => _frame;
|
||||||
|
|
||||||
public string SystemId => "A7800";
|
public string SystemId => "A7800";
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using BizHawk.Common;
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
|
{
|
||||||
|
public partial class A7800Hawk : IEmulator, IStatable, ISettable<A7800Hawk.A7800Settings, A7800Hawk.A7800SyncSettings>
|
||||||
|
{
|
||||||
|
public A7800Settings GetSettings()
|
||||||
|
{
|
||||||
|
return _settings.Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public A7800SyncSettings GetSyncSettings()
|
||||||
|
{
|
||||||
|
return _syncSettings.Clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool PutSettings(A7800Settings o)
|
||||||
|
{
|
||||||
|
_settings = o;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool PutSyncSettings(A7800SyncSettings o)
|
||||||
|
{
|
||||||
|
bool ret = A7800SyncSettings.NeedsReboot(_syncSettings, o);
|
||||||
|
_syncSettings = o;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private A7800Settings _settings = new A7800Settings();
|
||||||
|
private A7800SyncSettings _syncSettings = new A7800SyncSettings();
|
||||||
|
|
||||||
|
public class A7800Settings
|
||||||
|
{
|
||||||
|
public A7800Settings Clone()
|
||||||
|
{
|
||||||
|
return (A7800Settings)MemberwiseClone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class A7800SyncSettings
|
||||||
|
{
|
||||||
|
private string _port1 = A7800HawkControllerDeck.DefaultControllerName;
|
||||||
|
private string _port2 = A7800HawkControllerDeck.DefaultControllerName;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string Port1
|
||||||
|
{
|
||||||
|
get { return _port1; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!A7800HawkControllerDeck.ValidControllerTypes.ContainsKey(value))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Invalid controller type: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_port1 = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public string Port2
|
||||||
|
{
|
||||||
|
get { return _port2; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (!A7800HawkControllerDeck.ValidControllerTypes.ContainsKey(value))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Invalid controller type: " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_port2 = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public A7800SyncSettings Clone()
|
||||||
|
{
|
||||||
|
return (A7800SyncSettings)MemberwiseClone();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool NeedsReboot(A7800SyncSettings x, A7800SyncSettings y)
|
||||||
|
{
|
||||||
|
return !DeepEquality.DeepEquals(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,6 +53,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
ser.Sync("Lag", ref _lagcount);
|
ser.Sync("Lag", ref _lagcount);
|
||||||
ser.Sync("Frame", ref _frame);
|
ser.Sync("Frame", ref _frame);
|
||||||
ser.Sync("IsLag", ref _islag);
|
ser.Sync("IsLag", ref _islag);
|
||||||
|
_controllerDeck.SyncState(ser);
|
||||||
|
|
||||||
ser.EndSection();
|
ser.EndSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
isPorted: false,
|
isPorted: false,
|
||||||
isReleased: true)]
|
isReleased: true)]
|
||||||
[ServiceNotApplicable(typeof(ISettable<,>), typeof(IDriveLight))]
|
[ServiceNotApplicable(typeof(ISettable<,>), typeof(IDriveLight))]
|
||||||
public partial class A7800Hawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable
|
public partial class A7800Hawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable,
|
||||||
|
ISettable<A7800Hawk.A7800Settings, A7800Hawk.A7800SyncSettings>
|
||||||
{
|
{
|
||||||
// this register selects between 2600 and 7800 mode in the A7800
|
// this register selects between 2600 and 7800 mode in the A7800
|
||||||
// however, we already have a 2600 emulator so this core will only be loading A7800 games
|
// however, we already have a 2600 emulator so this core will only be loading A7800 games
|
||||||
|
@ -25,14 +26,20 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
public byte[] Maria_regs = new byte[0x20];
|
public byte[] Maria_regs = new byte[0x20];
|
||||||
public byte[] RAM = new byte[0x1000];
|
public byte[] RAM = new byte[0x1000];
|
||||||
public byte[] regs_6532 = new byte[0x80];
|
public byte[] regs_6532 = new byte[0x80];
|
||||||
|
public byte[] hs_bios_mem = new byte[0x800];
|
||||||
|
|
||||||
private readonly byte[] _rom;
|
public readonly byte[] _rom;
|
||||||
private readonly byte[] _hsbios;
|
public readonly byte[] _hsbios;
|
||||||
private readonly byte[] _bios;
|
public readonly byte[] _bios;
|
||||||
private readonly byte[] _hsram = new byte[2048];
|
public readonly byte[] _hsram = new byte[2048];
|
||||||
|
|
||||||
private int _frame = 0;
|
private int _frame = 0;
|
||||||
|
|
||||||
|
public string s_mapper;
|
||||||
|
public MapperBase mapper;
|
||||||
|
|
||||||
|
private readonly ITraceable _tracer;
|
||||||
|
|
||||||
public MOS6502X cpu;
|
public MOS6502X cpu;
|
||||||
public Maria maria;
|
public Maria maria;
|
||||||
private bool _isPAL;
|
private bool _isPAL;
|
||||||
|
@ -45,10 +52,14 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
|
|
||||||
maria = new Maria();
|
maria = new Maria();
|
||||||
tia = new TIA();
|
tia = new TIA();
|
||||||
|
cpu = new MOS6502X
|
||||||
ser.Register<IVideoProvider>(maria);
|
{
|
||||||
ser.Register<ISoundProvider>(tia);
|
ReadMemory = ReadMemory,
|
||||||
ServiceProvider = ser;
|
WriteMemory = WriteMemory,
|
||||||
|
PeekMemory = ReadMemory,
|
||||||
|
DummyReadMemory = ReadMemory,
|
||||||
|
OnExecFetch = ExecFetch
|
||||||
|
};
|
||||||
|
|
||||||
maria = new Maria
|
maria = new Maria
|
||||||
{
|
{
|
||||||
|
@ -56,6 +67,9 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
};
|
};
|
||||||
|
|
||||||
CoreComm = comm;
|
CoreComm = comm;
|
||||||
|
|
||||||
|
_controllerDeck = new A7800HawkControllerDeck(_syncSettings.Port1, _syncSettings.Port2);
|
||||||
|
|
||||||
byte[] highscoreBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_HSC", false, "Some functions may not work without the high score BIOS.");
|
byte[] highscoreBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_HSC", false, "Some functions may not work without the high score BIOS.");
|
||||||
byte[] palBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_PAL", false, "The game will not run if the correct region BIOS is not available.");
|
byte[] palBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_PAL", false, "The game will not run if the correct region BIOS is not available.");
|
||||||
byte[] ntscBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_NTSC", false, "The game will not run if the correct region BIOS is not available.");
|
byte[] ntscBios = comm.CoreFileProvider.GetFirmware("A78", "Bios_NTSC", false, "The game will not run if the correct region BIOS is not available.");
|
||||||
|
@ -74,7 +88,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
// if none found default is zero
|
// if none found default is zero
|
||||||
// also check for PAL region
|
// also check for PAL region
|
||||||
string hash_md5 = null;
|
string hash_md5 = null;
|
||||||
string s_mapper = null;
|
s_mapper = null;
|
||||||
hash_md5 = "md5:" + rom.HashMD5(0, rom.Length);
|
hash_md5 = "md5:" + rom.HashMD5(0, rom.Length);
|
||||||
|
|
||||||
var gi = Database.CheckDatabase(hash_md5);
|
var gi = Database.CheckDatabase(hash_md5);
|
||||||
|
@ -82,22 +96,24 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
if (gi != null)
|
if (gi != null)
|
||||||
{
|
{
|
||||||
var dict = gi.GetOptionsDict();
|
var dict = gi.GetOptionsDict();
|
||||||
if (!dict.ContainsKey("PAL"))
|
if (dict.ContainsKey("PAL"))
|
||||||
{
|
{
|
||||||
_isPAL = true;
|
_isPAL = true;
|
||||||
}
|
}
|
||||||
if (!dict.ContainsKey("board"))
|
if (dict.ContainsKey("board"))
|
||||||
{
|
{
|
||||||
s_mapper = dict["board"];
|
s_mapper = dict["board"];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new Exception("No Board selected for this mapper");
|
throw new Exception("No Board selected for this game");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("ROM not in gamedb");
|
throw new Exception("ROM not in gamedb");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reset_Mapper(s_mapper);
|
||||||
|
|
||||||
_rom = rom;
|
_rom = rom;
|
||||||
_hsbios = highscoreBios;
|
_hsbios = highscoreBios;
|
||||||
_bios = _isPAL ? palBios : ntscBios;
|
_bios = _isPAL ? palBios : ntscBios;
|
||||||
|
@ -111,21 +127,31 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
if (_isPAL)
|
if (_isPAL)
|
||||||
{
|
{
|
||||||
maria._frameHz = 50;
|
maria._frameHz = 50;
|
||||||
|
maria._screen_width = 454;
|
||||||
|
maria._screen_height = 313;
|
||||||
maria._palette = PALPalette;
|
maria._palette = PALPalette;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
maria._frameHz = 60;
|
maria._frameHz = 60;
|
||||||
|
maria._screen_width = 454;
|
||||||
|
maria._screen_height = 263;
|
||||||
maria._palette = NTSCPalette;
|
maria._palette = NTSCPalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ser.Register<IVideoProvider>(maria);
|
||||||
|
ser.Register<ISoundProvider>(tia);
|
||||||
|
ServiceProvider = ser;
|
||||||
|
|
||||||
|
_tracer = new TraceBuffer { Header = cpu.TraceHeader };
|
||||||
|
ser.Register<ITraceable>(_tracer);
|
||||||
|
|
||||||
HardReset();
|
HardReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayType Region => _isPAL ? DisplayType.PAL : DisplayType.NTSC;
|
public DisplayType Region => _isPAL ? DisplayType.PAL : DisplayType.NTSC;
|
||||||
|
|
||||||
public A7800HawkControl ControlAdapter { get; private set; }
|
private readonly A7800HawkControllerDeck _controllerDeck;
|
||||||
|
|
||||||
private void HardReset()
|
private void HardReset()
|
||||||
{
|
{
|
||||||
|
@ -142,7 +168,24 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
Maria_regs = new byte[0x20];
|
Maria_regs = new byte[0x20];
|
||||||
RAM = new byte[0x1000];
|
RAM = new byte[0x1000];
|
||||||
regs_6532 = new byte[0x80];
|
regs_6532 = new byte[0x80];
|
||||||
}
|
|
||||||
|
cpu_cycle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecFetch(ushort addr)
|
||||||
|
{
|
||||||
|
//MemoryCallbacks.CallExecutes(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Reset_Mapper(string m)
|
||||||
|
{
|
||||||
|
if (m=="0")
|
||||||
|
{
|
||||||
|
mapper = new MapperDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper.Core = this;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MariaTables.cs
|
* MariaTables.cs
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using BizHawk.Common;
|
||||||
|
using BizHawk.Common.ReflectionExtensions;
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
|
{
|
||||||
|
public class A7800HawkControllerDeck
|
||||||
|
{
|
||||||
|
public A7800HawkControllerDeck(string controller1Name, string controller2Name)
|
||||||
|
{
|
||||||
|
if (!ValidControllerTypes.ContainsKey(controller1Name))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Invalid controller type: " + controller1Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ValidControllerTypes.ContainsKey(controller2Name))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Invalid controller type: " + controller2Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Port1 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller1Name], 1);
|
||||||
|
Port2 = (IPort)Activator.CreateInstance(ValidControllerTypes[controller2Name], 2);
|
||||||
|
|
||||||
|
Definition = new ControllerDefinition
|
||||||
|
{
|
||||||
|
Name = "A7800 Controller",
|
||||||
|
BoolButtons = Port1.Definition.BoolButtons
|
||||||
|
.Concat(Port2.Definition.BoolButtons)
|
||||||
|
.Concat(new[]
|
||||||
|
{
|
||||||
|
"Power",
|
||||||
|
"Reset",
|
||||||
|
"Select",
|
||||||
|
"BW", // should be "Color"??
|
||||||
|
"Left Difficulty", // better not put P# on these as they might not correspond to player numbers
|
||||||
|
"Right Difficulty"
|
||||||
|
})
|
||||||
|
.ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
Definition.FloatControls.AddRange(Port1.Definition.FloatControls);
|
||||||
|
Definition.FloatControls.AddRange(Port2.Definition.FloatControls);
|
||||||
|
|
||||||
|
Definition.FloatRanges.AddRange(Port1.Definition.FloatRanges);
|
||||||
|
Definition.FloatRanges.AddRange(Port2.Definition.FloatRanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte ReadPort1(IController c)
|
||||||
|
{
|
||||||
|
return Port1.Read(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte ReadPort2(IController c)
|
||||||
|
{
|
||||||
|
return Port2.Read(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControllerDefinition Definition { get; }
|
||||||
|
|
||||||
|
public void SyncState(Serializer ser)
|
||||||
|
{
|
||||||
|
ser.BeginSection("Port1");
|
||||||
|
Port1.SyncState(ser);
|
||||||
|
ser.EndSection();
|
||||||
|
|
||||||
|
ser.BeginSection("Port2");
|
||||||
|
Port2.SyncState(ser);
|
||||||
|
ser.EndSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly IPort Port1;
|
||||||
|
private readonly IPort Port2;
|
||||||
|
|
||||||
|
private static Dictionary<string, Type> _controllerTypes;
|
||||||
|
|
||||||
|
public static Dictionary<string, Type> ValidControllerTypes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_controllerTypes == null)
|
||||||
|
{
|
||||||
|
_controllerTypes = typeof(A7800HawkControllerDeck).Assembly
|
||||||
|
.GetTypes()
|
||||||
|
.Where(t => typeof(IPort).IsAssignableFrom(t))
|
||||||
|
.Where(t => !t.IsAbstract && !t.IsInterface)
|
||||||
|
.ToDictionary(tkey => tkey.DisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return _controllerTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string DefaultControllerName => typeof(StandardController).DisplayName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using BizHawk.Common;
|
||||||
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
|
namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a controller plugged into a controller port on the intellivision
|
||||||
|
/// </summary>
|
||||||
|
public interface IPort
|
||||||
|
{
|
||||||
|
byte Read(IController c);
|
||||||
|
|
||||||
|
ControllerDefinition Definition { get; }
|
||||||
|
|
||||||
|
void SyncState(Serializer ser);
|
||||||
|
|
||||||
|
int PortNum { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisplayName("Unplugged Controller")]
|
||||||
|
public class UnpluggedController : IPort
|
||||||
|
{
|
||||||
|
public UnpluggedController(int portNum)
|
||||||
|
{
|
||||||
|
PortNum = portNum;
|
||||||
|
Definition = new ControllerDefinition
|
||||||
|
{
|
||||||
|
BoolButtons = new List<string>()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte Read(IController c)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControllerDefinition Definition { get; }
|
||||||
|
|
||||||
|
public void SyncState(Serializer ser)
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
public int PortNum { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[DisplayName("Joystick Controller")]
|
||||||
|
public class StandardController : IPort
|
||||||
|
{
|
||||||
|
public StandardController(int portNum)
|
||||||
|
{
|
||||||
|
PortNum = portNum;
|
||||||
|
Definition = new ControllerDefinition
|
||||||
|
{
|
||||||
|
BoolButtons = BaseDefinition
|
||||||
|
.Select(b => "P" + PortNum + " " + b)
|
||||||
|
.ToList()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public int PortNum { get; }
|
||||||
|
|
||||||
|
public byte Read(IController c)
|
||||||
|
{
|
||||||
|
byte result = 0;
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
if (c.IsPressed(Definition.BoolButtons[i]))
|
||||||
|
{
|
||||||
|
result |= HandControllerButtons[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControllerDefinition Definition { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public void SyncState(Serializer ser)
|
||||||
|
{
|
||||||
|
// Nothing todo, I think
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly string[] BaseDefinition =
|
||||||
|
{
|
||||||
|
"U", "D", "L", "R", "Fire"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static byte[] HandControllerButtons =
|
||||||
|
{
|
||||||
|
0x60, // UP
|
||||||
|
0xC0, // Down
|
||||||
|
0xA0, // Left
|
||||||
|
0x48, // Right
|
||||||
|
0x81 // Fire
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,9 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
// Emulates the Atari 7800 Maria graphics chip
|
// Emulates the Atari 7800 Maria graphics chip
|
||||||
public class Maria : IVideoProvider
|
public class Maria : IVideoProvider
|
||||||
{
|
{
|
||||||
public int _frameHz;
|
public int _frameHz = 60;
|
||||||
|
public int _screen_width = 454;
|
||||||
|
public int _screen_height = 263;
|
||||||
|
|
||||||
public int[] _vidbuffer;
|
public int[] _vidbuffer;
|
||||||
public int[] _palette;
|
public int[] _palette;
|
||||||
|
@ -17,10 +19,10 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
return _vidbuffer;
|
return _vidbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int VirtualWidth => 275;
|
public int VirtualWidth => 454;
|
||||||
public int VirtualHeight => BufferHeight;
|
public int VirtualHeight => _screen_height;
|
||||||
public int BufferWidth { get; private set; }
|
public int BufferWidth => 454;
|
||||||
public int BufferHeight { get; private set; }
|
public int BufferHeight => _screen_height;
|
||||||
public int BackgroundColor => unchecked((int)0xff000000);
|
public int BackgroundColor => unchecked((int)0xff000000);
|
||||||
public int VsyncNumerator => _frameHz;
|
public int VsyncNumerator => _frameHz;
|
||||||
public int VsyncDenominator => 1;
|
public int VsyncDenominator => 1;
|
||||||
|
@ -28,11 +30,6 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
// the Maria chip can directly access memory
|
// the Maria chip can directly access memory
|
||||||
public Func<ushort, byte> ReadMemory;
|
public Func<ushort, byte> ReadMemory;
|
||||||
|
|
||||||
// there are 4 maria cycles in a CPU cycle (fast access, both NTSC and PAL)
|
|
||||||
// if the 6532 or TIA are accessed (PC goes to one of those addresses) the next access will be slower by 1/2 a CPU cycle
|
|
||||||
// i.e. it will take 6 Maria cycles instead of 4
|
|
||||||
public bool slow_access = false;
|
|
||||||
|
|
||||||
// each frame contains 263 scanlines
|
// each frame contains 263 scanlines
|
||||||
// each scanline consists of 113.5 CPU cycles (fast access) which equates to 454 Maria cycles
|
// each scanline consists of 113.5 CPU cycles (fast access) which equates to 454 Maria cycles
|
||||||
// In total there are 29850.5 CPU cycles (fast access) in a frame
|
// In total there are 29850.5 CPU cycles (fast access) in a frame
|
||||||
|
@ -43,7 +40,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
|
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
|
_vidbuffer = new int[VirtualWidth * VirtualHeight];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
}
|
}
|
||||||
else if (addr < 0x480)
|
else if (addr < 0x480)
|
||||||
{
|
{
|
||||||
return 0xFF; // cartridge space available
|
// cartridge space available
|
||||||
|
return mapper.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
else if (addr < 0x500)
|
else if (addr < 0x500)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +65,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
}
|
}
|
||||||
else if (addr < 0x1800)
|
else if (addr < 0x1800)
|
||||||
{
|
{
|
||||||
return 0xFF; // cartridge space available
|
// cartridge space available
|
||||||
|
return mapper.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
else if (addr < 0x2800)
|
else if (addr < 0x2800)
|
||||||
{
|
{
|
||||||
|
@ -72,11 +74,12 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
}
|
}
|
||||||
else if (addr < 0x4000)
|
else if (addr < 0x4000)
|
||||||
{
|
{
|
||||||
return RAM[addr - 0x2800 + 0x800];
|
// could be either RAM mirror or ROM
|
||||||
|
return mapper.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return 0xFF; // cartridge and other OPSYS
|
return mapper.ReadMemory(addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +128,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
else if (addr < 0x480)
|
else if (addr < 0x480)
|
||||||
{
|
{
|
||||||
// cartridge space available
|
// cartridge space available
|
||||||
|
mapper.WriteMemory(addr, value);
|
||||||
}
|
}
|
||||||
else if (addr < 0x500)
|
else if (addr < 0x500)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +138,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
else if (addr < 0x1800)
|
else if (addr < 0x1800)
|
||||||
{
|
{
|
||||||
// cartridge space available
|
// cartridge space available
|
||||||
|
mapper.WriteMemory(addr, value);
|
||||||
}
|
}
|
||||||
else if (addr < 0x2800)
|
else if (addr < 0x2800)
|
||||||
{
|
{
|
||||||
|
@ -141,13 +146,16 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
||||||
}
|
}
|
||||||
else if (addr < 0x4000)
|
else if (addr < 0x4000)
|
||||||
{
|
{
|
||||||
RAM[addr - 0x2800 + 0x800] = value;
|
// could be either RAM mirror or ROM
|
||||||
|
mapper.WriteMemory(addr, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// cartridge and other OPSYS
|
// cartridge and other OPSYS
|
||||||
|
mapper.WriteMemory(addr, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue