Coleco Turbo Controller
This commit is contained in:
parent
14a0d114b8
commit
39808f793d
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
public class ColecoVisionControllerDeck
|
||||
{
|
||||
public ColecoVisionControllerDeck(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 = "ColecoVision Basic Controller",
|
||||
BoolButtons = Port1.Definition.BoolButtons
|
||||
.Concat(Port2.Definition.BoolButtons)
|
||||
.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, bool left_mode)
|
||||
{
|
||||
return Port1.Read(c, left_mode);
|
||||
}
|
||||
|
||||
public byte ReadPort2(IController c, bool left_mode)
|
||||
{
|
||||
return Port2.Read(c, left_mode);
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition { get; private set; }
|
||||
|
||||
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 = null;
|
||||
|
||||
public static Dictionary<string, Type> ValidControllerTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_controllerTypes == null)
|
||||
{
|
||||
_controllerTypes = typeof(ColecoVisionControllerDeck).Assembly
|
||||
.GetTypes()
|
||||
.Where(t => typeof(IPort).IsAssignableFrom(t))
|
||||
.Where(t => !t.IsAbstract && !t.IsInterface)
|
||||
.ToDictionary(tkey => tkey.DisplayName());
|
||||
}
|
||||
|
||||
return _controllerTypes;
|
||||
}
|
||||
}
|
||||
|
||||
public static string DefaultControllerName
|
||||
{
|
||||
get { return typeof(StandardController).DisplayName(); }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.ReflectionExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a controller plugged into a controller port on the intellivision
|
||||
/// </summary>
|
||||
public interface IPort
|
||||
{
|
||||
byte Read(IController c, bool left_mode);
|
||||
|
||||
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, bool left_mode)
|
||||
{
|
||||
return 0; // needs checking
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition { get; private set; }
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public int PortNum { get; private set; }
|
||||
}
|
||||
|
||||
[DisplayName("ColecoVision Basic 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; private set; }
|
||||
|
||||
public byte Read(IController c, bool left_mode)
|
||||
{
|
||||
if (left_mode)
|
||||
{
|
||||
byte retval = 0x7F;
|
||||
if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0xFE;
|
||||
if (c.IsPressed(Definition.BoolButtons[1])) retval &= 0xFD;
|
||||
if (c.IsPressed(Definition.BoolButtons[2])) retval &= 0xFB;
|
||||
if (c.IsPressed(Definition.BoolButtons[3])) retval &= 0xF7;
|
||||
if (c.IsPressed(Definition.BoolButtons[4])) retval &= 0x3F;
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte retval = 0xF;
|
||||
// 0x00;
|
||||
if (c.IsPressed(Definition.BoolButtons[14])) retval = 0x01;
|
||||
if (c.IsPressed(Definition.BoolButtons[10])) retval = 0x02;
|
||||
if (c.IsPressed(Definition.BoolButtons[11])) retval = 0x03;
|
||||
// 0x04;
|
||||
if (c.IsPressed(Definition.BoolButtons[13])) retval = 0x05;
|
||||
if (c.IsPressed(Definition.BoolButtons[16])) retval = 0x06;
|
||||
if (c.IsPressed(Definition.BoolButtons[8])) retval = 0x07;
|
||||
// 0x08;
|
||||
if (c.IsPressed(Definition.BoolButtons[17])) retval = 0x09;
|
||||
if (c.IsPressed(Definition.BoolButtons[6])) retval = 0x0A;
|
||||
if (c.IsPressed(Definition.BoolButtons[15])) retval = 0x0B;
|
||||
if (c.IsPressed(Definition.BoolButtons[9])) retval = 0x0C;
|
||||
if (c.IsPressed(Definition.BoolButtons[7])) retval = 0x0D;
|
||||
if (c.IsPressed(Definition.BoolButtons[12])) retval = 0x0E;
|
||||
|
||||
if (c.IsPressed(Definition.BoolButtons[5]) == false) retval |= 0x40;
|
||||
retval |= 0x30; // always set these bits
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition { get; private set; }
|
||||
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
// Nothing todo, I think
|
||||
}
|
||||
|
||||
private static readonly string[] BaseDefinition =
|
||||
{
|
||||
"Up", "Right", "Down", "Left", "L", "R",
|
||||
"Key 0", "Key 1", "Key 2", "Key 3", "Key 4", "Key 5",
|
||||
"Key 6", "Key 7", "Key 8", "Key 9", "Pound", "Star"
|
||||
};
|
||||
}
|
||||
|
||||
[DisplayName("Turbo Controller")]
|
||||
public class ColecoTurboController : IPort
|
||||
{
|
||||
public ColecoTurboController(int portNum)
|
||||
{
|
||||
PortNum = portNum;
|
||||
Definition = new ControllerDefinition
|
||||
{
|
||||
BoolButtons = BaseBoolDefinition
|
||||
.Select(b => "P" + PortNum + " " + b)
|
||||
.ToList(),
|
||||
FloatControls = { "P" + PortNum + " Disc X", "P" + PortNum + " Disc Y" },
|
||||
FloatRanges = { new[] { -127.0f, 0, 127.0f }, new[] { -127.0f, 0, 127.0f } }
|
||||
};
|
||||
}
|
||||
|
||||
public int PortNum { get; private set; }
|
||||
|
||||
public ControllerDefinition Definition { get; private set; }
|
||||
|
||||
public byte Read(IController c, bool left_mode)
|
||||
{
|
||||
if (left_mode)
|
||||
{
|
||||
byte retval = 0x7B;
|
||||
|
||||
if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0x3F;
|
||||
/*
|
||||
if (c.IsPressed(Definition.BoolButtons[1])) retval &= 0xF7;
|
||||
if (c.IsPressed(Definition.BoolButtons[2])) retval &= 0xFB;
|
||||
if (c.IsPressed(Definition.BoolButtons[3])) retval &= 0xFD;
|
||||
if (c.IsPressed(Definition.BoolButtons[4])) retval &= 0xFE;
|
||||
if (c.IsPressed(Definition.BoolButtons[5])) retval &= 0x7F;
|
||||
if (c.IsPressed(Definition.BoolButtons[6])) retval &= 0xDF;
|
||||
if (c.IsPressed(Definition.BoolButtons[7])) retval &= 0xEF;
|
||||
*/
|
||||
int x = (int)c.GetFloat(Definition.FloatControls[0]);
|
||||
int y = (int)c.GetFloat(Definition.FloatControls[1]);
|
||||
retval &= CalcDirection(x, y);
|
||||
|
||||
//Console.WriteLine(retval);
|
||||
return retval;
|
||||
} else
|
||||
{
|
||||
byte retval = 0x7B;
|
||||
if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0x3F;
|
||||
/*
|
||||
if (c.IsPressed(Definition.BoolButtons[1])) retval &= 0xF7;
|
||||
if (c.IsPressed(Definition.BoolButtons[2])) retval &= 0xFB;
|
||||
if (c.IsPressed(Definition.BoolButtons[3])) retval &= 0xFD;
|
||||
if (c.IsPressed(Definition.BoolButtons[4])) retval &= 0xFE;
|
||||
if (c.IsPressed(Definition.BoolButtons[5])) retval &= 0x7F;
|
||||
if (c.IsPressed(Definition.BoolButtons[6])) retval &= 0xDF;
|
||||
if (c.IsPressed(Definition.BoolButtons[7])) retval &= 0xEF;
|
||||
*/
|
||||
int x = (int)c.GetFloat(Definition.FloatControls[0]);
|
||||
int y = (int)c.GetFloat(Definition.FloatControls[1]);
|
||||
retval &= CalcDirection(x, y);
|
||||
|
||||
//Console.WriteLine(retval);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
// Nothing todo, I think
|
||||
}
|
||||
|
||||
private static readonly string[] BaseBoolDefinition =
|
||||
{
|
||||
"Pedal", "T1", "T2", "T3", "T4", "T5", "T6", "T7"
|
||||
};
|
||||
|
||||
// x and y are both assumed to be in [-127, 127]
|
||||
// x increases from left to right
|
||||
// y increases from top to bottom
|
||||
private static byte CalcDirection(int x, int y)
|
||||
{
|
||||
y = -y; // vflip to match the arrangement of FloatControllerButtons
|
||||
|
||||
// deadzone: if we're less than ? units from the origin, return no direction
|
||||
if (x * x + y * y < Deadzone * Deadzone)
|
||||
{
|
||||
return 0x7F; // nothing pressed
|
||||
}
|
||||
|
||||
double t = Math.Atan2(y, x) * 8.0 / Math.PI;
|
||||
int i = (int)Math.Round(t);
|
||||
return FloatControllerButtons[i & 15];
|
||||
}
|
||||
|
||||
private const int Deadzone = 50;
|
||||
|
||||
private static byte[] FloatControllerButtons = new byte[]
|
||||
{
|
||||
0x6F, // E
|
||||
0x4F, // ENE
|
||||
0x4F, // NE
|
||||
0x4F, // NNE
|
||||
|
||||
0x4F, // N
|
||||
0x5F, // NNW
|
||||
0x5F, // NW
|
||||
0x5F, // WNW
|
||||
|
||||
0x5F, // W
|
||||
0x7F, // WSW
|
||||
0x7F, // SW
|
||||
0x7F, // SSW
|
||||
|
||||
0x7F, // S
|
||||
0x6F, // SSE
|
||||
0x6F, // SE
|
||||
0x6F, // ESE
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
public partial class ColecoVision : ISettable<object, ColecoVision.ColecoSyncSettings>
|
||||
public partial class ColecoVision : IEmulator, IStatable, ISettable<ColecoVision.ColecoSettings, ColecoVision.ColecoSyncSettings>
|
||||
{
|
||||
public object GetSettings()
|
||||
public ColecoSettings GetSettings()
|
||||
{
|
||||
return null;
|
||||
return Settings.Clone();
|
||||
}
|
||||
|
||||
public ColecoSyncSettings GetSyncSettings()
|
||||
|
@ -14,28 +18,77 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
return _syncSettings.Clone();
|
||||
}
|
||||
|
||||
public bool PutSettings(object o)
|
||||
public bool PutSettings(ColecoSettings o)
|
||||
{
|
||||
Settings = o;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool PutSyncSettings(ColecoSyncSettings o)
|
||||
{
|
||||
bool ret = o.SkipBiosIntro != _syncSettings.SkipBiosIntro;
|
||||
ret |= ColecoSyncSettings.NeedsReboot(_syncSettings, o);
|
||||
_syncSettings = o;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private ColecoSyncSettings _syncSettings;
|
||||
public class ColecoSettings
|
||||
{
|
||||
public ColecoSettings Clone()
|
||||
{
|
||||
return (ColecoSettings)MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
||||
public ColecoSettings Settings = new ColecoSettings();
|
||||
public ColecoSyncSettings _syncSettings = new ColecoSyncSettings();
|
||||
|
||||
public class ColecoSyncSettings
|
||||
{
|
||||
public bool SkipBiosIntro { get; set; }
|
||||
|
||||
private string _port1 = ColecoVisionControllerDeck.DefaultControllerName;
|
||||
private string _port2 = ColecoVisionControllerDeck.DefaultControllerName;
|
||||
|
||||
[JsonIgnore]
|
||||
public string Port1
|
||||
{
|
||||
get { return _port1; }
|
||||
set
|
||||
{
|
||||
if (!ColecoVisionControllerDeck.ValidControllerTypes.ContainsKey(value))
|
||||
{
|
||||
throw new InvalidOperationException("Invalid controller type: " + value);
|
||||
}
|
||||
|
||||
_port1 = value;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public string Port2
|
||||
{
|
||||
get { return _port2; }
|
||||
set
|
||||
{
|
||||
if (!ColecoVisionControllerDeck.ValidControllerTypes.ContainsKey(value))
|
||||
{
|
||||
throw new InvalidOperationException("Invalid controller type: " + value);
|
||||
}
|
||||
|
||||
_port2 = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ColecoSyncSettings Clone()
|
||||
{
|
||||
return (ColecoSyncSettings)MemberwiseClone();
|
||||
}
|
||||
|
||||
public static bool NeedsReboot(ColecoSyncSettings x, ColecoSyncSettings y)
|
||||
{
|
||||
return !DeepEquality.DeepEquals(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components;
|
||||
using BizHawk.Emulation.Cores.Components.Z80;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
|
@ -11,7 +12,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
isReleased: true
|
||||
)]
|
||||
[ServiceNotApplicable(typeof(ISaveRam), typeof(IDriveLight))]
|
||||
public sealed partial class ColecoVision : IEmulator, IDebuggable, IInputPollable, IStatable, ISettable<object, ColecoVision.ColecoSyncSettings>
|
||||
public sealed partial class ColecoVision : IEmulator, IDebuggable, IInputPollable, IStatable, ISettable<ColecoVision.ColecoSettings, ColecoVision.ColecoSyncSettings>
|
||||
{
|
||||
// ROM
|
||||
public byte[] RomData;
|
||||
|
@ -21,7 +22,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
// Machine
|
||||
public Z80A Cpu;
|
||||
public TMS9918A VDP;
|
||||
|
||||
|
||||
public byte[] Ram = new byte[1024];
|
||||
private readonly TraceBuffer Tracer = new TraceBuffer();
|
||||
|
||||
|
@ -41,12 +42,15 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
Cpu.WriteHardware = WritePort;
|
||||
Cpu.MemoryCallbacks = MemoryCallbacks;
|
||||
|
||||
VDP = new TMS9918A(Cpu);
|
||||
(ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(VDP);
|
||||
PSG = new SN76489();
|
||||
_fakeSyncSound = new FakeSyncSound(PSG, 735);
|
||||
(ServiceProvider as BasicServiceProvider).Register<ISoundProvider>(_fakeSyncSound);
|
||||
|
||||
ControllerDeck = new ColecoVisionControllerDeck(this._syncSettings.Port1, this._syncSettings.Port2);
|
||||
|
||||
VDP = new TMS9918A(Cpu, ControllerDeck);
|
||||
(ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(VDP);
|
||||
|
||||
// TODO: hack to allow bios-less operation would be nice, no idea if its feasible
|
||||
BiosRom = CoreComm.CoreFileProvider.GetFirmware("Coleco", "Bios", true, "Coleco BIOS file is required.");
|
||||
|
||||
|
@ -61,10 +65,19 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
var serviceProvider = ServiceProvider as BasicServiceProvider;
|
||||
serviceProvider.Register<IDisassemblable>(new Disassembler());
|
||||
serviceProvider.Register<ITraceable>(Tracer);
|
||||
|
||||
VDP.Controller = Controller;
|
||||
}
|
||||
|
||||
public IEmulatorServiceProvider ServiceProvider { get; private set; }
|
||||
|
||||
public ControllerDefinition ControllerDefinition
|
||||
{
|
||||
get { return ControllerDeck.Definition; }
|
||||
}
|
||||
public ColecoVisionControllerDeck ControllerDeck { get; private set; }
|
||||
public IController Controller { get; set; }
|
||||
|
||||
const ushort RamSizeMask = 0x03FF;
|
||||
|
||||
public void FrameAdvance(bool render, bool renderSound)
|
||||
|
@ -78,7 +91,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
{
|
||||
Cpu.Logger = (s) => Tracer.Put(s);
|
||||
}
|
||||
|
||||
VDP.Controller = Controller;
|
||||
VDP.ExecuteFrame();
|
||||
PSG.EndFrame(Cpu.TotalExecutedCycles);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
{
|
||||
public partial class ColecoVision
|
||||
{
|
||||
public static readonly ControllerDefinition ColecoVisionControllerDefinition = new ControllerDefinition
|
||||
/* public static readonly ControllerDefinition ColecoVisionControllerDefinition = new ControllerDefinition
|
||||
{
|
||||
Name = "ColecoVision Basic Controller",
|
||||
BoolButtons =
|
||||
|
@ -21,53 +21,25 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
"P2 Key 6", "P2 Key 7", "P2 Key 8", "P2 Key 9", "P2 Star", "P2 Pound"
|
||||
}
|
||||
};
|
||||
|
||||
public ControllerDefinition ControllerDefinition { get { return ColecoVisionControllerDefinition; } }
|
||||
public IController Controller { get; set; }
|
||||
|
||||
enum InputPortMode { Left, Right }
|
||||
*/
|
||||
public enum InputPortMode { Left, Right }
|
||||
InputPortMode InputPortSelection;
|
||||
|
||||
byte ReadController1()
|
||||
{
|
||||
_isLag = false;
|
||||
|
||||
byte retval;
|
||||
if (InputPortSelection == InputPortMode.Left)
|
||||
{
|
||||
byte retval = 0x7F;
|
||||
if (Controller.IsPressed("P1 Up")) retval &= 0xFE;
|
||||
if (Controller.IsPressed("P1 Right")) retval &= 0xFD;
|
||||
if (Controller.IsPressed("P1 Down")) retval &= 0xFB;
|
||||
if (Controller.IsPressed("P1 Left")) retval &= 0xF7;
|
||||
if (Controller.IsPressed("P1 L")) retval &= 0x3F;
|
||||
retval = ControllerDeck.ReadPort1(Controller, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (InputPortSelection == InputPortMode.Right)
|
||||
{
|
||||
byte retval = 0xF;
|
||||
// 0x00;
|
||||
if (Controller.IsPressed("P1 Key 8")) retval = 0x01;
|
||||
if (Controller.IsPressed("P1 Key 4")) retval = 0x02;
|
||||
if (Controller.IsPressed("P1 Key 5")) retval = 0x03;
|
||||
// 0x04;
|
||||
if (Controller.IsPressed("P1 Key 7")) retval = 0x05;
|
||||
if (Controller.IsPressed("P1 Pound")) retval = 0x06;
|
||||
if (Controller.IsPressed("P1 Key 2")) retval = 0x07;
|
||||
// 0x08;
|
||||
if (Controller.IsPressed("P1 Star")) retval = 0x09;
|
||||
if (Controller.IsPressed("P1 Key 0")) retval = 0x0A;
|
||||
if (Controller.IsPressed("P1 Key 9")) retval = 0x0B;
|
||||
if (Controller.IsPressed("P1 Key 3")) retval = 0x0C;
|
||||
if (Controller.IsPressed("P1 Key 1")) retval = 0x0D;
|
||||
if (Controller.IsPressed("P1 Key 6")) retval = 0x0E;
|
||||
|
||||
if (Controller.IsPressed("P1 R") == false) retval |= 0x40;
|
||||
retval |= 0x30; // always set these bits
|
||||
retval = ControllerDeck.ReadPort1(Controller, false);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
return 0x7F;
|
||||
}
|
||||
|
||||
|
@ -75,42 +47,18 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
byte ReadController2()
|
||||
{
|
||||
_isLag = false;
|
||||
|
||||
byte retval;
|
||||
if (InputPortSelection == InputPortMode.Left)
|
||||
{
|
||||
byte retval = 0x7F;
|
||||
if (Controller.IsPressed("P2 Up")) retval &= 0xFE;
|
||||
if (Controller.IsPressed("P2 Right")) retval &= 0xFD;
|
||||
if (Controller.IsPressed("P2 Down")) retval &= 0xFB;
|
||||
if (Controller.IsPressed("P2 Left")) retval &= 0xF7;
|
||||
if (Controller.IsPressed("P2 L")) retval &= 0x3F;
|
||||
retval = ControllerDeck.ReadPort2(Controller, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (InputPortSelection == InputPortMode.Right)
|
||||
{
|
||||
byte retval = 0xF;
|
||||
// 0x00;
|
||||
if (Controller.IsPressed("P2 Key 8")) retval = 0x01;
|
||||
if (Controller.IsPressed("P2 Key 4")) retval = 0x02;
|
||||
if (Controller.IsPressed("P2 Key 5")) retval = 0x03;
|
||||
// 0x04;
|
||||
if (Controller.IsPressed("P2 Key 7")) retval = 0x05;
|
||||
if (Controller.IsPressed("P2 Pound")) retval = 0x06;
|
||||
if (Controller.IsPressed("P2 Key 2")) retval = 0x07;
|
||||
// 0x08;
|
||||
if (Controller.IsPressed("P2 Star")) retval = 0x09;
|
||||
if (Controller.IsPressed("P2 Key 0")) retval = 0x0A;
|
||||
if (Controller.IsPressed("P2 Key 9")) retval = 0x0B;
|
||||
if (Controller.IsPressed("P2 Key 3")) retval = 0x0C;
|
||||
if (Controller.IsPressed("P2 Key 1")) retval = 0x0D;
|
||||
if (Controller.IsPressed("P2 Key 6")) retval = 0x0E;
|
||||
|
||||
if (Controller.IsPressed("P2 R") == false) retval |= 0x40;
|
||||
retval |= 0x30; // always set these bits
|
||||
retval = ControllerDeck.ReadPort2(Controller, false);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0x7F;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.IO;
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components.Z80;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
|
@ -20,6 +21,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
byte VdpBuffer;
|
||||
int TmsMode;
|
||||
|
||||
// interrupt control for quadrature reads
|
||||
bool spin_on1, spin_on2;
|
||||
|
||||
bool Mode1Bit { get { return (Registers[1] & 16) > 0; } }
|
||||
bool Mode2Bit { get { return (Registers[0] & 2) > 0; } }
|
||||
bool Mode3Bit { get { return (Registers[1] & 8) > 0; } }
|
||||
|
@ -50,12 +54,35 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
if (scanLine == 192)
|
||||
{
|
||||
|
||||
InterruptPending = true;
|
||||
|
||||
if (EnableInterrupts)
|
||||
Cpu.NonMaskableInterrupt = true;
|
||||
}
|
||||
|
||||
Cpu.ExecuteCycles(228);
|
||||
|
||||
byte temp_ret1 = Deck.ReadPort1(Controller, true);
|
||||
byte temp_ret2 = Deck.ReadPort2(Controller, true);
|
||||
|
||||
if (((temp_ret1.Bit(4) && !spin_on1) | ( temp_ret2.Bit(4) && !spin_on2)) && scanLine == 50)
|
||||
{
|
||||
|
||||
if (EnableInterrupts)
|
||||
Cpu.NonMaskableInterrupt = true;
|
||||
|
||||
if (temp_ret1.Bit(4) && !spin_on1)
|
||||
spin_on1 = true;
|
||||
|
||||
if (temp_ret2.Bit(4) && !spin_on2)
|
||||
spin_on2 = true;
|
||||
}
|
||||
if (!temp_ret1.Bit(4))
|
||||
spin_on1 = false;
|
||||
if (!temp_ret2.Bit(4))
|
||||
spin_on2 = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,9 +464,13 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
}
|
||||
|
||||
Z80A Cpu;
|
||||
public TMS9918A(Z80A cpu)
|
||||
ColecoVisionControllerDeck Deck;
|
||||
public IController Controller;
|
||||
|
||||
public TMS9918A(Z80A cpu, ColecoVisionControllerDeck deck)
|
||||
{
|
||||
this.Cpu = cpu;
|
||||
this.Deck = deck;
|
||||
}
|
||||
|
||||
public int[] FrameBuffer = new int[256 * 192];
|
||||
|
|
Loading…
Reference in New Issue