ChannelFHawk: CPU mostly there. It's running games now. Still need to work on input.
This commit is contained in:
parent
c86691bfb1
commit
c74b47315f
|
@ -5,10 +5,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
{
|
{
|
||||||
public partial class ChannelF
|
public partial class ChannelF
|
||||||
{
|
{
|
||||||
public bool[] StateConsole = new bool[4];
|
public bool[] StateConsole = new bool[5];
|
||||||
public string[] ButtonsConsole =
|
public string[] ButtonsConsole =
|
||||||
{
|
{
|
||||||
"TIME", "MODE", "HOLD", "START"
|
"TIME", "MODE", "HOLD", "START", "RESET"
|
||||||
};
|
};
|
||||||
|
|
||||||
public byte DataConsole
|
public byte DataConsole
|
||||||
|
@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
int w = 0;
|
int w = 0;
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
byte mask = (byte) (1 << i);
|
byte mask = (byte) (1 << i);
|
||||||
w = StateConsole[i] ? w | mask : w & ~mask;
|
w = StateConsole[i] ? w | mask : w & ~mask;
|
||||||
|
|
|
@ -8,11 +8,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
{
|
{
|
||||||
ser.BeginSection("ChannelF");
|
ser.BeginSection("ChannelF");
|
||||||
ser.Sync(nameof(VRAM), ref VRAM, false);
|
ser.Sync(nameof(VRAM), ref VRAM, false);
|
||||||
ser.Sync(nameof(_colour), ref _colour);
|
ser.Sync(nameof(latch_colour), ref latch_colour);
|
||||||
ser.Sync(nameof(_x), ref _x);
|
ser.Sync(nameof(latch_x), ref latch_x);
|
||||||
ser.Sync(nameof(_y), ref _y);
|
ser.Sync(nameof(latch_y), ref latch_y);
|
||||||
ser.Sync(nameof(_arm), ref _arm);
|
//ser.Sync(nameof(ControllersEnabled), ref ControllersEnabled);
|
||||||
ser.Sync(nameof(ControllersEnabled), ref ControllersEnabled);
|
|
||||||
CPU.SyncState(ser);
|
CPU.SyncState(ser);
|
||||||
ser.EndSection();
|
ser.EndSection();
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -5,15 +5,70 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
{
|
{
|
||||||
public partial class ChannelF : IVideoProvider, IRegionable
|
public partial class ChannelF : IVideoProvider, IRegionable
|
||||||
{
|
{
|
||||||
public int _frameHz = 60;
|
/// <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 latch_colour = 2; //2;
|
||||||
|
private int latch_x;
|
||||||
|
private int latch_y;
|
||||||
|
|
||||||
|
private readonly int[] frameBuffer = new int[128 * 64];
|
||||||
|
|
||||||
|
private void BuildFrame()
|
||||||
|
{
|
||||||
|
for (int r = 0; r < 64; r++)
|
||||||
|
{
|
||||||
|
// lines
|
||||||
|
var p1 = (VRAM[(r * 0x80) + 125]) & 0x03;
|
||||||
|
var p2 = (VRAM[(r * 0x80) + 126]) & 0x03;
|
||||||
|
var pOffset = ((p2 & 0x02) | (p1 >> 1)) << 2;
|
||||||
|
|
||||||
|
for (int c = 0; c < 128; c++)
|
||||||
|
{
|
||||||
|
// columns
|
||||||
|
var colourIndex = pOffset + (VRAM[c | (r << 7)] & 0x03);
|
||||||
|
frameBuffer[(r << 7) + c] = CMap[colourIndex];
|
||||||
|
//frameBuffer[(r << 7) + c + 1] = CMap[colourIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int _frameHz = 60;
|
||||||
public int[] CroppedBuffer = new int[102 * 58];
|
public int[] CroppedBuffer = new int[102 * 58];
|
||||||
|
|
||||||
public int VirtualWidth => BufferWidth * 2;
|
public int VirtualWidth => BufferWidth * 2;
|
||||||
public int VirtualHeight => (int)((double)BufferHeight * 1.3) * 2;
|
public int VirtualHeight => (int)((double)BufferHeight * 1.3) * 2;
|
||||||
public int BufferWidth => 102; //128
|
public int BufferWidth => 102; //128
|
||||||
public int BufferHeight => 58; //64
|
public int BufferHeight => 58; //64
|
||||||
public int BackgroundColor => Colors.ARGB(0x00, 0x00, 0x00);
|
public int BackgroundColor => Colors.ARGB(0xFF, 0xFF, 0xFF);
|
||||||
public int VsyncNumerator => _frameHz;
|
public int VsyncNumerator => _frameHz;
|
||||||
public int VsyncDenominator => 1;
|
public int VsyncDenominator => 1;
|
||||||
|
|
||||||
|
@ -42,10 +97,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
}
|
}
|
||||||
|
|
||||||
return CroppedBuffer;
|
return CroppedBuffer;
|
||||||
|
|
||||||
//return frameBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayType Region => DisplayType.NTSC;
|
public DisplayType Region => DisplayType.NTSC;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using BizHawk.Emulation.Common;
|
using BizHawk.Emulation.Common;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
@ -8,10 +10,18 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
public partial class ChannelF
|
public partial class ChannelF
|
||||||
{
|
{
|
||||||
[CoreConstructor(VSystemID.Raw.ChannelF)]
|
[CoreConstructor(VSystemID.Raw.ChannelF)]
|
||||||
public ChannelF(CoreComm comm, GameInfo game, byte[] rom)
|
public ChannelF(CoreLoadParameters<ChannelFSettings, ChannelFSyncSettings> lp)
|
||||||
{
|
{
|
||||||
var ser = new BasicServiceProvider(this);
|
var ser = new BasicServiceProvider(this);
|
||||||
ServiceProvider = ser;
|
ServiceProvider = ser;
|
||||||
|
CoreComm = lp.Comm;
|
||||||
|
_gameInfo = lp.Roms.Select(r => r.Game).ToList();
|
||||||
|
_files = lp.Roms.Select(r => r.RomData).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
var settings = lp.Settings ?? new ChannelFSettings();
|
||||||
|
var syncSettings = lp.SyncSettings ?? new ChannelFSyncSettings();
|
||||||
|
|
||||||
MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||||
|
|
||||||
ControllerDefinition = ChannelFControllerDefinition;
|
ControllerDefinition = ChannelFControllerDefinition;
|
||||||
|
@ -27,12 +37,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
_tracer = new TraceBuffer(CPU.TraceHeader);
|
_tracer = new TraceBuffer(CPU.TraceHeader);
|
||||||
|
|
||||||
var bios01 = comm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131253"));
|
var bios01 = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131253"));
|
||||||
var bios02 = comm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131254"));
|
var bios02 = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131254"));
|
||||||
|
|
||||||
BIOS01 = bios01;
|
BIOS01 = bios01;
|
||||||
BIOS02 = bios02;
|
BIOS02 = bios02;
|
||||||
|
|
||||||
|
var rom = _files.First();
|
||||||
|
|
||||||
Array.Copy(rom, 0, Rom, 0, rom.Length);
|
Array.Copy(rom, 0, Rom, 0, rom.Length);
|
||||||
|
|
||||||
CalcClock();
|
CalcClock();
|
||||||
|
@ -45,6 +57,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
SetupMemoryDomains();
|
SetupMemoryDomains();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal CoreComm CoreComm { get; }
|
||||||
|
|
||||||
|
public List<GameInfo> _gameInfo;
|
||||||
|
private readonly List<byte[]> _files;
|
||||||
|
|
||||||
public F3850 CPU;
|
public F3850 CPU;
|
||||||
private readonly TraceBuffer _tracer;
|
private readonly TraceBuffer _tracer;
|
||||||
public IController _controller;
|
public IController _controller;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
public sealed partial class F3850
|
public sealed partial class F3850
|
||||||
{
|
{
|
||||||
public const int MaxInstructionLength = 40;
|
public const int MaxInstructionLength = 48;
|
||||||
|
|
||||||
public long TotalExecutedCycles;
|
public long TotalExecutedCycles;
|
||||||
|
|
||||||
|
@ -15,264 +15,268 @@
|
||||||
{
|
{
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x00: LR_A_KU(); break; // LR A, (KU)
|
case 0x00: LR_A_KU(); break; // LR A, (KU)
|
||||||
case 0x01: LR_A_KL(); break; // LR A, (KL)
|
case 0x01: LR_A_KL(); break; // LR A, (KL)
|
||||||
case 0x02: LR_A_QU(); break; // LR A, (QU)
|
case 0x02: LR_A_QU(); break; // LR A, (QU)
|
||||||
case 0x03: LR_A_QL(); break; // LR A, (QL)
|
case 0x03: LR_A_QL(); break; // LR A, (QL)
|
||||||
case 0x04: LR_KU_A(); break; // LR KU, (A)
|
case 0x04: LR_KU_A(); break; // LR KU, (A)
|
||||||
case 0x05: LR_KL_A(); break; // LR KL, (A)
|
case 0x05: LR_KL_A(); break; // LR KL, (A)
|
||||||
case 0x06: LR_QU_A(); break; // LR QU, (A)
|
case 0x06: LR_QU_A(); break; // LR QU, (A)
|
||||||
case 0x07: LR_QL_A(); break; // LR QL, (A)
|
case 0x07: LR_QL_A(); break; // LR QL, (A)
|
||||||
case 0x08: LR_K_P(); break; // LR K, (P)
|
case 0x08: LR_K_P(); break; // LR K, (P)
|
||||||
case 0x09: LR_P_K(); break; // LR P, (K)
|
case 0x09: LR_P_K(); break; // LR P, (K)
|
||||||
case 0x0A: LR_A_IS(); break; // LR A, (ISAR)
|
case 0x0A: LR_A_IS(); break; // LR A, (ISAR)
|
||||||
case 0x0B: LR_IS_A(); break; // LR ISAR, (A)
|
case 0x0B: LR_IS_A(); break; // LR ISAR, (A)
|
||||||
case 0x0C: PK(); break; // LR PC1, (PC0); LR PC0l <- (r13); LR PC0h, (r12)
|
case 0x0C: PK(); break; // LR PC1, (PC0); LR PC0l <- (r13); LR PC0h, (r12)
|
||||||
case 0x0D: LR_P0_Q(); break; // LR PC0l, (r15); LR PC0h <- (r14)
|
case 0x0D: LR_P0_Q(); break; // LR PC0l, (r15); LR PC0h <- (r14)
|
||||||
case 0x0E: LR_Q_DC(); break; // LR r14, (DC0h); r15 <- (DC0l)
|
case 0x0E: LR_Q_DC(); break; // LR r14, (DC0h); r15 <- (DC0l)
|
||||||
case 0x0F: LR_DC_Q(); break; // LR DC0h, (r14); DC0l <- (r15)
|
case 0x0F: LR_DC_Q(); break; // LR DC0h, (r14); DC0l <- (r15)
|
||||||
case 0x10: LR_DC_H(); break; // LR DC0h, (r10); DC0l <- (r11)
|
case 0x10: LR_DC_H(); break; // LR DC0h, (r10); DC0l <- (r11)
|
||||||
case 0x11: LR_H_DC(); break; // LR r10, (DC0h); r11 <- (DC0l)
|
case 0x11: LR_H_DC(); break; // LR r10, (DC0h); r11 <- (DC0l)
|
||||||
case 0x12: SHIFT_R(1); break; // Shift (A) right one bit position (zero fill)
|
case 0x12: SR(1); break; // Shift (A) right one bit position (zero fill)
|
||||||
case 0x13: SHIFT_L(1); break; // Shift (A) left one bit position (zero fill)
|
case 0x13: SL(1); break; // Shift (A) left one bit position (zero fill)
|
||||||
case 0x14: SHIFT_R(4); break; // Shift (A) right four bit positions (zero fill)
|
case 0x14: SR(4); break; // Shift (A) right four bit positions (zero fill)
|
||||||
case 0x15: SHIFT_L(4); break; // Shift (A) left four bit positions (zero fill)
|
case 0x15: SL(4); break; // Shift (A) left four bit positions (zero fill)
|
||||||
case 0x16: LM(); break; // A <- ((DC0))
|
case 0x16: LM(); break; // A <- ((DC0))
|
||||||
case 0x17: ST(); break; // (DC) <- (A)
|
case 0x17: ST(); break; // (DC) <- (A)
|
||||||
case 0x18: COM(); break; // A <- A XOR 255 (complement A)
|
case 0x18: COM(); break; // A <- A XOR 255 (complement A)
|
||||||
case 0x19: LNK(); break; // A <- (A) + (C)
|
case 0x19: LNK(); break; // A <- (A) + (C)
|
||||||
case 0x1A: DI(); break; // Clear ICB
|
case 0x1A: DI(); break; // Clear ICB
|
||||||
case 0x1B: EI(); break; // Set ICB
|
case 0x1B: EI(); break; // Set ICB
|
||||||
case 0x1C: POP(); break; // PC0 <- PC1
|
case 0x1C: POP(); break; // PC0 <- PC1
|
||||||
case 0x1D: LR_W_J(); break; // W <- (r9)
|
case 0x1D: LR_W_J(); break; // W <- (r9)
|
||||||
case 0x1E: LR_J_W(); break; // r9 <- (W)
|
case 0x1E: LR_J_W(); break; // r9 <- (W)
|
||||||
case 0x1F: INC(); break; // A <- (A) + 1
|
case 0x1F: INC(); break; // A <- (A) + 1
|
||||||
case 0x20: LI(); break; // A <- H'aa'
|
case 0x20: LI(); break; // A <- H'aa'
|
||||||
case 0x21: NI(); break; // A <- (A) AND H'aa'
|
case 0x21: NI(); break; // A <- (A) AND H'aa'
|
||||||
case 0x22: OI(); break; // A <- (A) OR H'aa'
|
case 0x22: OI(); break; // A <- (A) OR H'aa'
|
||||||
case 0x23: XI(); break; // A <- (A) XOR H'aa'
|
case 0x23: XI(); break; // A <- (A) XOR H'aa'
|
||||||
case 0x24: AI(); break; // A <- (A) + H'aa'
|
case 0x24: AI(); break; // A <- (A) + H'aa'
|
||||||
case 0x25: CI(); break; // H'aa' + (A) + 1 (modify flags without saving result)
|
case 0x25: CI(); break; // H'aa' + (A) + 1 (modify flags without saving result)
|
||||||
case 0x26: IN(); break; // DB <- PP; A <- (I/O Port PP)
|
case 0x26: IN(); break; // DB <- PP; A <- (I/O Port PP)
|
||||||
case 0x27: OUT(); break; // DB <- PP; I/O Port PP <- (A)
|
case 0x27: OUT(); break; // DB <- PP; I/O Port PP <- (A)
|
||||||
case 0x28: PI(); break; // A <- H'ii'; PC1 <- (PC0) + 1; PC0l <- H'jj'; PC0h <- (A)
|
case 0x28: PI(); break; // A <- H'ii'; PC1 <- (PC0) + 1; PC0l <- H'jj'; PC0h <- (A)
|
||||||
case 0x29: JMP(); break; // A <- H'ii'; PC0l <- H'jj'; PC0h <- (A)
|
case 0x29: JMP(); break; // A <- H'ii'; PC0l <- H'jj'; PC0h <- (A)
|
||||||
case 0x2A: DCI(); break; // DC0h <- ii; increment PC0; DC0l <- jj; increment PC0
|
case 0x2A: DCI(); break; // DC0h <- ii; increment PC0; DC0l <- jj; increment PC0
|
||||||
case 0x2B: NOP(); break; // No operation (4 cycles - fetch next opcode)
|
case 0x2B: NOP(); break; // No operation (4 cycles - fetch next opcode)
|
||||||
case 0x2C: XDC(); break; // DC0 <-> DC1
|
case 0x2C: XDC(); break; // DC0 <-> DC1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case 0x30: DS(0); break; // SR <- (SR) + H'FF'
|
case 0x30: DS(0); break; // SR <- (SR) + H'FF'
|
||||||
case 0x31: DS(1); break; // SR <- (SR) + H'FF'
|
case 0x31: DS(1); break; // SR <- (SR) + H'FF'
|
||||||
case 0x32: DS(2); break; // SR <- (SR) + H'FF'
|
case 0x32: DS(2); break; // SR <- (SR) + H'FF'
|
||||||
case 0x33: DS(3); break; // SR <- (SR) + H'FF'
|
case 0x33: DS(3); break; // SR <- (SR) + H'FF'
|
||||||
case 0x34: DS(4); break; // SR <- (SR) + H'FF'
|
case 0x34: DS(4); break; // SR <- (SR) + H'FF'
|
||||||
case 0x35: DS(5); break; // SR <- (SR) + H'FF'
|
case 0x35: DS(5); break; // SR <- (SR) + H'FF'
|
||||||
case 0x36: DS(6); break; // SR <- (SR) + H'FF'
|
case 0x36: DS(6); break; // SR <- (SR) + H'FF'
|
||||||
case 0x37: DS(7); break; // SR <- (SR) + H'FF'
|
case 0x37: DS(7); break; // SR <- (SR) + H'FF'
|
||||||
case 0x38: DS(8); break; // SR <- (SR) + H'FF'
|
case 0x38: DS(8); break; // SR <- (SR) + H'FF'
|
||||||
case 0x39: DS(9); break; // SR <- (SR) + H'FF'
|
case 0x39: DS(9); break; // SR <- (SR) + H'FF'
|
||||||
case 0x3A: DS(10); break; // SR <- (SR) + H'FF'
|
case 0x3A: DS(10); break; // SR <- (SR) + H'FF'
|
||||||
case 0x3B: DS(11); break; // SR <- (SR) + H'FF'
|
case 0x3B: DS(11); break; // SR <- (SR) + H'FF'
|
||||||
case 0x3C: DS_ISAR(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR)
|
case 0x3C: DS_ISAR(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR)
|
||||||
case 0x3D: DS_ISAR_INC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR incremented
|
case 0x3D: DS_ISAR_INC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR incremented
|
||||||
case 0x3E: DS_ISAR_DEC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR decremented
|
case 0x3E: DS_ISAR_DEC(); break; // SR <- (SR) + H'FF' (SR pointed to by the ISAR); ISAR decremented
|
||||||
|
|
||||||
case 0x40: LR_A_R(0); break; // A <- (SR)
|
case 0x40: LR_A_R(0); break; // A <- (SR)
|
||||||
case 0x41: LR_A_R(1); break; // A <- (SR)
|
case 0x41: LR_A_R(1); break; // A <- (SR)
|
||||||
case 0x42: LR_A_R(2); break; // A <- (SR)
|
case 0x42: LR_A_R(2); break; // A <- (SR)
|
||||||
case 0x43: LR_A_R(3); break; // A <- (SR)
|
case 0x43: LR_A_R(3); break; // A <- (SR)
|
||||||
case 0x44: LR_A_R(4); break; // A <- (SR)
|
case 0x44: LR_A_R(4); break; // A <- (SR)
|
||||||
case 0x45: LR_A_R(5); break; // A <- (SR)
|
case 0x45: LR_A_R(5); break; // A <- (SR)
|
||||||
case 0x46: LR_A_R(6); break; // A <- (SR)
|
case 0x46: LR_A_R(6); break; // A <- (SR)
|
||||||
case 0x47: LR_A_R(7); break; // A <- (SR)
|
case 0x47: LR_A_R(7); break; // A <- (SR)
|
||||||
case 0x48: LR_A_R(8); break; // A <- (SR)
|
case 0x48: LR_A_R(8); break; // A <- (SR)
|
||||||
case 0x49: LR_A_R(9); break; // A <- (SR)
|
case 0x49: LR_A_R(9); break; // A <- (SR)
|
||||||
case 0x4A: LR_A_R(10); break; // A <- (SR)
|
case 0x4A: LR_A_R(10); break; // A <- (SR)
|
||||||
case 0x4B: LR_A_R(11); break; // A <- (SR)
|
case 0x4B: LR_A_R(11); break; // A <- (SR)
|
||||||
case 0x4C: LR_A_ISAR(); break; // A <- (SR) (SR pointed to by the ISAR)
|
case 0x4C: LR_A_ISAR(); break; // A <- (SR) (SR pointed to by the ISAR)
|
||||||
case 0x4D: LR_A_ISAR_INC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR incremented
|
case 0x4D: LR_A_ISAR_INC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR incremented
|
||||||
case 0x4E: LR_A_ISAR_DEC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR decremented
|
case 0x4E: LR_A_ISAR_DEC(); break; // A <- (SR) (SR pointed to by the ISAR); ISAR decremented
|
||||||
|
|
||||||
case 0x50: LR_R_A(0); break; // SR <- (A)
|
case 0x50: LR_R_A(0); break; // SR <- (A)
|
||||||
case 0x51: LR_R_A(1); break; // SR <- (A)
|
case 0x51: LR_R_A(1); break; // SR <- (A)
|
||||||
case 0x52: LR_R_A(2); break; // SR <- (A)
|
case 0x52: LR_R_A(2); break; // SR <- (A)
|
||||||
case 0x53: LR_R_A(3); break; // SR <- (A)
|
case 0x53: LR_R_A(3); break; // SR <- (A)
|
||||||
case 0x54: LR_R_A(4); break; // SR <- (A)
|
case 0x54: LR_R_A(4); break; // SR <- (A)
|
||||||
case 0x55: LR_R_A(5); break; // SR <- (A)
|
case 0x55: LR_R_A(5); break; // SR <- (A)
|
||||||
case 0x56: LR_R_A(6); break; // SR <- (A)
|
case 0x56: LR_R_A(6); break; // SR <- (A)
|
||||||
case 0x57: LR_R_A(7); break; // SR <- (A)
|
case 0x57: LR_R_A(7); break; // SR <- (A)
|
||||||
case 0x58: LR_R_A(8); break; // SR <- (A)
|
case 0x58: LR_R_A(8); break; // SR <- (A)
|
||||||
case 0x59: LR_R_A(9); break; // SR <- (A)
|
case 0x59: LR_R_A(9); break; // SR <- (A)
|
||||||
case 0x5A: LR_R_A(10); break; // SR <- (A)
|
case 0x5A: LR_R_A(10); break; // SR <- (A)
|
||||||
case 0x5B: LR_R_A(11); break; // SR <- (A)
|
case 0x5B: LR_R_A(11); break; // SR <- (A)
|
||||||
case 0x5C: LR_ISAR_A(); break; // SR <- (A) (SR pointed to by the ISAR)
|
case 0x5C: LR_ISAR_A(); break; // SR <- (A) (SR pointed to by the ISAR)
|
||||||
case 0x5D: LR_ISAR_A_INC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR incremented
|
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 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 0x60: LISU(0); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x61: LISU(1); break; // ISARU <- 0'e' (octal)
|
case 0x61: LISU(1); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x62: LISU(2); break; // ISARU <- 0'e' (octal)
|
case 0x62: LISU(2); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x63: LISU(3); break; // ISARU <- 0'e' (octal)
|
case 0x63: LISU(3); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x64: LISU(4); break; // ISARU <- 0'e' (octal)
|
case 0x64: LISU(4); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x65: LISU(5); break; // ISARU <- 0'e' (octal)
|
case 0x65: LISU(5); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x66: LISU(6); break; // ISARU <- 0'e' (octal)
|
case 0x66: LISU(6); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x67: LISU(7); break; // ISARU <- 0'e' (octal)
|
case 0x67: LISU(7); break; // ISARU <- 0'e' (octal)
|
||||||
case 0x68: LISL(0); break; // ISARL <- 0'e' (octal)
|
case 0x68: LISL(0); break; // ISARL <- 0'e' (octal)
|
||||||
case 0x69: LISL(1); break; // ISARL <- 0'e' (octal)
|
case 0x69: LISL(1); break; // ISARL <- 0'e' (octal)
|
||||||
case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal)
|
case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal)
|
||||||
case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal)
|
case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal)
|
||||||
case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal)
|
case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal)
|
||||||
case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal)
|
case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal)
|
||||||
case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal)
|
case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal)
|
||||||
case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal)
|
case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal)
|
||||||
|
|
||||||
case 0x70: LIS(0); break; // A <- H'0a'
|
case 0x70: LIS(0); break; // A <- H'0a' (CLR)
|
||||||
case 0x71: LIS(1); break; // A <- H'0a'
|
case 0x71: LIS(1); break; // A <- H'0a'
|
||||||
case 0x72: LIS(2); break; // A <- H'0a'
|
case 0x72: LIS(2); break; // A <- H'0a'
|
||||||
case 0x73: LIS(3); break; // A <- H'0a'
|
case 0x73: LIS(3); break; // A <- H'0a'
|
||||||
case 0x74: LIS(4); break; // A <- H'0a'
|
case 0x74: LIS(4); break; // A <- H'0a'
|
||||||
case 0x75: LIS(5); break; // A <- H'0a'
|
case 0x75: LIS(5); break; // A <- H'0a'
|
||||||
case 0x76: LIS(6); break; // A <- H'0a'
|
case 0x76: LIS(6); break; // A <- H'0a'
|
||||||
case 0x77: LIS(7); break; // A <- H'0a'
|
case 0x77: LIS(7); break; // A <- H'0a'
|
||||||
case 0x78: LIS(8); break; // A <- H'0a'
|
case 0x78: LIS(8); break; // A <- H'0a'
|
||||||
case 0x79: LIS(9); break; // A <- H'0a'
|
case 0x79: LIS(9); break; // A <- H'0a'
|
||||||
case 0x7a: LIS(10); break; // A <- H'0a'
|
case 0x7a: LIS(10); break; // A <- H'0a'
|
||||||
case 0x7b: LIS(11); break; // A <- H'0a'
|
case 0x7b: LIS(11); break; // A <- H'0a'
|
||||||
case 0x7c: LIS(12); break; // A <- H'0a'
|
case 0x7c: LIS(12); break; // A <- H'0a'
|
||||||
case 0x7d: LIS(13); break; // A <- H'0a'
|
case 0x7d: LIS(13); break; // A <- H'0a'
|
||||||
case 0x7e: LIS(14); break; // A <- H'0a'
|
case 0x7e: LIS(14); break; // A <- H'0a'
|
||||||
case 0x7f: LIS(15); break; // A <- H'0a'
|
case 0x7f: LIS(15); break; // A <- H'0a'
|
||||||
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
|
|
||||||
case 0x8B: OM(); break; // A <- (A) OR ((DC0)); DC0 <- (DC0) + 1
|
|
||||||
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; // 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)
|
|
||||||
|
|
||||||
|
case 0x80: BTN(); break; // Branch on true - no branch (3 cycle effective NOP)
|
||||||
|
case 0x81: BP(); break; // Branch if positive (sign bit is set)
|
||||||
|
case 0x82: BC(); break; // Branch on carry (carry bit is set)
|
||||||
|
case 0x83: BT_CS(); break; // Branch on carry or positive
|
||||||
|
case 0x84: BZ(); break; // Branch on zero (zero bit is set)
|
||||||
|
case 0x85: BT_ZS(); break; // Branch on zero or positive
|
||||||
|
case 0x86: BT_ZC(); break; // Branch if zero or on carry
|
||||||
|
case 0x87: BT_ZCS(); break; // Branch if zero or positive or on carry
|
||||||
|
|
||||||
case 0xA4: INS_1(4); break; // DB <- Port Address (4 thru 15)
|
case 0x88: AM(); break; // A <- (A) + ((DC0))Binary; DC0 <- (DC0) + 1
|
||||||
case 0xA5: INS_1(5); break; // DB <- Port Address (4 thru 15)
|
case 0x89: AMD(); break; // A <- (A) + ((DC0))Decimal; DC0 <- (DC0) + 1
|
||||||
case 0xA6: INS_1(6); break; // DB <- Port Address (4 thru 15)
|
case 0x8A: NM(); break; // A <- (A) AND ((DC0)); DC0 <- (DC0) + 1
|
||||||
case 0xA7: INS_1(7); break; // DB <- Port Address (4 thru 15)
|
case 0x8B: OM(); break; // A <- (A) OR ((DC0)); DC0 <- (DC0) + 1
|
||||||
case 0xA8: INS_1(8); break; // DB <- Port Address (4 thru 15)
|
case 0x8C: XM(); break; // A <- (A) XOR ((DC0)); DC0 <- (DC0) + 1
|
||||||
case 0xA9: INS_1(9); break; // DB <- Port Address (4 thru 15)
|
case 0x8D: CM(); break; // Set status flags on basis of: ((DC)) + (A) + 1; DC0 <- (DC0) + 1; DC <- (DC) + (A)
|
||||||
case 0xAA: INS_1(10); break; // DB <- Port Address (4 thru 15)
|
case 0x8E: ADC(); break; // DC <- (DC) + (A)
|
||||||
case 0xAB: INS_1(11); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xAC: INS_1(12); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xAD: INS_1(13); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xAE: INS_1(14); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xAF: INS_1(15); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xB0: OUTS_0(0); break; // I/O Port 0 or 1 <- (A)
|
|
||||||
case 0xB1: OUTS_0(1); break; // I/O Port 0 or 1 <- (A)
|
|
||||||
|
|
||||||
|
case 0x8F: BR7(); break; // Branch on ISAR (any of the low 3 bits of ISAR are reset)
|
||||||
|
case 0x90: BR(); break; // Unconditional branch relative (always)
|
||||||
|
case 0x91: BM(); break; // Branch on negative (sign bit is reset)
|
||||||
|
case 0x92: BNC(); break; // Branch if no carry (carry bit is reset)
|
||||||
|
case 0x93: BF_CS(); break; // Branch on false - negative and no carry
|
||||||
|
case 0x94: BNZ(); break; // Branch on not zero (zero bit is reset)
|
||||||
|
case 0x95: BF_ZS(); break; // Branch on false - negative and not zero
|
||||||
|
case 0x96: BF_ZC(); break; // Branch on false - no carry and not zero
|
||||||
|
case 0x97: BF_ZCS(); break; // Branch on false - no carry and not zero and negative
|
||||||
|
case 0x98: BNO(); break; // Branch if no overflow (OVF bit is reset)
|
||||||
|
case 0x99: BF_OS(); break; // Branch on false - no overflow and negative
|
||||||
|
case 0x9A: BF_OC(); break; // Branch on false - no overflow and no carry
|
||||||
|
case 0x9B: BF_OCS(); break; // Branch on false - no overflow and no carry and negative
|
||||||
|
case 0x9C: BF_OZ(); break; // Branch on false - no overflow and not zero
|
||||||
|
case 0x9D: BF_OZS(); break; // Branch on false - no overflow and not zero and negative
|
||||||
|
case 0x9E: BF_OZC(); break; // Branch on false - no overflow and not zero and no carry
|
||||||
|
case 0x9F: BF_OZCS(); break; // Branch on false - no overflow and not zero and no carry and negative
|
||||||
|
|
||||||
case 0xB4: OUTS_1(4); break; // DB <- Port Address (4 thru 15)
|
case 0xA0: INS_0(0); break; // A <- (I/O Port 0 or 1)
|
||||||
case 0xB5: OUTS_1(5); break; // DB <- Port Address (4 thru 15)
|
case 0xA1: INS_0(1); break; // A <- (I/O Port 0 or 1)
|
||||||
case 0xB6: OUTS_1(6); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xB7: OUTS_1(7); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xB8: OUTS_1(8); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xB9: OUTS_1(9); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xBA: OUTS_1(10); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xBB: OUTS_1(11); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xBC: OUTS_1(12); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xBD: OUTS_1(13); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xBE: OUTS_1(14); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xBF: OUTS_1(15); break; // DB <- Port Address (4 thru 15)
|
|
||||||
case 0xC0: AS(0); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC1: AS(1); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC2: AS(2); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC3: AS(3); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC4: AS(4); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC5: AS(5); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC6: AS(6); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC7: AS(7); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC8: AS(8); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xC9: AS(9); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xCA: AS(10); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xCB: AS(11); break; // A <- (A) + (r) Binary
|
|
||||||
case 0xCC: AS_IS(); break; // A <- (A) + (r addressed via ISAR) Binary
|
|
||||||
case 0xCD: AS_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Binary; Increment ISAR
|
|
||||||
case 0xCE: AS_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Binary; Decrement ISAR
|
|
||||||
|
|
||||||
case 0xD0: ASD(0); break; // A <- (A) + (r) Decimal
|
case 0xA4: INS_1(4); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD1: ASD(1); break; // A <- (A) + (r) Decimal
|
case 0xA5: INS_1(5); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD2: ASD(2); break; // A <- (A) + (r) Decimal
|
case 0xA6: INS_1(6); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD3: ASD(3); break; // A <- (A) + (r) Decimal
|
case 0xA7: INS_1(7); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD4: ASD(4); break; // A <- (A) + (r) Decimal
|
case 0xA8: INS_1(8); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD5: ASD(5); break; // A <- (A) + (r) Decimal
|
case 0xA9: INS_1(9); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD6: ASD(6); break; // A <- (A) + (r) Decimal
|
case 0xAA: INS_1(10); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD7: ASD(7); break; // A <- (A) + (r) Decimal
|
case 0xAB: INS_1(11); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD8: ASD(8); break; // A <- (A) + (r) Decimal
|
case 0xAC: INS_1(12); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xD9: ASD(9); break; // A <- (A) + (r) Decimal
|
case 0xAD: INS_1(13); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xDA: ASD(10); break; // A <- (A) + (r) Decimal
|
case 0xAE: INS_1(14); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xDB: ASD(11); break; // A <- (A) + (r) Decimal
|
case 0xAF: INS_1(15); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xDC: ASD_IS(); break; // A <- (A) + (r addressed via ISAR) Decimal
|
|
||||||
case 0xDD: ASD_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Increment ISAR
|
|
||||||
case 0xDE: ASD_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Decrement ISAR
|
|
||||||
|
|
||||||
case 0xE0: XS(0); break; // A <- (A) XOR (r)
|
case 0xB0: OUTS_0(0); break; // I/O Port 0 or 1 <- (A)
|
||||||
case 0xE1: XS(1); break; // A <- (A) XOR (r)
|
case 0xB1: OUTS_0(1); break; // I/O Port 0 or 1 <- (A)
|
||||||
case 0xE2: XS(2); break; // A <- (A) XOR (r)
|
|
||||||
case 0xE3: XS(3); break; // A <- (A) XOR (r)
|
|
||||||
case 0xE4: XS(4); break; // A <- (A) XOR (r)
|
|
||||||
case 0xE5: XS(5); break; // A <- (A) XOR (r)
|
|
||||||
case 0xE6: XS(6); break; // A <- (A) XOR (r)
|
|
||||||
case 0xE7: XS(7); break; // A <- (A) XOR (r)
|
|
||||||
case 0xE8: XS(8); break; // A <- (A) XOR (r)
|
|
||||||
case 0xE9: XS(9); break; // A <- (A) XOR (r)
|
|
||||||
case 0xEA: XS(10); break; // A <- (A) XOR (r)
|
|
||||||
case 0xEB: XS(11); break; // A <- (A) XOR (r)
|
|
||||||
case 0xEC: XS_IS(); break; // A <- (A) XOR (r addressed via ISAR)
|
|
||||||
case 0xED: XS_IS_INC(); break; // A <- (A) XOR (r addressed via ISAR); Increment ISAR
|
|
||||||
case 0xEE: XS_IS_DEC(); break; // A <- (A) XOR (r addressed via ISAR); Decrement ISAR
|
|
||||||
|
|
||||||
case 0xF0: NS(0); break; // A <- (A) XOR (r)
|
case 0xB4: OUTS_1(4); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF1: NS(1); break; // A <- (A) XOR (r)
|
case 0xB5: OUTS_1(5); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF2: NS(2); break; // A <- (A) XOR (r)
|
case 0xB6: OUTS_1(6); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF3: NS(3); break; // A <- (A) XOR (r)
|
case 0xB7: OUTS_1(7); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF4: NS(4); break; // A <- (A) XOR (r)
|
case 0xB8: OUTS_1(8); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF5: NS(5); break; // A <- (A) XOR (r)
|
case 0xB9: OUTS_1(9); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF6: NS(6); break; // A <- (A) XOR (r)
|
case 0xBA: OUTS_1(10); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF7: NS(7); break; // A <- (A) XOR (r)
|
case 0xBB: OUTS_1(11); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF8: NS(8); break; // A <- (A) XOR (r)
|
case 0xBC: OUTS_1(12); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xF9: NS(9); break; // A <- (A) XOR (r)
|
case 0xBD: OUTS_1(13); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xFA: NS(10); break; // A <- (A) XOR (r)
|
case 0xBE: OUTS_1(14); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xFB: NS(11); break; // A <- (A) XOR (r)
|
case 0xBF: OUTS_1(15); break; // DB <- Port Address (4 thru 15)
|
||||||
case 0xFC: NS_IS(); break; // A <- (A) XOR (r addressed via ISAR)
|
|
||||||
case 0xFD: NS_IS_INC(); break; // A <- (A) XOR (r addressed via ISAR); Increment ISAR
|
|
||||||
case 0xFE: NS_IS_DEC(); break; // A <- (A) XOR (r addressed via ISAR); Decrement ISAR
|
|
||||||
|
|
||||||
default: ILLEGAL(); break; // Illegal Opcode
|
case 0xC0: AS(0); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC1: AS(1); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC2: AS(2); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC3: AS(3); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC4: AS(4); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC5: AS(5); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC6: AS(6); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC7: AS(7); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC8: AS(8); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xC9: AS(9); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xCA: AS(10); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xCB: AS(11); break; // A <- (A) + (r) Binary
|
||||||
|
case 0xCC: AS_IS(); break; // A <- (A) + (r addressed via ISAR) Binary
|
||||||
|
case 0xCD: AS_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Binary; Increment ISAR
|
||||||
|
case 0xCE: AS_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Binary; Decrement ISAR
|
||||||
|
|
||||||
|
case 0xD0: ASD(0); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD1: ASD(1); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD2: ASD(2); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD3: ASD(3); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD4: ASD(4); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD5: ASD(5); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD6: ASD(6); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD7: ASD(7); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD8: ASD(8); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xD9: ASD(9); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xDA: ASD(10); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xDB: ASD(11); break; // A <- (A) + (r) Decimal
|
||||||
|
case 0xDC: ASD_IS(); break; // A <- (A) + (r addressed via ISAR) Decimal
|
||||||
|
case 0xDD: ASD_IS_INC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Increment ISAR
|
||||||
|
case 0xDE: ASD_IS_DEC(); break; // A <- (A) + (r addressed via ISAR) Decimal; Decrement ISAR
|
||||||
|
|
||||||
|
case 0xE0: XS(0); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE1: XS(1); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE2: XS(2); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE3: XS(3); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE4: XS(4); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE5: XS(5); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE6: XS(6); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE7: XS(7); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE8: XS(8); break; // A <- (A) XOR (r)
|
||||||
|
case 0xE9: XS(9); break; // A <- (A) XOR (r)
|
||||||
|
case 0xEA: XS(10); break; // A <- (A) XOR (r)
|
||||||
|
case 0xEB: XS(11); break; // A <- (A) XOR (r)
|
||||||
|
case 0xEC: XS_IS(); break; // A <- (A) XOR (r addressed via ISAR)
|
||||||
|
case 0xED: XS_IS_INC(); break; // A <- (A) XOR (r addressed via ISAR); Increment ISAR
|
||||||
|
case 0xEE: XS_IS_DEC(); break; // A <- (A) XOR (r addressed via ISAR); Decrement ISAR
|
||||||
|
|
||||||
|
case 0xF0: NS(0); break; // A <- (A) AND (r)
|
||||||
|
case 0xF1: NS(1); break; // A <- (A) AND (r)
|
||||||
|
case 0xF2: NS(2); break; // A <- (A) AND (r)
|
||||||
|
case 0xF3: NS(3); break; // A <- (A) AND (r)
|
||||||
|
case 0xF4: NS(4); break; // A <- (A) AND (r)
|
||||||
|
case 0xF5: NS(5); break; // A <- (A) AND (r)
|
||||||
|
case 0xF6: NS(6); break; // A <- (A) AND (r)
|
||||||
|
case 0xF7: NS(7); break; // A <- (A) AND (r)
|
||||||
|
case 0xF8: NS(8); break; // A <- (A) AND (r)
|
||||||
|
case 0xF9: NS(9); break; // A <- (A) AND (r)
|
||||||
|
case 0xFA: NS(10); break; // A <- (A) AND (r)
|
||||||
|
case 0xFB: NS(11); break; // A <- (A) AND (r)
|
||||||
|
case 0xFC: NS_IS(); break; // A <- (A) AND (r addressed via ISAR)
|
||||||
|
case 0xFD: NS_IS_INC(); break; // A <- (A) AND (r addressed via ISAR); Increment ISAR
|
||||||
|
case 0xFE: NS_IS_DEC(); break; // A <- (A) AND (r addressed via ISAR); Decrement ISAR
|
||||||
|
|
||||||
|
default: ILLEGAL(); break; // Illegal Opcode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,24 +22,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
Regs[dest] = ReadHardware(Regs[src]);
|
Regs[dest] = ReadHardware(Regs[src]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper method moving from IO to A and setting flags accordingly
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest"></param>
|
||||||
|
/// <param name="src"></param>
|
||||||
public void LR_A_IO_Func(byte dest, byte 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
|
// overflow and carry unconditionally reset
|
||||||
FlagO = false;
|
FlagO = false;
|
||||||
FlagC = false;
|
FlagC = false;
|
||||||
|
|
||||||
Regs[dest] = Regs[src];
|
// data is complemented between I/O pin and accumulator.
|
||||||
|
Regs[dest] = (byte)(Regs[src] ^ 0xFF);
|
||||||
|
|
||||||
FlagZ = Regs[dest] == 0;
|
FlagS = Regs[dest].Bit(7);
|
||||||
|
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||||
// Sign SET if MSB == 0 (positive signed number)
|
|
||||||
FlagS = Regs[dest].Bit(7) == false;
|
|
||||||
|
|
||||||
// ICB flag not affected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearFlags_Func()
|
public void ClearFlags_Func()
|
||||||
|
@ -50,6 +48,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
FlagZ = false;
|
FlagZ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Helper function for transferring data between registers
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest"></param>
|
||||||
|
/// <param name="src"></param>
|
||||||
public void LR_Func(byte dest, byte src)
|
public void LR_Func(byte dest, byte src)
|
||||||
{
|
{
|
||||||
if (dest == DB)
|
if (dest == DB)
|
||||||
|
@ -86,16 +89,12 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
Regs[src] = (byte)((Regs[src] >> shift) & 0xFF);
|
Regs[src] = (byte)((Regs[src] >> shift) & 0xFF);
|
||||||
|
|
||||||
FlagZ = Regs[src] == 0;
|
FlagS = !Regs[src].Bit(7);
|
||||||
|
FlagZ = (Regs[src] & 0xFF) == 0;
|
||||||
// Sign SET if MSB == 0 (positive signed number)
|
|
||||||
FlagS = Regs[src].Bit(7) == false;
|
|
||||||
|
|
||||||
// ICB flag not affected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Left shit 'src' 'shift' positions (zero fill)
|
/// Left shift 'src' 'shift' positions (zero fill)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="src"></param>
|
/// <param name="src"></param>
|
||||||
/// <param name="shift"></param>
|
/// <param name="shift"></param>
|
||||||
|
@ -107,51 +106,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
Regs[src] = (byte)((Regs[src] << shift) & 0xFF);
|
Regs[src] = (byte)((Regs[src] << shift) & 0xFF);
|
||||||
|
|
||||||
FlagZ = Regs[src] == 0;
|
FlagS = !Regs[src].Bit(7);
|
||||||
|
FlagZ = (Regs[src] & 0xFF) == 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Binary addition
|
||||||
|
/// Statuses modified: OVF, ZERO, CARRY, SIGN
|
||||||
|
/// Statuses unaffected: ICB
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest"></param>
|
||||||
|
/// <param name="src"></param>
|
||||||
public void ADD_Func(byte dest, byte src)
|
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 res = Regs[dest] + Regs[src];
|
||||||
var sR = res & 0x80;
|
FlagS = !res.Bit(7);
|
||||||
|
FlagC = res.Bit(8);
|
||||||
FlagS = !((res & 0x80) > 0);
|
FlagZ = (res & 0xFF) == 0;
|
||||||
FlagZ = (res & 0xff) == 0;
|
FlagO = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != res.Bit(7));
|
||||||
FlagO = (sD == sS && sD != sR);
|
Regs[dest] = (byte)(res & 0xFF);
|
||||||
FlagC = (res & 0x100) > 0;
|
|
||||||
|
|
||||||
Regs[dest] = (byte) (res & 0xff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SUB_Func(byte dest, byte src)
|
public void SUB_Func(byte dest, byte src)
|
||||||
|
@ -160,89 +133,95 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
ADD_Func(dest, ALU0);
|
ADD_Func(dest, ALU0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decimal Add
|
||||||
|
/// http://www.bitsavers.org/components/fairchild/f8/67095664_F8_Guide_To_Programming_1976.pdf - page 40
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest"></param>
|
||||||
|
/// <param name="src"></param>
|
||||||
public void ADDD_Func(byte dest, byte src)
|
public void ADDD_Func(byte dest, byte src)
|
||||||
{
|
{
|
||||||
var d = Regs[dest];
|
// The accumulator and the memory location addressed by the DCO registers are assumed to contain two BCD digits.
|
||||||
var s = Regs[src];
|
// The content of the address memory byte is added to the contents of the accumulator to give a BCD result in the accumulator
|
||||||
var bcdRes = d + s;
|
// providing these steps are followed:
|
||||||
|
//
|
||||||
|
// Decimal addition is, in reality, three binary events. Consider 8-bit decimal addition.
|
||||||
|
// Assume two BCD digit augend XY is added to two BCD digit addend l).N, to give a BCD result PQ:
|
||||||
|
// XY
|
||||||
|
// +ZW
|
||||||
|
// --
|
||||||
|
// =PQ
|
||||||
|
//
|
||||||
|
// Two carries are important: any intermediate carry (IC) out of the low order answer digit (Q), and any overall carry (C) out of the high order digit (P).
|
||||||
|
// The three binary steps required to perform BCD addition are as follows:
|
||||||
|
|
||||||
var carryIntermediate = ((d & 0x0F) + (s & 0x0F)) > 0x0F;
|
// STEP 1: Binary add H'66' to the augend. (this should happen before this function is called)
|
||||||
var carryUpper = bcdRes >= 0x100;
|
// STEP 2: Binary add the addend to the sum from Step 1. Record the status of the carry (C) and intermediate carry (IC).
|
||||||
|
|
||||||
// temporary storage and set flags
|
var augend = Regs[dest];
|
||||||
Regs[ALU0] = Regs[dest];
|
var addend = Regs[src];
|
||||||
Regs[ALU1] = Regs[src];
|
var working = (byte)(augend + addend);
|
||||||
ADD_Func(ALU0, ALU1);
|
|
||||||
|
|
||||||
if (!carryIntermediate)
|
bool highCarry;
|
||||||
|
bool lowCarry;
|
||||||
|
|
||||||
|
highCarry = ((augend + addend) & 0xFF0) > 0xF0;
|
||||||
|
lowCarry = (augend & 0x0F) + (addend & 0x0F) > 0x0F;
|
||||||
|
|
||||||
|
var res = augend + addend;
|
||||||
|
FlagC = res.Bit(8);
|
||||||
|
FlagO = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != res.Bit(7));
|
||||||
|
FlagS = !working.Bit(7);
|
||||||
|
FlagZ = (working & 0xFF) == 0;
|
||||||
|
|
||||||
|
|
||||||
|
// STEP 3: Add a factor to the sum from Step 2, based on the status of C and IC. The factor to be added is given by the following table:
|
||||||
|
// C IC Sum to be added
|
||||||
|
// ------------------------
|
||||||
|
// 0 0 0xAA
|
||||||
|
// 0 1 0xA0
|
||||||
|
// 1 0 0x0A
|
||||||
|
// 1 1 0x00
|
||||||
|
//
|
||||||
|
// In Step 3, any carry from the low order digit to the high order digit is suppressed.
|
||||||
|
|
||||||
|
if (!highCarry && !lowCarry)
|
||||||
{
|
{
|
||||||
bcdRes = (bcdRes & 0xF0) | ((bcdRes + 0x0A) & 0x0F);
|
working = (byte)(((working + 0xa0) & 0xf0) + ((working + 0x0a) & 0x0f));
|
||||||
|
}
|
||||||
|
else if (!highCarry && lowCarry)
|
||||||
|
{
|
||||||
|
working = (byte)(((working + 0xa0) & 0xf0) + (working & 0x0f));
|
||||||
|
}
|
||||||
|
else if (highCarry && !lowCarry)
|
||||||
|
{
|
||||||
|
working = (byte)((working & 0xf0) + ((working + 0x0a) & 0x0f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add nothing (0x00)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!carryUpper)
|
Regs[dest] = (byte)(working & 0xFF);
|
||||||
{
|
|
||||||
bcdRes = (bcdRes + 0xA0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Regs[dest] = (byte)(bcdRes & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Binary add the two's compliment of the accumulator to the value on the databus
|
||||||
|
/// Set flags accordingly but accumlator is not touched
|
||||||
|
/// </summary>
|
||||||
public void CI_Func()
|
public void CI_Func()
|
||||||
{
|
{
|
||||||
// compare immediate
|
var twosComp = (byte)((Regs[A] ^ 0xFF) + 1);
|
||||||
// we need to achieve DB - A + 1
|
Regs[ALU0] = twosComp;
|
||||||
// flags set - results not stored
|
|
||||||
var comp = ((Regs[A] ^ 0xFF) + 1);
|
|
||||||
Regs[ALU0] = (byte)comp;
|
|
||||||
Regs[ALU1] = Regs[DB];
|
Regs[ALU1] = Regs[DB];
|
||||||
ADD_Func(ALU1, ALU0);
|
ADD_Func(ALU0, ALU1);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logical AND regs[dest] with regs[src] and store the result in regs[dest]
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest"></param>
|
||||||
|
/// <param name="src"></param>
|
||||||
public void AND_Func(byte dest, byte src)
|
public void AND_Func(byte dest, byte src)
|
||||||
{
|
{
|
||||||
// overflow and carry unconditionally reset
|
// overflow and carry unconditionally reset
|
||||||
|
@ -251,14 +230,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
Regs[dest] = (byte)(Regs[dest] & Regs[src]);
|
Regs[dest] = (byte)(Regs[dest] & Regs[src]);
|
||||||
|
|
||||||
FlagZ = Regs[src] == 0;
|
FlagS = !Regs[dest].Bit(7);
|
||||||
|
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||||
// Sign SET if MSB == 0 (positive signed number)
|
|
||||||
FlagS = Regs[src].Bit(7) == false;
|
|
||||||
|
|
||||||
// ICB flag not affected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logical OR regs[dest] with regs[src] and store the result in regs[dest]
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest"></param>
|
||||||
|
/// <param name="src"></param>
|
||||||
public void OR_Func(byte dest, byte src)
|
public void OR_Func(byte dest, byte src)
|
||||||
{
|
{
|
||||||
// overflow and carry unconditionally reset
|
// overflow and carry unconditionally reset
|
||||||
|
@ -267,14 +247,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
Regs[dest] = (byte)(Regs[dest] | Regs[src]);
|
Regs[dest] = (byte)(Regs[dest] | Regs[src]);
|
||||||
|
|
||||||
FlagZ = Regs[src] == 0;
|
FlagS = !Regs[dest].Bit(7);
|
||||||
|
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||||
// Sign SET if MSB == 0 (positive signed number)
|
|
||||||
FlagS = Regs[src].Bit(7) == false;
|
|
||||||
|
|
||||||
// ICB flag not affected
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The destination (regs[dest]) is XORed with (regs[src]).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dest"></param>
|
||||||
|
/// <param name="src"></param>
|
||||||
public void XOR_Func(byte dest, byte src)
|
public void XOR_Func(byte dest, byte src)
|
||||||
{
|
{
|
||||||
// overflow and carry unconditionally reset
|
// overflow and carry unconditionally reset
|
||||||
|
@ -283,12 +264,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
Regs[dest] = (byte)(Regs[dest] ^ Regs[src]);
|
Regs[dest] = (byte)(Regs[dest] ^ Regs[src]);
|
||||||
|
|
||||||
FlagZ = Regs[src] == 0;
|
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||||
|
FlagS = !Regs[dest].Bit(7);
|
||||||
// Sign SET if MSB == 0 (positive signed number)
|
|
||||||
FlagS = Regs[src].Bit(7) == false;
|
|
||||||
|
|
||||||
// ICB flag not affected
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status Register - Sign Flag
|
/// Status Register - Sign Flag
|
||||||
|
/// When the results of an ALU operation are being interpreted as a signed binary number, the high oidei bit (bit 7) represents the sign of the number
|
||||||
|
/// At the conclusion of instructions that may modify the Accumulator bit 7, the S bit (W register bit 0) is set to the complement of the Accumulator bit 7.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool FlagS
|
public bool FlagS
|
||||||
{
|
{
|
||||||
|
@ -102,6 +104,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status Register - Carry Flag
|
/// Status Register - Carry Flag
|
||||||
|
/// The C bit (W register bit 1) may be visualized as an extension of an 8-bit data unit; i.e., bit 8 of a 9-bit data unit.
|
||||||
|
/// When two bytes are added and the sum is greater than 255, the carry out of bit 7 appears in the C bit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool FlagC
|
public bool FlagC
|
||||||
{
|
{
|
||||||
|
@ -111,6 +115,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status Register - Zero Flag
|
/// Status Register - Zero Flag
|
||||||
|
/// The Z bit (W Register bit 2) is set whenever an arithmetic or logical operation generates a zero result.
|
||||||
|
/// The Z bit is reset to 0 when an arithmetic or logical operation could have generated a zero result, but did not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool FlagZ
|
public bool FlagZ
|
||||||
{
|
{
|
||||||
|
@ -120,6 +126,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status Register - Overflow Flag
|
/// Status Register - Overflow Flag
|
||||||
|
/// The high order Accumulator bit (bit 7) represents the sign of the number.
|
||||||
|
/// When the Accumulator contents are being interpreted as a signed binary number, some method must be provided for indicating carries out of the highest numeric bit (bit 6 of the Accumulator).
|
||||||
|
/// This is done using the 0 bit (W register bit 3). After arithmetic operations, the 0 bit is set to the EXCLUSIVE-OR of Carry Out of bits 6 and bits 7. This simplifies signed binary arithmetic.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool FlagO
|
public bool FlagO
|
||||||
{
|
{
|
||||||
|
@ -129,6 +138,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Status Register - Interrupt Master Enable Flag
|
/// Status Register - Interrupt Master Enable Flag
|
||||||
|
/// External logic can alter the operations sequence within the CPU by interrupting ongoing operations.
|
||||||
|
/// However, interrupts are allowed only when t (W register bit 4) is set to 1; interrupts are disallowed when the ICB bit is reset to O.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool FlagICB
|
public bool FlagICB
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -83,7 +83,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
public const byte OP_AND8 = 107;
|
public const byte OP_AND8 = 107;
|
||||||
public const byte OP_OR8 = 108;
|
public const byte OP_OR8 = 108;
|
||||||
public const byte OP_XOR8 = 109;
|
public const byte OP_XOR8 = 109;
|
||||||
//public const byte OP_COM = 110;
|
public const byte OP_COM = 99;
|
||||||
public const byte OP_SUB8 = 110;
|
public const byte OP_SUB8 = 110;
|
||||||
public const byte OP_ADD8 = 111;
|
public const byte OP_ADD8 = 111;
|
||||||
public const byte OP_CI = 112;
|
public const byte OP_CI = 112;
|
||||||
|
@ -94,17 +94,50 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
public const byte OP_BT = 117;
|
public const byte OP_BT = 117;
|
||||||
public const byte OP_ADD8D = 118;
|
public const byte OP_ADD8D = 118;
|
||||||
public const byte OP_BR7 = 119;
|
public const byte OP_BR7 = 119;
|
||||||
public const byte OP_BF = 120;
|
public const byte OP_BR = 120;
|
||||||
public const byte OP_IN = 121;
|
public const byte OP_BM = 121;
|
||||||
public const byte OP_OUT = 122;
|
public const byte OP_BNC = 122;
|
||||||
|
public const byte OP_BF_CS = 123;
|
||||||
|
public const byte OP_BNZ = 124;
|
||||||
|
public const byte OP_BF_ZS = 125;
|
||||||
|
public const byte OP_BF_ZC = 126;
|
||||||
|
public const byte OP_BF_ZCS = 127;
|
||||||
|
public const byte OP_BNO = 128;
|
||||||
|
public const byte OP_BF_OS = 129;
|
||||||
|
public const byte OP_BF_OC = 130;
|
||||||
|
public const byte OP_BF_OCS = 131;
|
||||||
|
public const byte OP_BF_OZ = 132;
|
||||||
|
public const byte OP_BF_OZS = 133;
|
||||||
|
public const byte OP_BF_OZC = 134;
|
||||||
|
public const byte OP_BF_OZCS = 135;
|
||||||
|
|
||||||
|
public const byte OP_BTN = 136;
|
||||||
|
public const byte OP_BP = 137;
|
||||||
|
public const byte OP_BC = 138;
|
||||||
|
public const byte OP_BT_CS = 139;
|
||||||
|
public const byte OP_BZ = 140;
|
||||||
|
public const byte OP_BT_ZS = 141;
|
||||||
|
public const byte OP_BT_ZC = 142;
|
||||||
|
public const byte OP_BT_ZCS = 143;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public const byte OP_BF = 141;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public const byte OP_IN = 151;
|
||||||
|
public const byte OP_OUT = 152;
|
||||||
//public const byte OP_AS_IS = 123;
|
//public const byte OP_AS_IS = 123;
|
||||||
//public const byte OP_XS_IS = 124;
|
//public const byte OP_XS_IS = 124;
|
||||||
//public const byte OP_NS_IS = 125;
|
//public const byte OP_NS_IS = 125;
|
||||||
public const byte OP_LR_A_DB_IO = 126;
|
public const byte OP_LR_A_DB_IO = 156;
|
||||||
public const byte OP_DS = 127;
|
public const byte OP_DS = 157;
|
||||||
//public const byte OP_CLEAR_FLAGS = 126;
|
//public const byte OP_CLEAR_FLAGS = 126;
|
||||||
//public const byte OP_SET_FLAGS_SZ = 127;
|
//public const byte OP_SET_FLAGS_SZ = 127;
|
||||||
public const byte OP_LIS = 128;
|
public const byte OP_LIS = 158;
|
||||||
|
|
||||||
|
|
||||||
public F3850()
|
public F3850()
|
||||||
|
@ -200,7 +233,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
LR_A_IO_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
LR_A_IO_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// loads supplied index value into register
|
// loads supplied index value into the bottom 4 bits of a register (upper bits are set to 0)
|
||||||
case OP_LIS:
|
case OP_LIS:
|
||||||
Regs[ALU1] = (byte)(cur_instr[instr_pntr++] & 0x0F);
|
Regs[ALU1] = (byte)(cur_instr[instr_pntr++] & 0x0F);
|
||||||
LR_Func(A, ALU1);
|
LR_Func(A, ALU1);
|
||||||
|
@ -252,6 +285,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
XOR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
XOR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// The accumulator is loaded with its one's complement
|
||||||
|
case OP_COM:
|
||||||
|
XOR_Func(A, BYTE);
|
||||||
|
//Regs[A] = (byte)(Regs[A] ^ 0xFF);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
// x <- (x) + 1
|
// x <- (x) + 1
|
||||||
case OP_INC8:
|
case OP_INC8:
|
||||||
ADD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
ADD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||||
|
@ -274,7 +314,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
// ISAR is incremented
|
// ISAR is incremented
|
||||||
case OP_IS_INC:
|
case OP_IS_INC:
|
||||||
Regs[ISAR] = (byte)((Regs[ISAR]& 0x38) | ((Regs[ISAR] + 1) & 0x07));
|
Regs[ISAR] = (byte)((Regs[ISAR] & 0x38) | ((Regs[ISAR] + 1) & 0x07));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ISAR is decremented
|
// ISAR is decremented
|
||||||
|
@ -282,184 +322,223 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
Regs[ISAR] = (byte)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07));
|
Regs[ISAR] = (byte)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// set the upper octal ISAR bits (b3,b4,b5)
|
// set the upper octal ISAR bits (b3,b4,b5) but do not alter the three least significant bits
|
||||||
case OP_LISU:
|
case OP_LISU:
|
||||||
Regs[ISAR] = (byte)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F);
|
Regs[ISAR] = (byte)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// set the lower octal ISAR bits (b0,b1,b2)
|
// set the lower octal ISAR bits (b0,b1,b2) but do not alter the three most significant bits
|
||||||
case OP_LISL:
|
case OP_LISL:
|
||||||
Regs[ISAR] = (byte) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F);
|
Regs[ISAR] = (byte) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// decrement scratchpad byte
|
// Unconditional Branch (relative)
|
||||||
//case OP_DS:
|
case OP_BR:
|
||||||
//SUB_Func(cur_instr[instr_pntr++], ONE);
|
DO_BF_BRANCH(0);
|
||||||
//break;
|
|
||||||
|
|
||||||
// Branch on TRUE
|
|
||||||
case OP_BT:
|
|
||||||
bool branchBT = false;
|
|
||||||
switch (cur_instr[instr_pntr++])
|
|
||||||
{
|
|
||||||
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;
|
break;
|
||||||
|
|
||||||
// Branch on ISARL
|
// Branch on Negative
|
||||||
case OP_BR7:
|
case OP_BM:
|
||||||
instr_pntr = 1; // lose a cycle
|
if (!FlagS)
|
||||||
if (Regs[ISAR].Bit(0) && Regs[ISAR].Bit(1) && Regs[ISAR].Bit(2))
|
DO_BF_BRANCH(0);
|
||||||
{
|
|
||||||
DONT_BRANCH();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
DONT_BF_BRANCH(0);
|
||||||
DO_BRANCH();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Branch on FALSE
|
// Branch if no carry
|
||||||
case OP_BF:
|
case OP_BNC:
|
||||||
bool branchBF = false;
|
if (!FlagC)
|
||||||
switch (cur_instr[instr_pntr++])
|
DO_BF_BRANCH(0);
|
||||||
{
|
else
|
||||||
case 0:
|
DONT_BF_BRANCH(0);
|
||||||
// unconditional branch relative
|
break;
|
||||||
branchBF = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
// Branch if negative and no carry
|
||||||
// branch on negative (sign bit is reset)
|
case OP_BF_CS:
|
||||||
if (!FlagS) branchBF = true;
|
if (!FlagS && !FlagC)
|
||||||
break;
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
case 2:
|
DONT_BF_BRANCH(0);
|
||||||
// branch if no carry (carry bit is reset)
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Branch if not zero
|
||||||
|
case OP_BNZ:
|
||||||
instr_pntr = 0;
|
instr_pntr = 0;
|
||||||
if (branchBF) DO_BRANCH();
|
if (!FlagZ)
|
||||||
else DONT_BRANCH();
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Branch on Negative and not Zero (same thing as branch on negative)
|
||||||
|
case OP_BF_ZS:
|
||||||
|
if (!FlagS && !FlagZ)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no Carry and not Zero
|
||||||
|
case OP_BF_ZC:
|
||||||
|
if (!FlagC && !FlagZ)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no Carry and not Zero and Negative
|
||||||
|
case OP_BF_ZCS:
|
||||||
|
if (!FlagC && !FlagZ && !FlagS)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no Overflow
|
||||||
|
case OP_BNO:
|
||||||
|
if (!FlagO)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no overflow and Negative
|
||||||
|
case OP_BF_OS:
|
||||||
|
if (!FlagO && !FlagS)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no overflow and Negative
|
||||||
|
case OP_BF_OC:
|
||||||
|
if (!FlagO && !FlagC)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no overflow and no carry and Negative
|
||||||
|
case OP_BF_OCS:
|
||||||
|
if (!FlagO && !FlagC && !FlagS)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no overflow and not zero
|
||||||
|
case OP_BF_OZ:
|
||||||
|
if (!FlagO && !FlagZ)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no overflow and not zero and negative
|
||||||
|
case OP_BF_OZS:
|
||||||
|
if (!FlagO && !FlagZ && !FlagS)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no overflow and not zero and no carry
|
||||||
|
case OP_BF_OZC:
|
||||||
|
if (!FlagO && !FlagZ && !FlagC)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on no overflow and not zero and no carry and negative
|
||||||
|
case OP_BF_OZCS:
|
||||||
|
if (!FlagO && !FlagZ && !FlagC && FlagS)
|
||||||
|
DO_BF_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on true - no branch
|
||||||
|
case OP_BTN:
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch if positive
|
||||||
|
case OP_BP:
|
||||||
|
if (FlagS)
|
||||||
|
DO_BT_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on carry
|
||||||
|
case OP_BC:
|
||||||
|
if (FlagC)
|
||||||
|
DO_BT_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on carry or positive
|
||||||
|
case OP_BT_CS:
|
||||||
|
if (FlagC || FlagS)
|
||||||
|
DO_BT_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch if zero
|
||||||
|
case OP_BZ:
|
||||||
|
if (FlagZ)
|
||||||
|
DO_BT_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch if zero or positive
|
||||||
|
case OP_BT_ZS:
|
||||||
|
if (FlagZ || FlagS)
|
||||||
|
DO_BT_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch if zero or carry
|
||||||
|
case OP_BT_ZC:
|
||||||
|
if (FlagZ || FlagC)
|
||||||
|
DO_BT_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch if zero or carry or positive
|
||||||
|
case OP_BT_ZCS:
|
||||||
|
if (FlagZ || FlagC || FlagS)
|
||||||
|
DO_BT_BRANCH(0);
|
||||||
|
else
|
||||||
|
DONT_BT_BRANCH(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Branch on ISARL - if any of the low 3 bits of ISAR are reset
|
||||||
|
case OP_BR7:
|
||||||
|
if (!Regs[ISAR].Bit(0) || !Regs[ISAR].Bit(1) || !Regs[ISAR].Bit(2))
|
||||||
|
DO_BF_BRANCH(1);
|
||||||
|
else
|
||||||
|
DONT_BF_BRANCH(1);
|
||||||
|
break;
|
||||||
|
|
||||||
// A <- (I/O Port 0 or 1)
|
// A <- (I/O Port 0 or 1)
|
||||||
case OP_IN:
|
case OP_IN:
|
||||||
instr_pntr++; // dest == A
|
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||||
Regs[ALU0] = cur_instr[instr_pntr++]; // src
|
//instr_pntr++; // dest == A
|
||||||
IN_Func(A, ALU0);
|
//Regs[ALU0] = cur_instr[instr_pntr++]; // src
|
||||||
|
//IN_Func(A, ALU0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// I/O Port 0 or 1 <- (A)
|
// I/O Port 0 or 1 <- (A)
|
||||||
case OP_OUT:
|
case OP_OUT:
|
||||||
WriteHardware(cur_instr[instr_pntr++], (byte)Regs[cur_instr[instr_pntr++]]);
|
WriteHardware(cur_instr[instr_pntr++], (byte)Regs[cur_instr[instr_pntr++]]);
|
||||||
|
//OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// instruction fetch
|
// instruction fetch
|
||||||
|
@ -485,7 +564,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
// CYCLE LENGTH: L
|
// CYCLE LENGTH: L
|
||||||
case ROMC_01:
|
case ROMC_01:
|
||||||
Read_Func(DB, PC0l, PC0h);
|
Read_Func(DB, PC0l, PC0h);
|
||||||
RegPC0 += (ushort)((sbyte) Regs[DB]);
|
RegPC0 = Regs[DB].Bit(7) ? (ushort)(RegPC0 - (byte)((Regs[DB] ^ 0xFF) + 1)) : (ushort)(RegPC0 + Regs[DB]);
|
||||||
|
/*
|
||||||
|
if (Regs[DB].Bit(7))
|
||||||
|
{
|
||||||
|
// sign bit set
|
||||||
|
var cN = (byte)((Regs[DB] ^ 0xFF) + 1);
|
||||||
|
// subtract
|
||||||
|
RegPC0 -= cN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// positive signed number
|
||||||
|
RegPC0 += Regs[DB];
|
||||||
|
}
|
||||||
|
//RegPC0 += (ushort)((sbyte) Regs[DB]);
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// The device whose DC0 address addresses a memory word within the address space of that device must place on the data bus the contents
|
// The device whose DC0 address addresses a memory word within the address space of that device must place on the data bus the contents
|
||||||
|
@ -522,6 +616,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
// CYCLE LENGTH: L
|
// CYCLE LENGTH: L
|
||||||
case ROMC_05:
|
case ROMC_05:
|
||||||
Write_Func(DC0l, DC0h, DB);
|
Write_Func(DC0l, DC0h, DB);
|
||||||
|
RegDC0++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Place the high order byte of DC0 on the data bus
|
// Place the high order byte of DC0 on the data bus
|
||||||
|
@ -555,7 +650,24 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
// All devices add the 8-bit value on the data bus, treated as a signed binary number, to the data counter
|
// All devices add the 8-bit value on the data bus, treated as a signed binary number, to the data counter
|
||||||
// CYCLE LENGTH: L
|
// CYCLE LENGTH: L
|
||||||
case ROMC_0A:
|
case ROMC_0A:
|
||||||
RegDC0 += (ushort) ((sbyte) Regs[DB]);
|
// The contents of the accumulator are treated as a signed binary number, and are added to the contents of every DCO register.
|
||||||
|
RegDC0 = Regs[DB].Bit(7) ? (ushort)(RegDC0 - (byte)((Regs[DB] ^ 0xFF) + 1)) : (ushort)(RegDC0 + Regs[DB]);
|
||||||
|
/*
|
||||||
|
if (Regs[DB].Bit(7))
|
||||||
|
{
|
||||||
|
// sign bit set
|
||||||
|
var cN = (byte)((Regs[DB] ^ 0xFF) + 1);
|
||||||
|
// subtract
|
||||||
|
RegDC0 -= cN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// positive signed number
|
||||||
|
RegDC0 += Regs[DB];
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//RegDC0 += (ushort) ((sbyte) Regs[DB]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// The device whose address space includes the value in PC1 must place the low order byte of PC1 on the data bus
|
// The device whose address space includes the value in PC1 must place the low order byte of PC1 on the data bus
|
||||||
|
@ -771,7 +883,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
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,
|
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 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 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)
|
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,
|
||||||
|
byte d38 = 0, byte d39 = 0, byte d40 = 0, byte d41 = 0, byte d42 = 0, byte d43 = 0, byte d44 = 0, byte d45 = 0, byte d46 = 0, byte d47 = 0)
|
||||||
{
|
{
|
||||||
cur_instr[0] = d0; cur_instr[1] = d1; cur_instr[2] = d2;
|
cur_instr[0] = d0; cur_instr[1] = d1; cur_instr[2] = d2;
|
||||||
cur_instr[3] = d3; cur_instr[4] = d4; cur_instr[5] = d5;
|
cur_instr[3] = d3; cur_instr[4] = d4; cur_instr[5] = d5;
|
||||||
|
@ -785,7 +898,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
cur_instr[27] = d27; cur_instr[28] = d28; cur_instr[29] = d29;
|
cur_instr[27] = d27; cur_instr[28] = d28; cur_instr[29] = d29;
|
||||||
cur_instr[30] = d30; cur_instr[31] = d31; cur_instr[32] = d32;
|
cur_instr[30] = d30; cur_instr[31] = d31; cur_instr[32] = d32;
|
||||||
cur_instr[33] = d33; cur_instr[34] = d34; cur_instr[35] = d35;
|
cur_instr[33] = d33; cur_instr[34] = d34; cur_instr[35] = d35;
|
||||||
cur_instr[36] = d36; cur_instr[37] = d37;
|
cur_instr[36] = d36; cur_instr[37] = d37; cur_instr[37] = d38;
|
||||||
|
cur_instr[39] = d36; cur_instr[40] = d37; cur_instr[41] = d38;
|
||||||
|
cur_instr[42] = d36; cur_instr[43] = d37; cur_instr[44] = d38;
|
||||||
|
cur_instr[45] = d36; cur_instr[46] = d37; cur_instr[47] = d38;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SyncState(Serializer ser)
|
public void SyncState(Serializer ser)
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
//return 0;
|
//return 0;
|
||||||
return Rom[addr - 0x800];
|
return Rom[addr - 0x800];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ports and related functions
|
/// Ports and related functions
|
||||||
|
/// Based on the luxor schematic here:
|
||||||
|
/// https://web.archive.org/web/20210524083634/http://channelf.se/veswiki/images/3/35/Luxor_page2_300dpi.png
|
||||||
|
/// https://channelf.se/veswiki/images/2/23/Luxor_page3_300dpi.png
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ChannelF
|
public partial class ChannelF
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Channel F has 4 8-bit IO ports connected.
|
/// The Channel F has 4 8-bit IO ports connected.
|
||||||
/// CPU - ports 0 and 1
|
/// CPU (3850) - ports 0 and 1
|
||||||
/// PSU - ports 4 and 5
|
/// PSU (3851) - ports 4 and 5
|
||||||
/// (the second PSU has no IO ports wired up)
|
/// (the second PSU has no IO ports wired up)
|
||||||
|
/// All CPU and PSU I/O ports are active-low with output-latches
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[] PortLatch = new byte[4];
|
public byte[] OutputLatch = new byte[4];
|
||||||
|
|
||||||
public bool ControllersEnabled;
|
public bool LS368Disabled;
|
||||||
|
|
||||||
public const int PORT0 = 0;
|
public const int PORT0 = 0;
|
||||||
public const int PORT1 = 1;
|
public const int PORT1 = 1;
|
||||||
|
@ -23,34 +27,204 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
public const int PORT5 = 3;
|
public const int PORT5 = 3;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CPU attempts to read data byte from the requested port
|
/// CPU is attempting to read from a port
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="addr"></param>
|
/// <param name="addr"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public byte ReadPort(ushort addr)
|
public byte ReadPort(ushort addr)
|
||||||
{
|
{
|
||||||
|
byte result = 1;
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
// Console buttons
|
default:
|
||||||
// b0: TIME
|
break;
|
||||||
// b1: MODE
|
|
||||||
// b2: HOLD
|
|
||||||
// b3: START
|
|
||||||
case 0:
|
case 0:
|
||||||
return (byte)((DataConsole ^ 0xff) | PortLatch[PORT0]);
|
|
||||||
|
|
||||||
// Right controller
|
// Console Buttons - these are connected to pins 0-3 (bits 0-3) through a 7404 Hex Inverter
|
||||||
// b0: RIGHT
|
|
||||||
// b1: LEFT
|
// sample RESET state first - this is connected directly to the RESET pin on the CPU
|
||||||
// b2: BACK
|
if (DataConsole.Bit(5))
|
||||||
// b3: FORWARD
|
{
|
||||||
// b4: CCW
|
CPU.Reset();
|
||||||
// b5: CW
|
}
|
||||||
// b6: PULL
|
|
||||||
// b7: PUSH
|
// get the 4 console buttons state
|
||||||
|
var cButtons = DataConsole & 0x0F;
|
||||||
|
|
||||||
|
// hex inverter
|
||||||
|
var cButtonsInverted = (byte)(DataConsole ^ 0xFF);
|
||||||
|
|
||||||
|
// AND latched output (pins 4 and 7 not connected)
|
||||||
|
result = (byte)((OutputLatch[PORT0] & 0x6F) | cButtonsInverted);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
|
// right controller (player 1)
|
||||||
|
|
||||||
|
// connected through 7404 Hex Inverter
|
||||||
|
// b0: RIGHT
|
||||||
|
// b1: LEFT
|
||||||
|
// b2: BACK
|
||||||
|
// b3: FORWARD
|
||||||
|
// b4: CCW
|
||||||
|
// b5: CW
|
||||||
|
var rButtons = DataRight & 0x3F;
|
||||||
|
|
||||||
|
// connected through LS368 Hex Interting 3-State Buffer
|
||||||
|
// the enable pin of this IC is driven by a CPU write to pin 6 on port 0
|
||||||
|
// b6: PULL
|
||||||
|
// b7: PUSH
|
||||||
|
var rButtons2 = LS368Disabled ? 0 : DataRight & 0xC0;
|
||||||
|
|
||||||
|
// hex inverters
|
||||||
|
var rbuttonsInverted = (byte)((rButtons | rButtons2) ^ 0xFF);
|
||||||
|
|
||||||
|
// AND latched output
|
||||||
|
result = (byte)(OutputLatch[PORT1] | rbuttonsInverted);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
|
||||||
|
// left controller (player 2)
|
||||||
|
|
||||||
|
// connected through LS368 Hex Interting 3-State Buffer
|
||||||
|
// the enable pin of this IC is driven by a CPU write to pin 6 on port 0
|
||||||
|
// b0: RIGHT
|
||||||
|
// b1: LEFT
|
||||||
|
// b2: BACK
|
||||||
|
// b3: FORWARD
|
||||||
|
// b4: CCW
|
||||||
|
// b5: CW
|
||||||
|
// b6: PULL
|
||||||
|
// b7: PUSH
|
||||||
|
var lButtons = LS368Disabled ? 0 : DataLeft & 0xFF;
|
||||||
|
|
||||||
|
// hex inverter
|
||||||
|
var lButtonsInverted = (byte)(lButtons ^ 0xFF);
|
||||||
|
|
||||||
|
// AND latched output
|
||||||
|
result = (byte)(OutputLatch[PORT4] | lButtonsInverted);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
|
||||||
|
// output only IO port - return the last latched output
|
||||||
|
result = OutputLatch[PORT5];
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// CPU is attempting to write to the specified IO port
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public void WritePort(ushort addr, byte value)
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
|
||||||
|
OutputLatch[PORT0] = value;
|
||||||
|
|
||||||
|
// LS368 enable pin on bit 6
|
||||||
|
LS368Disabled = value.Bit(6);
|
||||||
|
|
||||||
|
if (value.Bit(5))
|
||||||
|
{
|
||||||
|
// pulse clocks the 74195 parallel access shift register which feeds inputs of 2 NAND gates
|
||||||
|
// writing data to both sets of even and odd VRAM chips (based on the row and column addresses latched into the 7493 ICs
|
||||||
|
VRAM[(latch_y * 0x80) + latch_x] = (byte)latch_colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
|
||||||
|
OutputLatch[PORT1] = value;
|
||||||
|
|
||||||
|
// set pixel colour
|
||||||
|
// write data 0 = bit6
|
||||||
|
// write data 1 = bit7
|
||||||
|
latch_colour = ((value ^ 0xFF) >> 6) & 0x03;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
|
||||||
|
OutputLatch[PORT4] = value;
|
||||||
|
|
||||||
|
// latch horiztonal column address
|
||||||
|
// these are hex inverted along the way
|
||||||
|
// bit7 is not sent to the 7493s (IO47N) - make it logical 1 before hex inversion
|
||||||
|
var p1Data = value | 0x80;
|
||||||
|
latch_x = (p1Data ^ 0xFF) & 0xFF;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
|
||||||
|
OutputLatch[PORT5] = value;
|
||||||
|
|
||||||
|
// bits 6 (ToneAN) and 7 (ToneBN) are sound generation
|
||||||
|
var audio = (value >> 6) & 0x03;
|
||||||
|
if (audio != tone)
|
||||||
|
{
|
||||||
|
tone = audio;
|
||||||
|
time = 0;
|
||||||
|
amplitude = 1;
|
||||||
|
AudioChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remaining bits latch vertical row address
|
||||||
|
var vert = (value | 0xC0) & 0xFF;
|
||||||
|
latch_y = (vert ^ 0xFF) & 0xFF;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
/// <summary>
|
||||||
|
/// CPU attempts to read data byte from the requested port
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addr"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public byte ReadPort1(ushort addr)
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
// CPU Port 0
|
||||||
|
case 0:
|
||||||
|
// Console buttons
|
||||||
|
// b0: TIME
|
||||||
|
// b1: MODE
|
||||||
|
// b2: HOLD
|
||||||
|
// b3: START
|
||||||
|
return (byte)((DataConsole ^ 0xff) | OutputLatch[PORT0]);
|
||||||
|
|
||||||
|
|
||||||
|
// CPU Port 1
|
||||||
|
case 1:
|
||||||
|
// Right controller
|
||||||
|
// b0: RIGHT
|
||||||
|
// b1: LEFT
|
||||||
|
// b2: BACK
|
||||||
|
// b3: FORWARD
|
||||||
|
// b4: CCW
|
||||||
|
// b5: CW
|
||||||
|
// b6: PULL
|
||||||
|
// b7: PUSH
|
||||||
byte ed1;
|
byte ed1;
|
||||||
if ((PortLatch[PORT0] & 0x40) == 0)
|
if ((OutputLatch[PORT0] & 0x40) == 0)
|
||||||
{
|
{
|
||||||
ed1 = DataRight;
|
ed1 = DataRight;
|
||||||
}
|
}
|
||||||
|
@ -58,20 +232,21 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
{
|
{
|
||||||
ed1 = (byte) (0xC0 | DataRight);
|
ed1 = (byte) (0xC0 | DataRight);
|
||||||
}
|
}
|
||||||
return (byte) ((ed1 ^ 0xff) | PortLatch[PORT1]);
|
return (byte) ((ed1 ^ 0xff) | OutputLatch[PORT1]);
|
||||||
|
|
||||||
// Left controller
|
// PSU Port 4
|
||||||
// b0: RIGHT
|
|
||||||
// b1: LEFT
|
|
||||||
// b2: BACK
|
|
||||||
// b3: FORWARD
|
|
||||||
// b4: CCW
|
|
||||||
// b5: CW
|
|
||||||
// b6: PULL
|
|
||||||
// b7: PUSH
|
|
||||||
case 4:
|
case 4:
|
||||||
|
// Left controller
|
||||||
|
// b0: RIGHT
|
||||||
|
// b1: LEFT
|
||||||
|
// b2: BACK
|
||||||
|
// b3: FORWARD
|
||||||
|
// b4: CCW
|
||||||
|
// b5: CW
|
||||||
|
// b6: PULL
|
||||||
|
// b7: PUSH
|
||||||
byte ed4;
|
byte ed4;
|
||||||
if ((PortLatch[PORT0] & 0x40) == 0)
|
if ((OutputLatch[PORT0] & 0x40) == 0)
|
||||||
{
|
{
|
||||||
ed4 = DataLeft;
|
ed4 = DataLeft;
|
||||||
}
|
}
|
||||||
|
@ -79,10 +254,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
{
|
{
|
||||||
ed4 = 0xff;
|
ed4 = 0xff;
|
||||||
}
|
}
|
||||||
return (byte)((ed4 ^ 0xff) | PortLatch[PORT4]);
|
return (byte)((ed4 ^ 0xff) | OutputLatch[PORT4]);
|
||||||
|
|
||||||
|
// PSU Port 5
|
||||||
case 5:
|
case 5:
|
||||||
return (byte) (0 | PortLatch[PORT5]);
|
return (byte) (0 | OutputLatch[PORT5]);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -94,34 +270,50 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="addr"></param>
|
/// <param name="addr"></param>
|
||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
public void WritePort(ushort addr, byte value)
|
public void WritePort1(ushort addr, byte value)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
// CPU Port 0
|
||||||
case 0:
|
case 0:
|
||||||
PortLatch[PORT0] = value;
|
// b5: Executes a write to VRAM
|
||||||
|
// b6: Enable controllers data
|
||||||
|
OutputLatch[PORT0] = value;
|
||||||
|
|
||||||
if ((value & 0x20) != 0)
|
if ((value & 0x20) != 0)
|
||||||
{
|
{
|
||||||
|
// write to VRAM
|
||||||
var offset = _x + (_y * 128);
|
var offset = _x + (_y * 128);
|
||||||
VRAM[offset] = (byte)(_colour);
|
VRAM[offset] = (byte)(_colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((value & 0x40) != 0)
|
||||||
|
{
|
||||||
|
//ControllersEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// CPU Port 1
|
||||||
case 1:
|
case 1:
|
||||||
|
// bits 6 and 7 decide pixel colour (this is not inverted)
|
||||||
|
|
||||||
PortLatch[PORT1] = value;
|
OutputLatch[PORT1] = value;
|
||||||
|
|
||||||
|
|
||||||
// Write Data0 - indicates that valid data is present for both VRAM ODD0 and EVEN0
|
// Write Data0 - indicates that valid data is present for both VRAM ODD0 and EVEN0
|
||||||
bool data0 = value.Bit(6);
|
//bool data0 = value.Bit(6);
|
||||||
// Write Data1 - indicates that valid data is present for both VRAM ODD1 and EVEN1
|
// Write Data1 - indicates that valid data is present for both VRAM ODD1 and EVEN1
|
||||||
bool data1 = value.Bit(7);
|
//bool data1 = value.Bit(7);
|
||||||
|
|
||||||
|
|
||||||
//_colour = ((value) >> 6) & 3;
|
_colour = (value >> 6) & 0x3;
|
||||||
_colour = ((value ^ 0xff) >> 6) & 0x3;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// PSU Port 4
|
||||||
case 4:
|
case 4:
|
||||||
PortLatch[PORT4] = value;
|
//
|
||||||
|
OutputLatch[PORT4] = value;
|
||||||
_x = (value ^ 0xff) & 0x7f;
|
_x = (value ^ 0xff) & 0x7f;
|
||||||
//_x = (value | 0x80) ^ 0xFF;
|
//_x = (value | 0x80) ^ 0xFF;
|
||||||
/*
|
/*
|
||||||
|
@ -132,14 +324,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// PSU port 5
|
||||||
case 5:
|
case 5:
|
||||||
|
|
||||||
PortLatch[PORT5] = value;
|
OutputLatch[PORT5] = value;
|
||||||
//_y = (value & 31); // ^ 0xff;
|
//_y = (value & 31); // ^ 0xff;
|
||||||
//_y = (value | 0xC0) ^ 0xff;
|
//_y = (value | 0xC0) ^ 0xff;
|
||||||
|
|
||||||
|
@ -163,5 +355,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,45 +7,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ChannelF
|
public partial class ChannelF
|
||||||
{
|
{
|
||||||
/// <summary>
|
private void BuildFrame1()
|
||||||
/// 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 readonly int[] frameBuffer = new int[128 * 64];
|
|
||||||
|
|
||||||
private void BuildFrame()
|
|
||||||
{
|
{
|
||||||
// rows
|
// rows
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|
Loading…
Reference in New Issue