[NES] mapper cleanup and savestates
This commit is contained in:
parent
d225c23cc1
commit
0d5cff7408
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace BizHawk.Emulation.CPUs.M6502
|
||||
{
|
||||
|
@ -59,19 +61,6 @@ namespace BizHawk.Emulation.CPUs.M6502
|
|||
return val;
|
||||
}
|
||||
|
||||
// ==== CPU State ====
|
||||
|
||||
public byte A;
|
||||
public byte X;
|
||||
public byte Y;
|
||||
public byte P;
|
||||
public ushort PC;
|
||||
public byte S;
|
||||
|
||||
// TODO IRQ, NMI functions
|
||||
public bool Interrupt;
|
||||
public bool NMI;
|
||||
|
||||
private const ushort NMIVector = 0xFFFA;
|
||||
private const ushort ResetVector = 0xFFFC;
|
||||
private const ushort BRKVector = 0xFFFE;
|
||||
|
@ -91,13 +80,74 @@ namespace BizHawk.Emulation.CPUs.M6502
|
|||
WriteMemory((ushort)(S-- + 0x100), P);
|
||||
P = oldP;
|
||||
FlagI = true;
|
||||
if(type == ExceptionType.NMI)
|
||||
if (type == ExceptionType.NMI)
|
||||
PC = ReadWord(NMIVector);
|
||||
else
|
||||
PC = ReadWord(BRKVector);
|
||||
PendingCycles -= 7;
|
||||
}
|
||||
|
||||
// ==== CPU State ====
|
||||
|
||||
public byte A;
|
||||
public byte X;
|
||||
public byte Y;
|
||||
public byte P;
|
||||
public ushort PC;
|
||||
public byte S;
|
||||
|
||||
// TODO IRQ, NMI functions
|
||||
public bool Interrupt;
|
||||
public bool NMI;
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
writer.WriteLine("[MOS6502]");
|
||||
writer.WriteLine("A {0:X2}", A);
|
||||
writer.WriteLine("X {0:X2}", X);
|
||||
writer.WriteLine("Y {0:X2}", Y);
|
||||
writer.WriteLine("P {0:X2}", P);
|
||||
writer.WriteLine("PC {0:X4}", PC);
|
||||
writer.WriteLine("S {0:X2}", S);
|
||||
writer.WriteLine("NMI {0}", NMI);
|
||||
writer.WriteLine("Interrupt {0}", Interrupt);
|
||||
writer.WriteLine("TotalExecutedCycles {0}", TotalExecutedCycles);
|
||||
writer.WriteLine("PendingCycles {0}", PendingCycles);
|
||||
writer.WriteLine("[/MOS6502]\n");
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
string[] args = reader.ReadLine().Split(' ');
|
||||
if (args[0].Trim() == "") continue;
|
||||
if (args[0] == "[/MOS6502]") break;
|
||||
if (args[0] == "A")
|
||||
A = byte.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "X")
|
||||
X = byte.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "Y")
|
||||
Y = byte.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "P")
|
||||
P = byte.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "PC")
|
||||
PC = ushort.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "S")
|
||||
S = byte.Parse(args[1], NumberStyles.HexNumber);
|
||||
else if (args[0] == "NMI")
|
||||
NMI = bool.Parse(args[1]);
|
||||
else if (args[0] == "Interrupt")
|
||||
Interrupt = bool.Parse(args[1]);
|
||||
else if (args[0] == "TotalExecutedCycles")
|
||||
TotalExecutedCycles = int.Parse(args[1]);
|
||||
else if (args[0] == "PendingCycles")
|
||||
PendingCycles = int.Parse(args[1]);
|
||||
else
|
||||
Console.WriteLine("Skipping unrecognized identifier " + args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// ==== End State ====
|
||||
|
||||
/// <summary>Carry Flag</summary>
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
||||
{
|
||||
//TODO - hardcode CRAM size and assert
|
||||
|
||||
//generally mapper7
|
||||
|
||||
//Battletoads
|
||||
//Time Lord
|
||||
//Marble Madness
|
||||
|
||||
public class AxROM : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
string type;
|
||||
bool bus_conflict;
|
||||
byte[] cram;
|
||||
int cram_mask;
|
||||
int prg_mask;
|
||||
|
||||
//state
|
||||
byte[] cram;
|
||||
int prg;
|
||||
|
||||
public AxROM(string type)
|
||||
|
@ -81,5 +91,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
else base.WritePPU(addr,value);
|
||||
}
|
||||
|
||||
public override void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
base.SaveStateBinary(bw);
|
||||
bw.Write(prg);
|
||||
Util.WriteByteBuffer(bw, cram);
|
||||
}
|
||||
|
||||
public override void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
base.LoadStateBinary(br);
|
||||
prg = br.ReadInt32();
|
||||
cram = Util.ReadByteBuffer(br, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,12 +1,17 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
||||
{
|
||||
//generally mapper3
|
||||
|
||||
public class CPROM : NES.NESBoardBase
|
||||
{
|
||||
//generally mapper 13
|
||||
|
||||
//Videomation
|
||||
|
||||
//state
|
||||
byte[] cram;
|
||||
int chr;
|
||||
|
||||
|
@ -42,5 +47,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
cram[addr - 0x1000 + (chr << 12)] = value;
|
||||
else base.WritePPU(addr,value);
|
||||
}
|
||||
|
||||
public override void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
base.SaveStateBinary(bw);
|
||||
bw.Write(chr);
|
||||
Util.WriteByteBuffer(bw, cram);
|
||||
}
|
||||
|
||||
public override void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
base.LoadStateBinary(br);
|
||||
chr = br.ReadInt32();
|
||||
cram = Util.ReadByteBuffer(br, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,27 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
||||
{
|
||||
//generally mapper3
|
||||
|
||||
//Solomon's Key
|
||||
//Arkanoid
|
||||
//Arkista's Ring
|
||||
//Bump 'n' Jump
|
||||
//Cybernoid
|
||||
|
||||
public class CxROM : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
string type;
|
||||
int chr_mask;
|
||||
bool bus_conflict;
|
||||
|
||||
//state
|
||||
int chr;
|
||||
|
||||
public CxROM(string type)
|
||||
{
|
||||
this.type = type;
|
||||
|
@ -36,9 +50,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
else return base.ReadPPU(addr);
|
||||
}
|
||||
|
||||
int chr;
|
||||
int chr_mask;
|
||||
bool bus_conflict;
|
||||
public override void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
base.SaveStateBinary(bw);
|
||||
bw.Write(chr);
|
||||
}
|
||||
|
||||
public override void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
base.LoadStateBinary(br);
|
||||
chr = br.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,25 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
||||
{
|
||||
//generally mapper66
|
||||
|
||||
//Doraemon
|
||||
//Dragon Power
|
||||
//Gumshoe
|
||||
//Thunder & Lightning
|
||||
//Super Mario Bros. + Duck Hunt
|
||||
|
||||
//should this be called GNROM? there is no other Gx anything AFAIK..
|
||||
|
||||
public class GxROM : NES.NESBoardBase
|
||||
{
|
||||
//configuraton
|
||||
int prg_mask, chr_mask;
|
||||
|
||||
//state
|
||||
int prg, chr;
|
||||
|
||||
public override void Initialize(NES.RomInfo romInfo, NES nes)
|
||||
|
@ -40,6 +52,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
prg = (((value>>4) & 3) & prg_mask);
|
||||
}
|
||||
|
||||
int mask;
|
||||
public override void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
base.SaveStateBinary(bw);
|
||||
bw.Write(chr);
|
||||
bw.Write(prg);
|
||||
}
|
||||
|
||||
public override void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
base.LoadStateBinary(br);
|
||||
chr = br.ReadInt32();
|
||||
prg = br.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +1,23 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
||||
{
|
||||
//mapper 11
|
||||
|
||||
//Crystal Mines
|
||||
//Metal Fighter
|
||||
|
||||
public class Discrete_74x377 : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int prg_mask, chr_mask;
|
||||
int prg, chr;
|
||||
bool bus_conflict = true;
|
||||
|
||||
//state
|
||||
int prg, chr;
|
||||
|
||||
public override void Initialize(NES.RomInfo romInfo, NES nes)
|
||||
{
|
||||
base.Initialize(romInfo, nes);
|
||||
|
@ -47,5 +54,19 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
prg = (value & 3) & prg_mask;
|
||||
chr = (value >> 4) & chr_mask;
|
||||
}
|
||||
|
||||
public override void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
base.SaveStateBinary(bw);
|
||||
bw.Write(chr);
|
||||
bw.Write(prg);
|
||||
}
|
||||
|
||||
public override void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
base.LoadStateBinary(br);
|
||||
chr = br.ReadInt32();
|
||||
prg = br.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
{
|
||||
public class NROM : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
int mask;
|
||||
|
||||
//state
|
||||
//(none)
|
||||
|
||||
public override void Initialize(NES.RomInfo romInfo, NES nes)
|
||||
{
|
||||
base.Initialize(romInfo, nes);
|
||||
|
@ -16,7 +22,5 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
addr &= mask;
|
||||
return RomInfo.ROM[addr];
|
||||
}
|
||||
|
||||
int mask;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
||||
|
@ -26,6 +27,33 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
//well, lets leave it.
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
bw.Write(shift_count);
|
||||
bw.Write(shift_val);
|
||||
bw.Write(chr_mode);
|
||||
bw.Write(prg_mode);
|
||||
bw.Write(prg_slot);
|
||||
bw.Write((int)mirror);
|
||||
bw.Write(chr_0);
|
||||
bw.Write(chr_1);
|
||||
bw.Write(wram_disable);
|
||||
bw.Write(prg);
|
||||
}
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
shift_count = br.ReadInt32();
|
||||
shift_val = br.ReadInt32();
|
||||
chr_mode = br.ReadInt32();
|
||||
prg_mode = br.ReadInt32();
|
||||
prg_slot = br.ReadInt32();
|
||||
mirror = (NES.EMirrorType)br.ReadInt32();
|
||||
chr_0 = br.ReadInt32();
|
||||
chr_1 = br.ReadInt32();
|
||||
wram_disable = br.ReadInt32();
|
||||
prg = br.ReadInt32();
|
||||
}
|
||||
|
||||
public enum Rev
|
||||
{
|
||||
A, B1, B2, B3
|
||||
|
@ -137,12 +165,14 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
|
||||
public class SxROM : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
string type;
|
||||
MMC1 mmc1;
|
||||
int prg_mask, chr_mask;
|
||||
byte[] cram, pram;
|
||||
int cram_mask, pram_mask;
|
||||
|
||||
//state
|
||||
byte[] cram, pram;
|
||||
MMC1 mmc1;
|
||||
|
||||
public SxROM(string type)
|
||||
{
|
||||
|
@ -184,6 +214,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
cram = new byte[RomInfo.CRAM_Size * 1024];
|
||||
cram_mask = cram.Length - 1;
|
||||
}
|
||||
else cram = new byte[0];
|
||||
|
||||
Debug.Assert(RomInfo.PRAM_Size == 0 || RomInfo.PRAM_Size == 8);
|
||||
if (RomInfo.PRAM_Size != 0)
|
||||
|
@ -191,6 +222,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
pram = new byte[RomInfo.CRAM_Size * 1024];
|
||||
pram_mask = pram.Length - 1;
|
||||
}
|
||||
else pram = new byte[0];
|
||||
|
||||
if (RomInfo.CHR_Size != 0)
|
||||
{
|
||||
|
@ -264,6 +296,21 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
}
|
||||
}
|
||||
|
||||
public override void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
base.SaveStateBinary(bw);
|
||||
mmc1.SaveStateBinary(bw);
|
||||
Util.WriteByteBuffer(bw, pram);
|
||||
Util.WriteByteBuffer(bw, cram);
|
||||
}
|
||||
public override void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
base.LoadStateBinary(br);
|
||||
mmc1.LoadStateBinary(br);
|
||||
pram = Util.ReadByteBuffer(br, false);
|
||||
cram = Util.ReadByteBuffer(br, false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,30 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
||||
{
|
||||
//generally mapper2
|
||||
|
||||
//Mega Man
|
||||
//Castlevania
|
||||
//Contra
|
||||
//Duck Tales
|
||||
//Metal Gear
|
||||
|
||||
//TODO - simplify logic and handle fewer (known) cases (e.g. no IsPowerOfTwo, but rather hardcoded cases)
|
||||
|
||||
public class UxROM : NES.NESBoardBase
|
||||
{
|
||||
//configuration
|
||||
string type;
|
||||
int pagemask;
|
||||
int cram_mask;
|
||||
|
||||
//state
|
||||
int prg;
|
||||
byte[] cram;
|
||||
|
||||
public UxROM(string type)
|
||||
{
|
||||
this.type = type;
|
||||
|
@ -24,6 +39,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
else throw new InvalidOperationException("Invalid UxROM type");
|
||||
|
||||
//guess CRAM size (this is a very confident guess!)
|
||||
//(should these guesses be here?) (is this a guess? maybe all these boards have cram)
|
||||
if (RomInfo.CRAM_Size == -1) RomInfo.CRAM_Size = 8;
|
||||
|
||||
cram = new byte[RomInfo.CRAM_Size * 1024];
|
||||
|
@ -59,9 +75,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo.Boards
|
|||
else base.WritePPU(addr,value);
|
||||
}
|
||||
|
||||
int pagemask;
|
||||
int prg;
|
||||
byte[] cram;
|
||||
int cram_mask;
|
||||
public override void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
base.SaveStateBinary(bw);
|
||||
bw.Write(prg);
|
||||
Util.WriteByteBuffer(bw, cram);
|
||||
}
|
||||
|
||||
public override void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
base.LoadStateBinary(br);
|
||||
prg = br.ReadInt32();
|
||||
cram = Util.ReadByteBuffer(br, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,6 +49,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
void WritePRAM(int addr, byte value);
|
||||
void Initialize(RomInfo romInfo, NES nes);
|
||||
byte[] SaveRam { get; }
|
||||
void SaveStateBinary(BinaryWriter bw);
|
||||
void LoadStateBinary(BinaryReader br);
|
||||
};
|
||||
|
||||
public abstract class NESBoardBase : INESBoard
|
||||
|
@ -62,6 +64,15 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
public RomInfo RomInfo { get; set; }
|
||||
public NES NES { get; set; }
|
||||
|
||||
public virtual void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) bw.Write(mirroring[i]);
|
||||
}
|
||||
public virtual void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) mirroring[i] = br.ReadInt32();
|
||||
}
|
||||
|
||||
int[] mirroring = new int[4];
|
||||
protected void SetMirroring(int a, int b, int c, int d)
|
||||
{
|
||||
|
@ -132,17 +143,17 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
public virtual byte[] SaveRam { get { return null; } }
|
||||
}
|
||||
|
||||
//hardware
|
||||
//hardware/state
|
||||
protected MOS6502 cpu;
|
||||
INESBoard board;
|
||||
public PPU ppu;
|
||||
RomInfo romInfo;
|
||||
byte[] ram;
|
||||
|
||||
IPortDevice[] ports;
|
||||
int cpu_accumulate;
|
||||
|
||||
//user configuration
|
||||
int[,] palette; //TBD!!
|
||||
IPortDevice[] ports;
|
||||
RomInfo romInfo;
|
||||
|
||||
public byte ReadPPUReg(int addr)
|
||||
{
|
||||
|
@ -299,7 +310,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
ppu.FrameAdvance();
|
||||
}
|
||||
|
||||
int cpu_accumulate;
|
||||
protected void RunCpu(int cycles)
|
||||
{
|
||||
if (ppu.PAL)
|
||||
|
@ -415,27 +425,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
set { }
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter writer)
|
||||
{
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public string SystemId { get { return "NES"; } }
|
||||
public IList<MemoryDomain> MemoryDomains { get { return new List<MemoryDomain>(); } }
|
||||
public MemoryDomain MainMemory
|
||||
|
@ -684,6 +673,65 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
|
||||
HardReset();
|
||||
}
|
||||
|
||||
public void SaveStateText(TextWriter writer)
|
||||
{
|
||||
writer.WriteLine("[NES]");
|
||||
byte[] lol = SaveStateBinary();
|
||||
writer.WriteLine("blob {0}", Util.BytesToHexString(lol));
|
||||
writer.WriteLine("[/NES]");
|
||||
}
|
||||
|
||||
public void LoadStateText(TextReader reader)
|
||||
{
|
||||
byte[] blob = null;
|
||||
while (true)
|
||||
{
|
||||
string[] args = reader.ReadLine().Split(' ');
|
||||
if (args[0] == "blob")
|
||||
blob = Util.HexStringToBytes(args[1]);
|
||||
else if (args[0] == "[/NES]") break;
|
||||
}
|
||||
if (blob == null) throw new ArgumentException();
|
||||
LoadStateBinary(new BinaryReader(new MemoryStream(blob)));
|
||||
}
|
||||
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BinaryWriter bw = new BinaryWriter(ms);
|
||||
SaveStateBinary(bw);
|
||||
bw.Flush();
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
using (var sw = new StringWriter())
|
||||
{
|
||||
cpu.SaveStateText(sw);
|
||||
sw.Flush();
|
||||
Util.WriteByteBuffer(bw, System.Text.Encoding.ASCII.GetBytes(sw.ToString()));
|
||||
}
|
||||
Util.WriteByteBuffer(bw,ram);
|
||||
bw.Write(cpu_accumulate);
|
||||
board.SaveStateBinary(bw);
|
||||
ppu.SaveStateBinary(bw);
|
||||
bw.Flush();
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
using (var sr = new StringReader(System.Text.Encoding.ASCII.GetString(Util.ReadByteBuffer(br, false))))
|
||||
cpu.LoadStateText(sr);
|
||||
ram = Util.ReadByteBuffer(br, false);
|
||||
cpu_accumulate = br.ReadInt32();
|
||||
board.LoadStateBinary(br);
|
||||
ppu.LoadStateBinary(br);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,9 +51,50 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
Reset();
|
||||
}
|
||||
|
||||
//state
|
||||
int ppudead; //measured in frames
|
||||
bool idleSynch;
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
bw.Write(ppudead);
|
||||
bw.Write(idleSynch);
|
||||
bw.Write((bool)Reg2002_objoverflow);
|
||||
bw.Write((bool)Reg2002_objhit);
|
||||
bw.Write((bool)Reg2002_vblank_active);
|
||||
bw.Write(PPUGenLatch);
|
||||
bw.Write(reg_2000.Value);
|
||||
bw.Write(reg_2001.Value);
|
||||
bw.Write(reg_2003);
|
||||
Util.WriteByteBuffer(bw, OAM);
|
||||
Util.WriteByteBuffer(bw, PALRAM);
|
||||
Util.WriteByteBuffer(bw, NTARAM);
|
||||
bw.Write(vtoggle);
|
||||
bw.Write(VRAMBuffer);
|
||||
ppur.SaveStateBinary(bw);
|
||||
bw.Write(xbuf);
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
ppudead = br.ReadInt32();
|
||||
idleSynch = br.ReadBoolean();
|
||||
Reg2002_objoverflow = br.ReadBit();
|
||||
Reg2002_objhit = br.ReadBit();
|
||||
Reg2002_vblank_active = br.ReadBit();
|
||||
PPUGenLatch = br.ReadByte();
|
||||
reg_2000.Value = br.ReadByte();
|
||||
reg_2001.Value = br.ReadByte();
|
||||
reg_2003 = br.ReadByte();
|
||||
OAM = Util.ReadByteBuffer(br,false);
|
||||
PALRAM = Util.ReadByteBuffer(br, false);
|
||||
NTARAM = Util.ReadByteBuffer(br, false);
|
||||
vtoggle = br.ReadBoolean();
|
||||
VRAMBuffer = br.ReadByte();
|
||||
ppur.LoadStateBinary(br);
|
||||
xbuf = br.ReadShorts(xbuf.Length);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
regs_reset();
|
||||
|
|
|
@ -71,6 +71,42 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
reset();
|
||||
}
|
||||
|
||||
public void SaveStateBinary(BinaryWriter bw)
|
||||
{
|
||||
bw.Write(fv);
|
||||
bw.Write(v);
|
||||
bw.Write(h);
|
||||
bw.Write(vt);
|
||||
bw.Write(ht);
|
||||
bw.Write(_fv);
|
||||
bw.Write(_v);
|
||||
bw.Write(_h);
|
||||
bw.Write(_vt);
|
||||
bw.Write(_ht);
|
||||
bw.Write(fh);
|
||||
bw.Write(status.cycle);
|
||||
bw.Write(status.end_cycle);
|
||||
bw.Write(status.sl);
|
||||
}
|
||||
|
||||
public void LoadStateBinary(BinaryReader br)
|
||||
{
|
||||
fv = br.ReadInt32();
|
||||
v = br.ReadInt32();
|
||||
h = br.ReadInt32();
|
||||
vt = br.ReadInt32();
|
||||
ht = br.ReadInt32();
|
||||
_fv = br.ReadInt32();
|
||||
_v = br.ReadInt32();
|
||||
_h = br.ReadInt32();
|
||||
_vt = br.ReadInt32();
|
||||
_ht = br.ReadInt32();
|
||||
fh = br.ReadInt32();
|
||||
status.cycle = br.ReadInt32();
|
||||
status.end_cycle = br.ReadInt32();
|
||||
status.sl = br.ReadInt32();
|
||||
}
|
||||
|
||||
//normal clocked regs. as the game can interfere with these at any time, they need to be savestated
|
||||
public int fv;//3
|
||||
public int v;//1
|
||||
|
@ -221,8 +257,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
public Bit ppu_layer; //PPU layer select (should always be 0 in the NES; some Nintendo arcade boards presumably had two PPUs)
|
||||
public Bit vblank_nmi_gen; //Vertical blank NMI generation (0: off; 1: on)
|
||||
|
||||
|
||||
public byte Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)(ppu.ppur._h | (ppu.ppur._v << 1) | (vram_incr32 << 2) | (obj_pattern_hi << 3) | (bg_pattern_hi << 4) | (obj_size_16 << 5) | (ppu_layer << 6) | (vblank_nmi_gen << 7));
|
||||
}
|
||||
set
|
||||
{
|
||||
ppu.ppur._h = value & 1;
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
public byte pt_0, pt_1;
|
||||
};
|
||||
|
||||
public int[] xbuf = new int[256*256];
|
||||
public short[] xbuf = new short[256*256];
|
||||
|
||||
void Read_bgdata(ref BGDataRecord bgdata) {
|
||||
int addr = ppur.get_ntread();
|
||||
|
@ -68,11 +68,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
}
|
||||
|
||||
//TODO - check flashing sirens in werewolf
|
||||
int PaletteAdjustPixel(int pixel)
|
||||
short PaletteAdjustPixel(int pixel)
|
||||
{
|
||||
//tack on the deemph bits
|
||||
pixel |= (reg_2001.intense_red<<8)|(reg_2001.intense_green<<9)|(reg_2001.intense_blue<<10);
|
||||
return pixel;
|
||||
return (short)pixel;
|
||||
}
|
||||
|
||||
const int kLineTime = 341;
|
||||
|
|
|
@ -200,6 +200,65 @@ namespace BizHawk
|
|||
writer.WriteLine();
|
||||
}
|
||||
|
||||
public static void SaveAsHex(this int[] buffer, TextWriter writer)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
{
|
||||
writer.Write("{0:X8}", buffer[i]);
|
||||
}
|
||||
writer.WriteLine();
|
||||
}
|
||||
|
||||
public static void SaveAsHex(this uint[] buffer, TextWriter writer)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
{
|
||||
writer.Write("{0:X8}", buffer[i]);
|
||||
}
|
||||
writer.WriteLine();
|
||||
}
|
||||
|
||||
public static void Write(this BinaryWriter bw, int[] buffer)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
bw.Write(buffer[i]);
|
||||
}
|
||||
|
||||
public static void Write(this BinaryWriter bw, uint[] buffer)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
bw.Write(buffer[i]);
|
||||
}
|
||||
|
||||
public static void Write(this BinaryWriter bw, short[] buffer)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
bw.Write(buffer[i]);
|
||||
}
|
||||
|
||||
public static void Write(this BinaryWriter bw, ushort[] buffer)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
bw.Write(buffer[i]);
|
||||
}
|
||||
|
||||
public static int[] ReadInts(this BinaryReader br, int num)
|
||||
{
|
||||
int[] ret = new int[num];
|
||||
for (int i = 0; i < num; i++)
|
||||
ret[i] = br.ReadInt32();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static short[] ReadShorts(this BinaryReader br, int num)
|
||||
{
|
||||
short[] ret = new short[num];
|
||||
for (int i = 0; i < num; i++)
|
||||
ret[i] = br.ReadInt16();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static void ReadFromHex(this byte[] buffer, string hex)
|
||||
{
|
||||
if (hex.Length % 2 != 0)
|
||||
|
@ -232,6 +291,22 @@ namespace BizHawk
|
|||
buffer[i] = ushort.Parse(ushorthex, NumberStyles.HexNumber);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReadFromHex(this int[] buffer, BinaryWriter bw)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
bw.Write(buffer[i]);
|
||||
}
|
||||
|
||||
public static void SaveAsHex(this uint[] buffer, BinaryWriter bw)
|
||||
{
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
bw.Write(buffer[i]);
|
||||
}
|
||||
|
||||
//these don't work??? they dont get chosen by compiler
|
||||
public static void Write(this BinaryWriter bw, Bit bit) { bw.Write((bool)bit); }
|
||||
public static Bit ReadBit(this BinaryReader br) { return br.ReadBoolean(); }
|
||||
}
|
||||
|
||||
public static class Colors
|
||||
|
@ -255,7 +330,7 @@ namespace BizHawk
|
|||
|
||||
|
||||
//I think this is a little faster with uint than with byte
|
||||
struct Bit
|
||||
public struct Bit
|
||||
{
|
||||
Bit(uint val) { this.val = val; }
|
||||
uint val;
|
||||
|
@ -299,6 +374,7 @@ namespace BizHawk
|
|||
|
||||
/// <summary>
|
||||
/// conerts bytes to an uppercase string of hex numbers in upper case without any spacing or anything
|
||||
/// //could be extension method
|
||||
/// </summary>
|
||||
public static string BytesToHexString(byte[] bytes)
|
||||
{
|
||||
|
@ -308,6 +384,57 @@ namespace BizHawk
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
//could be extension method
|
||||
public static byte[] HexStringToBytes(string str)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
if (str.Length % 2 != 0) throw new ArgumentException();
|
||||
int len = str.Length/2;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
int d = 0;
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
char c = char.ToLower(str[i * 2 + j]);
|
||||
if (c >= '0' && c <= '9')
|
||||
d += (c - '0');
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
d += (c - 'a') + 10;
|
||||
else throw new ArgumentException();
|
||||
if (j == 0) d <<= 4;
|
||||
}
|
||||
ms.WriteByte((byte)d);
|
||||
}
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
//could be extension method
|
||||
public static void WriteByteBuffer(BinaryWriter bw, byte[] data)
|
||||
{
|
||||
if (data == null) bw.Write(0);
|
||||
else
|
||||
{
|
||||
bw.Write(data.Length);
|
||||
bw.Write(data);
|
||||
}
|
||||
}
|
||||
|
||||
//could be extension method
|
||||
public static byte[] ReadByteBuffer(BinaryReader br, bool return_null)
|
||||
{
|
||||
int len = br.ReadInt32();
|
||||
if (len == 0 && return_null) return null;
|
||||
byte[] ret = new byte[len];
|
||||
int ofs = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
int done = br.Read(ret, ofs, len);
|
||||
ofs += done;
|
||||
len -= done;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static unsafe int memcmp(void* a, string b, int len)
|
||||
{
|
||||
fixed (byte* bp = System.Text.Encoding.ASCII.GetBytes(b))
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
public bool LimitFramerate = true;
|
||||
public bool AutoMinimizeSkipping = true;
|
||||
public bool DisplayVSync = false;
|
||||
public bool RewindEnabled = true;
|
||||
|
||||
// Display options
|
||||
public bool DisplayFPS = false;
|
||||
|
|
|
@ -610,7 +610,7 @@ namespace BizHawk.MultiClient
|
|||
runFrame = true;
|
||||
}
|
||||
|
||||
if (/*Global.Config.RewindEnabled && */Global.ClientControls["Rewind"])
|
||||
if (Global.Config.RewindEnabled && Global.ClientControls["Rewind"])
|
||||
{
|
||||
rewindCredits += Global.Config.SpeedPercent;
|
||||
int rewindTodo = rewindCredits / 100;
|
||||
|
@ -629,7 +629,7 @@ namespace BizHawk.MultiClient
|
|||
bool genSound = false;
|
||||
if (runFrame)
|
||||
{
|
||||
if(!suppressCaptureRewind) CaptureRewindState();
|
||||
if(!suppressCaptureRewind && Global.Config.RewindEnabled) CaptureRewindState();
|
||||
if (!runloop_frameadvance) genSound = true;
|
||||
else if (!Global.Config.MuteFrameAdvance)
|
||||
genSound = true;
|
||||
|
|
|
@ -38,6 +38,8 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
if (inChangeSequence == false)
|
||||
{
|
||||
if (i >= LastState.Length)
|
||||
continue;
|
||||
if (CurrentState[i] == LastState[i])
|
||||
continue;
|
||||
|
||||
|
@ -82,6 +84,8 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
if (inChangeSequence == false)
|
||||
{
|
||||
if (i >= LastState.Length)
|
||||
continue;
|
||||
if (CurrentState[i] == LastState[i])
|
||||
continue;
|
||||
|
||||
|
|
|
@ -2386,7 +2386,7 @@ D821FB982CE47299FDB08A027EC0B8BE Super Mario Bros - Duck Hunt (U) NES board=Gx
|
|||
;GxROM 8,4 (mapper 66) ;these frequently needs to be corrected to V
|
||||
ADD4E9F5ED4391A6B3FDFC5F0E300E71 Doraemon (J) NES board=GxROM;mirror=V;PRG=8;CHR=4
|
||||
4E9D128C63A41C8CC20FF1114A67A2DD Dragon Power (U) NES board=GxROM;mirror=V;PRG=8;CHR=4
|
||||
8F43E7D7BD3DBDF6D8ADF3E046DE3562 Gumshoe (UE) NES board=GxROM;mirror=H;PRG=8;CHR=4
|
||||
8F43E7D7BD3DBDF6D8ADF3E046DE3562 Gumshoe (UE) NES board=GxROM;mirror=V;PRG=8;CHR=4
|
||||
|
||||
;GxROM 8,16 (mapper 66)
|
||||
BE40E77C5532AF8E2C1EA7B96831CCEA Thunder & Lightning (U).nes NES board=GxROM;mirror=H;PRG=8;CHR=16
|
Loading…
Reference in New Issue