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
{
var gba = new VBANext(rom.RomData, nextComm, game);
var gba = new VBANext(rom.RomData, nextComm, game, Deterministic, GetCoreSyncSettings<VBANext>());
nextEmulator = gba;
}
break;

File diff suppressed because it is too large Load Diff

View File

@ -3381,5 +3381,10 @@ namespace BizHawk.Client.EmuHawk
{
_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)]
public struct FrontEndSettings
public class FrontEndSettings
{
public enum SaveType : int
{
@ -45,18 +45,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
big = 0x20000
}
public SaveType saveType;
public FlashSize flashSize;
public FlashSize flashSize = FlashSize.big;
public bool enableRtc;
public bool mirroringEnable;
public bool skipBios;
public static FrontEndSettings GetDefaults()
{
return new FrontEndSettings
{
flashSize = FlashSize.big
};
}
public bool RTCUseRealTime = true;
public int RTCyear; // 00..99
public int RTCmonth; // 00..11
public int RTCmday; // 01..31
public int RTCwday; // 00..06
public int RTChour; // 00..23
public int RTCmin; // 00..59
public int RTCsec; // 00..59
}
/// <summary>
@ -83,7 +84,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
/// <param name="biosfilelen"></param>
/// <returns>success</returns>
[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>
/// hard reset

View File

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

View File

@ -8,6 +8,8 @@ using System.IO;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using Newtonsoft.Json;
using System.ComponentModel;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
@ -16,7 +18,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
{
IntPtr Core;
public VBANext(byte[] romfile, CoreComm nextComm, GameInfo gi)
public VBANext(byte[] romfile, CoreComm nextComm, GameInfo gi, bool deterministic, object _SS)
{
CoreComm = nextComm;
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)
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.flashSize = (LibVBANext.FrontEndSettings.FlashSize)gi.GetInt("flashSize", 0x10000);
FES.enableRtc = gi.GetInt("enableRtc", 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();
if (Core == IntPtr.Zero)
throw new InvalidOperationException("Create() returned nullptr!");
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!");
CoreComm.VsyncNum = 262144;
@ -78,7 +97,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public string SystemId { get { return "GBA"; } }
public bool DeterministicEmulation { get { return true; } }
public bool DeterministicEmulation { get; private set; }
public void ResetCounters()
{
@ -108,25 +127,33 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
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)
{
// internally, we try to salvage bad-sized saverams
if (!LibVBANext.SaveRamLoad(Core, data, data.Length))
throw new InvalidOperationException("SaveRamLoad() failed!");
}
public void ClearSaveRam()
{
throw new NotImplementedException();
}
public bool SaveRamModified
{
get
{
return false;
return LibVBANext.SaveRamSize(Core) != 0;
}
set
{
throw new InvalidOperationException();
}
}
@ -249,9 +276,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public object GetSyncSettings()
{
return null;
return _SyncSettings.Clone();
}
SyncSettings _SyncSettings;
public bool PutSettings(object o)
{
return false;
@ -259,7 +289,58 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
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

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 const int daysinmonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const int table [0x40] =
{
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
else if(address == 0x80000c4)
{
if(rtcClockData.byte2 & 1)
if(rtcClockData.byte2 & 1) // enable
{
if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5)
{
@ -549,20 +549,104 @@ void rtcReset (void)
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)
{
time_t t = RTCUseRealTime ? time(nullptr) : RTCTime;
#if defined _MSC_VER
gmtime_s(&times, &t);
#elif defined __MINGW32__
tm *tmp = gmtime(&t);
times = *tmp;
#elif defined __GNUC__
gmtime_r(&t, &times);
#endif
if (RTCUseRealTime)
{
time_t t = time(nullptr);
#if defined _MSC_VER
gmtime_s(&times, &t);
#elif defined __MINGW32__
tm *tmp = gmtime(&t);
times = *tmp;
#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;
bool RTCUseRealTime;
@ -572,7 +656,7 @@ void AdvanceRTC(int ticks)
while (RTCTicks >= 16777216)
{
RTCTicks -= 16777216;
RTCTime++;
rtcInternalTime.Increment();
}
}
@ -12903,7 +12987,7 @@ template<bool isReader>void SyncState(NewState *ns)
NSS(rtcClockData);
NSS(rtcEnabled);
NSS(RTCTime);
SSS(rtcInternalTime);
NSS(RTCTicks);
NSS(RTCUseRealTime);
@ -13173,6 +13257,15 @@ template<bool isReader>bool SyncBatteryRam(NewState *ns)
mirroringEnable = settings.mirroringEnable;
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)
{
flashDeviceID = 0x1b;

View File

@ -8,6 +8,16 @@ struct FrontEndSettings
int enableRtc; // [false] true
int mirroringEnable; // [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