186 lines
5.9 KiB
C#
186 lines
5.9 KiB
C#
using System.Collections.Generic;
|
|
|
|
namespace VirtualNes.Core
|
|
{
|
|
public struct State
|
|
{
|
|
public FILEHDR2 HEADER;
|
|
|
|
public BLOCKHDR regBLOCK;
|
|
public REGSTAT reg;
|
|
|
|
public BLOCKHDR ramBLOCK;
|
|
public RAMSTAT ram;
|
|
/// <summary> Maybe null cause by rom IsSaveRAM() </summary>
|
|
public byte[] WRAM;
|
|
|
|
public BLOCKHDR mmuBLOCK;
|
|
public MMUSTAT mmu;
|
|
public List<byte> CPU_MEM_BANK;
|
|
public byte[] VRAM;
|
|
public List<byte> CRAM;
|
|
|
|
public BLOCKHDR mmcBLOCK;
|
|
public MMCSTAT mmc;
|
|
|
|
public BLOCKHDR ctrBLOCK;
|
|
public CTRSTAT ctr;
|
|
|
|
public BLOCKHDR sndBLOCK;
|
|
public SNDSTAT snd;
|
|
|
|
public BLOCKHDR dskBLOCK;
|
|
public DISKDATA dsk;
|
|
public List<uint> dskdata;
|
|
|
|
public BLOCKHDR exctrBLOCK;
|
|
public EXCTRSTAT exctr;
|
|
|
|
public readonly byte[] ToBytes()
|
|
{
|
|
StateBuffer buffer = new StateBuffer();
|
|
|
|
HEADER.SaveState(buffer);
|
|
|
|
buffer.Write(WRAM != null ? WRAM.Length : 0);
|
|
buffer.Write(CPU_MEM_BANK != null ? CPU_MEM_BANK.Count : 0);
|
|
buffer.Write(VRAM != null ? VRAM.Length : 0);
|
|
buffer.Write(CRAM != null ? CRAM.Count : 0);
|
|
buffer.Write(dskdata != null ? dskdata.Count : 0);
|
|
|
|
if (regBLOCK.Valid)
|
|
{
|
|
regBLOCK.SaveState(buffer);
|
|
reg.SaveState(buffer);
|
|
}
|
|
|
|
if (ramBLOCK.Valid)
|
|
{
|
|
ramBLOCK.SaveState(buffer);
|
|
ram.SaveState(buffer);
|
|
if (WRAM != null) buffer.Write(WRAM);
|
|
}
|
|
|
|
if (mmuBLOCK.Valid)
|
|
{
|
|
mmuBLOCK.SaveState(buffer);
|
|
mmu.SaveState(buffer);
|
|
buffer.Write(CPU_MEM_BANK.ToArray());
|
|
buffer.Write(VRAM);
|
|
buffer.Write(CRAM.ToArray());
|
|
}
|
|
|
|
if (mmcBLOCK.Valid)
|
|
{
|
|
mmcBLOCK.SaveState(buffer);
|
|
mmc.SaveState(buffer);
|
|
}
|
|
|
|
if (ctrBLOCK.Valid)
|
|
{
|
|
ctrBLOCK.SaveState(buffer);
|
|
ctr.SaveState(buffer);
|
|
}
|
|
|
|
if (sndBLOCK.Valid)
|
|
{
|
|
sndBLOCK.SaveState(buffer);
|
|
snd.SaveState(buffer);
|
|
}
|
|
|
|
if (dskBLOCK.Valid)
|
|
{
|
|
dskBLOCK.SaveState(buffer);
|
|
dsk.SaveState(buffer);
|
|
foreach (var data in dskdata)
|
|
{
|
|
buffer.Write(data);
|
|
}
|
|
}
|
|
|
|
if (exctrBLOCK.Valid)
|
|
{
|
|
exctrBLOCK.SaveState(buffer);
|
|
exctr.SaveState(buffer);
|
|
}
|
|
|
|
return buffer.Data.ToArray();
|
|
}
|
|
public void FromByte(byte[] data)
|
|
{
|
|
StateReader buffer = new StateReader(data);
|
|
|
|
HEADER.LoadState(buffer);
|
|
|
|
var WRAM_Length = buffer.Read_int();
|
|
var CPU_MEM_BANK_Length = buffer.Read_int();
|
|
var VRAM_Length = buffer.Read_int();
|
|
var CRAM_Length = buffer.Read_int();
|
|
var dskdata_Length = buffer.Read_int();
|
|
|
|
while (buffer.Remain > 0)
|
|
{
|
|
BLOCKHDR block = new BLOCKHDR();
|
|
block.LoadState(buffer);
|
|
|
|
switch (block.ID)
|
|
{
|
|
case "REG DATA":
|
|
regBLOCK = block;
|
|
reg.LoadState(buffer);
|
|
break;
|
|
case "RAM DATA":
|
|
ramBLOCK = block;
|
|
ram.LoadState(buffer);
|
|
if (WRAM_Length > 0)
|
|
WRAM = buffer.Read_bytes(WRAM_Length);
|
|
else
|
|
WRAM = new byte[0];
|
|
break;
|
|
case "MMU DATA":
|
|
mmuBLOCK = block;
|
|
mmu.LoadState(buffer);
|
|
if (CPU_MEM_BANK_Length > 0)
|
|
CPU_MEM_BANK = new List<byte>(buffer.Read_bytes(CPU_MEM_BANK_Length));
|
|
else
|
|
CPU_MEM_BANK = new List<byte>();
|
|
|
|
if (VRAM_Length > 0)
|
|
VRAM = buffer.Read_bytes(VRAM_Length);
|
|
else
|
|
VRAM = new byte[0];
|
|
if (CRAM_Length > 0)
|
|
CRAM = new List<byte>(buffer.Read_bytes(CRAM_Length));
|
|
else
|
|
CRAM = new List<byte>();
|
|
break;
|
|
case "MMC DATA":
|
|
mmcBLOCK = block;
|
|
mmc.LoadState(buffer);
|
|
break;
|
|
case "CTR DATA":
|
|
ctrBLOCK = block;
|
|
ctr.LoadState(buffer);
|
|
break;
|
|
case "SND DATA":
|
|
sndBLOCK = block;
|
|
snd.LoadState(buffer);
|
|
break;
|
|
case "DISKDATA":
|
|
dskBLOCK = block;
|
|
dsk.LoadState(buffer);
|
|
if (dskdata_Length > 0)
|
|
dskdata = new List<uint>(buffer.Read_uints(dskdata_Length));
|
|
else
|
|
dskdata = new List<uint>();
|
|
break;
|
|
case "EXCTRDAT":
|
|
exctrBLOCK = block;
|
|
exctr.LoadState(buffer);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|