Merge branch 'master' into c64-refactor

This commit is contained in:
SaxxonPike 2019-07-14 10:45:44 -05:00
commit ad7cae8b71
40 changed files with 2881 additions and 227 deletions

View File

@ -473,7 +473,7 @@ C017BAF7FA0DE71219DFAB91CAA59F8F Woody Pop (W) GG World
A23E89266DDAD3C856E7401D04A49C6C Woody Pop (W) (Rev 1) GG World A23E89266DDAD3C856E7401D04A49C6C Woody Pop (W) (Rev 1) GG World
13F72ACFEA47587F9AA9F655BF98653C World Class Leader Board Golf (UE) GG Sports;Golf USA;Europe 13F72ACFEA47587F9AA9F655BF98653C World Class Leader Board Golf (UE) GG Sports;Golf USA;Europe
D95D381C6AFFB8345EE5457655E393D1 World Cup USA 94 (UE) (En,Fr,De,Es,It,Nl,Pt,Sv) GG Sports;Soccer USA;Europe D95D381C6AFFB8345EE5457655E393D1 World Cup USA 94 (UE) (En,Fr,De,Es,It,Nl,Pt,Sv) GG Sports;Soccer USA;Europe
D8939B64458FAF174CDC1241F777CB59 World Derby (J) GG GGLink Japan D8939B64458FAF174CDC1241F777CB59 World Derby (J) GG SRAM=8192;GGLink Japan
E7EABBFC7A1F1339C4720249AEA92A32 World Series Baseball '95 (U) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA E7EABBFC7A1F1339C4720249AEA92A32 World Series Baseball '95 (U) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA
59359FC38865CFF00C90D6EB148DDC2F World Series Baseball (U) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA 59359FC38865CFF00C90D6EB148DDC2F World Series Baseball (U) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA
05CAC33029F0CAAC27774504C1AA8597 World Series Baseball (U) (Rev 1) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA 05CAC33029F0CAAC27774504C1AA8597 World Series Baseball (U) (Rev 1) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA

View File

@ -1252,6 +1252,7 @@
<Compile Include="tools\VirtualPads\schema\AppleIISchema.cs" /> <Compile Include="tools\VirtualPads\schema\AppleIISchema.cs" />
<Compile Include="tools\VirtualPads\schema\C64Schema.cs" /> <Compile Include="tools\VirtualPads\schema\C64Schema.cs" />
<Compile Include="tools\VirtualPads\schema\ColecoSchema.cs" /> <Compile Include="tools\VirtualPads\schema\ColecoSchema.cs" />
<Compile Include="tools\VirtualPads\schema\VECSchema.cs" />
<Compile Include="tools\VirtualPads\schema\GGLSchema.cs" /> <Compile Include="tools\VirtualPads\schema\GGLSchema.cs" />
<Compile Include="tools\VirtualPads\schema\DualGBSchema.cs" /> <Compile Include="tools\VirtualPads\schema\DualGBSchema.cs" />
<Compile Include="tools\VirtualPads\schema\GBASchema.cs" /> <Compile Include="tools\VirtualPads\schema\GBASchema.cs" />

View File

@ -357,6 +357,8 @@
this.DGBHawksettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.DGBHawksettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GGLSubMenu = new System.Windows.Forms.ToolStripMenuItem(); this.GGLSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.GGLsettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.GGLsettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.VectrexSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.VectrexsettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GenesisSubMenu = new System.Windows.Forms.ToolStripMenuItem(); this.GenesisSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.vDPViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.vDPViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.GenesisGameGenieECDC = new System.Windows.Forms.ToolStripMenuItem(); this.GenesisGameGenieECDC = new System.Windows.Forms.ToolStripMenuItem();
@ -521,6 +523,7 @@
this.virtualBoyToolStripMenuItem, this.virtualBoyToolStripMenuItem,
this.neoGeoPocketToolStripMenuItem, this.neoGeoPocketToolStripMenuItem,
this.zXSpectrumToolStripMenuItem, this.zXSpectrumToolStripMenuItem,
this.VectrexSubMenu,
this.HelpSubMenu, this.HelpSubMenu,
this.amstradCPCToolStripMenuItem}); this.amstradCPCToolStripMenuItem});
this.MainformMenu.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow; this.MainformMenu.LayoutStyle = System.Windows.Forms.ToolStripLayoutStyle.Flow;
@ -3230,6 +3233,21 @@
this.GGLsettingsToolStripMenuItem.Text = "Settings..."; this.GGLsettingsToolStripMenuItem.Text = "Settings...";
this.GGLsettingsToolStripMenuItem.Click += new System.EventHandler(this.GGLSettingsMenuItem_Click); this.GGLsettingsToolStripMenuItem.Click += new System.EventHandler(this.GGLSettingsMenuItem_Click);
// //
// VectrexSubMenu
//
this.VectrexSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.VectrexsettingsToolStripMenuItem});
this.VectrexSubMenu.Name = "VectrexSubMenu";
this.VectrexSubMenu.Size = new System.Drawing.Size(60, 19);
this.VectrexSubMenu.Text = "&Vectrex";
//
// VectrexsettingsToolStripMenuItem
//
this.VectrexsettingsToolStripMenuItem.Name = "VectrexsettingsToolStripMenuItem";
this.VectrexsettingsToolStripMenuItem.Size = new System.Drawing.Size(125, 22);
this.VectrexsettingsToolStripMenuItem.Text = "Settings...";
this.VectrexsettingsToolStripMenuItem.Click += new System.EventHandler(this.VectrexSettingsMenuItem_Click);
//
// GenesisSubMenu // GenesisSubMenu
// //
this.GenesisSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.GenesisSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -4561,6 +4579,8 @@
private System.Windows.Forms.ToolStripMenuItem DGBHawksettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem DGBHawksettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem GGLSubMenu; private System.Windows.Forms.ToolStripMenuItem GGLSubMenu;
private System.Windows.Forms.ToolStripMenuItem GGLsettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem GGLsettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem VectrexSubMenu;
private System.Windows.Forms.ToolStripMenuItem VectrexsettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem GenesisSubMenu; private System.Windows.Forms.ToolStripMenuItem GenesisSubMenu;
private System.Windows.Forms.ToolStripMenuItem GenesisSettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem GenesisSettingsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem AtariSettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem AtariSettingsToolStripMenuItem;

View File

@ -2395,6 +2395,15 @@ namespace BizHawk.Client.EmuHawk
#endregion #endregion
#region Vectrex
private void VectrexSettingsMenuItem_Click(object sender, EventArgs e)
{
GenericCoreConfig.DoDialog(this, "Vectrex Settings");
}
#endregion
#region GEN #region GEN
private void GenVdpViewerMenuItem_Click(object sender, EventArgs e) private void GenVdpViewerMenuItem_Click(object sender, EventArgs e)

View File

@ -1741,6 +1741,7 @@ namespace BizHawk.Client.EmuHawk
pCFXToolStripMenuItem.Visible = false; pCFXToolStripMenuItem.Visible = false;
zXSpectrumToolStripMenuItem.Visible = false; zXSpectrumToolStripMenuItem.Visible = false;
amstradCPCToolStripMenuItem.Visible = false; amstradCPCToolStripMenuItem.Visible = false;
VectrexSubMenu.Visible = false;
switch (system) switch (system)
{ {
@ -1856,6 +1857,9 @@ namespace BizHawk.Client.EmuHawk
case "GGL": case "GGL":
GGLSubMenu.Visible = true; GGLSubMenu.Visible = true;
break; break;
case "VEC":
VectrexSubMenu.Visible = true;
break;
} }
} }

View File

@ -5,6 +5,7 @@ using System.Linq;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.NES; using BizHawk.Emulation.Cores.Nintendo.NES;
using BizHawk.Emulation.Cores.Nintendo.SubNESHawk;
using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES; using BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
@ -17,6 +18,7 @@ namespace BizHawk.Client.EmuHawk
if (core is NES) if (core is NES)
{ {
var nes = (NES)core; var nes = (NES)core;
var ss = nes.GetSyncSettings(); var ss = nes.GetSyncSettings();
var isFds = nes.IsFDS; var isFds = nes.IsFDS;
@ -122,6 +124,117 @@ namespace BizHawk.Client.EmuHawk
yield return NesConsoleButtons(); yield return NesConsoleButtons();
} }
} }
else if (core is SubNESHawk)
{
{
var nes = (SubNESHawk)core;
var ss = nes.GetSyncSettings();
var isFds = nes.IsFDS;
if (ss.Controls.Famicom)
{
yield return StandardController(1);
yield return Famicom2ndController();
switch (ss.Controls.FamicomExpPort)
{
default:
case "UnpluggedFam":
break;
case "Zapper":
yield return Zapper(3);
break;
case "ArkanoidFam":
yield return ArkanoidPaddle(3);
break;
case "Famicom4P":
yield return StandardController(3);
yield return StandardController(4);
break;
case "FamilyBasicKeyboard":
yield return FamicomFamilyKeyboard(3);
break;
case "OekaKids":
yield return OekaKidsTablet(3);
break;
}
}
else
{
var currentControlerNo = 1;
switch (ss.Controls.NesLeftPort)
{
default:
case "UnpluggedNES":
break;
case "ControllerNES":
yield return StandardController(1);
currentControlerNo++;
break;
case "Zapper":
yield return Zapper(1);
currentControlerNo++;
break;
case "ArkanoidNES":
yield return ArkanoidPaddle(1);
currentControlerNo++;
break;
case "FourScore":
yield return StandardController(1);
yield return StandardController(2);
currentControlerNo += 2;
break;
case "PowerPad":
yield return PowerPad(1);
currentControlerNo++;
break;
case "ControllerSNES":
throw new Exception("TODO");
}
switch (ss.Controls.NesRightPort)
{
default:
case "UnpluggedNES":
break;
case "ControllerNES":
yield return StandardController(currentControlerNo);
break;
case "Zapper":
yield return Zapper(currentControlerNo);
break;
case "ArkanoidNES":
yield return ArkanoidPaddle(currentControlerNo);
break;
case "FourScore":
yield return StandardController(currentControlerNo);
yield return StandardController(currentControlerNo + 1);
currentControlerNo += 2;
break;
case "PowerPad":
yield return PowerPad(currentControlerNo);
break;
case "ControllerSNES":
throw new Exception("TODO");
}
if (currentControlerNo == 0)
{
yield return null;
}
}
if (isFds)
{
yield return FdsConsoleButtons(core.ControllerDefinition.BoolButtons.Count(b => b.StartsWith("FDS Insert ")));
}
else
{
yield return NesConsoleButtons();
}
}
}
else else
// Quicknes Can support none, one or two controllers. // Quicknes Can support none, one or two controllers.
{ {

View File

@ -0,0 +1,163 @@
using System.Collections.Generic;
using System.Drawing;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Consoles.Vectrex;
namespace BizHawk.Client.EmuHawk
{
[Schema("VEC")]
public class VECSchema : IVirtualPadSchema
{
public IEnumerable<PadSchema> GetPadSchemas(IEmulator core)
{
var VECSyncSettings = ((VectrexHawk)core).GetSyncSettings().Clone();
var port1 = VECSyncSettings.Port1;
var port2 = VECSyncSettings.Port2;
if (port1 == "Vectrex Digital Controller")
{
yield return StandardController(1);
}
if (port2 == "Vectrex Digital Controller")
{
yield return StandardController(2);
}
if (port1 == "Vectrex Analog Controller")
{
yield return AnalogController(1);
}
if (port2 == "Vectrex Analog Controller")
{
yield return AnalogController(2);
}
}
private static PadSchema StandardController(int controller)
{
return new PadSchema
{
IsConsole = false,
DefaultSize = new Size(200, 100),
Buttons = new[]
{
new PadSchema.ButtonSchema
{
Name = $"P{controller} Up",
Icon = Properties.Resources.BlueUp,
Location = new Point(14, 12),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Down",
Icon = Properties.Resources.BlueDown,
Location = new Point(14, 56),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Left",
Icon = Properties.Resources.Back,
Location = new Point(2, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Right",
Icon = Properties.Resources.Forward,
Location = new Point(24, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 1",
DisplayName = "1",
Location = new Point(74, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 2",
DisplayName = "2",
Location = new Point(98, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 3",
DisplayName = "3",
Location = new Point(122, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 4",
DisplayName = "4",
Location = new Point(146, 34),
Type = PadSchema.PadInputType.Boolean
}
}
};
}
private static PadSchema AnalogController(int controller)
{
return new PadSchema
{
IsConsole = false,
DefaultSize = new Size(280, 380),
Buttons = new[]
{
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 1",
DisplayName = "1",
Location = new Point(74, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 2",
DisplayName = "2",
Location = new Point(98, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 3",
DisplayName = "3",
Location = new Point(122, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Button 4",
DisplayName = "4",
Location = new Point(146, 34),
Type = PadSchema.PadInputType.Boolean
},
new PadSchema.ButtonSchema
{
Name = $"P{controller} Stick X",
Location = new Point(2, 80),
MinValue = 127,
MidValue = 0,
MaxValue = -128,
MinValueSec = -128,
MidValueSec = 0,
MaxValueSec = 127,
Type = PadSchema.PadInputType.AnalogStick,
SecondaryNames = new[]
{
$"P{controller} Stick Y",
}
}
}
};
}
}
}

View File

@ -1543,6 +1543,14 @@
<Compile Include="CPUs\CP1610\CP1610.Disassembler.cs" /> <Compile Include="CPUs\CP1610\CP1610.Disassembler.cs" />
<Compile Include="CPUs\CP1610\CP1610.Execute.cs" /> <Compile Include="CPUs\CP1610\CP1610.Execute.cs" />
<Compile Include="CPUs\HuC6280\HuC6280_CDL.cs" /> <Compile Include="CPUs\HuC6280\HuC6280_CDL.cs" />
<Compile Include="CPUs\MC6800\Disassembler.cs" />
<Compile Include="CPUs\MC6800\Execute.cs" />
<Compile Include="CPUs\MC6800\Indexed_Modes.cs" />
<Compile Include="CPUs\MC6800\Interrupts.cs" />
<Compile Include="CPUs\MC6800\MC6800.cs" />
<Compile Include="CPUs\MC6800\Operations.cs" />
<Compile Include="CPUs\MC6800\OP_Tables.cs" />
<Compile Include="CPUs\MC6800\Registers.cs" />
<Compile Include="CPUs\MC6809\Execute.cs" /> <Compile Include="CPUs\MC6809\Execute.cs" />
<Compile Include="CPUs\MC6809\Interrupts.cs" /> <Compile Include="CPUs\MC6809\Interrupts.cs" />
<Compile Include="CPUs\MC6809\MC6809.cs" /> <Compile Include="CPUs\MC6809\MC6809.cs" />

View File

@ -0,0 +1,319 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BizHawk.Emulation.Common.Components.MC6800
{
public sealed partial class MC6800
{
static string[] table =
{
"???", // 00
"NOP", // 01
"???", // 02
"???", // 03
"???", // 04
"???", // 05
"TAP", // 06
"TPA", // 07
"INX", // 08
"DEX", // 09
"CLV", // 0a
"SEV", // 0b
"CLC", // 0c
"SEC", // 0d
"CLI", // 0e
"SEI", // 0f
"SBA", // 10
"CBA", // 11
"???", // 12
"???", // 13
"???", // 14
"???", // 15
"TAB", // 16
"TBA", // 17
"???", // 18
"DAA", // 19
"???", // 1a
"ABA", // 1b
"???", // 1c
"???", // 1d
"???", // 1e
"???", // 1f
"BRA i8", // 20
"???", // 21
"BHI i8", // 22
"BLS i8", // 23
"BHS i8", // 24
"BLO i8", // 25
"BNE i8", // 26
"BEQ i8", // 27
"BVC i8", // 28
"BVS i8", // 29
"BPL i8", // 2a
"BMI i8", // 2b
"BGE i8", // 2c
"BLT i8", // 2d
"BGT i8", // 2e
"BLE i8", // 2f
"TSX", // 30
"INS", // 31
"PULA", // 32
"PULB", // 33
"DES", // 34
"TXS", // 35
"PSHA", // 36
"PSHB", // 37
"???", // 38
"RTS", // 39
"???", // 3a
"RTI", // 3b
"???", // 3c
"???", // 3d
"WAI", // 3e
"SWI", // 3f
"NEG A", // 40
"???", // 41
"???", // 42
"COM A", // 43
"LSR A", // 44
"???", // 45
"ROR A", // 46
"ASR A", // 47
"ASL A", // 48
"ROL A", // 49
"DEC A", // 4a
"???", // 4b
"INC A", // 4c
"TST A", // 4d
"???", // 4e
"CLR A", // 4f
"NEG B", // 50
"???", // 51
"???", // 52
"COM B", // 53
"LSR B", // 54
"???", // 55
"ROR B", // 56
"ASR B", // 57
"ASL B", // 58
"ROL B", // 59
"DEC B", // 5a
"???", // 5b
"INC B", // 5c
"TST B", // 5d
"???", // 5e
"CLR B", // 5f
"NEG ix16", // 60
"???", // 61
"???", // 62
"COM ix16", // 63
"LSR ix16", // 64
"???", // 65
"ROR ix16", // 66
"ASR ix16", // 67
"ASL ix16", // 68
"ROL ix16", // 69
"DEC ix16", // 6a
"???", // 6b
"INC ix16", // 6c
"TST ix16", // 6d
"JMP ix16", // 6e
"CLR ix16", // 6f
"NEG ex16", // 70
"???", // 71
"???", // 72
"COM ex16", // 73
"LSR ex16", // 74
"???", // 75
"ROR ex16", // 76
"ASR ex16", // 77
"ASL ex16", // 78
"ROL ex16", // 79
"DEC ex16", // 7a
"???", // 7b
"INC ex16", // 7c
"TST ex16", // 7d
"JMP ex16", // 7e
"CLR ex16", // 7f
"SUB A,i8", // 80
"CMP A,i8", // 81
"SBC A,i8", // 82
"???", // 83
"AND A,i8", // 84
"BIT A,i8", // 85
"LD A,i8", // 86
"???", // 87
"EOR A,i8", // 88
"ADC A,i8", // 89
"OR A,i8", // 8a
"ADD A,i8", // 8b
"CMP X,i16", // 8c
"BSR i8", // 8d
"LD SP,i16", // 8e
"???", // 8f
"SUB A,DP+i8", // 90
"CMP A,DP+i8", // 91
"SBC A,DP+i8", // 92
"???", // 93
"AND A,DP+i8", // 94
"BIT A,DP+i8", // 95
"LD A,DP+i8", // 96
"ST A,DP+i8", // 97
"EOR A,DP+i8", // 98
"ADC A,DP+i8", // 99
"OR A,DP+i8", // 9a
"ADD A,DP+i8", // 9b
"CMP X,DP+i8", // 9c
"???", // 9d
"LD SP,DP+i8", // 9e
"ST SP,DP+i8", // 9f
"SUB A,ix16", // a0
"CMP A,ix16", // a1
"SBC A,ix16", // a2
"???", // a3
"AND A,ix16", // a4
"BIT A,ix16", // a5
"LD A,ix16", // a6
"ST A,ix16", // a7
"EOR A,ix16", // a8
"ADC A,ix16", // a9
"OR A,ix16", // aa
"ADD A,ix16", // ab
"CMP X,ix16", // ac
"JSR ix16", // ad
"LD SP,ix16", // ae
"ST SP,ix16", // af
"SUB A,ex16", // b0
"CMP A,ex16", // b1
"SBC A,ex16", // b2
"???", // b3
"AND A,ex16", // b4
"BIT A,ex16", // b5
"LD A,ex16", // b6
"ST A,ex16", // b7
"EOR A,ex16", // b8
"ADC A,ex16", // b9
"OR A,ex16", // ba
"ADD A,ex16", // bb
"CMP X,ex16", // bc
"JSR ex16", // bd
"LD SP,ex16", // be
"ST SP,ex16", // bf
"SUB B,i8", // c0
"CMP B,i8", // c1
"SBC B,i8", // c2
"???", // c3
"AND B,i8", // c4
"BIT B,i8", // c5
"LD B,i8", // c6
"???", // c7
"EOR B,i8", // c8
"ADC B,i8", // c9
"OR B,i8", // ca
"ADD B,i8", // cb
"???", // cc
"???", // cd
"LD X,i16", // ce
"???", // cf
"SUB B,DP+i8", // d0
"CMP B,DP+i8", // d1
"SBC B,DP+i8", // d2
"???", // d3
"AND B,DP+i8", // d4
"BIT B,DP+i8", // d5
"LD B,DP+i8", // d6
"ST B,DP+i8", // d7
"EOR B,DP+i8", // d8
"ADC B,DP+i8", // d9
"OR B,DP+i8", // da
"ADD B,DP+i8", // db
"???", // dc
"???", // dd
"LD X,DP+i8", // de
"ST X,DP+i8", // df
"SUB B,ix16", // e0
"CMP B,ix16", // e1
"SBC B,ix16", // e2
"???", // e3
"AND B,ix16", // e4
"BIT B,ix16", // e5
"LD B,ix16", // e6
"ST B,ix16", // e7
"EOR B,ix16", // e8
"ADC B,ix16", // e9
"OR B,ix16", // ea
"ADD B,ix16", // eb
"???", // ec
"???", // ed
"LD X,ix16", // ee
"ST X,ix16", // ef
"SUB B,ex16", // f0
"CMP B,ex16", // f1
"SBC B,ex16", // f2
"???", // f3
"AND B,ex16", // f4
"BIT B,ex16", // f5
"LD B,ex16", // f6
"ST B,ex16", // f7
"EOR B,ex16", // f8
"ADC B,ex16", // f9
"OR B,ex16", // fa
"ADD B,ex16", // fb
"???", // fc
"???", // fd
"LD X,ex16", // fe
"ST X,ex16", // ff
};
public static string Disassemble(ushort addr, Func<ushort, byte> reader, out ushort size)
{
ushort origaddr = addr;
List<byte> bytes = new List<byte>();
bytes.Add(reader(addr++));
string result = table[bytes[0]];
if (result.Contains("i8"))
{
byte d = reader(addr++);
bytes.Add(d);
result = result.Replace("i8", string.Format("#{0:X2}h", d));
}
else if (result.Contains("i16"))
{
byte dhi = reader(addr++);
byte dlo = reader(addr++);
bytes.Add(dhi);
bytes.Add(dlo);
result = result.Replace("i16", string.Format("#{0:X2}{1:X2}h", dhi, dlo));
}
else if (result.Contains("ex16"))
{
byte dhi = reader(addr++);
byte dlo = reader(addr++);
bytes.Add(dhi);
bytes.Add(dlo);
result = result.Replace("ex16", "(" + string.Format("#{0:X2}{1:X2}h", dhi, dlo) + ")");
}
else if (result.Contains("ix16"))
{
byte d = reader(addr++);
bytes.Add(d);
result = result.Replace("ix16", "X + " + "ea");
result = result.Replace("ea", string.Format("{0:N}h", d));
}
StringBuilder ret = new StringBuilder();
ret.Append(string.Format("{0:X4}: ", origaddr));
foreach (var b in bytes)
ret.Append(string.Format("{0:X2} ", b));
while (ret.Length < 22)
ret.Append(' ');
ret.Append(result);
size = (ushort)(addr - origaddr);
return ret.ToString();
}
}
}

View File

@ -0,0 +1,285 @@
using System;
namespace BizHawk.Emulation.Common.Components.MC6800
{
public partial class MC6800
{
public ulong TotalExecutedCycles;
// variables for executing instructions
public int instr_pntr = 0;
public ushort[] cur_instr = new ushort[60];
public int opcode_see;
public int IRQS;
public int irq_pntr;
ushort reg_d_ad;
ushort reg_h_ad;
ushort reg_l_ad;
public void FetchInstruction(byte opcode)
{
opcode_see = opcode;
switch (opcode)
{
case 0x00: ILLEGAL(); break; // ILLEGAL
case 0x01: NOP_(); break; // NOP (Inherent)
case 0x02: ILLEGAL(); break; // ILLEGAL
case 0x03: ILLEGAL(); break; // ILLEGAL
case 0x04: ILLEGAL(); break; // ILLEGAL
case 0x05: ILLEGAL(); break; // ILLEGAL
case 0x06: REG_OP(TAP, A); break; // TAP (Inherent)
case 0x07: REG_OP(TPA, A); break; // TPA (Inherent)
case 0x08: REG_OP_16(INX, X); break; // INX (Inherent)
case 0x09: REG_OP_16(DEX, X); break; // DEX (Inherent)
case 0x0A: REG_OP(CLV, CC); break; // CLV (Inherent)
case 0x0B: REG_OP(SEV, CC); break; // SEV (Inherent)
case 0x0C: REG_OP(CLC, CC); break; // CLC (Inherent)
case 0x0D: REG_OP(SEC, CC); break; // SEC (Inherent)
case 0x0E: REG_OP(CLI, CC); break; // CLI (Inherent)
case 0x0F: REG_OP(SEI, CC); break; // SEI (Inherent)
case 0x10: REG_OP(SBA, A); break; // SBA (Inherent)
case 0x11: REG_OP(CBA, A); break; // CBA (Inherent)
case 0x12: ILLEGAL(); break; // ILLEGAL
case 0x13: ILLEGAL(); break; // ILLEGAL
case 0x14: ILLEGAL(); break; // ILLEGAL
case 0x15: ILLEGAL(); break; // ILLEGAL
case 0x16: REG_OP(TAB, A); break; // TAB (Inherent)
case 0x17: REG_OP(TBA, A); break; // TBA (Inherent)
case 0x18: ILLEGAL(); break; // ILLEGAL
case 0x19: REG_OP(DA, A); break; // DAA (Inherent)
case 0x1A: ILLEGAL(); break; // ILLEGAL
case 0x1B: REG_OP(ABA, A); break; // ABA (Inherent)
case 0x1C: ILLEGAL(); break; // ILLEGAL
case 0x1D: ILLEGAL(); break; // ILLEGAL
case 0x1E: ILLEGAL(); break; // ILLEGAL
case 0x1F: ILLEGAL(); break; // ILLEGAL
case 0x20: BR_(true); break; // BRA (Relative)
case 0x21: ILLEGAL(); break; // ILLEGAL
case 0x22: BR_(!(FlagC | FlagZ)); break; // BHI (Relative)
case 0x23: BR_(FlagC | FlagZ); break; // BLS (Relative)
case 0x24: BR_(!FlagC); break; // BHS , BCC (Relative)
case 0x25: BR_(FlagC); break; // BLO , BCS (Relative)
case 0x26: BR_(!FlagZ); break; // BNE (Relative)
case 0x27: BR_(FlagZ); break; // BEQ (Relative)
case 0x28: BR_(!FlagV); break; // BVC (Relative)
case 0x29: BR_(FlagV); break; // BVS (Relative)
case 0x2A: BR_(!FlagN); break; // BPL (Relative)
case 0x2B: BR_(FlagN); break; // BMI (Relative)
case 0x2C: BR_(FlagN == FlagV); break; // BGE (Relative)
case 0x2D: BR_(FlagN ^ FlagV); break; // BLT (Relative)
case 0x2E: BR_((!FlagZ) & (FlagN == FlagV)); break; // BGT (Relative)
case 0x2F: BR_(FlagZ | (FlagN ^ FlagV)); break; // BLE (Relative)
case 0x30: REG_OP_16(TSX, X); break; // TSX (Inherent)
case 0x31: REG_OP_16(INS, SP); break; // INS (Inherent)
case 0x32: PUL_(A); break; // PULA (Inherent)
case 0x33: PUL_(B); break; // PULB (Inherent)
case 0x34: REG_OP_16(DES, SP); break; // DES (Inherent)
case 0x35: REG_OP_16(TXS, SP); break; // TXS (Inherent)
case 0x36: PSH_(A); break; // PSHA (Inherent)
case 0x37: PSH_(B); break; // PSHB (Inherent)
case 0x38: ILLEGAL(); break; // ILLEGAL
case 0x39: RTS(); break; // RTS (Inherent)
case 0x3A: ILLEGAL(); break; // ILLEGAL
case 0x3B: RTI(); break; // RTI (Inherent)
case 0x3C: ILLEGAL(); break; // ILLEGAL
case 0x3D: ILLEGAL(); break; // ILLEGAL
case 0x3E: WAI_(); break; // WAI (Inherent)
case 0x3F: SWI1(); break; // SWI (Inherent)
case 0x40: REG_OP(NEG, A); break; // NEGA (Inherent)
case 0x41: ILLEGAL(); break; // ILLEGAL
case 0x42: ILLEGAL(); break; // ILLEGAL
case 0x43: REG_OP(COM, A); break; // COMA (Inherent)
case 0x44: REG_OP(LSR, A); break; // LSRA (Inherent)
case 0x45: ILLEGAL(); break; // ILLEGAL
case 0x46: REG_OP(ROR, A); break; // RORA (Inherent)
case 0x47: REG_OP(ASR, A); break; // ASRA (Inherent)
case 0x48: REG_OP(ASL, A); break; // ASLA , LSLA (Inherent)
case 0x49: REG_OP(ROL, A); break; // ROLA (Inherent)
case 0x4A: REG_OP(DEC8, A); break; // DECA (Inherent)
case 0x4B: ILLEGAL(); break; // ILLEGAL
case 0x4C: REG_OP(INC8, A); break; // INCA (Inherent)
case 0x4D: REG_OP(TST, A); break; // TSTA (Inherent)
case 0x4E: ILLEGAL(); break; // ILLEGAL
case 0x4F: REG_OP(CLR, A); break; // CLRA (Inherent)
case 0x50: REG_OP(NEG, B); break; // NEGB (Inherent)
case 0x51: ILLEGAL(); break; // ILLEGAL
case 0x52: ILLEGAL(); break; // ILLEGAL
case 0x53: REG_OP(COM, B); break; // COMB (Inherent)
case 0x54: REG_OP(LSR, B); break; // LSRB (Inherent)
case 0x55: ILLEGAL(); break; // ILLEGAL
case 0x56: REG_OP(ROR, B); break; // RORB (Inherent)
case 0x57: REG_OP(ASR, B); break; // ASRB (Inherent)
case 0x58: REG_OP(ASL, B); break; // ASLB , LSLB (Inherent)
case 0x59: REG_OP(ROL, B); break; // ROLB (Inherent)
case 0x5A: REG_OP(DEC8, B); break; // DECB (Inherent)
case 0x5B: ILLEGAL(); break; // ILLEGAL
case 0x5C: REG_OP(INC8, B); break; // INCB (Inherent)
case 0x5D: REG_OP(TST, B); break; // TSTB (Inherent)
case 0x5E: ILLEGAL(); break; // ILLEGAL
case 0x5F: REG_OP(CLR, B); break; // CLRB (Inherent)
case 0x60: INDEX_OP(I_NEG); break; // NEG (Indexed)
case 0x61: ILLEGAL(); break; // ILLEGAL
case 0x62: ILLEGAL(); break; // ILLEGAL
case 0x63: INDEX_OP(I_COM); break; // COM (Indexed)
case 0x64: INDEX_OP(I_LSR); break; // LSR (Indexed)
case 0x65: ILLEGAL(); break; // ILLEGAL
case 0x66: INDEX_OP(I_ROR); break; // ROR (Indexed)
case 0x67: INDEX_OP(I_ASR); break; // ASR (Indexed)
case 0x68: INDEX_OP(I_ASL); break; // ASL , LSL (Indexed)
case 0x69: INDEX_OP(I_ROL); break; // ROL (Indexed)
case 0x6A: INDEX_OP(I_DEC); break; // DEC (Indexed)
case 0x6B: ILLEGAL(); break; // ILLEGAL
case 0x6C: INDEX_OP(I_INC); break; // INC (Indexed)
case 0x6D: INDEX_OP(I_TST); break; // TST (Indexed)
case 0x6E: INDEX_OP(I_JMP); break; // JMP (Indexed)
case 0x6F: INDEX_OP(I_CLR); break; // CLR (Indexed)
case 0x70: EXT_MEM(NEG); break; // NEG (Extended)
case 0x71: ILLEGAL(); break; // ILLEGAL
case 0x72: ILLEGAL(); break; // ILLEGAL
case 0x73: EXT_MEM(COM); break; // COM (Extended)
case 0x74: EXT_MEM(LSR); break; // LSR (Extended)
case 0x75: ILLEGAL(); break; // ILLEGAL
case 0x76: EXT_MEM(ROR); break; // ROR (Extended)
case 0x77: EXT_MEM(ASR); break; // ASR (Extended)
case 0x78: EXT_MEM(ASL); break; // ASL , LSL (Extended)
case 0x79: EXT_MEM(ROL); break; // ROL (Extended)
case 0x7A: EXT_MEM(DEC8); break; // DEC (Extended)
case 0x7B: ILLEGAL(); break; // ILLEGAL
case 0x7C: EXT_MEM(INC8); break; // INC (Extended)
case 0x7D: EXT_MEM(TST); break; // TST (Extended)
case 0x7E: JMP_EXT_(); break; // JMP (Extended)
case 0x7F: EXT_MEM(CLR); break; // CLR (Extended)
case 0x80: REG_OP_IMD(SUB8, A); break; // SUBA (Immediate)
case 0x81: REG_OP_IMD(CMP8, A); break; // CMPA (Immediate)
case 0x82: REG_OP_IMD(SBC8, A); break; // SBCA (Immediate)
case 0x83: ILLEGAL(); break; // ILLEGAL
case 0x84: REG_OP_IMD(AND8, A); break; // ANDA (Immediate)
case 0x85: REG_OP_IMD(BIT, A); break; // BITA (Immediate)
case 0x86: REG_OP_IMD(LD_8, A); break; // LDA (Immediate)
case 0x87: ILLEGAL(); break; // ILLEGAL
case 0x88: REG_OP_IMD(XOR8, A); break; // EORA (Immediate)
case 0x89: REG_OP_IMD(ADC8, A); break; // ADCA (Immediate)
case 0x8A: REG_OP_IMD(OR8, A); break; // ORA (Immediate)
case 0x8B: REG_OP_IMD(ADD8, A); break; // ADDA (Immediate)
case 0x8C: IMD_CMP_16(CMP16, X); break; // CMPX (Immediate)
case 0x8D: BSR_(); break; // BSR (Relative)
case 0x8E: REG_OP_LD_16(SP); break; // LDS (Immediate)
case 0x8F: ILLEGAL(); break; // ILLEGAL
case 0x90: DIRECT_MEM_4(SUB8, A); break; // SUBA (Direct)
case 0x91: DIRECT_MEM_4(CMP8, A); break; // CMPA (Direct)
case 0x92: DIRECT_MEM_4(SBC8, A); break; // SBCA (Direct)
case 0x93: ILLEGAL(); break; // ILLEGAL
case 0x94: DIRECT_MEM_4(AND8, A); break; // ANDA (Direct)
case 0x95: DIRECT_MEM_4(BIT, A); break; // BITA (Direct)
case 0x96: DIRECT_MEM_4(LD_8, A); break; // LDA (Direct)
case 0x97: DIRECT_ST_4(A); break; // STA (Direct)
case 0x98: DIRECT_MEM_4(XOR8, A); break; // EORA (Direct)
case 0x99: DIRECT_MEM_4(ADC8, A); break; // ADCA (Direct)
case 0x9A: DIRECT_MEM_4(OR8, A); break; // ORA (Direct)
case 0x9B: DIRECT_MEM_4(ADD8, A); break; // ADDA (Direct)
case 0x9C: DIR_CMP_16(CMP16, X); break; // CMPX (Direct)
case 0x9D: ILLEGAL(); break; // ILLEGAL
case 0x9E: DIR_OP_LD_16(SP); break; // LDS (Direct)
case 0x9F: DIR_OP_ST_16(SP); break; // STS (Direct)
case 0xA0: INDEX_OP_REG(I_SUB, A); break; // SUBA (Indexed)
case 0xA1: INDEX_OP_REG(I_CMP, A); break; // CMPA (Indexed)
case 0xA2: INDEX_OP_REG(I_SBC, A); break; // SBCA (Indexed)
case 0xA3: ILLEGAL(); break; // ILLEGAL
case 0xA4: INDEX_OP_REG(I_AND, A); break; // ANDA (Indexed)
case 0xA5: INDEX_OP_REG(I_BIT, A); break; // BITA (Indexed)
case 0xA6: INDEX_OP_REG(I_LD, A); break; // LDA (Indexed)
case 0xA7: INDEX_OP_REG(I_ST, A); break; // STA (Indexed)
case 0xA8: INDEX_OP_REG(I_XOR, A); break; // EORA (Indexed)
case 0xA9: INDEX_OP_REG(I_ADC, A); break; // ADCA (Indexed)
case 0xAA: INDEX_OP_REG(I_OR, A); break; // ORA (Indexed)
case 0xAB: INDEX_OP_REG(I_ADD, A); break; // ADDA (Indexed)
case 0xAC: INDEX_OP_REG(I_CMP16, X); break; // CMPX (Indexed)
case 0xAD: INDEX_OP(I_JSR); break; // JSR (Indexed)
case 0xAE: INDEX_OP_REG(I_LD16, SP); break; // LDS (Indexed)
case 0xAF: INDEX_OP_REG(I_ST16, SP); break; // STS (Indexed)
case 0xB0: EXT_REG(SUB8, A); break; // SUBA (Extended)
case 0xB1: EXT_REG(CMP8, A); break; // CMPA (Extended)
case 0xB2: EXT_REG(SBC8, A); break; // SBCA (Extended)
case 0xB3: ILLEGAL(); break; // ILLEGAL
case 0xB4: EXT_REG(AND8, A); break; // ANDA (Extended)
case 0xB5: EXT_REG(BIT, A); break; // BITA (Extended)
case 0xB6: EXT_REG(LD_8, A); break; // LDA (Extended)
case 0xB7: EXT_ST(A); break; // STA (Extended)
case 0xB8: EXT_REG(XOR8, A); break; // EORA (Extended)
case 0xB9: EXT_REG(ADC8, A); break; // ADCA (Extended)
case 0xBA: EXT_REG(OR8, A); break; // ORA (Extended)
case 0xBB: EXT_REG(ADD8, A); break; // ADDA (Extended)
case 0xBC: EXT_CMP_16(CMP16, X); break; // CMPX (Extended)
case 0xBD: JSR_EXT(); break; // JSR (Extended)
case 0xBE: EXT_OP_LD_16(SP); break; // LDS (Extended)
case 0xBF: EXT_OP_ST_16(SP); break; // STS (Extended)
case 0xC0: REG_OP_IMD(SUB8, B); break; // SUBB (Immediate)
case 0xC1: REG_OP_IMD(CMP8, B); break; // CMPB (Immediate)
case 0xC2: REG_OP_IMD(SBC8, B); break; // SBCB (Immediate)
case 0xC3: ILLEGAL(); break; // ILLEGAL
case 0xC4: REG_OP_IMD(AND8, B); break; // ANDB (Immediate)
case 0xC5: REG_OP_IMD(BIT, B); break; // BITB (Immediate)
case 0xC6: REG_OP_IMD(LD_8, B); break; // LDB (Immediate)
case 0xC7: ILLEGAL(); break; // ILLEGAL
case 0xC8: REG_OP_IMD(XOR8, B); break; // EORB (Immediate)
case 0xC9: REG_OP_IMD(ADC8, B); break; // ADCB (Immediate)
case 0xCA: REG_OP_IMD(OR8, B); break; // ORB (Immediate)
case 0xCB: REG_OP_IMD(ADD8, B); break; // ADDB (Immediate)
case 0xCC: ILLEGAL(); break; // ILLEGAL
case 0xCD: ILLEGAL(); break; // ILLEGAL
case 0xCE: REG_OP_LD_16(X); break; // LDX (Immediate)
case 0xCF: ILLEGAL(); break; // ILLEGAL
case 0xD0: DIRECT_MEM_4(SUB8, B); break; // SUBB (Direct)
case 0xD1: DIRECT_MEM_4(CMP8, B); break; // CMPB (Direct)
case 0xD2: DIRECT_MEM_4(SBC8, B); break; // SBCB (Direct)
case 0xD3: ILLEGAL(); break; // ILLEGAL
case 0xD4: DIRECT_MEM_4(AND8, B); break; // ANDB (Direct)
case 0xD5: DIRECT_MEM_4(BIT, B); break; // BITB (Direct)
case 0xD6: DIRECT_MEM_4(LD_8, B); break; // LDB (Direct)
case 0xD7: DIRECT_ST_4(B); break; // STB (Direct)
case 0xD8: DIRECT_MEM_4(XOR8, B); break; // EORB (Direct)
case 0xD9: DIRECT_MEM_4(ADC8, B); break; // ADCB (Direct)
case 0xDA: DIRECT_MEM_4(OR8, B); break; // ORB (Direct)
case 0xDB: DIRECT_MEM_4(ADD8, B); break; // ADDB (Direct)
case 0xDC: ILLEGAL(); break; // ILLEGAL
case 0xDD: ILLEGAL(); break; // ILLEGAL
case 0xDE: DIR_OP_LD_16(X); break; // LDX (Direct)
case 0xDF: DIR_OP_ST_16(X); break; // STX (Direct)
case 0xE0: INDEX_OP_REG(I_SUB, B); break; // SUBB (Indexed)
case 0xE1: INDEX_OP_REG(I_CMP, B); break; // CMPB (Indexed)
case 0xE2: INDEX_OP_REG(I_SBC, B); break; // SBCB (Indexed)
case 0xE3: ILLEGAL(); break; // ILLEGAL
case 0xE4: INDEX_OP_REG(I_AND, B); break; // ANDB (Indexed)
case 0xE5: INDEX_OP_REG(I_BIT, B); break; // BITB (Indexed)
case 0xE6: INDEX_OP_REG(I_LD, B); break; // LDB (Indexed)
case 0xE7: INDEX_OP_REG(I_ST, B); break; // STB (Indexed)
case 0xE8: INDEX_OP_REG(I_XOR, B); break; // EORB (Indexed)
case 0xE9: INDEX_OP_REG(I_ADC, B); break; // ADCB (Indexed)
case 0xEA: INDEX_OP_REG(I_OR, B); break; // ORB (Indexed)
case 0xEB: INDEX_OP_REG(I_ADD, B); break; // ADDB (Indexed)
case 0xEC: ILLEGAL(); break; // ILLEGAL
case 0xED: ILLEGAL(); break; // ILLEGAL
case 0xEE: INDEX_OP_REG(I_LD16, X); break; // LDX (Indexed)
case 0xEF: INDEX_OP_REG(I_ST16, X); break; // STX (Indexed)
case 0xF0: EXT_REG(SUB8, B); break; // SUBB (Extended)
case 0xF1: EXT_REG(CMP8, B); break; // CMPB (Extended)
case 0xF2: EXT_REG(SBC8, B); break; // SBCB (Extended)
case 0xF3: ILLEGAL(); break; // ILLEGAL
case 0xF4: EXT_REG(AND8, B); break; // ANDB (Extended)
case 0xF5: EXT_REG(BIT, B); break; // BITB (Extended)
case 0xF6: EXT_REG(LD_8, B); break; // LDB (Extended)
case 0xF7: EXT_ST(B); break; // STB (Extended)
case 0xF8: EXT_REG(XOR8, B); break; // EORB (Extended)
case 0xF9: EXT_REG(ADC8, B); break; // ADCB (Extended)
case 0xFA: EXT_REG(OR8, B); break; // ORB (Extended)
case 0xFB: EXT_REG(ADD8, B); break; // ADDB (Extended)
case 0xFC: ILLEGAL(); break; // ILLEGAL
case 0xFD: ILLEGAL(); break; // ILLEGAL
case 0xFE: EXT_OP_LD_16(X); break; // LDX (Extended)
case 0xFF: EXT_OP_ST_16(X); break; // STX (Extended)
}
}
}
}

View File

@ -0,0 +1,207 @@
using System;
namespace BizHawk.Emulation.Common.Components.MC6800
{
public partial class MC6800
{
public const ushort I_NEG = 0;
public const ushort I_COM = 1;
public const ushort I_LSR = 2;
public const ushort I_ROR = 3;
public const ushort I_ASR = 4;
public const ushort I_ASL = 5;
public const ushort I_ROL = 6;
public const ushort I_DEC = 7;
public const ushort I_INC = 8;
public const ushort I_TST = 9;
public const ushort I_JMP = 10;
public const ushort I_CLR = 11;
public const ushort I_SUB = 12;
public const ushort I_CMP = 13;
public const ushort I_SBC = 14;
public const ushort I_AND = 15;
public const ushort I_BIT = 16;
public const ushort I_LD = 17;
public const ushort I_ST = 18;
public const ushort I_XOR = 19;
public const ushort I_ADC = 20;
public const ushort I_OR = 21;
public const ushort I_ADD = 22;
public const ushort I_CMP16 = 23;
public const ushort I_JSR = 24;
public const ushort I_LD16 = 25;
public const ushort I_ST16 = 26;
public ushort indexed_op;
public ushort indexed_reg;
public ushort indexed_op_reg;
private void INDEX_OP(ushort oper)
{
indexed_op = oper;
PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE);
IRQS = -1;
}
private void INDEX_OP_REG(ushort oper, ushort src)
{
indexed_op = oper;
indexed_op_reg = src;
PopulateCURINSTR(RD_INC_OP, ALU, PC, IDX_DCDE);
IRQS = -1;
}
private void INDEX_OP_JMP()
{
PopulateCURINSTR(TR, PC, IDX_EA);
IRQS = 1;
}
private void INDEX_OP_JSR()
{
PopulateCURINSTR(TR, ADDR, PC,
IDLE,
IDLE,
TR, PC, IDX_EA,
WR_DEC_LO, SP, ADDR,
WR_DEC_HI, SP, ADDR);
IRQS = 6;
}
private void INDEX_OP_LD()
{
PopulateCURINSTR(IDLE,
RD_INC, ALU, IDX_EA,
RD_INC_OP, ALU2, IDX_EA, LD_16, indexed_op_reg, ALU, ALU2);
IRQS = 3;
}
private void INDEX_OP_ST()
{
PopulateCURINSTR(IDLE,
WR_HI_INC, IDX_EA, indexed_op_reg,
WR_DEC_LO, IDX_EA, indexed_op_reg);
IRQS = 3;
}
private void INDEX_OP_LDD()
{
PopulateCURINSTR(IDLE,
RD_INC, A, IDX_EA,
RD_INC_OP, B, IDX_EA, LD_16, ADDR, A, B);
IRQS = 3;
}
private void INDEX_OP_STD()
{
PopulateCURINSTR(SET_ADDR, ADDR, A, A,
WR_HI_INC, IDX_EA, ADDR,
WR_DEC_LO, IDX_EA, B);
IRQS = 3;
}
private void INDEX_OP_EX4(ushort oper)
{
PopulateCURINSTR(IDLE,
RD_INC_OP, ALU, IDX_EA, oper, indexed_op_reg, ALU);
IRQS = 2;
}
private void INDEX_OP_EX4_ST()
{
PopulateCURINSTR(IDLE,
WR, IDX_EA, indexed_op_reg);
IRQS = 2;
}
private void INDEX_OP_EX6(ushort oper)
{
PopulateCURINSTR(IDLE,
RD, ALU, IDX_EA,
oper, ALU,
WR, IDX_EA, ALU);
IRQS = 4;
}
private void INDEX_OP_EX6D(ushort oper)
{
PopulateCURINSTR(IDLE,
RD_INC, ALU, IDX_EA,
RD_INC_OP, ALU2, IDX_EA, SET_ADDR, ADDR, ALU, ALU2,
oper, ADDR);
IRQS = 4;
}
private void INDEX_CMP_EX6(ushort oper)
{
PopulateCURINSTR(IDLE,
RD_INC, ALU, IDX_EA,
RD_INC_OP, ALU2, IDX_EA, SET_ADDR, ADDR, ALU, ALU2,
oper, indexed_op_reg, ADDR);
IRQS = 4;
}
// ALU holds the post byte
public void Index_decode()
{
Regs[IDX_EA] = (ushort)(Regs[X] + Regs[ALU]);
PopulateCURINSTR(IDX_OP_BLD);
instr_pntr = 0;
irq_pntr = 100;
}
public void Index_Op_Builder()
{
switch(indexed_op)
{
case I_NEG: INDEX_OP_EX6(NEG); break; // NEG
case I_COM: INDEX_OP_EX6(COM); break; // COM
case I_LSR: INDEX_OP_EX6(LSR); break; // LSR
case I_ROR: INDEX_OP_EX6(ROR); break; // ROR
case I_ASR: INDEX_OP_EX6(ASR); break; // ASR
case I_ASL: INDEX_OP_EX6(ASL); break; // ASL
case I_ROL: INDEX_OP_EX6(ROL); break; // ROL
case I_DEC: INDEX_OP_EX6(DEC8); break; // DEC
case I_INC: INDEX_OP_EX6(INC8); break; // INC
case I_TST: INDEX_OP_EX6(TST); break; // TST
case I_JMP: INDEX_OP_JMP(); break; // JMP
case I_CLR: INDEX_OP_EX6(CLR); break; // CLR
case I_SUB: INDEX_OP_EX4(SUB8); break; // SUB A,B
case I_CMP: INDEX_OP_EX4(CMP8); break; // CMP A,B
case I_SBC: INDEX_OP_EX4(SBC8); break; // SBC A,B
case I_AND: INDEX_OP_EX4(AND8); break; // AND A,B
case I_BIT: INDEX_OP_EX4(BIT); break; // BIT A,B
case I_LD: INDEX_OP_EX4(LD_8); break; // LD A,B
case I_ST: INDEX_OP_EX4_ST(); break; // ST A,B
case I_XOR: INDEX_OP_EX4(XOR8); break; // XOR A,B
case I_ADC: INDEX_OP_EX4(ADC8); break; // ADC A,B
case I_OR: INDEX_OP_EX4(OR8); break; // OR A,B
case I_ADD: INDEX_OP_EX4(ADD8); break; // ADD A,B
case I_CMP16: INDEX_CMP_EX6(CMP16); break; // CMP X, SP
case I_JSR: INDEX_OP_JSR(); break; // JSR
case I_LD16: INDEX_OP_LD(); break; // LD X, SP
case I_ST16: INDEX_OP_ST(); break; // ST X, SP
}
instr_pntr = 0;
irq_pntr = -1;
}
}
}

View File

@ -0,0 +1,60 @@
using System;
namespace BizHawk.Emulation.Common.Components.MC6800
{
public partial class MC6800
{
private void IRQ_()
{
Regs[ADDR] = 0xFFF8;
PopulateCURINSTR(IDLE,
IDLE,
DEC16, SP,
WR_DEC_LO, SP, PC,
WR_DEC_HI, SP, PC,
WR_DEC_LO, SP, X,
WR_DEC_HI, SP, X,
WR_DEC_LO, SP, B,
WR_DEC_LO, SP, A,
WR, SP, CC,
SET_I,
RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, PC, ALU, ALU2);
IRQS = 19;
}
private void NMI_()
{
Regs[ADDR] = 0xFFFC;
PopulateCURINSTR(IDLE,
IDLE,
DEC16, SP,
WR_DEC_LO, SP, PC,
WR_DEC_HI, SP, PC,
WR_DEC_LO, SP, X,
WR_DEC_HI, SP, X,
WR_DEC_LO, SP, B,
WR_DEC_LO, SP, A,
WR, SP, CC,
SET_I,
RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, PC, ALU, ALU2);
IRQS = 19;
}
public bool NMIPending;
public bool IRQPending;
public Action IRQCallback = delegate () { };
public Action NMICallback = delegate () { };
private void ResetInterrupts()
{
}
}
}

View File

@ -0,0 +1,589 @@
using System;
using BizHawk.Common;
// Motorola Corp 6800
namespace BizHawk.Emulation.Common.Components.MC6800
{
public sealed partial class MC6800
{
// operations that can take place in an instruction
public const ushort IDLE = 0;
public const ushort OP = 1;
public const ushort RD = 2;
public const ushort WR = 3;
public const ushort TR = 4;
public const ushort SET_ADDR = 5;
public const ushort ADD8 = 6;
public const ushort SUB8 = 7;
public const ushort ADC8 = 8;
public const ushort SBC8 = 9;
public const ushort INC16 = 10;
public const ushort INC8 = 11;
public const ushort DEC16 = 12;
public const ushort DEC8 = 13;
public const ushort ROL = 14;
public const ushort ROR = 15;
public const ushort COM = 16;
public const ushort DA = 17;
public const ushort AND8 = 18;
public const ushort XOR8 = 19;
public const ushort OR8 = 20;
public const ushort ASL = 21;
public const ushort ASR = 22;
public const ushort LSR = 23;
public const ushort BIT = 24;
public const ushort WAI = 25;
public const ushort RD_INC = 26;
public const ushort RD_INC_OP = 27;
public const ushort WR_DEC_LO = 28;
public const ushort WR_DEC_HI = 29;
public const ushort WR_HI = 30;
public const ushort LD_8 = 31;
public const ushort LD_16 = 32;
public const ushort NEG = 33;
public const ushort TST = 34;
public const ushort CLR = 35;
public const ushort ADD8BR = 36;
public const ushort IDX_DCDE = 37;
public const ushort IDX_OP_BLD = 38;
public const ushort WR_HI_INC = 39;
public const ushort SET_I = 40;
public const ushort CMP8 = 41;
public const ushort CMP16 = 42;
public const ushort TAP = 43;
public const ushort TPA = 44;
public const ushort INX = 45;
public const ushort DEX = 46;
public const ushort CLV = 47;
public const ushort SEV = 48;
public const ushort CLC = 49;
public const ushort SEC = 50;
public const ushort CLI = 51;
public const ushort SEI = 52;
public const ushort SBA = 53;
public const ushort CBA = 54;
public const ushort TAB = 55;
public const ushort TBA = 56;
public const ushort ABA = 57;
public const ushort TSX = 58;
public const ushort INS = 59;
public const ushort DES = 60;
public const ushort TXS = 61;
public MC6800()
{
Reset();
}
public void Reset()
{
ResetRegisters();
ResetInterrupts();
TotalExecutedCycles = 0;
Regs[PC] = 0xFFFE;
PopulateCURINSTR(IDLE,
IDLE,
IDLE,
RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, PC, ALU, ALU2);
IRQS = 6;
instr_pntr = irq_pntr = 0;
}
// Memory Access
public Func<ushort, byte> ReadMemory;
public Action<ushort, byte> WriteMemory;
public Func<ushort, byte> PeekMemory;
public Func<ushort, byte> DummyReadMemory;
// Special Function for Speed switching executed on a STOP
public Func<int, int> SpeedFunc;
//this only calls when the first byte of an instruction is fetched.
public Action<ushort> OnExecFetch;
public void UnregisterMemoryMapper()
{
ReadMemory = null;
ReadMemory = null;
PeekMemory = null;
DummyReadMemory = null;
}
public void SetCallbacks
(
Func<ushort, byte> ReadMemory,
Func<ushort, byte> DummyReadMemory,
Func<ushort, byte> PeekMemory,
Action<ushort, byte> WriteMemory
)
{
this.ReadMemory = ReadMemory;
this.DummyReadMemory = DummyReadMemory;
this.PeekMemory = PeekMemory;
this.WriteMemory = WriteMemory;
}
//a little CDL related stuff
public delegate void DoCDLCallbackType(ushort addr, MC6800.eCDLogMemFlags flags);
public DoCDLCallbackType CDLCallback;
public enum eCDLogMemFlags
{
FetchFirst = 1,
FetchOperand = 2,
Data = 4,
Write = 8
};
// Execute instructions
public void ExecuteOne()
{
//Console.Write(opcode_see + " ");
//Console.WriteLine(Regs[PC] + " ");
switch (cur_instr[instr_pntr++])
{
case IDLE:
// do nothing
break;
case OP:
// Read the opcode of the next instruction
if (OnExecFetch != null) OnExecFetch(PC);
if (TraceCallback != null) TraceCallback(State());
if (CDLCallback != null) CDLCallback(PC, eCDLogMemFlags.FetchFirst);
FetchInstruction(ReadMemory(Regs[PC]++));
instr_pntr = 0;
irq_pntr = -1;
break;
case RD:
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case RD_INC:
Read_Inc_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case RD_INC_OP:
Read_Inc_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
switch (cur_instr[instr_pntr++])
{
case AND8:
AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case ADD8:
ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case ADC8:
ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case OR8:
OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case XOR8:
XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case BIT:
BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case SUB8:
SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case SBC8:
SBC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case CMP8:
CMP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case DEC16:
DEC16_Func(cur_instr[instr_pntr++]);
break;
case ADD8BR:
ADD8BR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case TR:
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case SET_ADDR:
reg_d_ad = cur_instr[instr_pntr++];
reg_h_ad = cur_instr[instr_pntr++];
reg_l_ad = cur_instr[instr_pntr++];
Regs[reg_d_ad] = (ushort)((Regs[reg_h_ad] << 8) | Regs[reg_l_ad]);
break;
case IDX_DCDE:
Index_decode();
break;
case IDX_OP_BLD:
Index_Op_Builder();
break;
case LD_8:
LD_8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case LD_16:
LD_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
}
break;
case WR:
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR_DEC_LO:
Write_Dec_Lo_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR_DEC_HI:
Write_Dec_HI_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR_HI:
Write_Hi_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WR_HI_INC:
Write_Hi_Inc_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case TR:
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case LD_8:
LD_8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case LD_16:
LD_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case IDX_OP_BLD:
Index_Op_Builder();
break;
case SET_ADDR:
reg_d_ad = cur_instr[instr_pntr++];
reg_h_ad = cur_instr[instr_pntr++];
reg_l_ad = cur_instr[instr_pntr++];
// Console.WriteLine(reg_d_ad + " " + reg_h_ad + " " + reg_l_ad);
// Console.WriteLine(Regs[reg_d_ad] + " " + Regs[reg_h_ad] + " " + Regs[reg_l_ad]);
Regs[reg_d_ad] = (ushort)((Regs[reg_h_ad] << 8) | Regs[reg_l_ad]);
break;
case NEG:
NEG_8_Func(cur_instr[instr_pntr++]);
break;
case TST:
TST_Func(cur_instr[instr_pntr++]);
break;
case CLR:
CLR_Func(cur_instr[instr_pntr++]);
break;
case SET_I:
FlagI = true;
break;
case ADD8BR:
ADD8BR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case ADD8:
ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case SUB8:
SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case ADC8:
ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case SBC8:
SBC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case CMP8:
CMP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case INC16:
INC16_Func(cur_instr[instr_pntr++]);
break;
case INC8:
INC8_Func(cur_instr[instr_pntr++]);
break;
case DEC16:
DEC16_Func(cur_instr[instr_pntr++]);
break;
case CMP16:
CMP16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case DEC8:
DEC8_Func(cur_instr[instr_pntr++]);
break;
case ROL:
ROL_Func(cur_instr[instr_pntr++]);
break;
case ROR:
ROR_Func(cur_instr[instr_pntr++]);
break;
case COM:
COM_Func(cur_instr[instr_pntr++]);
break;
case DA:
DA_Func(cur_instr[instr_pntr++]);
break;
case AND8:
AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case XOR8:
XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case OR8:
OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case ASL:
ASL_Func(cur_instr[instr_pntr++]);
break;
case ASR:
ASR_Func(cur_instr[instr_pntr++]);
break;
case LSR:
LSR_Func(cur_instr[instr_pntr++]);
break;
case TAP:
instr_pntr++;
Regs[CC] = (ushort)((Regs[A] & 0x3F) | 0xC0); // last 2 bits always 1
break;
case TPA:
instr_pntr++;
Regs[A] = Regs[CC];
break;
case INX:
instr_pntr++;
Regs[X] = (ushort)(Regs[X] + 1);
FlagZ = Regs[X] == 0;
break;
case DEX:
instr_pntr++;
Regs[X] = (ushort)(Regs[X] - 1);
FlagZ = Regs[X] == 0;
break;
case CLV:
instr_pntr++;
FlagV = false;
break;
case SEV:
instr_pntr++;
FlagV = true;
break;
case CLC:
instr_pntr++;
FlagC = false;
break;
case SEC:
instr_pntr++;
FlagC = true;
break;
case CLI:
instr_pntr++;
FlagI = false;
break;
case SEI:
instr_pntr++;
FlagI = true;
break;
case SBA:
instr_pntr++;
SBC8_Func(A, B);
break;
case CBA:
instr_pntr++;
CMP8_Func(A, B);
break;
case TAB:
instr_pntr++;
Regs[B] = Regs[A];
break;
case TBA:
instr_pntr++;
Regs[A] = Regs[B];
break;
case ABA:
instr_pntr++;
ADD8_Func(A, B);
break;
case TSX:
instr_pntr++;
Regs[X] = (ushort)(Regs[SP] + 1);
break;
case INS:
instr_pntr++;
Regs[SP] = (ushort)(Regs[SP] + 1);
break;
case DES:
instr_pntr++;
Regs[SP] = (ushort)(Regs[SP] - 1);
break;
case TXS:
instr_pntr++;
Regs[SP] = (ushort)(Regs[X] - 1);
break;
case BIT:
BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case WAI:
if (NMIPending)
{
NMIPending = false;
Regs[ADDR] = 0xFFFC;
PopulateCURINSTR(RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, PC, ALU, ALU2);
irq_pntr = -1;
IRQS = 3;
if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====CWAI NMI====", RegisterInfo = "" }); }
}
else if (IRQPending && !FlagI)
{
IRQPending = false;
Regs[ADDR] = 0xFFF8;
PopulateCURINSTR(RD_INC, ALU, ADDR,
RD_INC, ALU2, ADDR,
SET_ADDR, PC, ALU, ALU2);
irq_pntr = -1;
IRQS = 3;
if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====CWAI IRQ====", RegisterInfo = "" }); }
}
else
{
PopulateCURINSTR(WAI);
irq_pntr = 0;
IRQS = -1;
}
instr_pntr = 0;
break;
}
if (++irq_pntr == IRQS)
{
// NMI has priority
if (NMIPending)
{
NMIPending = false;
if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====NMI====", RegisterInfo = "" }); }
NMI_();
NMICallback();
instr_pntr = irq_pntr = 0;
}
// then regular IRQ
else if (IRQPending && !FlagI)
{
if (!FlagI)
{
IRQPending = false;
if (TraceCallback != null) { TraceCallback(new TraceInfo { Disassembly = "====IRQ====", RegisterInfo = "" }); }
IRQ_();
IRQCallback();
instr_pntr = irq_pntr = 0;
}
}
// otherwise start the next instruction
else
{
PopulateCURINSTR(OP);
instr_pntr = irq_pntr = 0;
IRQS = -1;
}
}
TotalExecutedCycles++;
}
// tracer stuff
public Action<TraceInfo> TraceCallback;
public string TraceHeader
{
get { return "MC6809: PC, machine code, mnemonic, operands, registers (A, B, X, SP, CC), Cy, flags (EHINZVC)"; }
}
public TraceInfo State(bool disassemble = true)
{
ushort notused;
return new TraceInfo
{
Disassembly = $"{(disassemble ? Disassemble(Regs[PC], ReadMemory, out notused) : "---")} ".PadRight(50),
RegisterInfo = string.Format(
"A:{0:X2} B:{1:X2} X:{2:X4} SP:{3:X4} CC:{4:X2} Cy:{5} {6}{7}{8}{9}{10}{11}",
Regs[A],
Regs[B],
Regs[X],
Regs[SP],
Regs[CC],
TotalExecutedCycles,
FlagH ? "H" : "h",
FlagI ? "I" : "i",
FlagN ? "N" : "n",
FlagZ ? "Z" : "z",
FlagV ? "V" : "v",
FlagC ? "C" : "c"
)
};
}
/// <summary>
/// Optimization method to set cur_instr
/// </summary>
private void PopulateCURINSTR(ushort d0 = 0, ushort d1 = 0, ushort d2 = 0, ushort d3 = 0, ushort d4 = 0, ushort d5 = 0, ushort d6 = 0, ushort d7 = 0, ushort d8 = 0,
ushort d9 = 0, ushort d10 = 0, ushort d11 = 0, ushort d12 = 0, ushort d13 = 0, ushort d14 = 0, ushort d15 = 0, ushort d16 = 0, ushort d17 = 0, ushort d18 = 0,
ushort d19 = 0, ushort d20 = 0, ushort d21 = 0, ushort d22 = 0, ushort d23 = 0, ushort d24 = 0, ushort d25 = 0, ushort d26 = 0, ushort d27 = 0, ushort d28 = 0,
ushort d29 = 0, ushort d30 = 0, ushort d31 = 0, ushort d32 = 0, ushort d33 = 0, ushort d34 = 0, ushort d35 = 0, ushort d36 = 0, ushort d37 = 0, ushort d38 = 0,
ushort d39 = 0, ushort d40 = 0, ushort d41 = 0, ushort d42 = 0, ushort d43 = 0, ushort d44 = 0, ushort d45 = 0, ushort d46 = 0, ushort d47 = 0, ushort d48 = 0,
ushort d49 = 0, ushort d50 = 0, ushort d51 = 0, ushort d52 = 0, ushort d53 = 0, ushort d54 = 0, ushort d55 = 0, ushort d56 = 0, ushort d57 = 0, ushort d58 = 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;
cur_instr[6] = d6; cur_instr[7] = d7; cur_instr[8] = d8;
cur_instr[9] = d9; cur_instr[10] = d10; cur_instr[11] = d11;
cur_instr[12] = d12; cur_instr[13] = d13; cur_instr[14] = d14;
cur_instr[15] = d15; cur_instr[16] = d16; cur_instr[17] = d17;
cur_instr[18] = d18; cur_instr[19] = d19; cur_instr[20] = d20;
cur_instr[21] = d21; cur_instr[22] = d22; cur_instr[23] = d23;
cur_instr[24] = d24; cur_instr[25] = d25; cur_instr[26] = d26;
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[38] = d38;
cur_instr[39] = d39; cur_instr[40] = d40; cur_instr[41] = d41;
cur_instr[42] = d42; cur_instr[43] = d43; cur_instr[44] = d44;
cur_instr[45] = d45; cur_instr[46] = d46; cur_instr[47] = d47;
cur_instr[48] = d48; cur_instr[49] = d49; cur_instr[50] = d50;
cur_instr[51] = d51; cur_instr[52] = d52; cur_instr[53] = d53;
cur_instr[54] = d54; cur_instr[55] = d55; cur_instr[56] = d56;
cur_instr[57] = d57; cur_instr[58] = d58;
}
// State Save/Load
public void SyncState(Serializer ser)
{
ser.BeginSection("MC6809");
ser.Sync(nameof(NMIPending), ref NMIPending);
ser.Sync(nameof(IRQPending), ref IRQPending);
ser.Sync(nameof(indexed_op), ref indexed_op);
ser.Sync(nameof(indexed_reg), ref indexed_reg);
ser.Sync(nameof(indexed_op_reg), ref indexed_op_reg);
ser.Sync(nameof(instr_pntr), ref instr_pntr);
ser.Sync(nameof(cur_instr), ref cur_instr, false);
ser.Sync(nameof(opcode_see), ref opcode_see);
ser.Sync(nameof(IRQS), ref IRQS);
ser.Sync(nameof(irq_pntr), ref irq_pntr);
ser.Sync(nameof(Regs), ref Regs, false);
ser.Sync(nameof(TotalExecutedCycles), ref TotalExecutedCycles);
ser.EndSection();
}
}
}

View File

@ -0,0 +1,320 @@
using System;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Common.Components.MC6800
{
public partial class MC6800
{
// this contains the vectors of instrcution operations
// NOTE: This list is NOT confirmed accurate for each individual cycle
private void NOP_()
{
PopulateCURINSTR(IDLE);
IRQS = 1;
}
private void ILLEGAL()
{
//throw new Exception("Encountered illegal instruction");
PopulateCURINSTR(IDLE);
IRQS = 1;
}
private void REG_OP(ushort oper, ushort src)
{
PopulateCURINSTR(oper, src);
IRQS = 1;
}
private void REG_OP_16(ushort oper, ushort src)
{
PopulateCURINSTR(IDLE,
IDLE,
oper, src);
IRQS = 3;
}
private void DIRECT_MEM(ushort oper)
{
PopulateCURINSTR(RD_INC, ALU, PC,
SET_ADDR, ADDR, DP, ALU,
RD, ALU, ADDR,
oper, ALU,
WR, ADDR, ALU);
IRQS = 5;
}
private void DIRECT_ST_4(ushort dest)
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
IDLE,
WR, ADDR, dest);
IRQS = 3;
}
private void DIRECT_MEM_4(ushort oper, ushort dest)
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
IDLE,
RD_INC_OP, ALU, ADDR, oper, dest, ALU);
IRQS = 3;
}
private void EXT_MEM(ushort oper)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, ADDR, ALU, ALU2,
RD, ALU, ADDR,
oper, ALU,
WR, ADDR, ALU);
IRQS = 6;
}
private void EXT_REG(ushort oper, ushort dest)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
RD, ALU, ADDR,
oper, dest, ALU);
IRQS = 4;
}
private void EXT_ST(ushort dest)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
IDLE,
WR, ADDR, dest);
IRQS = 4;
}
private void REG_OP_IMD(ushort oper, ushort dest)
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, oper, dest, ALU);
IRQS = 1;
}
private void DIR_CMP_16(ushort oper, ushort dest)
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
RD_INC, ALU, ADDR,
RD, ALU2, ADDR,
SET_ADDR, ADDR, ALU, ALU2,
oper, dest, ADDR);
IRQS = 5;
}
private void IMD_CMP_16(ushort oper, ushort dest)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
oper, dest, ADDR);
IRQS = 3;
}
private void REG_OP_LD_16(ushort dest)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, LD_16, dest, ALU, ALU2);
IRQS = 2;
}
private void DIR_OP_LD_16(ushort dest)
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
IDLE,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, LD_16, dest, ALU, ALU2);
IRQS = 4;
}
private void DIR_OP_ST_16(ushort src)
{
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
IDLE,
WR_HI_INC, ADDR, src,
WR_DEC_LO, ADDR, src);
IRQS = 4;
}
private void EXT_OP_LD_16(ushort dest)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, LD_16, dest, ALU, ALU2);
IRQS = 4;
}
private void EXT_OP_ST_16(ushort src)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, ADDR, ALU, ALU2,
WR_HI_INC, ADDR, src,
WR_DEC_LO, ADDR, src);
IRQS = 5;
}
private void EXT_CMP_16(ushort oper, ushort dest)
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
RD_INC, ALU, ADDR,
RD, ALU2, ADDR,
SET_ADDR, ADDR, ALU, ALU2,
oper, dest, ADDR);
IRQS = 6;
}
private void JMP_EXT_()
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, PC, ALU, ALU2);
IRQS = 3;
}
private void JSR_EXT()
{
PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC, ALU2, PC,
SET_ADDR, ADDR, ALU, ALU2,
TR, ALU, PC,
IDLE,
TR, PC, ADDR,
WR_DEC_LO, SP, ALU,
WR_DEC_HI, SP, ALU);
IRQS = 8;
}
private void BR_(bool cond)
{
if (cond)
{
PopulateCURINSTR(RD_INC, ALU, PC,
ADD8BR, PC, ALU);
IRQS = 2;
}
else
{
PopulateCURINSTR(RD_INC, ALU, PC,
IDLE);
IRQS = 2;
}
}
private void BSR_()
{
PopulateCURINSTR(RD_INC, ALU, PC,
TR, ADDR, PC,
ADD8BR, PC, ALU,
IDLE,
IDLE,
WR_DEC_LO, SP, ADDR,
WR_DEC_HI, SP, ADDR);
IRQS = 7;
}
private void RTS()
{
PopulateCURINSTR(INC16, SP,
RD_INC, ALU, SP,
RD, ALU2, SP,
SET_ADDR, PC, ALU, ALU2);
IRQS = 4;
}
private void RTI()
{
PopulateCURINSTR(INC16, SP,
RD_INC, CC, SP,
RD_INC, B, SP,
RD_INC, A, SP,
RD_INC, ALU, SP,
RD_INC_OP, ALU2, SP, SET_ADDR, X, ALU, ALU2,
RD_INC, ALU, SP,
RD, ALU2, SP,
SET_ADDR, PC, ALU, ALU2);
IRQS = 9;
}
private void PSH_(ushort src)
{
PopulateCURINSTR(WR, SP, src,
IDLE,
DEC16, SP);
IRQS = 3;
}
private void PUL_(ushort src)
{
PopulateCURINSTR(INC16, SP,
IDLE,
RD, src, SP);
IRQS = 3;
}
private void SWI1()
{
Regs[ADDR] = 0xFFFA;
PopulateCURINSTR(IDLE,
WR_DEC_LO, SP, PC,
WR_DEC_HI, SP, PC,
WR_DEC_LO, SP, X,
WR_DEC_HI, SP, X,
WR_DEC_LO, SP, A,
WR_DEC_LO, SP, B,
WR_DEC_LO, SP, CC,
SET_I,
RD_INC, ALU, ADDR,
RD_INC_OP, ALU2, ADDR, SET_ADDR, PC, ALU, ALU2);
IRQS = 11;
}
private void WAI_()
{
PopulateCURINSTR(WR_DEC_LO, SP, PC,
WR_DEC_HI, SP, PC,
WR_DEC_LO, SP, X,
WR_DEC_HI, SP, X,
WR_DEC_LO, SP, A,
WR_DEC_LO, SP, B,
WR_DEC_LO, SP, CC,
WAI);
IRQS = 8;
}
}
}

View File

@ -0,0 +1,421 @@
using System;
using BizHawk.Common.NumberExtensions;
namespace BizHawk.Emulation.Common.Components.MC6800
{
public partial class MC6800
{
public void Read_Func(ushort dest, ushort src)
{
if (CDLCallback != null)
{
if (src == PC) CDLCallback(Regs[src], eCDLogMemFlags.FetchOperand);
else CDLCallback(Regs[src], eCDLogMemFlags.Data);
}
Regs[dest] = ReadMemory(Regs[src]);
}
public void Read_Inc_Func(ushort dest, ushort src)
{
if (CDLCallback != null)
{
if (src == PC) CDLCallback(Regs[src], eCDLogMemFlags.FetchOperand);
else CDLCallback(Regs[src], eCDLogMemFlags.Data);
}
//Console.WriteLine(dest + " " + src + " " + opcode_see);
Regs[dest] = ReadMemory(Regs[src]);
Regs[src]++;
}
public void Write_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
WriteMemory(Regs[dest], (byte)Regs[src]);
}
public void Write_Dec_Lo_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
WriteMemory(Regs[dest], (byte)Regs[src]);
Regs[dest] -= 1;
}
public void Write_Dec_HI_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
WriteMemory(Regs[dest], (byte)(Regs[src] >> 8));
Regs[dest] -= 1;
}
public void Write_Hi_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
WriteMemory(Regs[dest], (byte)(Regs[src] >> 8));
}
public void Write_Hi_Inc_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
WriteMemory(Regs[dest], (byte)(Regs[src] >> 8));
Regs[dest]++;
}
public void NEG_8_Func(ushort src)
{
int Reg16_d = 0;
Reg16_d -= Regs[src];
FlagC = Regs[src] != 0x0;
FlagZ = (Reg16_d & 0xFF) == 0;
FlagV = Regs[src] == 0x80;
FlagN = (Reg16_d & 0xFF) > 127;
ushort ans = (ushort)(Reg16_d & 0xFF);
// redo for half carry flag
Reg16_d = 0;
Reg16_d -= (Regs[src] & 0xF);
FlagH = Reg16_d.Bit(4);
Regs[src] = ans;
}
public void TR_Func(ushort dest, ushort src)
{
Regs[dest] = Regs[src];
}
public void LD_8_Func(ushort dest, ushort src)
{
Regs[dest] = Regs[src];
FlagZ = (Regs[dest] & 0xFF) == 0;
FlagV = false;
FlagN = (Regs[dest] & 0xFF) > 127;
}
public void LD_16_Func(ushort dest, ushort src_h, ushort src_l)
{
Regs[dest] = (ushort)(Regs[src_h] << 8 | Regs[src_l]);
FlagZ = Regs[dest] == 0;
FlagV = false;
FlagN = Regs[dest] > 0x7FFF;
}
public void TST_Func(ushort src)
{
FlagZ = Regs[src] == 0;
FlagV = false;
FlagN = (Regs[src] & 0xFF) > 127;
FlagC = false;
}
public void CLR_Func(ushort src)
{
Regs[src] = 0;
FlagZ = true;
FlagV = false;
FlagC = false;
FlagN = false;
}
public void ADD8BR_Func(ushort dest, ushort src)
{
if (Regs[src] > 127) { Regs[src] |= 0xFF00; }
Regs[dest] = (ushort)(Regs[dest] + (short)Regs[src]);
}
public void ADD8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
Reg16_d += Regs[src];
FlagC = Reg16_d.Bit(8);
FlagZ = (Reg16_d & 0xFF) == 0;
ushort ans = (ushort)(Reg16_d & 0xFF);
// redo for half carry flag
Reg16_d = Regs[dest] & 0xF;
Reg16_d += (Regs[src] & 0xF);
FlagH = Reg16_d.Bit(4);
FlagV = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
FlagN = ans > 127;
Regs[dest] = ans;
}
public void SUB8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
Reg16_d -= Regs[src];
FlagC = Reg16_d.Bit(8);
FlagZ = (Reg16_d & 0xFF) == 0;
ushort ans = (ushort)(Reg16_d & 0xFF);
// redo for half carry flag
Reg16_d = Regs[dest] & 0xF;
Reg16_d -= (Regs[src] & 0xF);
FlagH = Reg16_d.Bit(4);
FlagN = ans > 127;
FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
Regs[dest] = ans;
}
// same as SUB8 but result not stored
public void CMP8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
Reg16_d -= Regs[src];
FlagC = Reg16_d.Bit(8);
FlagZ = (Reg16_d & 0xFF) == 0;
ushort ans = (ushort)(Reg16_d & 0xFF);
// redo for half carry flag
Reg16_d = Regs[dest] & 0xF;
Reg16_d -= (Regs[src] & 0xF);
FlagH = Reg16_d.Bit(4);
FlagN = ans > 127;
FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
}
public void BIT_Func(ushort dest, ushort src)
{
ushort ans = (ushort)(Regs[dest] & Regs[src]);
FlagZ = ans == 0;
FlagV = false;
FlagN = ans > 127;
}
public void ASL_Func(ushort src)
{
FlagC = Regs[src].Bit(7);
FlagV = Regs[src].Bit(7) ^ Regs[src].Bit(6);
Regs[src] = (ushort)((Regs[src] << 1) & 0xFF);
FlagZ = Regs[src] == 0;
FlagH = false;
FlagN = (Regs[src] & 0xFF) > 127;
}
public void ASR_Func(ushort src)
{
FlagC = Regs[src].Bit(0);
ushort temp = (ushort)(Regs[src] & 0x80); // MSB doesn't change in this operation
Regs[src] = (ushort)((Regs[src] >> 1) | temp);
FlagZ = Regs[src] == 0;
FlagH = false;
FlagN = (Regs[src] & 0xFF) > 127;
}
public void LSR_Func(ushort src)
{
FlagC = Regs[src].Bit(0);
Regs[src] = (ushort)(Regs[src] >> 1);
FlagZ = Regs[src] == 0;
FlagN = false;
}
public void COM_Func(ushort src)
{
Regs[src] = (ushort)((~Regs[src]) & 0xFF);
FlagC = true;
FlagZ = Regs[src] == 0;
FlagV = false;
FlagN = (Regs[src] & 0xFF) > 127;
}
public void AND8_Func(ushort dest, ushort src)
{
Regs[dest] = (ushort)(Regs[dest] & Regs[src]);
FlagZ = Regs[dest] == 0;
FlagV = false;
FlagN = Regs[dest] > 127;
}
public void OR8_Func(ushort dest, ushort src)
{
Regs[dest] = (ushort)(Regs[dest] | Regs[src]);
FlagZ = Regs[dest] == 0;
FlagV = false;
FlagN = Regs[dest] > 127;
}
public void XOR8_Func(ushort dest, ushort src)
{
Regs[dest] = (ushort)(Regs[dest] ^ Regs[src]);
FlagZ = Regs[dest] == 0;
FlagV = false;
FlagN = Regs[dest] > 127;
}
public void ROR_Func(ushort src)
{
ushort c = (ushort)(FlagC ? 0x80 : 0);
FlagC = Regs[src].Bit(0);
Regs[src] = (ushort)(c | (Regs[src] >> 1));
FlagZ = Regs[src] == 0;
FlagN = (Regs[src] & 0xFF) > 127;
}
public void ROL_Func(ushort src)
{
ushort c = (ushort)(FlagC ? 1 : 0);
FlagC = Regs[src].Bit(7);
FlagV = Regs[src].Bit(7) ^ Regs[src].Bit(6);
Regs[src] = (ushort)(((Regs[src] << 1) & 0xFF) | c);
FlagZ = Regs[src] == 0;
FlagN = (Regs[src] & 0xFF) > 127;
}
public void INC8_Func(ushort src)
{
FlagV = Regs[src] == 0x7F;
Regs[src] = (ushort)((Regs[src] + 1) & 0xFF);
FlagZ = Regs[src] == 0;
FlagN = (Regs[src] & 0xFF) > 127;
}
public void DEC8_Func(ushort src)
{
FlagV = Regs[src] == 0x80;
Regs[src] = (ushort)((Regs[src] - 1) & 0xFF);
FlagZ = Regs[src] == 0;
FlagN = (Regs[src] & 0xFF) > 127;
}
public void INC16_Func(ushort src)
{
Regs[src] += 1;
}
public void DEC16_Func(ushort src)
{
Regs[src] -= 1;
}
public void ADC8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
int c = FlagC ? 1 : 0;
Reg16_d += (Regs[src] + c);
FlagC = Reg16_d.Bit(8);
FlagZ = (Reg16_d & 0xFF) == 0;
ushort ans = (ushort)(Reg16_d & 0xFF);
// redo for half carry flag
Reg16_d = Regs[dest] & 0xF;
Reg16_d += ((Regs[src] & 0xF) + c);
FlagH = Reg16_d.Bit(4);
FlagV = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
FlagN = false;
Regs[dest] = ans;
}
public void SBC8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
int c = FlagC ? 1 : 0;
Reg16_d -= (Regs[src] + c);
FlagC = Reg16_d.Bit(8);
FlagZ = (Reg16_d & 0xFF) == 0;
ushort ans = (ushort)(Reg16_d & 0xFF);
// redo for half carry flag
Reg16_d = Regs[dest] & 0xF;
Reg16_d -= ((Regs[src] & 0xF) + c);
FlagH = Reg16_d.Bit(4);
FlagN = ans > 127;
FlagV = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
Regs[dest] = ans;
}
public void DA_Func(ushort src)
{
int a = Regs[src];
byte CF = 0;
if (FlagC || ((a & 0xF) > 9))
{
CF = 6;
}
if (FlagC || (((a >> 4) & 0xF) > 9) || ((((a >> 4) & 0xF) > 8) && ((a & 0xF) > 9)))
{
CF |= (byte)(6 << 4);
}
a += CF;
if ((a > 0xFF) || FlagC)
{
FlagC = true;
}
else
{
FlagC = false;
}
Regs[src] = (byte)a;
FlagN = a > 127;
FlagZ = a == 0;
// FlagV is listed as undefined in the documentation
}
public void CMP16_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
int Reg16_s = Regs[src];
Reg16_d -= Reg16_s;
FlagC = Reg16_d.Bit(16);
FlagZ = (Reg16_d & 0xFFFF) == 0;
ushort ans = (ushort)(Reg16_d & 0xFFFF);
FlagN = ans > 0x7FFF;
FlagV = (Regs[dest].Bit(15) != Regs[src].Bit(15)) && (Regs[dest].Bit(15) != ans.Bit(15));
}
}
}

View File

@ -0,0 +1 @@
TODO: STOP for second byte nonzero

View File

@ -0,0 +1,68 @@
using System;
namespace BizHawk.Emulation.Common.Components.MC6800
{
public partial class MC6800
{
// registers
public ushort[] Regs = new ushort[11];
public const ushort PC = 0;
public const ushort SP = 1;
public const ushort X = 2;
public const ushort A = 3;
public const ushort B = 4;
public const ushort ADDR = 5; // internal
public const ushort ALU = 6; // internal
public const ushort ALU2 = 7; // internal
public const ushort DP = 8; // always zero
public const ushort CC = 9;
public const ushort IDX_EA = 10;
public bool FlagC
{
get { return (Regs[CC] & 0x01) != 0; }
set { Regs[CC] = (byte)((Regs[CC] & ~0x01) | (value ? 0x01 : 0x00)); }
}
public bool FlagV
{
get { return (Regs[CC] & 0x02) != 0; }
set { Regs[CC] = (byte)((Regs[CC] & ~0x02) | (value ? 0x02 : 0x00)); }
}
public bool FlagZ
{
get { return (Regs[CC] & 0x04) != 0; }
set { Regs[CC] = (byte)((Regs[CC] & ~0x04) | (value ? 0x04 : 0x00)); }
}
public bool FlagN
{
get { return (Regs[CC] & 0x08) != 0; }
set { Regs[CC] = (byte)((Regs[CC] & ~0x08) | (value ? 0x08 : 0x00)); }
}
public bool FlagI
{
get { return (Regs[CC] & 0x10) != 0; }
set { Regs[CC] = (byte)((Regs[CC] & ~0x10) | (value ? 0x10 : 0x00)); }
}
public bool FlagH
{
get { return (Regs[CC] & 0x20) != 0; }
set { Regs[CC] = (byte)((Regs[CC] & ~0x20) | (value ? 0x20 : 0x00)); }
}
private void ResetRegisters()
{
for (int i = 0; i < 14; i++)
{
Regs[i] = 0;
}
FlagI = true;
}
}
}

View File

@ -1010,15 +1010,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
} }
} }
} }
else if (result.Contains("r8"))
{
byte d = reader(addr++);
bytes.Add(d);
int offs = d;
if (offs >= 128)
offs -= 256;
result = result.Replace("r8", string.Format("{0:X4}h", (ushort)(addr + offs)));
}
StringBuilder ret = new StringBuilder(); StringBuilder ret = new StringBuilder();
ret.Append(string.Format("{0:X4}: ", origaddr)); ret.Append(string.Format("{0:X4}: ", origaddr));
foreach (var b in bytes) foreach (var b in bytes)

View File

@ -180,7 +180,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case 0x9A: DIRECT_MEM_4(OR8, A); break; // ORA (Direct) case 0x9A: DIRECT_MEM_4(OR8, A); break; // ORA (Direct)
case 0x9B: DIRECT_MEM_4(ADD8, A); break; // ADDA (Direct) case 0x9B: DIRECT_MEM_4(ADD8, A); break; // ADDA (Direct)
case 0x9C: DIR_CMP_16(CMP16, X); break; // CMPX (Direct) case 0x9C: DIR_CMP_16(CMP16, X); break; // CMPX (Direct)
case 0x9D: REG_OP(ADC8, A); break; // JSR (Direct) case 0x9D: JSR_(); break; // JSR (Direct)
case 0x9E: DIR_OP_LD_16(X); break; // LDX (Direct) case 0x9E: DIR_OP_LD_16(X); break; // LDX (Direct)
case 0x9F: DIR_OP_ST_16(X); break; // STX (Direct) case 0x9F: DIR_OP_ST_16(X); break; // STX (Direct)
case 0xA0: INDEX_OP_REG(I_SUB, A); break; // SUBA (Indexed) case 0xA0: INDEX_OP_REG(I_SUB, A); break; // SUBA (Indexed)

View File

@ -103,7 +103,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void INDEX_OP_ST() private void INDEX_OP_ST()
{ {
PopulateCURINSTR(IDLE, PopulateCURINSTR(ST_16, indexed_op_reg,
WR_HI_INC, IDX_EA, indexed_op_reg, WR_HI_INC, IDX_EA, indexed_op_reg,
WR_DEC_LO, IDX_EA, indexed_op_reg); WR_DEC_LO, IDX_EA, indexed_op_reg);
@ -121,8 +121,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void INDEX_OP_STD() private void INDEX_OP_STD()
{ {
PopulateCURINSTR(SET_ADDR, ADDR, A, A, PopulateCURINSTR(ST_16, Dr,
WR_HI_INC, IDX_EA, ADDR, WR_LO_INC, IDX_EA, A,
WR_DEC_LO, IDX_EA, B); WR_DEC_LO, IDX_EA, B);
IRQS = 3; IRQS = 3;
@ -138,7 +138,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void INDEX_OP_EX4_ST() private void INDEX_OP_EX4_ST()
{ {
PopulateCURINSTR(IDLE, PopulateCURINSTR(ST_8, indexed_op_reg,
WR, IDX_EA, indexed_op_reg); WR, IDX_EA, indexed_op_reg);
IRQS = 2; IRQS = 2;

View File

@ -29,54 +29,54 @@ namespace BizHawk.Emulation.Common.Components.MC6809
public const ushort AND8 = 18; public const ushort AND8 = 18;
public const ushort XOR8 = 19; public const ushort XOR8 = 19;
public const ushort OR8 = 20; public const ushort OR8 = 20;
public const ushort CP8 = 21; public const ushort ASL = 21;
public const ushort ASL = 22; public const ushort ASR = 22;
public const ushort ASR = 23; public const ushort LSR = 23;
public const ushort LSR = 24; public const ushort BIT = 24;
public const ushort BIT = 25; public const ushort CWAI = 25;
public const ushort CWAI = 26; public const ushort SYNC = 26;
public const ushort SYNC = 27; public const ushort RD_INC = 27;
public const ushort INT_GET = 28; public const ushort RD_INC_OP = 28;
public const ushort HALT_CHK = 29; public const ushort WR_DEC_LO = 29;
public const ushort RD_INC = 30; public const ushort WR_DEC_HI = 30;
public const ushort SET_ADDR = 31; public const ushort WR_HI = 31;
public const ushort NEG = 32; public const ushort SET_ADDR = 32;
public const ushort TST = 33; public const ushort NEG = 33;
public const ushort CLR = 34; public const ushort TST = 34;
public const ushort OP_PG_2 = 35; public const ushort CLR = 35;
public const ushort OP_PG_3 = 36; public const ushort OP_PG_2 = 36;
public const ushort SEX = 37; public const ushort OP_PG_3 = 37;
public const ushort RD_INC_OP = 38; public const ushort SEX = 38;
public const ushort EXG = 39; public const ushort EXG = 39;
public const ushort TFR = 40; public const ushort TFR = 40;
public const ushort WR_DEC_LO = 41; public const ushort ADD8BR = 41;
public const ushort WR_DEC_HI = 42; public const ushort ABX = 42;
public const ushort WR_HI = 43; public const ushort MUL = 43;
public const ushort ADD8BR = 44; public const ushort JPE = 44;
public const ushort ABX = 45; public const ushort IDX_DCDE = 45;
public const ushort MUL = 46; public const ushort IDX_OP_BLD = 46;
public const ushort JPE = 47; public const ushort EA_8 = 47;
public const ushort IDX_DCDE = 48; public const ushort EA_16 = 48;
public const ushort IDX_OP_BLD = 49; public const ushort PSH_n = 49;
public const ushort EA_8 = 50; public const ushort PUL_n = 50;
public const ushort EA_16 = 51; public const ushort WR_DEC_LO_OP = 51;
public const ushort PSH_n = 52; public const ushort WR_DEC_HI_OP = 52;
public const ushort PUL_n = 53; public const ushort WR_HI_INC = 53;
public const ushort WR_DEC_LO_OP = 54; public const ushort WR_LO_INC = 54;
public const ushort WR_DEC_HI_OP = 55; public const ushort SET_ADDR_PUL = 55;
public const ushort SET_ADDR_PUL = 56; public const ushort SET_F_I = 56;
public const ushort SET_F_I = 57; public const ushort SET_I = 57;
public const ushort SET_I = 58; public const ushort SET_E = 58;
public const ushort SET_E = 59; public const ushort ANDCC = 59;
public const ushort ANDCC = 60; public const ushort CMP8 = 60;
public const ushort CMP8 = 61; public const ushort SUB16 = 61;
public const ushort SUB16 = 62; public const ushort ADD16 = 62;
public const ushort ADD16 = 63; public const ushort CMP16 = 63;
public const ushort CMP16 = 64; public const ushort CMP16D = 64;
public const ushort CMP16D = 65; public const ushort LD_8 = 65;
public const ushort WR_HI_INC = 66; public const ushort LD_16 = 66;
public const ushort LD_8 = 67; public const ushort ST_8 = 67;
public const ushort LD_16 = 68; public const ushort ST_16 = 68;
public const ushort LEA = 69; public const ushort LEA = 69;
public const ushort CLR_E = 70; public const ushort CLR_E = 70;
@ -299,6 +299,9 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case WR_HI_INC: case WR_HI_INC:
Write_Hi_Inc_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); Write_Hi_Inc_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
case WR_LO_INC:
Write_Lo_Inc_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case TR: case TR:
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
@ -308,6 +311,12 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case LD_16: case LD_16:
LD_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); LD_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
case ST_8:
ST_8_Func(cur_instr[instr_pntr++]);
break;
case ST_16:
ST_16_Func(cur_instr[instr_pntr++]);
break;
case LEA: case LEA:
LEA_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); LEA_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
@ -439,9 +448,6 @@ namespace BizHawk.Emulation.Common.Components.MC6809
case OR8: case OR8:
OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]); OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break; break;
case CP8:
CP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
break;
case ASL: case ASL:
ASL_Func(cur_instr[instr_pntr++]); ASL_Func(cur_instr[instr_pntr++]);
break; break;
@ -507,12 +513,6 @@ namespace BizHawk.Emulation.Common.Components.MC6809
IRQS = 1; IRQS = 1;
instr_pntr = irq_pntr = 0; instr_pntr = irq_pntr = 0;
PopulateCURINSTR(SYNC); PopulateCURINSTR(SYNC);
break;
case INT_GET:
break;
case HALT_CHK:
break; break;
} }

View File

@ -52,7 +52,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void DIRECT_ST_4(ushort dest) private void DIRECT_ST_4(ushort dest)
{ {
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
IDLE, ST_8, dest,
WR, ADDR, dest); WR, ADDR, dest);
IRQS = 3; IRQS = 3;
@ -93,7 +93,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
{ {
PopulateCURINSTR(RD_INC, ALU, PC, PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
IDLE, ST_8, dest,
WR, ADDR, dest); WR, ADDR, dest);
IRQS = 4; IRQS = 4;
@ -168,8 +168,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void DIR_OP_ST_16D() private void DIR_OP_ST_16D()
{ {
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
SET_ADDR, ALU, A, A, ST_16, Dr,
WR_HI_INC, ADDR, ALU, WR_LO_INC, ADDR, A,
WR, ADDR, B); WR, ADDR, B);
IRQS = 4; IRQS = 4;
@ -216,7 +216,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void DIR_OP_ST_16(ushort src) private void DIR_OP_ST_16(ushort src)
{ {
PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU, PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
IDLE, ST_16, src,
WR_HI_INC, ADDR, src, WR_HI_INC, ADDR, src,
WR_DEC_LO, ADDR, src); WR_DEC_LO, ADDR, src);
@ -238,7 +238,7 @@ namespace BizHawk.Emulation.Common.Components.MC6809
{ {
PopulateCURINSTR(RD_INC, ALU, PC, PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
IDLE, ST_16, src,
WR_HI_INC, ADDR, src, WR_HI_INC, ADDR, src,
WR_DEC_LO, ADDR, src); WR_DEC_LO, ADDR, src);
@ -260,8 +260,8 @@ namespace BizHawk.Emulation.Common.Components.MC6809
{ {
PopulateCURINSTR(RD_INC, ALU, PC, PopulateCURINSTR(RD_INC, ALU, PC,
RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2, RD_INC_OP, ALU2, PC, SET_ADDR, ADDR, ALU, ALU2,
SET_ADDR, ALU, A, A, ST_16, Dr,
WR_HI_INC, ADDR, ALU, WR_LO_INC, ADDR, A,
WR, ADDR, B); WR, ADDR, B);
IRQS = 5; IRQS = 5;
@ -322,12 +322,12 @@ namespace BizHawk.Emulation.Common.Components.MC6809
private void JSR_() private void JSR_()
{ {
PopulateCURINSTR(RD_INC, ALU, PC, PopulateCURINSTR(RD_INC_OP, ALU, PC, SET_ADDR, ADDR, DP, ALU,
SET_ADDR, ADDR, DP, ALU, TR, ALU, PC,
DEC16, SP, DEC16, SP,
TR, PC, ADDR, TR, PC, ADDR,
WR_DEC_LO, SP, ADDR, WR_DEC_LO, SP, ALU,
WR_HI, SP, ADDR); WR_HI, SP, ALU);
IRQS = 6; IRQS = 6;
} }

View File

@ -62,6 +62,13 @@ namespace BizHawk.Emulation.Common.Components.MC6809
Regs[dest]++; Regs[dest]++;
} }
public void Write_Lo_Inc_Func(ushort dest, ushort src)
{
if (CDLCallback != null) CDLCallback(Regs[dest], eCDLogMemFlags.Write | eCDLogMemFlags.Data);
WriteMemory(Regs[dest], (byte)Regs[src]);
Regs[dest]++;
}
public void NEG_8_Func(ushort src) public void NEG_8_Func(ushort src)
{ {
int Reg16_d = 0; int Reg16_d = 0;
@ -94,6 +101,13 @@ namespace BizHawk.Emulation.Common.Components.MC6809
FlagN = (Regs[dest] & 0xFF) > 127; FlagN = (Regs[dest] & 0xFF) > 127;
} }
public void ST_8_Func(ushort dest)
{
FlagZ = (Regs[dest] & 0xFF) == 0;
FlagV = false;
FlagN = (Regs[dest] & 0xFF) > 127;
}
public void LD_16_Func(ushort dest, ushort src_h, ushort src_l) public void LD_16_Func(ushort dest, ushort src_h, ushort src_l)
{ {
Regs[dest] = (ushort)(Regs[src_h] << 8 | Regs[src_l]); Regs[dest] = (ushort)(Regs[src_h] << 8 | Regs[src_l]);
@ -103,6 +117,18 @@ namespace BizHawk.Emulation.Common.Components.MC6809
FlagN = Regs[dest] > 0x7FFF; FlagN = Regs[dest] > 0x7FFF;
} }
public void ST_16_Func(ushort dest)
{
if (dest == Dr)
{
Regs[dest] = D;
}
FlagZ = Regs[dest] == 0;
FlagV = false;
FlagN = Regs[dest] > 0x7FFF;
}
// for LEAX/Y, zero flag can be effected, but not for U/S // for LEAX/Y, zero flag can be effected, but not for U/S
public void LEA_Func(ushort dest, ushort src) public void LEA_Func(ushort dest, ushort src)
{ {
@ -311,23 +337,6 @@ namespace BizHawk.Emulation.Common.Components.MC6809
FlagN = Regs[dest] > 127; FlagN = Regs[dest] > 127;
} }
public void CP8_Func(ushort dest, ushort src)
{
int Reg16_d = Regs[dest];
Reg16_d -= Regs[src];
FlagC = Reg16_d.Bit(8);
FlagZ = (Reg16_d & 0xFF) == 0;
// redo for half carry flag
Reg16_d = Regs[dest] & 0xF;
Reg16_d -= (Regs[src] & 0xF);
FlagH = Reg16_d.Bit(4);
FlagN = true;
}
public void ROR_Func(ushort src) public void ROR_Func(ushort src)
{ {
ushort c = (ushort)(FlagC ? 0x80 : 0); ushort c = (ushort)(FlagC ? 0x80 : 0);
@ -429,28 +438,34 @@ namespace BizHawk.Emulation.Common.Components.MC6809
Regs[dest] = ans; Regs[dest] = ans;
} }
// DA code courtesy of AWJ: http://forums.nesdev.com/viewtopic.php?f=20&t=15944
public void DA_Func(ushort src) public void DA_Func(ushort src)
{ {
byte a = (byte)Regs[src]; int a = Regs[src];
if (!FlagN) byte CF = 0;
{ // after an addition, adjust if (half-)carry occurred or if result is out of bounds if (FlagC || ((a & 0xF) > 9))
if (FlagC || a > 0x99) { a += 0x60; FlagC = true; } {
if (FlagH || (a & 0x0f) > 0x09) { a += 0x6; } CF = 6;
}
if (FlagC || (((a >> 4) & 0xF) > 9) || ((((a >> 4) & 0xF) > 8) && ((a & 0xF) > 9)))
{
CF |= (byte)(6 << 4);
}
a += CF;
if ((a > 0xFF) || FlagC)
{
FlagC = true;
} }
else else
{ // after a subtraction, only adjust if (half-)carry occurred {
if (FlagC) { a -= 0x60; } FlagC = false;
if (FlagH) { a -= 0x6; }
} }
Regs[src] = (byte)a;
a &= 0xFF; FlagN = a > 127;
Regs[src] = a;
FlagZ = a == 0; FlagZ = a == 0;
FlagH = false; // FlagV is listed as undefined in the documentation
} }
// D register implied // D register implied

View File

@ -104,6 +104,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private int _hmbDelay; private int _hmbDelay;
private byte _hmbVal; private byte _hmbVal;
private int _hmClrDelay;
private int _prg0Delay; private int _prg0Delay;
private int _prg1Delay; private int _prg1Delay;
private byte _prg0Val; private byte _prg0Val;
@ -387,6 +389,21 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
} }
} }
if (_hmClrDelay > 0)
{
_hmClrDelay++;
if (_hmClrDelay == 5)
{
_hmClrDelay = 0;
_player0.HM = 0;
_player0.Missile.Hm = 0;
_player1.HM = 0;
_player1.Missile.Hm = 0;
_ball.HM = 0;
}
}
// Reset the RDY flag when we reach hblank // Reset the RDY flag when we reach hblank
if (_hsyncCnt <= 0) if (_hsyncCnt <= 0)
{ {
@ -799,7 +816,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_hmove.BallLatch = true; _hmove.BallLatch = true;
_hmove.BallCnt = 0; _hmove.BallCnt = 0;
_hmove.LateHBlankReset = true; if (_hsyncCnt < 67) { _hmove.LateHBlankReset = true; }
} }
} }
@ -1357,11 +1374,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
} }
else if (maskedAddr == 0x2B) // HMCLR else if (maskedAddr == 0x2B) // HMCLR
{ {
_player0.HM = 0; _hmClrDelay = 1;
_player0.Missile.Hm = 0;
_player1.HM = 0;
_player1.Missile.Hm = 0;
_ball.HM = 0;
} }
else if (maskedAddr == 0x2C) // CXCLR else if (maskedAddr == 0x2C) // CXCLR
{ {

View File

@ -51,6 +51,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
ser.Sync("hmb_delay", ref _hmbDelay); ser.Sync("hmb_delay", ref _hmbDelay);
ser.Sync("hmb_val", ref _hmbVal); ser.Sync("hmb_val", ref _hmbVal);
ser.Sync("_hmClrDelay", ref _hmClrDelay);
ser.Sync("PRG0_delay", ref _prg0Delay); ser.Sync("PRG0_delay", ref _prg0Delay);
ser.Sync("PRG1_delay", ref _prg1Delay); ser.Sync("PRG1_delay", ref _prg1Delay);
ser.Sync("PRG0_val", ref _prg0Val); ser.Sync("PRG0_val", ref _prg0Val);

View File

@ -1,7 +1,6 @@
using System; using System;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;

View File

@ -1,7 +1,6 @@
using System; using System;
using BizHawk.Emulation.Common;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Consoles.Vectrex namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{ {

View File

@ -1,9 +1,7 @@
using System; using System;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
/* /*
0x0000 - 0x7FFF ROM 0x0000 - 0x7FFF ROM
0x8000 - 0xC7FF Unmapped 0x8000 - 0xC7FF Unmapped

View File

@ -66,7 +66,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
Core._vidbuffer[(int)(Math.Round(x_pos) + 1 + 260 * (Math.Round(y_pos) - 1))] |= (int)(br & bright_int_3); Core._vidbuffer[(int)(Math.Round(x_pos) + 1 + 260 * (Math.Round(y_pos) - 1))] |= (int)(br & bright_int_3);
Core._vidbuffer[(int)(Math.Round(x_pos) - 1 + 260 * (Math.Round(y_pos) + 1))] |= (int)(br & bright_int_3); Core._vidbuffer[(int)(Math.Round(x_pos) - 1 + 260 * (Math.Round(y_pos) + 1))] |= (int)(br & bright_int_3);
Core._vidbuffer[(int)(Math.Round(x_pos) - 1 + 260 * (Math.Round(y_pos) - 1))] |= (int)(br & bright_int_3); Core._vidbuffer[(int)(Math.Round(x_pos) - 1 + 260 * (Math.Round(y_pos) - 1))] |= (int)(br & bright_int_3);
} }
} }

View File

@ -3,7 +3,6 @@ using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Components.M6502;
namespace BizHawk.Emulation.Cores.Consoles.Vectrex namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{ {
@ -16,24 +15,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public void NewCDL(ICodeDataLog cdl) public void NewCDL(ICodeDataLog cdl)
{ {
cdl["RAM"] = new byte[MemoryDomains["RAM"].Size]; cdl["RAM"] = new byte[MemoryDomains["Main RAM"].Size];
cdl["ROM"] = new byte[MemoryDomains["ROM"].Size];
if (MemoryDomains.Has("Save RAM")) cdl.SubType = "VEC";
{
cdl["Save RAM"] = new byte[MemoryDomains["Save RAM"].Size];
}
if (MemoryDomains.Has("Battery RAM"))
{
cdl["Battery RAM"] = new byte[MemoryDomains["Battery RAM"].Size];
}
if (MemoryDomains.Has("Battery RAM"))
{
cdl["Battery RAM"] = new byte[MemoryDomains["Battery RAM"].Size];
}
cdl.SubType = "VIC20";
cdl.SubVer = 0; cdl.SubVer = 0;
} }
@ -46,9 +31,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
private enum CDLog_AddrType private enum CDLog_AddrType
{ {
None, None,
RAM,
ROM, ROM,
MainRAM,
SaveRAM,
} }
[Flags] [Flags]
@ -77,8 +61,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
switch (results.Type) switch (results.Type)
{ {
case CDLog_AddrType.None: break; case CDLog_AddrType.None: break;
case CDLog_AddrType.MainRAM: CDL["Main RAM"][results.Address] |= (byte)flags; break; case CDLog_AddrType.RAM: CDL["RAM"][results.Address] |= (byte)flags; break;
case CDLog_AddrType.SaveRAM: CDL["Save RAM"][results.Address] |= (byte)flags; break; case CDLog_AddrType.ROM: CDL["ROM"][results.Address] |= (byte)flags; break;
} }
} }
} }

View File

@ -1,8 +1,5 @@
using BizHawk.Common.NumberExtensions; using System;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Consoles.Vectrex namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{ {
@ -32,21 +29,32 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
HardReset(); HardReset();
} }
if (controller.IsPressed("Reset"))
{
SoftReset();
}
_islag = true; _islag = true;
// button inputs go to port 14 in the audio registers // button inputs go to port 14 in the audio registers
audio.Register[14] = (byte)(_controllerDeck.ReadPort1(controller) & 0xF); audio.Register[14] = (byte)(_controllerDeck.ReadPort1(controller) & 0xF);
audio.Register[14] |= (byte)(_controllerDeck.ReadPort2(controller) << 4); audio.Register[14] |= (byte)(_controllerDeck.ReadPort2(controller) << 4);
if (ControllerDefinition.Name == "Vectrex Analog Controller")
{
// joystick position is based on pot reading // joystick position is based on pot reading
joy1_LR = (byte)(Math.Floor(controller.GetFloat("P1 Stick X")) + 128); joy1_LR = (byte)(Math.Floor(controller.GetFloat("P1 Stick X")) + 128);
joy1_UD = (byte)(Math.Floor(controller.GetFloat("P1 Stick Y")) + 128); joy1_UD = (byte)(Math.Floor(controller.GetFloat("P1 Stick Y")) + 128);
joy2_LR = (byte)(Math.Floor(controller.GetFloat("P2 Stick X")) + 128); joy2_LR = (byte)(Math.Floor(controller.GetFloat("P2 Stick X")) + 128);
joy2_UD = (byte)(Math.Floor(controller.GetFloat("P2 Stick Y")) + 128); joy2_UD = (byte)(Math.Floor(controller.GetFloat("P2 Stick Y")) + 128);
}
// override stick reading with digital input if supplied else
{
// most games just use digital reading, so have a digital option for simplicity
// On vectrex there is no such thing as pressing left + right or up + down // On vectrex there is no such thing as pressing left + right or up + down
// so convention will be up and right dominate // so convention will be up and right dominate
joy1_UD = joy1_LR = joy2_UD = joy2_LR = 128;
if (controller.IsPressed("P1 Down")) { joy1_UD = 0xFF; } if (controller.IsPressed("P1 Down")) { joy1_UD = 0xFF; }
if (controller.IsPressed("P1 Up")) { joy1_UD = 0; } if (controller.IsPressed("P1 Up")) { joy1_UD = 0; }
if (controller.IsPressed("P1 Left")) { joy1_LR = 0xFF; } if (controller.IsPressed("P1 Left")) { joy1_LR = 0xFF; }
@ -56,7 +64,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
if (controller.IsPressed("P2 Up")) { joy2_UD = 0; } if (controller.IsPressed("P2 Up")) { joy2_UD = 0; }
if (controller.IsPressed("P2 Left")) { joy2_LR = 0xFF; } if (controller.IsPressed("P2 Left")) { joy2_LR = 0xFF; }
if (controller.IsPressed("P2 Right")) { joy2_LR = 0; } if (controller.IsPressed("P2 Right")) { joy2_LR = 0; }
}
frame_end = false; frame_end = false;
@ -72,15 +80,19 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public void do_frame() public void do_frame()
{ {
_vidbuffer = new int[VirtualWidth * VirtualHeight]; for (int i = 0; i < 30000; i++)
//while (!frame_end)
//for (int i = 0; i < 100; i++)
while (!frame_end)
{ {
internal_state_tick(); internal_state_tick();
audio.tick(); audio.tick();
ppu.tick(); ppu.tick();
cpu.ExecuteOne(); cpu.ExecuteOne();
if (frame_end)
{
get_video_frame();
frame_end = false;
}
} }
} }
@ -109,10 +121,21 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public int _frameHz = 50; public int _frameHz = 50;
public int[] _vidbuffer; public int[] _vidbuffer;
public int[] _framebuffer;
public int[] GetVideoBuffer() public int[] GetVideoBuffer()
{ {
return _vidbuffer; return _framebuffer;
}
public void get_video_frame()
{
for (int i = 0; i < _vidbuffer.Length; i++)
{
_framebuffer[i] = _vidbuffer[i];
_vidbuffer[i] = 0;
}
} }
public int VirtualWidth => 256 + 4; public int VirtualWidth => 256 + 4;

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
@ -37,12 +36,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
1), 1),
}; };
if (cart_RAM != null)
{
var CartRam = new MemoryDomainByteArray("Cart RAM", MemoryDomain.Endian.Little, cart_RAM, true, 1);
domains.Add(CartRam);
}
MemoryDomains = new MemoryDomainList(domains); MemoryDomains = new MemoryDomainList(domains);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains); (ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains);
} }

View File

@ -6,28 +6,20 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public partial class VectrexHawk : ISaveRam public partial class VectrexHawk : ISaveRam
{ {
public byte[] CloneSaveRam() public byte[] CloneSaveRam()
{
if (cart_RAM != null)
{
return (byte[])cart_RAM.Clone();
}
else
{ {
return null; return null;
} }
}
public void StoreSaveRam(byte[] data) public void StoreSaveRam(byte[] data)
{ {
Buffer.BlockCopy(data, 0, cart_RAM, 0, data.Length);
Console.WriteLine("loading SRAM here");
} }
public bool SaveRamModified public bool SaveRamModified
{ {
get get
{ {
return has_bat & _syncSettings.Use_SRAM; return false;
} }
} }
} }

View File

@ -53,7 +53,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public enum ControllerType public enum ControllerType
{ {
Default, Digital,
Analog
} }
[JsonIgnore] [JsonIgnore]
@ -62,14 +63,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
[DisplayName("Controller 1")] [DisplayName("Controller 1")]
[Description("Select Controller Type")] [Description("Select Controller Type")]
[DefaultValue(ControllerType.Default)] [DefaultValue(ControllerType.Digital)]
public ControllerType VectrexController1 public ControllerType VectrexController1
{ {
get { return _VectrexController1; } get { return _VectrexController1; }
set set
{ {
if (value == ControllerType.Default) { Port1 = VectrexHawkControllerDeck.DefaultControllerName; } if (value == ControllerType.Digital) { Port1 = VectrexHawkControllerDeck.DefaultControllerName; }
else { Port1 = VectrexHawkControllerDeck.DefaultControllerName; } else { Port1 = "Vectrex Analog Controller"; }
_VectrexController1 = value; _VectrexController1 = value;
} }
@ -77,24 +78,19 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
[DisplayName("Controller 2")] [DisplayName("Controller 2")]
[Description("Select Controller Type")] [Description("Select Controller Type")]
[DefaultValue(ControllerType.Default)] [DefaultValue(ControllerType.Digital)]
public ControllerType VectrexController2 public ControllerType VectrexController2
{ {
get { return _VectrexController2; } get { return _VectrexController2; }
set set
{ {
if (value == ControllerType.Default) { Port2 = VectrexHawkControllerDeck.DefaultControllerName; } if (value == ControllerType.Digital) { Port2 = VectrexHawkControllerDeck.DefaultControllerName; }
else { Port2 = VectrexHawkControllerDeck.DefaultControllerName; } else { Port2 = "Vectrex Analog Controller"; }
_VectrexController2 = value; _VectrexController2 = value;
} }
} }
[DisplayName("Use Existing SaveRAM")]
[Description("When true, existing SaveRAM will be loaded at boot up")]
[DefaultValue(false)]
public bool Use_SRAM { get; set; }
public VectrexSyncSettings Clone() public VectrexSyncSettings Clone()
{ {
return (VectrexSyncSettings)MemberwiseClone(); return (VectrexSyncSettings)MemberwiseClone();

View File

@ -47,6 +47,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
ms.Close(); ms.Close();
core = ms.ToArray(); core = ms.ToArray();
} }
cpu.SyncState(ser); cpu.SyncState(ser);
mapper.SyncState(ser); mapper.SyncState(ser);
ppu.SyncState(ser); ppu.SyncState(ser);
@ -109,12 +110,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
ser.Sync(nameof(joy2_LR), ref joy2_LR); ser.Sync(nameof(joy2_LR), ref joy2_LR);
ser.Sync(nameof(joy2_UD), ref joy2_UD); ser.Sync(nameof(joy2_UD), ref joy2_UD);
ser.Sync(nameof(_framebuffer), ref _framebuffer, false);
// probably a better way to do this ser.Sync(nameof(_vidbuffer), ref _vidbuffer, false);
if (cart_RAM != null)
{
ser.Sync(nameof(cart_RAM), ref cart_RAM, false);
}
ser.EndSection(); ser.EndSection();
} }

View File

@ -4,15 +4,13 @@ using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.Components.MC6809; using BizHawk.Emulation.Common.Components.MC6809;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Consoles.Vectrex namespace BizHawk.Emulation.Cores.Consoles.Vectrex
{ {
[Core( [Core(
"VectrexHawk", "VectrexHawk",
"", "",
isPorted: false, isPorted: false,
isReleased: false)] isReleased: true)]
[ServiceNotApplicable(typeof(IDriveLight))] [ServiceNotApplicable(typeof(IDriveLight))]
public partial class VectrexHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable, public partial class VectrexHawk : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable,
ISettable<VectrexHawk.VectrexSettings, VectrexHawk.VectrexSyncSettings> ISettable<VectrexHawk.VectrexSettings, VectrexHawk.VectrexSyncSettings>
@ -23,9 +21,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
public byte[] _bios, minestorm; public byte[] _bios, minestorm;
public readonly byte[] _rom; public readonly byte[] _rom;
public byte[] cart_RAM;
public bool has_bat;
private int _frame = 0; private int _frame = 0;
public MapperBase mapper; public MapperBase mapper;
@ -140,8 +135,24 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
ppu.Reset(); ppu.Reset();
audio.Reset(); audio.Reset();
serialport.Reset(); serialport.Reset();
cpu.Reset();
RAM = new byte[0x400];
_vidbuffer = new int[VirtualWidth * VirtualHeight]; _vidbuffer = new int[VirtualWidth * VirtualHeight];
_framebuffer = new int[VirtualWidth * VirtualHeight];
}
public void SoftReset()
{
Register_Reset();
ppu.Reset();
audio.Reset();
serialport.Reset();
cpu.Reset();
_vidbuffer = new int[VirtualWidth * VirtualHeight];
_framebuffer = new int[VirtualWidth * VirtualHeight];
} }
private void ExecFetch(ushort addr) private void ExecFetch(ushort addr)

View File

@ -32,7 +32,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
.Concat(Port2.Definition.BoolButtons) .Concat(Port2.Definition.BoolButtons)
.Concat(new[] .Concat(new[]
{ {
"Power" "Power",
"Reset"
}) })
.ToList() .ToList()
}; };

View File

@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
int PortNum { get; } int PortNum { get; }
} }
[DisplayName("Vectrex Controller")] [DisplayName("Vectrex Digital Controller")]
public class StandardControls : IPort public class StandardControls : IPort
{ {
public StandardControls(int portNum) public StandardControls(int portNum)
@ -30,12 +30,10 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
PortNum = portNum; PortNum = portNum;
Definition = new ControllerDefinition Definition = new ControllerDefinition
{ {
Name = "Vectrex Controller", Name = "Vectrex Digital Controller",
BoolButtons = BaseDefinition BoolButtons = BaseDefinition
.Select(b => "P" + PortNum + " " + b) .Select(b => "P" + PortNum + " " + b)
.ToList(), .ToList(),
FloatControls = { "P" + PortNum + " Stick X", "P" + PortNum + " Stick Y" },
FloatRanges = { new[] { 127.0f, 0, -128.0f }, new[] { -128.0f, 0, 127.0f } }
}; };
} }
@ -72,4 +70,51 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex
//nothing //nothing
} }
} }
[DisplayName("Vectrex Analog Controller")]
public class AnalogControls : IPort
{
public AnalogControls(int portNum)
{
PortNum = portNum;
Definition = new ControllerDefinition
{
Name = "Vectrex Analog Controller",
BoolButtons = BaseDefinition
.Select(b => "P" + PortNum + " " + b)
.ToList(),
FloatControls = { "P" + PortNum + " Stick X", "P" + PortNum + " Stick Y" },
FloatRanges = { new[] { 127.0f, 0, -128.0f }, new[] { -128.0f, 0, 127.0f } }
};
}
public int PortNum { get; }
public ControllerDefinition Definition { get; }
public byte Read(IController c)
{
byte result = 0xFF;
if (c.IsPressed($"P{PortNum} Button 1")) { result &= 0xFE; }
if (c.IsPressed($"P{PortNum} Button 2")) { result &= 0xFD; }
if (c.IsPressed($"P{PortNum} Button 3")) { result &= 0xFB; }
if (c.IsPressed($"P{PortNum} Button 4")) { result &= 0xF7; }
return result;
}
private static readonly string[] BaseDefinition =
{
"Button 1",
"Button 2",
"Button 3",
"Button 4"
};
public void SyncState(Serializer ser)
{
//nothing
}
}
} }

View File

@ -307,7 +307,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
else else
{ {
separator_counter = 15; separator_counter = 15;
irq_countdown = 6; irq_countdown = 5;
} }
} }

View File

@ -69,6 +69,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SubNESHawk
public int _frame = 0; public int _frame = 0;
public bool IsFDS
{
get { return subnes.Board is FDS; }
}
private readonly ITraceable _tracer; private readonly ITraceable _tracer;
#region ISettable #region ISettable