commit
b2d453441e
|
@ -2,7 +2,7 @@
|
|||
/snes9xgit
|
||||
|
||||
svnrev.cs
|
||||
|
||||
.vs/**
|
||||
**/bin/**
|
||||
**/obj/**
|
||||
/output/**
|
||||
|
|
Binary file not shown.
|
@ -743,6 +743,34 @@
|
|||
"P2 B1": "",
|
||||
"P2 B2": ""
|
||||
},
|
||||
"SMS Paddle Controller": {
|
||||
"P1 Left": "LeftArrow, J1 POV1L",
|
||||
"P1 Right": "RightArrow, J1 POV1R",
|
||||
"P1 B1": "Z, J1 B1, X1 X",
|
||||
"Reset": "J1 B9, X1 Back",
|
||||
"Pause": "J1 B10, X1 Start"
|
||||
},
|
||||
"SMS Light Phaser Controller": {
|
||||
"P1 Trigger": "Z, J1 B1, X1 X, WMouse L",
|
||||
"Reset": "J1 B9, X1 Back",
|
||||
"Pause": "J1 B10, X1 Start"
|
||||
},
|
||||
"SMS Sports Pad Controller": {
|
||||
"P1 Up": "UpArrow, J1 POV1U",
|
||||
"P1 Down": "DownArrow, J1 POV1D",
|
||||
"P1 Left": "LeftArrow, J1 POV1L",
|
||||
"P1 Right": "RightArrow, J1 POV1R",
|
||||
"P1 B1": "Z, J1 B1, X1 X",
|
||||
"P1 B2": "X, J1 B2, X1 A",
|
||||
"Reset": "J1 B9, X1 Back",
|
||||
"Pause": "J1 B10, X1 Start",
|
||||
"P2 Up": "",
|
||||
"P2 Down": "",
|
||||
"P2 Left": "",
|
||||
"P2 Right": "",
|
||||
"P2 B1": "",
|
||||
"P2 B2": ""
|
||||
},
|
||||
"GG Controller": {
|
||||
"P1 Up": "UpArrow, J1 POV1U, X1 DpadUp, X1 LStickUp",
|
||||
"P1 Down": "DownArrow, J1 POV1D, X1 DpadDown, X1 LStickDown",
|
||||
|
@ -1567,6 +1595,47 @@
|
|||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
}
|
||||
},
|
||||
"SMS Paddle Controller": {
|
||||
"P1 Paddle": {
|
||||
"Value": "X1 LeftThumbX",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
}
|
||||
},
|
||||
"SMS Light Phaser Controller": {
|
||||
"P1 X": {
|
||||
"Value": "WMouse X",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.0
|
||||
},
|
||||
"P1 Y": {
|
||||
"Value": "WMouse Y",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.0
|
||||
}
|
||||
},
|
||||
"SMS Sports Pad Controller": {
|
||||
"P1 X": {
|
||||
"Value": "X1 LeftThumbX",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
"P1 Y": {
|
||||
"Value": "X1 LeftThumbY",
|
||||
"Mult": -1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
"P2 X": {
|
||||
"Value": "X2 LeftThumbX",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
"P2 Y": {
|
||||
"Value": "X2 LeftThumbY",
|
||||
"Mult": -1.0,
|
||||
"Deadzone": 0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -298,6 +298,8 @@ sha1:CEFEBA536DB507DBDEF8A538F9C332D7A75BF613 You Ling Xing Dong (Ch) NES boar
|
|||
sha1:DBFCC70CC2DEC7A889429ED542267F0F1BD967BF Ying Xiong Chuan Qi (Ch) NES board=MAPPER224
|
||||
sha1:FFB4706E49B826C6CDD12E502E8AE94FC9810B7F Monty no Doki Doki Daisassou (FDS Conversion) (Unl) [U][!] NES board=UNIF_UNL-LH32;WRAM=8;VRAM=8;PAD_H=1
|
||||
sha1:17473C223453D2D80FCB9DCFA317947287DC5C52 Xing He Zhan Shi (China) (Unl) NES board=WAIXINGMAPPER176
|
||||
sha1:B1C74236FD17FAB4AB9AA6AB28E38864C66D6255 Pocahontus (UNL) NES board=MAPPER182;PRG=256;CHR=256;WRAM=8;PAD_H=1
|
||||
sha1:5FA23F88432006DCF6874EA36E9E7DA8934427BE Super Donkey Kong (Unl) NES board=MAPPER182;PRG=128;CHR=128;WRAM=8;PAD_H=1
|
||||
|
||||
;wrong vram info
|
||||
sha1:32D71DD6C5A8D78A918FE1B9D6D6C4A570D9652D Oeka Kids Anpanman no Hiragana Daisuki (J) NES board=MAPPER096;VRAM=32
|
||||
|
|
|
@ -231,7 +231,7 @@ B19256C6716147A9744F5BD528F14450 Magic Knight Rayearth 2 - Making of Magic Knig
|
|||
846D48D0F4024C8094117599D0E1EEF1 Magic Knight Rayearth (J) GG SRAM=8192 Japan
|
||||
E496FF2196C372F4D6111538950D25CA Magical Puzzle Popils (W) (En,Ja) GG Puzzle SRAM=8192 World
|
||||
3AF0C6DDF5F00A493E1F159FCEDC0933 Magical Taruruuto-kun (J) GG Japan
|
||||
B0C35BC53AB7C184D34E5624F69AAD24 The Majors Pro Baseball (U) GG Sports;Baseball SRAM=128;GGLink USA
|
||||
B0C35BC53AB7C184D34E5624F69AAD24 The Majors Pro Baseball (U) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA
|
||||
A15C5219F766D516D1B8D9A09B9A2BB4 Mappy (J) GG Japan
|
||||
B83F36FD113A8F75F1A29652ACB641FC Marble Madness (UE) GG Arcade USA;Europe
|
||||
BA846684A66E90372C3C234955EE28BC Marko's Magic Football (E) (En,Fr,De,Es) GG Europe
|
||||
|
@ -461,9 +461,9 @@ A23E89266DDAD3C856E7401D04A49C6C Woody Pop (W) (Rev 1) GG World
|
|||
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
|
||||
D8939B64458FAF174CDC1241F777CB59 World Derby (J) GG GGLink Japan
|
||||
E7EABBFC7A1F1339C4720249AEA92A32 World Series Baseball '95 (U) GG Sports;Baseball SRAM=128;GGLink USA
|
||||
59359FC38865CFF00C90D6EB148DDC2F World Series Baseball (U) GG Sports;Baseball SRAM=128;GGLink USA
|
||||
05CAC33029F0CAAC27774504C1AA8597 World Series Baseball (U) (Rev 1) GG Sports;Baseball SRAM=128;GGLink 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
|
||||
05CAC33029F0CAAC27774504C1AA8597 World Series Baseball (U) (Rev 1) GG Sports;Baseball SRAM=128;GGLink;EEPROM USA
|
||||
D810E851AD60ED5BA50B6246C2CE12F2 WWF Raw (UE) GG Sports;Wrestling USA;Europe
|
||||
571AC03B80E3075C699CD583BF8651FD X-Men - Gamemaster's Legacy (UE) GG Marvel USA;Europe
|
||||
CA15F2BA2507EBD836C42D9D10231EB1 X-Men - Mojo World (UE) GG Marvel USA;Europe
|
||||
|
|
|
@ -106,7 +106,7 @@ F2535DF9BDC3A84221303FA62D61AD6E Back to the Future Part II (E) SMS Europe
|
|||
3D24A52E98E6C85D7C059386451CE749 Back to the Future Part III (E) SMS PAL Europe
|
||||
8A94DED3D95AA46DAE8800B92E66D3EE Baku Baku (B) SMS Brazil
|
||||
7A5D3B9963E316CB7F73BBDC2A7311C6 Bank Panic (E) SMS Europe
|
||||
26DF4404950CB8DA47235833C0C101C6 Bart vs. the Space Mutants (E) SMS Europe
|
||||
26DF4404950CB8DA47235833C0C101C6 Bart vs. the Space Mutants (E) SMS PAL Europe
|
||||
CBA2EC2940619956359801618E7AAB17 Bart vs. the World (E) SMS Europe
|
||||
0069B1BD9C5B6B88ACE6324D7E61539F Basketball Nightmare (E) SMS Sports;Basketball Europe
|
||||
215876A62D3CA48D28E98CD8A2C70A15 Batman Returns (E) SMS Europe
|
||||
|
|
|
@ -470,7 +470,7 @@ namespace BizHawk.Client.Common
|
|||
System = "PSX"
|
||||
};
|
||||
}
|
||||
else if (ext == ".iso" || ext == ".cue" || ext == ".ccd")
|
||||
else if (ext == ".iso" || ext == ".cue" || ext == ".ccd" || ext == ".mds")
|
||||
{
|
||||
if (file.IsArchive)
|
||||
{
|
||||
|
@ -494,7 +494,7 @@ namespace BizHawk.Client.Common
|
|||
throw new InvalidOperationException("\r\n" + discMountJob.OUT_Log);
|
||||
}
|
||||
|
||||
var disc = discMountJob.OUT_Disc;
|
||||
var disc = discMountJob.OUT_Disc;
|
||||
|
||||
// -----------
|
||||
// TODO - use more sophisticated IDer
|
||||
|
@ -514,7 +514,9 @@ namespace BizHawk.Client.Common
|
|||
// try to use our wizard methods
|
||||
game = new GameInfo { Name = Path.GetFileNameWithoutExtension(file.Name), Hash = discHash };
|
||||
|
||||
switch (new DiscIdentifier(disc).DetectDiscType())
|
||||
var dt = new DiscIdentifier(disc).DetectDiscType();
|
||||
|
||||
switch (dt)
|
||||
{
|
||||
case DiscType.SegaSaturn:
|
||||
game.System = "SAT";
|
||||
|
@ -532,9 +534,23 @@ namespace BizHawk.Client.Common
|
|||
case DiscType.PCFX:
|
||||
game.System = "PCFX";
|
||||
break;
|
||||
case DiscType.TurboCD:
|
||||
game.System = "PCECD";
|
||||
break;
|
||||
|
||||
case DiscType.Amiga:
|
||||
case DiscType.CDi:
|
||||
case DiscType.Dreamcast:
|
||||
case DiscType.GameCube:
|
||||
case DiscType.NeoGeoCD:
|
||||
case DiscType.Panasonic3DO:
|
||||
case DiscType.Playdia:
|
||||
case DiscType.Wii:
|
||||
// no supported emulator core for these (yet)
|
||||
game.System = dt.ToString();
|
||||
throw new NoAvailableCoreException(dt.ToString());
|
||||
|
||||
case DiscType.AudioDisc:
|
||||
case DiscType.TurboCD:
|
||||
case DiscType.UnknownCDFS:
|
||||
case DiscType.UnknownFormat:
|
||||
if (PreferredPlatformIsDefined(ext))
|
||||
|
@ -543,7 +559,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
game.System = "PCECD";
|
||||
game.System = "NULL"; // "PCECD";
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -552,6 +568,9 @@ namespace BizHawk.Client.Common
|
|||
|
||||
switch (game.System)
|
||||
{
|
||||
case "NULL":
|
||||
nextEmulator = null;
|
||||
break;
|
||||
case "GEN":
|
||||
var genesis = new GPGX(nextComm, null, new[] { disc }, GetCoreSettings<GPGX>(), GetCoreSyncSettings<GPGX>());
|
||||
nextEmulator = genesis;
|
||||
|
@ -1029,7 +1048,14 @@ namespace BizHawk.Client.Common
|
|||
DoMessageCallback("Failed to load a GB rom in SGB mode. Disabling SGB Mode.");
|
||||
return LoadRom(path, nextComm, false, recursiveCount + 1);
|
||||
}
|
||||
else
|
||||
|
||||
// handle exceptions thrown by the new detected systems that bizhawk does not have cores for
|
||||
else if (ex is NoAvailableCoreException)
|
||||
{
|
||||
DoLoadErrorCallback(ex.Message + "\n\n" + ex, system);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
DoLoadErrorCallback("A core accepted the rom, but threw an exception while loading it:\n\n" + ex, system);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@ namespace BizHawk.Client.Common
|
|||
[RequiredService]
|
||||
private IEmulator Emulator { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
private IMemoryDomains Domains { get; set; }
|
||||
|
||||
private readonly LuaFunctionList _luaFunctions = new LuaFunctionList();
|
||||
|
||||
public EventLuaLibrary(Lua lua)
|
||||
|
@ -210,7 +213,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
[LuaMethod("onmemoryexecute", "Fires after the given address is executed by the core")]
|
||||
public string OnMemoryExecute(LuaFunction luaf, uint address, string name = null)
|
||||
public string OnMemoryExecute(LuaFunction luaf, uint address, string name = null, string domain = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -225,8 +228,16 @@ namespace BizHawk.Client.Common
|
|||
var nlf = new NamedLuaFunction(luaf, "OnMemoryExecute", LogOutputCallback, CurrentThread, name);
|
||||
_luaFunctions.Add(nlf);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(domain))
|
||||
{
|
||||
if (Domains != null && Domains.HasSystemBus)
|
||||
{
|
||||
domain = Domains.SystemBus.Name;
|
||||
}
|
||||
}
|
||||
|
||||
DebuggableCore.MemoryCallbacks.Add(
|
||||
new MemoryCallback(MemoryCallbackType.Execute, "Lua Hook", nlf.Callback, address, null));
|
||||
new MemoryCallback(domain, MemoryCallbackType.Execute, "Lua Hook", nlf.Callback, address, null));
|
||||
return nlf.Guid.ToString();
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +252,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
[LuaMethod("onmemoryread", "Fires after the given address is read by the core. If no address is given, it will attach to every memory read")]
|
||||
public string OnMemoryRead(LuaFunction luaf, uint? address = null, string name = null)
|
||||
public string OnMemoryRead(LuaFunction luaf, uint? address = null, string name = null, string domain = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -255,8 +266,16 @@ namespace BizHawk.Client.Common
|
|||
var nlf = new NamedLuaFunction(luaf, "OnMemoryRead", LogOutputCallback, CurrentThread, name);
|
||||
_luaFunctions.Add(nlf);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(domain))
|
||||
{
|
||||
if (Domains != null && Domains.HasSystemBus)
|
||||
{
|
||||
domain = Domains.SystemBus.Name;
|
||||
}
|
||||
}
|
||||
|
||||
DebuggableCore.MemoryCallbacks.Add(
|
||||
new MemoryCallback(MemoryCallbackType.Read, "Lua Hook", nlf.Callback, address, null));
|
||||
new MemoryCallback(domain, MemoryCallbackType.Read, "Lua Hook", nlf.Callback, address, null));
|
||||
return nlf.Guid.ToString();
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +290,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
[LuaMethod("onmemorywrite", "Fires after the given address is written by the core. If no address is given, it will attach to every memory write")]
|
||||
public string OnMemoryWrite(LuaFunction luaf, uint? address = null, string name = null)
|
||||
public string OnMemoryWrite(LuaFunction luaf, uint? address = null, string name = null, string domain = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -285,8 +304,16 @@ namespace BizHawk.Client.Common
|
|||
var nlf = new NamedLuaFunction(luaf, "OnMemoryWrite", LogOutputCallback, CurrentThread, name);
|
||||
_luaFunctions.Add(nlf);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(domain))
|
||||
{
|
||||
if (Domains != null && Domains.HasSystemBus)
|
||||
{
|
||||
domain = Domains.SystemBus.Name;
|
||||
}
|
||||
}
|
||||
|
||||
DebuggableCore.MemoryCallbacks.Add(
|
||||
new MemoryCallback(MemoryCallbackType.Write, "Lua Hook", nlf.Callback, address, null));
|
||||
new MemoryCallback(domain, MemoryCallbackType.Write, "Lua Hook", nlf.Callback, address, null));
|
||||
return nlf.Guid.ToString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.ComponentModel;
|
|||
using NLua;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Common.BufferExtensions;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -108,6 +109,37 @@ namespace BizHawk.Client.Common
|
|||
return false;
|
||||
}
|
||||
|
||||
[LuaMethod("hash_region", "Returns a hash as a string of a region of memory, starting from addr, through count bytes. If the domain is unspecified, it uses the current region.")]
|
||||
public string HashRegion(int addr, int count, string domain = null)
|
||||
{
|
||||
var d = string.IsNullOrEmpty(domain) ? Domain : DomainList[VerifyMemoryDomain(domain)];
|
||||
|
||||
// checks
|
||||
if (addr < 0 || addr >= d.Size)
|
||||
{
|
||||
string error = $"Address {addr} is outside the bounds of domain {d.Name}";
|
||||
Log(error);
|
||||
throw new ArgumentOutOfRangeException(error);
|
||||
}
|
||||
if (addr + count > d.Size)
|
||||
{
|
||||
string error = $"Address {addr} + count {count} is outside the bounds of domain {d.Name}";
|
||||
Log(error);
|
||||
throw new ArgumentOutOfRangeException(error);
|
||||
}
|
||||
|
||||
byte[] data = new byte[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
data[i] = d.PeekByte(addr + i);
|
||||
}
|
||||
|
||||
using (var hasher = System.Security.Cryptography.SHA256.Create())
|
||||
{
|
||||
return hasher.ComputeHash(data).BytesToHexString();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Common Special and Legacy Methods
|
||||
|
|
|
@ -318,7 +318,7 @@ namespace BizHawk.Client.Common
|
|||
if (Movie is TasMovie)
|
||||
{
|
||||
(Movie as TasMovie).GreenzoneCurrentFrame();
|
||||
if (Movie.IsPlaying && Global.Emulator.Frame > Movie.InputLogLength)
|
||||
if (Movie.IsPlaying && Global.Emulator.Frame >= Movie.InputLogLength)
|
||||
{
|
||||
HandleFrameLoopForRecordMode();
|
||||
}
|
||||
|
|
|
@ -514,14 +514,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
Log?.Dispose();
|
||||
Log = branch.InputLog.Clone();
|
||||
////_changes = true;
|
||||
|
||||
_lagLog.FromLagLog(branch.LagLog);
|
||||
|
||||
// if there are branch states, they will be loaded anyway
|
||||
// but if there's none, or only *after* divergent point, don't invalidate the entire movie anymore
|
||||
if (divergentPoint.HasValue)
|
||||
{
|
||||
_stateManager.Invalidate(divergentPoint.Value);
|
||||
_lagLog.FromLagLog(branch.LagLog); // don't truncate LagLog if the branch's one is shorter, but input is the same
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -530,8 +530,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
_stateManager.LoadBranch(Branches.IndexOf(branch));
|
||||
_stateManager.SetState(branch.Frame, branch.CoreData);
|
||||
|
||||
////ChangeLog = branch.ChangeLog;
|
||||
|
||||
if (BindMarkersToInput) // pretty critical not to erase them
|
||||
{
|
||||
Markers = branch.Markers;
|
||||
|
|
|
@ -44,14 +44,16 @@ namespace BizHawk.Client.Common
|
|||
private readonly TasMovie _movie;
|
||||
private ulong _expectedStateSize;
|
||||
|
||||
private readonly int _minFrequency = VersionInfo.DeveloperBuild ? 2 : 1;
|
||||
private readonly int _minFrequency = 1;
|
||||
private const int MaxFrequency = 16;
|
||||
private int MaxStates => (int)(Settings.Cap / _expectedStateSize) + (int)((ulong)Settings.DiskCapacitymb * 1024 * 1024 / _expectedStateSize);
|
||||
private int FileStateGap => 1 << Settings.FileStateGap;
|
||||
|
||||
private int StateFrequency
|
||||
{
|
||||
get
|
||||
{
|
||||
int freq = (int)(_expectedStateSize / 65536);
|
||||
int freq = (int)_expectedStateSize / Settings.MemStateGapDivider / 1024;
|
||||
|
||||
if (freq < _minFrequency)
|
||||
{
|
||||
|
@ -66,11 +68,7 @@ namespace BizHawk.Client.Common
|
|||
return freq;
|
||||
}
|
||||
}
|
||||
|
||||
private int MaxStates => (int)(Settings.Cap / _expectedStateSize) + (int)((ulong)Settings.DiskCapacitymb * 1024 * 1024 / _expectedStateSize);
|
||||
|
||||
private int StateGap => 1 << Settings.StateGap;
|
||||
|
||||
|
||||
public TasStateManager(TasMovie movie)
|
||||
{
|
||||
_movie = movie;
|
||||
|
@ -585,7 +583,7 @@ namespace BizHawk.Client.Common
|
|||
for (int i = 1; i < _states.Count; i++)
|
||||
{
|
||||
if (_movie.Markers.IsMarker(_states.ElementAt(i).Key + 1)
|
||||
|| _states.ElementAt(i).Key % StateGap == 0)
|
||||
|| _states.ElementAt(i).Key % FileStateGap == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,9 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
DiskSaveCapacitymb = 512;
|
||||
Capacitymb = 512;
|
||||
DiskCapacitymb = 512;
|
||||
StateGap = 4;
|
||||
DiskCapacitymb = 1; // not working yet
|
||||
MemStateGapDivider = 64;
|
||||
FileStateGap = 4;
|
||||
BranchStatesInTasproj = false;
|
||||
EraseBranchStatesFirst = true;
|
||||
}
|
||||
|
@ -22,7 +23,8 @@ namespace BizHawk.Client.Common
|
|||
DiskSaveCapacitymb = settings.DiskSaveCapacitymb;
|
||||
Capacitymb = settings.Capacitymb;
|
||||
DiskCapacitymb = settings.DiskCapacitymb;
|
||||
StateGap = settings.StateGap;
|
||||
MemStateGapDivider = settings.MemStateGapDivider;
|
||||
FileStateGap = settings.FileStateGap;
|
||||
BranchStatesInTasproj = settings.BranchStatesInTasproj;
|
||||
EraseBranchStatesFirst = settings.EraseBranchStatesFirst;
|
||||
}
|
||||
|
@ -55,12 +57,19 @@ namespace BizHawk.Client.Common
|
|||
[Description("The size limit of the state history buffer on the disk. When this limit is reached it will start removing previous savestates")]
|
||||
public int DiskCapacitymb { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the divider that determines memory state gap
|
||||
/// </summary>
|
||||
[DisplayName("Divider for memory state interval")]
|
||||
[Description("The actual state gap in frames is calculated as ExpectedStateSize / div / 1024")]
|
||||
public int MemStateGapDivider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the amount of states to skip during project saving
|
||||
/// </summary>
|
||||
[DisplayName("State interval for .tasproj")]
|
||||
[Description("The actual state gap in frames is calculated as Nth power on 2")]
|
||||
public int StateGap { get; set; }
|
||||
public int FileStateGap { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether or not to save branch states into the movie file
|
||||
|
@ -99,7 +108,8 @@ namespace BizHawk.Client.Common
|
|||
sb.AppendLine(DiskCapacitymb.ToString());
|
||||
sb.AppendLine(BranchStatesInTasproj.ToString());
|
||||
sb.AppendLine(EraseBranchStatesFirst.ToString());
|
||||
sb.AppendLine(StateGap.ToString());
|
||||
sb.AppendLine(FileStateGap.ToString());
|
||||
sb.AppendLine(MemStateGapDivider.ToString());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
@ -123,13 +133,13 @@ namespace BizHawk.Client.Common
|
|||
DiskSaveCapacitymb = refCapacity;
|
||||
}
|
||||
|
||||
DiskCapacitymb = lines.Length > 2 ? int.Parse(lines[2]) : 512;
|
||||
int i = 2;
|
||||
|
||||
BranchStatesInTasproj = lines.Length > 3 && bool.Parse(lines[3]);
|
||||
|
||||
EraseBranchStatesFirst = lines.Length <= 4 || bool.Parse(lines[4]);
|
||||
|
||||
StateGap = lines.Length > 5 ? int.Parse(lines[5]) : 4;
|
||||
DiskCapacitymb = lines.Length > i ? int.Parse(lines[i++]) : 1;
|
||||
BranchStatesInTasproj = lines.Length > i && bool.Parse(lines[i++]);
|
||||
EraseBranchStatesFirst = lines.Length <= i || bool.Parse(lines[i++]);
|
||||
FileStateGap = lines.Length > i ? int.Parse(lines[i++]) : 4;
|
||||
FileStateGap = lines.Length > i ? int.Parse(lines[i++]) : 64;
|
||||
}
|
||||
catch (Exception) // TODO: this is bad
|
||||
{
|
||||
|
|
|
@ -284,29 +284,61 @@ namespace BizHawk.Client.Common
|
|||
case WatchSize.Byte:
|
||||
return (byte?)_val;
|
||||
case WatchSize.Word:
|
||||
if (addr == _watch.Address)
|
||||
if (_watch.BigEndian)
|
||||
{
|
||||
if (addr == _watch.Address)
|
||||
{
|
||||
return (byte)(_val & 0xFF);
|
||||
}
|
||||
return (byte)(_val >> 8);
|
||||
}
|
||||
|
||||
return (byte)(_val & 0xFF);
|
||||
case WatchSize.DWord:
|
||||
if (addr == _watch.Address)
|
||||
else
|
||||
{
|
||||
if (addr == _watch.Address)
|
||||
{
|
||||
return (byte)(_val >> 8);
|
||||
}
|
||||
return (byte)(_val & 0xFF);
|
||||
}
|
||||
case WatchSize.DWord:
|
||||
if (_watch.BigEndian)
|
||||
{
|
||||
if (addr == _watch.Address)
|
||||
{
|
||||
return (byte)((_val >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
if (addr == _watch.Address + 1)
|
||||
{
|
||||
return (byte)((_val >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
if (addr == _watch.Address + 2)
|
||||
{
|
||||
return (byte)((_val >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
return (byte)(_val & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr == _watch.Address)
|
||||
{
|
||||
return (byte)(_val & 0xFF);
|
||||
}
|
||||
|
||||
if (addr == _watch.Address + 1)
|
||||
{
|
||||
return (byte)((_val >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
if (addr == _watch.Address + 2)
|
||||
{
|
||||
return (byte)((_val >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
return (byte)((_val >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
if (addr == _watch.Address + 1)
|
||||
{
|
||||
return (byte)((_val >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
if (addr == _watch.Address + 2)
|
||||
{
|
||||
return (byte)((_val >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
return (byte)(_val & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace BizHawk.Client.DiscoHawk
|
|||
foreach (string str in files)
|
||||
{
|
||||
string ext = Path.GetExtension(str).ToUpper();
|
||||
if(!ext.In(new string[]{".CUE",".ISO",".CCD"}))
|
||||
if(!ext.In(new string[]{".CUE",".ISO",".CCD", ".MDS"}))
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
else
|
||||
{
|
||||
cmdRom = arg;
|
||||
cmdRom = args[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.CoreInfoPanel = new System.Windows.Forms.Panel();
|
||||
//this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.VersionLabel = new System.Windows.Forms.Label();
|
||||
this.btnCopyHash = new System.Windows.Forms.Button();
|
||||
this.linkLabel2 = new System.Windows.Forms.LinkLabel();
|
||||
|
@ -146,7 +145,6 @@
|
|||
//
|
||||
// linkLabel3
|
||||
//
|
||||
this.linkLabel3.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.linkLabel3.AutoSize = true;
|
||||
this.linkLabel3.Location = new System.Drawing.Point(198, 112);
|
||||
this.linkLabel3.Name = "linkLabel3";
|
||||
|
@ -176,7 +174,6 @@
|
|||
this.Controls.Add(this.linkLabel3);
|
||||
this.Controls.Add(this.linkLabel2);
|
||||
this.Controls.Add(this.btnCopyHash);
|
||||
//this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.CoreInfoPanel);
|
||||
this.Controls.Add(this.VersionLabel);
|
||||
this.Controls.Add(this.label4);
|
||||
|
|
|
@ -51,11 +51,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
return new[]
|
||||
{
|
||||
".NES", ".FDS", ".UNF", ".SMS", ".GG", ".SG", ".GB", ".GBC", ".GBA", ".PCE", ".SGX", ".BIN", ".SMD", ".GEN", ".MD", ".SMC", ".SFC", ".A26", ".A78", ".LNX", ".COL", ".ROM", ".M3U", ".CUE", ".CCD", ".SGB", ".Z64", ".V64", ".N64", ".WS", ".WSC", ".XML", ".DSK", ".DO", ".PO", ".PSF", ".MINIPSF", ".NSF",
|
||||
".EXE", ".PRG", ".D64", "*G64", ".CRT", ".TAP", ".32X"
|
||||
".EXE", ".PRG", ".D64", "*G64", ".CRT", ".TAP", ".32X", ".MDS"
|
||||
};
|
||||
}
|
||||
|
||||
return new[] { ".NES", ".FDS", ".UNF", ".SMS", ".GG", ".SG", ".GB", ".GBC", ".GBA", ".PCE", ".SGX", ".BIN", ".SMD", ".GEN", ".MD", ".SMC", ".SFC", ".A26", ".A78", ".LNX", ".COL", ".ROM", ".M3U", ".CUE", ".CCD", ".SGB", ".Z64", ".V64", ".N64", ".WS", ".WSC", ".XML", ".DSK", ".DO", ".PO", ".PSF", ".MINIPSF", ".NSF", ".32X" };
|
||||
return new[] { ".NES", ".FDS", ".UNF", ".SMS", ".GG", ".SG", ".GB", ".GBC", ".GBA", ".PCE", ".SGX", ".BIN", ".SMD", ".GEN", ".MD", ".SMC", ".SFC", ".A26", ".A78", ".LNX", ".COL", ".ROM", ".M3U", ".CUE", ".CCD", ".SGB", ".Z64", ".V64", ".N64", ".WS", ".WSC", ".XML", ".DSK", ".DO", ".PO", ".PSF", ".MINIPSF", ".NSF", ".32X", ".MDS" };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -442,7 +442,12 @@
|
|||
this.ShowMenuContextMenuSeparator = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.ShowMenuContextMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.timerMouseIdle = new System.Windows.Forms.Timer(this.components);
|
||||
this.MainformMenu.SuspendLayout();
|
||||
this.SMSControllerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SMSControllerStandardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SMSControllerPaddleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SMSControllerLightPhaserToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SMSControllerSportsPadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MainformMenu.SuspendLayout();
|
||||
this.MainStatusBar.SuspendLayout();
|
||||
this.MainFormContextMenu.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
|
@ -2475,7 +2480,8 @@
|
|||
this.SMSSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.SMSregionToolStripMenuItem,
|
||||
this.SMSdisplayToolStripMenuItem,
|
||||
this.SMStoolStripMenuItem2,
|
||||
this.SMSControllerToolStripMenuItem,
|
||||
this.SMStoolStripMenuItem2,
|
||||
this.SMSenableBIOSToolStripMenuItem,
|
||||
this.SMSEnableFMChipMenuItem,
|
||||
this.SMSOverclockMenuItem,
|
||||
|
@ -2542,9 +2548,44 @@
|
|||
this.SMSdisplayNtscToolStripMenuItem.Text = "NTSC";
|
||||
this.SMSdisplayNtscToolStripMenuItem.Click += new System.EventHandler(this.SMS_DisplayNTSC_Click);
|
||||
//
|
||||
// SMSdisplayPalToolStripMenuItem
|
||||
// SMSControllerToolStripMenuItem
|
||||
//
|
||||
this.SMSdisplayPalToolStripMenuItem.Name = "SMSdisplayPalToolStripMenuItem";
|
||||
this.SMSControllerToolStripMenuItem.Name = "SMSControllerToolStripMenuItem";
|
||||
this.SMSControllerToolStripMenuItem.Text = "&Controller Type";
|
||||
this.SMSControllerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.SMSControllerStandardToolStripMenuItem,
|
||||
this.SMSControllerPaddleToolStripMenuItem,
|
||||
this.SMSControllerLightPhaserToolStripMenuItem,
|
||||
this.SMSControllerSportsPadToolStripMenuItem});
|
||||
//
|
||||
// SMSControllerStandardToolStripMenuItem
|
||||
//
|
||||
this.SMSControllerStandardToolStripMenuItem.Name = "SMSControllerStandardToolStripMenuItem";
|
||||
this.SMSControllerStandardToolStripMenuItem.Text = "Standard";
|
||||
this.SMSControllerStandardToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerStandardToolStripMenuItem_Click);
|
||||
//
|
||||
// SMSControllerPaddleToolStripMenuItem
|
||||
//
|
||||
this.SMSControllerPaddleToolStripMenuItem.Name = "SMSControllerPaddleToolStripMenuItem";
|
||||
this.SMSControllerPaddleToolStripMenuItem.Text = "Paddle";
|
||||
this.SMSControllerPaddleToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerPaddleToolStripMenuItem_Click);
|
||||
//
|
||||
// SMSControllerLightPhaserToolStripMenuItem
|
||||
//
|
||||
this.SMSControllerLightPhaserToolStripMenuItem.Name = "SMSControllerLightPhaserToolStripMenuItem";
|
||||
this.SMSControllerLightPhaserToolStripMenuItem.Text = "Light Phaser";
|
||||
this.SMSControllerLightPhaserToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerLightPhaserToolStripMenuItem_Click);
|
||||
//
|
||||
// SMSControllerSportsPadToolStripMenuItem
|
||||
//
|
||||
this.SMSControllerSportsPadToolStripMenuItem.Name = "SMSControllerSportsPadToolStripMenuItem";
|
||||
this.SMSControllerSportsPadToolStripMenuItem.Text = "Sports Pad";
|
||||
this.SMSControllerSportsPadToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerSportsPadToolStripMenuItem_Click);
|
||||
|
||||
//
|
||||
// SMSdisplayPalToolStripMenuItem
|
||||
//
|
||||
this.SMSdisplayPalToolStripMenuItem.Name = "SMSdisplayPalToolStripMenuItem";
|
||||
this.SMSdisplayPalToolStripMenuItem.Size = new System.Drawing.Size(104, 22);
|
||||
this.SMSdisplayPalToolStripMenuItem.Text = "PAL";
|
||||
this.SMSdisplayPalToolStripMenuItem.Click += new System.EventHandler(this.SMS_DisplayPAL_Click);
|
||||
|
@ -4368,5 +4409,10 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem SgbSameBoyMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem pCFXToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem preferencesToolStripMenuItem3;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerStandardToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerPaddleToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerLightPhaserToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerSportsPadToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1745,6 +1745,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
SMSdisplayNtscToolStripMenuItem.Checked = ss.DisplayType == "NTSC";
|
||||
SMSdisplayPalToolStripMenuItem.Checked = ss.DisplayType == "PAL";
|
||||
SMSdisplayAutoToolStripMenuItem.Checked = ss.DisplayType == "Auto";
|
||||
SMSControllerStandardToolStripMenuItem.Checked = ss.ControllerType == "Standard";
|
||||
SMSControllerPaddleToolStripMenuItem.Checked = ss.ControllerType == "Paddle";
|
||||
SMSControllerLightPhaserToolStripMenuItem.Checked = ss.ControllerType == "Light Phaser";
|
||||
SMSControllerSportsPadToolStripMenuItem.Checked = ss.ControllerType == "Sports Pad";
|
||||
SMSenableBIOSToolStripMenuItem.Checked = ss.UseBIOS;
|
||||
SMSEnableFMChipMenuItem.Checked = ss.EnableFM;
|
||||
SMSOverclockMenuItem.Checked = ss.AllowOverlock;
|
||||
|
@ -1899,6 +1903,34 @@ namespace BizHawk.Client.EmuHawk
|
|||
GlobalWin.Tools.Load<SmsVDPViewer>();
|
||||
}
|
||||
|
||||
private void SMSControllerStandardToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Standard";
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void SMSControllerPaddleToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Paddle";
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void SMSControllerLightPhaserToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Light Phaser";
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void SMSControllerSportsPadToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Sports Pad";
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region TI83
|
||||
|
|
|
@ -274,7 +274,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (argParse.cmdRom != null)
|
||||
{
|
||||
// Commandline should always override auto-load
|
||||
LoadRom(argParse.cmdRom, new LoadRomArgs { OpenAdvanced = new OpenAdvanced_OpenRom() });
|
||||
var ioa = OpenAdvancedSerializer.ParseWithLegacy(argParse.cmdRom);
|
||||
LoadRom(argParse.cmdRom, new LoadRomArgs { OpenAdvanced = ioa });
|
||||
if (Global.Game == null)
|
||||
{
|
||||
MessageBox.Show("Failed to load " + argParse.cmdRom + " specified on commandline");
|
||||
|
@ -2076,13 +2077,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (VersionInfo.DeveloperBuild)
|
||||
{
|
||||
return FormatFilter(
|
||||
"Rom Files", "*.nes;*.fds;*.unf;*.sms;*.gg;*.sg;*.pce;*.sgx;*.bin;*.smd;*.rom;*.a26;*.a78;*.lnx;*.m3u;*.cue;*.ccd;*.exe;*.gb;*.gbc;*.gba;*.gen;*.md;*.32x;*.col;*.int;*.smc;*.sfc;*.prg;*.d64;*.g64;*.crt;*.tap;*.sgb;*.xml;*.z64;*.v64;*.n64;*.ws;*.wsc;*.dsk;*.do;*.po;*.vb;*.ngp;*.ngc;*.psf;*.minipsf;*.nsf;%ARCH%",
|
||||
"Rom Files", "*.nes;*.fds;*.unf;*.sms;*.gg;*.sg;*.pce;*.sgx;*.bin;*.smd;*.rom;*.a26;*.a78;*.lnx;*.m3u;*.cue;*.ccd;*.mds;*.exe;*.gb;*.gbc;*.gba;*.gen;*.md;*.32x;*.col;*.int;*.smc;*.sfc;*.prg;*.d64;*.g64;*.crt;*.tap;*.sgb;*.xml;*.z64;*.v64;*.n64;*.ws;*.wsc;*.dsk;*.do;*.po;*.vb;*.ngp;*.ngc;*.psf;*.minipsf;*.nsf;%ARCH%",
|
||||
"Music Files", "*.psf;*.minipsf;*.sid;*.nsf",
|
||||
"Disc Images", "*.cue;*.ccd;*.m3u",
|
||||
"Disc Images", "*.cue;*.ccd;*.mds;*.m3u",
|
||||
"NES", "*.nes;*.fds;*.unf;*.nsf;%ARCH%",
|
||||
"Super NES", "*.smc;*.sfc;*.xml;%ARCH%",
|
||||
"Master System", "*.sms;*.gg;*.sg;%ARCH%",
|
||||
"PC Engine", "*.pce;*.sgx;*.cue;*.ccd;%ARCH%",
|
||||
"PC Engine", "*.pce;*.sgx;*.cue;*.ccd;*.mds;%ARCH%",
|
||||
"TI-83", "*.rom;%ARCH%",
|
||||
"Archive Files", "%ARCH%",
|
||||
"Savestate", "*.state",
|
||||
|
@ -2094,7 +2095,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
"Gameboy Advance", "*.gba;%ARCH%",
|
||||
"Colecovision", "*.col;%ARCH%",
|
||||
"Intellivision", "*.int;*.bin;*.rom;%ARCH%",
|
||||
"PlayStation", "*.cue;*.ccd;*.m3u",
|
||||
"PlayStation", "*.cue;*.ccd;*.mds;*.m3u",
|
||||
"PSX Executables (experimental)", "*.exe",
|
||||
"PSF Playstation Sound File", "*.psf;*.minipsf",
|
||||
"Commodore 64", "*.prg; *.d64, *.g64; *.crt; *.tap;%ARCH%",
|
||||
|
@ -2108,17 +2109,17 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
return FormatFilter(
|
||||
"Rom Files", "*.nes;*.fds;*.unf;*.sms;*.gg;*.sg;*.gb;*.gbc;*.gba;*.pce;*.sgx;*.bin;*.smd;*.gen;*.md;*.32x;*.smc;*.sfc;*.a26;*.a78;*.lnx;*.col;*.int;*.rom;*.m3u;*.cue;*.ccd;*.sgb;*.z64;*.v64;*.n64;*.ws;*.wsc;*.xml;*.dsk;*.do;*.po;*.psf;*.ngp;*.ngc;*.prg;*.d64;*.g64;*.minipsf;*.nsf;%ARCH%",
|
||||
"Disc Images", "*.cue;*.ccd;*.m3u",
|
||||
"Rom Files", "*.nes;*.fds;*.unf;*.sms;*.gg;*.sg;*.gb;*.gbc;*.gba;*.pce;*.sgx;*.bin;*.smd;*.gen;*.md;*.32x;*.smc;*.sfc;*.a26;*.a78;*.lnx;*.col;*.int;*.rom;*.m3u;*.cue;*.ccd;*.mds;*.sgb;*.z64;*.v64;*.n64;*.ws;*.wsc;*.xml;*.dsk;*.do;*.po;*.psf;*.ngp;*.ngc;*.prg;*.d64;*.g64;*.minipsf;*.nsf;%ARCH%",
|
||||
"Disc Images", "*.cue;*.ccd;*.mds;*.m3u",
|
||||
"NES", "*.nes;*.fds;*.unf;*.nsf;%ARCH%",
|
||||
"Super NES", "*.smc;*.sfc;*.xml;%ARCH%",
|
||||
"PlayStation", "*.cue;*.ccd;*.m3u",
|
||||
"PlayStation", "*.cue;*.ccd;*.mds;*.m3u",
|
||||
"PSF Playstation Sound File", "*.psf;*.minipsf",
|
||||
"Nintendo 64", "*.z64;*.v64;*.n64",
|
||||
"Gameboy", "*.gb;*.gbc;*.sgb;%ARCH%",
|
||||
"Gameboy Advance", "*.gba;%ARCH%",
|
||||
"Master System", "*.sms;*.gg;*.sg;%ARCH%",
|
||||
"PC Engine", "*.pce;*.sgx;*.cue;*.ccd;%ARCH%",
|
||||
"PC Engine", "*.pce;*.sgx;*.cue;*.ccd;*.mds;%ARCH%",
|
||||
"Atari 2600", "*.a26;%ARCH%",
|
||||
"Atari 7800", "*.a78;%ARCH%",
|
||||
"Atari Lynx", "*.lnx;%ARCH%",
|
||||
|
@ -3582,6 +3583,12 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
if (ioa is OpenAdvanced_OpenRom)
|
||||
{
|
||||
var ioa_openrom = (OpenAdvanced_OpenRom)ioa;
|
||||
path = ioa_openrom.Path;
|
||||
}
|
||||
|
||||
CoreFileProvider.SyncCoreCommInputSignals(nextComm);
|
||||
var result = loader.LoadRom(path, nextComm);
|
||||
|
||||
|
|
|
@ -28,220 +28,87 @@
|
|||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.OK = new System.Windows.Forms.Button();
|
||||
this.Cancel = new System.Windows.Forms.Button();
|
||||
this.trackBar1 = new System.Windows.Forms.TrackBar();
|
||||
this.trackBar2 = new System.Windows.Forms.TrackBar();
|
||||
this.trackBar3 = new System.Windows.Forms.TrackBar();
|
||||
this.trackBar4 = new System.Windows.Forms.TrackBar();
|
||||
this.trackBar5 = new System.Windows.Forms.TrackBar();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar2)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar3)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar4)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar5)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// OK
|
||||
//
|
||||
this.OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OK.Location = new System.Drawing.Point(41, 262);
|
||||
this.OK.Name = "OK";
|
||||
this.OK.Size = new System.Drawing.Size(75, 23);
|
||||
this.OK.TabIndex = 0;
|
||||
this.OK.Text = "&OK";
|
||||
this.OK.UseVisualStyleBackColor = true;
|
||||
this.OK.Click += new System.EventHandler(this.Ok_Click);
|
||||
//
|
||||
// Cancel
|
||||
//
|
||||
this.Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.Cancel.Location = new System.Drawing.Point(122, 262);
|
||||
this.Cancel.Name = "Cancel";
|
||||
this.Cancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.Cancel.TabIndex = 1;
|
||||
this.Cancel.Text = "&Cancel";
|
||||
this.Cancel.UseVisualStyleBackColor = true;
|
||||
this.Cancel.Click += new System.EventHandler(this.Cancel_Click);
|
||||
//
|
||||
// trackBar1
|
||||
//
|
||||
this.trackBar1.Location = new System.Drawing.Point(12, 12);
|
||||
this.trackBar1.Name = "trackBar1";
|
||||
this.trackBar1.Size = new System.Drawing.Size(104, 45);
|
||||
this.trackBar1.TabIndex = 2;
|
||||
this.trackBar1.ValueChanged += new System.EventHandler(this.TrackBar1_ValueChanged);
|
||||
//
|
||||
// trackBar2
|
||||
//
|
||||
this.trackBar2.Location = new System.Drawing.Point(12, 60);
|
||||
this.trackBar2.Name = "trackBar2";
|
||||
this.trackBar2.Size = new System.Drawing.Size(104, 45);
|
||||
this.trackBar2.TabIndex = 3;
|
||||
this.trackBar2.ValueChanged += new System.EventHandler(this.TrackBar2_ValueChanged);
|
||||
//
|
||||
// trackBar3
|
||||
//
|
||||
this.trackBar3.Location = new System.Drawing.Point(12, 108);
|
||||
this.trackBar3.Name = "trackBar3";
|
||||
this.trackBar3.Size = new System.Drawing.Size(104, 45);
|
||||
this.trackBar3.TabIndex = 4;
|
||||
this.trackBar3.ValueChanged += new System.EventHandler(this.TrackBar3_ValueChanged);
|
||||
//
|
||||
// trackBar4
|
||||
//
|
||||
this.trackBar4.Location = new System.Drawing.Point(12, 156);
|
||||
this.trackBar4.Name = "trackBar4";
|
||||
this.trackBar4.Size = new System.Drawing.Size(104, 45);
|
||||
this.trackBar4.TabIndex = 5;
|
||||
this.trackBar4.ValueChanged += new System.EventHandler(this.TrackBar4_ValueChanged);
|
||||
//
|
||||
// trackBar5
|
||||
//
|
||||
this.trackBar5.Location = new System.Drawing.Point(12, 204);
|
||||
this.trackBar5.Name = "trackBar5";
|
||||
this.trackBar5.Size = new System.Drawing.Size(104, 45);
|
||||
this.trackBar5.TabIndex = 6;
|
||||
this.trackBar5.ValueChanged += new System.EventHandler(this.TrackBar5_ValueChanged);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(122, 12);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(50, 13);
|
||||
this.label1.TabIndex = 7;
|
||||
this.label1.Text = "Square 1";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(122, 60);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(50, 13);
|
||||
this.label2.TabIndex = 8;
|
||||
this.label2.Text = "Square 2";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(122, 108);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(45, 13);
|
||||
this.label3.TabIndex = 9;
|
||||
this.label3.Text = "Triangle";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(122, 156);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(34, 13);
|
||||
this.label4.TabIndex = 10;
|
||||
this.label4.Text = "Noise";
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(122, 204);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(31, 13);
|
||||
this.label5.TabIndex = 11;
|
||||
this.label5.Text = "DMC";
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(122, 25);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(13, 13);
|
||||
this.label6.TabIndex = 12;
|
||||
this.label6.Text = "0";
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(122, 73);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(13, 13);
|
||||
this.label7.TabIndex = 13;
|
||||
this.label7.Text = "0";
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(122, 121);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(13, 13);
|
||||
this.label8.TabIndex = 14;
|
||||
this.label8.Text = "0";
|
||||
//
|
||||
// label9
|
||||
//
|
||||
this.label9.AutoSize = true;
|
||||
this.label9.Location = new System.Drawing.Point(122, 169);
|
||||
this.label9.Name = "label9";
|
||||
this.label9.Size = new System.Drawing.Size(13, 13);
|
||||
this.label9.TabIndex = 15;
|
||||
this.label9.Text = "0";
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(122, 217);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(13, 13);
|
||||
this.label10.TabIndex = 16;
|
||||
this.label10.Text = "0";
|
||||
//
|
||||
// NESSoundConfig
|
||||
//
|
||||
this.AcceptButton = this.OK;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.Cancel;
|
||||
this.ClientSize = new System.Drawing.Size(209, 297);
|
||||
this.Controls.Add(this.label10);
|
||||
this.Controls.Add(this.label9);
|
||||
this.Controls.Add(this.label8);
|
||||
this.Controls.Add(this.label7);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.trackBar5);
|
||||
this.Controls.Add(this.trackBar4);
|
||||
this.Controls.Add(this.trackBar3);
|
||||
this.Controls.Add(this.trackBar2);
|
||||
this.Controls.Add(this.trackBar1);
|
||||
this.Controls.Add(this.Cancel);
|
||||
this.Controls.Add(this.OK);
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "NESSoundConfig";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "NES Sound Channels";
|
||||
this.Load += new System.EventHandler(this.NESSoundConfig_Load);
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar2)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar3)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar4)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar5)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
this.OK = new System.Windows.Forms.Button();
|
||||
this.Cancel = new System.Windows.Forms.Button();
|
||||
this.trackBar1 = new System.Windows.Forms.TrackBar();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// OK
|
||||
//
|
||||
this.OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OK.Location = new System.Drawing.Point(41, 117);
|
||||
this.OK.Name = "OK";
|
||||
this.OK.Size = new System.Drawing.Size(75, 23);
|
||||
this.OK.TabIndex = 0;
|
||||
this.OK.Text = "&OK";
|
||||
this.OK.UseVisualStyleBackColor = true;
|
||||
this.OK.Click += new System.EventHandler(this.Ok_Click);
|
||||
//
|
||||
// Cancel
|
||||
//
|
||||
this.Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.Cancel.Location = new System.Drawing.Point(122, 117);
|
||||
this.Cancel.Name = "Cancel";
|
||||
this.Cancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.Cancel.TabIndex = 1;
|
||||
this.Cancel.Text = "&Cancel";
|
||||
this.Cancel.UseVisualStyleBackColor = true;
|
||||
this.Cancel.Click += new System.EventHandler(this.Cancel_Click);
|
||||
//
|
||||
// trackBar1
|
||||
//
|
||||
this.trackBar1.LargeChange = 1;
|
||||
this.trackBar1.Location = new System.Drawing.Point(12, 12);
|
||||
this.trackBar1.Minimum = 1;
|
||||
this.trackBar1.Name = "trackBar1";
|
||||
this.trackBar1.Size = new System.Drawing.Size(104, 45);
|
||||
this.trackBar1.TabIndex = 2;
|
||||
this.trackBar1.Value = 1;
|
||||
this.trackBar1.ValueChanged += new System.EventHandler(this.TrackBar1_ValueChanged);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(122, 12);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(67, 13);
|
||||
this.label1.TabIndex = 7;
|
||||
this.label1.Text = "APU Volume";
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(122, 25);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(13, 13);
|
||||
this.label6.TabIndex = 12;
|
||||
this.label6.Text = "0";
|
||||
//
|
||||
// NESSoundConfig
|
||||
//
|
||||
this.AcceptButton = this.OK;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.Cancel;
|
||||
this.ClientSize = new System.Drawing.Size(209, 152);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.trackBar1);
|
||||
this.Controls.Add(this.Cancel);
|
||||
this.Controls.Add(this.OK);
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "NESSoundConfig";
|
||||
this.ShowIcon = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "NES Sound Channels";
|
||||
this.Load += new System.EventHandler(this.NESSoundConfig_Load);
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
|
@ -250,19 +117,7 @@
|
|||
private System.Windows.Forms.Button OK;
|
||||
private System.Windows.Forms.Button Cancel;
|
||||
private System.Windows.Forms.TrackBar trackBar1;
|
||||
private System.Windows.Forms.TrackBar trackBar2;
|
||||
private System.Windows.Forms.TrackBar trackBar3;
|
||||
private System.Windows.Forms.TrackBar trackBar4;
|
||||
private System.Windows.Forms.TrackBar trackBar5;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.Label label9;
|
||||
private System.Windows.Forms.Label label10;
|
||||
}
|
||||
}
|
|
@ -38,11 +38,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
// get baseline maxes from a default config object
|
||||
var d = new NES.NESSettings();
|
||||
trackBar1.Maximum = d.Square1;
|
||||
trackBar2.Maximum = d.Square2;
|
||||
trackBar3.Maximum = d.Triangle;
|
||||
trackBar4.Maximum = d.Noise;
|
||||
trackBar5.Maximum = d.DMC;
|
||||
trackBar1.Minimum = d.APU_vol;
|
||||
}
|
||||
|
||||
private void NESSoundConfig_Load(object sender, EventArgs e)
|
||||
|
@ -50,11 +46,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
_oldSettings = NES.GetSettings();
|
||||
_settings = _oldSettings.Clone();
|
||||
|
||||
trackBar1.Value = _settings.Square1;
|
||||
trackBar2.Value = _settings.Square2;
|
||||
trackBar3.Value = _settings.Triangle;
|
||||
trackBar4.Value = _settings.Noise;
|
||||
trackBar5.Value = _settings.DMC;
|
||||
trackBar1.Value = _settings.APU_vol;
|
||||
}
|
||||
|
||||
private void Ok_Click(object sender, EventArgs e)
|
||||
|
@ -72,35 +64,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void TrackBar1_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
label6.Text = trackBar1.Value.ToString();
|
||||
_settings.Square1 = trackBar1.Value;
|
||||
NES.PutSettings(_settings);
|
||||
}
|
||||
|
||||
private void TrackBar2_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
label7.Text = trackBar2.Value.ToString();
|
||||
_settings.Square2 = trackBar2.Value;
|
||||
NES.PutSettings(_settings);
|
||||
}
|
||||
|
||||
private void TrackBar3_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
label8.Text = trackBar3.Value.ToString();
|
||||
_settings.Triangle = trackBar3.Value;
|
||||
NES.PutSettings(_settings);
|
||||
}
|
||||
|
||||
private void TrackBar4_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
label9.Text = trackBar4.Value.ToString();
|
||||
_settings.Noise = trackBar4.Value;
|
||||
NES.PutSettings(_settings);
|
||||
}
|
||||
|
||||
private void TrackBar5_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
label10.Text = trackBar5.Value.ToString();
|
||||
_settings.DMC = trackBar5.Value;
|
||||
_settings.APU_vol = trackBar1.Value;
|
||||
NES.PutSettings(_settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
public Action Callback { get; set; }
|
||||
|
||||
public void Add(IDebuggable core, uint address, uint mask, MemoryCallbackType type)
|
||||
public void Add(IDebuggable core, string scope, uint address, uint mask, MemoryCallbackType type)
|
||||
{
|
||||
Add(new Breakpoint(core, Callback, address, mask, type));
|
||||
Add(new Breakpoint(core, scope, Callback, address, mask, type));
|
||||
}
|
||||
|
||||
public new void Clear()
|
||||
|
@ -69,8 +69,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
private bool _active;
|
||||
private readonly IDebuggable _core;
|
||||
|
||||
public Breakpoint(bool readOnly, IDebuggable core, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
|
||||
public Breakpoint(bool readOnly, IDebuggable core, string scope, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
|
||||
{
|
||||
Scope = scope;
|
||||
_core = core;
|
||||
Type = type;
|
||||
Callback = callBack;
|
||||
|
@ -82,8 +83,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
ReadOnly = readOnly;
|
||||
}
|
||||
|
||||
public Breakpoint(IDebuggable core, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
|
||||
public Breakpoint(IDebuggable core, string scope, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
|
||||
{
|
||||
Scope = scope;
|
||||
_core = core;
|
||||
Type = type;
|
||||
Callback = callBack;
|
||||
|
@ -94,8 +96,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
Active = enabled;
|
||||
}
|
||||
|
||||
public Breakpoint(string name, bool readOnly, IDebuggable core, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
|
||||
public Breakpoint(string name, bool readOnly, IDebuggable core, string scope, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
|
||||
{
|
||||
Scope = scope;
|
||||
_core = core;
|
||||
Type = type;
|
||||
Callback = callBack;
|
||||
|
@ -107,6 +110,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
ReadOnly = readOnly;
|
||||
}
|
||||
|
||||
public string Scope { get; }
|
||||
public Action Callback { get; }
|
||||
public uint? Address { get; set; }
|
||||
public uint? AddressMask { get; set; }
|
||||
|
@ -159,7 +163,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void AddCallback()
|
||||
{
|
||||
_core.MemoryCallbacks.Add(new MemoryCallback(Type, Name, Callback, Address, AddressMask));
|
||||
_core.MemoryCallbacks.Add(new MemoryCallback(Scope, Type, Name, Callback, Address, AddressMask));
|
||||
}
|
||||
|
||||
private void RemoveCallback()
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public void AddBreakpoint(uint address, uint mask, MemoryCallbackType type)
|
||||
{
|
||||
_breakpoints.Add(Core, address, mask, type);
|
||||
_breakpoints.Add(Core, MemoryDomains.SystemBus.Name, address, mask, type);
|
||||
|
||||
BreakpointView.ItemCount = _breakpoints.Count;
|
||||
UpdateBreakpointRemoveButton();
|
||||
|
@ -157,7 +157,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (b.ShowHawkDialog() == DialogResult.OK)
|
||||
{
|
||||
_breakpoints.Add(Core, b.Address, b.AddressMask, b.BreakType);
|
||||
_breakpoints.Add(Core, MemoryDomains.SystemBus.Name, b.Address, b.AddressMask, b.BreakType);
|
||||
}
|
||||
|
||||
BreakpointView.ItemCount = _breakpoints.Count;
|
||||
|
@ -170,7 +170,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
public void AddSeekBreakpoint(uint pcVal, int pcBitSize)
|
||||
{
|
||||
var name = SeekName + pcVal.ToHexString(pcBitSize / 4);
|
||||
_breakpoints.Add(new Breakpoint(name, true, Core, SeekCallback, pcVal, 0xFFFFFFFF, MemoryCallbackType.Execute));
|
||||
_breakpoints.Add(new Breakpoint(name, true, Core, MemoryDomains.SystemBus.Name, SeekCallback, pcVal, 0xFFFFFFFF, MemoryCallbackType.Execute));
|
||||
}
|
||||
|
||||
public void RemoveCurrentSeek()
|
||||
|
@ -284,7 +284,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (b.ShowHawkDialog() == DialogResult.OK)
|
||||
{
|
||||
_breakpoints.Add(new Breakpoint(Core, breakpoint.Callback, b.Address, b.AddressMask, b.BreakType, breakpoint.Active));
|
||||
_breakpoints.Add(new Breakpoint(Core, MemoryDomains.SystemBus.Name, breakpoint.Callback, b.Address, b.AddressMask, b.BreakType, breakpoint.Active));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
[OptionalService]
|
||||
private IDisassemblable Disassembler { get; set; }
|
||||
|
||||
[OptionalService]
|
||||
[RequiredService]
|
||||
private IMemoryDomains MemoryDomains { get; set; }
|
||||
|
||||
private IMemoryCallbackSystem MemoryCallbacks { get { return Debuggable.MemoryCallbacks; } }
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
this.AddressLabel = new System.Windows.Forms.Label();
|
||||
this.AddressesLabel = new System.Windows.Forms.Label();
|
||||
this.Header = new System.Windows.Forms.Label();
|
||||
this.swapBytesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.HexMenuStrip.SuspendLayout();
|
||||
this.ViewerContextMenuStrip.SuspendLayout();
|
||||
this.MemoryViewerBox.SuspendLayout();
|
||||
|
@ -126,7 +127,7 @@
|
|||
this.toolStripSeparator1,
|
||||
this.ExitMenuItem});
|
||||
this.FileSubMenu.Name = "FileSubMenu";
|
||||
this.FileSubMenu.Size = new System.Drawing.Size(35, 20);
|
||||
this.FileSubMenu.Size = new System.Drawing.Size(37, 20);
|
||||
this.FileSubMenu.Text = "&File";
|
||||
this.FileSubMenu.DropDownOpened += new System.EventHandler(this.FileSubMenu_DropDownOpened);
|
||||
//
|
||||
|
@ -135,7 +136,7 @@
|
|||
this.SaveMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.SaveAs;
|
||||
this.SaveMenuItem.Name = "SaveMenuItem";
|
||||
this.SaveMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
|
||||
this.SaveMenuItem.Size = new System.Drawing.Size(225, 22);
|
||||
this.SaveMenuItem.Size = new System.Drawing.Size(229, 22);
|
||||
this.SaveMenuItem.Text = "Save";
|
||||
this.SaveMenuItem.Click += new System.EventHandler(this.SaveMenuItem_Click);
|
||||
//
|
||||
|
@ -144,14 +145,14 @@
|
|||
this.SaveAsBinaryMenuItem.Name = "SaveAsBinaryMenuItem";
|
||||
this.SaveAsBinaryMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
|
||||
| System.Windows.Forms.Keys.S)));
|
||||
this.SaveAsBinaryMenuItem.Size = new System.Drawing.Size(225, 22);
|
||||
this.SaveAsBinaryMenuItem.Size = new System.Drawing.Size(229, 22);
|
||||
this.SaveAsBinaryMenuItem.Text = "Save as binary...";
|
||||
this.SaveAsBinaryMenuItem.Click += new System.EventHandler(this.SaveAsBinaryMenuItem_Click);
|
||||
//
|
||||
// SaveAsTextMenuItem
|
||||
//
|
||||
this.SaveAsTextMenuItem.Name = "SaveAsTextMenuItem";
|
||||
this.SaveAsTextMenuItem.Size = new System.Drawing.Size(225, 22);
|
||||
this.SaveAsTextMenuItem.Size = new System.Drawing.Size(229, 22);
|
||||
this.SaveAsTextMenuItem.Text = "Save as text...";
|
||||
this.SaveAsTextMenuItem.Click += new System.EventHandler(this.SaveAsTextMenuItem_Click);
|
||||
//
|
||||
|
@ -159,26 +160,26 @@
|
|||
//
|
||||
this.importAsBinaryToolStripMenuItem.Name = "importAsBinaryToolStripMenuItem";
|
||||
this.importAsBinaryToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.I)));
|
||||
this.importAsBinaryToolStripMenuItem.Size = new System.Drawing.Size(225, 22);
|
||||
this.importAsBinaryToolStripMenuItem.Size = new System.Drawing.Size(229, 22);
|
||||
this.importAsBinaryToolStripMenuItem.Text = "Import as binary...";
|
||||
this.importAsBinaryToolStripMenuItem.Click += new System.EventHandler(this.importAsBinaryToolStripMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator4
|
||||
//
|
||||
this.toolStripSeparator4.Name = "toolStripSeparator4";
|
||||
this.toolStripSeparator4.Size = new System.Drawing.Size(222, 6);
|
||||
this.toolStripSeparator4.Size = new System.Drawing.Size(226, 6);
|
||||
//
|
||||
// LoadTableFileMenuItem
|
||||
//
|
||||
this.LoadTableFileMenuItem.Name = "LoadTableFileMenuItem";
|
||||
this.LoadTableFileMenuItem.Size = new System.Drawing.Size(225, 22);
|
||||
this.LoadTableFileMenuItem.Size = new System.Drawing.Size(229, 22);
|
||||
this.LoadTableFileMenuItem.Text = "&Load .tbl file";
|
||||
this.LoadTableFileMenuItem.Click += new System.EventHandler(this.LoadTableFileMenuItem_Click);
|
||||
//
|
||||
// CloseTableFileMenuItem
|
||||
//
|
||||
this.CloseTableFileMenuItem.Name = "CloseTableFileMenuItem";
|
||||
this.CloseTableFileMenuItem.Size = new System.Drawing.Size(225, 22);
|
||||
this.CloseTableFileMenuItem.Size = new System.Drawing.Size(229, 22);
|
||||
this.CloseTableFileMenuItem.Text = "Close .tbl file";
|
||||
this.CloseTableFileMenuItem.Click += new System.EventHandler(this.CloseTableFileMenuItem_Click);
|
||||
//
|
||||
|
@ -187,26 +188,26 @@
|
|||
this.RecentTablesSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.noneToolStripMenuItem});
|
||||
this.RecentTablesSubMenu.Name = "RecentTablesSubMenu";
|
||||
this.RecentTablesSubMenu.Size = new System.Drawing.Size(225, 22);
|
||||
this.RecentTablesSubMenu.Size = new System.Drawing.Size(229, 22);
|
||||
this.RecentTablesSubMenu.Text = "Recent";
|
||||
this.RecentTablesSubMenu.DropDownOpened += new System.EventHandler(this.RecentTablesSubMenu_DropDownOpened);
|
||||
//
|
||||
// noneToolStripMenuItem
|
||||
//
|
||||
this.noneToolStripMenuItem.Name = "noneToolStripMenuItem";
|
||||
this.noneToolStripMenuItem.Size = new System.Drawing.Size(99, 22);
|
||||
this.noneToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
|
||||
this.noneToolStripMenuItem.Text = "None";
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
this.toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
this.toolStripSeparator1.Size = new System.Drawing.Size(222, 6);
|
||||
this.toolStripSeparator1.Size = new System.Drawing.Size(226, 6);
|
||||
//
|
||||
// ExitMenuItem
|
||||
//
|
||||
this.ExitMenuItem.Name = "ExitMenuItem";
|
||||
this.ExitMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4)));
|
||||
this.ExitMenuItem.Size = new System.Drawing.Size(225, 22);
|
||||
this.ExitMenuItem.Size = new System.Drawing.Size(229, 22);
|
||||
this.ExitMenuItem.Text = "E&xit";
|
||||
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
|
||||
//
|
||||
|
@ -221,7 +222,7 @@
|
|||
this.FindNextMenuItem,
|
||||
this.FindPrevMenuItem});
|
||||
this.EditMenuItem.Name = "EditMenuItem";
|
||||
this.EditMenuItem.Size = new System.Drawing.Size(37, 20);
|
||||
this.EditMenuItem.Size = new System.Drawing.Size(39, 20);
|
||||
this.EditMenuItem.Text = "&Edit";
|
||||
this.EditMenuItem.DropDownOpened += new System.EventHandler(this.EditMenuItem_DropDownOpened);
|
||||
//
|
||||
|
@ -230,7 +231,7 @@
|
|||
this.CopyMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Duplicate;
|
||||
this.CopyMenuItem.Name = "CopyMenuItem";
|
||||
this.CopyMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
|
||||
this.CopyMenuItem.Size = new System.Drawing.Size(144, 22);
|
||||
this.CopyMenuItem.Size = new System.Drawing.Size(147, 22);
|
||||
this.CopyMenuItem.Text = "&Copy";
|
||||
this.CopyMenuItem.Click += new System.EventHandler(this.CopyMenuItem_Click);
|
||||
//
|
||||
|
@ -238,7 +239,7 @@
|
|||
//
|
||||
this.ExportMenuItem.Name = "ExportMenuItem";
|
||||
this.ExportMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E)));
|
||||
this.ExportMenuItem.Size = new System.Drawing.Size(144, 22);
|
||||
this.ExportMenuItem.Size = new System.Drawing.Size(147, 22);
|
||||
this.ExportMenuItem.Text = "&Export";
|
||||
this.ExportMenuItem.Click += new System.EventHandler(this.ExportMenuItem_Click);
|
||||
//
|
||||
|
@ -247,20 +248,20 @@
|
|||
this.PasteMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Paste;
|
||||
this.PasteMenuItem.Name = "PasteMenuItem";
|
||||
this.PasteMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
|
||||
this.PasteMenuItem.Size = new System.Drawing.Size(144, 22);
|
||||
this.PasteMenuItem.Size = new System.Drawing.Size(147, 22);
|
||||
this.PasteMenuItem.Text = "&Paste";
|
||||
this.PasteMenuItem.Click += new System.EventHandler(this.PasteMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator6
|
||||
//
|
||||
this.toolStripSeparator6.Name = "toolStripSeparator6";
|
||||
this.toolStripSeparator6.Size = new System.Drawing.Size(141, 6);
|
||||
this.toolStripSeparator6.Size = new System.Drawing.Size(144, 6);
|
||||
//
|
||||
// FindMenuItem
|
||||
//
|
||||
this.FindMenuItem.Name = "FindMenuItem";
|
||||
this.FindMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
|
||||
this.FindMenuItem.Size = new System.Drawing.Size(144, 22);
|
||||
this.FindMenuItem.Size = new System.Drawing.Size(147, 22);
|
||||
this.FindMenuItem.Text = "&Find...";
|
||||
this.FindMenuItem.Click += new System.EventHandler(this.FindMenuItem_Click);
|
||||
//
|
||||
|
@ -268,7 +269,7 @@
|
|||
//
|
||||
this.FindNextMenuItem.Name = "FindNextMenuItem";
|
||||
this.FindNextMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F3;
|
||||
this.FindNextMenuItem.Size = new System.Drawing.Size(144, 22);
|
||||
this.FindNextMenuItem.Size = new System.Drawing.Size(147, 22);
|
||||
this.FindNextMenuItem.Text = "Find Next";
|
||||
this.FindNextMenuItem.Click += new System.EventHandler(this.FindNextMenuItem_Click);
|
||||
//
|
||||
|
@ -276,7 +277,7 @@
|
|||
//
|
||||
this.FindPrevMenuItem.Name = "FindPrevMenuItem";
|
||||
this.FindPrevMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F2;
|
||||
this.FindPrevMenuItem.Size = new System.Drawing.Size(144, 22);
|
||||
this.FindPrevMenuItem.Size = new System.Drawing.Size(147, 22);
|
||||
this.FindPrevMenuItem.Text = "Find Prev";
|
||||
this.FindPrevMenuItem.Click += new System.EventHandler(this.FindPrevMenuItem_Click);
|
||||
//
|
||||
|
@ -285,6 +286,7 @@
|
|||
this.OptionsSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.MemoryDomainsMenuItem,
|
||||
this.DataSizeSubMenu,
|
||||
this.swapBytesToolStripMenuItem,
|
||||
this.BigEndianMenuItem,
|
||||
this.toolStripSeparator2,
|
||||
this.GoToAddressMenuItem,
|
||||
|
@ -293,7 +295,7 @@
|
|||
this.UnfreezeAllMenuItem,
|
||||
this.PokeAddressMenuItem});
|
||||
this.OptionsSubMenu.Name = "OptionsSubMenu";
|
||||
this.OptionsSubMenu.Size = new System.Drawing.Size(56, 20);
|
||||
this.OptionsSubMenu.Size = new System.Drawing.Size(61, 20);
|
||||
this.OptionsSubMenu.Text = "&Options";
|
||||
this.OptionsSubMenu.DropDownOpened += new System.EventHandler(this.OptionsSubMenu_DropDownOpened);
|
||||
//
|
||||
|
@ -302,7 +304,7 @@
|
|||
this.MemoryDomainsMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.toolStripSeparator3});
|
||||
this.MemoryDomainsMenuItem.Name = "MemoryDomainsMenuItem";
|
||||
this.MemoryDomainsMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.MemoryDomainsMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.MemoryDomainsMenuItem.Text = "&Memory Domains";
|
||||
this.MemoryDomainsMenuItem.DropDownOpened += new System.EventHandler(this.MemoryDomainsMenuItem_DropDownOpened);
|
||||
//
|
||||
|
@ -318,47 +320,47 @@
|
|||
this.DataSizeWordMenuItem,
|
||||
this.DataSizeDWordMenuItem});
|
||||
this.DataSizeSubMenu.Name = "DataSizeSubMenu";
|
||||
this.DataSizeSubMenu.Size = new System.Drawing.Size(207, 22);
|
||||
this.DataSizeSubMenu.Size = new System.Drawing.Size(221, 22);
|
||||
this.DataSizeSubMenu.Text = "Data Size";
|
||||
//
|
||||
// DataSizeByteMenuItem
|
||||
//
|
||||
this.DataSizeByteMenuItem.Name = "DataSizeByteMenuItem";
|
||||
this.DataSizeByteMenuItem.Size = new System.Drawing.Size(105, 22);
|
||||
this.DataSizeByteMenuItem.Size = new System.Drawing.Size(106, 22);
|
||||
this.DataSizeByteMenuItem.Text = "1 Byte";
|
||||
this.DataSizeByteMenuItem.Click += new System.EventHandler(this.DataSizeByteMenuItem_Click);
|
||||
//
|
||||
// DataSizeWordMenuItem
|
||||
//
|
||||
this.DataSizeWordMenuItem.Name = "DataSizeWordMenuItem";
|
||||
this.DataSizeWordMenuItem.Size = new System.Drawing.Size(105, 22);
|
||||
this.DataSizeWordMenuItem.Size = new System.Drawing.Size(106, 22);
|
||||
this.DataSizeWordMenuItem.Text = "2 Byte";
|
||||
this.DataSizeWordMenuItem.Click += new System.EventHandler(this.DataSizeWordMenuItem_Click);
|
||||
//
|
||||
// DataSizeDWordMenuItem
|
||||
//
|
||||
this.DataSizeDWordMenuItem.Name = "DataSizeDWordMenuItem";
|
||||
this.DataSizeDWordMenuItem.Size = new System.Drawing.Size(105, 22);
|
||||
this.DataSizeDWordMenuItem.Size = new System.Drawing.Size(106, 22);
|
||||
this.DataSizeDWordMenuItem.Text = "4 Byte";
|
||||
this.DataSizeDWordMenuItem.Click += new System.EventHandler(this.DataSizeDWordMenuItem_Click);
|
||||
//
|
||||
// BigEndianMenuItem
|
||||
//
|
||||
this.BigEndianMenuItem.Name = "BigEndianMenuItem";
|
||||
this.BigEndianMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.BigEndianMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.BigEndianMenuItem.Text = "Big Endian";
|
||||
this.BigEndianMenuItem.Click += new System.EventHandler(this.BigEndianMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator2
|
||||
//
|
||||
this.toolStripSeparator2.Name = "toolStripSeparator2";
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(204, 6);
|
||||
this.toolStripSeparator2.Size = new System.Drawing.Size(218, 6);
|
||||
//
|
||||
// GoToAddressMenuItem
|
||||
//
|
||||
this.GoToAddressMenuItem.Name = "GoToAddressMenuItem";
|
||||
this.GoToAddressMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G)));
|
||||
this.GoToAddressMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.GoToAddressMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.GoToAddressMenuItem.Text = "&Go to Address...";
|
||||
this.GoToAddressMenuItem.Click += new System.EventHandler(this.GoToAddressMenuItem_Click);
|
||||
//
|
||||
|
@ -367,7 +369,7 @@
|
|||
this.AddToRamWatchMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.FindHS;
|
||||
this.AddToRamWatchMenuItem.Name = "AddToRamWatchMenuItem";
|
||||
this.AddToRamWatchMenuItem.ShortcutKeyDisplayString = "Ctrl+W";
|
||||
this.AddToRamWatchMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.AddToRamWatchMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.AddToRamWatchMenuItem.Text = "Add to RAM Watch";
|
||||
this.AddToRamWatchMenuItem.Click += new System.EventHandler(this.AddToRamWatchMenuItem_Click);
|
||||
//
|
||||
|
@ -376,7 +378,7 @@
|
|||
this.FreezeAddressMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Freeze;
|
||||
this.FreezeAddressMenuItem.Name = "FreezeAddressMenuItem";
|
||||
this.FreezeAddressMenuItem.ShortcutKeyDisplayString = "Space";
|
||||
this.FreezeAddressMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.FreezeAddressMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.FreezeAddressMenuItem.Text = "&Freeze Address";
|
||||
this.FreezeAddressMenuItem.Click += new System.EventHandler(this.FreezeAddressMenuItem_Click);
|
||||
//
|
||||
|
@ -385,7 +387,7 @@
|
|||
this.UnfreezeAllMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Unfreeze;
|
||||
this.UnfreezeAllMenuItem.Name = "UnfreezeAllMenuItem";
|
||||
this.UnfreezeAllMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.Delete)));
|
||||
this.UnfreezeAllMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.UnfreezeAllMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.UnfreezeAllMenuItem.Text = "Unfreeze All";
|
||||
this.UnfreezeAllMenuItem.Click += new System.EventHandler(this.UnfreezeAllMenuItem_Click);
|
||||
//
|
||||
|
@ -394,7 +396,7 @@
|
|||
this.PokeAddressMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.poke;
|
||||
this.PokeAddressMenuItem.Name = "PokeAddressMenuItem";
|
||||
this.PokeAddressMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P)));
|
||||
this.PokeAddressMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.PokeAddressMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.PokeAddressMenuItem.Text = "&Poke Address";
|
||||
this.PokeAddressMenuItem.Click += new System.EventHandler(this.PokeAddressMenuItem_Click);
|
||||
//
|
||||
|
@ -403,7 +405,7 @@
|
|||
this.SettingsSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.CustomColorsSubMenu});
|
||||
this.SettingsSubMenu.Name = "SettingsSubMenu";
|
||||
this.SettingsSubMenu.Size = new System.Drawing.Size(58, 20);
|
||||
this.SettingsSubMenu.Size = new System.Drawing.Size(61, 20);
|
||||
this.SettingsSubMenu.Text = "&Settings";
|
||||
//
|
||||
// CustomColorsSubMenu
|
||||
|
@ -413,25 +415,25 @@
|
|||
this.toolStripSeparator8,
|
||||
this.ResetColorsToDefaultMenuItem});
|
||||
this.CustomColorsSubMenu.Name = "CustomColorsSubMenu";
|
||||
this.CustomColorsSubMenu.Size = new System.Drawing.Size(143, 22);
|
||||
this.CustomColorsSubMenu.Size = new System.Drawing.Size(153, 22);
|
||||
this.CustomColorsSubMenu.Text = "Custom Colors";
|
||||
//
|
||||
// SetColorsMenuItem
|
||||
//
|
||||
this.SetColorsMenuItem.Name = "SetColorsMenuItem";
|
||||
this.SetColorsMenuItem.Size = new System.Drawing.Size(153, 22);
|
||||
this.SetColorsMenuItem.Size = new System.Drawing.Size(157, 22);
|
||||
this.SetColorsMenuItem.Text = "Set Colors";
|
||||
this.SetColorsMenuItem.Click += new System.EventHandler(this.SetColorsMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator8
|
||||
//
|
||||
this.toolStripSeparator8.Name = "toolStripSeparator8";
|
||||
this.toolStripSeparator8.Size = new System.Drawing.Size(150, 6);
|
||||
this.toolStripSeparator8.Size = new System.Drawing.Size(154, 6);
|
||||
//
|
||||
// ResetColorsToDefaultMenuItem
|
||||
//
|
||||
this.ResetColorsToDefaultMenuItem.Name = "ResetColorsToDefaultMenuItem";
|
||||
this.ResetColorsToDefaultMenuItem.Size = new System.Drawing.Size(153, 22);
|
||||
this.ResetColorsToDefaultMenuItem.Size = new System.Drawing.Size(157, 22);
|
||||
this.ResetColorsToDefaultMenuItem.Text = "Reset to Default";
|
||||
this.ResetColorsToDefaultMenuItem.Click += new System.EventHandler(this.ResetColorsToDefaultMenuItem_Click);
|
||||
//
|
||||
|
@ -464,7 +466,7 @@
|
|||
this.toolStripMenuItem1,
|
||||
this.viewN64MatrixToolStripMenuItem});
|
||||
this.ViewerContextMenuStrip.Name = "ViewerContextMenuStrip";
|
||||
this.ViewerContextMenuStrip.Size = new System.Drawing.Size(208, 264);
|
||||
this.ViewerContextMenuStrip.Size = new System.Drawing.Size(222, 264);
|
||||
this.ViewerContextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.ViewerContextMenuStrip_Opening);
|
||||
//
|
||||
// CopyContextItem
|
||||
|
@ -472,7 +474,7 @@
|
|||
this.CopyContextItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Duplicate;
|
||||
this.CopyContextItem.Name = "CopyContextItem";
|
||||
this.CopyContextItem.ShortcutKeyDisplayString = "Ctrl+C";
|
||||
this.CopyContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.CopyContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.CopyContextItem.Text = "&Copy";
|
||||
this.CopyContextItem.Click += new System.EventHandler(this.CopyMenuItem_Click);
|
||||
//
|
||||
|
@ -480,7 +482,7 @@
|
|||
//
|
||||
this.ExportContextItem.Name = "ExportContextItem";
|
||||
this.ExportContextItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E)));
|
||||
this.ExportContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.ExportContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.ExportContextItem.Text = "&Export";
|
||||
//
|
||||
// PasteContextItem
|
||||
|
@ -488,7 +490,7 @@
|
|||
this.PasteContextItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Paste;
|
||||
this.PasteContextItem.Name = "PasteContextItem";
|
||||
this.PasteContextItem.ShortcutKeyDisplayString = "Ctrl+V";
|
||||
this.PasteContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.PasteContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.PasteContextItem.Text = "&Paste";
|
||||
this.PasteContextItem.Click += new System.EventHandler(this.PasteMenuItem_Click);
|
||||
//
|
||||
|
@ -497,7 +499,7 @@
|
|||
this.FreezeContextItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Freeze;
|
||||
this.FreezeContextItem.Name = "FreezeContextItem";
|
||||
this.FreezeContextItem.ShortcutKeyDisplayString = "Space";
|
||||
this.FreezeContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.FreezeContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.FreezeContextItem.Text = "&Freeze";
|
||||
this.FreezeContextItem.Click += new System.EventHandler(this.FreezeAddressMenuItem_Click);
|
||||
//
|
||||
|
@ -506,7 +508,7 @@
|
|||
this.AddToRamWatchContextItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.FindHS;
|
||||
this.AddToRamWatchContextItem.Name = "AddToRamWatchContextItem";
|
||||
this.AddToRamWatchContextItem.ShortcutKeyDisplayString = "Ctrl+W";
|
||||
this.AddToRamWatchContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.AddToRamWatchContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.AddToRamWatchContextItem.Text = "&Add to RAM Watch";
|
||||
this.AddToRamWatchContextItem.Click += new System.EventHandler(this.AddToRamWatchMenuItem_Click);
|
||||
//
|
||||
|
@ -515,7 +517,7 @@
|
|||
this.UnfreezeAllContextItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Unfreeze;
|
||||
this.UnfreezeAllContextItem.Name = "UnfreezeAllContextItem";
|
||||
this.UnfreezeAllContextItem.ShortcutKeyDisplayString = "Shift+Del";
|
||||
this.UnfreezeAllContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.UnfreezeAllContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.UnfreezeAllContextItem.Text = "&Unfreeze All";
|
||||
this.UnfreezeAllContextItem.Click += new System.EventHandler(this.UnfreezeAllMenuItem_Click);
|
||||
//
|
||||
|
@ -524,20 +526,20 @@
|
|||
this.PokeContextItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.poke;
|
||||
this.PokeContextItem.Name = "PokeContextItem";
|
||||
this.PokeContextItem.ShortcutKeyDisplayString = "Ctrl+P";
|
||||
this.PokeContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.PokeContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.PokeContextItem.Text = "&Poke Address";
|
||||
this.PokeContextItem.Click += new System.EventHandler(this.PokeAddressMenuItem_Click);
|
||||
//
|
||||
// ContextSeparator1
|
||||
//
|
||||
this.ContextSeparator1.Name = "ContextSeparator1";
|
||||
this.ContextSeparator1.Size = new System.Drawing.Size(204, 6);
|
||||
this.ContextSeparator1.Size = new System.Drawing.Size(218, 6);
|
||||
//
|
||||
// IncrementContextItem
|
||||
//
|
||||
this.IncrementContextItem.Name = "IncrementContextItem";
|
||||
this.IncrementContextItem.ShortcutKeyDisplayString = "+";
|
||||
this.IncrementContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.IncrementContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.IncrementContextItem.Text = "&Increment";
|
||||
this.IncrementContextItem.Click += new System.EventHandler(this.IncrementContextItem_Click);
|
||||
//
|
||||
|
@ -545,32 +547,32 @@
|
|||
//
|
||||
this.DecrementContextItem.Name = "DecrementContextItem";
|
||||
this.DecrementContextItem.ShortcutKeyDisplayString = "-";
|
||||
this.DecrementContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.DecrementContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.DecrementContextItem.Text = "&Decrement";
|
||||
this.DecrementContextItem.Click += new System.EventHandler(this.DecrementContextItem_Click);
|
||||
//
|
||||
// ContextSeparator2
|
||||
//
|
||||
this.ContextSeparator2.Name = "ContextSeparator2";
|
||||
this.ContextSeparator2.Size = new System.Drawing.Size(204, 6);
|
||||
this.ContextSeparator2.Size = new System.Drawing.Size(218, 6);
|
||||
//
|
||||
// GoToContextItem
|
||||
//
|
||||
this.GoToContextItem.Name = "GoToContextItem";
|
||||
this.GoToContextItem.ShortcutKeyDisplayString = "Ctrl+G";
|
||||
this.GoToContextItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.GoToContextItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.GoToContextItem.Text = "&Go to Address...";
|
||||
this.GoToContextItem.Click += new System.EventHandler(this.GoToAddressMenuItem_Click);
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(204, 6);
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(218, 6);
|
||||
//
|
||||
// viewN64MatrixToolStripMenuItem
|
||||
//
|
||||
this.viewN64MatrixToolStripMenuItem.Name = "viewN64MatrixToolStripMenuItem";
|
||||
this.viewN64MatrixToolStripMenuItem.Size = new System.Drawing.Size(207, 22);
|
||||
this.viewN64MatrixToolStripMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.viewN64MatrixToolStripMenuItem.Text = "View N64 Matrix";
|
||||
this.viewN64MatrixToolStripMenuItem.Click += new System.EventHandler(this.viewN64MatrixToolStripMenuItem_Click);
|
||||
//
|
||||
|
@ -638,6 +640,14 @@
|
|||
this.Header.TabIndex = 2;
|
||||
this.Header.Text = "label1";
|
||||
//
|
||||
// swapBytesToolStripMenuItem
|
||||
//
|
||||
this.swapBytesToolStripMenuItem.CheckOnClick = true;
|
||||
this.swapBytesToolStripMenuItem.Name = "swapBytesToolStripMenuItem";
|
||||
this.swapBytesToolStripMenuItem.Size = new System.Drawing.Size(221, 22);
|
||||
this.swapBytesToolStripMenuItem.Text = "Swap Bytes";
|
||||
this.swapBytesToolStripMenuItem.Click += new System.EventHandler(this.SwapBytesMenuItem_Click);
|
||||
//
|
||||
// HexEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -732,5 +742,6 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem ExportContextItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem ExportMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem importAsBinaryToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem swapBytesToolStripMenuItem;
|
||||
}
|
||||
}
|
|
@ -79,6 +79,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
private MemoryDomain _romDomain;
|
||||
private HexFind _hexFind = new HexFind();
|
||||
|
||||
[ConfigPersist]
|
||||
private bool SwapBytes { get; set; }
|
||||
|
||||
[ConfigPersist]
|
||||
private bool BigEndian { get; set; }
|
||||
|
||||
|
@ -179,7 +182,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
_domain = MemoryDomains.MainMemory;
|
||||
}
|
||||
|
||||
SwapBytes = false;
|
||||
BigEndian = _domain.EndianType == MemoryDomain.Endian.Big;
|
||||
|
||||
_maxRow = _domain.Size / 2;
|
||||
|
||||
// Don't reset scroll bar if restarting the same rom
|
||||
|
@ -526,7 +531,24 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (_addr + j + DataSize <= _domain.Size)
|
||||
{
|
||||
rowStr.AppendFormat(_digitFormatString, MakeValue(_addr + j));
|
||||
int t_val = 0;
|
||||
int t_next = 0;
|
||||
bool is_cht;
|
||||
for (int k = 0; k < DataSize; k++)
|
||||
{
|
||||
t_next = MakeValue(1, _addr + j + k, out is_cht);
|
||||
|
||||
if (SwapBytes)
|
||||
{
|
||||
t_val += (t_next << (k * 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
t_val += (t_next << ((DataSize - k - 1) * 8));
|
||||
}
|
||||
}
|
||||
|
||||
rowStr.AppendFormat(_digitFormatString, t_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -565,28 +587,31 @@ namespace BizHawk.Client.EmuHawk
|
|||
: _domain.PeekByte(address);
|
||||
}
|
||||
|
||||
private int MakeValue(int dataSize, long address)
|
||||
private int MakeValue(int dataSize, long address, out bool is_cheat)
|
||||
{
|
||||
if (Global.CheatList.IsActive(_domain, address))
|
||||
{
|
||||
return Global.CheatList.GetCheatValue(_domain, address, (WatchSize)DataSize ).Value;
|
||||
is_cheat = true;
|
||||
return Global.CheatList.GetCheatValue(_domain, address, (WatchSize)dataSize ).Value;
|
||||
}
|
||||
|
||||
is_cheat = false;
|
||||
switch (dataSize)
|
||||
{
|
||||
default:
|
||||
case 1:
|
||||
return _domain.PeekByte(address);
|
||||
case 2:
|
||||
return _domain.PeekUshort(address, BigEndian);
|
||||
return _domain.PeekUshort(address, SwapBytes);
|
||||
case 4:
|
||||
return (int)_domain.PeekUint(address, BigEndian);
|
||||
return (int)_domain.PeekUint(address, SwapBytes);
|
||||
}
|
||||
}
|
||||
|
||||
private int MakeValue(long address)
|
||||
{
|
||||
return MakeValue(DataSize, address);
|
||||
bool temp;
|
||||
return MakeValue(DataSize, address, out temp);
|
||||
}
|
||||
|
||||
private void SetMemoryDomain(string name)
|
||||
|
@ -600,6 +625,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
_domain = MemoryDomains[name];
|
||||
}
|
||||
|
||||
SwapBytes = false;
|
||||
BigEndian = _domain.EndianType == MemoryDomain.Endian.Big;
|
||||
_maxRow = _domain.Size / 2;
|
||||
SetUpScrollBar();
|
||||
|
@ -1444,8 +1470,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
long start = addresses[i];
|
||||
long end = addresses[i] + DataSize -1 ;
|
||||
bool temp;
|
||||
for(long a = start;a<=end;a++)
|
||||
sb.AppendFormat("{0:X2}", MakeValue(1,a));
|
||||
sb.AppendFormat("{0:X2}", MakeValue(1,a, out temp));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1598,7 +1625,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void BigEndianMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
BigEndian ^= true;
|
||||
//BigEndian ^= true;
|
||||
//UpdateValues();
|
||||
}
|
||||
|
||||
private void SwapBytesMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
SwapBytes ^= true;
|
||||
UpdateValues();
|
||||
}
|
||||
|
||||
|
|
|
@ -610,9 +610,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
TasBranch branch = GetBranch(BranchView.CurrentCell.RowIndex.Value);
|
||||
Point location = Location;
|
||||
location.Offset(-Screenshot.Width, 0);
|
||||
int width = Tastudio.VideoProvider.BufferWidth;
|
||||
int height = Tastudio.VideoProvider.BufferHeight;
|
||||
int width = branch.OSDFrameBuffer.Width;
|
||||
int height = branch.OSDFrameBuffer.Height;
|
||||
location.Offset(-width, 0);
|
||||
|
||||
Screenshot.UpdateValues(branch, PointToScreen(location), width, height,
|
||||
(int)Graphics.FromHwnd(this.Handle).MeasureString(
|
||||
|
|
|
@ -48,28 +48,38 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.DiskCapacityNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.SaveCapacityNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.FileCapacityNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.NumSaveStatesLabel = new System.Windows.Forms.Label();
|
||||
this.BranchStatesInTasproj = new System.Windows.Forms.CheckBox();
|
||||
this.EraseBranchStatesFirst = new System.Windows.Forms.CheckBox();
|
||||
this.StateGap = new System.Windows.Forms.NumericUpDown();
|
||||
this.FileStateGapNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.label11 = new System.Windows.Forms.Label();
|
||||
this.NumFramesLabel = new System.Windows.Forms.Label();
|
||||
this.FileNumFramesLabel = new System.Windows.Forms.Label();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.label14 = new System.Windows.Forms.Label();
|
||||
this.MemFramesLabel = new System.Windows.Forms.Label();
|
||||
this.label13 = new System.Windows.Forms.Label();
|
||||
this.MemStateGapDividerNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label12 = new System.Windows.Forms.Label();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this.MemCapacityNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DiskCapacityNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.SaveCapacityNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.StateGap)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.FileCapacityNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.FileStateGapNumeric)).BeginInit();
|
||||
this.groupBox1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.MemStateGapDividerNumeric)).BeginInit();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// CancelBtn
|
||||
//
|
||||
this.CancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.CancelBtn.Location = new System.Drawing.Point(217, 220);
|
||||
this.CancelBtn.Location = new System.Drawing.Point(242, 259);
|
||||
this.CancelBtn.Name = "CancelBtn";
|
||||
this.CancelBtn.Size = new System.Drawing.Size(60, 23);
|
||||
this.CancelBtn.TabIndex = 0;
|
||||
|
@ -80,7 +90,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
// OkBtn
|
||||
//
|
||||
this.OkBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.OkBtn.Location = new System.Drawing.Point(151, 220);
|
||||
this.OkBtn.Location = new System.Drawing.Point(176, 259);
|
||||
this.OkBtn.Name = "OkBtn";
|
||||
this.OkBtn.Size = new System.Drawing.Size(60, 23);
|
||||
this.OkBtn.TabIndex = 1;
|
||||
|
@ -90,7 +100,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
//
|
||||
// MemCapacityNumeric
|
||||
//
|
||||
this.MemCapacityNumeric.Location = new System.Drawing.Point(15, 49);
|
||||
this.MemCapacityNumeric.Location = new System.Drawing.Point(12, 36);
|
||||
this.MemCapacityNumeric.Maximum = new decimal(new int[] {
|
||||
1024,
|
||||
0,
|
||||
|
@ -114,20 +124,20 @@ namespace BizHawk.Client.EmuHawk
|
|||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(70, 52);
|
||||
this.label1.Location = new System.Drawing.Point(73, 39);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(21, 13);
|
||||
this.label1.Size = new System.Drawing.Size(23, 13);
|
||||
this.label1.TabIndex = 4;
|
||||
this.label1.Text = "mb";
|
||||
this.label1.Text = "MB";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(12, 32);
|
||||
this.label2.Location = new System.Drawing.Point(9, 19);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(88, 13);
|
||||
this.label2.Size = new System.Drawing.Size(48, 13);
|
||||
this.label2.TabIndex = 5;
|
||||
this.label2.Text = "Memory Capacity";
|
||||
this.label2.Text = "Capacity";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
|
@ -150,7 +160,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(12, 136);
|
||||
this.label4.Location = new System.Drawing.Point(160, 9);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(84, 13);
|
||||
this.label4.TabIndex = 8;
|
||||
|
@ -159,17 +169,18 @@ namespace BizHawk.Client.EmuHawk
|
|||
// NumStatesLabel
|
||||
//
|
||||
this.NumStatesLabel.AutoSize = true;
|
||||
this.NumStatesLabel.Location = new System.Drawing.Point(99, 136);
|
||||
this.NumStatesLabel.Location = new System.Drawing.Point(250, 9);
|
||||
this.NumStatesLabel.Name = "NumStatesLabel";
|
||||
this.NumStatesLabel.Size = new System.Drawing.Size(25, 13);
|
||||
this.NumStatesLabel.Size = new System.Drawing.Size(13, 13);
|
||||
this.NumStatesLabel.TabIndex = 9;
|
||||
this.NumStatesLabel.Text = "1kb";
|
||||
this.NumStatesLabel.Text = "1";
|
||||
//
|
||||
// DiskCapacityNumeric
|
||||
//
|
||||
this.DiskCapacityNumeric.Location = new System.Drawing.Point(15, 113);
|
||||
this.DiskCapacityNumeric.Enabled = false;
|
||||
this.DiskCapacityNumeric.Location = new System.Drawing.Point(24, 241);
|
||||
this.DiskCapacityNumeric.Maximum = new decimal(new int[] {
|
||||
65536,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
|
@ -182,7 +193,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.DiskCapacityNumeric.Size = new System.Drawing.Size(55, 20);
|
||||
this.DiskCapacityNumeric.TabIndex = 3;
|
||||
this.DiskCapacityNumeric.Value = new decimal(new int[] {
|
||||
512,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
|
@ -191,61 +202,63 @@ namespace BizHawk.Client.EmuHawk
|
|||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(70, 116);
|
||||
this.label5.Enabled = false;
|
||||
this.label5.Location = new System.Drawing.Point(79, 244);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(21, 13);
|
||||
this.label5.Size = new System.Drawing.Size(23, 13);
|
||||
this.label5.TabIndex = 4;
|
||||
this.label5.Text = "mb";
|
||||
this.label5.Text = "MB";
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(12, 96);
|
||||
this.label6.Enabled = false;
|
||||
this.label6.Location = new System.Drawing.Point(21, 224);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(72, 13);
|
||||
this.label6.TabIndex = 5;
|
||||
this.label6.Text = "Disk Capacity";
|
||||
//
|
||||
// SaveCapacityNumeric
|
||||
// FileCapacityNumeric
|
||||
//
|
||||
this.SaveCapacityNumeric.Location = new System.Drawing.Point(150, 49);
|
||||
this.SaveCapacityNumeric.Maximum = new decimal(new int[] {
|
||||
this.FileCapacityNumeric.Location = new System.Drawing.Point(12, 36);
|
||||
this.FileCapacityNumeric.Maximum = new decimal(new int[] {
|
||||
65536,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.SaveCapacityNumeric.Name = "SaveCapacityNumeric";
|
||||
this.SaveCapacityNumeric.Size = new System.Drawing.Size(55, 20);
|
||||
this.SaveCapacityNumeric.TabIndex = 3;
|
||||
this.SaveCapacityNumeric.Value = new decimal(new int[] {
|
||||
this.FileCapacityNumeric.Name = "FileCapacityNumeric";
|
||||
this.FileCapacityNumeric.Size = new System.Drawing.Size(55, 20);
|
||||
this.FileCapacityNumeric.TabIndex = 3;
|
||||
this.FileCapacityNumeric.Value = new decimal(new int[] {
|
||||
512,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.SaveCapacityNumeric.ValueChanged += new System.EventHandler(this.SaveCapacityNumeric_ValueChanged);
|
||||
this.FileCapacityNumeric.ValueChanged += new System.EventHandler(this.SaveCapacityNumeric_ValueChanged);
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(205, 52);
|
||||
this.label7.Location = new System.Drawing.Point(73, 39);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(21, 13);
|
||||
this.label7.Size = new System.Drawing.Size(23, 13);
|
||||
this.label7.TabIndex = 4;
|
||||
this.label7.Text = "mb";
|
||||
this.label7.Text = "MB";
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(147, 32);
|
||||
this.label8.Location = new System.Drawing.Point(9, 19);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(112, 13);
|
||||
this.label8.Size = new System.Drawing.Size(48, 13);
|
||||
this.label8.TabIndex = 5;
|
||||
this.label8.Text = "Project Save Capacity";
|
||||
this.label8.Text = "Capacity";
|
||||
//
|
||||
// label9
|
||||
//
|
||||
this.label9.AutoSize = true;
|
||||
this.label9.Location = new System.Drawing.Point(147, 72);
|
||||
this.label9.Location = new System.Drawing.Point(9, 59);
|
||||
this.label9.Name = "label9";
|
||||
this.label9.Size = new System.Drawing.Size(84, 13);
|
||||
this.label9.TabIndex = 8;
|
||||
|
@ -254,21 +267,21 @@ namespace BizHawk.Client.EmuHawk
|
|||
// NumSaveStatesLabel
|
||||
//
|
||||
this.NumSaveStatesLabel.AutoSize = true;
|
||||
this.NumSaveStatesLabel.Location = new System.Drawing.Point(234, 72);
|
||||
this.NumSaveStatesLabel.Location = new System.Drawing.Point(96, 59);
|
||||
this.NumSaveStatesLabel.Name = "NumSaveStatesLabel";
|
||||
this.NumSaveStatesLabel.Size = new System.Drawing.Size(25, 13);
|
||||
this.NumSaveStatesLabel.Size = new System.Drawing.Size(13, 13);
|
||||
this.NumSaveStatesLabel.TabIndex = 9;
|
||||
this.NumSaveStatesLabel.Text = "1kb";
|
||||
this.NumSaveStatesLabel.Text = "1";
|
||||
//
|
||||
// BranchStatesInTasproj
|
||||
//
|
||||
this.BranchStatesInTasproj.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.BranchStatesInTasproj.AutoSize = true;
|
||||
this.BranchStatesInTasproj.Location = new System.Drawing.Point(15, 165);
|
||||
this.BranchStatesInTasproj.Location = new System.Drawing.Point(12, 153);
|
||||
this.BranchStatesInTasproj.Name = "BranchStatesInTasproj";
|
||||
this.BranchStatesInTasproj.Size = new System.Drawing.Size(158, 17);
|
||||
this.BranchStatesInTasproj.Size = new System.Drawing.Size(118, 17);
|
||||
this.BranchStatesInTasproj.TabIndex = 10;
|
||||
this.BranchStatesInTasproj.Text = "Put branch states to .tasproj";
|
||||
this.BranchStatesInTasproj.Text = "Save branch states";
|
||||
this.BranchStatesInTasproj.UseVisualStyleBackColor = true;
|
||||
this.BranchStatesInTasproj.CheckedChanged += new System.EventHandler(this.BranchStatesInTasproj_CheckedChanged);
|
||||
//
|
||||
|
@ -278,7 +291,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.EraseBranchStatesFirst.AutoSize = true;
|
||||
this.EraseBranchStatesFirst.Checked = true;
|
||||
this.EraseBranchStatesFirst.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.EraseBranchStatesFirst.Location = new System.Drawing.Point(15, 190);
|
||||
this.EraseBranchStatesFirst.Location = new System.Drawing.Point(6, 153);
|
||||
this.EraseBranchStatesFirst.Name = "EraseBranchStatesFirst";
|
||||
this.EraseBranchStatesFirst.Size = new System.Drawing.Size(139, 17);
|
||||
this.EraseBranchStatesFirst.TabIndex = 11;
|
||||
|
@ -286,50 +299,146 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.EraseBranchStatesFirst.UseVisualStyleBackColor = true;
|
||||
this.EraseBranchStatesFirst.CheckedChanged += new System.EventHandler(this.EraseBranchStatesFIrst_CheckedChanged);
|
||||
//
|
||||
// StateGap
|
||||
// FileStateGapNumeric
|
||||
//
|
||||
this.StateGap.Location = new System.Drawing.Point(151, 112);
|
||||
this.StateGap.Maximum = new decimal(new int[] {
|
||||
this.FileStateGapNumeric.Location = new System.Drawing.Point(12, 100);
|
||||
this.FileStateGapNumeric.Maximum = new decimal(new int[] {
|
||||
8,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.StateGap.Name = "StateGap";
|
||||
this.StateGap.Size = new System.Drawing.Size(55, 20);
|
||||
this.StateGap.TabIndex = 12;
|
||||
this.StateGap.Value = new decimal(new int[] {
|
||||
this.FileStateGapNumeric.Name = "FileStateGapNumeric";
|
||||
this.FileStateGapNumeric.Size = new System.Drawing.Size(55, 20);
|
||||
this.FileStateGapNumeric.TabIndex = 12;
|
||||
this.FileStateGapNumeric.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.StateGap.ValueChanged += new System.EventHandler(this.StateGap_ValueChanged);
|
||||
this.FileStateGapNumeric.ValueChanged += new System.EventHandler(this.FileStateGap_ValueChanged);
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(148, 96);
|
||||
this.label10.Location = new System.Drawing.Point(9, 84);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(91, 13);
|
||||
this.label10.Size = new System.Drawing.Size(55, 13);
|
||||
this.label10.TabIndex = 13;
|
||||
this.label10.Text = "Project State Gap";
|
||||
this.label10.Text = "State Gap";
|
||||
//
|
||||
// label11
|
||||
//
|
||||
this.label11.AutoSize = true;
|
||||
this.label11.Location = new System.Drawing.Point(147, 135);
|
||||
this.label11.Location = new System.Drawing.Point(8, 123);
|
||||
this.label11.Name = "label11";
|
||||
this.label11.Size = new System.Drawing.Size(61, 13);
|
||||
this.label11.TabIndex = 14;
|
||||
this.label11.Text = "State every";
|
||||
//
|
||||
// NumFramesLabel
|
||||
// FileNumFramesLabel
|
||||
//
|
||||
this.NumFramesLabel.AutoSize = true;
|
||||
this.NumFramesLabel.Location = new System.Drawing.Point(204, 135);
|
||||
this.NumFramesLabel.Name = "NumFramesLabel";
|
||||
this.NumFramesLabel.Size = new System.Drawing.Size(47, 13);
|
||||
this.NumFramesLabel.TabIndex = 15;
|
||||
this.NumFramesLabel.Text = "0 frames";
|
||||
this.FileNumFramesLabel.AutoSize = true;
|
||||
this.FileNumFramesLabel.Location = new System.Drawing.Point(65, 123);
|
||||
this.FileNumFramesLabel.Name = "FileNumFramesLabel";
|
||||
this.FileNumFramesLabel.Size = new System.Drawing.Size(47, 13);
|
||||
this.FileNumFramesLabel.TabIndex = 15;
|
||||
this.FileNumFramesLabel.Text = "0 frames";
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.label14);
|
||||
this.groupBox1.Controls.Add(this.MemFramesLabel);
|
||||
this.groupBox1.Controls.Add(this.label13);
|
||||
this.groupBox1.Controls.Add(this.MemStateGapDividerNumeric);
|
||||
this.groupBox1.Controls.Add(this.label12);
|
||||
this.groupBox1.Controls.Add(this.EraseBranchStatesFirst);
|
||||
this.groupBox1.Controls.Add(this.label2);
|
||||
this.groupBox1.Controls.Add(this.MemCapacityNumeric);
|
||||
this.groupBox1.Controls.Add(this.label1);
|
||||
this.groupBox1.Location = new System.Drawing.Point(12, 34);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(143, 176);
|
||||
this.groupBox1.TabIndex = 16;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Memory Usage";
|
||||
//
|
||||
// label14
|
||||
//
|
||||
this.label14.AutoSize = true;
|
||||
this.label14.Location = new System.Drawing.Point(73, 102);
|
||||
this.label14.Name = "label14";
|
||||
this.label14.Size = new System.Drawing.Size(21, 13);
|
||||
this.label14.TabIndex = 17;
|
||||
this.label14.Text = "KB";
|
||||
//
|
||||
// MemFramesLabel
|
||||
//
|
||||
this.MemFramesLabel.AutoSize = true;
|
||||
this.MemFramesLabel.Location = new System.Drawing.Point(66, 123);
|
||||
this.MemFramesLabel.Name = "MemFramesLabel";
|
||||
this.MemFramesLabel.Size = new System.Drawing.Size(47, 13);
|
||||
this.MemFramesLabel.TabIndex = 16;
|
||||
this.MemFramesLabel.Text = "0 frames";
|
||||
//
|
||||
// label13
|
||||
//
|
||||
this.label13.AutoSize = true;
|
||||
this.label13.Location = new System.Drawing.Point(9, 123);
|
||||
this.label13.Name = "label13";
|
||||
this.label13.Size = new System.Drawing.Size(61, 13);
|
||||
this.label13.TabIndex = 15;
|
||||
this.label13.Text = "State every";
|
||||
//
|
||||
// MemStateGapDividerNumeric
|
||||
//
|
||||
this.MemStateGapDividerNumeric.Location = new System.Drawing.Point(12, 100);
|
||||
this.MemStateGapDividerNumeric.Maximum = new decimal(new int[] {
|
||||
1024,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.MemStateGapDividerNumeric.Minimum = new decimal(new int[] {
|
||||
64,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.MemStateGapDividerNumeric.Name = "MemStateGapDividerNumeric";
|
||||
this.MemStateGapDividerNumeric.Size = new System.Drawing.Size(55, 20);
|
||||
this.MemStateGapDividerNumeric.TabIndex = 7;
|
||||
this.MemStateGapDividerNumeric.Value = new decimal(new int[] {
|
||||
65,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.MemStateGapDividerNumeric.ValueChanged += new System.EventHandler(this.MemStateGapDivider_ValueChanged);
|
||||
//
|
||||
// label12
|
||||
//
|
||||
this.label12.AutoSize = true;
|
||||
this.label12.Location = new System.Drawing.Point(9, 84);
|
||||
this.label12.Name = "label12";
|
||||
this.label12.Size = new System.Drawing.Size(91, 13);
|
||||
this.label12.TabIndex = 6;
|
||||
this.label12.Text = "State Gap Divider";
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.label8);
|
||||
this.groupBox2.Controls.Add(this.FileCapacityNumeric);
|
||||
this.groupBox2.Controls.Add(this.FileNumFramesLabel);
|
||||
this.groupBox2.Controls.Add(this.label7);
|
||||
this.groupBox2.Controls.Add(this.BranchStatesInTasproj);
|
||||
this.groupBox2.Controls.Add(this.label11);
|
||||
this.groupBox2.Controls.Add(this.label9);
|
||||
this.groupBox2.Controls.Add(this.label10);
|
||||
this.groupBox2.Controls.Add(this.NumSaveStatesLabel);
|
||||
this.groupBox2.Controls.Add(this.FileStateGapNumeric);
|
||||
this.groupBox2.Location = new System.Drawing.Point(163, 34);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(138, 176);
|
||||
this.groupBox2.TabIndex = 17;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Project File";
|
||||
//
|
||||
// StateHistorySettingsForm
|
||||
//
|
||||
|
@ -337,28 +446,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.CancelButton = this.CancelBtn;
|
||||
this.ClientSize = new System.Drawing.Size(289, 255);
|
||||
this.Controls.Add(this.NumFramesLabel);
|
||||
this.Controls.Add(this.label11);
|
||||
this.Controls.Add(this.label10);
|
||||
this.Controls.Add(this.StateGap);
|
||||
this.Controls.Add(this.EraseBranchStatesFirst);
|
||||
this.Controls.Add(this.BranchStatesInTasproj);
|
||||
this.Controls.Add(this.NumSaveStatesLabel);
|
||||
this.Controls.Add(this.NumStatesLabel);
|
||||
this.Controls.Add(this.label9);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.SavestateSizeLabel);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.label8);
|
||||
this.Controls.Add(this.label7);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.SaveCapacityNumeric);
|
||||
this.Controls.Add(this.label2);
|
||||
this.ClientSize = new System.Drawing.Size(315, 294);
|
||||
this.Controls.Add(this.groupBox2);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.DiskCapacityNumeric);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.MemCapacityNumeric);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.SavestateSizeLabel);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.NumStatesLabel);
|
||||
this.Controls.Add(this.OkBtn);
|
||||
this.Controls.Add(this.CancelBtn);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
|
@ -369,8 +466,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
this.Load += new System.EventHandler(this.StateHistorySettings_Load);
|
||||
((System.ComponentModel.ISupportInitialize)(this.MemCapacityNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.DiskCapacityNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.SaveCapacityNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.StateGap)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.FileCapacityNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.FileStateGapNumeric)).EndInit();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.MemStateGapDividerNumeric)).EndInit();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -388,16 +490,23 @@ namespace BizHawk.Client.EmuHawk
|
|||
private NumericUpDown DiskCapacityNumeric;
|
||||
private Label label5;
|
||||
private Label label6;
|
||||
private NumericUpDown SaveCapacityNumeric;
|
||||
private NumericUpDown FileCapacityNumeric;
|
||||
private Label label7;
|
||||
private Label label8;
|
||||
private Label label9;
|
||||
private Label NumSaveStatesLabel;
|
||||
private CheckBox BranchStatesInTasproj;
|
||||
private CheckBox EraseBranchStatesFirst;
|
||||
private NumericUpDown StateGap;
|
||||
private NumericUpDown FileStateGapNumeric;
|
||||
private Label label10;
|
||||
private Label label11;
|
||||
private Label NumFramesLabel;
|
||||
private Label FileNumFramesLabel;
|
||||
private GroupBox groupBox1;
|
||||
private NumericUpDown MemStateGapDividerNumeric;
|
||||
private Label label12;
|
||||
private GroupBox groupBox2;
|
||||
private Label MemFramesLabel;
|
||||
private Label label13;
|
||||
private Label label14;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,11 +29,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
_settings.Capacitymb : MemCapacityNumeric.Maximum;
|
||||
DiskCapacityNumeric.Value = _settings.DiskCapacitymb < MemCapacityNumeric.Maximum ?
|
||||
_settings.DiskCapacitymb : MemCapacityNumeric.Maximum;
|
||||
SaveCapacityNumeric.Value = _settings.DiskSaveCapacitymb < MemCapacityNumeric.Maximum ?
|
||||
FileCapacityNumeric.Value = _settings.DiskSaveCapacitymb < MemCapacityNumeric.Maximum ?
|
||||
_settings.DiskSaveCapacitymb : MemCapacityNumeric.Maximum;
|
||||
|
||||
StateGap.Value = _settings.StateGap;
|
||||
SavestateSizeLabel.Text = Math.Round(_stateSizeMb, 2).ToString() + " mb";
|
||||
MemStateGapDividerNumeric.Maximum = Statable.SaveStateBinary().Length / 1024 / 2 + 1;
|
||||
MemStateGapDividerNumeric.Minimum = Statable.SaveStateBinary().Length / 1024 / 16;
|
||||
MemStateGapDividerNumeric.Value = _settings.MemStateGapDivider < MemStateGapDividerNumeric.Minimum ?
|
||||
MemStateGapDividerNumeric.Minimum : _settings.MemStateGapDivider;
|
||||
|
||||
FileStateGapNumeric.Value = _settings.FileStateGap;
|
||||
SavestateSizeLabel.Text = Math.Round(_stateSizeMb, 2).ToString() + " MB";
|
||||
CapacityNumeric_ValueChanged(null, null);
|
||||
SaveCapacityNumeric_ValueChanged(null, null);
|
||||
BranchStatesInTasproj.Checked = _settings.BranchStatesInTasproj;
|
||||
|
@ -47,8 +52,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
_settings.Capacitymb = (int)MemCapacityNumeric.Value;
|
||||
_settings.DiskCapacitymb = (int)DiskCapacityNumeric.Value;
|
||||
_settings.DiskSaveCapacitymb = (int)SaveCapacityNumeric.Value;
|
||||
_settings.StateGap = (int)StateGap.Value;
|
||||
_settings.DiskSaveCapacitymb = (int)FileCapacityNumeric.Value;
|
||||
_settings.MemStateGapDivider = (int)MemStateGapDividerNumeric.Value;
|
||||
_settings.FileStateGap = (int)FileStateGapNumeric.Value;
|
||||
DialogResult = DialogResult.OK;
|
||||
Close();
|
||||
}
|
||||
|
@ -68,7 +74,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void SaveCapacityNumeric_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
NumSaveStatesLabel.Text = ((int)Math.Floor(SaveCapacityNumeric.Value / _stateSizeMb)).ToString();
|
||||
NumSaveStatesLabel.Text = ((int)Math.Floor(FileCapacityNumeric.Value / _stateSizeMb)).ToString();
|
||||
}
|
||||
|
||||
private void BranchStatesInTasproj_CheckedChanged(object sender, EventArgs e)
|
||||
|
@ -81,11 +87,23 @@ namespace BizHawk.Client.EmuHawk
|
|||
_settings.EraseBranchStatesFirst = EraseBranchStatesFirst.Checked;
|
||||
}
|
||||
|
||||
private void StateGap_ValueChanged(object sender, EventArgs e)
|
||||
private void FileStateGap_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
NumFramesLabel.Text = StateGap.Value == 0
|
||||
FileNumFramesLabel.Text = FileStateGapNumeric.Value == 0
|
||||
? "frame"
|
||||
: $"{1 << (int)StateGap.Value} frames";
|
||||
: $"{1 << (int)FileStateGapNumeric.Value} frames";
|
||||
}
|
||||
|
||||
private void MemStateGapDivider_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
int val = (int)(Statable.SaveStateBinary().Length / MemStateGapDividerNumeric.Value / 1024);
|
||||
|
||||
if (val <= 1)
|
||||
MemStateGapDividerNumeric.Maximum = MemStateGapDividerNumeric.Value;
|
||||
|
||||
MemFramesLabel.Text = val <= 1
|
||||
? "frame"
|
||||
: $"{val} frames";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
public partial class ScreenshotForm : Form
|
||||
{
|
||||
// but still appear topmost
|
||||
private const int WS_EX_TOPMOST = 0x00000008;
|
||||
|
||||
private const int WidthCap = 320;
|
||||
private const int HeightCap = 240;
|
||||
|
||||
private const int Interval = 40;
|
||||
private const double AlphaStep = 0.125;
|
||||
|
||||
|
@ -32,9 +29,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
public ScreenshotForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Width = WidthCap;
|
||||
Height = HeightCap;
|
||||
|
||||
var fontSize = 10;
|
||||
var fontStyle = FontStyle.Regular;
|
||||
Font = new Font(FontFamily.GenericMonospace, fontSize, fontStyle);
|
||||
|
@ -71,15 +66,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
Text = _branch.UserText;
|
||||
Location = location;
|
||||
|
||||
// Set the screenshot to "1x" resolution of the core
|
||||
// cores like n64 and psx are going to still have sizes too big for the control, so cap them
|
||||
if (Width > WidthCap)
|
||||
{
|
||||
double ratio = WidthCap / (double)Width;
|
||||
Width = WidthCap;
|
||||
_drawingHeight = (int)((double)(_drawingHeight) * ratio);
|
||||
}
|
||||
|
||||
if (Padding > 0)
|
||||
{
|
||||
Padding += 2;
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private bool _triggerAutoRestore; // If true, autorestore will be called on mouse up
|
||||
private bool? _autoRestorePaused = null;
|
||||
private int? _seekStartFrame = null;
|
||||
private bool _shouldUnpauseFromRewind = false;
|
||||
private bool _unpauseAfterSeeking = false;
|
||||
|
||||
private ControllerDefinition ControllerType => Global.MovieSession.MovieControllerAdapter.Definition;
|
||||
|
||||
|
@ -111,10 +111,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
|
||||
Mainform.PauseOnFrame = null;
|
||||
if (_shouldUnpauseFromRewind)
|
||||
if (_unpauseAfterSeeking)
|
||||
{
|
||||
Mainform.UnpauseEmulator();
|
||||
_shouldUnpauseFromRewind = false;
|
||||
_unpauseAfterSeeking = false;
|
||||
}
|
||||
|
||||
if (CurrentTasMovie != null)
|
||||
|
@ -762,7 +762,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void TasView_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if (e.Button == MouseButtons.Right && !TasView.IsPointingAtColumnHeader && !_supressContextMenu && TasView.SelectedRows.Any())
|
||||
if (e.Button == MouseButtons.Right && !TasView.IsPointingAtColumnHeader &&
|
||||
!_supressContextMenu && TasView.SelectedRows.Any() && !_leftButtonHeld)
|
||||
{
|
||||
if (Global.MovieSession.Movie.FrameCount < TasView.SelectedRows.Max())
|
||||
{
|
||||
|
|
|
@ -72,11 +72,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
else if (ofd.FileName.EndsWith(".bkm") || ofd.FileName.EndsWith(".bk2")) // todo: proper extention iteration
|
||||
{
|
||||
Mainform.StartNewMovie(MovieService.Get(ofd.FileName), false);
|
||||
|
||||
var result1 = MessageBox.Show("This is a regular movie, a new project must be created from it, in order to use in TAStudio\nProceed?", "Convert movie", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
|
||||
if (result1 == DialogResult.OK)
|
||||
{
|
||||
Mainform.StartNewMovie(MovieService.Get(ofd.FileName), false);
|
||||
ConvertCurrentMovieToTasproj();
|
||||
StartNewMovieWrapper(false);
|
||||
SetUpColumns();
|
||||
|
|
|
@ -829,7 +829,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
if (frame == Emulator.Frame)
|
||||
return;
|
||||
|
||||
_shouldUnpauseFromRewind = fromRewinding && !Mainform.EmulatorPaused;
|
||||
_unpauseAfterSeeking = (fromRewinding || WasRecording) && !Mainform.EmulatorPaused;
|
||||
TastudioPlayMode();
|
||||
KeyValuePair<int, byte[]> closestState = CurrentTasMovie.TasStateManager.GetStateClosestToFrame(frame);
|
||||
if (closestState.Value != null && (frame < Emulator.Frame || closestState.Key > Emulator.Frame))
|
||||
|
@ -871,7 +871,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
// frame == Emulator.Frame when frame == 0
|
||||
if (frame > Emulator.Frame)
|
||||
{
|
||||
if (Mainform.EmulatorPaused || Mainform.IsSeeking || fromRewinding) // make seek frame keep up with emulation on fast scrolls
|
||||
// make seek frame keep up with emulation on fast scrolls
|
||||
if (Mainform.EmulatorPaused || Mainform.IsSeeking || fromRewinding || WasRecording)
|
||||
{
|
||||
StartSeeking(frame);
|
||||
}
|
||||
|
|
|
@ -94,6 +94,8 @@ namespace BizHawk.Emulation.Common
|
|||
public uint? Address => null;
|
||||
|
||||
public uint? AddressMask => null;
|
||||
|
||||
public string Scope => ""; // This will be relevant if/when the trace logger can trace anything other than the system bus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,14 @@ namespace BizHawk.Emulation.Common
|
|||
/// <seealso cref="IMemoryCallbackSystem" />
|
||||
public class MemoryCallbackSystem : IMemoryCallbackSystem
|
||||
{
|
||||
public MemoryCallbackSystem()
|
||||
public MemoryCallbackSystem(string[] availableScopes)
|
||||
{
|
||||
if (availableScopes == null)
|
||||
{
|
||||
availableScopes = new[] { "System Bus" };
|
||||
}
|
||||
|
||||
AvailableScopes = availableScopes;
|
||||
ExecuteCallbacksAvailable = true;
|
||||
|
||||
_reads.CollectionChanged += OnCollectionChanged;
|
||||
|
@ -35,8 +41,15 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
public bool ExecuteCallbacksAvailable { get; }
|
||||
|
||||
public string[] AvailableScopes { get; }
|
||||
|
||||
public void Add(IMemoryCallback callback)
|
||||
{
|
||||
if (!AvailableScopes.Contains(callback.Scope))
|
||||
{
|
||||
throw new InvalidOperationException($"{callback.Scope} is not currently supported for callbacks");
|
||||
}
|
||||
|
||||
switch (callback.Type)
|
||||
{
|
||||
case MemoryCallbackType.Execute:
|
||||
|
@ -61,38 +74,38 @@ namespace BizHawk.Emulation.Common
|
|||
_empty = false;
|
||||
}
|
||||
|
||||
private static void Call(ObservableCollection<IMemoryCallback> cbs, uint addr)
|
||||
private static void Call(ObservableCollection<IMemoryCallback> cbs, uint addr, string scope)
|
||||
{
|
||||
for (int i = 0; i < cbs.Count; i++)
|
||||
{
|
||||
if (!cbs[i].Address.HasValue || cbs[i].Address == (addr & cbs[i].AddressMask))
|
||||
if (!cbs[i].Address.HasValue || (cbs[i].Scope == scope && cbs[i].Address == (addr & cbs[i].AddressMask)))
|
||||
{
|
||||
cbs[i].Callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CallReads(uint addr)
|
||||
public void CallReads(uint addr, string scope)
|
||||
{
|
||||
if (_hasReads)
|
||||
{
|
||||
Call(_reads, addr);
|
||||
Call(_reads, addr, scope);
|
||||
}
|
||||
}
|
||||
|
||||
public void CallWrites(uint addr)
|
||||
public void CallWrites(uint addr, string scope)
|
||||
{
|
||||
if (_hasWrites)
|
||||
{
|
||||
Call(_writes, addr);
|
||||
Call(_writes, addr, scope);
|
||||
}
|
||||
}
|
||||
|
||||
public void CallExecutes(uint addr)
|
||||
public void CallExecutes(uint addr, string scope)
|
||||
{
|
||||
if (_hasExecutes)
|
||||
{
|
||||
Call(_execs, addr);
|
||||
Call(_execs, addr, scope);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,6 +115,21 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
public bool HasExecutes => _hasExecutes;
|
||||
|
||||
public bool HasReadsForScope(string scope)
|
||||
{
|
||||
return _reads.Where(e => e.Scope == scope).Any();
|
||||
}
|
||||
|
||||
public bool HasWritesForScope(string scope)
|
||||
{
|
||||
return _writes.Where(e => e.Scope == scope).Any();
|
||||
}
|
||||
|
||||
public bool HasExecutesForScope(string scope)
|
||||
{
|
||||
return _execs.Where(e => e.Scope == scope).Any();
|
||||
}
|
||||
|
||||
private void UpdateHasVariables()
|
||||
{
|
||||
_hasReads = _reads.Count > 0;
|
||||
|
@ -273,7 +301,7 @@ namespace BizHawk.Emulation.Common
|
|||
|
||||
public class MemoryCallback : IMemoryCallback
|
||||
{
|
||||
public MemoryCallback(MemoryCallbackType type, string name, Action callback, uint? address, uint? mask)
|
||||
public MemoryCallback(string scope, MemoryCallbackType type, string name, Action callback, uint? address, uint? mask)
|
||||
{
|
||||
if (type == MemoryCallbackType.Execute && !address.HasValue)
|
||||
{
|
||||
|
@ -285,6 +313,7 @@ namespace BizHawk.Emulation.Common
|
|||
Callback = callback;
|
||||
Address = address;
|
||||
AddressMask = mask ?? 0xFFFFFFFF;
|
||||
Scope = scope;
|
||||
}
|
||||
|
||||
public MemoryCallbackType Type { get; }
|
||||
|
@ -292,5 +321,6 @@ namespace BizHawk.Emulation.Common
|
|||
public Action Callback { get; }
|
||||
public uint? Address { get; }
|
||||
public uint? AddressMask { get; }
|
||||
public string Scope { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,20 @@ namespace BizHawk.Emulation.Common
|
|||
}
|
||||
}
|
||||
|
||||
public class NoAvailableCoreException : Exception
|
||||
{
|
||||
public NoAvailableCoreException()
|
||||
: base("System is currently NOT emulated")
|
||||
{
|
||||
}
|
||||
|
||||
public NoAvailableCoreException(string message)
|
||||
: base ("System is currently NOT emulated: " + message)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class CGBNotSupportedException : Exception
|
||||
{
|
||||
public CGBNotSupportedException()
|
||||
|
|
|
@ -37,27 +37,49 @@ namespace BizHawk.Emulation.Common
|
|||
/// </summary>
|
||||
bool HasExecutes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not there are currently any read hooks
|
||||
/// </summary>
|
||||
bool HasReadsForScope(string scope);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not there are currently any write hooks
|
||||
/// </summary>
|
||||
bool HasWritesForScope(string scope);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not there are currently any execute hooks
|
||||
/// </summary>
|
||||
bool HasExecutesForScope(string scope);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a callback for the given type to the given address
|
||||
/// If no address is specified the callback will be hooked to all addresses
|
||||
/// Note: an execute callback can not be added without an address, else an InvalidOperationException will occur
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidCastException">Thrown when the <see cref="IMemoryCallback.Scope"/> property of the <see cref="IMemoryCallback"/> is not in the <see cref="AvailableScopes"/></exception>
|
||||
void Add(IMemoryCallback callback);
|
||||
|
||||
/// <summary>
|
||||
/// Executes all Read callbacks for the given address
|
||||
/// Executes all Read callbacks for the given address and domain
|
||||
/// </summary>
|
||||
void CallReads(uint addr);
|
||||
/// <param name="addr">The address to check for callbacks</param>
|
||||
/// <param name="scope">The scope that the address pertains to. Must be a value in <see cref="AvailableScopes"></param>
|
||||
void CallReads(uint addr, string scope);
|
||||
|
||||
/// <summary>
|
||||
/// Executes all Write callbacks for the given address
|
||||
/// Executes all Write callbacks for the given address and domain
|
||||
/// </summary>
|
||||
void CallWrites(uint addr);
|
||||
/// <param name="addr">The address to check for callbacks</param>
|
||||
/// <param name="scope">The scope that the address pertains to. Must be a value in <see cref="AvailableScopes"></param>
|
||||
void CallWrites(uint addr, string scope);
|
||||
|
||||
/// <summary>
|
||||
/// Executes all Execute callbacks for the given address
|
||||
/// Executes all Execute callbacks for the given address and domain
|
||||
/// </summary>
|
||||
void CallExecutes(uint addr);
|
||||
/// <param name="addr">The address to check for callbacks</param>
|
||||
/// <param name="scope">The scope that the address pertains to. Must be a value in <see cref="AvailableScopes"></param>
|
||||
void CallExecutes(uint addr, string scope);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the given callback from the list
|
||||
|
@ -73,6 +95,12 @@ namespace BizHawk.Emulation.Common
|
|||
/// Removes all read,write, and execute callbacks
|
||||
/// </summary>
|
||||
void Clear();
|
||||
|
||||
/// <summary>
|
||||
/// A list of available "scopes" (memory domains, cpus, etc) that a the <see cref="IMemoryCallback.Scope"/> property of the <see cref="IMemoryCallback"/> can have
|
||||
/// Passing a <see cref="IMemoryCallback"/> into the <see cref="Add(IMemoryCallback)"/> method that is not in this list will result in an <seealso cref="InvalidOperationException"/>
|
||||
/// </summary>
|
||||
string[] AvailableScopes { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -86,6 +114,7 @@ namespace BizHawk.Emulation.Common
|
|||
Action Callback { get; }
|
||||
uint? Address { get; }
|
||||
uint? AddressMask { get; }
|
||||
string Scope { get; }
|
||||
}
|
||||
|
||||
public enum MemoryCallbackType
|
||||
|
|
|
@ -365,7 +365,7 @@
|
|||
</Compile>
|
||||
<Compile Include="Consoles\Atari\A7800Hawk\M6532.cs" />
|
||||
<Compile Include="Consoles\Atari\A7800Hawk\Maria.cs" />
|
||||
<Compile Include="Consoles\Atari\A7800Hawk\Pokey.cs" />
|
||||
<Compile Include="Consoles\Atari\A7800Hawk\Pokey.cs" />
|
||||
<Compile Include="Consoles\Atari\A7800Hawk\TIA_Sound\Tia.Audio.cs" />
|
||||
<Compile Include="Consoles\Atari\A7800Hawk\TIA_Sound\TIA.cs" />
|
||||
<Compile Include="Consoles\Atari\A7800Hawk\TIA_Sound\Tia.SyncState.cs" />
|
||||
|
@ -463,6 +463,9 @@
|
|||
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.IEmulator.cs">
|
||||
<DependentUpon>Gambatte.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.ILinkable.cs">
|
||||
<DependentUpon>Gambatte.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\Gameboy\Gambatte.IMemoryDomains.cs">
|
||||
<DependentUpon>Gambatte.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -749,6 +752,7 @@
|
|||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\Mapper049.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\Mapper052.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\Mapper074.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\Mapper114.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\Mapper115.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\Mapper121.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\MMC3_family\Mapper123.cs" />
|
||||
|
@ -877,6 +881,9 @@
|
|||
<Compile Include="Consoles\Nintendo\NES\NES.IDriveLight.cs">
|
||||
<DependentUpon>NES.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\NES\NES.ICodeDataLogger.cs">
|
||||
<DependentUpon>NES.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Consoles\Nintendo\NES\NES.IInputPollable.cs">
|
||||
<DependentUpon>NES.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -1068,6 +1075,8 @@
|
|||
<Compile Include="Consoles\Sega\Saturn\LibSaturnus.cs" />
|
||||
<Compile Include="Consoles\Sega\Saturn\Saturnus.cs" />
|
||||
<Compile Include="Consoles\Sega\Saturn\SaturnusControllerDeck.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\EEPROM.93c46.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\MemoryMap.EEPROM.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\SMS.cs" />
|
||||
<Compile Include="Consoles\Sega\SMS\SMS.ICodeDataLogger.cs">
|
||||
<DependentUpon>SMS.cs</DependentUpon>
|
||||
|
@ -1183,12 +1192,14 @@
|
|||
<Compile Include="CPUs\Z80-GB\Registers.cs" />
|
||||
<Compile Include="CPUs\Z80-GB\Tables.cs" />
|
||||
<Compile Include="CPUs\Z80-GB\Z80.cs" />
|
||||
<Compile Include="CPUs\Z80\Disassembler.cs" />
|
||||
<Compile Include="CPUs\Z80\Execute.cs" />
|
||||
<Compile Include="CPUs\Z80\Interrupts.cs" />
|
||||
<Compile Include="CPUs\Z80\Registers.cs" />
|
||||
<Compile Include="CPUs\Z80\Tables.cs" />
|
||||
<Compile Include="CPUs\Z80\Z80A.cs" />
|
||||
<Compile Include="CPUs\Z80A\NewDisassembler.cs" />
|
||||
<Compile Include="CPUs\Z80A\Execute.cs" />
|
||||
<Compile Include="CPUs\Z80A\Interrupts.cs" />
|
||||
<Compile Include="CPUs\Z80A\Registers.cs" />
|
||||
<Compile Include="CPUs\Z80A\Operations.cs" />
|
||||
<Compile Include="CPUs\Z80A\Tables_Direct.cs" />
|
||||
<Compile Include="CPUs\Z80A\Tables_Indirect.cs" />
|
||||
<Compile Include="CPUs\Z80A\Z80A.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
|
|
|
@ -192,7 +192,7 @@ namespace BizHawk.Emulation.Cores.Components.CP1610
|
|||
|
||||
if (MemoryCallbacks != null)
|
||||
{
|
||||
MemoryCallbacks.CallExecutes(RegisterPC);
|
||||
MemoryCallbacks.CallExecutes(RegisterPC, "System Bus");
|
||||
}
|
||||
|
||||
switch (opcode)
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace BizHawk.Emulation.Cores.Components.CP1610
|
|||
{
|
||||
if (MemoryCallbacks != null && !peek)
|
||||
{
|
||||
MemoryCallbacks.CallReads(addr);
|
||||
MemoryCallbacks.CallReads(addr, "System Bus");
|
||||
}
|
||||
|
||||
return ReadMemory(addr, peek);
|
||||
|
@ -41,7 +41,7 @@ namespace BizHawk.Emulation.Cores.Components.CP1610
|
|||
{
|
||||
if (MemoryCallbacks != null && !poke)
|
||||
{
|
||||
MemoryCallbacks.CallWrites(addr);
|
||||
MemoryCallbacks.CallWrites(addr, "System Bus");
|
||||
}
|
||||
|
||||
WriteMemory(addr, value, poke);
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280
|
|||
LagIFlag = FlagI;
|
||||
|
||||
if (Debug) Logger(State());
|
||||
MemoryCallbacks.CallExecutes(PC);
|
||||
MemoryCallbacks.CallExecutes(PC, "System Bus");
|
||||
|
||||
if (CDL != null && CDL.Active) CDLOpcode();
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280
|
|||
{
|
||||
byte page = MPR[address >> 13];
|
||||
var result = ReadMemory21((page << 13) | (address & 0x1FFF));
|
||||
MemoryCallbacks.CallReads(address);
|
||||
MemoryCallbacks.CallReads(address, "System Bus");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280
|
|||
{
|
||||
byte page = MPR[address >> 13];
|
||||
WriteMemory21((page << 13) | (address & 0x1FFF), value);
|
||||
MemoryCallbacks.CallWrites(address);
|
||||
MemoryCallbacks.CallWrites(address, "System Bus");
|
||||
}
|
||||
|
||||
private ushort ReadWord(ushort address)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,55 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
private bool iff1;
|
||||
public bool IFF1 { get { return iff1; } set { iff1 = value; } }
|
||||
|
||||
private bool iff2;
|
||||
public bool IFF2 { get { return iff2; } set { iff2 = value; } }
|
||||
|
||||
private bool interrupt;
|
||||
public bool Interrupt { get { return interrupt; } set { interrupt = value; } }
|
||||
|
||||
private bool nonMaskableInterrupt;
|
||||
public bool NonMaskableInterrupt
|
||||
{
|
||||
get { return nonMaskableInterrupt; }
|
||||
set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; }
|
||||
}
|
||||
|
||||
private bool nonMaskableInterruptPending;
|
||||
public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } }
|
||||
|
||||
private int interruptMode;
|
||||
public int InterruptMode
|
||||
{
|
||||
get { return interruptMode; }
|
||||
set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; }
|
||||
}
|
||||
|
||||
private bool halted;
|
||||
public bool Halted { get { return halted; } set { halted = value; } }
|
||||
|
||||
public Action IRQCallback = delegate() { };
|
||||
public Action NMICallback = delegate() { };
|
||||
|
||||
private void ResetInterrupts()
|
||||
{
|
||||
IFF1 = false;
|
||||
IFF2 = false;
|
||||
Interrupt = false;
|
||||
NonMaskableInterrupt = false;
|
||||
NonMaskableInterruptPending = false;
|
||||
InterruptMode = 1;
|
||||
Halted = false;
|
||||
}
|
||||
|
||||
private void Halt()
|
||||
{
|
||||
Halted = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,270 +0,0 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
[Serializable()]
|
||||
public struct RegisterPair
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public ushort Word;
|
||||
|
||||
[FieldOffset(0)]
|
||||
public byte Low;
|
||||
|
||||
[FieldOffset(1)]
|
||||
public byte High;
|
||||
|
||||
public RegisterPair(ushort value)
|
||||
{
|
||||
Word = value;
|
||||
Low = (byte)(Word);
|
||||
High = (byte)(Word >> 8);
|
||||
}
|
||||
|
||||
public static implicit operator ushort(RegisterPair rp)
|
||||
{
|
||||
return rp.Word;
|
||||
}
|
||||
|
||||
public static implicit operator RegisterPair(ushort value)
|
||||
{
|
||||
return new RegisterPair(value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool RegFlagC
|
||||
{
|
||||
get { return (RegAF.Low & 0x01) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x01) | (value ? 0x01 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagN
|
||||
{
|
||||
get { return (RegAF.Low & 0x02) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x02) | (value ? 0x02 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagP
|
||||
{
|
||||
get { return (RegAF.Low & 0x04) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x04) | (value ? 0x04 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlag3
|
||||
{
|
||||
get { return (RegAF.Low & 0x08) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x08) | (value ? 0x08 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagH
|
||||
{
|
||||
get { return (RegAF.Low & 0x10) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x10) | (value ? 0x10 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlag5
|
||||
{
|
||||
get { return (RegAF.Low & 0x20) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x20) | (value ? 0x20 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagZ
|
||||
{
|
||||
get { return (RegAF.Low & 0x40) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x40) | (value ? 0x40 : 0x00)); }
|
||||
}
|
||||
|
||||
private bool RegFlagS
|
||||
{
|
||||
get { return (RegAF.Low & 0x80) != 0; }
|
||||
set { RegAF.Low = (byte)((RegAF.Low & ~0x80) | (value ? 0x80 : 0x00)); }
|
||||
}
|
||||
|
||||
private RegisterPair RegAF;
|
||||
private RegisterPair RegBC;
|
||||
private RegisterPair RegDE;
|
||||
private RegisterPair RegHL;
|
||||
private RegisterPair RegWZ;
|
||||
|
||||
private RegisterPair RegAltAF; // Shadow for A and F
|
||||
private RegisterPair RegAltBC; // Shadow for B and C
|
||||
private RegisterPair RegAltDE; // Shadow for D and E
|
||||
private RegisterPair RegAltHL; // Shadow for H and L
|
||||
// NOTE: There is no AltWZ register (despite it being shown on various block diagrams)
|
||||
|
||||
private byte RegI; // I (interrupt vector)
|
||||
private byte RegR; // R (memory refresh)
|
||||
|
||||
private RegisterPair RegIX; // IX (index register x)
|
||||
private RegisterPair RegIY; // IY (index register y)
|
||||
|
||||
private RegisterPair RegSP; // SP (stack pointer)
|
||||
private RegisterPair RegPC; // PC (program counter)
|
||||
|
||||
private void ResetRegisters()
|
||||
{
|
||||
// Clear main registers
|
||||
RegAF = 0; RegBC = 0; RegDE = 0; RegHL = 0; RegWZ = 0;
|
||||
// Clear alternate registers
|
||||
RegAltAF = 0; RegAltBC = 0; RegAltDE = 0; RegAltHL = 0;
|
||||
// Clear special purpose registers
|
||||
RegI = 0; RegR = 0;
|
||||
RegIX.Word = 0; RegIY.Word = 0;
|
||||
RegSP.Word = 0; RegPC.Word = 0;
|
||||
}
|
||||
|
||||
public byte RegisterA
|
||||
{
|
||||
get { return RegAF.High; }
|
||||
set { RegAF.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterF
|
||||
{
|
||||
get { return RegAF.Low; }
|
||||
set { RegAF.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterAF
|
||||
{
|
||||
get { return RegAF.Word; }
|
||||
set { RegAF.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterB
|
||||
{
|
||||
get { return RegBC.High; }
|
||||
set { RegBC.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterC
|
||||
{
|
||||
get { return RegBC.Low; }
|
||||
set { RegBC.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterBC
|
||||
{
|
||||
get { return RegBC.Word; }
|
||||
set { RegBC.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterD
|
||||
{
|
||||
get { return RegDE.High; }
|
||||
set { RegDE.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterE
|
||||
{
|
||||
get { return RegDE.Low; }
|
||||
set { RegDE.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterDE
|
||||
{
|
||||
get { return RegDE.Word; }
|
||||
set { RegDE.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterH
|
||||
{
|
||||
get { return RegHL.High; }
|
||||
set { RegHL.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterL
|
||||
{
|
||||
get { return RegHL.Low; }
|
||||
set { RegHL.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterHL
|
||||
{
|
||||
get { return RegHL.Word; }
|
||||
set { RegHL.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterW
|
||||
{
|
||||
get { return RegWZ.High; }
|
||||
set { RegWZ.High = value; }
|
||||
}
|
||||
|
||||
public byte RegisterZ
|
||||
{
|
||||
get { return RegWZ.Low; }
|
||||
set { RegWZ.Low = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterWZ
|
||||
{
|
||||
get { return RegWZ.Word; }
|
||||
set { RegWZ.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterPC
|
||||
{
|
||||
get { return RegPC.Word; }
|
||||
set { RegPC.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterSP
|
||||
{
|
||||
get { return RegSP.Word; }
|
||||
set { RegSP.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterIX
|
||||
{
|
||||
get { return RegIX.Word; }
|
||||
set { RegIX.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterIY
|
||||
{
|
||||
get { return RegIY.Word; }
|
||||
set { RegIY.Word = value; }
|
||||
}
|
||||
|
||||
public byte RegisterI
|
||||
{
|
||||
get { return RegI; }
|
||||
set { RegI = value; }
|
||||
}
|
||||
|
||||
public byte RegisterR
|
||||
{
|
||||
get { return RegR; }
|
||||
set { RegR = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterShadowAF
|
||||
{
|
||||
get { return RegAltAF.Word; }
|
||||
set { RegAltAF.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterShadowBC
|
||||
{
|
||||
get { return RegAltBC.Word; }
|
||||
set { RegAltBC.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterShadowDE
|
||||
{
|
||||
get { return RegAltDE.Word; }
|
||||
set { RegAltDE.Word = value; }
|
||||
}
|
||||
|
||||
public ushort RegisterShadowHL
|
||||
{
|
||||
get { return RegAltHL.Word; }
|
||||
set { RegAltHL.Word = value; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,331 +0,0 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
private void InitialiseTables()
|
||||
{
|
||||
InitTableInc();
|
||||
InitTableDec();
|
||||
InitTableParity();
|
||||
InitTableALU();
|
||||
InitTableRotShift();
|
||||
InitTableHalfBorrow();
|
||||
InitTableHalfCarry();
|
||||
InitTableNeg();
|
||||
InitTableDaa();
|
||||
}
|
||||
|
||||
private byte[] TableInc;
|
||||
private void InitTableInc()
|
||||
{
|
||||
TableInc = new byte[256];
|
||||
for (int i = 0; i < 256; ++i)
|
||||
TableInc[i] = FlagByte(false, false, i == 0x80, UndocumentedX(i), (i & 0xF) == 0x0, UndocumentedY(i), i == 0, i > 127);
|
||||
}
|
||||
|
||||
private byte[] TableDec;
|
||||
private void InitTableDec()
|
||||
{
|
||||
TableDec = new byte[256];
|
||||
for (int i = 0; i < 256; ++i)
|
||||
TableDec[i] = FlagByte(false, true, i == 0x7F, UndocumentedX(i), (i & 0xF) == 0xF, UndocumentedY(i), i == 0, i > 127);
|
||||
}
|
||||
|
||||
private bool[] TableParity;
|
||||
private void InitTableParity()
|
||||
{
|
||||
TableParity = new bool[256];
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
int Bits = 0;
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
Bits += (i >> j) & 1;
|
||||
}
|
||||
TableParity[i] = (Bits & 1) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
private ushort[, , ,] TableALU;
|
||||
private void InitTableALU()
|
||||
{
|
||||
TableALU = new ushort[8, 256, 256, 2]; // Class, OP1, OP2, Carry
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
for (int op1 = 0; op1 < 256; ++op1)
|
||||
{
|
||||
for (int op2 = 0; op2 < 256; ++op2)
|
||||
{
|
||||
for (int c = 0; c < 2; ++c)
|
||||
{
|
||||
|
||||
int ac = (i == 1 || i == 3) ? c : 0;
|
||||
|
||||
bool S = false;
|
||||
bool Z = false;
|
||||
bool C = false;
|
||||
bool H = false;
|
||||
bool N = false;
|
||||
bool P = false;
|
||||
|
||||
byte result_b = 0;
|
||||
int result_si = 0;
|
||||
int result_ui = 0;
|
||||
|
||||
// Fetch result
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
result_si = (sbyte)op1 + (sbyte)op2 + ac;
|
||||
result_ui = op1 + op2 + ac;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 7:
|
||||
result_si = (sbyte)op1 - (sbyte)op2 - ac;
|
||||
result_ui = op1 - op2 - ac;
|
||||
break;
|
||||
case 4:
|
||||
result_si = op1 & op2;
|
||||
break;
|
||||
case 5:
|
||||
result_si = op1 ^ op2;
|
||||
break;
|
||||
case 6:
|
||||
result_si = op1 | op2;
|
||||
break;
|
||||
}
|
||||
|
||||
result_b = (byte)result_si;
|
||||
|
||||
// Parity/Carry
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 7:
|
||||
P = result_si < -128 || result_si > 127;
|
||||
C = result_ui < 0 || result_ui > 255;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
P = TableParity[result_b];
|
||||
C = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Subtraction
|
||||
N = i == 2 || i == 3 || i == 7;
|
||||
|
||||
// Half carry
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
H = ((op1 & 0xF) + (op2 & 0xF) + (ac & 0xF)) > 0xF;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 7:
|
||||
H = ((op1 & 0xF) - (op2 & 0xF) - (ac & 0xF)) < 0x0;
|
||||
break;
|
||||
case 4:
|
||||
H = true;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
H = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Undocumented
|
||||
byte UndocumentedFlags = (byte)(result_b & 0x28);
|
||||
if (i == 7) UndocumentedFlags = (byte)(op2 & 0x28);
|
||||
|
||||
S = result_b > 127;
|
||||
Z = result_b == 0;
|
||||
|
||||
if (i == 7) result_b = (byte)op1;
|
||||
|
||||
TableALU[i, op1, op2, c] = (ushort)(
|
||||
result_b * 256 +
|
||||
((C ? 0x01 : 0) + (N ? 0x02 : 0) + (P ? 0x04 : 0) + (H ? 0x10 : 0) + (Z ? 0x40 : 0) + (S ? 0x80 : 0)) +
|
||||
(UndocumentedFlags));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool[,] TableHalfBorrow;
|
||||
private void InitTableHalfBorrow()
|
||||
{
|
||||
TableHalfBorrow = new bool[256, 256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
TableHalfBorrow[i, j] = ((i & 0xF) - (j & 0xF)) < 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool[,] TableHalfCarry;
|
||||
private void InitTableHalfCarry()
|
||||
{
|
||||
TableHalfCarry = new bool[256, 256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
for (int j = 0; j < 256; j++)
|
||||
{
|
||||
TableHalfCarry[i, j] = ((i & 0xF) + (j & 0xF)) > 0xF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ushort[, ,] TableRotShift;
|
||||
private void InitTableRotShift()
|
||||
{
|
||||
TableRotShift = new ushort[2, 8, 65536]; // All, operation, AF
|
||||
for (int all = 0; all < 2; all++)
|
||||
{
|
||||
for (int y = 0; y < 8; ++y)
|
||||
{
|
||||
for (int af = 0; af < 65536; af++)
|
||||
{
|
||||
byte Old = (byte)(af >> 8);
|
||||
bool OldCarry = (af & 0x01) != 0;
|
||||
|
||||
ushort newAf = (ushort)(af & ~(0x13)); // Clear HALF-CARRY, SUBTRACT and CARRY flags
|
||||
|
||||
byte New = Old;
|
||||
if ((y & 1) == 0)
|
||||
{
|
||||
if ((Old & 0x80) != 0) ++newAf;
|
||||
|
||||
New <<= 1;
|
||||
|
||||
if ((y & 0x04) == 0)
|
||||
{
|
||||
if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((y & 0x02) != 0) New |= 0x01;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if ((Old & 0x01) != 0) ++newAf;
|
||||
|
||||
New >>= 1;
|
||||
|
||||
if ((y & 0x04) == 0)
|
||||
{
|
||||
if (((y & 0x02) == 0) ? ((newAf & 0x01) != 0) : OldCarry) New |= 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((y & 0x02) == 0) New |= (byte)(Old & 0x80);
|
||||
}
|
||||
}
|
||||
|
||||
newAf &= 0xFF;
|
||||
newAf |= (ushort)(New * 256);
|
||||
|
||||
if (all == 1)
|
||||
{
|
||||
newAf &= unchecked((ushort)~0xC4); // Clear S, Z, P
|
||||
if (New > 127) newAf |= 0x80;
|
||||
if (New == 0) newAf |= 0x40;
|
||||
if (TableParity[New]) newAf |= 0x04;
|
||||
}
|
||||
|
||||
TableRotShift[all, y, af] = (ushort)((newAf & ~0x28) | ((newAf >> 8) & 0x28));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ushort[] TableNeg;
|
||||
private void InitTableNeg()
|
||||
{
|
||||
TableNeg = new ushort[65536];
|
||||
for (int af = 0; af < 65536; af++)
|
||||
{
|
||||
ushort raf = 0;
|
||||
byte b = (byte)(af >> 8);
|
||||
byte a = (byte)-b;
|
||||
raf |= (ushort)(a * 256);
|
||||
raf |= FlagByte(b != 0x00, true, b == 0x80, UndocumentedX(a), TableHalfCarry[a, b], UndocumentedY(a), a == 0, a > 127);
|
||||
TableNeg[af] = raf;
|
||||
}
|
||||
}
|
||||
|
||||
private ushort[] TableDaa;
|
||||
private void InitTableDaa()
|
||||
{
|
||||
TableDaa = new ushort[65536];
|
||||
for (int af = 0; af < 65536; ++af)
|
||||
{
|
||||
byte a = (byte)(af >> 8);
|
||||
byte tmp = a;
|
||||
|
||||
if (IsN(af))
|
||||
{
|
||||
if (IsH(af) || ((a & 0x0F) > 0x09)) tmp -= 0x06;
|
||||
if (IsC(af) || a > 0x99) tmp -= 0x60;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsH(af) || ((a & 0x0F) > 0x09)) tmp += 0x06;
|
||||
if (IsC(af) || a > 0x99) tmp += 0x60;
|
||||
}
|
||||
|
||||
TableDaa[af] = (ushort)((tmp * 256) + FlagByte(IsC(af) || a > 0x99, IsN(af), TableParity[tmp], UndocumentedX(tmp), ((a ^ tmp) & 0x10) != 0, UndocumentedY(tmp), tmp == 0, tmp > 127));
|
||||
}
|
||||
}
|
||||
|
||||
private byte FlagByte(bool C, bool N, bool P, bool X, bool H, bool Y, bool Z, bool S)
|
||||
{
|
||||
return (byte)(
|
||||
(C ? 0x01 : 0) +
|
||||
(N ? 0x02 : 0) +
|
||||
(P ? 0x04 : 0) +
|
||||
(X ? 0x08 : 0) +
|
||||
(H ? 0x10 : 0) +
|
||||
(Y ? 0x20 : 0) +
|
||||
(Z ? 0x40 : 0) +
|
||||
(S ? 0x80 : 0)
|
||||
);
|
||||
}
|
||||
|
||||
private bool UndocumentedX(int value)
|
||||
{
|
||||
return (value & 0x08) != 0;
|
||||
}
|
||||
|
||||
private bool UndocumentedY(int value)
|
||||
{
|
||||
return (value & 0x20) != 0;
|
||||
}
|
||||
|
||||
private bool IsC(int value) { return (value & 0x01) != 0; }
|
||||
private bool IsN(int value) { return (value & 0x02) != 0; }
|
||||
private bool IsP(int value) { return (value & 0x04) != 0; }
|
||||
private bool IsX(int value) { return (value & 0x08) != 0; }
|
||||
private bool IsH(int value) { return (value & 0x10) != 0; }
|
||||
private bool IsY(int value) { return (value & 0x20) != 0; }
|
||||
private bool IsZ(int value) { return (value & 0x40) != 0; }
|
||||
private bool IsS(int value) { return (value & 0x80) != 0; }
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
// This Z80 emulator is a modified version of Ben Ryves 'Brazil' emulator.
|
||||
// It is MIT licensed.
|
||||
|
||||
// for WZ register details, see: http://www.grimware.org/lib/exe/fetch.php/documentations/devices/z80/z80.memptr.eng.txt
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80
|
||||
{
|
||||
public sealed partial class Z80A
|
||||
{
|
||||
public Z80A()
|
||||
{
|
||||
InitialiseTables();
|
||||
Reset();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
PendingCycles = 0;
|
||||
ExpectedExecutedCycles = 0;
|
||||
TotalExecutedCycles = 0;
|
||||
}
|
||||
|
||||
public void SoftReset()
|
||||
{
|
||||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
}
|
||||
|
||||
// Memory Access
|
||||
|
||||
public Func<ushort, bool, byte> FetchMemory;
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
|
||||
public byte ReadMemoryWrapper(ushort addr)
|
||||
{
|
||||
if (MemoryCallbacks != null)
|
||||
{
|
||||
MemoryCallbacks.CallReads(addr);
|
||||
}
|
||||
|
||||
return ReadMemory(addr);
|
||||
}
|
||||
|
||||
public byte FetchFirstMemoryWrapper(ushort addr)
|
||||
{
|
||||
if (MemoryCallbacks != null)
|
||||
{
|
||||
MemoryCallbacks.CallReads(addr);
|
||||
}
|
||||
|
||||
if (FetchMemory != null)
|
||||
{
|
||||
return FetchMemory(addr, true);
|
||||
}
|
||||
|
||||
return ReadMemory(addr);
|
||||
}
|
||||
|
||||
public byte FetchMemoryWrapper(ushort addr)
|
||||
{
|
||||
if (MemoryCallbacks != null)
|
||||
{
|
||||
MemoryCallbacks.CallReads(addr);
|
||||
}
|
||||
|
||||
if (FetchMemory != null)
|
||||
{
|
||||
return FetchMemory(addr, false);
|
||||
}
|
||||
|
||||
return ReadMemory(addr);
|
||||
}
|
||||
|
||||
public void WriteMemoryWrapper(ushort addr, byte value)
|
||||
{
|
||||
if (MemoryCallbacks != null)
|
||||
{
|
||||
MemoryCallbacks.CallWrites(addr);
|
||||
}
|
||||
|
||||
WriteMemory(addr, value);
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; set; }
|
||||
|
||||
// Utility function, not used by core
|
||||
public ushort ReadWord(ushort addr)
|
||||
{
|
||||
ushort value = ReadMemory(addr++);
|
||||
value |= (ushort)(ReadMemory(addr) << 8);
|
||||
return value;
|
||||
}
|
||||
|
||||
// Hardware I/O Port Access
|
||||
|
||||
public Func<ushort, byte> ReadHardware;
|
||||
public Action<ushort, byte> WriteHardware;
|
||||
|
||||
// State Save/Load
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("Z80");
|
||||
ser.Sync("AF", ref RegAF.Word);
|
||||
ser.Sync("BC", ref RegBC.Word);
|
||||
ser.Sync("DE", ref RegDE.Word);
|
||||
ser.Sync("HL", ref RegHL.Word);
|
||||
ser.Sync("WZ", ref RegWZ.Word);
|
||||
ser.Sync("ShadowAF", ref RegAltAF.Word);
|
||||
ser.Sync("ShadowBC", ref RegAltBC.Word);
|
||||
ser.Sync("ShadowDE", ref RegAltDE.Word);
|
||||
ser.Sync("ShadowHL", ref RegAltHL.Word);
|
||||
ser.Sync("I", ref RegI);
|
||||
ser.Sync("R", ref RegR);
|
||||
ser.Sync("IX", ref RegIX.Word);
|
||||
ser.Sync("IY", ref RegIY.Word);
|
||||
ser.Sync("SP", ref RegSP.Word);
|
||||
ser.Sync("PC", ref RegPC.Word);
|
||||
ser.Sync("IRQ", ref interrupt);
|
||||
ser.Sync("NMI", ref nonMaskableInterrupt);
|
||||
ser.Sync("NMIPending", ref nonMaskableInterruptPending);
|
||||
ser.Sync("IM", ref interruptMode);
|
||||
ser.Sync("IFF1", ref iff1);
|
||||
ser.Sync("IFF2", ref iff2);
|
||||
ser.Sync("Halted", ref halted);
|
||||
ser.Sync("ExecutedCycles", ref totalExecutedCycles);
|
||||
ser.Sync("PendingCycles", ref pendingCycles);
|
||||
ser.Sync("EI_pending", ref EI_pending);
|
||||
ser.EndSection();
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,123 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
private bool iff1;
|
||||
public bool IFF1 { get { return iff1; } set { iff1 = value; } }
|
||||
|
||||
private bool iff2;
|
||||
public bool IFF2 { get { return iff2; } set { iff2 = value; } }
|
||||
|
||||
private bool nonMaskableInterrupt;
|
||||
public bool NonMaskableInterrupt
|
||||
{
|
||||
get { return nonMaskableInterrupt; }
|
||||
set { if (value && !nonMaskableInterrupt) NonMaskableInterruptPending = true; nonMaskableInterrupt = value; }
|
||||
}
|
||||
|
||||
private bool nonMaskableInterruptPending;
|
||||
public bool NonMaskableInterruptPending { get { return nonMaskableInterruptPending; } set { nonMaskableInterruptPending = value; } }
|
||||
|
||||
private int interruptMode;
|
||||
public int InterruptMode
|
||||
{
|
||||
get { return interruptMode; }
|
||||
set { if (value < 0 || value > 2) throw new ArgumentOutOfRangeException(); interruptMode = value; }
|
||||
}
|
||||
|
||||
public Action IRQCallback = delegate () { };
|
||||
public Action NMICallback = delegate () { };
|
||||
|
||||
private void NMI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
ASGN, PCl, 0x66,
|
||||
ASGN, PCh, 0,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// Mode 0 interrupts only take effect if a CALL or RST is on the data bus
|
||||
// Otherwise operation just continues as normal
|
||||
// For now assume a NOP is on the data bus, in which case no stack operations occur
|
||||
|
||||
//NOTE: TODO: When a CALL is present on the data bus, adjust WZ accordingly
|
||||
private void INTERRUPT_0(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// Just jump to $0038
|
||||
private void INTERRUPT_1()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, PCh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
ASGN, PCl, 0x38,
|
||||
IDLE,
|
||||
ASGN, PCh, 0,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// Interrupt mode 2 uses the I vector combined with a byte on the data bus
|
||||
// Again for now we assume only a 0 on the data bus and jump to (0xI00)
|
||||
private void INTERRUPT_2(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
ASGN, PCl, 0,
|
||||
TR, PCh, I,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
OP };
|
||||
}
|
||||
|
||||
private static ushort[] INT_vectors = new ushort[] {0x40, 0x48, 0x50, 0x58, 0x60};
|
||||
|
||||
private void ResetInterrupts()
|
||||
{
|
||||
IFF1 = false;
|
||||
IFF2 = false;
|
||||
NonMaskableInterrupt = false;
|
||||
NonMaskableInterruptPending = false;
|
||||
FlagI = false;
|
||||
InterruptMode = 1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,114 +1,27 @@
|
|||
//http://www.zophar.net/fileuploads/2/10819kouzv/z80undoc.html
|
||||
|
||||
//TODO: ex. (IX+00h) could be turned into (IX)
|
||||
|
||||
//usage:
|
||||
//VgMuseum.Z80.Disassembler disasm = new Disassembler();
|
||||
//ushort pc = RegPC.Word;
|
||||
//string str = disasm.Disassemble(() => ReadMemory(pc++));
|
||||
//Console.WriteLine(str);
|
||||
|
||||
//please note that however much youre tempted to, timings can't be put in a table here because they depend on how the instruction executes at runtime
|
||||
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public class Disassembler : IDisassemblable
|
||||
public sealed partial class Z80A : IDisassemblable
|
||||
{
|
||||
readonly static sbyte[,] opcodeSizes = new sbyte[7, 256];
|
||||
|
||||
public static void GenerateOpcodeSizes()
|
||||
{
|
||||
Disassembler disasm = new Disassembler();
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int pc = 0;
|
||||
byte[] opcode = { (byte)i, 0, 0, 0 };
|
||||
disasm.Disassemble(() => opcode[pc++]);
|
||||
opcodeSizes[0, i] = (sbyte)pc;
|
||||
}
|
||||
|
||||
opcodeSizes[0, 0xCB] = -1;
|
||||
opcodeSizes[0, 0xED] = -2;
|
||||
opcodeSizes[0, 0xDD] = -3;
|
||||
opcodeSizes[0, 0xFD] = -4;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int pc = 0;
|
||||
byte[] opcode = { 0xCB, (byte)i, 0, 0, 0 };
|
||||
disasm.Disassemble(() => opcode[pc++]);
|
||||
opcodeSizes[1, i] = (sbyte)pc;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int pc = 0;
|
||||
byte[] opcode = { 0xED, (byte)i, 0, 0, 0 };
|
||||
disasm.Disassemble(() => opcode[pc++]);
|
||||
opcodeSizes[2, i] = (sbyte)pc;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int pc = 0;
|
||||
byte[] opcode = { 0xDD, (byte)i, 0, 0, 0 };
|
||||
disasm.Disassemble(() => opcode[pc++]);
|
||||
opcodeSizes[3, i] = (sbyte)pc;
|
||||
}
|
||||
|
||||
opcodeSizes[3, 0xCB] = -5;
|
||||
opcodeSizes[3, 0xED] = -2;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int pc = 0;
|
||||
byte[] opcode = { 0xFD, (byte)i, 0, 0, 0 };
|
||||
disasm.Disassemble(() => opcode[pc++]);
|
||||
opcodeSizes[4, i] = (sbyte)pc;
|
||||
}
|
||||
|
||||
opcodeSizes[3, 0xCB] = -6;
|
||||
opcodeSizes[3, 0xED] = -2;
|
||||
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int pc = 0;
|
||||
byte[] opcode = { 0xDD, 0xCB, (byte)i, 0, 0, 0 };
|
||||
disasm.Disassemble(() => opcode[pc++]);
|
||||
opcodeSizes[5, i] = (sbyte)pc;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
int pc = 0;
|
||||
byte[] opcode = { 0xFD, 0xCB, (byte)i, 0, 0, 0 };
|
||||
disasm.Disassemble(() => opcode[pc++]);
|
||||
opcodeSizes[6, i] = (sbyte)pc;
|
||||
}
|
||||
}
|
||||
|
||||
static string Result(string format, Func<byte> read)
|
||||
static string Result(string format, Func<ushort, byte> read, ref ushort addr)
|
||||
{
|
||||
//d immediately succeeds the opcode
|
||||
//n immediate succeeds the opcode and the displacement (if present)
|
||||
//nn immediately succeeds the opcode and the displacement (if present)
|
||||
if (format.IndexOf("nn") != -1)
|
||||
{
|
||||
byte B = read();
|
||||
byte C = read();
|
||||
byte B = read(addr++);
|
||||
byte C = read(addr++);
|
||||
format = format.Replace("nn", string.Format("{0:X4}h", B + C * 256));
|
||||
}
|
||||
|
||||
if (format.IndexOf("n") != -1)
|
||||
{
|
||||
byte B = read();
|
||||
byte B = read(addr++);
|
||||
format = format.Replace("n", string.Format("{0:X2}h", B));
|
||||
}
|
||||
|
||||
|
@ -116,7 +29,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80
|
|||
|
||||
if (format.IndexOf("d") != -1)
|
||||
{
|
||||
byte B = read();
|
||||
byte B = read(addr++);
|
||||
bool neg = ((B & 0x80) != 0);
|
||||
char sign = neg ? '-' : '+';
|
||||
int val = neg ? 256 - B : B;
|
||||
|
@ -480,46 +393,49 @@ namespace BizHawk.Emulation.Cores.Components.Z80
|
|||
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0x100
|
||||
};
|
||||
|
||||
string DisassembleInternal(Func<byte> read)
|
||||
public string Disassemble(ushort addr, Func<ushort, byte> read, out ushort size)
|
||||
{
|
||||
byte A = read();
|
||||
ushort start_addr = addr;
|
||||
ushort extra_inc = 0;
|
||||
byte A = read(addr++);
|
||||
string format;
|
||||
switch (A)
|
||||
{
|
||||
case 0xCB:
|
||||
A = read();
|
||||
A = read(addr++);
|
||||
format = mnemonicsCB[A];
|
||||
break;
|
||||
case 0xDD:
|
||||
A = read();
|
||||
A = read(addr++);
|
||||
switch (A)
|
||||
{
|
||||
case 0xCB: format = mnemonicsDDCB[A]; break;
|
||||
case 0xCB: format = mnemonicsDDCB[read((ushort)(addr + 1))]; extra_inc = 1; break;
|
||||
case 0xED: format = mnemonicsED[A]; break;
|
||||
default: format = mnemonicsDD[A]; break;
|
||||
}
|
||||
break;
|
||||
case 0xED:
|
||||
A = read();
|
||||
A = read(addr++);
|
||||
format = mnemonicsED[A];
|
||||
break;
|
||||
case 0xFD:
|
||||
A = read();
|
||||
A = read(addr++);
|
||||
switch (A)
|
||||
{
|
||||
case 0xCB: format = mnemonicsFDCB[A]; break;
|
||||
case 0xCB: format = mnemonicsFDCB[read((ushort)(addr + 1))]; extra_inc = 1; break;
|
||||
case 0xED: format = mnemonicsED[A]; break;
|
||||
default: format = mnemonicsFD[A]; break;
|
||||
}
|
||||
break;
|
||||
default: format = mnemonics[A]; break;
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
string temp = Result(format, read, ref addr);
|
||||
|
||||
public string Disassemble(Func<byte> read)
|
||||
{
|
||||
return Result(DisassembleInternal(read), read);
|
||||
addr += extra_inc;
|
||||
|
||||
size = (ushort)(addr - start_addr);
|
||||
return temp;
|
||||
}
|
||||
|
||||
#region IDisassemblable
|
||||
|
@ -543,7 +459,8 @@ namespace BizHawk.Emulation.Cores.Components.Z80
|
|||
public string Disassemble(MemoryDomain m, uint addr, out int length)
|
||||
{
|
||||
int loc = (int)addr;
|
||||
string ret = Disassemble(() => m.PeekByte(loc++));
|
||||
ushort unused = 0;
|
||||
string ret = Disassemble((ushort) addr, a => m.PeekByte(a), out unused);
|
||||
length = loc - (int)addr;
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,742 @@
|
|||
using BizHawk.Common.NumberExtensions;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
public void Read_Func(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest] = ReadMemory((ushort)(Regs[src_l] | (Regs[src_h]) << 8));
|
||||
}
|
||||
|
||||
public void I_Read_Func(ushort dest, ushort src_l, ushort src_h, ushort inc)
|
||||
{
|
||||
Regs[dest] = ReadMemory((ushort)((Regs[src_l] | (Regs[src_h] << 8)) + inc));
|
||||
}
|
||||
|
||||
public void Write_Func(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
WriteMemory((ushort)(Regs[dest_l] | (Regs[dest_h] << 8)), (byte)Regs[src]);
|
||||
}
|
||||
|
||||
public void I_Write_Func(ushort dest_l, ushort dest_h, ushort inc, ushort src)
|
||||
{
|
||||
WriteMemory((ushort)((Regs[dest_l] | (Regs[dest_h] << 8)) + inc), (byte)Regs[src]);
|
||||
}
|
||||
|
||||
public void OUT_Func(ushort dest, ushort src)
|
||||
{
|
||||
WriteHardware(Regs[dest], (byte)(Regs[src]));
|
||||
}
|
||||
|
||||
public void IN_Func(ushort dest, ushort src)
|
||||
{
|
||||
Regs[dest] = ReadHardware(Regs[src]);
|
||||
}
|
||||
|
||||
public void TR_Func(ushort dest, ushort src)
|
||||
{
|
||||
Regs[dest] = Regs[src];
|
||||
}
|
||||
|
||||
public void TR16_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
Regs[dest_l] = Regs[src_l];
|
||||
Regs[dest_h] = Regs[src_h];
|
||||
}
|
||||
|
||||
public void ADD16_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
int Reg16_d = Regs[dest_l] | (Regs[dest_h] << 8);
|
||||
int Reg16_s = Regs[src_l] | (Regs[src_h] << 8);
|
||||
int temp = Reg16_d + Reg16_s;
|
||||
|
||||
FlagC = temp.Bit(16);
|
||||
FlagH = ((Reg16_d & 0xFFF) + (Reg16_s & 0xFFF)) > 0xFFF;
|
||||
FlagN = false;
|
||||
Flag3 = (temp & 0x0800) != 0;
|
||||
Flag5 = (temp & 0x2000) != 0;
|
||||
|
||||
Regs[dest_l] = (ushort)(temp & 0xFF);
|
||||
Regs[dest_h] = (ushort)((temp & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
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);
|
||||
FlagN = false;
|
||||
Flag3 = (ans & 0x08) != 0;
|
||||
Flag5 = (ans & 0x20) != 0;
|
||||
FlagP = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
|
||||
FlagS = 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 = true;
|
||||
Flag3 = (ans & 0x08) != 0;
|
||||
Flag5 = (ans & 0x20) != 0;
|
||||
FlagP = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
|
||||
FlagS = ans > 127;
|
||||
|
||||
Regs[dest] = ans;
|
||||
}
|
||||
|
||||
public void BIT_Func(ushort bit, ushort src)
|
||||
{
|
||||
FlagZ = !Regs[src].Bit(bit);
|
||||
FlagP = FlagZ; // special case
|
||||
FlagH = true;
|
||||
FlagN = false;
|
||||
FlagS = ((bit == 7) && Regs[src].Bit(bit));
|
||||
Flag5 = Regs[src].Bit(5);
|
||||
Flag3 = Regs[src].Bit(3);
|
||||
}
|
||||
|
||||
// When doing I* + n bit tests, flags 3 and 5 come from I* + n
|
||||
// This cooresponds to the high byte of WZ
|
||||
// This is the same for the (HL) bit tests, except that WZ were not assigned to before the test occurs
|
||||
public void I_BIT_Func(ushort bit, ushort src)
|
||||
{
|
||||
FlagZ = !Regs[src].Bit(bit);
|
||||
FlagP = FlagZ; // special case
|
||||
FlagH = true;
|
||||
FlagN = false;
|
||||
FlagS = ((bit == 7) && Regs[src].Bit(bit));
|
||||
Flag5 = Regs[W].Bit(5);
|
||||
Flag3 = Regs[W].Bit(3);
|
||||
}
|
||||
|
||||
public void SET_Func(ushort bit, ushort src)
|
||||
{
|
||||
Regs[src] |= (ushort)(1 << bit);
|
||||
}
|
||||
|
||||
public void RES_Func(ushort bit, ushort src)
|
||||
{
|
||||
Regs[src] &= (ushort)(0xFF - (1 << bit));
|
||||
}
|
||||
|
||||
public void ASGN_Func(ushort src, ushort val)
|
||||
{
|
||||
Regs[src] = val;
|
||||
}
|
||||
|
||||
public void SLL_Func(ushort src)
|
||||
{
|
||||
FlagC = Regs[src].Bit(7);
|
||||
|
||||
Regs[src] = (ushort)(((Regs[src] << 1) & 0xFF) | 0x1);
|
||||
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void SLA_Func(ushort src)
|
||||
{
|
||||
FlagC = Regs[src].Bit(7);
|
||||
|
||||
Regs[src] = (ushort)((Regs[src] << 1) & 0xFF);
|
||||
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void SRA_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);
|
||||
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void SRL_Func(ushort src)
|
||||
{
|
||||
FlagC = Regs[src].Bit(0) ? true : false;
|
||||
|
||||
Regs[src] = (ushort)(Regs[src] >> 1);
|
||||
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void CPL_Func(ushort src)
|
||||
{
|
||||
Regs[src] = (ushort)((~Regs[src]) & 0xFF);
|
||||
|
||||
FlagH = true;
|
||||
FlagN = true;
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
}
|
||||
|
||||
public void CCF_Func(ushort src)
|
||||
{
|
||||
FlagH = FlagC;
|
||||
FlagC = !FlagC;
|
||||
FlagN = false;
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
}
|
||||
|
||||
public void SCF_Func(ushort src)
|
||||
{
|
||||
FlagC = true;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
}
|
||||
|
||||
public void AND8_Func(ushort dest, ushort src)
|
||||
{
|
||||
Regs[dest] = (ushort)(Regs[dest] & Regs[src]);
|
||||
|
||||
FlagZ = Regs[dest] == 0;
|
||||
FlagC = false;
|
||||
FlagH = true;
|
||||
FlagN = false;
|
||||
Flag3 = (Regs[dest] & 0x08) != 0;
|
||||
Flag5 = (Regs[dest] & 0x20) != 0;
|
||||
FlagS = Regs[dest] > 127;
|
||||
FlagP = TableParity[Regs[dest]];
|
||||
}
|
||||
|
||||
public void OR8_Func(ushort dest, ushort src)
|
||||
{
|
||||
Regs[dest] = (ushort)(Regs[dest] | Regs[src]);
|
||||
|
||||
FlagZ = Regs[dest] == 0;
|
||||
FlagC = false;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
Flag3 = (Regs[dest] & 0x08) != 0;
|
||||
Flag5 = (Regs[dest] & 0x20) != 0;
|
||||
FlagS = Regs[dest] > 127;
|
||||
FlagP = TableParity[Regs[dest]];
|
||||
}
|
||||
|
||||
public void XOR8_Func(ushort dest, ushort src)
|
||||
{
|
||||
Regs[dest] = (ushort)((Regs[dest] ^ Regs[src]));
|
||||
|
||||
FlagZ = Regs[dest] == 0;
|
||||
FlagC = false;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
Flag3 = (Regs[dest] & 0x08) != 0;
|
||||
Flag5 = (Regs[dest] & 0x20) != 0;
|
||||
FlagS = Regs[dest] > 127;
|
||||
FlagP = TableParity[Regs[dest]];
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 = true;
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagP = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
|
||||
FlagS = ans > 127;
|
||||
}
|
||||
|
||||
public void RRC_Func(ushort src)
|
||||
{
|
||||
bool imm = src == Aim;
|
||||
if (imm) { src = A; }
|
||||
|
||||
FlagC = Regs[src].Bit(0);
|
||||
|
||||
Regs[src] = (ushort)((FlagC ? 0x80 : 0) | (Regs[src] >> 1));
|
||||
|
||||
if (!imm)
|
||||
{
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
}
|
||||
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void RR_Func(ushort src)
|
||||
{
|
||||
bool imm = src == Aim;
|
||||
if (imm) { src = A; }
|
||||
|
||||
ushort c = (ushort)(FlagC ? 0x80 : 0);
|
||||
|
||||
FlagC = Regs[src].Bit(0);
|
||||
|
||||
Regs[src] = (ushort)(c | (Regs[src] >> 1));
|
||||
|
||||
if (!imm)
|
||||
{
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
}
|
||||
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void RLC_Func(ushort src)
|
||||
{
|
||||
bool imm = src == Aim;
|
||||
if (imm) { src = A; }
|
||||
|
||||
ushort c = (ushort)(Regs[src].Bit(7) ? 1 : 0);
|
||||
FlagC = Regs[src].Bit(7);
|
||||
|
||||
Regs[src] = (ushort)(((Regs[src] << 1) & 0xFF) | c);
|
||||
|
||||
if (!imm)
|
||||
{
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
}
|
||||
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void RL_Func(ushort src)
|
||||
{
|
||||
bool imm = src == Aim;
|
||||
if (imm) { src = A; }
|
||||
|
||||
ushort c = (ushort)(FlagC ? 1 : 0);
|
||||
FlagC = Regs[src].Bit(7);
|
||||
|
||||
Regs[src] = (ushort)(((Regs[src] << 1) & 0xFF) | c);
|
||||
|
||||
if (!imm)
|
||||
{
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagZ = Regs[src] == 0;
|
||||
FlagP = TableParity[Regs[src]];
|
||||
}
|
||||
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
}
|
||||
|
||||
public void INC8_Func(ushort src)
|
||||
{
|
||||
int Reg16_d = Regs[src];
|
||||
Reg16_d += 1;
|
||||
|
||||
FlagZ = (Reg16_d & 0xFF) == 0;
|
||||
|
||||
ushort ans = (ushort)(Reg16_d & 0xFF);
|
||||
|
||||
// redo for half carry flag
|
||||
Reg16_d = Regs[src] & 0xF;
|
||||
Reg16_d += 1;
|
||||
|
||||
FlagH = Reg16_d.Bit(4);
|
||||
FlagN = false;
|
||||
|
||||
Regs[src] = ans;
|
||||
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagP = Regs[src] == 0x80;
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
}
|
||||
|
||||
public void DEC8_Func(ushort src)
|
||||
{
|
||||
int Reg16_d = Regs[src];
|
||||
Reg16_d -= 1;
|
||||
|
||||
FlagZ = (Reg16_d & 0xFF) == 0;
|
||||
|
||||
ushort ans = (ushort)(Reg16_d & 0xFF);
|
||||
|
||||
// redo for half carry flag
|
||||
Reg16_d = Regs[src] & 0xF;
|
||||
Reg16_d -= 1;
|
||||
|
||||
FlagH = Reg16_d.Bit(4);
|
||||
FlagN = true;
|
||||
|
||||
Regs[src] = ans;
|
||||
|
||||
FlagS = Regs[src].Bit(7);
|
||||
FlagP = Regs[src] == 0x7F;
|
||||
Flag3 = (Regs[src] & 0x08) != 0;
|
||||
Flag5 = (Regs[src] & 0x20) != 0;
|
||||
}
|
||||
|
||||
public void INC16_Func(ushort src_l, ushort src_h)
|
||||
{
|
||||
int Reg16_d = Regs[src_l] | (Regs[src_h] << 8);
|
||||
|
||||
Reg16_d += 1;
|
||||
|
||||
Regs[src_l] = (ushort)(Reg16_d & 0xFF);
|
||||
Regs[src_h] = (ushort)((Reg16_d & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
public void DEC16_Func(ushort src_l, ushort src_h)
|
||||
{
|
||||
int Reg16_d = Regs[src_l] | (Regs[src_h] << 8);
|
||||
|
||||
Reg16_d -= 1;
|
||||
|
||||
Regs[src_l] = (ushort)(Reg16_d & 0xFF);
|
||||
Regs[src_h] = (ushort)((Reg16_d & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
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);
|
||||
FlagN = false;
|
||||
Flag3 = (ans & 0x08) != 0;
|
||||
Flag5 = (ans & 0x20) != 0;
|
||||
FlagP = (Regs[dest].Bit(7) == Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
|
||||
FlagS = ans > 127;
|
||||
|
||||
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 = true;
|
||||
Flag3 = (ans & 0x08) != 0;
|
||||
Flag5 = (ans & 0x20) != 0;
|
||||
FlagP = (Regs[dest].Bit(7) != Regs[src].Bit(7)) && (Regs[dest].Bit(7) != ans.Bit(7));
|
||||
FlagS = ans > 127;
|
||||
|
||||
Regs[dest] = ans;
|
||||
}
|
||||
|
||||
public void DA_Func(ushort src)
|
||||
{
|
||||
byte a = (byte)Regs[src];
|
||||
byte temp = a;
|
||||
|
||||
if (FlagN)
|
||||
{
|
||||
if (FlagH || ((a & 0x0F) > 0x09)) { temp -= 0x06; }
|
||||
if (FlagC || a > 0x99) { temp -= 0x60; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FlagH || ((a & 0x0F) > 0x09)) { temp += 0x06; }
|
||||
if (FlagC || a > 0x99) { temp += 0x60; }
|
||||
}
|
||||
|
||||
temp &= 0xFF;
|
||||
|
||||
FlagC = FlagC || a > 0x99;
|
||||
FlagZ = temp == 0;
|
||||
FlagH = ((a ^ temp) & 0x10) != 0;
|
||||
FlagP = TableParity[temp];
|
||||
FlagS = temp > 127;
|
||||
Flag3 = (temp & 0x08) != 0;
|
||||
Flag5 = (temp & 0x20) != 0;
|
||||
|
||||
Regs[src] = temp;
|
||||
}
|
||||
|
||||
// used for signed operations
|
||||
public void ADDS_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
int Reg16_d = Regs[dest_l];
|
||||
int Reg16_s = Regs[src_l];
|
||||
|
||||
Reg16_d += Reg16_s;
|
||||
|
||||
ushort temp = 0;
|
||||
|
||||
// since this is signed addition, calculate the high byte carry appropriately
|
||||
// note that flags are unaffected by this operation
|
||||
if (Reg16_s.Bit(7))
|
||||
{
|
||||
if (((Reg16_d & 0xFF) >= Regs[dest_l]))
|
||||
{
|
||||
temp = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = (ushort)(Reg16_d.Bit(8) ? 1 : 0);
|
||||
}
|
||||
|
||||
ushort ans_l = (ushort)(Reg16_d & 0xFF);
|
||||
|
||||
Regs[dest_l] = ans_l;
|
||||
Regs[dest_h] += temp;
|
||||
Regs[dest_h] &= 0xFF;
|
||||
|
||||
}
|
||||
|
||||
public void EXCH_16_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
ushort temp = Regs[dest_l];
|
||||
Regs[dest_l] = Regs[src_l];
|
||||
Regs[src_l] = temp;
|
||||
|
||||
temp = Regs[dest_h];
|
||||
Regs[dest_h] = Regs[src_h];
|
||||
Regs[src_h] = temp;
|
||||
}
|
||||
|
||||
public void SBC_16_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
int Reg16_d = Regs[dest_l] | (Regs[dest_h] << 8);
|
||||
int Reg16_s = Regs[src_l] | (Regs[src_h] << 8);
|
||||
int c = FlagC ? 1 : 0;
|
||||
|
||||
int ans = Reg16_d - Reg16_s - c;
|
||||
|
||||
FlagN = true;
|
||||
FlagC = ans.Bit(16);
|
||||
FlagP = (Reg16_d.Bit(15) != Reg16_s.Bit(15)) && (Reg16_d.Bit(15) != ans.Bit(15));
|
||||
FlagS = (ushort)(ans & 0xFFFF) > 32767;
|
||||
FlagZ = (ans & 0xFFFF) == 0;
|
||||
Flag3 = (ans & 0x0800) != 0;
|
||||
Flag5 = (ans & 0x2000) != 0;
|
||||
|
||||
// redo for half carry flag
|
||||
Reg16_d &= 0xFFF;
|
||||
Reg16_d -= ((Reg16_s & 0xFFF) + c);
|
||||
|
||||
FlagH = Reg16_d.Bit(12);
|
||||
|
||||
Regs[dest_l] = (ushort)(ans & 0xFF);
|
||||
Regs[dest_h] = (ushort)((ans >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
public void ADC_16_Func(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
int Reg16_d = Regs[dest_l] | (Regs[dest_h] << 8);
|
||||
int Reg16_s = Regs[src_l] | (Regs[src_h] << 8);
|
||||
|
||||
int ans = Reg16_d + Reg16_s + (FlagC ? 1 : 0);
|
||||
|
||||
FlagH = ((Reg16_d & 0xFFF) + (Reg16_s & 0xFFF) + (FlagC ? 1 : 0)) > 0xFFF;
|
||||
FlagN = false;
|
||||
FlagC = ans.Bit(16);
|
||||
FlagP = (Reg16_d.Bit(15) == Reg16_s.Bit(15)) && (Reg16_d.Bit(15) != ans.Bit(15));
|
||||
FlagS = (ans & 0xFFFF) > 32767;
|
||||
FlagZ = (ans & 0xFFFF) == 0;
|
||||
Flag3 = (ans & 0x0800) != 0;
|
||||
Flag5 = (ans & 0x2000) != 0;
|
||||
|
||||
Regs[dest_l] = (ushort)(ans & 0xFF);
|
||||
Regs[dest_h] = (ushort)((ans >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
public void NEG_8_Func(ushort src)
|
||||
{
|
||||
int Reg16_d = 0;
|
||||
Reg16_d -= Regs[src];
|
||||
|
||||
FlagC = Regs[src] != 0x0;
|
||||
FlagZ = (Reg16_d & 0xFF) == 0;
|
||||
FlagP = Regs[src] == 0x80;
|
||||
FlagS = (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;
|
||||
FlagN = true;
|
||||
Flag3 = (ans & 0x08) != 0;
|
||||
Flag5 = (ans & 0x20) != 0;
|
||||
}
|
||||
|
||||
public void RRD_Func(ushort dest, ushort src)
|
||||
{
|
||||
ushort temp1 = Regs[src];
|
||||
ushort temp2 = Regs[dest];
|
||||
Regs[dest] = (ushort)(((temp1 & 0x0F) << 4) + ((temp2 & 0xF0) >> 4));
|
||||
Regs[src] = (ushort)((temp1 & 0xF0) + (temp2 & 0x0F));
|
||||
|
||||
temp1 = Regs[src];
|
||||
FlagS = temp1 > 127;
|
||||
FlagZ = temp1 == 0;
|
||||
FlagH = false;
|
||||
FlagP = TableParity[temp1];
|
||||
FlagN = false;
|
||||
Flag3 = (temp1 & 0x08) != 0;
|
||||
Flag5 = (temp1 & 0x20) != 0;
|
||||
}
|
||||
|
||||
public void RLD_Func(ushort dest, ushort src)
|
||||
{
|
||||
ushort temp1 = Regs[src];
|
||||
ushort temp2 = Regs[dest];
|
||||
Regs[dest] = (ushort)((temp1 & 0x0F) + ((temp2 & 0x0F) << 4));
|
||||
Regs[src] = (ushort)((temp1 & 0xF0) + ((temp2 & 0xF0) >> 4));
|
||||
|
||||
temp1 = Regs[src];
|
||||
FlagS = temp1 > 127;
|
||||
FlagZ = temp1 == 0;
|
||||
FlagH = false;
|
||||
FlagP = TableParity[temp1];
|
||||
FlagN = false;
|
||||
Flag3 = (temp1 & 0x08) != 0;
|
||||
Flag5 = (temp1 & 0x20) != 0;
|
||||
}
|
||||
|
||||
// sets flags for LD/R
|
||||
public void SET_FL_LD_Func()
|
||||
{
|
||||
FlagP = (Regs[C] | (Regs[B] << 8)) != 0;
|
||||
FlagH = false;
|
||||
FlagN = false;
|
||||
Flag5 = ((Regs[ALU] + Regs[A]) & 0x02) != 0;
|
||||
Flag3 = ((Regs[ALU] + Regs[A]) & 0x08) != 0;
|
||||
}
|
||||
|
||||
// set flags for CP/R
|
||||
public void SET_FL_CP_Func()
|
||||
{
|
||||
int Reg8_d = Regs[A];
|
||||
int Reg8_s = Regs[ALU];
|
||||
|
||||
// get half carry flag
|
||||
byte temp = (byte)((Reg8_d & 0xF) - (Reg8_s & 0xF));
|
||||
FlagH = temp.Bit(4);
|
||||
|
||||
temp = (byte)(Reg8_d - Reg8_s);
|
||||
FlagN = true;
|
||||
FlagZ = temp == 0;
|
||||
FlagS = temp > 127;
|
||||
FlagP = (Regs[C] | (Regs[B] << 8)) != 0;
|
||||
|
||||
temp = (byte)(Reg8_d - Reg8_s - (FlagH ? 1 : 0));
|
||||
Flag5 = (temp & 0x02) != 0;
|
||||
Flag3 = (temp & 0x08) != 0;
|
||||
}
|
||||
|
||||
// set flags for LD A, I/R
|
||||
public void SET_FL_IR_Func(ushort dest)
|
||||
{
|
||||
if (dest == A)
|
||||
{
|
||||
FlagN = false;
|
||||
FlagH = false;
|
||||
FlagZ = Regs[A] == 0;
|
||||
FlagS = Regs[A] > 127;
|
||||
FlagP = iff2;
|
||||
Flag5 = (Regs[A] & 0x02) != 0;
|
||||
Flag3 = (Regs[A] & 0x08) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
TODO:
|
||||
|
||||
Mode 0 and 2 interrupts
|
||||
Check T-cycle level memory access timing
|
||||
Check R register
|
||||
new tests for WZ Registers
|
||||
Memory refresh - IR is pushed onto the address bus at instruction start, does anything need this?
|
||||
Data Bus - For mode zero and 2 interrupts, need a system that uses it to test
|
|
@ -0,0 +1,132 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
// registers
|
||||
// note these are not constants. When shadows are used, they will be changed accordingly
|
||||
public ushort PCl = 0;
|
||||
public ushort PCh = 1;
|
||||
public ushort SPl = 2;
|
||||
public ushort SPh = 3;
|
||||
public ushort A = 4;
|
||||
public ushort F = 5;
|
||||
public ushort B = 6;
|
||||
public ushort C = 7;
|
||||
public ushort D = 8;
|
||||
public ushort E = 9;
|
||||
public ushort H = 10;
|
||||
public ushort L = 11;
|
||||
public ushort W = 12;
|
||||
public ushort Z = 13;
|
||||
public ushort Aim = 14; // use this indicator for RLCA etc., since the Z flag is reset on those
|
||||
public ushort Ixl = 15;
|
||||
public ushort Ixh = 16;
|
||||
public ushort Iyl = 17;
|
||||
public ushort Iyh = 18;
|
||||
public ushort Int = 19;
|
||||
public ushort R = 20;
|
||||
public ushort I = 21;
|
||||
public ushort ZERO = 22; // it is convenient to have a register that is always zero, to reuse instructions
|
||||
public ushort ALU = 23; // This will be temporary arthimatic storage
|
||||
// shadow registers
|
||||
public ushort A_s = 24;
|
||||
public ushort F_s = 25;
|
||||
public ushort B_s = 26;
|
||||
public ushort C_s = 27;
|
||||
public ushort D_s = 28;
|
||||
public ushort E_s = 29;
|
||||
public ushort H_s = 30;
|
||||
public ushort L_s = 31;
|
||||
|
||||
public ushort[] Regs = new ushort[36];
|
||||
|
||||
public bool FlagI;
|
||||
|
||||
public bool FlagC
|
||||
{
|
||||
get { return (Regs[5] & 0x01) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x01) | (value ? 0x01 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagN
|
||||
{
|
||||
get { return (Regs[5] & 0x02) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x02) | (value ? 0x02 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagP
|
||||
{
|
||||
get { return (Regs[5] & 0x04) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x04) | (value ? 0x04 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool Flag3
|
||||
{
|
||||
get { return (Regs[5] & 0x08) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x08) | (value ? 0x08 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagH
|
||||
{
|
||||
get { return (Regs[5] & 0x10) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x10) | (value ? 0x10 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool Flag5
|
||||
{
|
||||
get { return (Regs[5] & 0x20) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x20) | (value ? 0x20 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagZ
|
||||
{
|
||||
get { return (Regs[5] & 0x40) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x40) | (value ? 0x40 : 0x00)); }
|
||||
}
|
||||
|
||||
public bool FlagS
|
||||
{
|
||||
get { return (Regs[5] & 0x80) != 0; }
|
||||
set { Regs[5] = (ushort)((Regs[5] & ~0x80) | (value ? 0x80 : 0x00)); }
|
||||
}
|
||||
|
||||
public ushort RegPC
|
||||
{
|
||||
get { return (ushort)(Regs[0] | (Regs[1] << 8)); }
|
||||
set
|
||||
{
|
||||
Regs[0] = (ushort)(value & 0xFF);
|
||||
Regs[1] = (ushort)((value >> 8) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetRegisters()
|
||||
{
|
||||
for (int i=0; i < 36; i++)
|
||||
{
|
||||
Regs[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private bool[] TableParity;
|
||||
private void InitTableParity()
|
||||
{
|
||||
TableParity = new bool[256];
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
int Bits = 0;
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
Bits += (i >> j) & 1;
|
||||
}
|
||||
TableParity[i] = (Bits & 1) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,572 @@
|
|||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
// this contains the vectors of instrcution operations
|
||||
// NOTE: This list is NOT confirmed accurate for each individual cycle
|
||||
|
||||
private void NOP_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// NOTE: In a real Z80, this operation just flips a switch to choose between 2 registers
|
||||
// but it's simpler to emulate just by exchanging the register with it's shadow
|
||||
private void EXCH_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{EXCH,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void EXX_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{EXX,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// this exchanges 2 16 bit registers
|
||||
private void EXCH_16_(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{EXCH_16, dest_l, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void INC_16(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
|
||||
private void DEC_16(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
DEC16, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// this is done in two steps technically, but the flags don't work out using existing funcitons
|
||||
// so let's use a different function since it's an internal operation anyway
|
||||
private void ADD_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
ADD16, dest_l, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void REG_OP(ushort operation, ushort dest, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, dest, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// Operations using the I and R registers take one T-cycle longer
|
||||
private void REG_OP_IR(ushort operation, ushort dest, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, dest, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
SET_FL_IR, dest,
|
||||
OP };
|
||||
}
|
||||
|
||||
// note: do not use DEC here since no flags are affected by this operation
|
||||
private void DJNZ_()
|
||||
{
|
||||
if ((Regs[B] - 1) != 0)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
ASGN, W, 0,
|
||||
IDLE,
|
||||
ADDS, PCl, PCh, Z, W,
|
||||
TR16, Z, W, PCl, PCh,
|
||||
OP };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
ASGN, B, (ushort)((Regs[B] - 1) & 0xFF),
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
}
|
||||
|
||||
private void HALT_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
HALT };
|
||||
}
|
||||
|
||||
private void JR_COND(bool cond)
|
||||
{
|
||||
if (cond)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
ASGN, W, 0,
|
||||
IDLE,
|
||||
ADDS, PCl, PCh, Z, W,
|
||||
TR16, Z, W, PCl, PCh,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
OP };
|
||||
}
|
||||
}
|
||||
|
||||
private void JP_COND(bool cond)
|
||||
{
|
||||
if (cond)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
}
|
||||
|
||||
private void RET_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void RETI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void RETN_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
EI_RETN,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
OP };
|
||||
}
|
||||
|
||||
|
||||
private void RET_COND(bool cond)
|
||||
{
|
||||
if (cond)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, W, SPl, SPh,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
OP };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
}
|
||||
|
||||
private void CALL_COND(bool cond)
|
||||
{
|
||||
if (cond)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, PCh,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
TR, PCl, Z,
|
||||
TR, PCh, W,
|
||||
OP };
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
OP };
|
||||
}
|
||||
}
|
||||
|
||||
private void INT_OP(ushort operation, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void BIT_OP(ushort operation, ushort bit, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{operation, bit, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void PUSH_(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, src_h,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
IDLE,
|
||||
WR, SPl, SPh, src_l,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
|
||||
private void POP_(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, src_l, SPl, SPh,
|
||||
IDLE,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
RD, src_h, SPl, SPh,
|
||||
IDLE,
|
||||
INC16, SPl, SPh,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void RST_(ushort n)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCh,
|
||||
DEC16, SPl, SPh,
|
||||
WR, SPl, SPh, PCl,
|
||||
IDLE,
|
||||
ASGN, Z, n,
|
||||
ASGN, W, 0,
|
||||
TR16, PCl, PCh, Z, W,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void PREFIX_(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
PREFIX, src};
|
||||
}
|
||||
|
||||
private void PREFETCH_(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{TR16, Z, W, src_l, src_h,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
PREFIX, IXYprefetch };
|
||||
}
|
||||
|
||||
private void DI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{DI,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void EI_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{EI,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void JP_16(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{TR, PCl, src_l,
|
||||
IDLE,
|
||||
TR, PCh, src_h,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_SP_16(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR, SPl, src_l,
|
||||
TR, SPh, src_h,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void OUT_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
TR, W, A,
|
||||
OUT, ALU, A,
|
||||
TR, Z, ALU,
|
||||
INC16, Z, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP};
|
||||
}
|
||||
|
||||
private void OUT_REG_(ushort dest, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
OUT, dest, src,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
OP};
|
||||
}
|
||||
|
||||
private void IN_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
TR, W, A,
|
||||
IN, A, ALU,
|
||||
TR, Z, ALU,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP};
|
||||
}
|
||||
|
||||
private void IN_REG_(ushort dest, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IN, dest, src,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
OP};
|
||||
}
|
||||
|
||||
private void REG_OP_16_(ushort op, ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
op, dest_l, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP};
|
||||
}
|
||||
|
||||
private void INT_MODE_(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
INT_MODE, src,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void RRD_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, L, H,
|
||||
IDLE,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
RRD, ALU, A,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void RLD_()
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, L, H,
|
||||
IDLE,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
RLD, ALU, A,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,478 @@
|
|||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public partial class Z80A
|
||||
{
|
||||
private void INT_OP_IND(ushort operation, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
operation, ALU,
|
||||
IDLE,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void BIT_OP_IND(ushort operation, ushort bit, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
operation, bit, ALU,
|
||||
IDLE,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// Note that this operation uses I_BIT, same as indexed BIT.
|
||||
// This is where the strange behaviour in Flag bits 3 and 5 come from.
|
||||
// normally WZ contain I* + n when doing I_BIT ops, but here we use that code path
|
||||
// even though WZ is not assigned to, letting it's value from other operations show through
|
||||
private void BIT_TE_IND(ushort operation, ushort bit, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
I_BIT, bit, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void REG_OP_IND_INC(ushort operation, ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
operation, dest, ALU,
|
||||
INC16, src_l, src_h,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void REG_OP_IND(ushort operation, ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
RD, ALU, Z, W,
|
||||
INC16, Z, W,
|
||||
operation, dest, ALU,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_16_IND_nn(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WR, Z, W, src_l,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
WR, Z, W, src_h,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_IND_16_nn(ushort dest_l, ushort dest_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, dest_l, Z, W,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
IDLE,
|
||||
RD, dest_h, Z, W,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_8_IND_nn(ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WR, Z, W, src,
|
||||
INC16, Z, W,
|
||||
TR, W, A,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_IND_8_nn(ushort dest)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, Z, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, W, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
RD, dest, Z, W,
|
||||
IDLE,
|
||||
INC16, Z, W,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_8_IND(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
WR, Z, W, src,
|
||||
INC16, Z, W,
|
||||
TR, W, A,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_8_IND_IND(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
IDLE,
|
||||
WR, dest_l, dest_h, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_IND_8_INC(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, dest, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_IND_8_DEC(ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, dest, src_l, src_h,
|
||||
IDLE,
|
||||
DEC16, src_l, src_h,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_IND_16(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, dest_l, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
RD, dest_h, src_l, src_h,
|
||||
IDLE,
|
||||
INC16, src_l, src_h,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void INC_8_IND(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
INC8, ALU,
|
||||
IDLE,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void DEC_8_IND(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, src_l, src_h,
|
||||
IDLE,
|
||||
DEC8, ALU,
|
||||
IDLE,
|
||||
WR, src_l, src_h, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
// NOTE: WZ implied for the wollowing 3 functions
|
||||
private void I_INT_OP(ushort operation, ushort dest)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
operation, ALU,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
TR, dest, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void I_BIT_OP(ushort operation, ushort bit, ushort dest)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
operation, bit, ALU,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
TR, dest, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void I_BIT_TE(ushort bit)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
I_BIT, bit, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void I_OP_n(ushort operation, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
IDLE,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
operation, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void I_OP_n_n(ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
IDLE,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
WR, Z, W, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void I_REG_OP_IND_n(ushort operation, ushort dest, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, Z, W, src_l, src_h,
|
||||
IDLE,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
RD, ALU, Z, W,
|
||||
IDLE,
|
||||
operation, dest, ALU,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void I_LD_8_IND_n(ushort dest_l, ushort dest_h, ushort src)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
RD, ALU, PCl, PCh,
|
||||
IDLE,
|
||||
INC16, PCl, PCh,
|
||||
IDLE,
|
||||
TR16, Z, W, dest_l, dest_h,
|
||||
IDLE,
|
||||
ADDS, Z, W, ALU, ZERO,
|
||||
IDLE,
|
||||
WR, Z, W, src,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
|
||||
private void LD_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{RD, ALU, L, H,
|
||||
IDLE,
|
||||
WR, E, D, ALU,
|
||||
IDLE,
|
||||
operation, L, H,
|
||||
IDLE,
|
||||
operation, E, D,
|
||||
IDLE,
|
||||
DEC16, C, B,
|
||||
SET_FL_LD,
|
||||
IDLE,
|
||||
OP_R, 0, operation, repeat_instr };
|
||||
}
|
||||
|
||||
private void CP_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, ALU, L, H,
|
||||
operation, L, H,
|
||||
IDLE,
|
||||
IDLE,
|
||||
DEC16, C, B,
|
||||
SET_FL_CP,
|
||||
IDLE,
|
||||
operation, Z, W,
|
||||
IDLE,
|
||||
OP_R, 1, operation, repeat_instr };
|
||||
}
|
||||
|
||||
private void IN_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IN, ALU, C,
|
||||
IDLE,
|
||||
WR, L, H, ALU,
|
||||
IDLE,
|
||||
operation, L, H,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
operation, Z, W,
|
||||
IDLE,
|
||||
DEC8, B,
|
||||
IDLE,
|
||||
OP_R, 2, operation, repeat_instr };
|
||||
}
|
||||
|
||||
private void OUT_OP_R(ushort operation, ushort repeat_instr)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{RD, ALU, L, H,
|
||||
IDLE,
|
||||
OUT, C, ALU,
|
||||
IDLE,
|
||||
IDLE,
|
||||
operation, L, H,
|
||||
DEC8, B,
|
||||
IDLE,
|
||||
TR16, Z, W, C, B,
|
||||
operation, Z, W,
|
||||
IDLE,
|
||||
OP_R, 3, operation, repeat_instr };
|
||||
}
|
||||
|
||||
// this is an indirect change of a a 16 bit register with memory
|
||||
private void EXCH_16_IND_(ushort dest_l, ushort dest_h, ushort src_l, ushort src_h)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
RD, Z, dest_l, dest_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
I_RD, W, dest_l, dest_h, 1,
|
||||
IDLE,
|
||||
IDLE,
|
||||
WR, dest_l, dest_h, src_l,
|
||||
IDLE,
|
||||
IDLE,
|
||||
I_WR, dest_l, dest_h, 1, src_h,
|
||||
IDLE,
|
||||
IDLE,
|
||||
TR16, src_l, src_h, Z, W,
|
||||
IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
OP };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,688 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
||||
// Z80A CPU
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80A
|
||||
{
|
||||
public sealed partial class Z80A
|
||||
{
|
||||
// operations that can take place in an instruction
|
||||
public const ushort IDLE = 0;
|
||||
public const ushort OP = 1;
|
||||
public const ushort OP_R = 2; // used for repeating operations
|
||||
public const ushort HALT = 3;
|
||||
public const ushort RD = 4;
|
||||
public const ushort WR = 5;
|
||||
public const ushort I_RD = 6;
|
||||
public const ushort I_WR = 7;
|
||||
public const ushort TR = 8;
|
||||
public const ushort TR16 = 9;
|
||||
public const ushort ADD16 = 10;
|
||||
public const ushort ADD8 = 11;
|
||||
public const ushort SUB8 = 12;
|
||||
public const ushort ADC8 = 13;
|
||||
public const ushort SBC8 = 14;
|
||||
public const ushort SBC16 = 15;
|
||||
public const ushort ADC16 = 16;
|
||||
public const ushort INC16 = 17;
|
||||
public const ushort INC8 = 18;
|
||||
public const ushort DEC16 = 19;
|
||||
public const ushort DEC8 = 20;
|
||||
public const ushort RLC = 21;
|
||||
public const ushort RL = 22;
|
||||
public const ushort RRC = 23;
|
||||
public const ushort RR = 24;
|
||||
public const ushort CPL = 25;
|
||||
public const ushort DA = 26;
|
||||
public const ushort SCF = 27;
|
||||
public const ushort CCF = 28;
|
||||
public const ushort AND8 = 29;
|
||||
public const ushort XOR8 = 30;
|
||||
public const ushort OR8 = 31;
|
||||
public const ushort CP8 = 32;
|
||||
public const ushort SLA = 33;
|
||||
public const ushort SRA = 34;
|
||||
public const ushort SRL = 35;
|
||||
public const ushort SLL = 36;
|
||||
public const ushort BIT = 37;
|
||||
public const ushort RES = 38;
|
||||
public const ushort SET = 39;
|
||||
public const ushort EI = 40;
|
||||
public const ushort DI = 41;
|
||||
public const ushort EXCH = 42;
|
||||
public const ushort EXX = 43;
|
||||
public const ushort EXCH_16 = 44;
|
||||
public const ushort PREFIX = 45;
|
||||
public const ushort PREFETCH = 46;
|
||||
public const ushort ASGN = 47;
|
||||
public const ushort ADDS = 48; // signed 16 bit operation used in 2 instructions
|
||||
public const ushort INT_MODE = 49;
|
||||
public const ushort EI_RETN = 50;
|
||||
public const ushort EI_RETI = 51; // reti has no delay in interrupt enable
|
||||
public const ushort OUT = 52;
|
||||
public const ushort IN = 53;
|
||||
public const ushort NEG = 54;
|
||||
public const ushort RRD = 55;
|
||||
public const ushort RLD = 56;
|
||||
public const ushort SET_FL_LD = 57;
|
||||
public const ushort SET_FL_CP = 58;
|
||||
public const ushort SET_FL_IR = 59;
|
||||
public const ushort I_BIT = 60;
|
||||
public const ushort HL_BIT = 61;
|
||||
|
||||
public byte temp_R;
|
||||
|
||||
public Z80A()
|
||||
{
|
||||
Reset();
|
||||
InitTableParity();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
ResetRegisters();
|
||||
ResetInterrupts();
|
||||
TotalExecutedCycles = 0;
|
||||
cur_instr = new ushort[] { OP };
|
||||
instr_pntr = 0;
|
||||
NO_prefix = true;
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; set; }
|
||||
|
||||
// Memory Access
|
||||
public Func<ushort, byte> FetchMemory;
|
||||
public Func<ushort, byte> ReadMemory;
|
||||
public Action<ushort, byte> WriteMemory;
|
||||
public Func<ushort, byte> PeekMemory;
|
||||
public Func<ushort, byte> DummyReadMemory;
|
||||
|
||||
// Hardware I/O Port Access
|
||||
public Func<ushort, byte> ReadHardware;
|
||||
public Action<ushort, byte> WriteHardware;
|
||||
|
||||
//this only calls when the first byte of an instruction is fetched.
|
||||
public Action<ushort> OnExecFetch;
|
||||
|
||||
public void UnregisterMemoryMapper()
|
||||
{
|
||||
ReadMemory = null;
|
||||
WriteMemory = null;
|
||||
PeekMemory = null;
|
||||
DummyReadMemory = null;
|
||||
ReadHardware = null;
|
||||
WriteHardware = null;
|
||||
}
|
||||
|
||||
public void SetCallbacks
|
||||
(
|
||||
Func<ushort, byte> ReadMemory,
|
||||
Func<ushort, byte> DummyReadMemory,
|
||||
Func<ushort, byte> PeekMemory,
|
||||
Action<ushort, byte> WriteMemory,
|
||||
Func<ushort, byte> ReadHardware,
|
||||
Action<ushort, byte> WriteHardware
|
||||
)
|
||||
{
|
||||
this.ReadMemory = ReadMemory;
|
||||
this.DummyReadMemory = DummyReadMemory;
|
||||
this.PeekMemory = PeekMemory;
|
||||
this.WriteMemory = WriteMemory;
|
||||
this.ReadHardware = ReadHardware;
|
||||
this.WriteHardware = WriteHardware;
|
||||
}
|
||||
|
||||
// Execute instructions
|
||||
public void ExecuteOne()
|
||||
{
|
||||
if (Regs[A] > 255) { Console.WriteLine(RegPC); }
|
||||
switch (cur_instr[instr_pntr++])
|
||||
{
|
||||
case IDLE:
|
||||
// do nothing
|
||||
break;
|
||||
case OP:
|
||||
// Read the opcode of the next instruction
|
||||
if (EI_pending > 0)
|
||||
{
|
||||
EI_pending--;
|
||||
if (EI_pending == 0) { IFF1 = IFF2 = true; }
|
||||
}
|
||||
|
||||
// Process interrupt requests.
|
||||
if (nonMaskableInterruptPending)
|
||||
{
|
||||
nonMaskableInterruptPending = false;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
iff2 = iff1;
|
||||
iff1 = false;
|
||||
NMI_();
|
||||
NMICallback();
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
{
|
||||
iff1 = iff2 = false;
|
||||
EI_pending = 0;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
switch (interruptMode)
|
||||
{
|
||||
case 0:
|
||||
// Requires something to be pushed onto the data bus
|
||||
// we'll assume it's a zero for now
|
||||
INTERRUPT_0(0);
|
||||
break;
|
||||
case 1:
|
||||
INTERRUPT_1();
|
||||
break;
|
||||
case 2:
|
||||
// Low byte of interrupt vector comes from data bus
|
||||
// We'll assume it's zero for now
|
||||
INTERRUPT_2(0);
|
||||
break;
|
||||
}
|
||||
IRQCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
}
|
||||
instr_pntr = 0;
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
temp_R++;
|
||||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
break;
|
||||
case OP_R:
|
||||
// determine if we repeat based on what operation we are doing
|
||||
// single execution versions also come here, but never repeat
|
||||
ushort temp1 = cur_instr[instr_pntr++];
|
||||
ushort temp2 = cur_instr[instr_pntr++];
|
||||
ushort temp3 = cur_instr[instr_pntr++];
|
||||
|
||||
bool repeat = false;
|
||||
int Reg16_d = Regs[C] | (Regs[B] << 8);
|
||||
switch (temp1)
|
||||
{
|
||||
case 0:
|
||||
repeat = Reg16_d != 0;
|
||||
break;
|
||||
case 1:
|
||||
repeat = (Reg16_d != 0) && !FlagZ;
|
||||
break;
|
||||
case 2:
|
||||
repeat = Regs[B] != 0;
|
||||
break;
|
||||
case 3:
|
||||
repeat = Regs[B] != 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// if we repeat, we do a 5 cycle refresh which decrements PC by 2
|
||||
// if we don't repeat, continue on as a normal opcode fetch
|
||||
if (repeat && temp3 > 0)
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
DEC16, PCl, PCh,
|
||||
IDLE,
|
||||
DEC16, PCl, PCh,
|
||||
OP };
|
||||
|
||||
// adjust WZ register accordingly
|
||||
switch (temp1)
|
||||
{
|
||||
case 0:
|
||||
// TEST: PC before or after the instruction?
|
||||
Regs[Z] = Regs[PCl];
|
||||
Regs[W] = Regs[PCh];
|
||||
INC16_Func(Z, W);
|
||||
break;
|
||||
case 1:
|
||||
// TEST: PC before or after the instruction?
|
||||
Regs[Z] = Regs[PCl];
|
||||
Regs[W] = Regs[PCh];
|
||||
INC16_Func(Z, W);
|
||||
break;
|
||||
case 2:
|
||||
// Nothing
|
||||
break;
|
||||
case 3:
|
||||
// Nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interrupts can occur at this point, so process them accordingly
|
||||
// Read the opcode of the next instruction
|
||||
if (EI_pending > 0)
|
||||
{
|
||||
EI_pending--;
|
||||
if (EI_pending == 0) { IFF1 = IFF2 = true; }
|
||||
}
|
||||
|
||||
// Process interrupt requests.
|
||||
if (nonMaskableInterruptPending)
|
||||
{
|
||||
nonMaskableInterruptPending = false;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
iff2 = iff1;
|
||||
iff1 = false;
|
||||
NMI_();
|
||||
NMICallback();
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
{
|
||||
iff1 = iff2 = false;
|
||||
EI_pending = 0;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
switch (interruptMode)
|
||||
{
|
||||
case 0:
|
||||
// Requires something to be pushed onto the data bus
|
||||
// we'll assume it's a zero for now
|
||||
INTERRUPT_0(0);
|
||||
break;
|
||||
case 1:
|
||||
INTERRUPT_1();
|
||||
break;
|
||||
case 2:
|
||||
// Low byte of interrupt vector comes from data bus
|
||||
// We'll assume it's zero for now
|
||||
INTERRUPT_2(0);
|
||||
break;
|
||||
}
|
||||
IRQCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (OnExecFetch != null) OnExecFetch(RegPC);
|
||||
if (TraceCallback != null) TraceCallback(State());
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
}
|
||||
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
temp_R++;
|
||||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
}
|
||||
instr_pntr = 0;
|
||||
break;
|
||||
|
||||
case HALT:
|
||||
halted = true;
|
||||
if (EI_pending > 0)
|
||||
{
|
||||
EI_pending--;
|
||||
if (EI_pending == 0) { IFF1 = IFF2 = true; }
|
||||
}
|
||||
|
||||
// Process interrupt requests.
|
||||
if (nonMaskableInterruptPending)
|
||||
{
|
||||
nonMaskableInterruptPending = false;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====NMI====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
iff2 = iff1;
|
||||
iff1 = false;
|
||||
NMI_();
|
||||
NMICallback();
|
||||
halted = false;
|
||||
}
|
||||
else if (iff1 && FlagI)
|
||||
{
|
||||
iff1 = iff2 = false;
|
||||
EI_pending = 0;
|
||||
|
||||
if (TraceCallback != null)
|
||||
{
|
||||
TraceCallback(new TraceInfo{Disassembly = "====IRQ====", RegisterInfo = ""});
|
||||
}
|
||||
|
||||
switch (interruptMode)
|
||||
{
|
||||
case 0:
|
||||
// Requires something to be pushed onto the data bus
|
||||
// we'll assume it's a zero for now
|
||||
INTERRUPT_0(0);
|
||||
break;
|
||||
case 1:
|
||||
INTERRUPT_1();
|
||||
break;
|
||||
case 2:
|
||||
// Low byte of interrupt vector comes from data bus
|
||||
// We'll assume it's zero for now
|
||||
INTERRUPT_2(0);
|
||||
break;
|
||||
}
|
||||
IRQCallback();
|
||||
halted = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_instr = new ushort[]
|
||||
{IDLE,
|
||||
IDLE,
|
||||
IDLE,
|
||||
HALT };
|
||||
}
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
temp_R++;
|
||||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
|
||||
instr_pntr = 0;
|
||||
break;
|
||||
case RD:
|
||||
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case WR:
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case I_RD:
|
||||
I_Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case I_WR:
|
||||
I_Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case TR:
|
||||
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case TR16:
|
||||
TR16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case ADD16:
|
||||
ADD16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], 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 ADC16:
|
||||
ADC_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SBC8:
|
||||
SBC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SBC16:
|
||||
SBC_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case INC16:
|
||||
INC16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case INC8:
|
||||
INC8_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case DEC16:
|
||||
DEC16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case DEC8:
|
||||
DEC8_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case RLC:
|
||||
RLC_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case RL:
|
||||
RL_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case RRC:
|
||||
RRC_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case RR:
|
||||
RR_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case CPL:
|
||||
CPL_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case DA:
|
||||
DA_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SCF:
|
||||
SCF_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case CCF:
|
||||
CCF_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 CP8:
|
||||
CP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SLA:
|
||||
SLA_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SRA:
|
||||
SRA_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SRL:
|
||||
SRL_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SLL:
|
||||
SLL_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case BIT:
|
||||
BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case I_BIT:
|
||||
I_BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case RES:
|
||||
RES_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SET:
|
||||
SET_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case EI:
|
||||
EI_pending = 2;
|
||||
break;
|
||||
case DI:
|
||||
IFF1 = IFF2 = false;
|
||||
break;
|
||||
case EXCH:
|
||||
EXCH_16_Func(F_s, A_s, F, A);
|
||||
break;
|
||||
case EXX:
|
||||
EXCH_16_Func(C_s, B_s, C, B);
|
||||
EXCH_16_Func(E_s, D_s, E, D);
|
||||
EXCH_16_Func(L_s, H_s, L, H);
|
||||
break;
|
||||
case EXCH_16:
|
||||
EXCH_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case PREFIX:
|
||||
ushort prefix_src = cur_instr[instr_pntr++];
|
||||
NO_prefix = false;
|
||||
if (prefix_src == CBpre) { CB_prefix = true; }
|
||||
if (prefix_src == EXTDpre) { EXTD_prefix = true; }
|
||||
if (prefix_src == IXpre) { IX_prefix = true; }
|
||||
if (prefix_src == IYpre) { IY_prefix = true; }
|
||||
if (prefix_src == IXCBpre) { IXCB_prefix = true; IXCB_prefetch = true; }
|
||||
if (prefix_src == IYCBpre) { IYCB_prefix = true; IYCB_prefetch = true; }
|
||||
|
||||
FetchInstruction(FetchMemory(RegPC++));
|
||||
instr_pntr = 0;
|
||||
// only the first prefix in a double prefix increases R, although I don't know how / why
|
||||
if (prefix_src < 4)
|
||||
{
|
||||
temp_R = (byte)(Regs[R] & 0x7F);
|
||||
temp_R++;
|
||||
temp_R &= 0x7F;
|
||||
Regs[R] = (byte)((Regs[R] & 0x80) | temp_R);
|
||||
}
|
||||
break;
|
||||
case ASGN:
|
||||
ASGN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case ADDS:
|
||||
ADDS_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case EI_RETI:
|
||||
// NOTE: This is needed for systems using multiple interrupt sources, it triggers the next interrupt
|
||||
// Not currently implemented here
|
||||
iff1 = iff2;
|
||||
break;
|
||||
case EI_RETN:
|
||||
iff1 = iff2;
|
||||
break;
|
||||
case OUT:
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case IN:
|
||||
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case NEG:
|
||||
NEG_8_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case INT_MODE:
|
||||
interruptMode = cur_instr[instr_pntr++];
|
||||
break;
|
||||
case RRD:
|
||||
RRD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case RLD:
|
||||
RLD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
break;
|
||||
case SET_FL_LD:
|
||||
SET_FL_LD_Func();
|
||||
break;
|
||||
case SET_FL_CP:
|
||||
SET_FL_CP_Func();
|
||||
break;
|
||||
case SET_FL_IR:
|
||||
SET_FL_IR_Func(cur_instr[instr_pntr++]);
|
||||
break;
|
||||
}
|
||||
totalExecutedCycles++;
|
||||
}
|
||||
|
||||
// tracer stuff
|
||||
public Action<TraceInfo> TraceCallback;
|
||||
|
||||
public string TraceHeader
|
||||
{
|
||||
get { return "Z80A: PC, machine code, mnemonic, operands, registers (AF, BC, DE, HL, IX, IY, SP, Cy), flags (CNP3H5ZS)"; }
|
||||
}
|
||||
|
||||
public TraceInfo State(bool disassemble = true)
|
||||
{
|
||||
ushort bytes_read = 0;
|
||||
|
||||
string disasm = disassemble ? Disassemble(RegPC, ReadMemory, out bytes_read) : "---";
|
||||
string byte_code = null;
|
||||
|
||||
for (ushort i = 0; i < bytes_read; i++)
|
||||
{
|
||||
byte_code += ReadMemory((ushort)(RegPC + i)).ToHexString(2);
|
||||
if (i < (bytes_read - 1))
|
||||
{
|
||||
byte_code += " ";
|
||||
}
|
||||
}
|
||||
|
||||
return new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format(
|
||||
"{0:X4}: {1} {2}",
|
||||
RegPC,
|
||||
byte_code.PadRight(12),
|
||||
disasm.PadRight(26)),
|
||||
RegisterInfo = string.Format(
|
||||
"AF:{0:X4} BC:{1:X4} DE:{2:X4} HL:{3:X4} IX:{4:X4} IY:{5:X4} SP:{6:X4} Cy:{7} {8}{9}{10}{11}{12}{13}{14}{15}{16}",
|
||||
(Regs[A] << 8) + Regs[F],
|
||||
(Regs[B] << 8) + Regs[C],
|
||||
(Regs[D] << 8) + Regs[E],
|
||||
(Regs[H] << 8) + Regs[L],
|
||||
(Regs[Ixh] << 8) + Regs[Ixl],
|
||||
(Regs[Iyh] << 8) + Regs[Iyl],
|
||||
Regs[SPl] | (Regs[SPh] << 8),
|
||||
TotalExecutedCycles,
|
||||
FlagC ? "C" : "c",
|
||||
FlagN ? "N" : "n",
|
||||
FlagP ? "P" : "p",
|
||||
Flag3 ? "3" : "-",
|
||||
FlagH ? "H" : "h",
|
||||
Flag5 ? "5" : "-",
|
||||
FlagZ ? "Z" : "z",
|
||||
FlagS ? "S" : "s",
|
||||
FlagI ? "E" : "e")
|
||||
};
|
||||
}
|
||||
// State Save/Load
|
||||
|
||||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("Z80A");
|
||||
ser.Sync("Regs", ref Regs, false);
|
||||
ser.Sync("NMI", ref nonMaskableInterrupt);
|
||||
ser.Sync("NMIPending", ref nonMaskableInterruptPending);
|
||||
ser.Sync("IM", ref interruptMode);
|
||||
ser.Sync("IFF1", ref iff1);
|
||||
ser.Sync("IFF2", ref iff2);
|
||||
ser.Sync("Halted", ref halted);
|
||||
ser.Sync("ExecutedCycles", ref totalExecutedCycles);
|
||||
ser.Sync("EI_pending", ref EI_pending);
|
||||
|
||||
ser.Sync("instruction_pointer", ref instr_pntr);
|
||||
ser.Sync("current instruction", ref cur_instr, false);
|
||||
ser.Sync("opcode", ref opcode);
|
||||
ser.Sync("FlagI", ref FlagI);
|
||||
|
||||
ser.Sync("NO Preifx", ref NO_prefix);
|
||||
ser.Sync("CB Preifx", ref CB_prefix);
|
||||
ser.Sync("IX_prefix", ref IX_prefix);
|
||||
ser.Sync("IY_prefix", ref IY_prefix);
|
||||
ser.Sync("IXCB_prefix", ref IXCB_prefix);
|
||||
ser.Sync("IYCB_prefix", ref IYCB_prefix);
|
||||
ser.Sync("EXTD_prefix", ref EXTD_prefix);
|
||||
ser.Sync("IXCB_prefetch", ref IXCB_prefetch);
|
||||
ser.Sync("IYCB_prefetch", ref IYCB_prefetch);
|
||||
ser.Sync("PF", ref PF);
|
||||
|
||||
ser.EndSection();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,36 +12,36 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
{
|
||||
return new Dictionary<string, RegisterValue>
|
||||
{
|
||||
["A"] = _cpu.RegisterA,
|
||||
["AF"] = _cpu.RegisterAF,
|
||||
["B"] = _cpu.RegisterB,
|
||||
["BC"] = _cpu.RegisterBC,
|
||||
["C"] = _cpu.RegisterC,
|
||||
["D"] = _cpu.RegisterD,
|
||||
["DE"] = _cpu.RegisterDE,
|
||||
["E"] = _cpu.RegisterE,
|
||||
["F"] = _cpu.RegisterF,
|
||||
["H"] = _cpu.RegisterH,
|
||||
["HL"] = _cpu.RegisterHL,
|
||||
["I"] = _cpu.RegisterI,
|
||||
["IX"] = _cpu.RegisterIX,
|
||||
["IY"] = _cpu.RegisterIY,
|
||||
["L"] = _cpu.RegisterL,
|
||||
["PC"] = _cpu.RegisterPC,
|
||||
["R"] = _cpu.RegisterR,
|
||||
["Shadow AF"] = _cpu.RegisterShadowAF,
|
||||
["Shadow BC"] = _cpu.RegisterShadowBC,
|
||||
["Shadow DE"] = _cpu.RegisterShadowDE,
|
||||
["Shadow HL"] = _cpu.RegisterShadowHL,
|
||||
["SP"] = _cpu.RegisterSP,
|
||||
["Flag C"] = _cpu.RegisterF.Bit(0),
|
||||
["Flag N"] = _cpu.RegisterF.Bit(1),
|
||||
["Flag P/V"] = _cpu.RegisterF.Bit(2),
|
||||
["Flag 3rd"] = _cpu.RegisterF.Bit(3),
|
||||
["Flag H"] = _cpu.RegisterF.Bit(4),
|
||||
["Flag 5th"] = _cpu.RegisterF.Bit(5),
|
||||
["Flag Z"] = _cpu.RegisterF.Bit(6),
|
||||
["Flag S"] = _cpu.RegisterF.Bit(7)
|
||||
["A"] = _cpu.Regs[_cpu.A],
|
||||
["AF"] = _cpu.Regs[_cpu.F] + (_cpu.Regs[_cpu.A] << 8),
|
||||
["B"] = _cpu.Regs[_cpu.B],
|
||||
["BC"] = _cpu.Regs[_cpu.C] + (_cpu.Regs[_cpu.B] << 8),
|
||||
["C"] = _cpu.Regs[_cpu.C],
|
||||
["D"] = _cpu.Regs[_cpu.D],
|
||||
["DE"] = _cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8),
|
||||
["E"] = _cpu.Regs[_cpu.E],
|
||||
["F"] = _cpu.Regs[_cpu.F],
|
||||
["H"] = _cpu.Regs[_cpu.H],
|
||||
["HL"] = _cpu.Regs[_cpu.L] + (_cpu.Regs[_cpu.H] << 8),
|
||||
["I"] = _cpu.Regs[_cpu.I],
|
||||
["IX"] = _cpu.Regs[_cpu.Ixl] + (_cpu.Regs[_cpu.Ixh] << 8),
|
||||
["IY"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
|
||||
["L"] = _cpu.Regs[_cpu.L],
|
||||
["PC"] = _cpu.Regs[_cpu.PCl] + (_cpu.Regs[_cpu.PCh] << 8),
|
||||
["R"] = _cpu.Regs[_cpu.R],
|
||||
["Shadow AF"] = _cpu.Regs[_cpu.F_s] + (_cpu.Regs[_cpu.A_s] << 8),
|
||||
["Shadow BC"] = _cpu.Regs[_cpu.C_s] + (_cpu.Regs[_cpu.B_s] << 8),
|
||||
["Shadow DE"] = _cpu.Regs[_cpu.E_s] + (_cpu.Regs[_cpu.D_s] << 8),
|
||||
["Shadow HL"] = _cpu.Regs[_cpu.L_s] + (_cpu.Regs[_cpu.H_s] << 8),
|
||||
["SP"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
|
||||
["Flag C"] = _cpu.FlagC,
|
||||
["Flag N"] = _cpu.FlagN,
|
||||
["Flag P/V"] = _cpu.FlagP,
|
||||
["Flag 3rd"] = _cpu.Flag3,
|
||||
["Flag H"] = _cpu.FlagH,
|
||||
["Flag 5th"] = _cpu.Flag5,
|
||||
["Flag Z"] = _cpu.FlagZ,
|
||||
["Flag S"] = _cpu.FlagS
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,78 +49,90 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
{
|
||||
switch (register)
|
||||
{
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
case "A":
|
||||
_cpu.RegisterA = (byte)value;
|
||||
break;
|
||||
case "AF":
|
||||
_cpu.RegisterAF = (byte)value;
|
||||
break;
|
||||
case "B":
|
||||
_cpu.RegisterB = (byte)value;
|
||||
break;
|
||||
case "BC":
|
||||
_cpu.RegisterBC = (byte)value;
|
||||
break;
|
||||
case "C":
|
||||
_cpu.RegisterC = (byte)value;
|
||||
break;
|
||||
case "D":
|
||||
_cpu.RegisterD = (byte)value;
|
||||
break;
|
||||
case "DE":
|
||||
_cpu.RegisterDE = (byte)value;
|
||||
break;
|
||||
case "E":
|
||||
_cpu.RegisterE = (byte)value;
|
||||
break;
|
||||
case "F":
|
||||
_cpu.RegisterF = (byte)value;
|
||||
break;
|
||||
case "H":
|
||||
_cpu.RegisterH = (byte)value;
|
||||
break;
|
||||
case "HL":
|
||||
_cpu.RegisterHL = (byte)value;
|
||||
break;
|
||||
case "I":
|
||||
_cpu.RegisterI = (byte)value;
|
||||
break;
|
||||
case "IX":
|
||||
_cpu.RegisterIX = (byte)value;
|
||||
break;
|
||||
case "IY":
|
||||
_cpu.RegisterIY = (byte)value;
|
||||
break;
|
||||
case "L":
|
||||
_cpu.RegisterL = (byte)value;
|
||||
break;
|
||||
case "PC":
|
||||
_cpu.RegisterPC = (ushort)value;
|
||||
break;
|
||||
case "R":
|
||||
_cpu.RegisterR = (byte)value;
|
||||
break;
|
||||
case "Shadow AF":
|
||||
_cpu.RegisterShadowAF = (byte)value;
|
||||
break;
|
||||
case "Shadow BC":
|
||||
_cpu.RegisterShadowBC = (byte)value;
|
||||
break;
|
||||
case "Shadow DE":
|
||||
_cpu.RegisterShadowDE = (byte)value;
|
||||
break;
|
||||
case "Shadow HL":
|
||||
_cpu.RegisterShadowHL = (byte)value;
|
||||
break;
|
||||
case "SP":
|
||||
_cpu.RegisterSP = (byte)value;
|
||||
default:
|
||||
throw new InvalidOperationException();
|
||||
case "A":
|
||||
_cpu.Regs[_cpu.A] = (ushort)value;
|
||||
break;
|
||||
case "AF":
|
||||
_cpu.Regs[_cpu.F] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.A] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "B":
|
||||
_cpu.Regs[_cpu.B] = (ushort)value;
|
||||
break;
|
||||
case "BC":
|
||||
_cpu.Regs[_cpu.C] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.B] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "C":
|
||||
_cpu.Regs[_cpu.C] = (ushort)value;
|
||||
break;
|
||||
case "D":
|
||||
_cpu.Regs[_cpu.D] = (ushort)value;
|
||||
break;
|
||||
case "DE":
|
||||
_cpu.Regs[_cpu.E] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.D] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "E":
|
||||
_cpu.Regs[_cpu.E] = (ushort)value;
|
||||
break;
|
||||
case "F":
|
||||
_cpu.Regs[_cpu.F] = (ushort)value;
|
||||
break;
|
||||
case "H":
|
||||
_cpu.Regs[_cpu.H] = (ushort)value;
|
||||
break;
|
||||
case "HL":
|
||||
_cpu.Regs[_cpu.L] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.H] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "I":
|
||||
_cpu.Regs[_cpu.I] = (ushort)value;
|
||||
break;
|
||||
case "IX":
|
||||
_cpu.Regs[_cpu.Ixl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.Ixh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "IY":
|
||||
_cpu.Regs[_cpu.Iyl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.Iyh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "L":
|
||||
_cpu.Regs[_cpu.L] = (ushort)value;
|
||||
break;
|
||||
case "PC":
|
||||
_cpu.Regs[_cpu.PCl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.PCh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "R":
|
||||
_cpu.Regs[_cpu.R] = (ushort)value;
|
||||
break;
|
||||
case "Shadow AF":
|
||||
_cpu.Regs[_cpu.F_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.A_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow BC":
|
||||
_cpu.Regs[_cpu.C_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.B_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow DE":
|
||||
_cpu.Regs[_cpu.E_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.D_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow HL":
|
||||
_cpu.Regs[_cpu.L_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.H_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "SP":
|
||||
_cpu.Regs[_cpu.SPl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.SPh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem();
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void Step(StepType type)
|
||||
|
|
|
@ -13,21 +13,42 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
_controller = controller;
|
||||
_lagged = true;
|
||||
|
||||
_cpu.Debug = _tracer.Enabled;
|
||||
|
||||
if (_cpu.Debug && _cpu.Logger == null) // TODO, lets not do this on each frame. But lets refactor CoreComm/CoreComm first
|
||||
if (_tracer.Enabled)
|
||||
{
|
||||
_cpu.Logger = s => _tracer.Put(s);
|
||||
_cpu.TraceCallback = s => _tracer.Put(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cpu.TraceCallback = null;
|
||||
}
|
||||
|
||||
// I eyeballed this speed
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
_onPressed = controller.IsPressed("ON");
|
||||
_onPressed = controller.IsPressed("ON");
|
||||
|
||||
// and this was derived from other emus
|
||||
_cpu.ExecuteCycles(10000);
|
||||
_cpu.Interrupt = true;
|
||||
if (_onPressed && ON_key_int_EN && !ON_key_int)
|
||||
{
|
||||
ON_key_int = true;
|
||||
_cpu.FlagI = true;
|
||||
}
|
||||
|
||||
// see: http://wikiti.brandonw.net/index.php?title=83:Ports:04
|
||||
// for timer interrupt frequency
|
||||
|
||||
// CPU frequency is 6MHz
|
||||
for (int i = 0; i < 100000; i++)
|
||||
{
|
||||
_cpu.ExecuteOne();
|
||||
|
||||
TIM_count++;
|
||||
if (TIM_count >= TIM_hit)
|
||||
{
|
||||
TIM_count = 0;
|
||||
|
||||
if (TIM_1_int_EN)
|
||||
{
|
||||
TIM_1_int = true;
|
||||
_cpu.FlagI = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Frame++;
|
||||
|
|
|
@ -7,55 +7,52 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
{
|
||||
public partial class TI83 : IStatable
|
||||
{
|
||||
private byte[] _stateBuffer;
|
||||
public bool BinarySaveStatesPreferred
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public bool BinarySaveStatesPreferred => false;
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
SyncState(new Serializer(writer));
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
SyncState(new Serializer(reader));
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
SyncState(Serializer.CreateBinaryWriter(bw));
|
||||
SyncState(new Serializer(bw));
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
SyncState(Serializer.CreateBinaryReader(br));
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter tw)
|
||||
{
|
||||
SyncState(Serializer.CreateTextWriter(tw));
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader tr)
|
||||
{
|
||||
SyncState(Serializer.CreateTextReader(tr));
|
||||
SyncState(new Serializer(br));
|
||||
}
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
if (_stateBuffer == null)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var writer = new BinaryWriter(stream);
|
||||
SaveStateBinary(writer);
|
||||
_stateBuffer = stream.ToArray();
|
||||
writer.Close();
|
||||
return _stateBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
var stream = new MemoryStream(_stateBuffer);
|
||||
var writer = new BinaryWriter(stream);
|
||||
SaveStateBinary(writer);
|
||||
writer.Close();
|
||||
return _stateBuffer;
|
||||
}
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter bw = new BinaryWriter(ms);
|
||||
SaveStateBinary(bw);
|
||||
bw.Flush();
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("TI83");
|
||||
byte[] core = null;
|
||||
if (ser.IsWriter)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
ms.Close();
|
||||
core = ms.ToArray();
|
||||
}
|
||||
_cpu.SyncState(ser);
|
||||
|
||||
ser.BeginSection("TI83");
|
||||
ser.Sync("RAM", ref _ram, false);
|
||||
ser.Sync("romPageLow3Bits", ref _romPageLow3Bits);
|
||||
ser.Sync("romPageHighBit", ref _romPageHighBit);
|
||||
|
@ -72,6 +69,15 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
ser.Sync("Frame", ref _frame);
|
||||
ser.Sync("LagCount", ref _lagCount);
|
||||
ser.Sync("IsLag", ref _isLag);
|
||||
ser.Sync("ON_key_int", ref ON_key_int);
|
||||
ser.Sync("ON_key_int_EN", ref ON_key_int_EN);
|
||||
ser.Sync("TIM_1_int", ref TIM_1_int);
|
||||
ser.Sync("TIM_1_int_EN", ref TIM_1_int_EN);
|
||||
ser.Sync("TIM_frq", ref TIM_frq);
|
||||
ser.Sync("TIM_mult", ref TIM_mult);
|
||||
ser.Sync("TIM_count", ref TIM_count);
|
||||
ser.Sync("TIM_hit", ref TIM_hit);
|
||||
|
||||
ser.EndSection();
|
||||
|
||||
if (ser.IsReader)
|
||||
|
|
|
@ -2,7 +2,7 @@ using System;
|
|||
using System.Globalization;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components.Z80;
|
||||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
// http://www.ticalc.org/pub/text/calcinfo/
|
||||
namespace BizHawk.Emulation.Cores.Calculators
|
||||
|
@ -23,6 +23,7 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
PutSettings((TI83Settings)settings ?? new TI83Settings());
|
||||
|
||||
CoreComm = comm;
|
||||
_cpu.FetchMemory = ReadMemory;
|
||||
_cpu.ReadMemory = ReadMemory;
|
||||
_cpu.WriteMemory = WriteMemory;
|
||||
_cpu.ReadHardware = ReadHardware;
|
||||
|
@ -34,21 +35,13 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
_rom = rom;
|
||||
LinkPort = new TI83LinkPort(this);
|
||||
|
||||
// different calculators (different revisions?) have different initPC. we track this in the game database by rom hash
|
||||
// if( *(unsigned long *)(m_pRom + 0x6ce) == 0x04D3163E ) m_Regs.PC.W = 0x6ce; //KNOWN
|
||||
// else if( *(unsigned long *)(m_pRom + 0x6f6) == 0x04D3163E ) m_Regs.PC.W = 0x6f6; //UNKNOWN
|
||||
if (game["initPC"])
|
||||
{
|
||||
_startPC = ushort.Parse(game.OptionValue("initPC"), NumberStyles.HexNumber);
|
||||
}
|
||||
|
||||
HardReset();
|
||||
SetupMemoryDomains();
|
||||
|
||||
_tracer = new TraceBuffer { Header = _cpu.TraceHeader };
|
||||
|
||||
ser.Register<ITraceable>(_tracer);
|
||||
ser.Register<IDisassemblable>(new Disassembler());
|
||||
ser.Register<IDisassemblable>(_cpu);
|
||||
}
|
||||
|
||||
private readonly TraceBuffer _tracer;
|
||||
|
@ -57,8 +50,6 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
private readonly byte[] _rom;
|
||||
|
||||
// configuration
|
||||
private readonly ushort _startPC;
|
||||
|
||||
private IController _controller;
|
||||
|
||||
private byte[] _ram;
|
||||
|
@ -75,6 +66,10 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
private bool _cursorMoved;
|
||||
private int _frame;
|
||||
|
||||
public bool ON_key_int, ON_key_int_EN;
|
||||
public bool TIM_1_int, TIM_1_int_EN;
|
||||
public int TIM_frq, TIM_mult, TIM_count, TIM_hit;
|
||||
|
||||
// Link Cable
|
||||
public TI83LinkPort LinkPort { get; }
|
||||
|
||||
|
@ -151,7 +146,7 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
if (LinkActive)
|
||||
{
|
||||
// Prevent rom calls from disturbing link port activity
|
||||
if (LinkActive && _cpu.RegisterPC < 0x4000)
|
||||
if (LinkActive && _cpu.RegPC < 0x4000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -169,7 +164,60 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
_romPageLow3Bits = value & 0x7;
|
||||
break;
|
||||
case 3: // PORT_STATUS
|
||||
_maskOn = (byte)(value & 1);
|
||||
// controls ON key interrupts
|
||||
if ((value & 0x1) == 0)
|
||||
{
|
||||
ON_key_int = false;
|
||||
ON_key_int_EN = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ON_key_int_EN = true;
|
||||
}
|
||||
|
||||
// controls first timer interrupts
|
||||
if ((value & 0x2) == 0)
|
||||
{
|
||||
TIM_1_int = false;
|
||||
TIM_1_int_EN = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TIM_1_int_EN = true;
|
||||
}
|
||||
|
||||
// controls second timer, not yet implemented and unclear how to differentiate
|
||||
if ((value & 0x4) == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
// controls low power mode, not yet implemeneted
|
||||
if ((value & 0x8) == 0)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
break;
|
||||
case 4: // PORT_INTCTRL
|
||||
// controls ON key interrupts
|
||||
TIM_frq = value & 6;
|
||||
|
||||
TIM_mult = ((value & 0x10) == 0x10) ? 1800 : 1620;
|
||||
|
||||
TIM_hit = (int)Math.Floor((double)TIM_mult / (3 + TIM_frq * 2));
|
||||
|
||||
TIM_hit = (int)Math.Floor((double)6000000 / TIM_hit);
|
||||
|
||||
// Bit 0 is some form of memory mapping
|
||||
|
||||
// Bit 5 controls reset
|
||||
|
||||
// Bit 6-7 controls battery power compare (not implemented, will always return full power)
|
||||
|
||||
break;
|
||||
case 16: // PORT_DISPCTRL
|
||||
////Console.WriteLine("write PORT_DISPCTRL {0}",value);
|
||||
|
@ -198,22 +246,23 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
{
|
||||
// Console.WriteLine("read PORT_STATUS");
|
||||
// Bits:
|
||||
// 0 - Set if ON key is down and ON key is trapped
|
||||
// 0 - Set if ON key Interrupt generated
|
||||
// 1 - Update things (keyboard etc)
|
||||
// 2 - Unknown, but used
|
||||
// 3 - Set if ON key is up
|
||||
// 4-7 - Unknown
|
||||
////if (onPressed && maskOn) ret |= 1;
|
||||
////if (!onPressed) ret |= 0x8;
|
||||
return (byte)((_controller.IsPressed("ON") ? _maskOn : 8) | (LinkActive ? 0 : 2));
|
||||
|
||||
return (byte)((_controller.IsPressed("ON") ? 0 : 8) |
|
||||
(TIM_1_int ? 2 : 0) |
|
||||
(ON_key_int ? 1 : 0));
|
||||
}
|
||||
|
||||
case 4: // PORT_INTCTRL
|
||||
////Console.WriteLine("read PORT_INTCTRL");
|
||||
return 0xFF;
|
||||
// returns mirror of link port
|
||||
return (byte)((_romPageHighBit << 4) | (LinkState << 2) | LinkOutput);
|
||||
|
||||
case 16: // PORT_DISPCTRL
|
||||
////Console.WriteLine("read DISPCTRL");
|
||||
// Console.WriteLine("read DISPCTRL");
|
||||
break;
|
||||
|
||||
case 17: // PORT_DISPDATA
|
||||
|
@ -428,13 +477,13 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
|
||||
private void IRQCallback()
|
||||
{
|
||||
// Console.WriteLine("IRQ with vec {0} and cpu.InterruptMode {1}", cpu.RegisterI, cpu.InterruptMode);
|
||||
_cpu.Interrupt = false;
|
||||
//Console.WriteLine("IRQ with vec {0} and cpu.InterruptMode {1}", _cpu.Regs[_cpu.I], _cpu.InterruptMode);
|
||||
_cpu.FlagI = false;
|
||||
}
|
||||
|
||||
private void NMICallback()
|
||||
{
|
||||
Console.WriteLine("NMI");
|
||||
//Console.WriteLine("NMI");
|
||||
_cpu.NonMaskableInterrupt = false;
|
||||
}
|
||||
|
||||
|
@ -447,7 +496,7 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
_ram[i] = 0xFF;
|
||||
}
|
||||
|
||||
_cpu.RegisterPC = _startPC;
|
||||
_cpu.RegPC = 0;
|
||||
|
||||
_cpu.IFF1 = false;
|
||||
_cpu.IFF2 = false;
|
||||
|
@ -463,4 +512,4 @@ namespace BizHawk.Emulation.Cores.Calculators
|
|||
_displayX = _displayY = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
}
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem();
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
public bool CanStep(StepType type)
|
||||
{
|
||||
|
|
|
@ -183,9 +183,9 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
|
||||
private void SetCallbacks()
|
||||
{
|
||||
_machine.Memory.ReadCallback = MemoryCallbacks.CallReads;
|
||||
_machine.Memory.WriteCallback = MemoryCallbacks.CallWrites;
|
||||
_machine.Memory.ExecuteCallback = MemoryCallbacks.CallExecutes;
|
||||
_machine.Memory.ReadCallback = (addr) => MemoryCallbacks.CallReads(addr, "System Bus");
|
||||
_machine.Memory.WriteCallback = (addr) => MemoryCallbacks.CallWrites(addr, "System Bus");
|
||||
_machine.Memory.ExecuteCallback = (addr) => MemoryCallbacks.CallExecutes(addr, "System Bus");
|
||||
_machine.Memory.InputCallback = InputCallbacks.Call;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64
|
|||
|
||||
Init(SyncSettings.VicType, Settings.BorderType, SyncSettings.SidType, SyncSettings.TapeDriveType, SyncSettings.DiskDriveType);
|
||||
_cyclesPerFrame = _board.Vic.CyclesPerFrame;
|
||||
_memoryCallbacks = new MemoryCallbackSystem();
|
||||
_memoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
HardReset();
|
||||
|
||||
|
|
|
@ -148,6 +148,6 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.MOS
|
|||
|
||||
private const byte JsrSize = 3;
|
||||
|
||||
IMemoryCallbackSystem IDebuggable.MemoryCallbacks { get; } = new MemoryCallbackSystem();
|
||||
IMemoryCallbackSystem IDebuggable.MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
private IController _controller;
|
||||
private int _frame;
|
||||
private int _lastAddress;
|
||||
private bool _frameStartPending = true;
|
||||
|
||||
private bool _leftDifficultySwitchPressed;
|
||||
private bool _rightDifficultySwitchPressed;
|
||||
|
@ -34,6 +33,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
internal byte[] Rom { get; }
|
||||
internal int DistinctAccessCount { get; private set; }
|
||||
|
||||
// keeps track of tia cycles, 3 cycles per CPU cycle
|
||||
private int cyc_counter;
|
||||
|
||||
private static MapperBase SetMultiCartMapper(int romLength, int gameTotal)
|
||||
{
|
||||
switch (romLength / gameTotal)
|
||||
|
@ -134,7 +136,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
_mapper.Bit13 = addr.Bit(13);
|
||||
var temp = _mapper.ReadMemory((ushort)(addr & 0x1FFF));
|
||||
_tia.BusState = temp;
|
||||
MemoryCallbacks.CallReads(addr);
|
||||
MemoryCallbacks.CallReads(addr, "System Bus");
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
@ -155,7 +157,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
_mapper.WriteMemory((ushort)(addr & 0x1FFF), value);
|
||||
|
||||
MemoryCallbacks.CallWrites(addr);
|
||||
MemoryCallbacks.CallWrites(addr, "System Bus");
|
||||
}
|
||||
|
||||
internal void PokeMemory(ushort addr, byte value)
|
||||
|
@ -165,7 +167,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
private void ExecFetch(ushort addr)
|
||||
{
|
||||
MemoryCallbacks.CallExecutes(addr);
|
||||
MemoryCallbacks.CallExecutes(addr, "System Bus");
|
||||
}
|
||||
|
||||
private void RebootCore()
|
||||
|
@ -319,17 +321,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
_m6532 = new M6532(this);
|
||||
|
||||
// Set up the system state here. for instance..
|
||||
// Read from the reset vector for where to start
|
||||
Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC
|
||||
HardReset();
|
||||
|
||||
// Show mapper class on romstatusdetails
|
||||
CoreComm.RomStatusDetails = $"{this._game.Name}\r\nSHA1:{Rom.HashSHA1()}\r\nMD5:{Rom.HashMD5()}\r\nMapper Impl \"{_mapper.GetType()}\"";
|
||||
|
||||
// as it turns out, the stack pointer cannot be set to 0 for some games as they do not initilize it themselves.
|
||||
// some documentation seems to indicate it should beset to FD, but currently there is no documentation of the 6532
|
||||
// executing a reset sequence at power on, but it's needed so let's hard code it for now
|
||||
Cpu.S = 0xFD;
|
||||
}
|
||||
|
||||
private bool _pal;
|
||||
|
@ -349,96 +344,28 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
};
|
||||
|
||||
_tia.Reset();
|
||||
|
||||
_m6532 = new M6532(this);
|
||||
Cpu.PC = (ushort)(ReadMemory(0x1FFC) + (ReadMemory(0x1FFD) << 8)); // set the initial PC
|
||||
|
||||
// as it turns out, the stack pointer cannot be set to 0 for some games as they do not initilize it themselves.
|
||||
// some documentation seems to indicate it should beset to FD, but currently there is no documentation of the 6532
|
||||
// executing a reset sequence at power on, but it's needed so let's hard code it for now
|
||||
Cpu.S = 0xFD;
|
||||
|
||||
SetupMemoryDomains();
|
||||
}
|
||||
|
||||
private void VFrameAdvance() // advance up to 500 lines looking for end of video frame
|
||||
// after vsync falling edge, continues to end of next line
|
||||
{
|
||||
bool frameend = false;
|
||||
_tia.FrameEndCallBack = (n) => frameend = true;
|
||||
for (int i = 0; i < 500 && !frameend; i++)
|
||||
{
|
||||
ScanlineAdvance();
|
||||
}
|
||||
|
||||
_tia.FrameEndCallBack = null;
|
||||
}
|
||||
|
||||
private void StartFrameCond()
|
||||
{
|
||||
if (_frameStartPending)
|
||||
{
|
||||
_frame++;
|
||||
_islag = true;
|
||||
|
||||
if (_controller.IsPressed("Power"))
|
||||
{
|
||||
HardReset();
|
||||
}
|
||||
|
||||
if (_controller.IsPressed("Toggle Left Difficulty") && !_leftDifficultySwitchHeld)
|
||||
{
|
||||
_leftDifficultySwitchPressed ^= true;
|
||||
_leftDifficultySwitchHeld = true;
|
||||
}
|
||||
else if (!_controller.IsPressed("Toggle Left Difficulty"))
|
||||
{
|
||||
_leftDifficultySwitchHeld = false;
|
||||
}
|
||||
|
||||
if (_controller.IsPressed("Toggle Right Difficulty") && !_rightDifficultySwitchHeld)
|
||||
{
|
||||
_rightDifficultySwitchPressed ^= true;
|
||||
_rightDifficultySwitchHeld = true;
|
||||
}
|
||||
else if (!_controller.IsPressed("Toggle Right Difficulty"))
|
||||
{
|
||||
_rightDifficultySwitchHeld = false;
|
||||
}
|
||||
|
||||
_tia.BeginAudioFrame();
|
||||
_frameStartPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void FinishFrameCond()
|
||||
{
|
||||
if (_tia.LineCount >= _tia.NominalNumScanlines)
|
||||
{
|
||||
_tia.CompleteAudioFrame();
|
||||
if (_islag)
|
||||
{
|
||||
_lagcount++;
|
||||
}
|
||||
|
||||
_tia.LineCount = 0;
|
||||
_frameStartPending = true;
|
||||
}
|
||||
cyc_counter = 0;
|
||||
}
|
||||
|
||||
private void Cycle()
|
||||
{
|
||||
_tia.Execute(1);
|
||||
_tia.Execute(1);
|
||||
_tia.Execute(1);
|
||||
_m6532.Timer.Tick();
|
||||
if (Tracer.Enabled)
|
||||
_tia.Execute();
|
||||
cyc_counter++;
|
||||
if (cyc_counter == 3)
|
||||
{
|
||||
Tracer.Put(Cpu.TraceState());
|
||||
}
|
||||
_m6532.Timer.Tick();
|
||||
if (Tracer.Enabled)
|
||||
{
|
||||
Tracer.Put(Cpu.TraceState());
|
||||
}
|
||||
|
||||
Cpu.ExecuteOne();
|
||||
_mapper.ClockCpu();
|
||||
Cpu.ExecuteOne();
|
||||
_mapper.ClockCpu();
|
||||
|
||||
cyc_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal byte ReadControls1(bool peek)
|
||||
|
|
|
@ -56,101 +56,22 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem();
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
public bool CanStep(StepType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case StepType.Into:
|
||||
case StepType.Out:
|
||||
case StepType.Over:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void Step(StepType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case StepType.Into:
|
||||
StepInto();
|
||||
break;
|
||||
case StepType.Out:
|
||||
StepOut();
|
||||
break;
|
||||
case StepType.Over:
|
||||
StepOver();
|
||||
break;
|
||||
}
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public int TotalExecutedCycles => Cpu.TotalExecutedCycles;
|
||||
|
||||
private void StepInto()
|
||||
{
|
||||
do
|
||||
{
|
||||
CycleAdvance();
|
||||
} while (!Cpu.AtStart);
|
||||
}
|
||||
|
||||
private void StepOver()
|
||||
{
|
||||
var instruction = Cpu.PeekMemory(Cpu.PC);
|
||||
|
||||
if (instruction == JSR)
|
||||
{
|
||||
var destination = Cpu.PC + opsize[JSR];
|
||||
while (Cpu.PC != destination)
|
||||
{
|
||||
StepInto();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StepInto();
|
||||
}
|
||||
}
|
||||
|
||||
private void StepOut()
|
||||
{
|
||||
var instruction = Cpu.PeekMemory(Cpu.PC);
|
||||
|
||||
JSRCount = instruction == JSR ? 1 : 0;
|
||||
|
||||
var bailOutFrame = Frame + 1;
|
||||
while (true)
|
||||
{
|
||||
StepInto();
|
||||
var instr = Cpu.PeekMemory(Cpu.PC);
|
||||
if (instr == JSR)
|
||||
{
|
||||
JSRCount++;
|
||||
}
|
||||
else if (instr == RTS && JSRCount <= 0)
|
||||
{
|
||||
StepInto();
|
||||
JSRCount = 0;
|
||||
break;
|
||||
}
|
||||
else if (instr == RTS)
|
||||
{
|
||||
JSRCount--;
|
||||
}
|
||||
else // Emergency bail out logic
|
||||
{
|
||||
if (Frame == bailOutFrame)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int JSRCount = 0;
|
||||
|
||||
private const byte JSR = 0x20;
|
||||
|
@ -212,22 +133,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
|
||||
#region Currently Unused Debug hooks
|
||||
|
||||
private void ScanlineAdvance()
|
||||
{
|
||||
StartFrameCond();
|
||||
int currentLine = _tia.LineCount;
|
||||
while (_tia.LineCount == currentLine)
|
||||
Cycle();
|
||||
FinishFrameCond();
|
||||
}
|
||||
|
||||
private void CycleAdvance()
|
||||
{
|
||||
StartFrameCond();
|
||||
Cycle();
|
||||
FinishFrameCond();
|
||||
}
|
||||
|
||||
private int CurrentScanLine
|
||||
{
|
||||
get { return _tia.LineCount; }
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
||||
{
|
||||
|
@ -12,18 +13,56 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
_controller = controller;
|
||||
|
||||
StartFrameCond();
|
||||
while (_tia.LineCount < _tia.NominalNumScanlines)
|
||||
_frame++;
|
||||
_islag = true;
|
||||
|
||||
// Handle all the console controls here
|
||||
if (_controller.IsPressed("Power"))
|
||||
{
|
||||
HardReset();
|
||||
}
|
||||
|
||||
if (_controller.IsPressed("Toggle Left Difficulty") && !_leftDifficultySwitchHeld)
|
||||
{
|
||||
_leftDifficultySwitchPressed ^= true;
|
||||
_leftDifficultySwitchHeld = true;
|
||||
}
|
||||
else if (!_controller.IsPressed("Toggle Left Difficulty"))
|
||||
{
|
||||
_leftDifficultySwitchHeld = false;
|
||||
}
|
||||
|
||||
if (_controller.IsPressed("Toggle Right Difficulty") && !_rightDifficultySwitchHeld)
|
||||
{
|
||||
_rightDifficultySwitchPressed ^= true;
|
||||
_rightDifficultySwitchHeld = true;
|
||||
}
|
||||
else if (!_controller.IsPressed("Toggle Right Difficulty"))
|
||||
{
|
||||
_rightDifficultySwitchHeld = false;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
while (!_tia.New_Frame)
|
||||
{
|
||||
Cycle();
|
||||
count++;
|
||||
if (count > 1000000) { throw new Exception("ERROR: Unable to resolve Frame. Please Report."); }
|
||||
}
|
||||
|
||||
_tia.New_Frame = false;
|
||||
|
||||
if (rendersound == false)
|
||||
{
|
||||
_tia.AudioClocks = 0; // we need this here since the async sound provider won't check in this case
|
||||
}
|
||||
|
||||
FinishFrameCond();
|
||||
if (_islag)
|
||||
{
|
||||
_lagcount++;
|
||||
}
|
||||
|
||||
_tia.LineCount = 0;
|
||||
}
|
||||
|
||||
public int Frame => _frame;
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
ser.Sync("Lag", ref _lagcount);
|
||||
ser.Sync("Frame", ref _frame);
|
||||
ser.Sync("IsLag", ref _islag);
|
||||
ser.Sync("frameStartPending", ref _frameStartPending);
|
||||
ser.Sync("cyc_counter", ref cyc_counter);
|
||||
ser.Sync("leftDifficultySwitchPressed", ref _leftDifficultySwitchPressed);
|
||||
ser.Sync("rightDifficultySwitchPressed", ref _rightDifficultySwitchPressed);
|
||||
ser.Sync("leftDifficultySwitchHeld", ref _leftDifficultySwitchHeld);
|
||||
|
|
|
@ -41,7 +41,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
|
||||
if (Rom.HashSHA1() == "3A77DB43B6583E8689435F0F14AA04B9E57BDDED" ||
|
||||
Rom.HashSHA1() == "E986E1818E747BEB9B33CE4DFF1CDC6B55BDB620")
|
||||
Rom.HashSHA1() == "E986E1818E747BEB9B33CE4DFF1CDC6B55BDB620" ||
|
||||
Rom.HashSHA1() == "982B8016B393A9AA7DD110295A53C4612ECF2141")
|
||||
{
|
||||
game.RemoveOption("m");
|
||||
game.AddOption("m", "F8_sega");
|
||||
|
@ -102,18 +103,25 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
// give the emu a minimal of input\output connections so it doesn't crash
|
||||
var comm = new CoreComm(null, null);
|
||||
|
||||
|
||||
// here we advance past start up irregularities to see how long a frame is based on calls to Vsync
|
||||
// we run 72 frames, then run 270 scanlines worth of cycles.
|
||||
// if we don't hit a new frame, we can be pretty confident we are in PAL
|
||||
using (Atari2600 emu = new Atari2600(new CoreComm(null, null), newgame, rom, null, null))
|
||||
{
|
||||
List<int> framecounts = new List<int>();
|
||||
emu._tia.FrameEndCallBack = (i) => framecounts.Add(i);
|
||||
for (int i = 0; i < 71; i++) // run for 71 * 262 lines, since we're in NTSC mode
|
||||
for (int i = 0; i < 72; i++)
|
||||
{
|
||||
emu.FrameAdvance(NullController.Instance, false, false);
|
||||
}
|
||||
|
||||
int numpal = framecounts.Count((i) => i > 287);
|
||||
bool pal = numpal >= 25;
|
||||
Console.WriteLine("PAL Detection: {0} lines, {1}", numpal, pal);
|
||||
for (int i = 0; i < 61560; i++)
|
||||
{
|
||||
emu.Cycle();
|
||||
}
|
||||
|
||||
bool pal = !emu._tia.New_Frame;
|
||||
|
||||
Console.WriteLine("PAL Detection: {0}", pal);
|
||||
return pal;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
_spf = _vsyncNum / (double)_vsyncDen > 55.0 ? 735 : 882;
|
||||
}
|
||||
|
||||
// indicates to the core where a new frame is starting
|
||||
public bool New_Frame = false;
|
||||
|
||||
private const int BackColor = unchecked((int)0xff000000);
|
||||
private const int ScreenWidth = 160;
|
||||
private const int MaxScreenHeight = 312;
|
||||
|
@ -161,11 +164,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
/// </summary>
|
||||
public int LineCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a callback that is called at the end of a video frame. used internally
|
||||
/// </summary>
|
||||
public Action<int> FrameEndCallBack { private get; set; }
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
_hsyncCnt = 0;
|
||||
|
@ -229,11 +227,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
|
||||
// Execute TIA cycles
|
||||
public void Execute(int cycles)
|
||||
public void Execute()
|
||||
{
|
||||
// Still ignoring cycles...
|
||||
|
||||
// delay vblank latch
|
||||
// Handle all of the Latch delays that occur in the TIA
|
||||
if (_vblankDelay > 0)
|
||||
{
|
||||
_vblankDelay++;
|
||||
|
@ -244,7 +240,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
}
|
||||
|
||||
// delay latch to new playfield register
|
||||
if (_pf0Updater)
|
||||
{
|
||||
_pf0DelayClock++;
|
||||
|
@ -275,7 +270,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
}
|
||||
|
||||
// delay latch to missile enable
|
||||
if (_enam0Delay > 0)
|
||||
{
|
||||
_enam0Delay++;
|
||||
|
@ -296,7 +290,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
}
|
||||
|
||||
// delay latch to ball enable
|
||||
if (_enambDelay > 0)
|
||||
{
|
||||
_enambDelay++;
|
||||
|
@ -307,7 +300,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
}
|
||||
|
||||
// delay latch to player graphics registers
|
||||
if (_prg0Delay > 0)
|
||||
{
|
||||
_prg0Delay++;
|
||||
|
@ -333,7 +325,6 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
}
|
||||
}
|
||||
|
||||
// HMP write delay
|
||||
if (_hmp0Delay > 0)
|
||||
{
|
||||
_hmp0Delay++;
|
||||
|
@ -773,9 +764,12 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
// do the audio sampling
|
||||
if (_hsyncCnt == 36 || _hsyncCnt == 148)
|
||||
{
|
||||
LocalAudioCycles[AudioClocks] += (short)(AUD[0].Cycle() / 2);
|
||||
LocalAudioCycles[AudioClocks] += (short)(AUD[1].Cycle() / 2);
|
||||
AudioClocks++;
|
||||
if (AudioClocks < 2000)
|
||||
{
|
||||
LocalAudioCycles[AudioClocks] += (short)(AUD[0].Cycle() / 2);
|
||||
LocalAudioCycles[AudioClocks] += (short)(AUD[1].Cycle() / 2);
|
||||
AudioClocks++;
|
||||
}
|
||||
}
|
||||
|
||||
// Increment the hsync counter
|
||||
|
@ -796,7 +790,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
int topLine = _pal ? _core.Settings.PALTopLine : _core.Settings.NTSCTopLine;
|
||||
int bottomLine = _pal ? _core.Settings.PALBottomLine : _core.Settings.NTSCBottomLine;
|
||||
|
||||
// if vsync occured unexpectedly early, black out the remainer
|
||||
// if vsync occured unexpectedly early, black out the remainder
|
||||
for (; validlines < bottomLine; validlines++)
|
||||
{
|
||||
for (int i = 0; i < 160; i++)
|
||||
|
@ -972,7 +966,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
// write to frame buffer
|
||||
OutputFrame(_currentScanLine);
|
||||
|
||||
FrameEndCallBack?.Invoke(_currentScanLine);
|
||||
New_Frame = true;
|
||||
|
||||
// Clear all from last frame
|
||||
_currentScanLine = 0;
|
||||
|
@ -1337,17 +1331,5 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
{
|
||||
AUDC, AUDF, AUDV
|
||||
}
|
||||
|
||||
private int _frameStartCycles, _frameEndCycles;
|
||||
|
||||
public void BeginAudioFrame()
|
||||
{
|
||||
_frameStartCycles = _core.Cpu.TotalExecutedCycles;
|
||||
}
|
||||
|
||||
public void CompleteAudioFrame()
|
||||
{
|
||||
_frameEndCycles = _core.Cpu.TotalExecutedCycles;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,10 +62,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
|
|||
ser.Sync("vblankEnabled", ref _vblankEnabled);
|
||||
ser.Sync("vsyncEnabled", ref _vsyncEnabled);
|
||||
ser.Sync("CurrentScanLine", ref _currentScanLine);
|
||||
ser.Sync("scanlinebuffer", ref _scanlinebuffer, false);
|
||||
ser.Sync("AudioClocks", ref AudioClocks);
|
||||
ser.Sync("FrameStartCycles", ref _frameStartCycles);
|
||||
ser.Sync("FrameEndCycles", ref _frameEndCycles);
|
||||
ser.Sync("New_Frame", ref New_Frame);
|
||||
|
||||
ser.BeginSection("Player0");
|
||||
_player0.SyncState(ser);
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
}
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem();
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
public bool CanStep(StepType type)
|
||||
{
|
||||
|
|
|
@ -268,7 +268,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
|
||||
private void ExecFetch(ushort addr)
|
||||
{
|
||||
MemoryCallbacks.CallExecutes(addr);
|
||||
MemoryCallbacks.CallExecutes(addr, "System Bus");
|
||||
}
|
||||
|
||||
private void Reset_Mapper(string m)
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
{
|
||||
public byte ReadMemory(ushort addr)
|
||||
{
|
||||
MemoryCallbacks.CallReads(addr);
|
||||
MemoryCallbacks.CallReads(addr, "System Bus");
|
||||
|
||||
if ((addr & 0xFCE0) == 0)
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
|
|||
|
||||
public void WriteMemory(ushort addr, byte value)
|
||||
{
|
||||
MemoryCallbacks.CallWrites(addr);
|
||||
MemoryCallbacks.CallWrites(addr, "System Bus");
|
||||
|
||||
if ((addr & 0xFCE0) == 0)
|
||||
{
|
||||
|
|
|
@ -169,7 +169,7 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
|
|||
BoolButtons = { "Up", "Down", "Left", "Right", "A", "B", "Option 1", "Option 2", "Pause", "Power" },
|
||||
};
|
||||
|
||||
public ControllerDefinition ControllerDefinition { get { return LynxTroller; } }
|
||||
public ControllerDefinition ControllerDefinition => LynxTroller;
|
||||
|
||||
private LibLynx.Buttons GetButtons(IController controller)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,10 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
Name = "ColecoVision Basic Controller",
|
||||
BoolButtons = Port1.Definition.BoolButtons
|
||||
.Concat(Port2.Definition.BoolButtons)
|
||||
.Concat(new[]
|
||||
{
|
||||
"Power", "Reset"
|
||||
})
|
||||
.ToList()
|
||||
};
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
public byte Read(IController c, bool left_mode, int wheel)
|
||||
{
|
||||
return 0; // needs checking
|
||||
return 0x7F; // needs checking
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition { get; }
|
||||
|
|
|
@ -12,36 +12,36 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
{
|
||||
return new Dictionary<string, RegisterValue>
|
||||
{
|
||||
["A"] = _cpu.RegisterA,
|
||||
["AF"] = _cpu.RegisterAF,
|
||||
["B"] = _cpu.RegisterB,
|
||||
["BC"] = _cpu.RegisterBC,
|
||||
["C"] = _cpu.RegisterC,
|
||||
["D"] = _cpu.RegisterD,
|
||||
["DE"] = _cpu.RegisterDE,
|
||||
["E"] = _cpu.RegisterE,
|
||||
["F"] = _cpu.RegisterF,
|
||||
["H"] = _cpu.RegisterH,
|
||||
["HL"] = _cpu.RegisterHL,
|
||||
["I"] = _cpu.RegisterI,
|
||||
["IX"] = _cpu.RegisterIX,
|
||||
["IY"] = _cpu.RegisterIY,
|
||||
["L"] = _cpu.RegisterL,
|
||||
["PC"] = _cpu.RegisterPC,
|
||||
["R"] = _cpu.RegisterR,
|
||||
["Shadow AF"] = _cpu.RegisterShadowAF,
|
||||
["Shadow BC"] = _cpu.RegisterShadowBC,
|
||||
["Shadow DE"] = _cpu.RegisterShadowDE,
|
||||
["Shadow HL"] = _cpu.RegisterShadowHL,
|
||||
["SP"] = _cpu.RegisterSP,
|
||||
["Flag C"] = _cpu.RegisterF.Bit(0),
|
||||
["Flag N"] = _cpu.RegisterF.Bit(1),
|
||||
["Flag P/V"] = _cpu.RegisterF.Bit(2),
|
||||
["Flag 3rd"] = _cpu.RegisterF.Bit(3),
|
||||
["Flag H"] = _cpu.RegisterF.Bit(4),
|
||||
["Flag 5th"] = _cpu.RegisterF.Bit(5),
|
||||
["Flag Z"] = _cpu.RegisterF.Bit(6),
|
||||
["Flag S"] = _cpu.RegisterF.Bit(7)
|
||||
["A"] = _cpu.Regs[_cpu.A],
|
||||
["AF"] = _cpu.Regs[_cpu.F] + (_cpu.Regs[_cpu.A] << 8),
|
||||
["B"] = _cpu.Regs[_cpu.B],
|
||||
["BC"] = _cpu.Regs[_cpu.C] + (_cpu.Regs[_cpu.B] << 8),
|
||||
["C"] = _cpu.Regs[_cpu.C],
|
||||
["D"] = _cpu.Regs[_cpu.D],
|
||||
["DE"] = _cpu.Regs[_cpu.E] + (_cpu.Regs[_cpu.D] << 8),
|
||||
["E"] = _cpu.Regs[_cpu.E],
|
||||
["F"] = _cpu.Regs[_cpu.F],
|
||||
["H"] = _cpu.Regs[_cpu.H],
|
||||
["HL"] = _cpu.Regs[_cpu.L] + (_cpu.Regs[_cpu.H] << 8),
|
||||
["I"] = _cpu.Regs[_cpu.I],
|
||||
["IX"] = _cpu.Regs[_cpu.Ixl] + (_cpu.Regs[_cpu.Ixh] << 8),
|
||||
["IY"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
|
||||
["L"] = _cpu.Regs[_cpu.L],
|
||||
["PC"] = _cpu.Regs[_cpu.PCl] + (_cpu.Regs[_cpu.PCh] << 8),
|
||||
["R"] = _cpu.Regs[_cpu.R],
|
||||
["Shadow AF"] = _cpu.Regs[_cpu.F_s] + (_cpu.Regs[_cpu.A_s] << 8),
|
||||
["Shadow BC"] = _cpu.Regs[_cpu.C_s] + (_cpu.Regs[_cpu.B_s] << 8),
|
||||
["Shadow DE"] = _cpu.Regs[_cpu.E_s] + (_cpu.Regs[_cpu.D_s] << 8),
|
||||
["Shadow HL"] = _cpu.Regs[_cpu.L_s] + (_cpu.Regs[_cpu.H_s] << 8),
|
||||
["SP"] = _cpu.Regs[_cpu.Iyl] + (_cpu.Regs[_cpu.Iyh] << 8),
|
||||
["Flag C"] = _cpu.FlagC,
|
||||
["Flag N"] = _cpu.FlagN,
|
||||
["Flag P/V"] = _cpu.FlagP,
|
||||
["Flag 3rd"] = _cpu.Flag3,
|
||||
["Flag H"] = _cpu.FlagH,
|
||||
["Flag 5th"] = _cpu.Flag5,
|
||||
["Flag Z"] = _cpu.FlagZ,
|
||||
["Flag S"] = _cpu.FlagS
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,70 +52,82 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
default:
|
||||
throw new InvalidOperationException();
|
||||
case "A":
|
||||
_cpu.RegisterA = (byte)value;
|
||||
_cpu.Regs[_cpu.A] = (ushort)value;
|
||||
break;
|
||||
case "AF":
|
||||
_cpu.RegisterAF = (byte)value;
|
||||
_cpu.Regs[_cpu.F] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.A] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "B":
|
||||
_cpu.RegisterB = (byte)value;
|
||||
_cpu.Regs[_cpu.B] = (ushort)value;
|
||||
break;
|
||||
case "BC":
|
||||
_cpu.RegisterBC = (byte)value;
|
||||
_cpu.Regs[_cpu.C] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.B] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "C":
|
||||
_cpu.RegisterC = (byte)value;
|
||||
_cpu.Regs[_cpu.C] = (ushort)value;
|
||||
break;
|
||||
case "D":
|
||||
_cpu.RegisterD = (byte)value;
|
||||
_cpu.Regs[_cpu.D] = (ushort)value;
|
||||
break;
|
||||
case "DE":
|
||||
_cpu.RegisterDE = (byte)value;
|
||||
_cpu.Regs[_cpu.E] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.D] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "E":
|
||||
_cpu.RegisterE = (byte)value;
|
||||
_cpu.Regs[_cpu.E] = (ushort)value;
|
||||
break;
|
||||
case "F":
|
||||
_cpu.RegisterF = (byte)value;
|
||||
_cpu.Regs[_cpu.F] = (ushort)value;
|
||||
break;
|
||||
case "H":
|
||||
_cpu.RegisterH = (byte)value;
|
||||
_cpu.Regs[_cpu.H] = (ushort)value;
|
||||
break;
|
||||
case "HL":
|
||||
_cpu.RegisterHL = (byte)value;
|
||||
_cpu.Regs[_cpu.L] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.H] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "I":
|
||||
_cpu.RegisterI = (byte)value;
|
||||
_cpu.Regs[_cpu.I] = (ushort)value;
|
||||
break;
|
||||
case "IX":
|
||||
_cpu.RegisterIX = (byte)value;
|
||||
_cpu.Regs[_cpu.Ixl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.Ixh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "IY":
|
||||
_cpu.RegisterIY = (byte)value;
|
||||
_cpu.Regs[_cpu.Iyl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.Iyh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "L":
|
||||
_cpu.RegisterL = (byte)value;
|
||||
_cpu.Regs[_cpu.L] = (ushort)value;
|
||||
break;
|
||||
case "PC":
|
||||
_cpu.RegisterPC = (ushort)value;
|
||||
_cpu.Regs[_cpu.PCl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.PCh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "R":
|
||||
_cpu.RegisterR = (byte)value;
|
||||
_cpu.Regs[_cpu.R] = (ushort)value;
|
||||
break;
|
||||
case "Shadow AF":
|
||||
_cpu.RegisterShadowAF = (byte)value;
|
||||
_cpu.Regs[_cpu.F_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.A_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow BC":
|
||||
_cpu.RegisterShadowBC = (byte)value;
|
||||
_cpu.Regs[_cpu.C_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.B_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow DE":
|
||||
_cpu.RegisterShadowDE = (byte)value;
|
||||
_cpu.Regs[_cpu.E_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.D_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "Shadow HL":
|
||||
_cpu.RegisterShadowHL = (byte)value;
|
||||
_cpu.Regs[_cpu.L_s] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.H_s] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
case "SP":
|
||||
_cpu.RegisterSP = (byte)value;
|
||||
_cpu.Regs[_cpu.SPl] = (ushort)(value & 0xFF);
|
||||
_cpu.Regs[_cpu.SPh] = (ushort)(value & 0xFF00);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,16 +12,30 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
public void FrameAdvance(IController controller, bool render, bool renderSound)
|
||||
{
|
||||
_controller = controller;
|
||||
_cpu.Debug = _tracer.Enabled;
|
||||
|
||||
// NOTE: Need to research differences between reset and power cycle
|
||||
if (_controller.IsPressed("Power"))
|
||||
{
|
||||
HardReset();
|
||||
}
|
||||
|
||||
if (_controller.IsPressed("Reset"))
|
||||
{
|
||||
SoftReset();
|
||||
}
|
||||
|
||||
_frame++;
|
||||
_isLag = true;
|
||||
PSG.BeginFrame(_cpu.TotalExecutedCycles);
|
||||
|
||||
if (_cpu.Debug && _cpu.Logger == null) // TODO, lets not do this on each frame. But lets refactor CoreComm/CoreComm first
|
||||
if (_tracer.Enabled)
|
||||
{
|
||||
_cpu.Logger = (s) => _tracer.Put(s);
|
||||
_cpu.TraceCallback = s => _tracer.Put(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
_cpu.TraceCallback = null;
|
||||
}
|
||||
|
||||
byte tempRet1 = ControllerDeck.ReadPort1(controller, true, true);
|
||||
byte tempRet2 = ControllerDeck.ReadPort2(controller, true, true);
|
||||
|
||||
|
|
|
@ -7,53 +7,52 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
{
|
||||
public partial class ColecoVision : IStatable
|
||||
{
|
||||
public bool BinarySaveStatesPreferred => false;
|
||||
public bool BinarySaveStatesPreferred
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
SyncState(new Serializer(writer));
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
SyncState(new Serializer(reader));
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
SyncState(Serializer.CreateBinaryWriter(bw));
|
||||
SyncState(new Serializer(bw));
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
SyncState(Serializer.CreateBinaryReader(br));
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter tw)
|
||||
{
|
||||
SyncState(Serializer.CreateTextWriter(tw));
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader tr)
|
||||
{
|
||||
SyncState(Serializer.CreateTextReader(tr));
|
||||
SyncState(new Serializer(br));
|
||||
}
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
if (_stateBuffer == null)
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var writer = new BinaryWriter(stream);
|
||||
SaveStateBinary(writer);
|
||||
_stateBuffer = stream.ToArray();
|
||||
writer.Close();
|
||||
return _stateBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
var stream = new MemoryStream(_stateBuffer);
|
||||
var writer = new BinaryWriter(stream);
|
||||
SaveStateBinary(writer);
|
||||
writer.Close();
|
||||
return _stateBuffer;
|
||||
}
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter bw = new BinaryWriter(ms);
|
||||
SaveStateBinary(bw);
|
||||
bw.Flush();
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("Coleco");
|
||||
byte[] core = null;
|
||||
if (ser.IsWriter)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
ms.Close();
|
||||
core = ms.ToArray();
|
||||
}
|
||||
_cpu.SyncState(ser);
|
||||
|
||||
ser.BeginSection("Coleco");
|
||||
_vdp.SyncState(ser);
|
||||
PSG.SyncState(ser);
|
||||
ser.Sync("RAM", ref _ram, false);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components;
|
||||
using BizHawk.Emulation.Cores.Components.Z80;
|
||||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
|
@ -17,13 +17,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
{
|
||||
var ser = new BasicServiceProvider(this);
|
||||
ServiceProvider = ser;
|
||||
MemoryCallbacks = new MemoryCallbackSystem();
|
||||
MemoryCallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
CoreComm = comm;
|
||||
_syncSettings = (ColecoSyncSettings)syncSettings ?? new ColecoSyncSettings();
|
||||
bool skipbios = _syncSettings.SkipBiosIntro;
|
||||
|
||||
_cpu = new Z80A
|
||||
{
|
||||
FetchMemory = ReadMemory,
|
||||
ReadMemory = ReadMemory,
|
||||
WriteMemory = WriteMemory,
|
||||
ReadHardware = ReadPort,
|
||||
|
@ -53,7 +54,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
SetupMemoryDomains();
|
||||
|
||||
_tracer.Header = _cpu.TraceHeader;
|
||||
ser.Register<IDisassemblable>(new Disassembler());
|
||||
ser.Register<IDisassemblable>(_cpu);
|
||||
ser.Register<ITraceable>(_tracer);
|
||||
}
|
||||
|
||||
|
@ -223,5 +224,17 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
////Console.WriteLine("Unhandled write at {0:X4}:{1:X2}", addr, value);
|
||||
}
|
||||
|
||||
private void HardReset()
|
||||
{
|
||||
PSG.Reset();
|
||||
_cpu.Reset();
|
||||
}
|
||||
|
||||
private void SoftReset()
|
||||
{
|
||||
PSG.Reset();
|
||||
_cpu.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components.Z80;
|
||||
using BizHawk.Emulation.Cores.Components.Z80A;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
|
@ -54,14 +54,17 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
Cpu.NonMaskableInterrupt = true;
|
||||
}
|
||||
|
||||
Cpu.ExecuteCycles(228);
|
||||
|
||||
Cpu.Interrupt = false;
|
||||
for (int i = 0; i < 228; i++)
|
||||
{
|
||||
Cpu.ExecuteOne();
|
||||
}
|
||||
|
||||
Cpu.FlagI = false;
|
||||
if (Int_pending && scanLine==50)
|
||||
{
|
||||
if (EnableInterrupts)
|
||||
{
|
||||
Cpu.Interrupt = true;
|
||||
Cpu.FlagI = true;
|
||||
Int_pending = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
|
|||
}
|
||||
}
|
||||
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem();
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get; } = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
public bool CanStep(StepType type)
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
return false;
|
||||
}
|
||||
|
||||
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem();
|
||||
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
public IMemoryCallbackSystem MemoryCallbacks => _memorycallbacks;
|
||||
|
||||
[FeatureNotImplemented]
|
||||
|
|
|
@ -166,9 +166,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
void InitCallbacks()
|
||||
{
|
||||
padcb = new LibVBANext.StandardCallback(() => InputCallbacks.Call());
|
||||
fetchcb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallExecutes(addr));
|
||||
readcb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallReads(addr));
|
||||
writecb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallWrites(addr));
|
||||
fetchcb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallExecutes(addr, "System Bus"));
|
||||
readcb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallReads(addr, "System Bus"));
|
||||
writecb = new LibVBANext.AddressCallback((addr) => MemoryCallbacks.CallWrites(addr, "System Bus"));
|
||||
tracecb = new LibVBANext.TraceCallback((addr, opcode) => Tracer.Put(Trace(addr, opcode)));
|
||||
_inputCallbacks.ActiveChanged += SyncPadCallback;
|
||||
_memorycallbacks.ActiveChanged += SyncMemoryCallbacks;
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
private LibGambatte.MemoryCallback _writecb;
|
||||
private LibGambatte.MemoryCallback _execcb;
|
||||
|
||||
private MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem();
|
||||
private MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
/// <summary>
|
||||
/// for use in dual core
|
||||
|
@ -68,9 +68,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
|
||||
private void InitMemoryCallbacks()
|
||||
{
|
||||
_readcb = addr => MemoryCallbacks.CallReads(addr);
|
||||
_writecb = addr => MemoryCallbacks.CallWrites(addr);
|
||||
_execcb = addr => MemoryCallbacks.CallExecutes(addr);
|
||||
_readcb = addr => MemoryCallbacks.CallReads(addr, "System Bus");
|
||||
_writecb = addr => MemoryCallbacks.CallWrites(addr, "System Bus");
|
||||
_execcb = addr => MemoryCallbacks.CallExecutes(addr, "System Bus");
|
||||
_memorycallbacks.ActiveChanged += RefreshMemoryCallbacks;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||
{
|
||||
public partial class Gameboy : ILinkable
|
||||
{
|
||||
public bool LinkConnected { get; private set; }
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
[ServiceNotApplicable(typeof(IDriveLight), typeof(IDriveLight))]
|
||||
public partial class Gameboy : IEmulator, IVideoProvider, ISoundProvider, ISaveRam, IStatable, IInputPollable, ICodeDataLogger,
|
||||
IBoardInfo, IDebuggable, ISettable<Gameboy.GambatteSettings, Gameboy.GambatteSyncSettings>,
|
||||
IGameboyCommon, ICycleTiming
|
||||
IGameboyCommon, ICycleTiming, ILinkable
|
||||
{
|
||||
[CoreConstructor("GB", "GBC")]
|
||||
public Gameboy(CoreComm comm, GameInfo game, byte[] file, object settings, object syncSettings, bool deterministic)
|
||||
|
@ -513,9 +513,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
if (callback != null)
|
||||
{
|
||||
printer = new GambattePrinter(this, callback);
|
||||
LinkConnected = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LinkConnected = false;
|
||||
printer.Disconnect();
|
||||
printer = null;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem();
|
||||
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy
|
|||
{
|
||||
Filename = "sameboy.wbx",
|
||||
SbrkHeapSizeKB = 192,
|
||||
InvisibleHeapSizeKB = 4,
|
||||
InvisibleHeapSizeKB = 12,
|
||||
SealedHeapSizeKB = 9 * 1024,
|
||||
PlainHeapSizeKB = 4,
|
||||
MmapHeapSizeKB = 1024
|
||||
|
@ -300,6 +300,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy
|
|||
protected override void LoadStateBinaryInternal(BinaryReader reader)
|
||||
{
|
||||
UpdateCoreScanlineCallback(false);
|
||||
_core.SetPrinterCallback(_printerCallback);
|
||||
}
|
||||
|
||||
public bool IsCGBMode() => _cgb;
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
|
|||
get { return _memorycallbacks; }
|
||||
}
|
||||
|
||||
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem();
|
||||
private readonly MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
|
||||
|
||||
public bool CanStep(StepType type)
|
||||
{
|
||||
|
|
|
@ -759,13 +759,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
|
|||
switch (_breakparams._type)
|
||||
{
|
||||
case BreakType.Read:
|
||||
_breakparams._mcs.CallReads(_breakparams._addr);
|
||||
_breakparams._mcs.CallReads(_breakparams._addr, "System Bus");
|
||||
break;
|
||||
case BreakType.Write:
|
||||
_breakparams._mcs.CallWrites(_breakparams._addr);
|
||||
_breakparams._mcs.CallWrites(_breakparams._addr, "System Bus");
|
||||
break;
|
||||
case BreakType.Execute:
|
||||
_breakparams._mcs.CallExecutes(_breakparams._addr);
|
||||
_breakparams._mcs.CallExecutes(_breakparams._addr, "System Bus");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
{
|
||||
public sealed class APU
|
||||
{
|
||||
public static bool CFG_DECLICK = true;
|
||||
|
||||
public int Square1V = 376;
|
||||
public int Square2V = 376;
|
||||
public int TriangleV = 426;
|
||||
public int NoiseV = 247;
|
||||
public int DMCV = 167;
|
||||
public int m_vol = 1;
|
||||
|
||||
public int dmc_dma_countdown = -1;
|
||||
public bool call_from_write;
|
||||
|
@ -53,11 +47,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
pulse[1] = new PulseUnit(this, 1);
|
||||
if (old != null)
|
||||
{
|
||||
Square1V = old.Square1V;
|
||||
Square2V = old.Square2V;
|
||||
TriangleV = old.TriangleV;
|
||||
NoiseV = old.NoiseV;
|
||||
DMCV = old.DMCV;
|
||||
m_vol = old.m_vol;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1338,8 +1328,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
}
|
||||
|
||||
SyncIRQ();
|
||||
nes.irq_apu = irq_pending;
|
||||
|
||||
|
||||
// since the units run concurrently, the APU frame sequencer is ran last because
|
||||
// it can change the ouput values of the pulse/triangle channels
|
||||
// we want the changes to affect it on the *next* cycle.
|
||||
|
@ -1419,7 +1408,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
float output = pulse_out + tnd_out;
|
||||
// output = output * 2 - 1;
|
||||
// this needs to leave enough headroom for straying DC bias due to the DMC unit getting stuck outputs. smb3 is bad about that.
|
||||
int mix = (int)(20000 * output);
|
||||
int mix = (int)(20000 * output * (1 + m_vol/5));
|
||||
|
||||
dlist.Add(new Delta(sampleclock, mix - oldmix));
|
||||
oldmix = mix;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||
{
|
||||
|
@ -108,6 +109,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
{
|
||||
cheetahmen = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
prg_bank_mask_16k = 0x1F;
|
||||
prg_bank_mask_32k = 0xF;
|
||||
}
|
||||
|
||||
AutoMapperProps.Apply(this);
|
||||
|
||||
|
@ -155,6 +161,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
//$8000-FFFF: [.... ..CC] Low 2 bits of CHR
|
||||
//A~[..MH HPPP PPO. CCCC]
|
||||
|
||||
addr += 0x8000;
|
||||
|
||||
if (addr.Bit(13))
|
||||
{
|
||||
SetMirrorType(EMirrorType.Horizontal);
|
||||
|
@ -173,7 +181,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
switch (chip)
|
||||
{
|
||||
case 0:
|
||||
chip_offset = 0;
|
||||
chip_offset = 0x0;
|
||||
break;
|
||||
case 1:
|
||||
chip_offset = 0x80000;
|
||||
|
@ -201,7 +209,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
if (prg_mode == false)
|
||||
{
|
||||
int bank = (prg_reg >> 1) & prg_bank_mask_32k;
|
||||
return ROM[(bank * 0x8000) + addr];
|
||||
return ROM[(bank * 0x8000) + addr + chip_offset];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
using BizHawk.Common;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||
{
|
||||
// Mapper for Aladdin Super Game
|
||||
public sealed class Mapper114 : MMC3Board_Base
|
||||
{
|
||||
private ByteBuffer EXPREGS = new ByteBuffer(2);
|
||||
|
||||
private int prg_mask_16;
|
||||
|
||||
private byte[] sec = { 0, 3, 1, 5, 6, 7, 2, 4 };
|
||||
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "MAPPER114":
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
BaseSetup();
|
||||
SetMirrorType(EMirrorType.Horizontal);
|
||||
mmc3.MMC3Type = MMC3.EMMC3Type.MMC3A;
|
||||
prg_mask_16 = Cart.prg_size / 16 - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
EXPREGS.Dispose();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
ser.Sync("expregs", ref EXPREGS);
|
||||
}
|
||||
|
||||
public override void WriteEXP(int addr, byte value)
|
||||
{
|
||||
if ((addr & 0x7) == 0 && addr >= 0x1000)
|
||||
{
|
||||
EXPREGS[0] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteWRAM(int addr, byte value)
|
||||
{
|
||||
if ((addr & 0x7) == 0)
|
||||
{
|
||||
EXPREGS[0] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void WritePRG(int addr, byte value)
|
||||
{
|
||||
switch (addr & 0x6000)
|
||||
{
|
||||
case 0x0000: //$8000
|
||||
base.SetMirrorType((value & 1) == 1 ? EMirrorType.Horizontal : EMirrorType.Vertical);
|
||||
break;
|
||||
case 0x2000: //$A000
|
||||
value = (byte)((value & 0xC0) | sec[value & 0x07]);
|
||||
EXPREGS[1] = 1;
|
||||
base.WritePRG(0, value);
|
||||
break;
|
||||
case 0x4000: //$C000
|
||||
if(EXPREGS[1] == 1)
|
||||
{
|
||||
EXPREGS[1] = 0;
|
||||
base.WritePRG(1, value);
|
||||
}
|
||||
break;
|
||||
case 0x6000: //$E000
|
||||
if (value > 0)
|
||||
{
|
||||
base.WritePRG(0x6001, value);
|
||||
base.WritePRG(0x4000, value);
|
||||
base.WritePRG(0x4001, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.WritePRG(0x6000, value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte ReadPRG(int addr)
|
||||
{
|
||||
if ((EXPREGS[0] & 0x80) > 0)
|
||||
{
|
||||
var bank = EXPREGS[0] & 0x1F & prg_mask_16;
|
||||
return ROM[(bank << 14) + (addr & 0x3FFF)];
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.ReadPRG(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -146,7 +146,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
void WriteModeControl(int addr, byte value)
|
||||
{
|
||||
if (((addr & 0x4100) != 0x4100) || addr>=0x4200) return;
|
||||
if ((addr & 0x4100) != 0x4100) return;
|
||||
mode = value & 3;
|
||||
bool chr_base = value.Bit(2);
|
||||
|
||||
|
|
|
@ -255,19 +255,29 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
case 0x0020:
|
||||
timerlatch &= 0xff00;
|
||||
timerlatch |= value;
|
||||
//timerirq = false;
|
||||
break;
|
||||
case 0x0021:
|
||||
timerlatch &= 0x00ff;
|
||||
timerlatch |= value << 8;
|
||||
//timerirq = false;
|
||||
break;
|
||||
case 0x0022:
|
||||
timerreg = (byte)(value & 3);
|
||||
timervalue = timerlatch;
|
||||
if (diskenable)
|
||||
{
|
||||
timerreg = (byte)(value & 3);
|
||||
if ((value & 0x02) == 0x02)
|
||||
{
|
||||
timervalue = timerlatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
_timerirq = false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0023:
|
||||
diskenable = (value & 1) != 0;
|
||||
if (!diskenable) { _timerirq = false; }
|
||||
soundenable = (value & 2) != 0;
|
||||
break;
|
||||
case 0x0024:
|
||||
|
@ -344,7 +354,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
|
||||
public override void ClockCPU()
|
||||
{
|
||||
if ((timerreg & 2) != 0)// && timervalue > 0)
|
||||
if ((timerreg & 2) != 0 && diskenable)
|
||||
{
|
||||
if (timervalue!=0)
|
||||
{
|
||||
|
@ -352,22 +362,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
}
|
||||
if (timervalue == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
if ((timerreg & 1) != 0)
|
||||
{
|
||||
timervalue = timerlatch;
|
||||
//timervalue = 0xFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
timerreg &= unchecked((byte)~2);
|
||||
timervalue = 0;
|
||||
timerlatch = 0;
|
||||
}
|
||||
*/
|
||||
timervalue = timerlatch;
|
||||
timerirq = true;
|
||||
if ((timerreg & 1) == 0)
|
||||
{
|
||||
timerreg -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
audio.Clock();
|
||||
|
|
|
@ -67,14 +67,17 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
|||
byte[] fileheader = br.ReadBytes(16);
|
||||
if (fileheader[0] != 0x03)
|
||||
{
|
||||
throw new Exception("Corrupt FDS block 3");
|
||||
// Instead of exceptions, display strong warnings
|
||||
Console.WriteLine("WARNING: INVALID FILE, BLOCK 3 ERROR");
|
||||
//throw new Exception("Corrupt FDS block 3");
|
||||
}
|
||||
int filesize = fileheader[13] + fileheader[14] * 256;
|
||||
|
||||
byte[] file = br.ReadBytes(filesize + 1);
|
||||
if (file[0] != 0x04)
|
||||
{
|
||||
throw new Exception("Corrupt FDS block 4");
|
||||
Console.WriteLine("WARNING: INVALID FILE, BLOCK 4 ERROR");
|
||||
//throw new Exception("Corrupt FDS block 4");
|
||||
}
|
||||
|
||||
WriteBlock(ret, fileheader, 122);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue