misc. cleanup for Coleco and Intellivision

This commit is contained in:
adelikat 2017-04-24 12:24:56 -05:00
parent 4c71a34dfa
commit 7f663a0ed6
19 changed files with 349 additions and 266 deletions

View File

@ -97,20 +97,20 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
CoreComm.VsyncNum = 16000000; // 16.00 mhz refclock
CoreComm.VsyncDen = 16 * 105 * 159;
savebuff = new byte[LibLynx.BinStateSize(Core)];
savebuff2 = new byte[savebuff.Length + 13];
_savebuff = new byte[LibLynx.BinStateSize(Core)];
_savebuff2 = new byte[_savebuff.Length + 13];
int rot = game.OptionPresent("rotate") ? int.Parse(game.OptionValue("rotate")) : 0;
LibLynx.SetRotation(Core, rot);
if ((rot & 1) != 0)
{
BufferWidth = HEIGHT;
BufferHeight = WIDTH;
BufferWidth = Height;
BufferHeight = Width;
}
else
{
BufferWidth = WIDTH;
BufferHeight = HEIGHT;
BufferWidth = Width;
BufferHeight = Height;
}
SetupMemoryDomains();
}
@ -131,9 +131,9 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
LibLynx.Reset(Core);
}
int samples = soundbuff.Length;
IsLagFrame = LibLynx.Advance(Core, GetButtons(), videobuff, soundbuff, ref samples);
numsamp = samples / 2; // sound provider wants number of sample pairs
int samples = _soundbuff.Length;
IsLagFrame = LibLynx.Advance(Core, GetButtons(), _videobuff, _soundbuff, ref samples);
_numsamp = samples / 2; // sound provider wants number of sample pairs
if (IsLagFrame)
{
LagCount++;

View File

@ -46,18 +46,24 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public byte ReadPort1(IController c, bool left_mode, bool update_wheel)
{
if (update_wheel)
{
wheel1 = Port1.Update_Wheel(c, wheel1);
}
return Port1.Read(c, left_mode, wheel1);
}
public byte ReadPort2(IController c, bool left_mode, bool update_wheel)
{
if (update_wheel)
{
wheel2 = Port2.Update_Wheel(c, wheel2);
}
return Port2.Read(c, left_mode, wheel2);
}
public ControllerDefinition Definition { get; private set; }
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
{
@ -94,10 +100,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}
}
public static string DefaultControllerName
{
get { return typeof(StandardController).DisplayName(); }
}
public static string DefaultControllerName => typeof(StandardController).DisplayName();
}
}

View File

@ -9,7 +9,7 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.ColecoVision
{
/// <summary>
/// Represents a controller plugged into a controller port on the intellivision
/// Represents a controller plugged into a controller port on the Colecovision
/// </summary>
public interface IPort
{
@ -41,14 +41,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
return 0; // needs checking
}
public ControllerDefinition Definition { get; private set; }
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
{
// Do nothing
}
public int PortNum { get; private set; }
public int PortNum { get; }
public int Update_Wheel(IController c, int wheel)
{
@ -70,11 +70,11 @@ namespace BizHawk.Emulation.Cores.ColecoVision
};
}
public int PortNum { get; private set; }
public int PortNum { get; }
public byte Read(IController c, bool left_mode, int wheel)
public byte Read(IController c, bool leftMode, int wheel)
{
if (left_mode)
if (leftMode)
{
byte retval = 0x7F;
if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0xFE;
@ -109,7 +109,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}
}
public ControllerDefinition Definition { get; private set; }
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
@ -146,13 +146,13 @@ namespace BizHawk.Emulation.Cores.ColecoVision
};
}
public int PortNum { get; private set; }
public int PortNum { get; }
public ControllerDefinition Definition { get; private set; }
public ControllerDefinition Definition { get; }
public byte Read(IController c, bool left_mode, int wheel)
public byte Read(IController c, bool leftMode, int wheel)
{
if (left_mode)
if (leftMode)
{
byte retval = 0x4B;
@ -163,7 +163,8 @@ namespace BizHawk.Emulation.Cores.ColecoVision
retval |= CalcDirection(x, y);
return retval;
} else
}
else
{
byte retval = 0x4B;
if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0x3F;
@ -194,20 +195,28 @@ namespace BizHawk.Emulation.Cores.ColecoVision
y = -y; // vflip to match the arrangement of FloatControllerButtons
if (y >= 0 && x > 0)
{
return 0x10;
}
if (y >= 0 && x <= 0)
{
return 0x30;
}
if (y < 0 && x <= 0)
{
return 0x20;
}
if (y < 0 && x > 0)
{
return 0x00;
}
Console.WriteLine("Error");
return 0x1F;
}
//private const int Deadzone = 50;
public int Update_Wheel(IController c, int wheel)
{
return 0;
@ -230,8 +239,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
};
}
public int wheel_state { get; set; }
public int PortNum { get; private set; }
public ControllerDefinition Definition { get; private set; }
@ -299,19 +306,28 @@ namespace BizHawk.Emulation.Cores.ColecoVision
byte retval = 0;
if (wheel >= 0 && wheel < 180)
{
retval = 0x00;
}
if (wheel >= 180 && wheel < 360)
{
retval = 0x10;
if (wheel <0 && wheel > -180)
}
if (wheel < 0 && wheel > -180)
{
retval = 0x20;
if (wheel <= -180 && wheel >-360)
}
if (wheel <= -180 && wheel > -360)
{
retval = 0x30;
}
return retval;
}
//private const int Deadzone = 50;
public int Update_Wheel(IController c, int wheel)
{
int x = (int)c.GetFloat(Definition.FloatControls[0]);
@ -321,10 +337,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
wheel += diff;
if (wheel >= 360)
{
wheel = wheel - 360;
}
if (wheel <= -360)
{
wheel = wheel + 360;
}
return wheel;
}

View File

@ -5,6 +5,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public partial class ColecoVision
{
private SN76489 PSG;
private FakeSyncSound _fakeSyncSound;
private readonly FakeSyncSound _fakeSyncSound;
}
}

View File

@ -9,8 +9,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
"ColecoHawk",
"Vecna",
isPorted: false,
isReleased: true
)]
isReleased: true)]
[ServiceNotApplicable(typeof(ISaveRam), typeof(IDriveLight))]
public sealed partial class ColecoVision : IEmulator, IDebuggable, IInputPollable, IStatable, ISettable<ColecoVision.ColecoSettings, ColecoVision.ColecoSyncSettings>
{
@ -23,7 +22,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
private Z80A Cpu;
private TMS9918A VDP;
public byte[] Ram = new byte[1024];
private byte[] Ram = new byte[1024];
private readonly TraceBuffer Tracer = new TraceBuffer();
[CoreConstructor("Coleco")]
@ -74,12 +73,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition
{
get { return ControllerDeck.Definition; }
}
public ControllerDefinition ControllerDefinition => ControllerDeck.Definition;
public ColecoVisionControllerDeck ControllerDeck { get; }
private readonly ColecoVisionControllerDeck ControllerDeck;
public IController Controller { get; set; }
@ -97,12 +93,12 @@ namespace BizHawk.Emulation.Cores.ColecoVision
Cpu.Logger = (s) => Tracer.Put(s);
}
byte temp_ret1 = ControllerDeck.ReadPort1(Controller, true, true);
byte temp_ret2 = ControllerDeck.ReadPort2(Controller, true, true);
byte tempRet1 = ControllerDeck.ReadPort1(Controller, true, true);
byte tempRet2 = ControllerDeck.ReadPort2(Controller, true, true);
bool Int_pending = (!temp_ret1.Bit(4)) | (!temp_ret2.Bit(4));
bool intPending = (!tempRet1.Bit(4)) | (!tempRet2.Bit(4));
VDP.ExecuteFrame(Int_pending);
VDP.ExecuteFrame(intPending);
PSG.EndFrame(Cpu.TotalExecutedCycles);
@ -116,7 +112,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
{
RomData = new byte[0x8000];
for (int i = 0; i < 0x8000; i++)
{
RomData[i] = rom[i % rom.Length];
}
// hack to skip colecovision title screen
if (skipbios)
@ -160,9 +158,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
if (port >= 0xA0 && port <= 0xBF)
{
if ((port & 1) == 0)
{
VDP.WriteVdpData(value);
}
else
{
VDP.WriteVdpControl(value);
}
return;
}
@ -187,7 +190,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public bool DeterministicEmulation => true;
public void Dispose() { }
public void Dispose()
{
}
public void ResetCounters()
{

View File

@ -2,25 +2,8 @@
{
public partial class ColecoVision
{
/* public static readonly ControllerDefinition ColecoVisionControllerDefinition = new ControllerDefinition
{
Name = "ColecoVision Basic Controller",
BoolButtons =
{
"P1 Up", "P1 Down", "P1 Left", "P1 Right",
"P1 L", "P1 R",
"P1 Key 0", "P1 Key 1", "P1 Key 2", "P1 Key 3", "P1 Key 4", "P1 Key 5",
"P1 Key 6", "P1 Key 7", "P1 Key 8", "P1 Key 9", "P1 Star", "P1 Pound",
"P2 Up", "P2 Down", "P2 Left", "P2 Right",
"P2 L", "P2 R",
"P2 Key 0", "P2 Key 1", "P2 Key 2", "P2 Key 3", "P2 Key 4", "P2 Key 5",
"P2 Key 6", "P2 Key 7", "P2 Key 8", "P2 Key 9", "P2 Star", "P2 Pound"
}
};
*/
public enum InputPortMode { Left, Right }
InputPortMode InputPortSelection;
private InputPortMode InputPortSelection;
private byte ReadController1()
{
@ -58,7 +41,12 @@
return 0x7F;
}
public int Frame { get { return frame; } set { frame = value; } }
public int Frame
{
get { return frame; }
private set { frame = value; }
}
private int frame;
}
}

View File

@ -5,11 +5,19 @@
public byte ReadMemory(ushort addr)
{
if (addr >= 0x8000)
{
return RomData[addr & 0x7FFF];
}
if (addr >= 0x6000)
{
return Ram[addr & 1023];
}
if (addr < 0x2000)
{
return BiosRom[addr];
}
//Console.WriteLine("Unhandled read at {0:X4}", addr);
return 0xFF;

View File

@ -1,5 +1,4 @@
using System;
using System.Globalization;
using BizHawk.Common;
using BizHawk.Emulation.Common;
@ -10,36 +9,35 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public sealed class TMS9918A : IVideoProvider
{
public byte[] VRAM = new byte[0x4000];
byte[] Registers = new byte[8];
byte StatusByte;
private byte[] Registers = new byte[8];
private byte StatusByte;
bool VdpWaitingForLatchByte = true;
byte VdpLatch;
ushort VdpAddress;
byte VdpBuffer;
int TmsMode;
private bool VdpWaitingForLatchByte = true;
private byte VdpLatch;
private ushort VdpAddress;
private byte VdpBuffer;
private int TmsMode;
bool Mode1Bit { get { return (Registers[1] & 16) > 0; } }
bool Mode2Bit { get { return (Registers[0] & 2) > 0; } }
bool Mode3Bit { get { return (Registers[1] & 8) > 0; } }
private bool Mode1Bit => (Registers[1] & 16) > 0;
private bool Mode2Bit => (Registers[0] & 2) > 0;
private bool Mode3Bit => (Registers[1] & 8) > 0;
private bool EnableDoubledSprites => (Registers[1] & 1) > 0;
private bool EnableLargeSprites => (Registers[1] & 2) > 0;
private bool EnableInterrupts => (Registers[1] & 32) > 0;
private bool DisplayOn => (Registers[1] & 64) > 0;
private bool Mode16k => (Registers[1] & 128) > 0;
bool EnableDoubledSprites { get { return (Registers[1] & 1) > 0; } }
bool EnableLargeSprites { get { return (Registers[1] & 2) > 0; } }
bool EnableInterrupts { get { return (Registers[1] & 32) > 0; } }
bool DisplayOn { get { return (Registers[1] & 64) > 0; } }
bool Mode16k { get { return (Registers[1] & 128) > 0; } }
bool InterruptPending
private bool InterruptPending
{
get { return (StatusByte & 0x80) != 0; }
set { StatusByte = (byte)((StatusByte & ~0x02) | (value ? 0x80 : 0x00)); }
}
int ColorTableBase;
int PatternGeneratorBase;
int SpritePatternGeneratorBase;
int TmsPatternNameTableBase;
int TmsSpriteAttributeBase;
private int ColorTableBase;
private int PatternGeneratorBase;
private int SpritePatternGeneratorBase;
private int TmsPatternNameTableBase;
private int TmsSpriteAttributeBase;
public void ExecuteFrame(bool Int_pending)
{
@ -58,7 +56,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
Cpu.ExecuteCycles(228);
Cpu.Interrupt = false;
if (Int_pending && scanLine==50)
{
@ -68,7 +65,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
Int_pending = false;
}
}
}
}
@ -165,7 +161,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
return value;
}
void CheckVideoMode()
private void CheckVideoMode()
{
if (Mode1Bit) TmsMode = 1;
else if (Mode2Bit) TmsMode = 2;
@ -176,7 +172,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
throw new Exception("TMS video mode 1! please tell vecna which game uses this!");
}
void RenderScanline(int scanLine)
private void RenderScanline(int scanLine)
{
if (scanLine >= 192)
return;
@ -199,7 +195,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
// This may seem silly but if I ever implement mode 1, sprites are not rendered in that.
}
void RenderBackgroundM0(int scanLine)
private void RenderBackgroundM0(int scanLine)
{
if (DisplayOn == false)
{
@ -271,7 +267,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}
}
void RenderBackgroundM3(int scanLine)
private void RenderBackgroundM3(int scanLine)
{
if (DisplayOn == false)
{
@ -306,18 +302,22 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}
}
byte[] ScanlinePriorityBuffer = new byte[256];
byte[] SpriteCollisionBuffer = new byte[256];
private readonly byte[] ScanlinePriorityBuffer = new byte[256];
private readonly byte[] SpriteCollisionBuffer = new byte[256];
void RenderTmsSprites(int scanLine)
private void RenderTmsSprites(int scanLine)
{
if (EnableDoubledSprites == false)
{
RenderTmsSpritesStandard(scanLine);
}
else
{
RenderTmsSpritesDouble(scanLine);
}
}
void RenderTmsSpritesStandard(int scanLine)
private void RenderTmsSpritesStandard(int scanLine)
{
if (DisplayOn == false) return;
@ -384,7 +384,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}
}
void RenderTmsSpritesDouble(int scanLine)
private void RenderTmsSpritesDouble(int scanLine)
{
if (DisplayOn == false) return;
@ -449,23 +449,23 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}
}
Z80A Cpu;
private readonly Z80A Cpu;
public TMS9918A(Z80A cpu)
{
this.Cpu = cpu;
Cpu = cpu;
}
public int[] FrameBuffer = new int[256 * 192];
public readonly int[] FrameBuffer = new int[256 * 192];
public int[] GetVideoBuffer() { return FrameBuffer; }
public int VirtualWidth { get { return 293; } }
public int VirtualHeight { get { return 192; } }
public int BufferWidth { get { return 256; } }
public int BufferHeight { get { return 192; } }
public int BackgroundColor { get { return 0; } }
public int VirtualWidth => 293;
public int VirtualHeight => 192;
public int BufferWidth => 256;
public int BufferHeight => 192;
public int BackgroundColor => 0;
int[] PaletteTMS9918 = new int[]
private readonly int[] PaletteTMS9918 =
{
unchecked((int)0xFF000000),
unchecked((int)0xFF000000),
@ -498,8 +498,12 @@ namespace BizHawk.Emulation.Cores.ColecoVision
ser.EndSection();
if (ser.IsReader)
{
for (int i = 0; i < Registers.Length; i++)
{
WriteRegister(i, Registers[i]);
}
}
}
}
}

View File

@ -8,48 +8,51 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
public sealed class Cartridge : ICart
{
private ushort[] Data = new ushort[56320];
private readonly ushort[] Data = new ushort[56320];
private ushort[] Cart_Ram = new ushort[0x800];
// There are 10 mappers Intellivision games use (not counting intellicart which is handled seperately)
// we will pick the mapper from the game DB and default to 0
private int mapper = 0;
private int _mapper = 0;
public string BoardName => $"Mapper {mapper}";
public string BoardName => $"Mapper {_mapper}";
public void SyncState(Serializer ser)
{
ser.BeginSection("Cart");
ser.Sync("mapper", ref mapper);
ser.Sync("mapper", ref _mapper);
ser.Sync("Cart_Ram", ref Cart_Ram, false);
ser.EndSection();
}
public int Parse(byte[] Rom)
public int Parse(byte[] rom)
{
// Combine every two bytes into a word.
int index = 0;
while (index + 1 < Rom.Length)
while (index + 1 < rom.Length)
{
Data[(index / 2)] = (ushort)((Rom[index++] << 8) | Rom[index++]);
Data[(index / 2)] = (ushort)((rom[index++] << 8) | rom[index++]);
}
// look up hash in gamedb to see what mapper to use
// if none found default is zero
string hash_sha1 = null;
string s_mapper = null;
hash_sha1 = "sha1:" + Rom.HashSHA1(16, Rom.Length - 16);
hash_sha1 = "sha1:" + rom.HashSHA1(16, rom.Length - 16);
var gi = Database.CheckDatabase(hash_sha1);
if (gi != null)
{
var dict = gi.GetOptionsDict();
if (!dict.ContainsKey("board"))
{
throw new Exception("INTV gamedb entries must have a board identifier!");
}
s_mapper = dict["board"];
}
else
@ -57,14 +60,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
s_mapper = "0";
}
int.TryParse(s_mapper, out mapper);
int.TryParse(s_mapper, out _mapper);
return Rom.Length;
return rom.Length;
}
public ushort? ReadCart(ushort addr, bool peek)
{
switch (mapper)
switch (_mapper)
{
case 0:
if (addr >= 0x5000 && addr <= 0x6FFF)
@ -228,13 +231,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
break;
}
return null;
}
public bool WriteCart(ushort addr, ushort value, bool poke)
{
switch (mapper)
switch (_mapper)
{
case 4:
if (addr >= 0xD000 && addr <= 0xD3FF)

View File

@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
private readonly IPort Port1;
private readonly IPort Port2;
private static Dictionary<string, Type> _controllerTypes = null;
private static Dictionary<string, Type> _controllerTypes;
public static Dictionary<string, Type> ValidControllerTypes
{
@ -90,10 +90,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
}
public static string DefaultControllerName
{
get { return typeof(FakeAnalogController).DisplayName(); }
}
public static string DefaultControllerName => typeof(FakeAnalogController).DisplayName();
}
}

View File

@ -4,7 +4,6 @@ using System.ComponentModel;
using System.Linq;
using BizHawk.Common;
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision
@ -40,14 +39,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
return 0;
}
public ControllerDefinition Definition { get; private set; }
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
{
// Do nothing
}
public int PortNum { get; private set; }
public int PortNum { get; }
}
[DisplayName("Standard Controller")]
@ -64,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
};
}
public int PortNum { get; private set; }
public int PortNum { get; }
public byte Read(IController c)
{
@ -80,7 +79,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
return result;
}
public ControllerDefinition Definition { get; private set; }
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
@ -93,11 +92,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
"L", "R", "Top",
"Key 0", "Key 1", "Key 2", "Key 3", "Key 4", "Key 5",
"Key 6", "Key 7", "Key 8", "Key 9", "Enter", "Clear",
"N", "NNE", "NE", "ENE","E", "ESE", "SE", "SSE",
"S", "SSW", "SW", "WSW","W", "WNW", "NW", "NNW",
"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
"S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW",
};
private static byte[] HandControllerButtons = new byte[] {
private static byte[] HandControllerButtons =
{
0x60, // OUTPUT_ACTION_BUTTON_BOTTOM_LEFT
0xC0, // OUTPUT_ACTION_BUTTON_BOTTOM_RIGHT
0xA0, // OUTPUT_ACTION_BUTTON_TOP
@ -149,9 +149,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
};
}
public int PortNum { get; private set; }
public int PortNum { get; }
public ControllerDefinition Definition { get; private set; }
public ControllerDefinition Definition { get; }
public byte Read(IController c)
{
@ -183,7 +183,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
"Key 6", "Key 7", "Key 8", "Key 9", "Enter", "Clear"
};
private static byte[] BoolControllerButtons = new byte[]
private static byte[] BoolControllerButtons =
{
0x60, // OUTPUT_ACTION_BUTTON_BOTTOM_LEFT
0xC0, // OUTPUT_ACTION_BUTTON_BOTTOM_RIGHT
@ -210,7 +210,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
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)
if ((x * x) + (y * y) < Deadzone * Deadzone)
{
return 0; // nothing pressed
}
@ -223,7 +223,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
private const int Deadzone = 50;
private static byte[] FloatControllerButtons = new byte[]
private static byte[] FloatControllerButtons =
{
0x02, // E
0x06, // ENE

View File

@ -4,7 +4,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
public interface ICart
{
int Parse(byte[] Rom);
int Parse(byte[] rom);
ushort? ReadCart(ushort addr, bool peek);
bool WriteCart(ushort addr, ushort value, bool poke);

View File

@ -16,11 +16,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
ser.EndSection();
}
private ushort[] Data = new ushort[65536];
private bool[][] MemoryAttributes = new bool[32][];
private ushort[][] FineAddresses = new ushort[32][];
private readonly ushort[] Data = new ushort[65536];
private readonly bool[][] MemoryAttributes = new bool[32][];
private readonly ushort[][] FineAddresses = new ushort[32][];
private ushort[] CRC16_table =
private readonly ushort[] CRC16_table =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
@ -64,12 +64,15 @@ namespace BizHawk.Emulation.Cores.Intellivision
public int Parse(byte[] Rom)
{
int offset = 0;
// Check to see if the header is valid.
if (Rom[offset++] != 0xA8 || Rom[offset++] != (0xFF ^ Rom[offset++]))
{
return -1;
}
ushort crc, expected;
// Parse for data segments.
for (int segment = 0; segment < Rom[1]; segment++)
{
@ -84,6 +87,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
throw new ArgumentException("Ranges can't start higher than they end.");
}
for (int addr = start; addr <= end; addr++)
{
ushort data;
@ -94,36 +98,46 @@ namespace BizHawk.Emulation.Cores.Intellivision
data = (ushort)((high << 8) | low);
Data[addr] = data;
}
expected = (ushort)((Rom[offset++] << 8) | Rom[offset++]);
if (expected != crc)
{
throw new ArgumentException("Invalid CRC.");
}
}
// Parse for memory attributes.
for (int range = 0; range < 32; range++)
{
byte attributes = Rom[offset + (range >> 1)];
// Every second 2K block is stored in the upper 4 bits.
if ((range & 0x1) != 0)
{
attributes = (byte)(attributes >> 4);
}
attributes &= 0xF;
MemoryAttributes[range] = new bool[4];
// Readable.
MemoryAttributes[range][0] = ((range & 0x1) != 0);
MemoryAttributes[range][0] = (range & 0x1) != 0;
// Writeable.
MemoryAttributes[range][1] = ((range & 0x2) != 0);
MemoryAttributes[range][1] = (range & 0x2) != 0;
// Narrow.
MemoryAttributes[range][2] = ((range & 0x4) != 0);
MemoryAttributes[range][2] = (range & 0x4) != 0;
// Bank-switched.
MemoryAttributes[range][3] = ((range & 0x8) != 0);
MemoryAttributes[range][3] = (range & 0x8) != 0;
}
// Parse for fine addresses (Trimmed 2K ranges).
for (int range = 0; range < 32; range++)
{
int index;
// The lower and upper 2K in a 4K range are 16 addresses away from each other.
if ((range & 0x1) != 0)
{
@ -133,28 +147,34 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
index = offset + 32 + (range >> 1);
}
int range_start = range * 2048;
ushort start = (ushort)((((Rom[index] >> 4) & 0x07) << 8) + range_start);
ushort end = (ushort)((((Rom[index]) & 0x07) << 8) + 0xFF + range_start);
int rangeStart = range * 2048;
ushort start = (ushort)((((Rom[index] >> 4) & 0x07) << 8) + rangeStart);
ushort end = (ushort)(((Rom[index] & 0x07) << 8) + 0xFF + rangeStart);
if (end < start)
{
throw new ArgumentException("Ranges can't start higher than they end.");
}
FineAddresses[range] = new ushort[2];
FineAddresses[range][0] = start;
FineAddresses[range][1] = end;
}
crc = 0xFFFF;
for (int index = 0; index < 48; index++)
{
crc = UpdateCRC16(crc, Rom[offset++]);
}
expected = (ushort)((Rom[offset++] << 8) | (Rom[offset++] & 0xFF));
// Check if there is an invalid CRC for the memory attributes / fine addresses.
if (expected != crc)
{
throw new ArgumentException("Invalid CRC.");
}
return offset;
}
@ -166,6 +186,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
return Data[addr];
}
return null;
}
@ -180,13 +201,16 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
value &= 0xFF;
}
if (attributes[3])
{
throw new NotImplementedException("Bank-switched memory attribute not implemented.");
}
Data[addr] = value;
return true;
}
return false;
}
}

View File

@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition => ControllerDeck.Definition;
public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;
public IController Controller { get; set; }
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
if (_tracer.Enabled)
{
_cpu.TraceCallback = (s) => _tracer.Put(s);
_cpu.TraceCallback = s => _tracer.Put(s);
}
else
{
@ -28,14 +28,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
GetControllerState();
// this timer tracks cycles stolen by the STIC during the visible part of the frame, quite a large number of them actually
int delay_cycles = 700;
int delay_timer = -1;
int delayCycles = 700;
int delayTimer = -1;
_cpu.PendingCycles = 14934 - 3791 + _cpu.GetPendingCycles();
_stic.Sr1 = true;
_islag = true;
bool active_display = _stic.active_display;
bool activeDisplay = _stic.active_display;
// also at the start of every frame the color stack is reset
_stic.ColorSP = 0x0028;
@ -45,23 +45,25 @@ namespace BizHawk.Emulation.Cores.Intellivision
int cycles = _cpu.Execute();
_psg.generate_sound(cycles);
if (delay_cycles>=0 && active_display)
delay_cycles += cycles;
if (delay_timer> 0 && active_display)
if (delayCycles >= 0 && activeDisplay)
{
delay_timer -= cycles;
if (delay_timer<=0)
delayCycles += cycles;
}
if (delayTimer > 0 && activeDisplay)
{
delayTimer -= cycles;
if (delayTimer <= 0)
{
_stic.ToggleSr2();
delay_cycles = 0;
delayCycles = 0;
}
}
if (delay_cycles >= 750 && active_display)
if (delayCycles >= 750 && activeDisplay)
{
delay_cycles = -1;
delay_timer = 110;
delayCycles = -1;
delayTimer = 110;
_stic.ToggleSr2();
if (_sticRow >= 0)
{
@ -72,6 +74,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
_sticRow++;
}
Connect();
}
@ -106,17 +109,23 @@ namespace BizHawk.Emulation.Cores.Intellivision
_psg.generate_sound(cycles);
Connect();
}
_stic.in_vb_2 = false;
if (_islag)
{
_lagcount++;
}
if (Controller.IsPressed("Power"))
{
HardReset();
}
if (Controller.IsPressed("Reset"))
{
SoftReset();
}
}
public int Frame => _frame;

View File

@ -8,7 +8,8 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
get
{
return _lagcount; }
return _lagcount;
}
set
{

View File

@ -3,7 +3,6 @@
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision
{
public partial class Intellivision : IStatable
@ -61,7 +60,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
_stic.SyncState(ser);
_psg.SyncState(ser);
_cart.SyncState(ser);
ControllerDeck.SyncState(ser);
_controllerDeck.SyncState(ser);
ser.EndSection();
}

View File

@ -9,8 +9,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
"IntelliHawk",
"BrandonE, Alyosha",
isPorted: false,
isReleased: true
)]
isReleased: true)]
[ServiceNotApplicable(typeof(ISaveRam), typeof(IDriveLight), typeof(IRegionable))]
public sealed partial class Intellivision : IEmulator, IStatable, IInputPollable, IDisassemblable,
IDebuggable, ISettable<Intellivision.IntvSettings, Intellivision.IntvSyncSettings>
@ -24,12 +23,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
CoreComm = comm;
_rom = rom;
_gameInfo = game;
_settings = (IntvSettings)Settings ?? new IntvSettings();
_syncSettings = (IntvSyncSettings)SyncSettings ?? new IntvSyncSettings();
ControllerDeck = new IntellivisionControllerDeck(_syncSettings.Port1, _syncSettings.Port2);
_controllerDeck = new IntellivisionControllerDeck(_syncSettings.Port1, _syncSettings.Port2);
_cart = new Intellicart();
if (_cart.Parse(_rom) == -1)
@ -74,10 +72,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
SetupMemoryDomains();
}
public IntellivisionControllerDeck ControllerDeck { get; private set; }
private readonly IntellivisionControllerDeck _controllerDeck;
private readonly byte[] _rom;
private readonly GameInfo _gameInfo;
private readonly ITraceable _tracer;
private readonly CP1610 _cpu;
private readonly STIC _stic;
@ -87,14 +84,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
private int _frame;
private int _sticRow;
public void Connect()
private void Connect()
{
_cpu.SetIntRM(_stic.GetSr1());
_cpu.SetBusRq(_stic.GetSr2());
_stic.SetSst(_cpu.GetBusAk());
}
public void LoadExecutiveRom(byte[] erom)
private void LoadExecutiveRom(byte[] erom)
{
if (erom.Length != 8192)
{
@ -110,7 +107,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
}
public void LoadGraphicsRom(byte[] grom)
private void LoadGraphicsRom(byte[] grom)
{
if (grom.Length != 2048)
{
@ -124,10 +121,10 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
InputCallbacks.Call();
ushort port1 = ControllerDeck.ReadPort1(Controller);
ushort port1 = _controllerDeck.ReadPort1(Controller);
_psg.Register[15] = (ushort)(0xFF - port1);
ushort port2 = ControllerDeck.ReadPort2(Controller);
ushort port2 = _controllerDeck.ReadPort2(Controller);
_psg.Register[14] = (ushort)(0xFF - port2);
}

View File

@ -1,13 +1,14 @@
using BizHawk.Common.NumberExtensions;
using System;
using System;
using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision
{
public sealed class PSG : ISoundProvider
{
private BlipBuffer _blip = new BlipBuffer(4096);
private readonly BlipBuffer _blip = new BlipBuffer(4096);
private short[] _sampleBuffer = new short[0];
@ -18,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
public ushort[] Register = new ushort[16];
public int total_clock; // TODO: what is this uaed for?
public int total_clock; // TODO: what is this used for?
public void Reset()
{
@ -44,15 +45,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
throw new NotSupportedException("Async is not available");
}
public bool CanProvideAsync
{
get { return false; }
}
public bool CanProvideAsync => false;
public SyncSoundMode SyncMode
{
get { return SyncSoundMode.Sync; }
}
public SyncSoundMode SyncMode => SyncSoundMode.Sync;
public void SetSyncMode(SyncSoundMode mode)
{
@ -70,7 +65,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
nsamp = _blip.SamplesAvailable();
int targetLength = nsamp * 2;
if (_sampleBuffer.Length != targetLength)
{
_sampleBuffer = new short[targetLength];
}
_blip.ReadSamplesLeft(_sampleBuffer, nsamp);
for (int i = 0; i < _sampleBuffer.Length; i += 2)
@ -86,34 +83,35 @@ namespace BizHawk.Emulation.Cores.Intellivision
throw new Exception();
}
public static int[] volume_table = new int[16] {0x0000, 0x0055, 0x0079, 0x00AB, 0x00F1, 0x0155, 0x01E3, 0x02AA,
0x03C5, 0x0555, 0x078B, 0x0AAB, 0x0F16, 0x1555, 0x1E2B, 0x2AAA};
private static readonly int[] VolumeTable =
{
0x0000, 0x0055, 0x0079, 0x00AB, 0x00F1, 0x0155, 0x01E3, 0x02AA,
0x03C5, 0x0555, 0x078B, 0x0AAB, 0x0F16, 0x1555, 0x1E2B, 0x2AAA
};
private int _sampleClock;
private int _latchedSample;
public int TotalExecutedCycles;
public int PendingCycles;
private int TotalExecutedCycles;
private int PendingCycles;
private int psg_clock;
private int sq_per_A, sq_per_B, sq_per_C;
private int clock_A, clock_B, clock_C;
private int vol_A, vol_B, vol_C;
private bool A_on, B_on, C_on;
private bool A_up, B_up, C_up;
private bool A_noise, B_noise, C_noise;
public int psg_clock;
private int env_per;
private int env_clock;
private int env_shape;
private int env_E;
private int E_up_down;
private int env_vol_A, env_vol_B, env_vol_C;
public int sq_per_A, sq_per_B, sq_per_C;
public int clock_A, clock_B, clock_C;
public int vol_A, vol_B, vol_C;
public bool A_on, B_on, C_on;
public bool A_up, B_up, C_up;
public bool A_noise, B_noise, C_noise;
public int env_per;
public int env_clock;
public int env_shape;
public int env_E;
public int E_up_down;
public int env_vol_A, env_vol_B, env_vol_C;
public int noise_clock;
public int noise_per;
public int noise = 0x1;
private int noise_clock;
private int noise_per;
private int noise = 0x1;
public Func<ushort, bool, ushort> ReadMemory;
public Func<ushort, ushort, bool, bool> WriteMemory;
@ -150,27 +148,36 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
return (ushort)(Register[addr - 0x01F0]);
}
return null;
}
public void sync_psg_state()
private void sync_psg_state()
{
sq_per_A = (Register[0] & 0xFF) | (((Register[4] & 0xF) << 8));
if (sq_per_A == 0)
{
sq_per_A = 0x1000;
}
sq_per_B = (Register[1] & 0xFF) | (((Register[5] & 0xF) << 8));
if (sq_per_B == 0)
{
sq_per_B = 0x1000;
}
sq_per_C = (Register[2] & 0xFF) | (((Register[6] & 0xF) << 8));
if (sq_per_C == 0)
{
sq_per_C = 0x1000;
}
env_per = (Register[3] & 0xFF) | (((Register[7] & 0xFF) << 8));
if (env_per == 0)
{
env_per = 0x10000;
}
env_per *= 2;
A_on = Register[8].Bit(0);
@ -241,8 +248,10 @@ namespace BizHawk.Emulation.Cores.Intellivision
E_up_down = 1;
}
}
return true;
}
return false;
}
@ -270,7 +279,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
noise_clock--;
env_clock--;
//clock noise
// clock noise
if (noise_clock == 0)
{
noise = (noise >> 1) ^ (noise.Bit(0) ? 0x10004 : 0);
@ -286,7 +295,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (env_E == 16 || env_E == -1)
{
//we just completed a period of the envelope, determine what to do now based on the envelope shape
// we just completed a period of the envelope, determine what to do now based on the envelope shape
if (env_shape == 0 || env_shape == 1 || env_shape == 3 || env_shape == 9)
{
E_up_down = 0;
@ -344,24 +353,24 @@ namespace BizHawk.Emulation.Cores.Intellivision
sound_out_B = (noise.Bit(0) | B_noise) & (B_on | B_up);
sound_out_C = (noise.Bit(0) | C_noise) & (C_on | C_up);
//now calculate the volume of each channel and add them together
// now calculate the volume of each channel and add them together
int v;
if (env_vol_A == 0)
{
v = (short)(sound_out_A ? volume_table[vol_A] : 0);
v = (short)(sound_out_A ? VolumeTable[vol_A] : 0);
}
else
{
int shift_A = 3 - env_vol_A;
if (shift_A < 0)
shift_A = 0;
v = (short)(sound_out_A ? (volume_table[env_E] >> shift_A) : 0);
v = (short)(sound_out_A ? (VolumeTable[env_E] >> shift_A) : 0);
}
if (env_vol_B == 0)
{
v += (short)(sound_out_B ? volume_table[vol_B] : 0);
v += (short)(sound_out_B ? VolumeTable[vol_B] : 0);
}
else
@ -369,19 +378,19 @@ namespace BizHawk.Emulation.Cores.Intellivision
int shift_B = 3 - env_vol_B;
if (shift_B < 0)
shift_B = 0;
v += (short)(sound_out_B ? (volume_table[env_E] >> shift_B) : 0);
v += (short)(sound_out_B ? (VolumeTable[env_E] >> shift_B) : 0);
}
if (env_vol_C == 0)
{
v += (short)(sound_out_C ? volume_table[vol_C] : 0);
v += (short)(sound_out_C ? VolumeTable[vol_C] : 0);
}
else
{
int shift_C = 3 - env_vol_C;
if (shift_C < 0)
shift_C = 0;
v += (short)(sound_out_C ? (volume_table[env_E] >> shift_C) : 0);
v += (short)(sound_out_C ? (VolumeTable[env_E] >> shift_C) : 0);
}
if (v != _latchedSample)
@ -393,7 +402,6 @@ namespace BizHawk.Emulation.Cores.Intellivision
_sampleClock++;
}
}
}
}
}

View File

@ -55,19 +55,20 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
// gets called when a new border color is chosen
public void Update_Border()
private void Update_Border()
{
for (int i=0;i<176;i++)
for (int i = 0; i < 176; i++)
{
for (int j=0;j<8;j++)
for (int j = 0; j < 8; j++)
{
FrameBuffer[i + j * 176]= ColorToRGBA(Register[0x2C] & 0xF);
FrameBuffer[i + j * 176 + 176*200] = ColorToRGBA(Register[0x2C] & 0xF);
}
}
for (int j=8;j<(208-8);j++)
for (int j = 8; j < (208 - 8); j++)
{
for (int i=0;i<8;i++)
for (int i = 0; i < 8; i++)
{
FrameBuffer[i + j * 176] = ColorToRGBA(Register[0x2C] & 0xF);
FrameBuffer[i + 168 + j * 176] = ColorToRGBA(Register[0x2C] & 0xF);
@ -75,18 +76,18 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
}
public int VirtualWidth { get { return 277; } }
public int BufferWidth { get { return 176; } }
public int VirtualHeight { get { return 208; } }
public int BufferHeight { get { return 208; } }
public int BackgroundColor { get { return 0; } }
public int VirtualWidth => 277;
public int BufferWidth => 176;
public int VirtualHeight => 208;
public int BufferHeight => 208;
public int BackgroundColor => 0;
public void Reset()
{
Sr1 = true;
Sr2 = true;
for (int i=0;i<64;i++)
for (int i = 0; i < 64; i++)
{
Register[i] = 0;
write_reg(i, 0, false);
@ -149,12 +150,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
else if (reg < 0x33)
{
if (reg==0x32)
if (reg == 0x32)
{
value = (ushort)((value & 0x3) | 0x3FFC);
}
else
{
value = (ushort)((value & 0x7) | 0x3FF8);
}
}
else if (reg < 0x40)
{
@ -162,11 +165,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
Register[reg] = value;
if (reg==0x21 && !poke)
if (reg == 0x21 && !poke)
{
Fgbg = true;
}
if (reg==0x20 && !poke)
if (reg == 0x20 && !poke)
{
active_display = true;
}
@ -188,9 +192,10 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
Fgbg = false;
}
return Register[addr];
}
else if (addr>= 0x0040 && addr <= 0x007F && (in_vb_2 | !active_display))
else if (addr >= 0x0040 && addr <= 0x007F && (in_vb_2 | !active_display))
{
return Register[addr - 0x0040];
}
@ -223,6 +228,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
break;
}
return null;
}
@ -259,10 +265,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
break;
}
return false;
}
public int ColorToRGBA(int color)
private int ColorToRGBA(int color)
{
switch (color)
{
@ -299,6 +306,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
case 15:
return 0xB51A58;
}
throw new ArgumentException("Specified color does not exist.");
}
@ -307,15 +315,16 @@ namespace BizHawk.Emulation.Cores.Intellivision
// here we will also need to apply the 'delay' register values.
// this shifts the displayed portion of the screen relative to the BG
// The background is a 20x12 grid of "cards".
int bg=0;
int bg = 0;
for (int card_row = input_row; card_row < (input_row+1); card_row++)
{
for (int card_col = 0; card_col < 20; card_col++)
{
int buffer_offset = (card_row * 159 * 8) + (card_col * 8);
// The cards are stored sequentially in the System RAM.
ushort card = ReadMemory((ushort)(0x0200 + (card_row * 20) + card_col), false);
// Parse data from the card.
bool gram = ((card & 0x0800) != 0);
int card_num = card >> 3;
@ -323,6 +332,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (Fgbg)
{
bg = ((card >> 9) & 0x0008) | ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003);
// Only 64 of the GROM's cards can be used in FGBG Mode.
card_num &= 0x003F;
}
@ -334,6 +344,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
// GRAM only has 64 cards.
card_num &= 0x003F;
// The foreground color has an additional bit when not in Colored Squares mode.
if (squares)
fg |= 0x0008;
@ -343,6 +354,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
// All of the GROM's 256 cards can be used in Color Stack Mode.
card_num &= 0x00FF;
}
if (!gram && squares)
{
// Colored Squares Mode.
@ -353,9 +365,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
colors[2] = (card >> 6) & 0x0007;
colors[3] = ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003);
for (int z=0;z<4;z++)
for (int z = 0; z < 4; z++)
{
if (colors[z]==7)
if (colors[z] == 7)
{
colors[z] = Register[ColorSP] & 0x000F;
square_col[z] = 0;
@ -377,6 +389,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
int color;
int pixel = buffer_offset + (squares_row * 159) + squares_col;
// Determine the color of the quadrant the pixel is in.
if (squares_col < 4)
{
@ -426,9 +439,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
ColorSP = 0x0028;
}
}
bg = Register[ColorSP] & 0x000F;
}
}
for (int pict_row = 0; pict_row < 8; pict_row++)
{
// Each picture is stored sequentially in the GROM / GRAM, and so are their rows.
@ -455,6 +470,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
// The pixels go right as the bits get less significant.
BGBuffer[pixel] = ColorToRGBA(fg);
// also if the pixel is on set it in the collision matrix
// note that the collision field is attached to the lower right corner of the BG
// so we add 8 to x and 16 to y here
@ -468,6 +484,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
BGBuffer[pixel] = ColorToRGBA(bg);
}
row >>= 1;
}
}
@ -477,7 +494,6 @@ namespace BizHawk.Emulation.Cores.Intellivision
// now that we have the cards in BGbuffer, we can double vertical resolution to get Frame buffer
// there is a trick here in that we move the displayed area of the screen relative to the BG buffer
// this is done using the delay registers
int x_delay = Register[0x30] & 0x7;
int y_delay = Register[0x31] & 0x7;
@ -495,15 +511,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
{
FrameBuffer[(j * 2) * 176 + (i+8) + BORDER_OFFSET] = BGBuffer[(j - y_delay) * 159 + i - x_delay];
FrameBuffer[(j * 2 + 1) * 176 + (i+8) + BORDER_OFFSET] = BGBuffer[(j - y_delay) * 159 + i - x_delay];
} else
}
else
{
FrameBuffer[(j * 2) * 176 + (i + 8) + BORDER_OFFSET] = ColorToRGBA(bg);
FrameBuffer[(j * 2 + 1) * 176 + (i + 8) + BORDER_OFFSET] = ColorToRGBA(bg);
}
}
}
}
// see for more details: http://spatula-city.org/~im14u2c/intv/jzintv-1.0-beta3/doc/programming/stic.txt
@ -626,7 +641,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
}
//flip mobs accordingly
// flip mobs accordingly
if (x_flip)
{
for (int j = 0; j < 8; j++)
@ -642,7 +657,8 @@ namespace BizHawk.Emulation.Cores.Intellivision
mobs[j] = (byte)(temp_0 + temp_1 + temp_2 + temp_3 + temp_4 + temp_5 + temp_6 + temp_7);
}
if (yres>1)
if (yres > 1)
{
for (int j = 0; j < 8; j++)
{
@ -672,7 +688,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
byte temp_7 = mobs[7];
if (yres==1)
if (yres == 1)
{
mobs[0] = mobs[7];
mobs[1] = mobs[6];
@ -705,7 +721,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
}
//draw the mob and check for collision
// draw the mob and check for collision
for (int j = 0; j < 8; j++)
{
for (int k = 0; k < 8; k++)
@ -723,8 +739,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (!(priority && (Collision[cur_x, loc_y * 2 + cur_y]&0x100)>0))
FrameBuffer[(loc_y * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color);
}
//a MOB does not need to be visible for it to be interracting
//special case: a mob with x position 0 is counted as off
// a MOB does not need to be visible for it to be interracting
// special case: a mob with x position 0 is counted as off
if (intr && pixel && (cur_x) <= 167 && (loc_y * 2 + cur_y) < 210 && loc_x != 0)
{
Collision[cur_x, loc_y * 2 + cur_y] |= (ushort)(1 << i);
@ -767,8 +784,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (!(priority && (Collision[cur_x, (loc_y + 4 * y_size) * 2 + cur_y] & 0x100) > 0))
FrameBuffer[((loc_y + 4 * y_size) * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color);
}
//a MOB does not need to be visible for it to be interracting
//special case: a mob with x position 0 is counted as off
// a MOB does not need to be visible for it to be interracting
// special case: a mob with x position 0 is counted as off
if (intr && pixel && (cur_x) <= 167 && ((loc_y + 4 * y_size) * 2 + cur_y) < 210 && loc_x != 0)
{
Collision[cur_x, (loc_y + 4 * y_size) * 2 + cur_y] |= (ushort)(1 << i);
@ -781,8 +799,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (!(priority && (Collision[cur_x + 1, (loc_y + 4 * y_size) * 2 + cur_y] & 0x100) > 0))
FrameBuffer[((loc_y + 4 * y_size) * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) + 1 - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color);
}
//a MOB does not need to be visible for it to be interracting
//special case: a mob with x position 0 is counted as off
// a MOB does not need to be visible for it to be interracting
// special case: a mob with x position 0 is counted as off
if (intr && pixel && (cur_x + 1) <= 167 && ((loc_y + 4 * y_size) * 2 + cur_y) < 210 && loc_x != 0)
{
Collision[cur_x + 1, (loc_y + 4 * y_size) * 2 + cur_y] |= (ushort)(1 << i);
@ -845,13 +864,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
}
}
}
// after we check for collision, we can clear that value for the next frame.
Collision[i, j] = 0;
}
}
}
// end of Mobs function, we now have collision and graphics data for the mobs
}
}