gen: rewind is working, savestates are not working [yet]. will fix more tomorrow

This commit is contained in:
beirich 2012-09-17 05:48:24 +00:00
parent bdd74e356c
commit b04189b6b1
8 changed files with 229 additions and 18 deletions

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.IO;
namespace Native68000 namespace Native68000
{ {
@ -48,6 +49,9 @@ namespace Native68000
[DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int QueryCpuState(int regcode); public static extern int QueryCpuState(int regcode);
[DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetCpuState(int regcode, int value);
[DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("MusashiDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetCyclesRemaining(); public static extern int GetCyclesRemaining();
@ -72,5 +76,17 @@ namespace Native68000
public static int PC { get { return QueryCpuState(16); } } public static int PC { get { return QueryCpuState(16); } }
public static int SR { get { return QueryCpuState(17); } } public static int SR { get { return QueryCpuState(17); } }
public static int SP { get { return QueryCpuState(18); } } public static int SP { get { return QueryCpuState(18); } }
public static void SaveStateBinary(BinaryWriter writer)
{
for (int i=0; i<31; i++)
writer.Write(QueryCpuState(i));
}
public static void LoadStateBinary(BinaryReader reader)
{
for (int i = 0; i < 31; i++)
SetCpuState(i, reader.ReadInt32());
}
} }
} }

View File

@ -12,6 +12,7 @@ Still some lesser issues with cancelling a fadeout. Otherwise CDDA is working no
- JANSHIN DENSETSU sets the T flag prior to an LDA instruction; MANY TIMES (ie it doesnt seem to be an accident). - JANSHIN DENSETSU sets the T flag prior to an LDA instruction; MANY TIMES (ie it doesnt seem to be an accident).
Unclear if T flag actually affects LDA instruction. Unclear if T flag actually affects LDA instruction.
- Gradius II sets T flag prior to an STZ instruction. Unclear if T-flag affects STZ instruction.
- Ryuuko no Ken is all messed up, and I don't super care :| - Ryuuko no Ken is all messed up, and I don't super care :|
- Record of Lodoss War wont start game from title screen - Record of Lodoss War wont start game from title screen
- Valis: Screen is black during entire intro section - Valis: Screen is black during entire intro section

View File

@ -522,6 +522,39 @@ int orig_addr = VdpDataAddr;
WriteVdpRegister(i, Registers[i]); WriteVdpRegister(i, Registers[i]);
} }
public void SaveStateBinary(BinaryWriter writer)
{
writer.Write(VRAM);
writer.Write(CRAM);
writer.Write(VSRAM);
writer.Write(Registers);
writer.Write(ControlWordPending);
writer.Write(DmaFillModePending);
writer.Write(VdpDataAddr);
writer.Write(VdpDataCode);
}
public void LoadStateBinary(BinaryReader reader)
{
VRAM = reader.ReadBytes(VRAM.Length);
CRAM = reader.ReadUInt16s(CRAM.Length);
VSRAM = reader.ReadUInt16s(VSRAM.Length);
Registers = reader.ReadBytes(Registers.Length);
ControlWordPending = reader.ReadBoolean();
DmaFillModePending = reader.ReadBoolean();
VdpDataAddr = reader.ReadUInt16();
VdpDataCode = reader.ReadByte();
for (int i = 0; i < CRAM.Length; i++)
ProcessPalette(i);
for (int i = 0; i < VRAM.Length; i++)
UpdatePatternBuffer(i);
for (int i = 0; i < Registers.Length; i++)
WriteVdpRegister(i, Registers[i]);
}
#endregion #endregion
} }
} }

View File

@ -271,7 +271,7 @@ namespace BizHawk.Emulation.Consoles.Sega
public void SaveStateText(TextWriter writer) public void SaveStateText(TextWriter writer)
{ {
writer.WriteLine("[MegaDrive]"); /*writer.WriteLine("[MegaDrive]");
MainCPU.SaveStateText(writer, "Main68K"); MainCPU.SaveStateText(writer, "Main68K");
SoundCPU.SaveStateText(writer); SoundCPU.SaveStateText(writer);
PSG.SaveStateText(writer); PSG.SaveStateText(writer);
@ -283,14 +283,12 @@ namespace BizHawk.Emulation.Consoles.Sega
Ram.SaveAsHex(writer); Ram.SaveAsHex(writer);
writer.Write("Z80RAM "); writer.Write("Z80RAM ");
Z80Ram.SaveAsHex(writer); Z80Ram.SaveAsHex(writer);
writer.WriteLine("[/MegaDrive]");*/
writer.WriteLine("[/MegaDrive]");
} }
public void LoadStateText(TextReader reader) public void LoadStateText(TextReader reader)
{ {
while (true) /*while (true)
{ {
string[] args = reader.ReadLine().Split(' '); string[] args = reader.ReadLine().Split(' ');
if (args[0].Trim() == "") continue; if (args[0].Trim() == "") continue;
@ -316,22 +314,53 @@ namespace BizHawk.Emulation.Consoles.Sega
VDP.LoadStateText(reader); VDP.LoadStateText(reader);
else else
Console.WriteLine("Skipping unrecognized identifier " + args[0]); Console.WriteLine("Skipping unrecognized identifier " + args[0]);
} }*/
} }
public void SaveStateBinary(BinaryWriter writer) public void SaveStateBinary(BinaryWriter writer)
{ {
//throw new NotImplementedException(); Musashi.SaveStateBinary(writer); // 124
SoundCPU.SaveStateBinary(writer); // 46
PSG.SaveStateBinary(writer); // 15
VDP.SaveStateBinary(writer); // 65781
YM2612.SaveStateBinary(writer); // 35
writer.Write(Ram); // 65535
writer.Write(Z80Ram); // 8192
writer.Write(Frame); // 4
// lag counter crap TODO
writer.Write(M68000HasZ80Bus); // 1
writer.Write(Z80Reset); // 1
// TODO Saveram/EEPROM
} }
public void LoadStateBinary(BinaryReader reader) public void LoadStateBinary(BinaryReader reader)
{ {
//throw new NotImplementedException(); Musashi.LoadStateBinary(reader);
SoundCPU.LoadStateBinary(reader);
PSG.LoadStateBinary(reader);
VDP.LoadStateBinary(reader);
YM2612.LoadStateBinary(reader);
Ram = reader.ReadBytes(Ram.Length);
Z80Ram = reader.ReadBytes(Z80Ram.Length);
Frame = reader.ReadInt32();
M68000HasZ80Bus = reader.ReadBoolean();
Z80Reset = reader.ReadBoolean();
} }
public byte[] SaveStateBinary() public byte[] SaveStateBinary()
{ {
return new byte[0]; var buf = new byte[141485];
var stream = new MemoryStream(buf);
var writer = new BinaryWriter(stream);
SaveStateBinary(writer);
//Console.WriteLine("buf len = {0}", stream.Position);
writer.Close();
return buf;
} }
IList<MemoryDomain> memoryDomains; IList<MemoryDomain> memoryDomains;

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace BizHawk.Emulation.Sound namespace BizHawk.Emulation.Sound
{ {
@ -1053,11 +1054,6 @@ namespace BizHawk.Emulation.Sound
return value - Math.Floor(value); return value - Math.Floor(value);
} }
/// <summary>
/// basic linear audio resampler. sampling rate is inferred from buffer sizes
/// </summary>
/// <param name="input">stereo s16</param>
/// <param name="output">stereo s16</param>
static void LinearDownsampler(short[] input, short[] output) static void LinearDownsampler(short[] input, short[] output)
{ {
double samplefactor = input.Length / (double)output.Length; double samplefactor = input.Length / (double)output.Length;
@ -1162,5 +1158,134 @@ namespace BizHawk.Emulation.Sound
public void DiscardSamples() { } public void DiscardSamples() { }
public int MaxVolume { get; set; } public int MaxVolume { get; set; }
// ====================================================================================
// Save States
// ====================================================================================
public void SaveStateBinary(BinaryWriter writer)
{
writer.Write(TimerAPeriod);
writer.Write(TimerBPeriod);
writer.Write(TimerATripped);
writer.Write(TimerBTripped);
writer.Write(TimerAResetClock);
writer.Write(TimerBResetClock);
writer.Write(TimerALastReset);
writer.Write(TimerBLastReset);
writer.Write(TimerControl27);
writer.Write(egDivisorCounter);
writer.Write(egCycleCounter);
writer.Write(PartSelect);
writer.Write(RegisterSelect);
writer.Write(DacEnable);
writer.Write(DacValue);
for (int i = 0; i < 6; i++)
ChannelSaveStateBinary(writer, Channels[i]);
}
public void LoadStateBinary(BinaryReader reader)
{
TimerAPeriod = reader.ReadInt32();
TimerBPeriod = reader.ReadInt32();
TimerATripped = reader.ReadBoolean();
TimerBTripped = reader.ReadBoolean();
TimerAResetClock = reader.ReadInt32();
TimerBResetClock = reader.ReadInt32();
TimerALastReset = reader.ReadInt32();
TimerBLastReset = reader.ReadInt32();
TimerControl27 = reader.ReadByte();
egDivisorCounter = reader.ReadInt32();
egCycleCounter = reader.ReadInt32();
PartSelect = reader.ReadByte();
RegisterSelect = reader.ReadByte();
DacEnable = reader.ReadBoolean();
DacValue = reader.ReadByte();
for (int i = 0; i < 6; i++)
ChannelLoadStateBinary(reader, Channels[i]);
}
void ChannelSaveStateBinary(BinaryWriter writer, Channel c)
{
// TODO reduce size of state via casting
writer.Write(c.FrequencyNumber);
writer.Write(c.Block);
writer.Write(c.Feedback);
writer.Write(c.Algorithm);
writer.Write(c.SpecialMode);
writer.Write(c.LeftOutput);
writer.Write(c.RightOutput);
writer.Write(c.AMS_AmplitudeModulationSensitivity);
writer.Write(c.FMS_FrequencyModulationSensitivity);
for (int i = 0; i < 4; i++)
OperatorSaveStateBinary(writer, c.Operators[i]);
}
void ChannelLoadStateBinary(BinaryReader reader, Channel c)
{
c.FrequencyNumber = reader.ReadInt32();
c.Block = reader.ReadInt32();
c.Feedback = reader.ReadInt32();
c.Algorithm = reader.ReadInt32();
c.SpecialMode = reader.ReadBoolean();
c.LeftOutput = reader.ReadBoolean();
c.RightOutput = reader.ReadBoolean();
c.AMS_AmplitudeModulationSensitivity = reader.ReadInt32();
c.FMS_FrequencyModulationSensitivity = reader.ReadInt32();
for (int i = 0; i < 4; i++)
OperatorLoadStateBinary(reader, c.Operators[i]);
}
void OperatorSaveStateBinary(BinaryWriter writer, Operator op)
{
// TODO, size of states could be shrunken by using casts.
writer.Write(op.TL_TotalLevel);
writer.Write(op.SL_SustainLevel);
writer.Write(op.AR_AttackRate);
writer.Write(op.DR_DecayRate);
writer.Write(op.SR_SustainRate);
writer.Write(op.RR_ReleaseRate);
writer.Write(op.KS_KeyScale);
writer.Write(op.SSG_EG);
writer.Write(op.DT_Detune);
writer.Write(op.MUL_Multiple);
writer.Write(op.AM_AmplitudeModulation);
writer.Write(op.FrequencyNumber);
writer.Write(op.Block);
writer.Write(op.KeyCode);
writer.Write(op.Rks);
writer.Write(op.PhaseCounter);
writer.Write((byte)op.EnvelopeState);
writer.Write(op.EgAttenuation);
}
void OperatorLoadStateBinary(BinaryReader reader, Operator op)
{
op.TL_TotalLevel = reader.ReadInt32();
op.SL_SustainLevel = reader.ReadInt32();
op.AR_AttackRate = reader.ReadInt32();
op.DR_DecayRate = reader.ReadInt32();
op.SR_SustainRate = reader.ReadInt32();
op.RR_ReleaseRate = reader.ReadInt32();
op.KS_KeyScale = reader.ReadInt32();
op.SSG_EG = reader.ReadInt32();
op.DT_Detune = reader.ReadInt32();
op.MUL_Multiple = reader.ReadInt32();
op.AM_AmplitudeModulation = reader.ReadBoolean();
op.FrequencyNumber = reader.ReadInt32();
op.Block = reader.ReadInt32();
op.KeyCode = reader.ReadInt32();
op.Rks = reader.ReadInt32();
op.PhaseCounter = reader.ReadInt32();
op.EnvelopeState = (EnvelopeState)Enum.ToObject(typeof(EnvelopeState), reader.ReadByte());
op.EgAttenuation = reader.ReadInt32();
}
} }
} }

View File

@ -305,7 +305,7 @@ namespace BizHawk
bw.Write(buffer[i]); bw.Write(buffer[i]);
} }
public static int[] ReadInts(this BinaryReader br, int num) public static int[] ReadInt32s(this BinaryReader br, int num)
{ {
int[] ret = new int[num]; int[] ret = new int[num];
for (int i = 0; i < num; i++) for (int i = 0; i < num; i++)
@ -313,7 +313,7 @@ namespace BizHawk
return ret; return ret;
} }
public static short[] ReadShorts(this BinaryReader br, int num) public static short[] ReadInt16s(this BinaryReader br, int num)
{ {
short[] ret = new short[num]; short[] ret = new short[num];
for (int i = 0; i < num; i++) for (int i = 0; i < num; i++)
@ -321,6 +321,13 @@ namespace BizHawk
return ret; return ret;
} }
public static ushort[] ReadUInt16s(this BinaryReader br, int num)
{
ushort[] ret = new ushort[num];
for (int i = 0; i < num; i++)
ret[i] = br.ReadUInt16();
return ret;
}
public static void ReadFromHex(this byte[] buffer, string hex) public static void ReadFromHex(this byte[] buffer, string hex)
{ {

View File

@ -94,8 +94,8 @@ CBA55D463FECF2955736AA2EA5D6BD74 Lodoss Tousenki - Record of Lodoss War PCE
EFF6C174835503B034CF6A4079627DBD Road Spirits PCE EFF6C174835503B034CF6A4079627DBD Road Spirits PCE
FBC374F66ED4228120B74D327DE81298 B R-Type Complete CD (imperfect dump) PCE NeedSuperSysCard FBC374F66ED4228120B74D327DE81298 B R-Type Complete CD (imperfect dump) PCE NeedSuperSysCard
D71C2734BD4B048F810C80FE9BD4C6D0 R-Type Complete CD PCE NeedSuperSysCard D71C2734BD4B048F810C80FE9BD4C6D0 R-Type Complete CD PCE NeedSuperSysCard
5D16FE7D452DC9B46CAA7A436F45468D Sapphire PCE NeedSuperSysCard;ArcadeCard 5D16FE7D452DC9B46CAA7A436F45468D Sapphire PCE NeedSuperSysCard;ArcadeCard;EqualizeVolumes
DFAC092A700697944CD741F657D94F17 Sapphire PCE NeedSuperSysCard;ArcadeCard DFAC092A700697944CD741F657D94F17 Sapphire PCE NeedSuperSysCard;ArcadeCard;EqualizeVolumes
D67A425615770ECE13CF5157CA32EF61 Shubibinman III PCE D67A425615770ECE13CF5157CA32EF61 Shubibinman III PCE
E6CB40FD1E315B84D09100915DCABF9C Shadow of the Beast (U) PCE NeedSuperSysCard;EqualizeVolumes E6CB40FD1E315B84D09100915DCABF9C Shadow of the Beast (U) PCE NeedSuperSysCard;EqualizeVolumes
C8559632FE3EA3B4FBABBEF80865B36C Shape Shifter (U) PCE NeedSuperSysCard C8559632FE3EA3B4FBABBEF80865B36C Shape Shifter (U) PCE NeedSuperSysCard