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 bool[] StateConsole = new bool[4];
|
||||
public bool[] StateConsole = new bool[5];
|
||||
public string[] ButtonsConsole =
|
||||
{
|
||||
"TIME", "MODE", "HOLD", "START"
|
||||
"TIME", "MODE", "HOLD", "START", "RESET"
|
||||
};
|
||||
|
||||
public byte DataConsole
|
||||
|
@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
get
|
||||
{
|
||||
int w = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
byte mask = (byte) (1 << i);
|
||||
w = StateConsole[i] ? w | mask : w & ~mask;
|
||||
|
|
|
@ -8,11 +8,10 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
ser.BeginSection("ChannelF");
|
||||
ser.Sync(nameof(VRAM), ref VRAM, false);
|
||||
ser.Sync(nameof(_colour), ref _colour);
|
||||
ser.Sync(nameof(_x), ref _x);
|
||||
ser.Sync(nameof(_y), ref _y);
|
||||
ser.Sync(nameof(_arm), ref _arm);
|
||||
ser.Sync(nameof(ControllersEnabled), ref ControllersEnabled);
|
||||
ser.Sync(nameof(latch_colour), ref latch_colour);
|
||||
ser.Sync(nameof(latch_x), ref latch_x);
|
||||
ser.Sync(nameof(latch_y), ref latch_y);
|
||||
//ser.Sync(nameof(ControllersEnabled), ref ControllersEnabled);
|
||||
CPU.SyncState(ser);
|
||||
ser.EndSection();
|
||||
/*
|
||||
|
|
|
@ -5,15 +5,70 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
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 VirtualWidth => BufferWidth * 2;
|
||||
public int VirtualHeight => (int)((double)BufferHeight * 1.3) * 2;
|
||||
public int BufferWidth => 102; //128
|
||||
public int BufferHeight => 58; //64
|
||||
public int BackgroundColor => Colors.ARGB(0x00, 0x00, 0x00);
|
||||
public int BackgroundColor => Colors.ARGB(0xFF, 0xFF, 0xFF);
|
||||
public int VsyncNumerator => _frameHz;
|
||||
public int VsyncDenominator => 1;
|
||||
|
||||
|
@ -42,10 +97,6 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
}
|
||||
|
||||
return CroppedBuffer;
|
||||
|
||||
//return frameBuffer;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public DisplayType Region => DisplayType.NTSC;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
||||
|
@ -8,10 +10,18 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public partial class ChannelF
|
||||
{
|
||||
[CoreConstructor(VSystemID.Raw.ChannelF)]
|
||||
public ChannelF(CoreComm comm, GameInfo game, byte[] rom)
|
||||
public ChannelF(CoreLoadParameters<ChannelFSettings, ChannelFSyncSettings> lp)
|
||||
{
|
||||
var ser = new BasicServiceProvider(this);
|
||||
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" });
|
||||
|
||||
ControllerDefinition = ChannelFControllerDefinition;
|
||||
|
@ -27,12 +37,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
_tracer = new TraceBuffer(CPU.TraceHeader);
|
||||
|
||||
var bios01 = comm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131253"));
|
||||
var bios02 = comm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131254"));
|
||||
var bios01 = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131253"));
|
||||
var bios02 = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("ChannelF", "ChannelF_sl131254"));
|
||||
|
||||
BIOS01 = bios01;
|
||||
BIOS02 = bios02;
|
||||
|
||||
var rom = _files.First();
|
||||
|
||||
Array.Copy(rom, 0, Rom, 0, rom.Length);
|
||||
|
||||
CalcClock();
|
||||
|
@ -45,6 +57,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
SetupMemoryDomains();
|
||||
}
|
||||
|
||||
internal CoreComm CoreComm { get; }
|
||||
|
||||
public List<GameInfo> _gameInfo;
|
||||
private readonly List<byte[]> _files;
|
||||
|
||||
public F3850 CPU;
|
||||
private readonly TraceBuffer _tracer;
|
||||
public IController _controller;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
public sealed partial class F3850
|
||||
{
|
||||
public const int MaxInstructionLength = 40;
|
||||
public const int MaxInstructionLength = 48;
|
||||
|
||||
public long TotalExecutedCycles;
|
||||
|
||||
|
@ -15,264 +15,268 @@
|
|||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x00: LR_A_KU(); break; // LR A, (KU)
|
||||
case 0x01: LR_A_KL(); break; // LR A, (KL)
|
||||
case 0x02: LR_A_QU(); break; // LR A, (QU)
|
||||
case 0x03: LR_A_QL(); break; // LR A, (QL)
|
||||
case 0x04: LR_KU_A(); break; // LR KU, (A)
|
||||
case 0x05: LR_KL_A(); break; // LR KL, (A)
|
||||
case 0x06: LR_QU_A(); break; // LR QU, (A)
|
||||
case 0x07: LR_QL_A(); break; // LR QL, (A)
|
||||
case 0x08: LR_K_P(); break; // LR K, (P)
|
||||
case 0x09: LR_P_K(); break; // LR P, (K)
|
||||
case 0x0A: LR_A_IS(); break; // LR A, (ISAR)
|
||||
case 0x0B: LR_IS_A(); break; // LR ISAR, (A)
|
||||
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 0x0E: LR_Q_DC(); break; // LR r14, (DC0h); r15 <- (DC0l)
|
||||
case 0x0F: LR_DC_Q(); break; // LR DC0h, (r14); DC0l <- (r15)
|
||||
case 0x10: LR_DC_H(); break; // LR DC0h, (r10); DC0l <- (r11)
|
||||
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 0x13: SHIFT_L(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 0x15: SHIFT_L(4); break; // Shift (A) left four bit positions (zero fill)
|
||||
case 0x16: LM(); break; // A <- ((DC0))
|
||||
case 0x17: ST(); break; // (DC) <- (A)
|
||||
case 0x18: COM(); break; // A <- A XOR 255 (complement A)
|
||||
case 0x19: LNK(); break; // A <- (A) + (C)
|
||||
case 0x1A: DI(); break; // Clear ICB
|
||||
case 0x1B: EI(); break; // Set ICB
|
||||
case 0x1C: POP(); break; // PC0 <- PC1
|
||||
case 0x1D: LR_W_J(); break; // W <- (r9)
|
||||
case 0x1E: LR_J_W(); break; // r9 <- (W)
|
||||
case 0x1F: INC(); break; // A <- (A) + 1
|
||||
case 0x20: LI(); break; // A <- H'aa'
|
||||
case 0x21: NI(); break; // A <- (A) AND H'aa'
|
||||
case 0x22: OI(); break; // A <- (A) OR H'aa'
|
||||
case 0x23: XI(); break; // A <- (A) XOR H'aa'
|
||||
case 0x24: AI(); break; // A <- (A) + H'aa'
|
||||
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 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 0x29: JMP(); break; // A <- H'ii'; PC0l <- H'jj'; PC0h <- (A)
|
||||
case 0x2A: DCI(); break; // DC0h <- ii; increment PC0; DC0l <- jj; increment PC0
|
||||
case 0x2B: NOP(); break; // No operation (4 cycles - fetch next opcode)
|
||||
case 0x2C: XDC(); break; // DC0 <-> DC1
|
||||
case 0x00: LR_A_KU(); break; // LR A, (KU)
|
||||
case 0x01: LR_A_KL(); break; // LR A, (KL)
|
||||
case 0x02: LR_A_QU(); break; // LR A, (QU)
|
||||
case 0x03: LR_A_QL(); break; // LR A, (QL)
|
||||
case 0x04: LR_KU_A(); break; // LR KU, (A)
|
||||
case 0x05: LR_KL_A(); break; // LR KL, (A)
|
||||
case 0x06: LR_QU_A(); break; // LR QU, (A)
|
||||
case 0x07: LR_QL_A(); break; // LR QL, (A)
|
||||
case 0x08: LR_K_P(); break; // LR K, (P)
|
||||
case 0x09: LR_P_K(); break; // LR P, (K)
|
||||
case 0x0A: LR_A_IS(); break; // LR A, (ISAR)
|
||||
case 0x0B: LR_IS_A(); break; // LR ISAR, (A)
|
||||
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 0x0E: LR_Q_DC(); break; // LR r14, (DC0h); r15 <- (DC0l)
|
||||
case 0x0F: LR_DC_Q(); break; // LR DC0h, (r14); DC0l <- (r15)
|
||||
case 0x10: LR_DC_H(); break; // LR DC0h, (r10); DC0l <- (r11)
|
||||
case 0x11: LR_H_DC(); break; // LR r10, (DC0h); r11 <- (DC0l)
|
||||
case 0x12: SR(1); break; // Shift (A) right one bit position (zero fill)
|
||||
case 0x13: SL(1); break; // Shift (A) left one bit position (zero fill)
|
||||
case 0x14: SR(4); break; // Shift (A) right 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 0x17: ST(); break; // (DC) <- (A)
|
||||
case 0x18: COM(); break; // A <- A XOR 255 (complement A)
|
||||
case 0x19: LNK(); break; // A <- (A) + (C)
|
||||
case 0x1A: DI(); break; // Clear ICB
|
||||
case 0x1B: EI(); break; // Set ICB
|
||||
case 0x1C: POP(); break; // PC0 <- PC1
|
||||
case 0x1D: LR_W_J(); break; // W <- (r9)
|
||||
case 0x1E: LR_J_W(); break; // r9 <- (W)
|
||||
case 0x1F: INC(); break; // A <- (A) + 1
|
||||
case 0x20: LI(); break; // A <- H'aa'
|
||||
case 0x21: NI(); break; // A <- (A) AND H'aa'
|
||||
case 0x22: OI(); break; // A <- (A) OR H'aa'
|
||||
case 0x23: XI(); break; // A <- (A) XOR H'aa'
|
||||
case 0x24: AI(); break; // A <- (A) + H'aa'
|
||||
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 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 0x29: JMP(); break; // A <- H'ii'; PC0l <- H'jj'; PC0h <- (A)
|
||||
case 0x2A: DCI(); break; // DC0h <- ii; increment PC0; DC0l <- jj; increment PC0
|
||||
case 0x2B: NOP(); break; // No operation (4 cycles - fetch next opcode)
|
||||
case 0x2C: XDC(); break; // DC0 <-> DC1
|
||||
|
||||
|
||||
|
||||
case 0x30: DS(0); break; // SR <- (SR) + H'FF'
|
||||
case 0x31: DS(1); break; // SR <- (SR) + H'FF'
|
||||
case 0x32: DS(2); break; // SR <- (SR) + H'FF'
|
||||
case 0x33: DS(3); break; // SR <- (SR) + H'FF'
|
||||
case 0x34: DS(4); break; // SR <- (SR) + H'FF'
|
||||
case 0x35: DS(5); break; // SR <- (SR) + H'FF'
|
||||
case 0x36: DS(6); break; // SR <- (SR) + H'FF'
|
||||
case 0x37: DS(7); break; // SR <- (SR) + H'FF'
|
||||
case 0x38: DS(8); break; // SR <- (SR) + H'FF'
|
||||
case 0x39: DS(9); break; // SR <- (SR) + H'FF'
|
||||
case 0x3A: DS(10); 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 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 0x30: DS(0); break; // SR <- (SR) + H'FF'
|
||||
case 0x31: DS(1); break; // SR <- (SR) + H'FF'
|
||||
case 0x32: DS(2); break; // SR <- (SR) + H'FF'
|
||||
case 0x33: DS(3); break; // SR <- (SR) + H'FF'
|
||||
case 0x34: DS(4); break; // SR <- (SR) + H'FF'
|
||||
case 0x35: DS(5); break; // SR <- (SR) + H'FF'
|
||||
case 0x36: DS(6); break; // SR <- (SR) + H'FF'
|
||||
case 0x37: DS(7); break; // SR <- (SR) + H'FF'
|
||||
case 0x38: DS(8); break; // SR <- (SR) + H'FF'
|
||||
case 0x39: DS(9); break; // SR <- (SR) + H'FF'
|
||||
case 0x3A: DS(10); 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 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 0x40: LR_A_R(0); break; // A <- (SR)
|
||||
case 0x41: LR_A_R(1); break; // A <- (SR)
|
||||
case 0x42: LR_A_R(2); break; // A <- (SR)
|
||||
case 0x43: LR_A_R(3); break; // A <- (SR)
|
||||
case 0x44: LR_A_R(4); break; // A <- (SR)
|
||||
case 0x45: LR_A_R(5); break; // A <- (SR)
|
||||
case 0x46: LR_A_R(6); break; // A <- (SR)
|
||||
case 0x47: LR_A_R(7); break; // A <- (SR)
|
||||
case 0x48: LR_A_R(8); break; // A <- (SR)
|
||||
case 0x49: LR_A_R(9); break; // A <- (SR)
|
||||
case 0x4A: LR_A_R(10); 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 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 0x40: LR_A_R(0); break; // A <- (SR)
|
||||
case 0x41: LR_A_R(1); break; // A <- (SR)
|
||||
case 0x42: LR_A_R(2); break; // A <- (SR)
|
||||
case 0x43: LR_A_R(3); break; // A <- (SR)
|
||||
case 0x44: LR_A_R(4); break; // A <- (SR)
|
||||
case 0x45: LR_A_R(5); break; // A <- (SR)
|
||||
case 0x46: LR_A_R(6); break; // A <- (SR)
|
||||
case 0x47: LR_A_R(7); break; // A <- (SR)
|
||||
case 0x48: LR_A_R(8); break; // A <- (SR)
|
||||
case 0x49: LR_A_R(9); break; // A <- (SR)
|
||||
case 0x4A: LR_A_R(10); 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 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 0x50: LR_R_A(0); break; // SR <- (A)
|
||||
case 0x51: LR_R_A(1); break; // SR <- (A)
|
||||
case 0x52: LR_R_A(2); break; // SR <- (A)
|
||||
case 0x53: LR_R_A(3); break; // SR <- (A)
|
||||
case 0x54: LR_R_A(4); break; // SR <- (A)
|
||||
case 0x55: LR_R_A(5); break; // SR <- (A)
|
||||
case 0x56: LR_R_A(6); break; // SR <- (A)
|
||||
case 0x57: LR_R_A(7); break; // SR <- (A)
|
||||
case 0x58: LR_R_A(8); break; // SR <- (A)
|
||||
case 0x59: LR_R_A(9); break; // SR <- (A)
|
||||
case 0x5A: LR_R_A(10); 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 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 0x50: LR_R_A(0); break; // SR <- (A)
|
||||
case 0x51: LR_R_A(1); break; // SR <- (A)
|
||||
case 0x52: LR_R_A(2); break; // SR <- (A)
|
||||
case 0x53: LR_R_A(3); break; // SR <- (A)
|
||||
case 0x54: LR_R_A(4); break; // SR <- (A)
|
||||
case 0x55: LR_R_A(5); break; // SR <- (A)
|
||||
case 0x56: LR_R_A(6); break; // SR <- (A)
|
||||
case 0x57: LR_R_A(7); break; // SR <- (A)
|
||||
case 0x58: LR_R_A(8); break; // SR <- (A)
|
||||
case 0x59: LR_R_A(9); break; // SR <- (A)
|
||||
case 0x5A: LR_R_A(10); 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 0x5D: LR_ISAR_A_INC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR incremented
|
||||
case 0x5E: LR_ISAR_A_DEC(); break; // SR <- (A) (SR pointed to by the ISAR); ISAR decremented
|
||||
|
||||
case 0x60: LISU(0); break; // ISARU <- 0'e' (octal)
|
||||
case 0x61: LISU(1); break; // ISARU <- 0'e' (octal)
|
||||
case 0x62: LISU(2); break; // ISARU <- 0'e' (octal)
|
||||
case 0x63: LISU(3); break; // ISARU <- 0'e' (octal)
|
||||
case 0x64: LISU(4); break; // ISARU <- 0'e' (octal)
|
||||
case 0x65: LISU(5); break; // ISARU <- 0'e' (octal)
|
||||
case 0x66: LISU(6); break; // ISARU <- 0'e' (octal)
|
||||
case 0x67: LISU(7); break; // ISARU <- 0'e' (octal)
|
||||
case 0x68: LISL(0); break; // ISARL <- 0'e' (octal)
|
||||
case 0x69: LISL(1); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal)
|
||||
case 0x60: LISU(0); break; // ISARU <- 0'e' (octal)
|
||||
case 0x61: LISU(1); break; // ISARU <- 0'e' (octal)
|
||||
case 0x62: LISU(2); break; // ISARU <- 0'e' (octal)
|
||||
case 0x63: LISU(3); break; // ISARU <- 0'e' (octal)
|
||||
case 0x64: LISU(4); break; // ISARU <- 0'e' (octal)
|
||||
case 0x65: LISU(5); break; // ISARU <- 0'e' (octal)
|
||||
case 0x66: LISU(6); break; // ISARU <- 0'e' (octal)
|
||||
case 0x67: LISU(7); break; // ISARU <- 0'e' (octal)
|
||||
case 0x68: LISL(0); break; // ISARL <- 0'e' (octal)
|
||||
case 0x69: LISL(1); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6A: LISL(2); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6B: LISL(3); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6C: LISL(4); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6D: LISL(5); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6E: LISL(6); break; // ISARL <- 0'e' (octal)
|
||||
case 0x6F: LISL(7); break; // ISARL <- 0'e' (octal)
|
||||
|
||||
case 0x70: LIS(0); break; // A <- H'0a'
|
||||
case 0x71: LIS(1); break; // A <- H'0a'
|
||||
case 0x72: LIS(2); break; // A <- H'0a'
|
||||
case 0x73: LIS(3); break; // A <- H'0a'
|
||||
case 0x74: LIS(4); break; // A <- H'0a'
|
||||
case 0x75: LIS(5); break; // A <- H'0a'
|
||||
case 0x76: LIS(6); break; // A <- H'0a'
|
||||
case 0x77: LIS(7); break; // A <- H'0a'
|
||||
case 0x78: LIS(8); break; // A <- H'0a'
|
||||
case 0x79: LIS(9); break; // A <- H'0a'
|
||||
case 0x7a: LIS(10); break; // A <- H'0a'
|
||||
case 0x7b: LIS(11); break; // A <- H'0a'
|
||||
case 0x7c: LIS(12); break; // A <- H'0a'
|
||||
case 0x7d: LIS(13); break; // A <- H'0a'
|
||||
case 0x7e: LIS(14); break; // A <- H'0a'
|
||||
case 0x7f: LIS(15); break; // A <- H'0a'
|
||||
case 0x80: BT(0); break; // 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 0x70: LIS(0); break; // A <- H'0a' (CLR)
|
||||
case 0x71: LIS(1); break; // A <- H'0a'
|
||||
case 0x72: LIS(2); break; // A <- H'0a'
|
||||
case 0x73: LIS(3); break; // A <- H'0a'
|
||||
case 0x74: LIS(4); break; // A <- H'0a'
|
||||
case 0x75: LIS(5); break; // A <- H'0a'
|
||||
case 0x76: LIS(6); break; // A <- H'0a'
|
||||
case 0x77: LIS(7); break; // A <- H'0a'
|
||||
case 0x78: LIS(8); break; // A <- H'0a'
|
||||
case 0x79: LIS(9); break; // A <- H'0a'
|
||||
case 0x7a: LIS(10); break; // A <- H'0a'
|
||||
case 0x7b: LIS(11); break; // A <- H'0a'
|
||||
case 0x7c: LIS(12); break; // A <- H'0a'
|
||||
case 0x7d: LIS(13); break; // A <- H'0a'
|
||||
case 0x7e: LIS(14); break; // A <- H'0a'
|
||||
case 0x7f: LIS(15); break; // A <- H'0a'
|
||||
|
||||
case 0x80: 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 0xA5: INS_1(5); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA6: INS_1(6); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA7: INS_1(7); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA8: INS_1(8); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA9: INS_1(9); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xAA: INS_1(10); break; // DB <- Port Address (4 thru 15)
|
||||
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 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: 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 0xB5: OUTS_1(5); break; // DB <- Port Address (4 thru 15)
|
||||
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 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 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 0xA4: INS_1(4); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA5: INS_1(5); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA6: INS_1(6); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA7: INS_1(7); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA8: INS_1(8); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xA9: INS_1(9); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xAA: INS_1(10); break; // DB <- Port Address (4 thru 15)
|
||||
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 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 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 0xF0: NS(0); break; // A <- (A) XOR (r)
|
||||
case 0xF1: NS(1); break; // A <- (A) XOR (r)
|
||||
case 0xF2: NS(2); break; // A <- (A) XOR (r)
|
||||
case 0xF3: NS(3); break; // A <- (A) XOR (r)
|
||||
case 0xF4: NS(4); break; // A <- (A) XOR (r)
|
||||
case 0xF5: NS(5); break; // A <- (A) XOR (r)
|
||||
case 0xF6: NS(6); break; // A <- (A) XOR (r)
|
||||
case 0xF7: NS(7); break; // A <- (A) XOR (r)
|
||||
case 0xF8: NS(8); break; // A <- (A) XOR (r)
|
||||
case 0xF9: NS(9); break; // A <- (A) XOR (r)
|
||||
case 0xFA: NS(10); break; // A <- (A) XOR (r)
|
||||
case 0xFB: NS(11); break; // A <- (A) XOR (r)
|
||||
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
|
||||
case 0xB4: OUTS_1(4); break; // DB <- Port Address (4 thru 15)
|
||||
case 0xB5: OUTS_1(5); break; // DB <- Port Address (4 thru 15)
|
||||
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)
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// helper method that simulates transferring DB to accumulator (as part of an IN operation)
|
||||
// this sets flags accordingly
|
||||
// dest should always == A and src should always == DB for this function
|
||||
|
||||
// overflow and carry unconditionally reset
|
||||
FlagO = false;
|
||||
FlagC = false;
|
||||
|
||||
Regs[dest] = Regs[src];
|
||||
// data is complemented between I/O pin and accumulator.
|
||||
Regs[dest] = (byte)(Regs[src] ^ 0xFF);
|
||||
|
||||
FlagZ = Regs[dest] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[dest].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
FlagS = Regs[dest].Bit(7);
|
||||
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||
}
|
||||
|
||||
public void ClearFlags_Func()
|
||||
|
@ -50,6 +48,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
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)
|
||||
{
|
||||
if (dest == DB)
|
||||
|
@ -86,16 +89,12 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
Regs[src] = (byte)((Regs[src] >> shift) & 0xFF);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
FlagS = !Regs[src].Bit(7);
|
||||
FlagZ = (Regs[src] & 0xFF) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Left shit 'src' 'shift' positions (zero fill)
|
||||
/// Left shift 'src' 'shift' positions (zero fill)
|
||||
/// </summary>
|
||||
/// <param name="src"></param>
|
||||
/// <param name="shift"></param>
|
||||
|
@ -107,51 +106,25 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
Regs[src] = (byte)((Regs[src] << shift) & 0xFF);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
}
|
||||
|
||||
public void ADD_Func_(byte dest, byte src)
|
||||
{
|
||||
// addition of 2 signed bytes
|
||||
ushort dest16 = Regs[dest];
|
||||
|
||||
dest16 += Regs[src];
|
||||
|
||||
FlagC = dest16.Bit(8);
|
||||
FlagZ = (dest16 & 0xFF) == 0;
|
||||
|
||||
ushort ans = (ushort)(dest16 & 0xFF);
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = ans.Bit(7) == false;
|
||||
|
||||
// overflow based on carry out of bit6 XOR carry out of bit7
|
||||
var b6c = dest16 >> 7;
|
||||
var b7c = dest16 >> 8;
|
||||
FlagO = (b6c ^ b7c) != 0;
|
||||
|
||||
Regs[dest] = (byte)ans;
|
||||
FlagS = !Regs[src].Bit(7);
|
||||
FlagZ = (Regs[src] & 0xFF) == 0;
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// addition of 2 signed bytes
|
||||
var sD = Regs[dest] & 0x80;
|
||||
var sS = Regs[src] & 0x80;
|
||||
var res = Regs[dest] + Regs[src];
|
||||
var sR = res & 0x80;
|
||||
|
||||
FlagS = !((res & 0x80) > 0);
|
||||
FlagZ = (res & 0xff) == 0;
|
||||
FlagO = (sD == sS && sD != sR);
|
||||
FlagC = (res & 0x100) > 0;
|
||||
|
||||
Regs[dest] = (byte) (res & 0xff);
|
||||
FlagS = !res.Bit(7);
|
||||
FlagC = res.Bit(8);
|
||||
FlagZ = (res & 0xFF) == 0;
|
||||
FlagO = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != res.Bit(7));
|
||||
Regs[dest] = (byte)(res & 0xFF);
|
||||
}
|
||||
|
||||
public void SUB_Func(byte dest, byte src)
|
||||
|
@ -160,89 +133,95 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
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)
|
||||
{
|
||||
var d = Regs[dest];
|
||||
var s = Regs[src];
|
||||
var bcdRes = d + s;
|
||||
// The accumulator and the memory location addressed by the DCO registers are assumed to contain two BCD digits.
|
||||
// The content of the address memory byte is added to the contents of the accumulator to give a BCD result in the accumulator
|
||||
// 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;
|
||||
var carryUpper = bcdRes >= 0x100;
|
||||
// STEP 1: Binary add H'66' to the augend. (this should happen before this function is called)
|
||||
// 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
|
||||
Regs[ALU0] = Regs[dest];
|
||||
Regs[ALU1] = Regs[src];
|
||||
ADD_Func(ALU0, ALU1);
|
||||
var augend = Regs[dest];
|
||||
var addend = Regs[src];
|
||||
var working = (byte)(augend + addend);
|
||||
|
||||
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)
|
||||
{
|
||||
bcdRes = (bcdRes + 0xA0);
|
||||
}
|
||||
|
||||
Regs[dest] = (byte)(bcdRes & 0xFF);
|
||||
Regs[dest] = (byte)(working & 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()
|
||||
{
|
||||
// compare immediate
|
||||
// we need to achieve DB - A + 1
|
||||
// flags set - results not stored
|
||||
var comp = ((Regs[A] ^ 0xFF) + 1);
|
||||
Regs[ALU0] = (byte)comp;
|
||||
var twosComp = (byte)((Regs[A] ^ 0xFF) + 1);
|
||||
Regs[ALU0] = twosComp;
|
||||
Regs[ALU1] = Regs[DB];
|
||||
ADD_Func(ALU1, ALU0);
|
||||
}
|
||||
/*
|
||||
public void ADDD_Func_(ushort dest, ushort src)
|
||||
{
|
||||
// from MAME f8.cpp (BSD-3)
|
||||
// https://github.com/mamedev/mame/blob/97b67170277437131adf6ed4d60139c172529e4f/src/devices/cpu/f8/f8.cpp#L264
|
||||
byte d = (byte)Regs[dest];
|
||||
byte s = (byte)Regs[src];
|
||||
byte tmp = (byte)(d + s);
|
||||
|
||||
byte c = 0; // high order carry
|
||||
byte ic = 0; // low order carry
|
||||
|
||||
if (((d + s) & 0xFF0) > 0xF0)
|
||||
{
|
||||
c = 1;
|
||||
}
|
||||
|
||||
if ((d & 0x0F) + (s & 0x0F) > 0x0F)
|
||||
{
|
||||
ic = 1;
|
||||
}
|
||||
|
||||
//ALU_ClearFlags();
|
||||
ALU_ADD8_FLAGSONLY_Func(dest, src);
|
||||
Regs[ALU0] = tmp;
|
||||
//ALU_SetFlags_SZ(ALU0);
|
||||
|
||||
if (c == 0 && ic == 0)
|
||||
{
|
||||
tmp = (byte)(((tmp + 0xa0) & 0xf0) + ((tmp + 0x0a) & 0x0f));
|
||||
}
|
||||
|
||||
if (c == 0 && ic == 1)
|
||||
{
|
||||
tmp = (byte)(((tmp + 0xa0) & 0xf0) + (tmp & 0x0f));
|
||||
}
|
||||
|
||||
if (c == 1 && ic == 0)
|
||||
{
|
||||
tmp = (byte)((tmp & 0xf0) + ((tmp + 0x0a) & 0x0f));
|
||||
}
|
||||
|
||||
Regs[dest] = tmp;
|
||||
}
|
||||
*/
|
||||
ADD_Func(ALU0, ALU1);
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
|
@ -251,14 +230,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
Regs[dest] = (byte)(Regs[dest] & Regs[src]);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
FlagS = !Regs[dest].Bit(7);
|
||||
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
|
@ -267,14 +247,15 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
Regs[dest] = (byte)(Regs[dest] | Regs[src]);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
FlagS = !Regs[dest].Bit(7);
|
||||
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// overflow and carry unconditionally reset
|
||||
|
@ -283,12 +264,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
Regs[dest] = (byte)(Regs[dest] ^ Regs[src]);
|
||||
|
||||
FlagZ = Regs[src] == 0;
|
||||
|
||||
// Sign SET if MSB == 0 (positive signed number)
|
||||
FlagS = Regs[src].Bit(7) == false;
|
||||
|
||||
// ICB flag not affected
|
||||
FlagZ = (Regs[dest] & 0xFF) == 0;
|
||||
FlagS = !Regs[dest].Bit(7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,6 +93,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
public bool FlagS
|
||||
{
|
||||
|
@ -102,6 +104,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
public bool FlagC
|
||||
{
|
||||
|
@ -111,6 +115,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
public bool FlagZ
|
||||
{
|
||||
|
@ -120,6 +126,9 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
public bool FlagO
|
||||
{
|
||||
|
@ -129,6 +138,8 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
/// <summary>
|
||||
/// 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>
|
||||
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_OR8 = 108;
|
||||
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_ADD8 = 111;
|
||||
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_ADD8D = 118;
|
||||
public const byte OP_BR7 = 119;
|
||||
public const byte OP_BF = 120;
|
||||
public const byte OP_IN = 121;
|
||||
public const byte OP_OUT = 122;
|
||||
public const byte OP_BR = 120;
|
||||
public const byte OP_BM = 121;
|
||||
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_XS_IS = 124;
|
||||
//public const byte OP_NS_IS = 125;
|
||||
public const byte OP_LR_A_DB_IO = 126;
|
||||
public const byte OP_DS = 127;
|
||||
public const byte OP_LR_A_DB_IO = 156;
|
||||
public const byte OP_DS = 157;
|
||||
//public const byte OP_CLEAR_FLAGS = 126;
|
||||
//public const byte OP_SET_FLAGS_SZ = 127;
|
||||
public const byte OP_LIS = 128;
|
||||
public const byte OP_LIS = 158;
|
||||
|
||||
|
||||
public F3850()
|
||||
|
@ -200,7 +233,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
LR_A_IO_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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:
|
||||
Regs[ALU1] = (byte)(cur_instr[instr_pntr++] & 0x0F);
|
||||
LR_Func(A, ALU1);
|
||||
|
@ -252,6 +285,13 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
XOR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
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
|
||||
case OP_INC8:
|
||||
ADD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
|
@ -274,7 +314,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
// ISAR is incremented
|
||||
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;
|
||||
|
||||
// ISAR is decremented
|
||||
|
@ -282,184 +322,223 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
Regs[ISAR] = (byte)((Regs[ISAR] & 0x38) | ((Regs[ISAR] - 1) & 0x07));
|
||||
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:
|
||||
Regs[ISAR] = (byte)((((Regs[ISAR] & 0x07) | (cur_instr[instr_pntr++] & 0x07) << 3)) & 0x3F);
|
||||
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:
|
||||
Regs[ISAR] = (byte) (((Regs[ISAR] & 0x38) | (cur_instr[instr_pntr++] & 0x07)) & 0x3F);
|
||||
break;
|
||||
|
||||
// decrement scratchpad byte
|
||||
//case OP_DS:
|
||||
//SUB_Func(cur_instr[instr_pntr++], ONE);
|
||||
//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();
|
||||
// Unconditional Branch (relative)
|
||||
case OP_BR:
|
||||
DO_BF_BRANCH(0);
|
||||
break;
|
||||
|
||||
// Branch on ISARL
|
||||
case OP_BR7:
|
||||
instr_pntr = 1; // lose a cycle
|
||||
if (Regs[ISAR].Bit(0) && Regs[ISAR].Bit(1) && Regs[ISAR].Bit(2))
|
||||
{
|
||||
DONT_BRANCH();
|
||||
}
|
||||
|
||||
// Branch on Negative
|
||||
case OP_BM:
|
||||
if (!FlagS)
|
||||
DO_BF_BRANCH(0);
|
||||
else
|
||||
{
|
||||
DO_BRANCH();
|
||||
}
|
||||
DONT_BF_BRANCH(0);
|
||||
break;
|
||||
|
||||
// Branch on FALSE
|
||||
case OP_BF:
|
||||
bool branchBF = false;
|
||||
switch (cur_instr[instr_pntr++])
|
||||
{
|
||||
case 0:
|
||||
// unconditional branch relative
|
||||
branchBF = true;
|
||||
break;
|
||||
// Branch if no carry
|
||||
case OP_BNC:
|
||||
if (!FlagC)
|
||||
DO_BF_BRANCH(0);
|
||||
else
|
||||
DONT_BF_BRANCH(0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// branch on negative (sign bit is reset)
|
||||
if (!FlagS) branchBF = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// branch if no carry (carry bit is reset)
|
||||
if (!FlagC) branchBF = true;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// branch if no carry and negative
|
||||
if (!FlagC && !FlagS) branchBF = true;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// branch if not zero (zero bit is reset)
|
||||
if (!FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// branch if not zero and negative
|
||||
if (!FlagS && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// branch if no carry and result is no zero
|
||||
if (!FlagC && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// branch if not zero, carry and sign
|
||||
if (!FlagS && !FlagC && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// branch if there is no overflow (OVF bit is reset)
|
||||
if (!FlagO) branchBF = true;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// branch if negative and no overflow
|
||||
if (!FlagS && !FlagO) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
// branch if no overflow and no carry
|
||||
if (!FlagO && !FlagC) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xB:
|
||||
// branch if no overflow, no carry & negative
|
||||
if (!FlagO && !FlagC && !FlagS) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xC:
|
||||
// branch if no overflow and not zero
|
||||
if (!FlagO && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xD:
|
||||
// branch if no overflow, not zero and neg
|
||||
if (!FlagS && !FlagO && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xE:
|
||||
// branch if no overflow, no carry & not zero
|
||||
if (!FlagO && !FlagC && !FlagZ) branchBF = true;
|
||||
break;
|
||||
|
||||
case 0xF:
|
||||
// all neg
|
||||
if (!FlagO && !FlagC && !FlagS && FlagZ) branchBF = true;
|
||||
break;
|
||||
}
|
||||
// Branch if negative and no carry
|
||||
case OP_BF_CS:
|
||||
if (!FlagS && !FlagC)
|
||||
DO_BF_BRANCH(0);
|
||||
else
|
||||
DONT_BF_BRANCH(0);
|
||||
break;
|
||||
|
||||
// Branch if not zero
|
||||
case OP_BNZ:
|
||||
instr_pntr = 0;
|
||||
if (branchBF) DO_BRANCH();
|
||||
else DONT_BRANCH();
|
||||
if (!FlagZ)
|
||||
DO_BF_BRANCH(0);
|
||||
else
|
||||
DONT_BF_BRANCH(0);
|
||||
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)
|
||||
case OP_IN:
|
||||
instr_pntr++; // dest == A
|
||||
Regs[ALU0] = cur_instr[instr_pntr++]; // src
|
||||
IN_Func(A, ALU0);
|
||||
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
//instr_pntr++; // dest == A
|
||||
//Regs[ALU0] = cur_instr[instr_pntr++]; // src
|
||||
//IN_Func(A, ALU0);
|
||||
break;
|
||||
|
||||
// I/O Port 0 or 1 <- (A)
|
||||
case OP_OUT:
|
||||
WriteHardware(cur_instr[instr_pntr++], (byte)Regs[cur_instr[instr_pntr++]]);
|
||||
//OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
|
||||
// instruction fetch
|
||||
|
@ -485,7 +564,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
// CYCLE LENGTH: L
|
||||
case ROMC_01:
|
||||
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;
|
||||
|
||||
// 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
|
||||
case ROMC_05:
|
||||
Write_Func(DC0l, DC0h, DB);
|
||||
RegDC0++;
|
||||
break;
|
||||
|
||||
// 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
|
||||
// CYCLE LENGTH: L
|
||||
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;
|
||||
|
||||
// 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,
|
||||
byte d9 = 0, byte d10 = 0, byte d11 = 0, byte d12 = 0, byte d13 = 0, byte d14 = 0, byte d15 = 0, byte d16 = 0, byte d17 = 0, byte d18 = 0,
|
||||
byte d19 = 0, byte d20 = 0, byte d21 = 0, byte d22 = 0, byte d23 = 0, byte d24 = 0, byte d25 = 0, byte d26 = 0, byte d27 = 0, byte d28 = 0,
|
||||
byte d29 = 0, byte d30 = 0, byte d31 = 0, byte d32 = 0, byte d33 = 0, byte d34 = 0, byte d35 = 0, byte d36 = 0, byte d37 = 0)
|
||||
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[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[30] = d30; cur_instr[31] = d31; cur_instr[32] = d32;
|
||||
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)
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
//return 0;
|
||||
return Rom[addr - 0x800];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return 0xFF;
|
||||
}
|
||||
|
|
|
@ -4,18 +4,22 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
/// <summary>
|
||||
/// 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>
|
||||
public partial class ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// The Channel F has 4 8-bit IO ports connected.
|
||||
/// CPU - ports 0 and 1
|
||||
/// PSU - ports 4 and 5
|
||||
/// CPU (3850) - ports 0 and 1
|
||||
/// PSU (3851) - ports 4 and 5
|
||||
/// (the second PSU has no IO ports wired up)
|
||||
/// All CPU and PSU I/O ports are active-low with output-latches
|
||||
/// </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 PORT1 = 1;
|
||||
|
@ -23,34 +27,204 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
public const int PORT5 = 3;
|
||||
|
||||
/// <summary>
|
||||
/// CPU attempts to read data byte from the requested port
|
||||
/// CPU is attempting to read from a port
|
||||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <returns></returns>
|
||||
public byte ReadPort(ushort addr)
|
||||
{
|
||||
byte result = 1;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
// Console buttons
|
||||
// b0: TIME
|
||||
// b1: MODE
|
||||
// b2: HOLD
|
||||
// b3: START
|
||||
default:
|
||||
break;
|
||||
case 0:
|
||||
return (byte)((DataConsole ^ 0xff) | PortLatch[PORT0]);
|
||||
|
||||
// Right controller
|
||||
// b0: RIGHT
|
||||
// b1: LEFT
|
||||
// b2: BACK
|
||||
// b3: FORWARD
|
||||
// b4: CCW
|
||||
// b5: CW
|
||||
// b6: PULL
|
||||
// b7: PUSH
|
||||
// Console Buttons - these are connected to pins 0-3 (bits 0-3) through a 7404 Hex Inverter
|
||||
|
||||
// sample RESET state first - this is connected directly to the RESET pin on the CPU
|
||||
if (DataConsole.Bit(5))
|
||||
{
|
||||
CPU.Reset();
|
||||
}
|
||||
|
||||
// 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:
|
||||
|
||||
// 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;
|
||||
if ((PortLatch[PORT0] & 0x40) == 0)
|
||||
if ((OutputLatch[PORT0] & 0x40) == 0)
|
||||
{
|
||||
ed1 = DataRight;
|
||||
}
|
||||
|
@ -58,20 +232,21 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
ed1 = (byte) (0xC0 | DataRight);
|
||||
}
|
||||
return (byte) ((ed1 ^ 0xff) | PortLatch[PORT1]);
|
||||
return (byte) ((ed1 ^ 0xff) | OutputLatch[PORT1]);
|
||||
|
||||
// Left controller
|
||||
// b0: RIGHT
|
||||
// b1: LEFT
|
||||
// b2: BACK
|
||||
// b3: FORWARD
|
||||
// b4: CCW
|
||||
// b5: CW
|
||||
// b6: PULL
|
||||
// b7: PUSH
|
||||
// PSU Port 4
|
||||
case 4:
|
||||
// Left controller
|
||||
// b0: RIGHT
|
||||
// b1: LEFT
|
||||
// b2: BACK
|
||||
// b3: FORWARD
|
||||
// b4: CCW
|
||||
// b5: CW
|
||||
// b6: PULL
|
||||
// b7: PUSH
|
||||
byte ed4;
|
||||
if ((PortLatch[PORT0] & 0x40) == 0)
|
||||
if ((OutputLatch[PORT0] & 0x40) == 0)
|
||||
{
|
||||
ed4 = DataLeft;
|
||||
}
|
||||
|
@ -79,10 +254,11 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
{
|
||||
ed4 = 0xff;
|
||||
}
|
||||
return (byte)((ed4 ^ 0xff) | PortLatch[PORT4]);
|
||||
return (byte)((ed4 ^ 0xff) | OutputLatch[PORT4]);
|
||||
|
||||
// PSU Port 5
|
||||
case 5:
|
||||
return (byte) (0 | PortLatch[PORT5]);
|
||||
return (byte) (0 | OutputLatch[PORT5]);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
@ -94,34 +270,50 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
/// </summary>
|
||||
/// <param name="addr"></param>
|
||||
/// <param name="value"></param>
|
||||
public void WritePort(ushort addr, byte value)
|
||||
public void WritePort1(ushort addr, byte value)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
// CPU Port 0
|
||||
case 0:
|
||||
PortLatch[PORT0] = value;
|
||||
// b5: Executes a write to VRAM
|
||||
// b6: Enable controllers data
|
||||
OutputLatch[PORT0] = value;
|
||||
|
||||
if ((value & 0x20) != 0)
|
||||
{
|
||||
// write to VRAM
|
||||
var offset = _x + (_y * 128);
|
||||
VRAM[offset] = (byte)(_colour);
|
||||
}
|
||||
|
||||
if ((value & 0x40) != 0)
|
||||
{
|
||||
//ControllersEnabled = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// CPU Port 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
|
||||
bool data0 = value.Bit(6);
|
||||
//bool data0 = value.Bit(6);
|
||||
// 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 ^ 0xff) >> 6) & 0x3;
|
||||
_colour = (value >> 6) & 0x3;
|
||||
break;
|
||||
|
||||
// PSU Port 4
|
||||
case 4:
|
||||
PortLatch[PORT4] = value;
|
||||
//
|
||||
OutputLatch[PORT4] = value;
|
||||
_x = (value ^ 0xff) & 0x7f;
|
||||
//_x = (value | 0x80) ^ 0xFF;
|
||||
/*
|
||||
|
@ -132,14 +324,14 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
// PSU port 5
|
||||
case 5:
|
||||
|
||||
PortLatch[PORT5] = value;
|
||||
OutputLatch[PORT5] = value;
|
||||
//_y = (value & 31); // ^ 0xff;
|
||||
//_y = (value | 0xC0) ^ 0xff;
|
||||
|
||||
|
@ -163,5 +355,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,45 +7,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
/// </summary>
|
||||
public partial class ChannelF
|
||||
{
|
||||
/// <summary>
|
||||
/// 128x64 pixels - 8192x2bits (2 KB)
|
||||
/// For the purposes of this core we will use 8192 bytes and just & 0x03
|
||||
/// </summary>
|
||||
public byte[] VRAM = new byte[(128 * 64)];
|
||||
|
||||
public static readonly int[] FPalette =
|
||||
{
|
||||
/*
|
||||
0x101010, 0xFDFDFD, 0x5331FF, 0x5DCC02, 0xF33F4B, 0xE0E0E0, 0xA6FF91, 0xD0CEFF
|
||||
*/
|
||||
|
||||
Colors.ARGB(0x10, 0x10, 0x10), // Black
|
||||
Colors.ARGB(0xFD, 0xFD, 0xFD), // White
|
||||
Colors.ARGB(0xFF, 0x31, 0x53), // Red
|
||||
Colors.ARGB(0x02, 0xCC, 0x5D), // Green
|
||||
Colors.ARGB(0x4B, 0x3F, 0xF3), // Blue
|
||||
Colors.ARGB(0xE0, 0xE0, 0xE0), // Gray
|
||||
Colors.ARGB(0x91, 0xFF, 0xA6), // BGreen
|
||||
Colors.ARGB(0xCE, 0xD0, 0xFF), // BBlue
|
||||
|
||||
};
|
||||
|
||||
public static readonly int[] CMap =
|
||||
{
|
||||
0, 1, 1, 1,
|
||||
7, 4, 2, 3,
|
||||
5, 4, 2, 3,
|
||||
6, 4, 2, 3,
|
||||
};
|
||||
|
||||
private int _colour = 2;
|
||||
private int _x;
|
||||
private int _y;
|
||||
private int _arm;
|
||||
|
||||
private readonly int[] frameBuffer = new int[128 * 64];
|
||||
|
||||
private void BuildFrame()
|
||||
private void BuildFrame1()
|
||||
{
|
||||
// rows
|
||||
int counter = 0;
|
||||
|
|
Loading…
Reference in New Issue