Merge pull request #1 from TASVideos/master
Update from original repository
This commit is contained in:
commit
a10cfb4cb6
|
@ -596,7 +596,6 @@
|
|||
<Compile Include="Consoles\Belogic\LibUzem.cs" />
|
||||
<Compile Include="Consoles\Belogic\Uzem.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IDebuggable.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IO.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.MemoryDomains.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IStatable.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.ISettable.cs" />
|
||||
|
@ -605,12 +604,17 @@
|
|||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IEmulator.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.IVideoProvider.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\ChannelF.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.ALU.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Operations.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Disassembler.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Tables.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Registers.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.Execute.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\F8\F3850.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\Cart.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\Audio.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\Video.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\Ports.cs" />
|
||||
<Compile Include="Consoles\Fairchild\ChannelF\Memory.cs" />
|
||||
<Compile Include="Consoles\GCE\Vectrex\Audio.cs" />
|
||||
<Compile Include="Consoles\GCE\Vectrex\VectrexHawk.cs" />
|
||||
<Compile Include="Consoles\GCE\Vectrex\VectrexHawk.ICodeDataLog.cs" />
|
||||
|
|
|
@ -940,7 +940,7 @@ namespace BizHawk.Emulation.Cores.Computers.SinclairSpectrum
|
|||
return croppedBuffer;
|
||||
|
||||
case ZXSpectrum.BorderType.None:
|
||||
// all border sizes now 24
|
||||
// all border sizes now 0
|
||||
var lR__ = BorderLeftWidth;
|
||||
var rR__ = BorderRightWidth;
|
||||
var tR__ = BorderTopHeight;
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio related functions
|
||||
/// </summary>
|
||||
public partial class ChannelF : ISoundProvider
|
||||
{
|
||||
private double SampleRate = 44100;
|
||||
private int SamplesPerFrame;
|
||||
private double Period;
|
||||
private double CyclesPerSample;
|
||||
|
||||
|
||||
private int tone = 0;
|
||||
|
||||
private double[] tone_freqs = new double[] { 0, 1000, 500, 120 };
|
||||
private double amplitude = 0;
|
||||
private double decay = 0.998;
|
||||
private double time = 0;
|
||||
private double cycles = 0;
|
||||
private int samplePos = 0;
|
||||
private int lastCycle = 0;
|
||||
|
||||
private BlipBuffer _blip;
|
||||
|
||||
private short[] SampleBuffer;
|
||||
|
||||
private void SetupAudio()
|
||||
{
|
||||
Period = (double)1 / SampleRate;
|
||||
SamplesPerFrame = (int)(SampleRate / refreshRate);
|
||||
CyclesPerSample = (double)ClockPerFrame / (double)SamplesPerFrame;
|
||||
SampleBuffer = new short[SamplesPerFrame];
|
||||
_blip = new BlipBuffer(SamplesPerFrame);
|
||||
_blip.SetRates(ClockPerFrame * refreshRate, SampleRate);
|
||||
}
|
||||
|
||||
private void AudioChange()
|
||||
{
|
||||
if (tone == 0)
|
||||
{
|
||||
// silence
|
||||
}
|
||||
else
|
||||
{
|
||||
int SamplesPerWave = (int)(SampleRate / tone_freqs[tone]);
|
||||
double RadPerSample = (Math.PI * 2) / (double) SamplesPerWave;
|
||||
double SinVal = 0;
|
||||
|
||||
int NumSamples = (int)(((double)FrameClock - (double)lastCycle) / CyclesPerSample);
|
||||
|
||||
int startPos = lastCycle;
|
||||
|
||||
for (int i = 0; i < NumSamples; i++)
|
||||
{
|
||||
SinVal = Math.Sin(RadPerSample * (double) (i * SamplesPerWave));
|
||||
_blip.AddDelta((uint)startPos, (int) (Math.Floor(SinVal * 127) + 128) * 1024);
|
||||
startPos += (int)CyclesPerSample;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanProvideAsync => false;
|
||||
|
||||
public SyncSoundMode SyncMode => SyncSoundMode.Sync;
|
||||
|
||||
public void SetSyncMode(SyncSoundMode mode)
|
||||
{
|
||||
if (mode != SyncSoundMode.Sync)
|
||||
throw new InvalidOperationException("Only Sync mode is supported.");
|
||||
}
|
||||
|
||||
public void GetSamplesAsync(short[] samples)
|
||||
{
|
||||
throw new NotSupportedException("Async is not available");
|
||||
}
|
||||
|
||||
public void DiscardSamples()
|
||||
{
|
||||
SampleBuffer = new short[SamplesPerFrame];
|
||||
samplePos = 0;
|
||||
lastCycle = 0;
|
||||
}
|
||||
|
||||
public void GetSamplesSync(out short[] samples, out int nsamp)
|
||||
{
|
||||
AudioChange();
|
||||
|
||||
_blip.EndFrame((uint)ClockPerFrame);
|
||||
nsamp = _blip.SamplesAvailable();
|
||||
samples = new short[nsamp * 2];
|
||||
_blip.ReadSamples(samples, nsamp, true);
|
||||
|
||||
for (int i = 0; i < nsamp * 2; i += 2)
|
||||
{
|
||||
samples[i + 1] = samples[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// Cartridge and related functions
|
||||
/// </summary>
|
||||
public partial class ChannelF
|
||||
{
|
||||
public byte[] Rom = new byte[4096];
|
||||
}
|
||||
}
|
|
@ -1,12 +1,127 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
public partial class ChannelF
|
||||
{
|
||||
public bool[] StateConsole = new bool[4];
|
||||
public string[] ButtonsConsole = new string[]
|
||||
{
|
||||
"TIME", "MODE", "HOLD", "START"
|
||||
};
|
||||
public byte DataConsole
|
||||
{
|
||||
get
|
||||
{
|
||||
int w = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
byte mask = (byte) (1 << i);
|
||||
w = StateConsole[i] ? w | mask : w & ~mask;
|
||||
}
|
||||
|
||||
return (byte)(w & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
public bool[] StateRight = new bool[8];
|
||||
public string[] ButtonsRight = new string[]
|
||||
{
|
||||
"Right", "Left", "Back", "Forward", "CCW", "CW", "Pull", "Push"
|
||||
};
|
||||
public byte DataRight
|
||||
{
|
||||
get
|
||||
{
|
||||
int w = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
byte mask = (byte)(1 << i);
|
||||
w = StateRight[i] ? w | mask : w & ~mask;
|
||||
}
|
||||
|
||||
return (byte)(w & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
public bool[] StateLeft = new bool[8];
|
||||
public string[] ButtonsLeft = new string[]
|
||||
{
|
||||
"Right", "Left", "Back", "Forward", "CCW", "CW", "Pull", "Push"
|
||||
};
|
||||
public byte DataLeft
|
||||
{
|
||||
get
|
||||
{
|
||||
int w = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
byte mask = (byte)(1 << i);
|
||||
w = StateLeft[i] ? w | mask : w & ~mask;
|
||||
}
|
||||
|
||||
return (byte)(w & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Cycles through all the input callbacks
|
||||
/// This should be done once per frame
|
||||
/// </summary>
|
||||
public bool PollInput()
|
||||
{
|
||||
bool noInput = true;
|
||||
|
||||
InputCallbacks.Call();
|
||||
|
||||
lock (this)
|
||||
{
|
||||
for (int i = 0; i < ButtonsConsole.Length; i++)
|
||||
{
|
||||
var key = ButtonsConsole[i];
|
||||
bool prevState = StateConsole[i]; // CTRLConsole.Bit(i);
|
||||
bool currState = _controller.IsPressed(key);
|
||||
if (currState != prevState)
|
||||
{
|
||||
StateConsole[i] = currState;
|
||||
noInput = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ButtonsRight.Length; i++)
|
||||
{
|
||||
var key = "P1 " + ButtonsRight[i];
|
||||
bool prevState = StateRight[i];
|
||||
bool currState = _controller.IsPressed(key);
|
||||
if (currState != prevState)
|
||||
{
|
||||
StateRight[i] = currState;
|
||||
noInput = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < ButtonsLeft.Length; i++)
|
||||
{
|
||||
var key = "P2 " + ButtonsLeft[i];
|
||||
bool prevState = StateLeft[i];
|
||||
bool currState = _controller.IsPressed(key);
|
||||
if (currState != prevState)
|
||||
{
|
||||
StateLeft[i] = currState;
|
||||
noInput = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return noInput;
|
||||
}
|
||||
|
||||
public ControllerDefinition ChannelFControllerDefinition
|
||||
{
|
||||
get
|
||||
|
@ -14,23 +129,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
ControllerDefinition definition = new ControllerDefinition();
|
||||
definition.Name = "ChannelF Controller";
|
||||
|
||||
string pre = "P1 ";
|
||||
|
||||
// sticks
|
||||
List<string> stickL = new List<string>
|
||||
{
|
||||
// P1 (left) stick
|
||||
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Button Up", "P1 Button Down", "P1 Rotate Left", "P1 Rotate Right"
|
||||
};
|
||||
|
||||
foreach (var s in stickL)
|
||||
{
|
||||
definition.BoolButtons.Add(s);
|
||||
definition.CategoryLabels[s] = "Left Controller";
|
||||
}
|
||||
|
||||
List<string> stickR = new List<string>
|
||||
{
|
||||
// P1 (left) stick
|
||||
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Button Up", "P2 Button Down", "P2 Rotate Left", "P2 Rotate Right"
|
||||
// P1 (right) stick
|
||||
pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push"
|
||||
};
|
||||
|
||||
foreach (var s in stickR)
|
||||
|
@ -39,6 +144,20 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
definition.CategoryLabels[s] = "Right Controller";
|
||||
}
|
||||
|
||||
pre = "P2 ";
|
||||
|
||||
List<string> stickL = new List<string>
|
||||
{
|
||||
// P2 (left) stick
|
||||
pre + "Forward", pre + "Back", pre + "Left", pre + "Right", pre + "CCW", pre + "CW", pre + "Pull", pre + "Push"
|
||||
};
|
||||
|
||||
foreach (var s in stickL)
|
||||
{
|
||||
definition.BoolButtons.Add(s);
|
||||
definition.CategoryLabels[s] = "Left Controller";
|
||||
}
|
||||
|
||||
// console
|
||||
List<string> consoleButtons = new List<string>
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
if (reg > 63)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
CPU.Regs[reg] = (ushort) value;
|
||||
CPU.Regs[reg] = (byte) value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -56,13 +56,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
default:
|
||||
throw new InvalidOperationException();
|
||||
case "A":
|
||||
CPU.Regs[CPU.A] = (ushort)value;
|
||||
CPU.Regs[CPU.A] = (byte)value;
|
||||
break;
|
||||
case "W":
|
||||
CPU.Regs[CPU.W] = (ushort)value;
|
||||
CPU.Regs[CPU.W] = (byte)value;
|
||||
break;
|
||||
case "ISAR":
|
||||
CPU.Regs[CPU.ISAR] = (ushort)(value & 0x3F);
|
||||
CPU.Regs[CPU.ISAR] = (byte)(value & 0x3F);
|
||||
break;
|
||||
case "PC0":
|
||||
CPU.RegPC0 = (ushort)value;
|
||||
|
@ -74,25 +74,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
CPU.RegDC0 = (ushort)value;
|
||||
break;
|
||||
case "DB":
|
||||
CPU.Regs[CPU.DB] = (ushort)value;
|
||||
CPU.Regs[CPU.DB] = (byte)value;
|
||||
break;
|
||||
case "IO":
|
||||
CPU.Regs[CPU.IO] = (ushort)value;
|
||||
CPU.Regs[CPU.IO] = (byte)value;
|
||||
break;
|
||||
case "J":
|
||||
CPU.Regs[CPU.J] = (ushort)value;
|
||||
CPU.Regs[CPU.J] = (byte)value;
|
||||
break;
|
||||
case "H":
|
||||
CPU.Regs[CPU.Hl] = (ushort)(value & 0xFF);
|
||||
CPU.Regs[CPU.Hh] = (ushort)(value & 0xFF00);
|
||||
CPU.Regs[CPU.Hl] = (byte)(value & 0xFF);
|
||||
CPU.Regs[CPU.Hh] = (byte)(value & 0xFF00);
|
||||
break;
|
||||
case "K":
|
||||
CPU.Regs[CPU.Kl] = (ushort)(value & 0xFF);
|
||||
CPU.Regs[CPU.Kh] = (ushort)(value & 0xFF00);
|
||||
CPU.Regs[CPU.Kl] = (byte)(value & 0xFF);
|
||||
CPU.Regs[CPU.Kh] = (byte)(value & 0xFF00);
|
||||
break;
|
||||
case "Q":
|
||||
CPU.Regs[CPU.Ql] = (ushort)(value & 0xFF);
|
||||
CPU.Regs[CPU.Qh] = (ushort)(value & 0xFF00);
|
||||
CPU.Regs[CPU.Ql] = (byte)(value & 0xFF);
|
||||
CPU.Regs[CPU.Qh] = (byte)(value & 0xFF00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,12 +22,17 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
private void CalcClock()
|
||||
{
|
||||
var c = (cpuFreq * 1000000) / refreshRate;
|
||||
var c = ((cpuFreq * 1000000) / refreshRate);
|
||||
ClockPerFrame = (int) c;
|
||||
|
||||
SetupAudio();
|
||||
}
|
||||
|
||||
public bool FrameAdvance(IController controller, bool render, bool renderSound)
|
||||
{
|
||||
_controller = controller;
|
||||
_isLag = false;
|
||||
|
||||
if (_tracer.Enabled)
|
||||
{
|
||||
CPU.TraceCallback = s => _tracer.Put(s);
|
||||
|
@ -37,6 +42,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
CPU.TraceCallback = null;
|
||||
}
|
||||
|
||||
_isLag = PollInput();
|
||||
|
||||
while (FrameClock++ < ClockPerFrame)
|
||||
{
|
||||
CPU.ExecuteOne();
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
using System;
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
|
||||
public partial class ChannelF
|
||||
{
|
||||
public byte[] BIOS01 = new byte[1024];
|
||||
public byte[] BIOS02 = new byte[1024];
|
||||
|
||||
public byte[] FrameBuffer = new byte[0x2000];
|
||||
|
||||
public byte[] Cartridge = new byte[0x2000 - 0x800];
|
||||
|
||||
public byte[] PortLatch = new byte[64];
|
||||
|
||||
public byte ReadBus(ushort addr)
|
||||
{
|
||||
if (addr < 0x400)
|
||||
{
|
||||
// Rom0
|
||||
return BIOS01[addr];
|
||||
}
|
||||
else if (addr < 0x800)
|
||||
{
|
||||
// Rom1
|
||||
return BIOS02[addr - 0x400];
|
||||
}
|
||||
else if (addr < 0x2000)
|
||||
{
|
||||
// Cart
|
||||
return 0;
|
||||
return Cartridge[addr - 0x800];
|
||||
}
|
||||
else if (addr < 0x2000 + 2048)
|
||||
{
|
||||
// Framebuffer
|
||||
return FrameBuffer[addr - 0x2000];
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBus(ushort addr, byte value)
|
||||
{
|
||||
if (addr < 0x400)
|
||||
{
|
||||
// Rom0
|
||||
}
|
||||
else if (addr < 0x800)
|
||||
{
|
||||
// Rom1
|
||||
}
|
||||
else if (addr < 0x2000)
|
||||
{
|
||||
// Cart
|
||||
}
|
||||
else if (addr < 0x2000 + 2048)
|
||||
{
|
||||
// Framebuffer
|
||||
FrameBuffer[addr - 0x2000] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public byte ReadPort(ushort addr)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
public void WritePort(ushort addr, byte value)
|
||||
{
|
||||
PortLatch[addr] = value;
|
||||
|
||||
VID_PortIN(addr, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,7 +41,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
private void SyncState(Serializer ser)
|
||||
{
|
||||
|
||||
ser.BeginSection("ChannelF");
|
||||
ser.Sync(nameof(VRAM), ref VRAM, false);
|
||||
ser.Sync(nameof(_colour), ref _colour);
|
||||
ser.Sync(nameof(_x), ref _x);
|
||||
ser.Sync(nameof(_y), ref _y);
|
||||
ser.Sync(nameof(_arm), ref _arm);
|
||||
ser.Sync(nameof(ControllersEnabled), ref ControllersEnabled);
|
||||
CPU.SyncState(ser);
|
||||
ser.EndSection();
|
||||
/*
|
||||
|
||||
byte[] core = null;
|
||||
|
|
|
@ -7,95 +7,52 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
public partial class ChannelF : IVideoProvider, IRegionable
|
||||
{
|
||||
public static readonly int[] FPalette =
|
||||
{
|
||||
Colors.ARGB(0x10, 0x10, 0x10), // Black
|
||||
Colors.ARGB(0xFD, 0xFD, 0xFD), // White
|
||||
Colors.ARGB(0xFF, 0x31, 0x53), // Red
|
||||
Colors.ARGB(0x02, 0xCC, 0x5D), // Green
|
||||
Colors.ARGB(0x4B, 0x3F, 0xF3), // Blue
|
||||
Colors.ARGB(0xE0, 0xE0, 0xE0), // Gray
|
||||
Colors.ARGB(0x91, 0xFF, 0xA6), // BGreen
|
||||
Colors.ARGB(0xCE, 0xD0, 0xFF), // BBlue
|
||||
};
|
||||
|
||||
public static readonly int[] CMap =
|
||||
{
|
||||
0, 1, 1, 1,
|
||||
7, 4, 2, 3,
|
||||
5, 4, 2, 3,
|
||||
6, 4, 2, 3,
|
||||
};
|
||||
|
||||
public int _frameHz = 60;
|
||||
|
||||
public int[] _vidbuffer = new int[108 * 64];
|
||||
public int[] CroppedBuffer = new int[102 * 58];
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
int colour;
|
||||
int a = 0;
|
||||
int pOff;
|
||||
|
||||
// rows
|
||||
for (int y = 0; y < 64; y++)
|
||||
{
|
||||
pOff = ((FrameBuffer[(y * 128) + 125] & 0x3) & 0x02) | ((FrameBuffer[(y * 128) + 126] & 0x3) >> 1) << 2;
|
||||
|
||||
for (int x = a; x < a + 128; x++)
|
||||
{
|
||||
colour = pOff + (FrameBuffer[x | (y << 7)] & 0x03);
|
||||
var yM = y * 64;
|
||||
_vidbuffer[yM + x] = FPalette[CMap[colour]];
|
||||
}
|
||||
}
|
||||
|
||||
return _vidbuffer;
|
||||
}
|
||||
#region IVideoProvider
|
||||
|
||||
public int VirtualWidth => BufferWidth * 2;
|
||||
public int VirtualHeight => BufferHeight * 2;
|
||||
public int BufferWidth => 108; // 102
|
||||
public int BufferHeight => 64; // 58
|
||||
public int BackgroundColor => unchecked((int)0xFF000000);
|
||||
public int VirtualHeight => (int)((double)BufferHeight * 1.3) * 2;
|
||||
public int BufferWidth => 102; //128
|
||||
public int BufferHeight => 58; //64
|
||||
public int BackgroundColor => Colors.ARGB(0x00, 0x00, 0x00);
|
||||
public int VsyncNumerator => _frameHz;
|
||||
public int VsyncDenominator => 1;
|
||||
|
||||
private int row = 0;
|
||||
private int col = 0;
|
||||
private byte value = 0;
|
||||
|
||||
public void VID_PortIN(ushort port, byte val)
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
switch (port)
|
||||
BuildFrame();
|
||||
|
||||
var lBorderWidth = 4;
|
||||
var rBorderWidth = 128 - 102 - lBorderWidth;
|
||||
var tBorderHeight = 4;
|
||||
var bBorderHeight = 64 - 58 - tBorderHeight;
|
||||
var startP = 128 * tBorderHeight;
|
||||
var endP = 128 * bBorderHeight;
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int i = startP; i < frameBuffer.Length - endP; i += 128)
|
||||
{
|
||||
case 0:
|
||||
for (int p = lBorderWidth; p < 128 - rBorderWidth; p++)
|
||||
{
|
||||
if (index == CroppedBuffer.Length)
|
||||
break;
|
||||
|
||||
int o;
|
||||
PortLatch[port] = val;
|
||||
if ((val & 0x20) != 0)
|
||||
{
|
||||
o = (row * 128) + col;
|
||||
FrameBuffer[o] = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Set Color (bits 6 and 7)
|
||||
PortLatch[port] = val;
|
||||
value = (byte)(((val ^ 0xFF) >> 6) & 0x03);
|
||||
break;
|
||||
case 4: // X coordinate, inverted (bits 0-6)
|
||||
PortLatch[2] = val;
|
||||
col = (val | 0x80) ^ 0xFF;
|
||||
break;
|
||||
case 5: // Y coordinate, inverted (bits 0-5)
|
||||
PortLatch[3] = val;
|
||||
//sound TODO
|
||||
row = (val | 0xC0) ^ 0xFF;
|
||||
break;
|
||||
CroppedBuffer[index++] = FPalette[frameBuffer[i + p]];
|
||||
}
|
||||
}
|
||||
|
||||
return CroppedBuffer;
|
||||
|
||||
//return frameBuffer;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IRegionable
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
SyncByteArrayDomain("BIOS1", BIOS01);
|
||||
SyncByteArrayDomain("BIOS2", BIOS02);
|
||||
SyncByteArrayDomain("ROM", Cartridge);
|
||||
SyncByteArrayDomain("VRAM", FrameBuffer);
|
||||
SyncByteArrayDomain("ROM", Rom);
|
||||
SyncByteArrayDomain("VRAM", VRAM);
|
||||
}
|
||||
|
||||
private void SyncByteArrayDomain(string name, byte[] data)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
|
@ -39,18 +40,20 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
BIOS01 = bios01;
|
||||
BIOS02 = bios02;
|
||||
|
||||
Array.Copy(rom, 0, Cartridge, 0, rom.Length);
|
||||
Array.Copy(rom, 0, Rom, 0, rom.Length);
|
||||
|
||||
CalcClock();
|
||||
|
||||
ser.Register<IVideoProvider>(this);
|
||||
ser.Register<ITraceable>(_tracer);
|
||||
ser.Register<IDisassemblable>(CPU);
|
||||
ser.Register<ISoundProvider>(this);
|
||||
|
||||
SetupMemoryDomains();
|
||||
}
|
||||
|
||||
public F3850 CPU;
|
||||
private readonly TraceBuffer _tracer;
|
||||
public IController _controller;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,320 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// ALU Operations
|
||||
/// The arithmetic and logic unit provides all data manipulating logic for the F3850.
|
||||
/// It contains logic that operates on a single 8-bit source data work or combines two 8-bit words of source data
|
||||
/// to generate a single 8-bit result. Additional information is reported in status flags, where appropriate.
|
||||
///
|
||||
/// Operations Performed:
|
||||
/// * Addition
|
||||
/// * Compare
|
||||
/// * AND
|
||||
/// * OR
|
||||
/// * XOR
|
||||
/// </summary>
|
||||
public sealed partial class F3850
|
||||
{
|
||||
/// <summary>
|
||||
/// Clears all status flags (excluding the ICB flag)
|
||||
/// </summary>
|
||||
public void ALU_ClearFlags()
|
||||
{
|
||||
FlagC = false;
|
||||
FlagO = false;
|
||||
FlagS = false;
|
||||
FlagZ = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the SIGN and ZERO flags based on the supplied byte
|
||||
/// </summary>
|
||||
/// <param name="val"></param>
|
||||
public void ALU_SetFlags_SZ(ushort src)
|
||||
{
|
||||
FlagZ = (byte)Regs[src] == 0;
|
||||
FlagS = (~((byte)Regs[src]) & 0x80) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs addition and sets the CARRY and OVERFLOW flags accordingly
|
||||
/// </summary>
|
||||
/// <param name="dest"></param>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="carry"></param>
|
||||
public void ALU_ADD8_Func(ushort dest, ushort src, bool carry = false)
|
||||
{
|
||||
byte d = (byte)Regs[dest];
|
||||
byte s = (byte)Regs[src];
|
||||
byte c = carry ? (byte)1 : (byte)0;
|
||||
ushort result = (ushort)(d + s + c);
|
||||
|
||||
FlagC = (result & 0x100) != 0;
|
||||
FlagO = ((d ^ result) & (s ^ result) & 0x80) != 0;
|
||||
|
||||
Regs[dest] = (ushort)(result & 0xFF);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs addition and sets the CARRY and OVERFLOW flags accordingly WITHOUT saving to destination
|
||||
/// </summary>
|
||||
/// <param name="dest"></param>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="carry"></param>
|
||||
public void ALU_ADD8_FLAGSONLY_Func(ushort dest, ushort src)
|
||||
{
|
||||
byte d = (byte)Regs[dest];
|
||||
byte s = (byte)Regs[src];
|
||||
ushort result = (ushort)(d + s);
|
||||
|
||||
FlagC = (result & 0x100) != 0;
|
||||
FlagO = ((d ^ result) & (s ^ result) & 0x80) != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs decimal addition based on the two supplied bytes
|
||||
/// (looks like this is only used in the AMD operation)
|
||||
/// </summary>
|
||||
/// <param name="dest"></param>
|
||||
/// <param name="src"></param>
|
||||
public void ALU_ADD8D_Func(ushort dest, ushort src)
|
||||
{
|
||||
// from MAME f8.cpp (BSD-3)
|
||||
// https://github.com/mamedev/mame/blob/97b67170277437131adf6ed4d60139c172529e4f/src/devices/cpu/f8/f8.cpp#L264
|
||||
byte d = (byte)Regs[dest];
|
||||
byte s = (byte)Regs[src];
|
||||
byte tmp = (byte)(d + s);
|
||||
|
||||
byte c = 0; // high order carry
|
||||
byte ic = 0; // low order carry
|
||||
|
||||
if (((d + s) & 0xFF0) > 0xF0)
|
||||
{
|
||||
c = 1;
|
||||
}
|
||||
|
||||
if ((d & 0x0F) + (s & 0x0F) > 0x0F)
|
||||
{
|
||||
ic = 1;
|
||||
}
|
||||
|
||||
ALU_ClearFlags();
|
||||
ALU_ADD8_FLAGSONLY_Func(dest, src);
|
||||
Regs[ALU0] = tmp;
|
||||
ALU_SetFlags_SZ(ALU0);
|
||||
|
||||
if (c == 0 && ic == 0)
|
||||
{
|
||||
tmp = (byte)(((tmp + 0xa0) & 0xf0) + ((tmp + 0x0a) & 0x0f));
|
||||
}
|
||||
|
||||
if (c == 0 && ic == 1)
|
||||
{
|
||||
tmp = (byte)(((tmp + 0xa0) & 0xf0) + (tmp & 0x0f));
|
||||
}
|
||||
|
||||
if (c == 1 && ic == 0)
|
||||
{
|
||||
tmp = (byte)((tmp & 0xf0) + ((tmp + 0x0a) & 0x0f));
|
||||
}
|
||||
|
||||
Regs[dest] = tmp;
|
||||
}
|
||||
|
||||
public void ALU_SUB8_Func(ushort dest, ushort src)
|
||||
{
|
||||
byte d = (byte)Regs[dest];
|
||||
byte s = (byte)Regs[src];
|
||||
ushort result = (ushort)(d - s);
|
||||
|
||||
FlagC = (result & 0x100) != 0;
|
||||
FlagO = ((d ^ result) & (s ^ result) & 0x80) != 0;
|
||||
|
||||
int Reg16_d = Regs[dest];
|
||||
Reg16_d -= Regs[src];
|
||||
|
||||
FlagC = Reg16_d.Bit(8);
|
||||
FlagZ = (Reg16_d & 0xFF) == 0;
|
||||
|
||||
ushort ans = (ushort)(Reg16_d & 0xFF);
|
||||
|
||||
FlagO = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
|
||||
FlagS = ans > 127;
|
||||
|
||||
Regs[dest] = ans;
|
||||
}
|
||||
|
||||
/*
|
||||
public void ALU_SUB8_Func(ushort dest, ushort src)
|
||||
{
|
||||
int Reg16_d = Regs[dest];
|
||||
Reg16_d -= Regs[src];
|
||||
|
||||
FlagC = Reg16_d.Bit(8);
|
||||
FlagZ = (Reg16_d & 0xFF) == 0;
|
||||
|
||||
ushort ans = (ushort)(Reg16_d & 0xFF);
|
||||
|
||||
FlagO = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
|
||||
FlagS = ans > 127;
|
||||
|
||||
Regs[dest] = ans;
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Right shift 'src' 'shift' positions (zero fill)
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="shift"></param>
|
||||
public void ALU_SR_Func(ushort src, ushort shift)
|
||||
{
|
||||
Regs[src] = (ushort)((Regs[src] >> shift) & 0xFF);
|
||||
ALU_ClearFlags();
|
||||
ALU_SetFlags_SZ(src);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Left shit 'src' 'shift' positions (zero fill)
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="shift"></param>
|
||||
public void ALU_SL_Func(ushort src, ushort shift)
|
||||
{
|
||||
Regs[src] = (ushort)((Regs[src] << shift) & 0xFF);
|
||||
ALU_ClearFlags();
|
||||
ALU_SetFlags_SZ(src);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AND
|
||||
/// </summary>
|
||||
/// <param name="dest"></param>
|
||||
/// <param name="src"></param>
|
||||
public void ALU_AND8_Func(ushort dest, ushort src)
|
||||
{
|
||||
ALU_ClearFlags();
|
||||
Regs[dest] = (ushort)(Regs[dest] & Regs[src]);
|
||||
ALU_SetFlags_SZ(dest);
|
||||
}
|
||||
|
||||
public void ALU_OR8_Func(ushort dest, ushort src)
|
||||
{
|
||||
ALU_ClearFlags();
|
||||
Regs[dest] = (ushort)(Regs[dest] | Regs[src]);
|
||||
ALU_SetFlags_SZ(dest);
|
||||
}
|
||||
|
||||
public void ALU_XOR8_Func(ushort dest, ushort src)
|
||||
{
|
||||
ALU_ClearFlags();
|
||||
Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]);
|
||||
ALU_SetFlags_SZ(dest);
|
||||
}
|
||||
/*
|
||||
public void ALU_XOR8C_Func(ushort dest, ushort src)
|
||||
{
|
||||
// TODO
|
||||
Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]);
|
||||
FlagZ = Regs[dest] == 0;
|
||||
FlagC = false;
|
||||
FlagO = false;
|
||||
FlagS = Regs[dest] > 127;
|
||||
}
|
||||
*/
|
||||
|
||||
public void ADDS_FuncX(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
int Reg16_d = Regs[dest_l];
|
||||
int Reg16_s = Regs[src_l];
|
||||
|
||||
Reg16_d += Reg16_s;
|
||||
|
||||
ushort temp = 0;
|
||||
|
||||
// since this is signed addition, calculate the high byte carry appropriately
|
||||
// note that flags are unaffected by this operation
|
||||
if (Reg16_s.Bit(7))
|
||||
{
|
||||
if (((Reg16_d & 0xFF) >= Regs[dest_l]))
|
||||
{
|
||||
temp = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (ushort)(Reg16_d.Bit(8) ? 1 : 0);
|
||||
}
|
||||
|
||||
ushort ans_l = (ushort)(Reg16_d & 0xFF);
|
||||
|
||||
Regs[dest_l] = ans_l;
|
||||
Regs[dest_h] += temp;
|
||||
Regs[dest_h] &= 0xFF;
|
||||
}
|
||||
|
||||
public void Read_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
}
|
||||
|
||||
public void Write_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
}
|
||||
|
||||
public void LR8_Func(ushort dest, ushort src)
|
||||
{
|
||||
if (dest == DB)
|
||||
{
|
||||
// byte storage
|
||||
Regs[dest] = (ushort)(Regs[src] & 0xFF);
|
||||
}
|
||||
else if (dest == W)
|
||||
{
|
||||
// mask for status register
|
||||
Regs[dest] = (ushort)(Regs[src] & 0x1F);
|
||||
}
|
||||
else if (dest == ISAR)
|
||||
{
|
||||
// mask for ISAR register
|
||||
Regs[dest] = (ushort)(Regs[src] & 0x3F);
|
||||
}
|
||||
else
|
||||
{
|
||||
Regs[dest] = Regs[src];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void ALU_INC8_Func(ushort src)
|
||||
{
|
||||
int Reg16_d = Regs[src];
|
||||
Reg16_d += 1;
|
||||
|
||||
FlagC = Reg16_d.Bit(8);
|
||||
FlagZ = (Reg16_d & 0xFF) == 0;
|
||||
|
||||
ushort ans = (ushort)(Reg16_d & 0xFF);
|
||||
|
||||
Regs[src] = ans;
|
||||
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagO = Regs[src] == 0x80;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -19,7 +19,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
//n immediate succeeds the opcode and the displacement (if present)
|
||||
//nn immediately succeeds the opcode and the displacement (if present)
|
||||
|
||||
if (format.IndexOf("nn") != -1) format = format.Replace("nn", $"{read(addr++) << 8 + (read(addr++)):X4}h"); // MSB is read first
|
||||
if (format.IndexOf("nn") != -1)
|
||||
{
|
||||
format = format.Replace("nn", read(addr++)
|
||||
.ToString("X2") + read(addr++)
|
||||
.ToString("X2") + "h"); // MSB is read first
|
||||
}
|
||||
|
||||
if (format.IndexOf("n") != -1) format = format.Replace("n", $"{read(addr++):X2}h");
|
||||
|
||||
if (format.IndexOf("+d") != -1) format = format.Replace("+d", "d");
|
||||
|
@ -67,13 +73,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
"LR W, J", // 0x1D
|
||||
"LR J, W", // 0x1E
|
||||
"INC", // 0x1F
|
||||
"LI n", // 0x20
|
||||
"NI n", // 0x21
|
||||
"IO n", // 0x22
|
||||
"XI n", // 0x23
|
||||
"AI n", // 0x24
|
||||
"CI n", // 0x25
|
||||
"IN n", // 0x26
|
||||
"LI n", // 0x20
|
||||
"NI n", // 0x21
|
||||
"OI n", // 0x22
|
||||
"XI n", // 0x23
|
||||
"AI n", // 0x24
|
||||
"CI n", // 0x25
|
||||
"IN n", // 0x26
|
||||
"OUT n", // 0x27
|
||||
"PI nn", // 0x28
|
||||
"JMP nn", // 0x29
|
||||
|
@ -111,9 +117,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
"LR A, r09", // 0x49
|
||||
"LR A, r10", // 0x4A
|
||||
"LR A, r11", // 0x4B
|
||||
"LR A, ISAR", // 0x4C
|
||||
"LR A, ISAR INC", // 0x4D
|
||||
"LR A, ISAR DEC", // 0x4E
|
||||
"LR A, (ISAR)", // 0x4C
|
||||
"LR A, (ISAR) INC", // 0x4D
|
||||
"LR A, (ISAR) DEC", // 0x4E
|
||||
"ILLEGAL", // 0x4F
|
||||
"LR r00, A", // 0x50
|
||||
"LR r01, A", // 0x51
|
||||
|
@ -131,46 +137,46 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
"LR (ISAR), A INC", // 0x5D
|
||||
"LR (ISAR), A DEC", // 0x5E
|
||||
"ILLEGAL", // 0x5F
|
||||
"LISU 0x00", // 0x60
|
||||
"LISU 0x08", // 0x61
|
||||
"LISU 0x10", // 0x62
|
||||
"LISU 0x18", // 0x63
|
||||
"LISU 0x20", // 0x64
|
||||
"LISU 0x28", // 0x65
|
||||
"LISU 0x30", // 0x66
|
||||
"LISU 0x38", // 0x67
|
||||
"LISU 0x00", // 0x68
|
||||
"LISU 0x01", // 0x69
|
||||
"LISU 0x02", // 0x6A
|
||||
"LISU 0x03", // 0x6B
|
||||
"LISU 0x04", // 0x6C
|
||||
"LISU 0x05", // 0x6D
|
||||
"LISU 0x06", // 0x6E
|
||||
"LISU 0x07", // 0x6F
|
||||
"LIS 0x0", // 0x70
|
||||
"LIS 0x01", // 0x71
|
||||
"LIS 0x2", // 0x72
|
||||
"LIS 0x3", // 0x73
|
||||
"LIS 0x4", // 0x74
|
||||
"LIS 0x5", // 0x75
|
||||
"LIS 0x6", // 0x76
|
||||
"LIS 0x7", // 0x77
|
||||
"LIS 0x8", // 0x78
|
||||
"LIS 0x9", // 0x79
|
||||
"LIS 0xA", // 0x7A
|
||||
"LIS 0xB", // 0x7B
|
||||
"LIS 0xC", // 0x7C
|
||||
"LIS 0xD", // 0x7D
|
||||
"LIS 0xE", // 0x7E
|
||||
"LIS 0xF", // 0x7F
|
||||
"BT 0", // 0x80
|
||||
"BT 1", // 0x81
|
||||
"BT 2", // 0x82
|
||||
"BT 3", // 0x83
|
||||
"BT 4", // 0x84
|
||||
"BT 5", // 0x85
|
||||
"BT 6", // 0x86
|
||||
"BT 7", // 0x87
|
||||
"LISU 0", // 0x60
|
||||
"LISU 1", // 0x61
|
||||
"LISU 2", // 0x62
|
||||
"LISU 3", // 0x63
|
||||
"LISU 4", // 0x64
|
||||
"LISU 5", // 0x65
|
||||
"LISU 6", // 0x66
|
||||
"LISU 7", // 0x67
|
||||
"LISL 0", // 0x68
|
||||
"LISL 1", // 0x69
|
||||
"LISL 2", // 0x6A
|
||||
"LISL 3", // 0x6B
|
||||
"LISL 4", // 0x6C
|
||||
"LISL 5", // 0x6D
|
||||
"LISL 6", // 0x6E
|
||||
"LISL 7", // 0x6F
|
||||
"LIS 0", // 0x70
|
||||
"LIS 1", // 0x71
|
||||
"LIS 2", // 0x72
|
||||
"LIS 3", // 0x73
|
||||
"LIS 4", // 0x74
|
||||
"LIS 5", // 0x75
|
||||
"LIS 6", // 0x76
|
||||
"LIS 7", // 0x77
|
||||
"LIS 8", // 0x78
|
||||
"LIS 9", // 0x79
|
||||
"LIS A", // 0x7A
|
||||
"LIS B", // 0x7B
|
||||
"LIS C", // 0x7C
|
||||
"LIS D", // 0x7D
|
||||
"LIS E", // 0x7E
|
||||
"LIS F", // 0x7F
|
||||
"BT NOBRANCH", // 0x80
|
||||
"BP d", // 0x81
|
||||
"BC d", // 0x82
|
||||
"BP or C d", // 0x83
|
||||
"BZ d", // 0x84
|
||||
"BP d", // 0x85
|
||||
"BZ or C d", // 0x86
|
||||
"BP or C d", // 0x87
|
||||
"AM", // 0x88
|
||||
"AMD", // 0x89
|
||||
"NM", // 0x8A
|
||||
|
@ -179,22 +185,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
"CM", // 0x8D
|
||||
"ADC", // 0x8E
|
||||
"BR7 n", // 0x8F
|
||||
"BF 0x0 n", // 0x90
|
||||
"BF 0x1 n", // 0x91
|
||||
"BF 0x2 n", // 0x92
|
||||
"BF 0x3 n", // 0x93
|
||||
"BF 0x4 n", // 0x94
|
||||
"BF 0x5 n", // 0x95
|
||||
"BF 0x6 n", // 0x96
|
||||
"BF 0x7 n", // 0x97
|
||||
"BF 0x8 n", // 0x98
|
||||
"BF 0x9 n", // 0x99
|
||||
"BF 0xA n", // 0x9A
|
||||
"BF 0xB n", // 0x9B
|
||||
"BF 0xC n", // 0x9C
|
||||
"BF 0xD n", // 0x9D
|
||||
"BF 0xE n", // 0x9E
|
||||
"BF 0xF n", // 0x9F
|
||||
"BF UNCON d", // 0x90
|
||||
"BN d", // 0x91
|
||||
"BNC d", // 0x92
|
||||
"BNC & deg d", // 0x93
|
||||
"BNZ d", // 0x94
|
||||
"BN d", // 0x95
|
||||
"BNC & dZ d", // 0x96
|
||||
"BNC & deg d", // 0x97
|
||||
"BNO d", // 0x98
|
||||
"BN & dO d", // 0x99
|
||||
"BNO & dC d", // 0x9A
|
||||
"BNO & dC & deg d", // 0x9B
|
||||
"BNO & dZ d", // 0x9C
|
||||
"BN & dO d", // 0x9D
|
||||
"BNO & dC & dZ d", // 0x9E
|
||||
"BNO & dC & deg d", // 0x9F
|
||||
"INS 0", // 0xA0
|
||||
"INS 1", // 0xA1
|
||||
"ILLEGAL", // 0xA2
|
||||
|
|
|
@ -15,8 +15,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public long TotalExecutedCycles;
|
||||
|
||||
public int instr_pntr = 0;
|
||||
public ushort[] cur_instr = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime
|
||||
public ushort[] cur_romc = new ushort[MaxInstructionLength]; // fixed size - do not change at runtime
|
||||
public byte[] cur_instr = new byte[MaxInstructionLength]; // fixed size - do not change at runtime
|
||||
public byte[] cur_romc = new byte[MaxInstructionLength]; // fixed size - do not change at runtime
|
||||
public byte opcode;
|
||||
|
||||
public void FetchInstruction()
|
||||
|
@ -119,22 +119,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
case 0x5D: LR_ISAR_A_INC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR incremented
|
||||
case 0x5E: LR_ISAR_A_DEC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR decremented
|
||||
|
||||
case 0x60: LISU(0); break; // ISARU <- 0'e' (octal)
|
||||
case 0x61: LISU(8); break; // ISARU <- 0'e' (octal)
|
||||
case 0x62: LISU(16); break; // ISARU <- 0'e' (octal)
|
||||
case 0x63: LISU(24); break; // ISARU <- 0'e' (octal)
|
||||
case 0x64: LISU(32); break; // ISARU <- 0'e' (octal)
|
||||
case 0x65: LISU(40); break; // ISARU <- 0'e' (octal)
|
||||
case 0x66: LISU(48); break; // ISARU <- 0'e' (octal)
|
||||
case 0x67: LISU(56); break; // ISARU <- 0'e' (octal)
|
||||
case 0x68: LISL(0); break; // ISARL <- 0'e' (octal)
|
||||
case 0x69: LISL(1); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal)
|
||||
case 0x60: LISU(0); break; // ISARU <- 0'e' (octal)
|
||||
case 0x61: LISU(1); break; // ISARU <- 0'e' (octal)
|
||||
case 0x62: LISU(2); break; // ISARU <- 0'e' (octal)
|
||||
case 0x63: LISU(3); break; // ISARU <- 0'e' (octal)
|
||||
case 0x64: LISU(4); break; // ISARU <- 0'e' (octal)
|
||||
case 0x65: LISU(5); break; // ISARU <- 0'e' (octal)
|
||||
case 0x66: LISU(6); break; // ISARU <- 0'e' (octal)
|
||||
case 0x67: LISU(7); break; // ISARU <- 0'e' (octal)
|
||||
case 0x68: LISL(0); break; // ISARL <- 0'e' (octal)
|
||||
case 0x69: LISL(1); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal)
|
||||
|
||||
case 0x70: LIS(0); break; // A <- H'0a'
|
||||
case 0x71: LIS(1); break; // A <- H'0a'
|
||||
|
@ -152,14 +152,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
case 0x7d: LIS(13); break; // A <- H'0a'
|
||||
case 0x7e: LIS(14); break; // A <- H'0a'
|
||||
case 0x7f: LIS(15); break; // A <- H'0a'
|
||||
case 0x80: BT(0); break; // Test operand against W (Branching instruction)
|
||||
case 0x81: BT(1); break; // Test operand against W (Branching instruction)
|
||||
case 0x82: BT(2); break; // Test operand against W (Branching instruction)
|
||||
case 0x83: BT(3); break; // Test operand against W (Branching instruction)
|
||||
case 0x84: BT(4); break; // Test operand against W (Branching instruction)
|
||||
case 0x85: BT(5); break; // Test operand against W (Branching instruction)
|
||||
case 0x86: BT(6); break; // Test operand against W (Branching instruction)
|
||||
case 0x87: BT(7); break; // Test operand against W (Branching instruction)
|
||||
case 0x80: BT(0); break; // Branch on true - test operand against W register
|
||||
case 0x81: BT(1); break; // Branch if positive (sign bit is set)
|
||||
case 0x82: BT(2); break; // Branch on carry (carry bit is set)
|
||||
case 0x83: BT(3); break; // Branch on true - test operand against W register
|
||||
case 0x84: BT(4); break; // Branch on zero (zero bit is set)
|
||||
case 0x85: BT(5); break; // Branch on true - test operand against W register
|
||||
case 0x86: BT(6); break; // Branch on true - test operand against W register
|
||||
case 0x87: BT(7); break; // Branch on true - test operand against W register
|
||||
case 0x88: AM(); break; // A <- (A) + ((DC0))Binary; DC0 <- (DC0) + 1
|
||||
case 0x89: AMD(); break; // A <- (A) + ((DC0))Decimal; DC0 <- (DC0) + 1
|
||||
case 0x8A: NM(); break; // A <- (A) AND ((DC0)); DC0 <- (DC0) + 1
|
||||
|
@ -167,23 +167,23 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
case 0x8C: XM(); break; // A <- (A) XOR ((DC0)); DC0 <- (DC0) + 1
|
||||
case 0x8D: CM(); break; // Set status flags on basis of: ((DC)) + (A) + 1; DC0 <- (DC0) + 1; DC <- (DC) + (A)
|
||||
case 0x8E: ADC(); break; // DC <- (DC) + (A)
|
||||
case 0x8F: BR7(); break; // DC <- (DC) + (A)
|
||||
case 0x90: BF(0); break; // PC0 <- PC0+n+1
|
||||
case 0x91: BF(1); break; // PC0 <- PC0+n+1
|
||||
case 0x92: BF(2); break; // PC0 <- PC0+n+1
|
||||
case 0x93: BF(3); break; // PC0 <- PC0+n+1
|
||||
case 0x94: BF(4); break; // PC0 <- PC0+n+1
|
||||
case 0x95: BF(5); break; // PC0 <- PC0+n+1
|
||||
case 0x96: BF(6); break; // PC0 <- PC0+n+1
|
||||
case 0x97: BF(7); break; // PC0 <- PC0+n+1
|
||||
case 0x98: BF(8); break; // PC0 <- PC0+n+1
|
||||
case 0x99: BF(9); break; // PC0 <- PC0+n+1
|
||||
case 0x9A: BF(10); break; // PC0 <- PC0+n+1
|
||||
case 0x9B: BF(11); break; // PC0 <- PC0+n+1
|
||||
case 0x9C: BF(12); break; // PC0 <- PC0+n+1
|
||||
case 0x9D: BF(13); break; // PC0 <- PC0+n+1
|
||||
case 0x9E: BF(14); break; // PC0 <- PC0+n+1
|
||||
case 0x9F: BF(15); break; // PC0 <- PC0+n+1
|
||||
case 0x8F: BR7(); break; // Branch on ISAR (any of the low 3 bits of ISAR are reset)
|
||||
case 0x90: BF(0); break; // Unconditional branch (always)
|
||||
case 0x91: BF(1); break; // Branch if negative (sign bit is reset)
|
||||
case 0x92: BF(2); break; // Branch if no carry (carry bit is reset)
|
||||
case 0x93: BF(3); break; // Branch on false - test operand against W register
|
||||
case 0x94: BF(4); break; // Branch on not zero (zero bit is reset)
|
||||
case 0x95: BF(5); break; // Branch on false - test operand against W register
|
||||
case 0x96: BF(6); break; // Branch on false - test operand against W register
|
||||
case 0x97: BF(7); break; // Branch on false - test operand against W register
|
||||
case 0x98: BF(8); break; // Branch if no overflow (OVF bit is reset)
|
||||
case 0x99: BF(9); break; // Branch on false - test operand against W register
|
||||
case 0x9A: BF(10); break; // Branch on false - test operand against W register
|
||||
case 0x9B: BF(11); break; // Branch on false - test operand against W register
|
||||
case 0x9C: BF(12); break; // Branch on false - test operand against W register
|
||||
case 0x9D: BF(13); break; // Branch on false - test operand against W register
|
||||
case 0x9E: BF(14); break; // Branch on false - test operand against W register
|
||||
case 0x9F: BF(15); break; // Branch on false - test operand against W register
|
||||
case 0xA0: INS_0(0); break; // A <- (I/O Port 0 or 1)
|
||||
case 0xA1: INS_0(1); break; // A <- (I/O Port 0 or 1)
|
||||
|
||||
|
|
|
@ -0,0 +1,299 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// ALU Operations
|
||||
/// </summary>
|
||||
public sealed partial class F3850
|
||||
{
|
||||
public void Read_Func(byte dest, byte src_l, byte src_h)
|
||||
{
|
||||
Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
}
|
||||
|
||||
public void Write_Func(byte dest_l, byte dest_h, byte src)
|
||||
{
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), Regs[src]);
|
||||
}
|
||||
|
||||
public void IN_Func(byte dest, byte src)
|
||||
{
|
||||
Regs[dest] = ReadHardware(Regs[src]);
|
||||
}
|
||||
|
||||
public void LR_A_IO_Func(byte dest, byte src)
|
||||
{
|
||||
// helper method that simulates transferring DB to accumulator (as part of an IN operation)
|
||||
// this sets flags accordingly
|
||||
// dest should always == A and src should always == DB for this function
|
||||
|
||||
// overflow and carry unconditionally reset
|
||||
FlagO = false;
|
||||
FlagC = false;
|
||||
|
||||
Regs[dest] = Regs[src];
|
||||
|
||||
FlagZ = Regs[dest] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[dest].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
}
|
||||
|
||||
public void ClearFlags_Func()
|
||||
{
|
||||
FlagC = false;
|
||||
FlagO = false;
|
||||
FlagS = false;
|
||||
FlagZ = false;
|
||||
}
|
||||
|
||||
public void LR_Func(byte dest, byte src)
|
||||
{
|
||||
if (dest == DB)
|
||||
{
|
||||
// byte storage
|
||||
Regs[dest] = (byte)(Regs[src] & 0xFF);
|
||||
}
|
||||
else if (dest == W)
|
||||
{
|
||||
// mask for status register
|
||||
Regs[dest] = (byte)(Regs[src] & 0x1F);
|
||||
}
|
||||
else if (dest == ISAR)
|
||||
{
|
||||
// mask for ISAR register
|
||||
Regs[dest] = (byte)(Regs[src] & 0x3F);
|
||||
}
|
||||
else
|
||||
{
|
||||
Regs[dest] = Regs[src];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Right shift 'src' 'shift' positions (zero fill)
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="shift"></param>
|
||||
public void SR_Func(byte src, byte shift)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
FlagO = false;
|
||||
FlagC = false;
|
||||
|
||||
Regs[src] = (byte)((Regs[src] >> shift) & 0xFF);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Left shit 'src' 'shift' positions (zero fill)
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="shift"></param>
|
||||
public void SL_Func(byte src, byte shift)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
FlagO = false;
|
||||
FlagC = false;
|
||||
|
||||
Regs[src] = (byte)((Regs[src] << shift) & 0xFF);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
}
|
||||
|
||||
public void ADD_Func_(byte dest, byte src)
|
||||
{
|
||||
// addition of 2 signed bytes
|
||||
ushort dest16 = Regs[dest];
|
||||
|
||||
dest16 += Regs[src];
|
||||
|
||||
FlagC = dest16.Bit(8);
|
||||
FlagZ = (dest16 & 0xFF) == 0;
|
||||
|
||||
ushort ans = (ushort)(dest16 & 0xFF);
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = ans.Bit(7) == false;
|
||||
|
||||
// overflow based on carry out of bit6 XOR carry out of bit7
|
||||
var b6c = dest16 >> 7;
|
||||
var b7c = dest16 >> 8;
|
||||
FlagO = (b6c ^ b7c) != 0;
|
||||
|
||||
Regs[dest] = (byte)ans;
|
||||
}
|
||||
|
||||
public void ADD_Func(byte dest, byte src)
|
||||
{
|
||||
// addition of 2 signed bytes
|
||||
var sD = Regs[dest] & 0x80;
|
||||
var sS = Regs[src] & 0x80;
|
||||
var res = Regs[dest] + Regs[src];
|
||||
var sR = res & 0x80;
|
||||
|
||||
FlagS = !((res & 0x80) > 0);
|
||||
FlagZ = (res & 0xff) == 0;
|
||||
FlagO = (sD == sS && sD != sR);
|
||||
FlagC = (res & 0x100) > 0;
|
||||
|
||||
Regs[dest] = (byte) (res & 0xff);
|
||||
}
|
||||
|
||||
public void SUB_Func(byte dest, byte src)
|
||||
{
|
||||
Regs[ALU0] = (byte)((Regs[src] ^ 0xff) + 1);
|
||||
ADD_Func(dest, ALU0);
|
||||
}
|
||||
|
||||
public void ADDD_Func(byte dest, byte src)
|
||||
{
|
||||
var d = Regs[dest];
|
||||
var s = Regs[src];
|
||||
var bcdRes = d + s;
|
||||
|
||||
var carryIntermediate = ((d & 0x0F) + (s & 0x0F)) > 0x0F;
|
||||
var carryUpper = bcdRes >= 0x100;
|
||||
|
||||
// temporary storage and set flags
|
||||
Regs[ALU0] = Regs[dest];
|
||||
Regs[ALU1] = Regs[src];
|
||||
ADD_Func(ALU0, ALU1);
|
||||
|
||||
if (!carryIntermediate)
|
||||
{
|
||||
bcdRes = (bcdRes & 0xF0) | ((bcdRes + 0x0A) & 0x0F);
|
||||
}
|
||||
|
||||
if (!carryUpper)
|
||||
{
|
||||
bcdRes = (bcdRes + 0xA0);
|
||||
}
|
||||
|
||||
Regs[dest] = (byte)(bcdRes & 0xFF);
|
||||
}
|
||||
|
||||
public void CI_Func()
|
||||
{
|
||||
// compare immediate
|
||||
// we need to achieve DB - A + 1
|
||||
// flags set - results not stored
|
||||
var comp = ((Regs[A] ^ 0xFF) + 1);
|
||||
Regs[ALU0] = (byte)comp;
|
||||
Regs[ALU1] = Regs[DB];
|
||||
ADD_Func(ALU1, ALU0);
|
||||
}
|
||||
/*
|
||||
public void ADDD_Func_(ushort dest, ushort src)
|
||||
{
|
||||
// from MAME f8.cpp (BSD-3)
|
||||
// https://github.com/mamedev/mame/blob/97b67170277437131adf6ed4d60139c172529e4f/src/devices/cpu/f8/f8.cpp#L264
|
||||
byte d = (byte)Regs[dest];
|
||||
byte s = (byte)Regs[src];
|
||||
byte tmp = (byte)(d + s);
|
||||
|
||||
byte c = 0; // high order carry
|
||||
byte ic = 0; // low order carry
|
||||
|
||||
if (((d + s) & 0xFF0) > 0xF0)
|
||||
{
|
||||
c = 1;
|
||||
}
|
||||
|
||||
if ((d & 0x0F) + (s & 0x0F) > 0x0F)
|
||||
{
|
||||
ic = 1;
|
||||
}
|
||||
|
||||
//ALU_ClearFlags();
|
||||
ALU_ADD8_FLAGSONLY_Func(dest, src);
|
||||
Regs[ALU0] = tmp;
|
||||
//ALU_SetFlags_SZ(ALU0);
|
||||
|
||||
if (c == 0 && ic == 0)
|
||||
{
|
||||
tmp = (byte)(((tmp + 0xa0) & 0xf0) + ((tmp + 0x0a) & 0x0f));
|
||||
}
|
||||
|
||||
if (c == 0 && ic == 1)
|
||||
{
|
||||
tmp = (byte)(((tmp + 0xa0) & 0xf0) + (tmp & 0x0f));
|
||||
}
|
||||
|
||||
if (c == 1 && ic == 0)
|
||||
{
|
||||
tmp = (byte)((tmp & 0xf0) + ((tmp + 0x0a) & 0x0f));
|
||||
}
|
||||
|
||||
Regs[dest] = tmp;
|
||||
}
|
||||
*/
|
||||
|
||||
public void AND_Func(byte dest, byte src)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
FlagO = false;
|
||||
FlagC = false;
|
||||
|
||||
Regs[dest] = (byte)(Regs[dest] & Regs[src]);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
}
|
||||
|
||||
public void OR_Func(byte dest, byte src)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
FlagO = false;
|
||||
FlagC = false;
|
||||
|
||||
Regs[dest] = (byte)(Regs[dest] | Regs[src]);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
}
|
||||
|
||||
public void XOR_Func(byte dest, byte src)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
FlagO = false;
|
||||
FlagC = false;
|
||||
|
||||
Regs[dest] = (byte)(Regs[dest] ^ Regs[src]);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,83 +17,83 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
/// <summary>
|
||||
/// Registers (counters and scratchpad)
|
||||
/// </summary>
|
||||
public ushort[] Regs = new ushort[100];
|
||||
public byte[] Regs = new byte[100];
|
||||
|
||||
// scratchpad registers live in Regs 0-64
|
||||
public ushort J = 9;
|
||||
public ushort Hh = 10;
|
||||
public ushort Hl = 11;
|
||||
public ushort Kh = 12;
|
||||
public ushort Kl = 13;
|
||||
public ushort Qh = 14;
|
||||
public ushort Ql = 15;
|
||||
public byte J = 9;
|
||||
public byte Hh = 10;
|
||||
public byte Hl = 11;
|
||||
public byte Kh = 12;
|
||||
public byte Kl = 13;
|
||||
public byte Qh = 14;
|
||||
public byte Ql = 15;
|
||||
|
||||
// Internal CPU counters kept after the scratchpad for ease of implementation
|
||||
/// <summary>
|
||||
/// Accumulator
|
||||
/// </summary>
|
||||
public ushort A = 65;
|
||||
public byte A = 65;
|
||||
/// <summary>
|
||||
/// Status Register
|
||||
/// </summary>
|
||||
public ushort W = 66;
|
||||
public byte W = 66;
|
||||
/// <summary>
|
||||
/// Indirect Scratchpad Address Register
|
||||
/// (6bit)
|
||||
/// </summary>
|
||||
public ushort ISAR = 67;
|
||||
public byte ISAR = 67;
|
||||
/// <summary>
|
||||
/// Primary Program Counter (high byte)
|
||||
/// </summary>
|
||||
public ushort PC0h = 68;
|
||||
public byte PC0h = 68;
|
||||
/// <summary>
|
||||
/// Primary Program Counter (low byte)
|
||||
/// </summary>
|
||||
public ushort PC0l = 69;
|
||||
public byte PC0l = 69;
|
||||
/// <summary>
|
||||
/// Backup Program Counter (high byte)
|
||||
/// </summary>
|
||||
public ushort PC1h = 70;
|
||||
public byte PC1h = 70;
|
||||
/// <summary>
|
||||
/// Backup Program Counter (low byte)
|
||||
/// </summary>
|
||||
public ushort PC1l = 71;
|
||||
public byte PC1l = 71;
|
||||
/// <summary>
|
||||
/// Data counter (high byte)
|
||||
/// </summary>
|
||||
public ushort DC0h = 72;
|
||||
public byte DC0h = 72;
|
||||
/// <summary>
|
||||
/// Data Counter (low byte)
|
||||
/// </summary>
|
||||
public ushort DC0l = 73;
|
||||
public byte DC0l = 73;
|
||||
/// <summary>
|
||||
/// Temporary Arithmetic Storage
|
||||
/// </summary>
|
||||
public ushort ALU0 = 74;
|
||||
public byte ALU0 = 74;
|
||||
/// <summary>
|
||||
/// Temporary Arithmetic Storage
|
||||
/// </summary>
|
||||
public ushort ALU1 = 75;
|
||||
public byte ALU1 = 75;
|
||||
/// <summary>
|
||||
/// Data Bus
|
||||
/// </summary>
|
||||
public ushort DB = 76;
|
||||
public byte DB = 76;
|
||||
/// <summary>
|
||||
/// IO Bus/Latch
|
||||
/// </summary>
|
||||
public ushort IO = 77;
|
||||
public byte IO = 77;
|
||||
/// <summary>
|
||||
/// 0x00 value for arithmetic ops
|
||||
/// </summary>
|
||||
public ushort ZERO = 78;
|
||||
public byte ZERO = 78;
|
||||
/// <summary>
|
||||
/// 0x01 value for arithmetic ops
|
||||
/// </summary>
|
||||
public ushort ONE = 79;
|
||||
public byte ONE = 79;
|
||||
/// <summary>
|
||||
/// 0xFF value for arithmetic ops
|
||||
/// </summary>
|
||||
public ushort BYTE = 80;
|
||||
public byte BYTE = 80;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -102,7 +102,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public bool FlagS
|
||||
{
|
||||
get { return (Regs[W] & 0x01) != 0; }
|
||||
set { Regs[W] = (ushort)((Regs[W] & ~0x01) | (value ? 0x01 : 0x00)); }
|
||||
set { Regs[W] = (byte)((Regs[W] & ~0x01) | (value ? 0x01 : 0x00)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -111,7 +111,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public bool FlagC
|
||||
{
|
||||
get { return (Regs[W] & 0x02) != 0; }
|
||||
set { Regs[W] = (ushort)((Regs[W] & ~0x02) | (value ? 0x02 : 0x00)); }
|
||||
set { Regs[W] = (byte)((Regs[W] & ~0x02) | (value ? 0x02 : 0x00)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -120,7 +120,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public bool FlagZ
|
||||
{
|
||||
get { return (Regs[W] & 0x04) != 0; }
|
||||
set { Regs[W] = (ushort)((Regs[W] & ~0x04) | (value ? 0x04 : 0x00)); }
|
||||
set { Regs[W] = (byte)((Regs[W] & ~0x04) | (value ? 0x04 : 0x00)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -129,7 +129,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public bool FlagO
|
||||
{
|
||||
get { return (Regs[W] & 0x08) != 0; }
|
||||
set { Regs[W] = (ushort)((Regs[W] & ~0x08) | (value ? 0x08 : 0x00)); }
|
||||
set { Regs[W] = (byte)((Regs[W] & ~0x08) | (value ? 0x08 : 0x00)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -138,7 +138,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public bool FlagICB
|
||||
{
|
||||
get { return (Regs[W] & 0x10) != 0; }
|
||||
set { Regs[W] = (ushort)((Regs[W] & ~0x10) | (value ? 0x10 : 0x00)); }
|
||||
set { Regs[W] = (byte)((Regs[W] & ~0x10) | (value ? 0x10 : 0x00)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -149,8 +149,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
get { return (ushort)(Regs[PC0l] | (Regs[PC0h] << 8)); }
|
||||
set
|
||||
{
|
||||
Regs[PC0l] = (ushort)(value & 0xFF);
|
||||
Regs[PC0h] = (ushort)((value >> 8) & 0xFF);
|
||||
Regs[PC0l] = (byte)(value & 0xFF);
|
||||
Regs[PC0h] = (byte)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,8 +162,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
get { return (ushort)(Regs[PC1l] | (Regs[PC1h] << 8)); }
|
||||
set
|
||||
{
|
||||
Regs[PC1l] = (ushort)(value & 0xFF);
|
||||
Regs[PC1h] = (ushort)((value >> 8) & 0xFF);
|
||||
Regs[PC1l] = (byte)(value & 0xFF);
|
||||
Regs[PC1h] = (byte)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,8 +175,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
get { return (ushort)(Regs[DC0l] | (Regs[DC0h] << 8)); }
|
||||
set
|
||||
{
|
||||
Regs[DC0l] = (ushort)(value & 0xFF);
|
||||
Regs[DC0h] = (ushort)((value >> 8) & 0xFF);
|
||||
Regs[DC0l] = (byte)(value & 0xFF);
|
||||
Regs[DC0h] = (byte)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,6 +189,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
Regs[ONE] = 1;
|
||||
Regs[BYTE] = 0xFF;
|
||||
|
||||
// testing only - fill scratchpad with 0xff
|
||||
for (int i = 0; i < 64; i++)
|
||||
Regs[i] = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,8 +190,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
OP_LR8, DB, Ql, // DB <- (r15)
|
||||
IDLE,
|
||||
OP_LR8, DB, Ql, // DB <- (r15)
|
||||
OP_EI, // Set ICB Flag
|
||||
IDLE,
|
||||
ROMC_17, // PC0l <- (DB)
|
||||
IDLE,
|
||||
|
@ -306,7 +306,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void SHIFT_R(ushort index)
|
||||
private void SHIFT_R(byte index)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
|
@ -316,7 +316,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void SHIFT_L(ushort index)
|
||||
private void SHIFT_L(byte index)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
|
@ -364,7 +364,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_COM, // A <- A XOR 0xFF (compliment accumulator)
|
||||
OP_XOR8, A, BYTE, // A <- A XOR 0xFF (compliment accumulator)
|
||||
//OP_COM, // A <- A XOR 0xFF (compliment accumulator)
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
END);
|
||||
|
@ -420,7 +421,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_EI, // Set ICB Flag
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
@ -435,7 +436,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_EI, // Set ICB Flag
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
@ -466,9 +467,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_03_L, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
IDLE, //OP_CLEAR_FLAGS,
|
||||
OP_LR8, A, DB, // A <- (DB)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE, //OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
|
@ -534,9 +535,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_03_L, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
IDLE,
|
||||
OP_ADD8, A, DB, // A <- (A) + (DB)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
|
@ -551,8 +552,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_03_L, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_CI, A, DB, // Set flags for A <- (A) + (DB) + 1 (do not store result in A)
|
||||
IDLE,
|
||||
OP_CI, // Set flags for A <- (DB) + (-A) + 1 (do not store result in A)
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
|
@ -580,16 +581,16 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
ROMC_03_L, // DB/IO <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// L
|
||||
ROMC_1B, // DB <- ((IO));
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP_LR8, A, DB, // A <- (DB)
|
||||
OP_LR_A_DB_IO, A, DB, // A <- (DB) - flags set as result of IN or INS operation
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
|
@ -616,7 +617,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_EI, // Set ICB Flag
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
@ -652,7 +653,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_EI, // Set ICB Flag
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
@ -683,7 +684,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_EI, // Set ICB Flag
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
@ -747,13 +748,17 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void DS(ushort rIndex)
|
||||
private void DS(byte rIndex)
|
||||
{
|
||||
// only scratch registers 0-16
|
||||
rIndex = (byte)(rIndex & 0x0F);
|
||||
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_ADD8, rIndex, BYTE,
|
||||
OP_SET_FLAGS_SZ, rIndex,
|
||||
IDLE,
|
||||
OP_SUB8, rIndex, ONE,
|
||||
//OP_ADD8, rIndex, BYTE,
|
||||
IDLE,
|
||||
ROMC_00_L, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
END);
|
||||
|
@ -762,9 +767,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff
|
||||
OP_SET_FLAGS_SZ, Regs[ISAR],
|
||||
IDLE,
|
||||
OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff
|
||||
IDLE,
|
||||
ROMC_00_L, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
END);
|
||||
|
@ -774,9 +779,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff
|
||||
OP_SET_FLAGS_SZ, Regs[ISAR],
|
||||
IDLE,
|
||||
OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff
|
||||
IDLE,
|
||||
OP_IS_INC, // Inc ISAR
|
||||
ROMC_00_L, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
|
@ -786,16 +791,19 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_ADD8, Regs[ISAR], BYTE, // r[ISAR] = r[ISAR] + 0xff
|
||||
OP_SET_FLAGS_SZ, Regs[ISAR],
|
||||
IDLE,
|
||||
OP_SUB8, Regs[ISAR], ONE, // r[ISAR] = r[ISAR] + 0xff
|
||||
IDLE,
|
||||
OP_IS_DEC, // Dec ISAR
|
||||
ROMC_00_L, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
}
|
||||
|
||||
private void LR_A_R(ushort rIndex)
|
||||
private void LR_A_R(byte rIndex)
|
||||
{
|
||||
// only scratch registers 0-16
|
||||
rIndex = (byte)(rIndex & 0x0F);
|
||||
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_LR8, A, rIndex, // A <- (rIndex)
|
||||
|
@ -834,8 +842,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void LR_R_A(ushort rIndex)
|
||||
private void LR_R_A(byte rIndex)
|
||||
{
|
||||
// only scratch registers 0-16
|
||||
rIndex = (byte)(rIndex & 0x0F);
|
||||
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_LR8, rIndex, A, // rIndex <- (A)
|
||||
|
@ -874,7 +885,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void LISU(ushort octal)
|
||||
private void LISU(byte octal)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
|
@ -884,7 +895,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void LISL(ushort octal)
|
||||
private void LISL(byte octal)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
|
@ -894,17 +905,17 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void LIS(ushort index)
|
||||
private void LIS(byte index)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_LR8, A, index, // A <- index
|
||||
OP_LIS, index, // A <- index
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
||||
private void BT(ushort index)
|
||||
private void BT(byte index)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
|
@ -918,11 +929,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
ROMC_02, // DB <- ((DC0)); DC0++
|
||||
OP_CLEAR_FLAGS,
|
||||
ROMC_02, // DB <- ((DC0)); DC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP_ADD8, A, DB, // A <- (DB)
|
||||
IDLE,
|
||||
OP_ADD8, A, DB, // A <- (DB)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
|
@ -954,9 +965,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_02, // DB <- ((DC0)); DC0++
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_AND8, A, DB, // A <- (A) AND (DB)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
OP_AND8, A, DB, // A <- (A) AND (DB)
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
|
@ -971,9 +982,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_02, // DB <- ((DC0)); DC0++
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_OR8, A, DB, // A <- (A) OR (DB)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
OP_OR8, A, DB, // A <- (A) OR (DB)
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
|
@ -988,9 +999,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_02, // DB <- ((DC0)); DC0++
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
IDLE,
|
||||
OP_XOR8, A, DB, // A <- (A) XOR (DB)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
|
@ -1005,7 +1016,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_02, // DB <- ((DC0)); DC0++
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
IDLE,
|
||||
OP_CI, A,
|
||||
IDLE,
|
||||
IDLE,
|
||||
|
@ -1039,7 +1050,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
OP_BR7); // no END as there is branching logic within OP_BR7
|
||||
}
|
||||
|
||||
private void BF(ushort index)
|
||||
private void BF(byte index)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
|
@ -1049,14 +1060,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
OP_BF, index); // no END as there is branching logic within OP_BF
|
||||
}
|
||||
|
||||
private void INS_0(ushort index)
|
||||
private void INS_0(byte index)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
ROMC_1C_S, // Idle
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_IN, A, index, // A <- ((Port index - 0/1))
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
OP_IN, A, index, // A <- ((Port index - 0/1))
|
||||
OP_LR_A_DB_IO, A, A, // A <- (A) - flags set as result of IN or INS operation
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
|
@ -1064,7 +1075,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void INS_1(ushort index)
|
||||
private void INS_1(byte index)
|
||||
{
|
||||
Regs[IO] = index; // latch port index early
|
||||
|
||||
|
@ -1079,9 +1090,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// L
|
||||
ROMC_1B, // DB <- ((IO))
|
||||
IDLE,
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_LR8, A, DB, // A <- (DB)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
OP_LR_A_DB_IO, A, DB, // A <- (DB) - flags set as result of IN or INS operation
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
|
@ -1090,7 +1101,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void OUTS_0(ushort index)
|
||||
private void OUTS_0(byte index)
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
|
@ -1105,7 +1116,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void OUTS_1(ushort index)
|
||||
private void OUTS_1(byte index)
|
||||
{
|
||||
Regs[IO] = index; // latch port index early
|
||||
|
||||
|
@ -1126,19 +1137,20 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
OP_EI, // Set ICB Flag
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
||||
private void AS(ushort rIndex)
|
||||
private void AS(byte rIndex)
|
||||
{
|
||||
ALU_ClearFlags(); // clear flags early (as not enough cycle space for commands)
|
||||
// only scratch registers 0-15
|
||||
rIndex = (byte) (rIndex & 0x0F);
|
||||
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_ADD8, A, rIndex, // A <- (A) + (rIndex)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
OP_ADD8, A, rIndex, // A <- (A) + (rIndex)
|
||||
IDLE,
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
}
|
||||
|
@ -1147,8 +1159,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_AS_IS, // A <- (A) + ((ISAR)); setSZ
|
||||
IDLE,
|
||||
OP_ADD8, A, Regs[ISAR], // A <- (A) + ((ISAR));
|
||||
IDLE,
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
|
@ -1158,8 +1170,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_AS_IS, // A <- (A) + ((ISAR)); setSZ
|
||||
IDLE,
|
||||
OP_ADD8, A, Regs[ISAR], // A <- (A) + ((ISAR));
|
||||
OP_IS_INC, // Inc ISAR
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
|
@ -1169,15 +1181,18 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_AS_IS, // A <- (A) + ((ISAR)); setSZ
|
||||
IDLE,
|
||||
OP_ADD8, A, Regs[ISAR], // A <- (A) + ((ISAR));
|
||||
OP_IS_DEC, // Dec ISAR
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
}
|
||||
|
||||
private void ASD(ushort rIndex)
|
||||
private void ASD(byte rIndex)
|
||||
{
|
||||
// only scratch registers 0-15
|
||||
rIndex = (byte)(rIndex & 0x0F);
|
||||
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
ROMC_1C_S, // Idle
|
||||
|
@ -1236,13 +1251,16 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
END);
|
||||
}
|
||||
|
||||
private void XS(ushort rIndex)
|
||||
private void XS(byte rIndex)
|
||||
{
|
||||
// only scratch registers 0-15
|
||||
rIndex = (byte)(rIndex & 0x0F);
|
||||
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_CLEAR_FLAGS,
|
||||
OP_XOR8, A, rIndex, // A <- (A) XOR (reg)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
OP_XOR8, A, rIndex, // A <- (A) XOR (reg)
|
||||
IDLE,
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
}
|
||||
|
@ -1251,7 +1269,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_XS_IS, // A <- (A) XOR ((ISAR))
|
||||
OP_XOR8, A, Regs[ISAR], // A <- (A) XOR ((ISAR))
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
END);
|
||||
|
@ -1261,7 +1279,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_XS_IS, // A <- (A) XOR ((ISAR))
|
||||
OP_XOR8, A, Regs[ISAR], // A <- (A) XOR ((ISAR))
|
||||
OP_IS_INC, // Inc ISAR
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
|
@ -1271,20 +1289,21 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_XS_IS, // A <- (A) XOR ((ISAR))
|
||||
OP_XOR8, A, Regs[ISAR], // A <- (A) XOR ((ISAR))
|
||||
OP_IS_DEC, // Dec ISAR
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
}
|
||||
|
||||
private void NS(ushort rIndex)
|
||||
private void NS(byte rIndex)
|
||||
{
|
||||
ALU_ClearFlags(); // clear flags early (as not enough cycle space for commands)
|
||||
// only scratch registers 0-15
|
||||
rIndex = (byte)(rIndex & 0x0F);
|
||||
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_AND8, A, rIndex, // A <- (A) AND (reg)
|
||||
OP_SET_FLAGS_SZ, A,
|
||||
IDLE,
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
END);
|
||||
}
|
||||
|
@ -1293,7 +1312,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_NS_IS, // A <- (A) AND ((ISAR))
|
||||
OP_AND8, A, Regs[ISAR], // A <- (A) AND ((ISAR))
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
END);
|
||||
|
@ -1303,7 +1322,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_NS_IS, // A <- (A) AND ((ISAR))
|
||||
OP_AND8, A, Regs[ISAR], // A <- (A) AND ((ISAR))
|
||||
OP_IS_INC, // Inc ISAR
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
|
@ -1314,11 +1333,44 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
OP_NS_IS, // A <- (A) AND ((ISAR))
|
||||
OP_AND8, A, Regs[ISAR], // A <- (A) AND ((ISAR))
|
||||
OP_IS_DEC, // Dec ISAR
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
||||
|
||||
private void DO_BRANCH()
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
IDLE,
|
||||
ROMC_01, // forward or backward displacement
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
|
||||
private void DONT_BRANCH()
|
||||
{
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
IDLE,
|
||||
ROMC_03_S, // immediate operand fetch
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BizHawk.Common;
|
||||
|
@ -39,73 +40,77 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public sealed partial class F3850
|
||||
{
|
||||
// operations that can take place in an instruction
|
||||
public const ushort ROMC_01 = 1;
|
||||
public const ushort ROMC_02 = 2;
|
||||
public const ushort ROMC_03_S = 3;
|
||||
public const ushort ROMC_04 = 4;
|
||||
public const ushort ROMC_05 = 5;
|
||||
public const ushort ROMC_06 = 6;
|
||||
public const ushort ROMC_07 = 7;
|
||||
public const ushort ROMC_08 = 8;
|
||||
public const ushort ROMC_09 = 9;
|
||||
public const ushort ROMC_0A = 10;
|
||||
public const ushort ROMC_0B = 11;
|
||||
public const ushort ROMC_0C = 12;
|
||||
public const ushort ROMC_0D = 13;
|
||||
public const ushort ROMC_0E = 14;
|
||||
public const ushort ROMC_0F = 15;
|
||||
public const ushort ROMC_10 = 16;
|
||||
public const ushort ROMC_11 = 17;
|
||||
public const ushort ROMC_12 = 18;
|
||||
public const ushort ROMC_13 = 19;
|
||||
public const ushort ROMC_14 = 20;
|
||||
public const ushort ROMC_15 = 21;
|
||||
public const ushort ROMC_16 = 22;
|
||||
public const ushort ROMC_17 = 23;
|
||||
public const ushort ROMC_18 = 24;
|
||||
public const ushort ROMC_19 = 25;
|
||||
public const ushort ROMC_1A = 26;
|
||||
public const ushort ROMC_1B = 27;
|
||||
public const ushort ROMC_1C_S = 28;
|
||||
public const ushort ROMC_1D = 29;
|
||||
public const ushort ROMC_1E = 30;
|
||||
public const ushort ROMC_1F = 31;
|
||||
public const ushort ROMC_00_S = 32;
|
||||
public const ushort ROMC_00_L = 33;
|
||||
public const ushort ROMC_03_L = 34;
|
||||
public const ushort ROMC_1C_L = 35;
|
||||
public const byte ROMC_01 = 1;
|
||||
public const byte ROMC_02 = 2;
|
||||
public const byte ROMC_03_S = 3;
|
||||
public const byte ROMC_04 = 4;
|
||||
public const byte ROMC_05 = 5;
|
||||
public const byte ROMC_06 = 6;
|
||||
public const byte ROMC_07 = 7;
|
||||
public const byte ROMC_08 = 8;
|
||||
public const byte ROMC_09 = 9;
|
||||
public const byte ROMC_0A = 10;
|
||||
public const byte ROMC_0B = 11;
|
||||
public const byte ROMC_0C = 12;
|
||||
public const byte ROMC_0D = 13;
|
||||
public const byte ROMC_0E = 14;
|
||||
public const byte ROMC_0F = 15;
|
||||
public const byte ROMC_10 = 16;
|
||||
public const byte ROMC_11 = 17;
|
||||
public const byte ROMC_12 = 18;
|
||||
public const byte ROMC_13 = 19;
|
||||
public const byte ROMC_14 = 20;
|
||||
public const byte ROMC_15 = 21;
|
||||
public const byte ROMC_16 = 22;
|
||||
public const byte ROMC_17 = 23;
|
||||
public const byte ROMC_18 = 24;
|
||||
public const byte ROMC_19 = 25;
|
||||
public const byte ROMC_1A = 26;
|
||||
public const byte ROMC_1B = 27;
|
||||
public const byte ROMC_1C_S = 28;
|
||||
public const byte ROMC_1D = 29;
|
||||
public const byte ROMC_1E = 30;
|
||||
public const byte ROMC_1F = 31;
|
||||
public const byte ROMC_00_S = 32;
|
||||
public const byte ROMC_00_L = 33;
|
||||
public const byte ROMC_03_L = 34;
|
||||
public const byte ROMC_1C_L = 35;
|
||||
|
||||
public const ushort IDLE = 0;
|
||||
public const ushort END = 51;
|
||||
public const byte IDLE = 0;
|
||||
public const byte END = 51;
|
||||
|
||||
public const ushort OP_LR8 = 100;
|
||||
public const ushort OP_SHFT_R = 101;
|
||||
public const ushort OP_SHFT_L = 102;
|
||||
public const ushort OP_LNK = 103;
|
||||
public const ushort OP_DI = 104;
|
||||
public const ushort OP_EI = 105;
|
||||
public const ushort OP_INC8 = 106;
|
||||
public const ushort OP_AND8 = 107;
|
||||
public const ushort OP_OR8 = 108;
|
||||
public const ushort OP_XOR8 = 109;
|
||||
public const ushort OP_COM = 110;
|
||||
public const ushort OP_ADD8 = 111;
|
||||
public const ushort OP_CI = 112;
|
||||
public const ushort OP_IS_INC = 113;
|
||||
public const ushort OP_IS_DEC = 114;
|
||||
public const ushort OP_LISU = 115;
|
||||
public const ushort OP_LISL = 116;
|
||||
public const ushort OP_BT = 117;
|
||||
public const ushort OP_ADD8D = 118;
|
||||
public const ushort OP_BR7 = 119;
|
||||
public const ushort OP_BF = 120;
|
||||
public const ushort OP_IN = 121;
|
||||
public const ushort OP_OUT = 122;
|
||||
public const ushort OP_AS_IS = 123;
|
||||
public const ushort OP_XS_IS = 124;
|
||||
public const ushort OP_NS_IS = 125;
|
||||
public const ushort OP_CLEAR_FLAGS = 126;
|
||||
public const ushort OP_SET_FLAGS_SZ = 127;
|
||||
public const byte OP_LR8 = 100;
|
||||
public const byte OP_SHFT_R = 101;
|
||||
public const byte OP_SHFT_L = 102;
|
||||
public const byte OP_LNK = 103;
|
||||
public const byte OP_DI = 104;
|
||||
public const byte OP_EI = 105;
|
||||
public const byte OP_INC8 = 106;
|
||||
public const byte OP_AND8 = 107;
|
||||
public const byte OP_OR8 = 108;
|
||||
public const byte OP_XOR8 = 109;
|
||||
//public const byte OP_COM = 110;
|
||||
public const byte OP_SUB8 = 110;
|
||||
public const byte OP_ADD8 = 111;
|
||||
public const byte OP_CI = 112;
|
||||
public const byte OP_IS_INC = 113;
|
||||
public const byte OP_IS_DEC = 114;
|
||||
public const byte OP_LISU = 115;
|
||||
public const byte OP_LISL = 116;
|
||||
public const byte OP_BT = 117;
|
||||
public const byte OP_ADD8D = 118;
|
||||
public const byte OP_BR7 = 119;
|
||||
public const byte OP_BF = 120;
|
||||
public const byte OP_IN = 121;
|
||||
public const byte OP_OUT = 122;
|
||||
//public const byte OP_AS_IS = 123;
|
||||
//public const byte OP_XS_IS = 124;
|
||||
//public const byte OP_NS_IS = 125;
|
||||
public const byte OP_LR_A_DB_IO = 126;
|
||||
public const byte OP_DS = 127;
|
||||
//public const byte OP_CLEAR_FLAGS = 126;
|
||||
//public const byte OP_SET_FLAGS_SZ = 127;
|
||||
public const byte OP_LIS = 128;
|
||||
|
||||
|
||||
public F3850()
|
||||
|
@ -135,7 +140,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
IDLE,
|
||||
END);
|
||||
|
||||
ALU_ClearFlags();
|
||||
ClearFlags_Func();
|
||||
FlagICB = false;
|
||||
}
|
||||
|
||||
|
@ -191,52 +196,51 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
case IDLE:
|
||||
break;
|
||||
|
||||
// clears all flags except for ICB
|
||||
case OP_CLEAR_FLAGS:
|
||||
ALU_ClearFlags();
|
||||
break;
|
||||
|
||||
// sets SIGN and CARRY flags based upon the supplied value
|
||||
case OP_SET_FLAGS_SZ:
|
||||
ALU_SetFlags_SZ(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// load one register into another (or databus)
|
||||
case OP_LR8:
|
||||
LR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
LR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// load DB into A (as a part of an IN or INS instruction)
|
||||
case OP_LR_A_DB_IO:
|
||||
LR_A_IO_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// loads supplied index value into register
|
||||
case OP_LIS:
|
||||
Regs[ALU1] = (byte)(cur_instr[instr_pntr++] & 0x0F);
|
||||
LR_Func(A, ALU1);
|
||||
break;
|
||||
|
||||
// Shift register n bit positions to the right (zero fill)
|
||||
case OP_SHFT_R:
|
||||
ALU_SR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// Shift register n bit positions to the left (zero fill)
|
||||
case OP_SHFT_L:
|
||||
ALU_SL_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SL_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// x <- (x) ADD y
|
||||
case OP_ADD8:
|
||||
ALU_ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// x <- (x) MINUS y
|
||||
case OP_SUB8:
|
||||
SUB_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// x <- (x) ADD y (decimal)
|
||||
case OP_ADD8D:
|
||||
ALU_ADD8D_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADDD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// A <- (A) + (C)
|
||||
case OP_LNK:
|
||||
bool fc = FlagC;
|
||||
ALU_ClearFlags();
|
||||
|
||||
if (fc)
|
||||
{
|
||||
ALU_ADD8_Func(A, ONE);
|
||||
}
|
||||
|
||||
ALU_SetFlags_SZ(A);
|
||||
Regs[ALU0] = (byte)(FlagC ? 1 : 0);
|
||||
ADD_Func(A, ALU0);
|
||||
break;
|
||||
|
||||
// Clear ICB status bit
|
||||
|
@ -251,200 +255,219 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
// x <- (y) XOR DB
|
||||
case OP_XOR8:
|
||||
ALU_XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// x <- (y) XOR DB (complement accumulator)
|
||||
case OP_COM:
|
||||
Regs[A] = (byte)~Regs[A];
|
||||
ALU_ClearFlags();
|
||||
ALU_SetFlags_SZ(A);
|
||||
XOR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// x <- (x) + 1
|
||||
case OP_INC8:
|
||||
ALU_ClearFlags();
|
||||
ALU_ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ALU_SetFlags_SZ(A);
|
||||
ADD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// x <- (y) & DB
|
||||
case OP_AND8:
|
||||
ALU_AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
AND_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// x <- (y) | DB
|
||||
case OP_OR8:
|
||||
ALU_OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
OR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// DB + (x) + 1 (modify flags without saving result)
|
||||
case OP_CI:
|
||||
Regs[ALU0] = (byte)~Regs[cur_instr[instr_pntr++]];
|
||||
ALU_ADD8_Func(ALU0, DB, true);
|
||||
ALU_SetFlags_SZ(ALU0);
|
||||
CI_Func();
|
||||
break;
|
||||
|
||||
// ISAR is incremented
|
||||
case OP_IS_INC:
|
||||
Regs[ISAR] = (ushort)((Regs[ISAR]& 0x38) | ((Regs[ISAR] + 1) & 0x07));
|
||||
Regs[ISAR] = (byte)((Regs[ISAR]& 0x38) | ((Regs[ISAR] + 1) & 0x07));
|
||||
break;
|
||||
|
||||
// ISAR is decremented
|
||||
case OP_IS_DEC:
|
||||
Regs[ISAR] = (ushort)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07));
|
||||
Regs[ISAR] = (byte)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07));
|
||||
break;
|
||||
|
||||
// set the upper octal ISAR bits (b3,b4,b5)
|
||||
case OP_LISU:
|
||||
Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x07) | cur_instr[instr_pntr++]) & 0x3F);
|
||||
Regs[ISAR] = (byte)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F);
|
||||
break;
|
||||
|
||||
// set the lower octal ISAR bits (b0,b1,b2)
|
||||
case OP_LISL:
|
||||
Regs[ISAR] = (ushort) (((Regs[ISAR] & 0x38) | cur_instr[instr_pntr++]) & 0x3F);
|
||||
Regs[ISAR] = (byte) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F);
|
||||
break;
|
||||
|
||||
// test operand against status register
|
||||
// decrement scratchpad byte
|
||||
//case OP_DS:
|
||||
//SUB_Func(cur_instr[instr_pntr++], ONE);
|
||||
//break;
|
||||
|
||||
// Branch on TRUE
|
||||
case OP_BT:
|
||||
if ((Regs[W] & cur_instr[instr_pntr++]) != 0)
|
||||
bool branchBT = false;
|
||||
switch (cur_instr[instr_pntr++])
|
||||
{
|
||||
instr_pntr = 0;
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
ROMC_01,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr = 0;
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
ROMC_03_S,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB < -((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
case 0:
|
||||
// do not branch
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// branch if positive (sign bit is set)
|
||||
if (FlagS) branchBT = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// branch on carry (carry bit is set)
|
||||
if (FlagC) branchBT = true;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// branch if positive or on carry
|
||||
if (FlagS || FlagC) branchBT = true;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// branch if zero (zero bit is set)
|
||||
if (FlagZ) branchBT = true;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// branch if positive and zero
|
||||
if (FlagS || FlagZ) branchBT = true;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// branch if zero or on carry
|
||||
if (FlagZ || FlagC) branchBT = true;
|
||||
break;
|
||||
case 7:
|
||||
// branch if positive or on carry or zero
|
||||
if (FlagS || FlagC || FlagZ) branchBT = true;
|
||||
break;
|
||||
}
|
||||
|
||||
instr_pntr = 0;
|
||||
if (branchBT) DO_BRANCH();
|
||||
else DONT_BRANCH();
|
||||
break;
|
||||
|
||||
// Branch based on ISARL
|
||||
// Branch on ISARL
|
||||
case OP_BR7:
|
||||
if ((Regs[ISAR] & 7) == 7)
|
||||
instr_pntr = 1; // lose a cycle
|
||||
if (Regs[ISAR].Bit(0) && Regs[ISAR].Bit(1) && Regs[ISAR].Bit(2))
|
||||
{
|
||||
instr_pntr = 0;
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
ROMC_03_S, // DB/IO <- ((PC0)); PC0++
|
||||
//IDLE, <- lose a cycle that was stolen in the table
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
DONT_BRANCH();
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr = 0;
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
ROMC_01,
|
||||
//IDLE, <- lose a cycle that was stolen in the table
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
DO_BRANCH();
|
||||
}
|
||||
break;
|
||||
|
||||
// PC0 <- PC0+n+1
|
||||
// Branch on FALSE
|
||||
case OP_BF:
|
||||
if ((Regs[W] & cur_instr[instr_pntr++]) != 0)
|
||||
bool branchBF = false;
|
||||
switch (cur_instr[instr_pntr++])
|
||||
{
|
||||
instr_pntr = 0;
|
||||
PopulateCURINSTR(
|
||||
// S
|
||||
ROMC_03_S, // DB/IO <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
}
|
||||
else
|
||||
{
|
||||
instr_pntr = 0;
|
||||
PopulateCURINSTR(
|
||||
// L
|
||||
ROMC_01,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
// S
|
||||
ROMC_00_S, // DB <- ((PC0)); PC0++
|
||||
IDLE,
|
||||
IDLE,
|
||||
END);
|
||||
case 0:
|
||||
// unconditional branch relative
|
||||
branchBF = true;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// branch on negative (sign bit is reset)
|
||||
if (!FlagS) branchBF = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// branch if no carry (carry bit is reset)
|
||||
if (!FlagC) branchBF = true;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// branch if no carry and negative
|
||||
if (!FlagC && !FlagS) branchBF = true;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// branch if not zero (zero bit is reset)
|
||||
if (!FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// branch if not zero and negative
|
||||
if (!FlagS && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// branch if no carry and result is no zero
|
||||
if (!FlagC && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// branch if not zero, carry and sign
|
||||
if (!FlagS && !FlagC && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// branch if there is no overflow (OVF bit is reset)
|
||||
if (!FlagO) branchBF = true;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// branch if negative and no overflow
|
||||
if (!FlagS && !FlagO) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
// branch if no overflow and no carry
|
||||
if (!FlagO && !FlagC) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xB:
|
||||
// branch if no overflow, no carry & negative
|
||||
if (!FlagO && !FlagC && !FlagS) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xC:
|
||||
// branch if no overflow and not zero
|
||||
if (!FlagO && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xD:
|
||||
// branch if no overflow, not zero and neg
|
||||
if (!FlagS && !FlagO && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xE:
|
||||
// branch if no overflow, no carry & not zero
|
||||
if (!FlagO && !FlagC && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xF:
|
||||
// all neg
|
||||
if (!FlagO && !FlagC && !FlagS && FlagZ) branchBF = true;
|
||||
break;
|
||||
}
|
||||
|
||||
instr_pntr = 0;
|
||||
if (branchBF) DO_BRANCH();
|
||||
else DONT_BRANCH();
|
||||
break;
|
||||
|
||||
// A <- (I/O Port 0 or 1)
|
||||
case OP_IN:
|
||||
Regs[cur_instr[instr_pntr++]] = ReadHardware(cur_instr[instr_pntr++]);
|
||||
instr_pntr++; // dest == A
|
||||
Regs[ALU0] = cur_instr[instr_pntr++]; // src
|
||||
IN_Func(A, ALU0);
|
||||
break;
|
||||
|
||||
// I/O Port 0 or 1 <- (A)
|
||||
case OP_OUT:
|
||||
WriteHardware(cur_instr[instr_pntr++], (byte)cur_instr[instr_pntr++]);
|
||||
//OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
WriteHardware(cur_instr[instr_pntr++], (byte)Regs[cur_instr[instr_pntr++]]);
|
||||
break;
|
||||
|
||||
// Add the content of the SR register addressed by ISAR to A (Binary)
|
||||
case OP_AS_IS:
|
||||
ALU_ClearFlags();
|
||||
ALU_ADD8_Func(A, Regs[ISAR]);
|
||||
ALU_SetFlags_SZ(A);
|
||||
break;
|
||||
|
||||
// XOR the content of the SR register addressed by ISAR to A
|
||||
case OP_XS_IS:
|
||||
ALU_ClearFlags();
|
||||
ALU_XOR8_Func(A, Regs[ISAR]);
|
||||
ALU_SetFlags_SZ(A);
|
||||
break;
|
||||
|
||||
// AND the content of the SR register addressed by ISAR to A
|
||||
case OP_NS_IS:
|
||||
ALU_ClearFlags();
|
||||
ALU_AND8_Func(A, Regs[ISAR]);
|
||||
ALU_SetFlags_SZ(A);
|
||||
break;
|
||||
|
||||
|
||||
// instruction fetch
|
||||
// The device whose address space includes the contents of the PC0 register must place on the data bus the op code addressed by PC0;
|
||||
// then all devices increments the content of PC0.
|
||||
|
@ -650,7 +673,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// registers cannot be read back onto the data bus)
|
||||
// CYCLE LENGTH: L
|
||||
case ROMC_1B:
|
||||
Regs[DB] = ReadHardware(Regs[IO]);
|
||||
IN_Func(DB, IO);
|
||||
//Regs[DB] = ReadHardware(Regs[IO]);
|
||||
break;
|
||||
|
||||
// None
|
||||
|
@ -687,7 +711,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
public Action<TraceInfo> TraceCallback;
|
||||
|
||||
public string TraceHeader => "F3850: PC, machine code, mnemonic, operands, registers (R0, R1, R2, R3, R4, R5, R6, R7, R8, J, HU, HL, KU, KL, QU, QL, Cy), flags (IOZCS)";
|
||||
public string TraceHeader => "F3850: PC, machine code, mnemonic, operands, flags (IOZCS), registers (PC1, DC0, A, ISAR, DB, IO, J, H, K, Q, R00-R63), Cycles";
|
||||
|
||||
public TraceInfo State(bool disassemble = true)
|
||||
{
|
||||
|
@ -713,39 +737,50 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
byte_code.PadRight(12),
|
||||
disasm.PadRight(26)),
|
||||
RegisterInfo = string.Format(
|
||||
"R0:{0:X2} R1:{1:X2} R2:{2:X2} R3:{3:X2} R4:{4:X2} R5:{5:X2} R6:{6:X2} R7:{7:X2} R8:{8:X2} J:{9:X2} HU:{10:X2} HL:{11:X2} KU:{12:X2} KL:{13:X2} QU:{14:X2} QL:{15:X2} Cy:{16} {17}{18}{19}{20}{21}",
|
||||
Regs[0],
|
||||
Regs[1],
|
||||
Regs[2],
|
||||
Regs[3],
|
||||
Regs[4],
|
||||
Regs[5],
|
||||
Regs[6],
|
||||
Regs[7],
|
||||
Regs[8],
|
||||
"Flags:{75}{76}{77}{78}{79} " +
|
||||
"PC1:{0:X4} DC0:{1:X4} A:{2:X2} ISAR:{3:X2} DB:{4:X2} IO:{5:X2} J:{6:X2} H:{7:X4} K:{8:X4} Q:{9:X4} " +
|
||||
"R0:{10:X2} R1:{11:X2} R2:{12:X2} R3:{13:X2} R4:{14:X2} R5:{15:X2} R6:{16:X2} R7:{17:X2} R8:{18:X2} R9:{19:X2} " +
|
||||
"R10:{20:X2} R11:{21:X2} R12:{22:X2} R13:{23:X2} R14:{24:X2} R15:{25:X2} R16:{26:X2} R17:{27:X2} R18:{28:X2} R19:{29:X2} " +
|
||||
"R20:{30:X2} R21:{31:X2} R22:{32:X2} R23:{33:X2} R24:{34:X2} R25:{35:X2} R26:{36:X2} R27:{37:X2} R28:{38:X2} R29:{39:X2} " +
|
||||
"R30:{40:X2} R31:{41:X2} R32:{42:X2} R33:{43:X2} R34:{44:X2} R35:{45:X2} R36:{46:X2} R37:{47:X2} R38:{48:X2} R39:{49:X2} " +
|
||||
"R40:{50:X2} R41:{51:X2} R42:{52:X2} R43:{53:X2} R44:{54:X2} R45:{55:X2} R46:{56:X2} R47:{57:X2} R48:{58:X2} R49:{59:X2} " +
|
||||
"R50:{60:X2} R51:{61:X2} R52:{62:X2} R53:{63:X2} R54:{64:X2} R55:{65:X2} R56:{66:X2} R57:{67:X2} R58:{68:X2} R59:{69:X2} " +
|
||||
"R60:{70:X2} R61:{71:X2} R62:{72:X2} R63:{73:X2} " +
|
||||
"Cy:{74}",
|
||||
RegPC1,
|
||||
RegDC0,
|
||||
Regs[A],
|
||||
Regs[ISAR],
|
||||
Regs[DB],
|
||||
Regs[IO],
|
||||
Regs[J],
|
||||
Regs[Hh],
|
||||
Regs[Hl],
|
||||
Regs[Kh],
|
||||
Regs[Kl],
|
||||
Regs[Qh],
|
||||
Regs[Ql],
|
||||
(ushort)(Regs[Hl] | (Regs[Hh] << 8)),
|
||||
(ushort)(Regs[Kl] | (Regs[Kh] << 8)),
|
||||
(ushort)(Regs[Ql] | (Regs[Qh] << 8)),
|
||||
Regs[0], Regs[1], Regs[2], Regs[3], Regs[4], Regs[5], Regs[6], Regs[7], Regs[8], Regs[9],
|
||||
Regs[10], Regs[11], Regs[12], Regs[13], Regs[14], Regs[15], Regs[16], Regs[17], Regs[18], Regs[19],
|
||||
Regs[20], Regs[21], Regs[22], Regs[23], Regs[24], Regs[25], Regs[26], Regs[27], Regs[28], Regs[29],
|
||||
Regs[30], Regs[31], Regs[32], Regs[33], Regs[34], Regs[35], Regs[36], Regs[37], Regs[38], Regs[39],
|
||||
Regs[40], Regs[41], Regs[42], Regs[43], Regs[44], Regs[45], Regs[46], Regs[47], Regs[48], Regs[49],
|
||||
Regs[50], Regs[51], Regs[52], Regs[53], Regs[54], Regs[55], Regs[56], Regs[57], Regs[58], Regs[59],
|
||||
Regs[60], Regs[61], Regs[62], Regs[63],
|
||||
TotalExecutedCycles,
|
||||
FlagICB ? "I" : "i",
|
||||
FlagO ? "O" : "o",
|
||||
FlagZ ? "Z" : "z",
|
||||
FlagC ? "C" : "c",
|
||||
FlagS ? "S" : "s")
|
||||
FlagS ? "S" : "s"),
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optimization method to set cur_instr
|
||||
/// </summary>
|
||||
private void PopulateCURINSTR(ushort d0 = 0, ushort d1 = 0, ushort d2 = 0, ushort d3 = 0, ushort d4 = 0, ushort d5 = 0, ushort d6 = 0, ushort d7 = 0, ushort d8 = 0,
|
||||
ushort d9 = 0, ushort d10 = 0, ushort d11 = 0, ushort d12 = 0, ushort d13 = 0, ushort d14 = 0, ushort d15 = 0, ushort d16 = 0, ushort d17 = 0, ushort d18 = 0,
|
||||
ushort d19 = 0, ushort d20 = 0, ushort d21 = 0, ushort d22 = 0, ushort d23 = 0, ushort d24 = 0, ushort d25 = 0, ushort d26 = 0, ushort d27 = 0, ushort d28 = 0,
|
||||
ushort d29 = 0, ushort d30 = 0, ushort d31 = 0, ushort d32 = 0, ushort d33 = 0, ushort d34 = 0, ushort d35 = 0, ushort d36 = 0, ushort d37 = 0)
|
||||
private void PopulateCURINSTR(byte d0 = 0, byte d1 = 0, byte d2 = 0, byte d3 = 0, byte d4 = 0, byte d5 = 0, byte d6 = 0, byte d7 = 0, byte d8 = 0,
|
||||
byte d9 = 0, byte d10 = 0, byte d11 = 0, byte d12 = 0, byte d13 = 0, byte d14 = 0, byte d15 = 0, byte d16 = 0, byte d17 = 0, byte d18 = 0,
|
||||
byte d19 = 0, byte d20 = 0, byte d21 = 0, byte d22 = 0, byte d23 = 0, byte d24 = 0, byte d25 = 0, byte d26 = 0, byte d27 = 0, byte d28 = 0,
|
||||
byte d29 = 0, byte d30 = 0, byte d31 = 0, byte d32 = 0, byte d33 = 0, byte d34 = 0, byte d35 = 0, byte d36 = 0, byte d37 = 0)
|
||||
{
|
||||
cur_instr[0] = d0; cur_instr[1] = d1; cur_instr[2] = d2;
|
||||
cur_instr[3] = d3; cur_instr[4] = d4; cur_instr[5] = d5;
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// Memory and related functions
|
||||
/// </summary>
|
||||
public partial class ChannelF
|
||||
{
|
||||
public byte[] BIOS01 = new byte[1024];
|
||||
public byte[] BIOS02 = new byte[1024];
|
||||
|
||||
/// <summary>
|
||||
/// Simulates reading a byte of data from the address space
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <returns></returns>
|
||||
public byte ReadBus(ushort addr)
|
||||
{
|
||||
if (addr < 0x400)
|
||||
{
|
||||
// Rom0
|
||||
return BIOS01[addr];
|
||||
}
|
||||
else if (addr < 0x800)
|
||||
{
|
||||
// Rom1
|
||||
return BIOS02[addr - 0x400];
|
||||
}
|
||||
else if (addr < 0x2000)
|
||||
{
|
||||
// Cart
|
||||
//return 0;
|
||||
return Rom[addr - 0x800];
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simulates writing a byte of data to the address space (in its default configuration, there is no writeable RAM in the
|
||||
/// Channel F addressable through the address space)
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <returns></returns>
|
||||
public void WriteBus(ushort addr, byte value)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// Ports and related functions
|
||||
/// </summary>
|
||||
public partial class ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// The Channel F has 4 8-bit IO ports connected.
|
||||
/// CPU - ports 0 and 1
|
||||
/// PSU - ports 4 and 5
|
||||
/// (the second PSU has no IO ports wired up)
|
||||
/// </summary>
|
||||
public byte[] PortLatch = new byte[4];
|
||||
|
||||
public bool ControllersEnabled;
|
||||
|
||||
public const int PORT0 = 0;
|
||||
public const int PORT1 = 1;
|
||||
public const int PORT4 = 2;
|
||||
public const int PORT5 = 3;
|
||||
|
||||
/// <summary>
|
||||
/// CPU attempts to read data byte from the requested port
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <returns></returns>
|
||||
public byte ReadPort(ushort addr)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
// Console buttons
|
||||
// b0: TIME
|
||||
// b1: MODE
|
||||
// b2: HOLD
|
||||
// b3: START
|
||||
case 0:
|
||||
return (byte)((DataConsole ^ 0xff) | PortLatch[PORT0]);
|
||||
|
||||
// Right controller
|
||||
// b0: RIGHT
|
||||
// b1: LEFT
|
||||
// b2: BACK
|
||||
// b3: FORWARD
|
||||
// b4: CCW
|
||||
// b5: CW
|
||||
// b6: PULL
|
||||
// b7: PUSH
|
||||
case 1:
|
||||
byte ed1;
|
||||
if ((PortLatch[PORT0] & 0x40) == 0)
|
||||
{
|
||||
ed1 = DataRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
ed1 = (byte) (0xC0 | DataRight);
|
||||
}
|
||||
return (byte) ((ed1 ^ 0xff) | PortLatch[PORT1]);
|
||||
|
||||
// Left controller
|
||||
// b0: RIGHT
|
||||
// b1: LEFT
|
||||
// b2: BACK
|
||||
// b3: FORWARD
|
||||
// b4: CCW
|
||||
// b5: CW
|
||||
// b6: PULL
|
||||
// b7: PUSH
|
||||
case 4:
|
||||
byte ed4;
|
||||
if ((PortLatch[PORT0] & 0x40) == 0)
|
||||
{
|
||||
ed4 = DataLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
ed4 = 0xff;
|
||||
}
|
||||
return (byte)((ed4 ^ 0xff) | PortLatch[PORT4]);
|
||||
|
||||
case 5:
|
||||
return (byte) (0 | PortLatch[PORT5]);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CPU attempts to write data to the requested port (latch)
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <param name="value"></param>
|
||||
public void WritePort(ushort addr, byte value)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0:
|
||||
PortLatch[PORT0] = value;
|
||||
if ((value & 0x20) != 0)
|
||||
{
|
||||
var offset = _x + (_y * 128);
|
||||
VRAM[offset] = (byte)(_colour);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
PortLatch[PORT1] = value;
|
||||
|
||||
// Write Data0 - indicates that valid data is present for both VRAM ODD0 and EVEN0
|
||||
bool data0 = value.Bit(6);
|
||||
// Write Data1 - indicates that valid data is present for both VRAM ODD1 and EVEN1
|
||||
bool data1 = value.Bit(7);
|
||||
|
||||
//_colour = ((value) >> 6) & 3;
|
||||
_colour = ((value ^ 0xff) >> 6) & 0x3;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
PortLatch[PORT4] = value;
|
||||
_x = (value ^ 0xff) & 0x7f;
|
||||
//_x = (value | 0x80) ^ 0xFF;
|
||||
/*
|
||||
|
||||
// video horizontal position
|
||||
// 0 - video select
|
||||
// 1-6 - horiz A-F
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 5:
|
||||
|
||||
PortLatch[PORT5] = value;
|
||||
//_y = (value & 31); // ^ 0xff;
|
||||
//_y = (value | 0xC0) ^ 0xff;
|
||||
|
||||
//_y = (value ^ 0xff) & 0x1f;
|
||||
|
||||
// video vertical position and sound
|
||||
// 0-5 - Vertical A-F
|
||||
// 6 - Tone AN, 7 - Tone BN
|
||||
|
||||
_y = (value ^ 0xff) & 0x3f;
|
||||
|
||||
// audio
|
||||
var aVal = ((value >> 6) & 0x03); // (value & 0xc0) >> 6;
|
||||
if (aVal != tone)
|
||||
{
|
||||
tone = aVal;
|
||||
time = 0;
|
||||
amplitude = 1;
|
||||
AudioChange();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.CodeDom;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BizHawk.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// Video related functions
|
||||
/// </summary>
|
||||
public partial class ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// 128x64 pixels - 8192x2bits (2 KB)
|
||||
/// For the purposes of this core we will use 8192 bytes and just & 0x03
|
||||
/// </summary>
|
||||
public byte[] VRAM = new byte[(128 * 64)];
|
||||
|
||||
public static readonly int[] FPalette =
|
||||
{
|
||||
/*
|
||||
0x101010, 0xFDFDFD, 0x5331FF, 0x5DCC02, 0xF33F4B, 0xE0E0E0, 0xA6FF91, 0xD0CEFF
|
||||
*/
|
||||
|
||||
Colors.ARGB(0x10, 0x10, 0x10), // Black
|
||||
Colors.ARGB(0xFD, 0xFD, 0xFD), // White
|
||||
Colors.ARGB(0xFF, 0x31, 0x53), // Red
|
||||
Colors.ARGB(0x02, 0xCC, 0x5D), // Green
|
||||
Colors.ARGB(0x4B, 0x3F, 0xF3), // Blue
|
||||
Colors.ARGB(0xE0, 0xE0, 0xE0), // Gray
|
||||
Colors.ARGB(0x91, 0xFF, 0xA6), // BGreen
|
||||
Colors.ARGB(0xCE, 0xD0, 0xFF), // BBlue
|
||||
|
||||
};
|
||||
|
||||
public static readonly int[] CMap =
|
||||
{
|
||||
0, 1, 1, 1,
|
||||
7, 4, 2, 3,
|
||||
5, 4, 2, 3,
|
||||
6, 4, 2, 3,
|
||||
};
|
||||
|
||||
private int _colour = 2;
|
||||
private int _x;
|
||||
private int _y;
|
||||
private int _arm;
|
||||
|
||||
private int[] frameBuffer = new int[128 * 64];
|
||||
|
||||
private void BuildFrame()
|
||||
{
|
||||
// rows
|
||||
int counter = 0;
|
||||
for (int row = 0; row < 64; row++)
|
||||
{
|
||||
// columns 125 and 126 hold the palette index modifier for the entire row
|
||||
var rIndex = 128 * row;
|
||||
var c125 = (VRAM[rIndex + 125] & 0x03);
|
||||
var c126 = (VRAM[rIndex + 126] & 0x03);
|
||||
var pModifier = (((c126 & 0x02) | c125 >> 1) << 2);
|
||||
|
||||
pModifier = ((VRAM[(row << 7) + 125] & 2) >> 1) | (VRAM[(row << 7) + 126] & 3);
|
||||
pModifier = (pModifier << 2) & 0xc;
|
||||
|
||||
// columns
|
||||
for (int col = 0; col < 128; col++, counter++)
|
||||
{
|
||||
int cl = (VRAM[(row << 7) + col]) & 0x3;
|
||||
frameBuffer[(row << 7) + col] = CMap[pModifier | cl] & 0x7;
|
||||
//var nCol = pModifier + (VRAM[col | (row << 7)] & 0x03);
|
||||
//frameBuffer[counter] = FPalette[CMap[nCol]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue