gba stuff

This commit is contained in:
goyuken 2014-08-13 20:33:59 +00:00
parent 29f34ed79a
commit b8472ea760
10 changed files with 578 additions and 362 deletions

View File

@ -430,7 +430,7 @@ namespace BizHawk.Client.Common
} }
else else
{ {
var gba = new VBANext(rom.RomData, nextComm, game); var gba = new VBANext(rom.RomData, nextComm, game, Deterministic, GetCoreSyncSettings<VBANext>());
nextEmulator = gba; nextEmulator = gba;
} }
break; break;

File diff suppressed because it is too large Load Diff

View File

@ -3381,5 +3381,10 @@ namespace BizHawk.Client.EmuHawk
{ {
_master = null; _master = null;
} }
private void GBAcoresettingsToolStripMenuItem1_Click(object sender, EventArgs e)
{
GenericCoreConfig.DoDialog(this, "Gameboy Advance Settings");
}
} }
} }

View File

@ -28,7 +28,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct FrontEndSettings public class FrontEndSettings
{ {
public enum SaveType : int public enum SaveType : int
{ {
@ -45,18 +45,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
big = 0x20000 big = 0x20000
} }
public SaveType saveType; public SaveType saveType;
public FlashSize flashSize; public FlashSize flashSize = FlashSize.big;
public bool enableRtc; public bool enableRtc;
public bool mirroringEnable; public bool mirroringEnable;
public bool skipBios; public bool skipBios;
public static FrontEndSettings GetDefaults() public bool RTCUseRealTime = true;
{ public int RTCyear; // 00..99
return new FrontEndSettings public int RTCmonth; // 00..11
{ public int RTCmday; // 01..31
flashSize = FlashSize.big public int RTCwday; // 00..06
}; public int RTChour; // 00..23
} public int RTCmin; // 00..59
public int RTCsec; // 00..59
} }
/// <summary> /// <summary>
@ -83,7 +84,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
/// <param name="biosfilelen"></param> /// <param name="biosfilelen"></param>
/// <returns>success</returns> /// <returns>success</returns>
[DllImport(dllname, CallingConvention = cc)] [DllImport(dllname, CallingConvention = cc)]
public static extern bool LoadRom(IntPtr g, byte[] romfile, uint romfilelen, byte[] biosfile, uint biosfilelen, [In]ref FrontEndSettings settings); public static extern bool LoadRom(IntPtr g, byte[] romfile, uint romfilelen, byte[] biosfile, uint biosfilelen, [In]FrontEndSettings settings);
/// <summary> /// <summary>
/// hard reset /// hard reset

View File

@ -107,6 +107,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public byte[] CloneSaveRam() public byte[] CloneSaveRam()
{ {
throw new Exception("This needs to be fixed to match the VBANext Core!");
#if false
if (disposed) if (disposed)
throw new ObjectDisposedException(this.GetType().ToString()); throw new ObjectDisposedException(this.GetType().ToString());
if (!LibMeteor.libmeteor_hassaveram()) if (!LibMeteor.libmeteor_hassaveram())
@ -119,14 +121,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
Marshal.Copy(data, ret, 0, (int)size); Marshal.Copy(data, ret, 0, (int)size);
LibMeteor.libmeteor_savesaveram_destroy(data); LibMeteor.libmeteor_savesaveram_destroy(data);
return ret; return ret;
#endif
} }
public void StoreSaveRam(byte[] data) public void StoreSaveRam(byte[] data)
{ {
throw new Exception("This needs to be fixed to match the VBANext Core!");
#if false
if (disposed) if (disposed)
throw new ObjectDisposedException(this.GetType().ToString()); throw new ObjectDisposedException(this.GetType().ToString());
if (!LibMeteor.libmeteor_loadsaveram(data, (uint)data.Length)) if (!LibMeteor.libmeteor_loadsaveram(data, (uint)data.Length))
throw new Exception("libmeteor_loadsaveram() returned false!"); throw new Exception("libmeteor_loadsaveram() returned false!");
#endif
} }
public void ClearSaveRam() public void ClearSaveRam()

View File

@ -8,6 +8,8 @@ using System.IO;
using BizHawk.Common.BufferExtensions; using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.ComponentModel;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA namespace BizHawk.Emulation.Cores.Nintendo.GBA
{ {
@ -16,7 +18,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
{ {
IntPtr Core; IntPtr Core;
public VBANext(byte[] romfile, CoreComm nextComm, GameInfo gi) public VBANext(byte[] romfile, CoreComm nextComm, GameInfo gi, bool deterministic, object _SS)
{ {
CoreComm = nextComm; CoreComm = nextComm;
byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory."); byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory.");
@ -26,19 +28,36 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
if (biosfile.Length != 16 * 1024) if (biosfile.Length != 16 * 1024)
throw new ArgumentException("BIOS file is not exactly 16K!"); throw new ArgumentException("BIOS file is not exactly 16K!");
LibVBANext.FrontEndSettings FES; LibVBANext.FrontEndSettings FES = new LibVBANext.FrontEndSettings();
FES.saveType = (LibVBANext.FrontEndSettings.SaveType)gi.GetInt("saveType", 0); FES.saveType = (LibVBANext.FrontEndSettings.SaveType)gi.GetInt("saveType", 0);
FES.flashSize = (LibVBANext.FrontEndSettings.FlashSize)gi.GetInt("flashSize", 0x10000); FES.flashSize = (LibVBANext.FrontEndSettings.FlashSize)gi.GetInt("flashSize", 0x10000);
FES.enableRtc = gi.GetInt("enableRtc", 0) != 0; FES.enableRtc = gi.GetInt("enableRtc", 0) != 0;
FES.mirroringEnable = gi.GetInt("mirroringEnable", 0) != 0; FES.mirroringEnable = gi.GetInt("mirroringEnable", 0) != 0;
FES.skipBios = false; // todo: hook me up as a syncsetting
_SyncSettings = (SyncSettings)_SS ?? new SyncSettings();
DeterministicEmulation = deterministic;
FES.skipBios = _SyncSettings.SkipBios;
FES.RTCUseRealTime = _SyncSettings.RTCUseRealTime;
FES.RTCwday = (int)_SyncSettings.RTCInitialDay;
FES.RTCyear = _SyncSettings.RTCInitialTime.Year % 100;
FES.RTCmonth = _SyncSettings.RTCInitialTime.Month - 1;
FES.RTCmday = _SyncSettings.RTCInitialTime.Day;
FES.RTChour = _SyncSettings.RTCInitialTime.Hour;
FES.RTCmin = _SyncSettings.RTCInitialTime.Minute;
FES.RTCsec = _SyncSettings.RTCInitialTime.Second;
if (DeterministicEmulation)
{
FES.skipBios = false;
FES.RTCUseRealTime = false;
}
Core = LibVBANext.Create(); Core = LibVBANext.Create();
if (Core == IntPtr.Zero) if (Core == IntPtr.Zero)
throw new InvalidOperationException("Create() returned nullptr!"); throw new InvalidOperationException("Create() returned nullptr!");
try try
{ {
if (!LibVBANext.LoadRom(Core, romfile, (uint)romfile.Length, biosfile, (uint)biosfile.Length, ref FES)) if (!LibVBANext.LoadRom(Core, romfile, (uint)romfile.Length, biosfile, (uint)biosfile.Length, FES))
throw new InvalidOperationException("LoadRom() returned false!"); throw new InvalidOperationException("LoadRom() returned false!");
CoreComm.VsyncNum = 262144; CoreComm.VsyncNum = 262144;
@ -78,7 +97,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public string SystemId { get { return "GBA"; } } public string SystemId { get { return "GBA"; } }
public bool DeterministicEmulation { get { return true; } } public bool DeterministicEmulation { get; private set; }
public void ResetCounters() public void ResetCounters()
{ {
@ -108,25 +127,33 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public byte[] CloneSaveRam() public byte[] CloneSaveRam()
{ {
return new byte[16]; byte[] data = new byte[LibVBANext.SaveRamSize(Core)];
if (!LibVBANext.SaveRamSave(Core, data, data.Length))
throw new InvalidOperationException("SaveRamSave() failed!");
return data;
} }
public void StoreSaveRam(byte[] data) public void StoreSaveRam(byte[] data)
{ {
// internally, we try to salvage bad-sized saverams
if (!LibVBANext.SaveRamLoad(Core, data, data.Length))
throw new InvalidOperationException("SaveRamLoad() failed!");
} }
public void ClearSaveRam() public void ClearSaveRam()
{ {
throw new NotImplementedException();
} }
public bool SaveRamModified public bool SaveRamModified
{ {
get get
{ {
return false; return LibVBANext.SaveRamSize(Core) != 0;
} }
set set
{ {
throw new InvalidOperationException();
} }
} }
@ -249,9 +276,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public object GetSyncSettings() public object GetSyncSettings()
{ {
return null; return _SyncSettings.Clone();
} }
SyncSettings _SyncSettings;
public bool PutSettings(object o) public bool PutSettings(object o)
{ {
return false; return false;
@ -259,7 +289,58 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public bool PutSyncSettings(object o) public bool PutSyncSettings(object o)
{ {
return false; var s = (SyncSettings)o;
bool ret = SyncSettings.NeedsReboot(s, _SyncSettings);
_SyncSettings = s;
return ret;
}
public class SyncSettings
{
[DisplayName("Skip BIOS")]
[Description("Skips the BIOS intro. A BIOS file is still required. Forced to false for movie recording.")]
[DefaultValue(false)]
public bool SkipBios { get; set; }
[DisplayName("RTC Use Real Time")]
[Description("Causes the internal clock to reflect your system clock. Only relevant when a game has an RTC chip. Forced to false for movie recording.")]
[DefaultValue(true)]
public bool RTCUseRealTime { get; set; }
[DisplayName("RTC Initial Time")]
[Description("The initial time of emulation. Only relevant when a game has an RTC chip and \"RTC Use Real Time\" is false.")]
[DefaultValue(typeof(DateTime), "2010-01-01")]
public DateTime RTCInitialTime { get; set; }
public enum DayOfWeek
{
Sunday = 0,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
}
[DisplayName("RTC Initial Day")]
[Description("The day of the week to go with \"RTC Initial Time\". Due to peculiarities in the RTC chip, this can be set indepedently of the year, month, and day of month.")]
[DefaultValue(DayOfWeek.Friday)]
public DayOfWeek RTCInitialDay { get; set; }
public SyncSettings()
{
SettingsUtil.SetDefaultValues(this);
}
public static bool NeedsReboot(SyncSettings x, SyncSettings y)
{
return !DeepEquality.DeepEquals(x, y);
}
public SyncSettings Clone()
{
return (SyncSettings)MemberwiseClone();
}
} }
#endregion #endregion

Binary file not shown.

View File

@ -3,6 +3,8 @@
static float const apu_vols [4] = { -0.25f, -0.5f, -1.0f, -0.25f }; static float const apu_vols [4] = { -0.25f, -0.5f, -1.0f, -0.25f };
static const int daysinmonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const int table [0x40] = static const int table [0x40] =
{ {
0xFF10, 0,0xFF11,0xFF12,0xFF13,0xFF14, 0, 0, 0xFF10, 0,0xFF11,0xFF12,0xFF13,0xFF14, 0, 0,

View File

@ -424,7 +424,7 @@ bool rtcWrite(u32 address, u16 value)
rtcClockData.byte1 = (u8)value; // read/write rtcClockData.byte1 = (u8)value; // read/write
else if(address == 0x80000c4) else if(address == 0x80000c4)
{ {
if(rtcClockData.byte2 & 1) if(rtcClockData.byte2 & 1) // enable
{ {
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5)
{ {
@ -549,20 +549,104 @@ void rtcReset (void)
rtcClockData.state = IDLE; rtcClockData.state = IDLE;
} }
// guarantees predictable results regardless of stdlib
// could be modified later to better match internal quirks of
// the RTC chip actually used
struct
{
int year; // 00..99
int month; // 00..11
int mday; // 01..31
int wday; // 00..06
int hour; // 00..23
int min; // 00..59
int sec; // 00..59
template<bool isReader>void SyncState(NewState *ns)
{
NSS(year);
NSS(month);
NSS(mday);
NSS(wday);
NSS(hour);
NSS(min);
NSS(sec);
}
private:
int DaysInMonth()
{
// gba rtc doesn't understand 100/400 exceptions
int result = daysinmonth[month];
if (month == 1 && year % 4 == 0)
result++;
return result;
}
public:
void Increment()
{
sec++;
if (sec >= 60)
{
sec = 0;
min++;
if (min >= 60)
{
min = 0;
hour++;
if (hour >= 24)
{
hour = 0;
wday++;
if (wday >= 7)
wday = 0;
mday++;
if (mday >= DaysInMonth())
{
mday = 1;
month++;
if (month >= 12)
{
month = 0;
year++;
if (year >= 100)
year = 0;
}
}
}
}
}
}
} rtcInternalTime;
void GetTime(tm &times) void GetTime(tm &times)
{ {
time_t t = RTCUseRealTime ? time(nullptr) : RTCTime; if (RTCUseRealTime)
#if defined _MSC_VER {
gmtime_s(&times, &t); time_t t = time(nullptr);
#elif defined __MINGW32__ #if defined _MSC_VER
tm *tmp = gmtime(&t); gmtime_s(&times, &t);
times = *tmp; #elif defined __MINGW32__
#elif defined __GNUC__ tm *tmp = gmtime(&t);
gmtime_r(&t, &times); times = *tmp;
#endif #elif defined __GNUC__
gmtime_r(&t, &times);
#endif
}
else
{
times.tm_hour = rtcInternalTime.hour;
times.tm_mday = rtcInternalTime.mday;
times.tm_min = rtcInternalTime.min;
times.tm_mon = rtcInternalTime.month;
times.tm_sec = rtcInternalTime.sec;
times.tm_wday = rtcInternalTime.wday;
times.tm_year = rtcInternalTime.year;
}
} }
uint64_t RTCTime;
int RTCTicks; int RTCTicks;
bool RTCUseRealTime; bool RTCUseRealTime;
@ -572,7 +656,7 @@ void AdvanceRTC(int ticks)
while (RTCTicks >= 16777216) while (RTCTicks >= 16777216)
{ {
RTCTicks -= 16777216; RTCTicks -= 16777216;
RTCTime++; rtcInternalTime.Increment();
} }
} }
@ -12903,7 +12987,7 @@ template<bool isReader>void SyncState(NewState *ns)
NSS(rtcClockData); NSS(rtcClockData);
NSS(rtcEnabled); NSS(rtcEnabled);
NSS(RTCTime); SSS(rtcInternalTime);
NSS(RTCTicks); NSS(RTCTicks);
NSS(RTCUseRealTime); NSS(RTCUseRealTime);
@ -13173,6 +13257,15 @@ template<bool isReader>bool SyncBatteryRam(NewState *ns)
mirroringEnable = settings.mirroringEnable; mirroringEnable = settings.mirroringEnable;
skipBios = settings.skipBios; skipBios = settings.skipBios;
RTCUseRealTime = settings.RTCuseRealTime;
rtcInternalTime.hour = settings.RTChour;
rtcInternalTime.mday = settings.RTCmday;
rtcInternalTime.min = settings.RTCmin;
rtcInternalTime.month = settings.RTCmonth;
rtcInternalTime.sec = settings.RTCsec;
rtcInternalTime.wday = settings.RTCwday;
rtcInternalTime.year = settings.RTCyear;
if(flashSize == 0x10000) if(flashSize == 0x10000)
{ {
flashDeviceID = 0x1b; flashDeviceID = 0x1b;

View File

@ -8,6 +8,16 @@ struct FrontEndSettings
int enableRtc; // [false] true int enableRtc; // [false] true
int mirroringEnable; // [false] true int mirroringEnable; // [false] true
int skipBios; // [false] true int skipBios; // [false] true
int RTCuseRealTime;
int RTCyear; // 00..99
int RTCmonth; // 00..11
int RTCmday; // 01..31
int RTCwday; // 00..06
int RTChour; // 00..23
int RTCmin; // 00..59
int RTCsec; // 00..59
}; };
#define FLASH_128K_SZ 0x20000 #define FLASH_128K_SZ 0x20000