vba next: some gamedb and saveram hookups, not all finished
This commit is contained in:
parent
b29f9e5be1
commit
9e234b3bf5
|
@ -424,13 +424,13 @@ namespace BizHawk.Client.Common
|
|||
case "GBA":
|
||||
if (false)
|
||||
{
|
||||
var gba = new GBA(nextComm);
|
||||
var gba = new GBA(nextComm); // meteor
|
||||
gba.Load(rom.RomData);
|
||||
nextEmulator = gba;
|
||||
}
|
||||
else
|
||||
{
|
||||
var gba = new VBANext(rom.RomData, nextComm);
|
||||
var gba = new VBANext(rom.RomData, nextComm, game);
|
||||
nextEmulator = gba;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -27,6 +27,38 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
L = 512
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct FrontEndSettings
|
||||
{
|
||||
public enum SaveType : int
|
||||
{
|
||||
auto = 0,
|
||||
eeprom = 1,
|
||||
sram = 2,
|
||||
flash = 3,
|
||||
eeprom_sensor = 4,
|
||||
none = 5
|
||||
}
|
||||
public enum FlashSize : int
|
||||
{
|
||||
small = 0x10000,
|
||||
big = 0x20000
|
||||
}
|
||||
public SaveType saveType;
|
||||
public FlashSize flashSize;
|
||||
public bool enableRtc;
|
||||
public bool mirroringEnable;
|
||||
public bool skipBios;
|
||||
|
||||
public static FrontEndSettings GetDefaults()
|
||||
{
|
||||
return new FrontEndSettings
|
||||
{
|
||||
flashSize = FlashSize.big
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// create a new context
|
||||
/// </summary>
|
||||
|
@ -51,7 +83,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);
|
||||
public static extern bool LoadRom(IntPtr g, byte[] romfile, uint romfilelen, byte[] biosfile, uint biosfilelen, [In]ref FrontEndSettings settings);
|
||||
|
||||
/// <summary>
|
||||
/// hard reset
|
||||
|
@ -82,5 +114,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
public static extern void TxtStateSave(IntPtr g, [In]ref TextStateFPtrs ff);
|
||||
[DllImport(dllname, CallingConvention = cc)]
|
||||
public static extern void TxtStateLoad(IntPtr g, [In]ref TextStateFPtrs ff);
|
||||
|
||||
[DllImport(dllname, CallingConvention = cc)]
|
||||
public static extern int SaveRamSize(IntPtr g);
|
||||
[DllImport(dllname, CallingConvention = cc)]
|
||||
public static extern bool SaveRamSave(IntPtr g, byte[] data, int length);
|
||||
[DllImport(dllname, CallingConvention = cc)]
|
||||
public static extern bool SaveRamLoad(IntPtr g, byte[] data, int length);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
{
|
||||
IntPtr Core;
|
||||
|
||||
public VBANext(byte[] romfile, CoreComm nextComm)
|
||||
public VBANext(byte[] romfile, CoreComm nextComm, GameInfo gi)
|
||||
{
|
||||
CoreComm = nextComm;
|
||||
byte[] biosfile = CoreComm.CoreFileProvider.GetFirmware("GBA", "Bios", true, "GBA bios file is mandatory.");
|
||||
|
@ -26,12 +26,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
if (biosfile.Length != 16 * 1024)
|
||||
throw new ArgumentException("BIOS file is not exactly 16K!");
|
||||
|
||||
LibVBANext.FrontEndSettings FES;
|
||||
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
|
||||
|
||||
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))
|
||||
if (!LibVBANext.LoadRom(Core, romfile, (uint)romfile.Length, biosfile, (uint)biosfile.Length, ref FES))
|
||||
throw new InvalidOperationException("LoadRom() returned false!");
|
||||
|
||||
CoreComm.VsyncNum = 262144;
|
||||
|
@ -52,9 +59,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void FrameAdvance(bool render, bool rendersound = true)
|
||||
{
|
||||
Frame++;
|
||||
|
|
Binary file not shown.
|
@ -2,6 +2,7 @@
|
|||
#include <time.h>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
@ -48,12 +49,7 @@ class Gigazoid
|
|||
#define FLASH_PROGRAM 8
|
||||
#define FLASH_SETBANK 9
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
extern uint8_t libretro_save_buf[0x20000 + 0x2000];
|
||||
uint8_t *flashSaveMemory = libretro_save_buf;
|
||||
#else
|
||||
uint8_t flashSaveMemory[FLASH_128K_SZ];
|
||||
#endif
|
||||
|
||||
int flashState; // = FLASH_READ_ARRAY;
|
||||
int flashReadState; // = FLASH_READ_ARRAY;
|
||||
|
@ -64,11 +60,7 @@ int flashBank; // = 0;
|
|||
|
||||
void flashInit (void)
|
||||
{
|
||||
#ifdef __LIBRETRO__
|
||||
memset(flashSaveMemory, 0xff, 0x20000);
|
||||
#else
|
||||
memset(flashSaveMemory, 0xff, sizeof(flashSaveMemory));
|
||||
#endif
|
||||
}
|
||||
|
||||
void flashReset()
|
||||
|
@ -78,22 +70,6 @@ void flashReset()
|
|||
flashBank = 0;
|
||||
}
|
||||
|
||||
void flashSetSize(int size)
|
||||
{
|
||||
if(size == 0x10000) {
|
||||
flashDeviceID = 0x1b;
|
||||
flashManufacturerID = 0x32;
|
||||
} else {
|
||||
flashDeviceID = 0x13; //0x09;
|
||||
flashManufacturerID = 0x62; //0xc2;
|
||||
}
|
||||
// Added to make 64k saves compatible with 128k ones
|
||||
// (allow wrongfuly set 64k saves to work for Pokemon games)
|
||||
if ((size == 0x20000) && (flashSize == 0x10000))
|
||||
memcpy((uint8_t *)(flashSaveMemory+0x10000), (uint8_t *)(flashSaveMemory), 0x10000);
|
||||
flashSize = size;
|
||||
}
|
||||
|
||||
uint8_t flashRead(uint32_t address)
|
||||
{
|
||||
address &= 0xFFFF;
|
||||
|
@ -122,24 +98,14 @@ uint8_t flashRead(uint32_t address)
|
|||
|
||||
void flashSaveDecide(uint32_t address, uint8_t byte)
|
||||
{
|
||||
if(address == 0x0e005555) {
|
||||
saveType = 2;
|
||||
if (address == 0x0e005555)
|
||||
cpuSaveGameFunc = &Gigazoid::flashWrite;
|
||||
} else {
|
||||
saveType = 1;
|
||||
else
|
||||
cpuSaveGameFunc = &Gigazoid::sramWrite;
|
||||
}
|
||||
|
||||
(this->*cpuSaveGameFunc)(address, byte);
|
||||
}
|
||||
|
||||
void flashDelayedWrite(uint32_t address, uint8_t byte)
|
||||
{
|
||||
saveType = 2;
|
||||
cpuSaveGameFunc = &Gigazoid::flashWrite;
|
||||
flashWrite(address, byte);
|
||||
}
|
||||
|
||||
void flashWrite(uint32_t address, uint8_t byte)
|
||||
{
|
||||
address &= 0xFFFF;
|
||||
|
@ -243,13 +209,7 @@ int eepromByte; // = 0;
|
|||
int eepromBits; // = 0;
|
||||
int eepromAddress; // = 0;
|
||||
|
||||
#ifdef __LIBRETRO__
|
||||
// Workaround for broken-by-design GBA save semantics.
|
||||
extern u8 libretro_save_buf[0x20000 + 0x2000];
|
||||
u8 *eepromData = libretro_save_buf + 0x20000;
|
||||
#else
|
||||
u8 eepromData[0x2000];
|
||||
#endif
|
||||
|
||||
u8 eepromBuffer[16];
|
||||
bool eepromInUse; // = false;
|
||||
|
@ -257,11 +217,7 @@ int eepromSize; // = 512;
|
|||
|
||||
void eepromInit (void)
|
||||
{
|
||||
#ifdef __LIBRETRO__
|
||||
memset(eepromData, 255, 0x2000);
|
||||
#else
|
||||
memset(eepromData, 255, sizeof(eepromData));
|
||||
#endif
|
||||
}
|
||||
|
||||
void eepromReset (void)
|
||||
|
@ -401,18 +357,15 @@ u8 sramRead(u32 address)
|
|||
return flashSaveMemory[address & 0xFFFF];
|
||||
}
|
||||
|
||||
void sramDelayedWrite(u32 address, u8 byte)
|
||||
{
|
||||
saveType = 1;
|
||||
cpuSaveGameFunc = &Gigazoid::sramWrite;
|
||||
sramWrite(address, byte);
|
||||
}
|
||||
|
||||
void sramWrite(u32 address, u8 byte)
|
||||
{
|
||||
flashSaveMemory[address & 0xFFFF] = byte;
|
||||
}
|
||||
|
||||
void dummyWrite(u32 address, u8 byte)
|
||||
{
|
||||
}
|
||||
|
||||
/*============================================================
|
||||
RTC
|
||||
============================================================ */
|
||||
|
@ -437,32 +390,19 @@ typedef struct
|
|||
RTCCLOCKDATA rtcClockData;
|
||||
bool rtcEnabled; // = false;
|
||||
|
||||
void rtcEnable(bool e)
|
||||
{
|
||||
rtcEnabled = e;
|
||||
}
|
||||
|
||||
bool rtcIsEnabled (void)
|
||||
{
|
||||
return rtcEnabled;
|
||||
}
|
||||
|
||||
u16 rtcRead(u32 address)
|
||||
{
|
||||
if(rtcEnabled)
|
||||
switch(address)
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
case 0x80000c8:
|
||||
return rtcClockData.byte2;
|
||||
case 0x80000c6:
|
||||
return rtcClockData.byte1;
|
||||
case 0x80000c4:
|
||||
return rtcClockData.byte0;
|
||||
}
|
||||
case 0x80000c8:
|
||||
return rtcClockData.byte2;
|
||||
case 0x80000c6:
|
||||
return rtcClockData.byte1;
|
||||
case 0x80000c4:
|
||||
return rtcClockData.byte0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return READ16LE((&rom[address & 0x1FFFFFE]));
|
||||
}
|
||||
|
||||
static u8 toBCD(u8 value)
|
||||
|
@ -2764,7 +2704,6 @@ int gfxBG3X;
|
|||
int gfxBG3Y;
|
||||
|
||||
bool ioReadable[0x400];
|
||||
int gbaSaveType; // used to remember the save type on reset
|
||||
|
||||
//int gfxLastVCOUNT = 0;
|
||||
|
||||
|
@ -3054,7 +2993,7 @@ INLINE u32 CPUReadHalfWord(u32 address)
|
|||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
if(address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8)
|
||||
if(rtcEnabled && (address == 0x80000c4 || address == 0x80000c6 || address == 0x80000c8))
|
||||
value = rtcRead(address);
|
||||
else
|
||||
value = READ16LE(((u16 *)&rom[address & 0x1FFFFFE]));
|
||||
|
@ -3194,14 +3133,11 @@ INLINE void CPUWriteMemory(u32 address, u32 value)
|
|||
WRITE32LE(((u32 *)&oam[address & 0x3fc]), value);
|
||||
break;
|
||||
case 0x0D:
|
||||
if(cpuEEPROMEnabled) {
|
||||
if (cpuEEPROMEnabled)
|
||||
eepromWrite(value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x0E:
|
||||
if((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled)
|
||||
(this->*cpuSaveGameFunc)(address, (u8)value);
|
||||
(this->*cpuSaveGameFunc)(address, (u8)value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -3247,8 +3183,7 @@ INLINE void CPUWriteHalfWord(u32 address, u16 value)
|
|||
eepromWrite((u8)value);
|
||||
break;
|
||||
case 14:
|
||||
if((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled)
|
||||
(this->*cpuSaveGameFunc)(address, (u8)value);
|
||||
(this->*cpuSaveGameFunc)(address, (u8)value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -3362,11 +3297,8 @@ INLINE void CPUWriteByte(u32 address, u8 b)
|
|||
eepromWrite(b);
|
||||
break;
|
||||
case 14:
|
||||
if ((saveType != 5) && ((!eepromInUse) | cpuSramEnabled | cpuFlashEnabled))
|
||||
{
|
||||
(this->*cpuSaveGameFunc)(address, b);
|
||||
break;
|
||||
}
|
||||
(this->*cpuSaveGameFunc)(address, b);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -8860,14 +8792,14 @@ INLINE u32 gfxDecreaseBrightness(u32 color, int coeff)
|
|||
/*============================================================
|
||||
GBA.CPP
|
||||
============================================================ */
|
||||
int saveType;
|
||||
static const bool useBios = true;
|
||||
bool skipBios;
|
||||
bool cpuIsMultiBoot;
|
||||
int cpuSaveType;
|
||||
// it's a few bytes in the linkscript to make a multiboot image work in normal boot as well,
|
||||
// and most of the ones i've seen have done that, so this is not terribly useful
|
||||
static const bool cpuIsMultiBoot = false;
|
||||
int cpuSaveType; // used only in init() to set up function pointers
|
||||
bool enableRtc;
|
||||
bool mirroringEnable;
|
||||
bool skipSaveGameBattery;
|
||||
|
||||
int cpuDmaCount;
|
||||
|
||||
|
@ -8880,10 +8812,8 @@ u16 pix[2 * PIX_BUFFER_SCREEN_WIDTH * 160];
|
|||
uint8_t oam[0x400];
|
||||
uint8_t ioMem[0x400];
|
||||
|
||||
bool cpuSramEnabled; // = true;
|
||||
bool cpuFlashEnabled; // = true;
|
||||
bool cpuEEPROMEnabled; // = true;
|
||||
bool cpuEEPROMSensorEnabled; // = false;
|
||||
bool cpuEEPROMEnabled; // true to process writes to EEPROM at 0dxxxxxx
|
||||
bool cpuEEPROMSensorEnabled; // eeprom motion sensor? code is mostly disabled
|
||||
|
||||
#ifndef LSB_FIRST
|
||||
bool cpuBiosSwapped = false;
|
||||
|
@ -8955,97 +8885,6 @@ INLINE int CPUUpdateTicks (void)
|
|||
graphics.layerEnable = io_registers[REG_DISPCNT]; \
|
||||
}
|
||||
|
||||
// TODO: Batteryram stuffs
|
||||
/*
|
||||
bool CPUWriteBatteryFile(const char *fileName)
|
||||
{
|
||||
if(gbaSaveType == 0)
|
||||
{
|
||||
if(eepromInUse)
|
||||
gbaSaveType = 3;
|
||||
else
|
||||
switch(saveType)
|
||||
{
|
||||
case 1:
|
||||
gbaSaveType = 1;
|
||||
break;
|
||||
case 2:
|
||||
gbaSaveType = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((gbaSaveType) && (gbaSaveType!=5))
|
||||
{
|
||||
FILE *file = fopen(fileName, "wb");
|
||||
|
||||
if(!file) {
|
||||
systemMessage("Error creating file %s", fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
// only save if Flash/Sram in use or EEprom in use
|
||||
if(gbaSaveType != 3) {
|
||||
if(gbaSaveType == 2) {
|
||||
if(fwrite(flashSaveMemory, 1, flashSize, file) != (size_t)flashSize) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(fwrite(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(fwrite(eepromData, 1, eepromSize, file) != (size_t)eepromSize) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPUReadBatteryFile(const char *fileName)
|
||||
{
|
||||
FILE *file = fopen(fileName, "rb");
|
||||
|
||||
if(!file)
|
||||
return false;
|
||||
|
||||
// check file size to know what we should read
|
||||
fseek(file, 0, SEEK_END);
|
||||
|
||||
long size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
if(size == 512 || size == 0x2000) {
|
||||
if(fread(eepromData, 1, size, file) != (size_t)size) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(size == 0x20000) {
|
||||
if(fread(flashSaveMemory, 1, 0x20000, file) != 0x20000) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
flashSetSize(0x20000);
|
||||
} else {
|
||||
if(fread(flashSaveMemory, 1, 0x10000, file) != 0x10000) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
flashSetSize(0x10000);
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
int CPULoadRom(const u8 *romfile, const u32 romfilelen)
|
||||
{
|
||||
if (cpuIsMultiBoot)
|
||||
|
@ -12155,17 +11994,41 @@ void CPUUpdateRegister(uint32_t address, uint16_t value)
|
|||
|
||||
void CPUInit(const u8 *biosfile, const u32 biosfilelen)
|
||||
{
|
||||
#ifndef LSB_FIRST
|
||||
if(!cpuBiosSwapped) {
|
||||
for(unsigned int i = 0; i < sizeof(myROM)/4; i++) {
|
||||
WRITE32LE(&myROM[i], myROM[i]);
|
||||
}
|
||||
cpuBiosSwapped = true;
|
||||
eepromInUse = false;
|
||||
switch(cpuSaveType)
|
||||
{
|
||||
case 0: // automatic
|
||||
default:
|
||||
cpuEEPROMEnabled = true;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
cpuSaveGameFunc = &Gigazoid::flashSaveDecide; // EEPROM usage is automatically detected
|
||||
break;
|
||||
case 1: // EEPROM
|
||||
cpuEEPROMEnabled = true;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
cpuSaveGameFunc = &Gigazoid::dummyWrite; // EEPROM usage is automatically detected
|
||||
break;
|
||||
case 2: // SRAM
|
||||
cpuEEPROMEnabled = false;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
cpuSaveGameFunc = &Gigazoid::sramWrite;
|
||||
break;
|
||||
case 3: // FLASH
|
||||
cpuEEPROMEnabled = false;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
cpuSaveGameFunc = &Gigazoid::flashWrite;
|
||||
break;
|
||||
case 4: // EEPROM+Sensor
|
||||
cpuEEPROMEnabled = true;
|
||||
cpuEEPROMSensorEnabled = true;
|
||||
cpuSaveGameFunc = &Gigazoid::dummyWrite; // EEPROM usage is automatically detected
|
||||
break;
|
||||
case 5: // NONE
|
||||
cpuEEPROMEnabled = false;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
cpuSaveGameFunc = &Gigazoid::dummyWrite;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
gbaSaveType = 0;
|
||||
eepromInUse = 0;
|
||||
saveType = 0;
|
||||
|
||||
memcpy(bios, biosfile, 16384);
|
||||
|
||||
|
@ -12225,6 +12088,7 @@ void CPUInit(const u8 *biosfile, const u32 biosfilelen)
|
|||
for(i = 0x304; i < 0x400; i++)
|
||||
ioReadable[i] = false;
|
||||
|
||||
// what is this?
|
||||
if(romSize < 0x1fe2000) {
|
||||
*((uint16_t *)&rom[0x1fe209c]) = 0xdffa; // SWI 0xFA
|
||||
*((uint16_t *)&rom[0x1fe209e]) = 0x4770; // BX LR
|
||||
|
@ -12259,29 +12123,14 @@ void CPUInit(const u8 *biosfile, const u32 biosfilelen)
|
|||
address_lut[0x32] = &io_registers[REG_BG3PB];
|
||||
address_lut[0x34] = &io_registers[REG_BG3PC];
|
||||
address_lut[0x36] = &io_registers[REG_BG3PD];
|
||||
address_lut[0x40] = &io_registers[REG_WIN0H];
|
||||
address_lut[0x42] = &io_registers[REG_WIN1H];
|
||||
address_lut[0x44] = &io_registers[REG_WIN0V];
|
||||
address_lut[0x46] = &io_registers[REG_WIN1V];
|
||||
address_lut[0x40] = &io_registers[REG_WIN0H];
|
||||
address_lut[0x42] = &io_registers[REG_WIN1H];
|
||||
address_lut[0x44] = &io_registers[REG_WIN0V];
|
||||
address_lut[0x46] = &io_registers[REG_WIN1V];
|
||||
}
|
||||
|
||||
void CPUReset (void)
|
||||
{
|
||||
if(gbaSaveType == 0)
|
||||
{
|
||||
if(eepromInUse)
|
||||
gbaSaveType = 3;
|
||||
else
|
||||
switch(saveType)
|
||||
{
|
||||
case 1:
|
||||
gbaSaveType = 1;
|
||||
break;
|
||||
case 2:
|
||||
gbaSaveType = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rtcReset();
|
||||
memset(&bus.reg[0], 0, sizeof(bus.reg)); // clean registers
|
||||
memset(oam, 0, 0x400); // clean OAM
|
||||
|
@ -12450,11 +12299,9 @@ void CPUReset (void)
|
|||
dma2Dest = 0;
|
||||
dma3Source = 0;
|
||||
dma3Dest = 0;
|
||||
cpuSaveGameFunc = &Gigazoid::flashSaveDecide;
|
||||
renderLine = &Gigazoid::mode0RenderLine;
|
||||
fxOn = false;
|
||||
windowOn = false;
|
||||
saveType = 0;
|
||||
graphics.layerEnable = io_registers[REG_DISPCNT];
|
||||
|
||||
memset(line[0], -1, 240 * sizeof(u32));
|
||||
|
@ -12505,57 +12352,9 @@ void CPUReset (void)
|
|||
BIOS_RegisterRamReset(0xfe);
|
||||
else if(!useBios && !cpuIsMultiBoot)
|
||||
BIOS_RegisterRamReset(0xff);
|
||||
else if (skipBios)
|
||||
BIOS_RegisterRamReset(0xff); // ??
|
||||
|
||||
switch(cpuSaveType) {
|
||||
case 0: // automatic
|
||||
cpuSramEnabled = true;
|
||||
cpuFlashEnabled = true;
|
||||
cpuEEPROMEnabled = true;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
saveType = gbaSaveType = 0;
|
||||
break;
|
||||
case 1: // EEPROM
|
||||
cpuSramEnabled = false;
|
||||
cpuFlashEnabled = false;
|
||||
cpuEEPROMEnabled = true;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
saveType = gbaSaveType = 3;
|
||||
// EEPROM usage is automatically detected
|
||||
break;
|
||||
case 2: // SRAM
|
||||
cpuSramEnabled = true;
|
||||
cpuFlashEnabled = false;
|
||||
cpuEEPROMEnabled = false;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
cpuSaveGameFunc = &Gigazoid::sramDelayedWrite; // to insure we detect the write
|
||||
saveType = gbaSaveType = 1;
|
||||
break;
|
||||
case 3: // FLASH
|
||||
cpuSramEnabled = false;
|
||||
cpuFlashEnabled = true;
|
||||
cpuEEPROMEnabled = false;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
cpuSaveGameFunc = &Gigazoid::flashDelayedWrite; // to insure we detect the write
|
||||
saveType = gbaSaveType = 2;
|
||||
break;
|
||||
case 4: // EEPROM+Sensor
|
||||
cpuSramEnabled = false;
|
||||
cpuFlashEnabled = false;
|
||||
cpuEEPROMEnabled = true;
|
||||
cpuEEPROMSensorEnabled = true;
|
||||
// EEPROM usage is automatically detected
|
||||
saveType = gbaSaveType = 3;
|
||||
break;
|
||||
case 5: // NONE
|
||||
cpuSramEnabled = false;
|
||||
cpuFlashEnabled = false;
|
||||
cpuEEPROMEnabled = false;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
// no save at all
|
||||
saveType = gbaSaveType = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
ARM_PREFETCH;
|
||||
}
|
||||
|
||||
|
@ -13030,8 +12829,6 @@ void Gigazoid_Init()
|
|||
eepromInUse = false;
|
||||
eepromSize = 512;
|
||||
|
||||
rtcEnabled = false;
|
||||
|
||||
// this is constant now
|
||||
// soundSampleRate = 22050;
|
||||
|
||||
|
@ -13041,14 +12838,6 @@ void Gigazoid_Init()
|
|||
armIrqEnable = true;
|
||||
armMode = 0x1f;
|
||||
|
||||
romSize = 0x2000000;
|
||||
|
||||
cpuSramEnabled = true;
|
||||
cpuFlashEnabled = true;
|
||||
cpuEEPROMEnabled = true;
|
||||
cpuEEPROMSensorEnabled = false;
|
||||
|
||||
cpuSaveGameFunc = &Gigazoid::flashSaveDecide;
|
||||
renderLine = &Gigazoid::mode0RenderLine;
|
||||
|
||||
#define ARRAYINIT(n) memcpy((n), (n##_init), sizeof(n))
|
||||
|
@ -13205,8 +12994,7 @@ template<bool isReader>void SyncState(NewState *ns)
|
|||
EVS(cpuSaveGameFunc, &Gigazoid::flashWrite, 1);
|
||||
EVS(cpuSaveGameFunc, &Gigazoid::sramWrite, 2);
|
||||
EVS(cpuSaveGameFunc, &Gigazoid::flashSaveDecide, 3);
|
||||
EVS(cpuSaveGameFunc, &Gigazoid::flashDelayedWrite, 4);
|
||||
EVS(cpuSaveGameFunc, &Gigazoid::sramDelayedWrite, 5);
|
||||
EVS(cpuSaveGameFunc, &Gigazoid::dummyWrite, 4);
|
||||
EES(cpuSaveGameFunc, nullptr);
|
||||
|
||||
NSS(fxOn);
|
||||
|
@ -13237,7 +13025,6 @@ template<bool isReader>void SyncState(NewState *ns)
|
|||
NSS(gfxBG3Y);
|
||||
|
||||
NSS(ioReadable);
|
||||
NSS(gbaSaveType);
|
||||
|
||||
NSS(stopState);
|
||||
|
||||
|
@ -13261,13 +13048,10 @@ template<bool isReader>void SyncState(NewState *ns)
|
|||
NSS(timer3Reload);
|
||||
NSS(timer3ClockReload);
|
||||
|
||||
NSS(saveType);
|
||||
NSS(skipBios);
|
||||
NSS(cpuIsMultiBoot);
|
||||
NSS(cpuSaveType);
|
||||
NSS(enableRtc);
|
||||
NSS(mirroringEnable);
|
||||
NSS(skipSaveGameBattery);
|
||||
|
||||
NSS(cpuDmaCount);
|
||||
|
||||
|
@ -13278,8 +13062,6 @@ template<bool isReader>void SyncState(NewState *ns)
|
|||
NSS(oam);
|
||||
NSS(ioMem);
|
||||
|
||||
NSS(cpuSramEnabled);
|
||||
NSS(cpuFlashEnabled);
|
||||
NSS(cpuEEPROMEnabled);
|
||||
NSS(cpuEEPROMSensorEnabled);
|
||||
|
||||
|
@ -13311,6 +13093,63 @@ template<bool isReader>void SyncState(NewState *ns)
|
|||
NSS(lagged);
|
||||
}
|
||||
|
||||
// load a legacy battery ram file to a place where it might work, who knows
|
||||
void LoadLegacyBatteryRam(const u8 *data, int len)
|
||||
{
|
||||
std::memcpy(eepromData, data, std::min<int>(len, sizeof(eepromData)));
|
||||
std::memcpy(flashSaveMemory, data, std::min<int>(len, sizeof(flashSaveMemory)));
|
||||
if (len <= 0x10000)
|
||||
{
|
||||
// can salvage broken pokeymans saves in some cases
|
||||
std::memcpy(flashSaveMemory + 0x10000, data, std::min<int>(len, 0x10000));
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isReader>bool SyncBatteryRam(NewState *ns)
|
||||
{
|
||||
// if we were given a positive ID from the gamedb, we can choose to save/load only that type
|
||||
// else, we save\load everything -- even if we used our knowledge of the current state to
|
||||
// save only what was needed, we'd have to save that metadata as well for load
|
||||
|
||||
// since we may get other people's crap, try to detect that here
|
||||
char batteryramid[16];
|
||||
if (!isReader)
|
||||
{
|
||||
std::memcpy(batteryramid, "BIZVBANEXTBATTRY", 16);
|
||||
}
|
||||
NSS(batteryramid);
|
||||
if (isReader)
|
||||
{
|
||||
if (std::memcmp(batteryramid, "BIZVBANEXTBATTRY", 16) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (cpuSaveType)
|
||||
{
|
||||
default:
|
||||
case 0: // auto
|
||||
NSS(flashSaveMemory);
|
||||
NSS(eepromData);
|
||||
break;
|
||||
case 1:
|
||||
case 4: // eeprom
|
||||
PSS(eepromData, eepromSize);
|
||||
break;
|
||||
case 2: // sram
|
||||
// should only be 32K, but vba uses 64K as a stand-in for both SRAM (guess no game ever checks mirroring?),
|
||||
// and for 64K flash where the program never issues any flash commands
|
||||
PSS(flashSaveMemory, 0x10000);
|
||||
break;
|
||||
case 3: // flash
|
||||
PSS(flashSaveMemory, flashSize);
|
||||
break;
|
||||
case 5: // none
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Gigazoid()
|
||||
{
|
||||
Gigazoid_Init();
|
||||
|
@ -13320,25 +13159,31 @@ template<bool isReader>void SyncState(NewState *ns)
|
|||
{
|
||||
}
|
||||
|
||||
bool LoadRom(const u8 *romfile, const u32 romfilelen, const u8 *biosfile, const u32 biosfilelen)
|
||||
bool LoadRom(const u8 *romfile, const u32 romfilelen, const u8 *biosfile, const u32 biosfilelen, const FrontEndSettings &settings)
|
||||
{
|
||||
if (biosfilelen != 16384)
|
||||
return false;
|
||||
|
||||
// todo: set cpuismultiboot
|
||||
if (!CPULoadRom(romfile, romfilelen))
|
||||
return false;
|
||||
|
||||
// todo: populate these 4 variables from a syncsetting or a gamedb (vba_over.ini)
|
||||
cpuSaveType = 0;
|
||||
flashSize = 0x10000;
|
||||
enableRtc = false;
|
||||
mirroringEnable = false;
|
||||
cpuSaveType = settings.cpuSaveType;
|
||||
flashSize = settings.flashSize;
|
||||
enableRtc = settings.enableRtc;
|
||||
mirroringEnable = settings.mirroringEnable;
|
||||
skipBios = settings.skipBios;
|
||||
|
||||
if(flashSize == 0x10000)
|
||||
{
|
||||
flashDeviceID = 0x1b;
|
||||
flashManufacturerID = 0x32;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashDeviceID = 0x13; //0x09;
|
||||
flashManufacturerID = 0x62; //0xc2;
|
||||
}
|
||||
|
||||
if(flashSize == 0x10000 || flashSize == 0x20000)
|
||||
flashSetSize(flashSize);
|
||||
if(enableRtc)
|
||||
rtcEnable(enableRtc);
|
||||
doMirroring(mirroringEnable);
|
||||
|
||||
CPUInit(biosfile, biosfilelen);
|
||||
|
@ -13396,9 +13241,9 @@ EXPORT void Destroy(Gigazoid *g)
|
|||
delete g;
|
||||
}
|
||||
|
||||
EXPORT int LoadRom(Gigazoid *g, const u8 *romfile, const u32 romfilelen, const u8 *biosfile, const u32 biosfilelen)
|
||||
EXPORT int LoadRom(Gigazoid *g, const u8 *romfile, const u32 romfilelen, const u8 *biosfile, const u32 biosfilelen, const FrontEndSettings *settings)
|
||||
{
|
||||
return g->LoadRom(romfile, romfilelen, biosfile, biosfilelen);
|
||||
return g->LoadRom(romfile, romfilelen, biosfile, biosfilelen, *settings);
|
||||
}
|
||||
|
||||
EXPORT void Reset(Gigazoid *g)
|
||||
|
@ -13412,6 +13257,35 @@ EXPORT int FrameAdvance(Gigazoid *g, int input, u32 *videobuffer, s16 *audiobuff
|
|||
return g->FrameAdvance(input, videobuffer, audiobuffer, numsamp);
|
||||
}
|
||||
|
||||
EXPORT int SaveRamSize(Gigazoid *g)
|
||||
{
|
||||
NewStateDummy dummy;
|
||||
g->SyncBatteryRam<false>(&dummy);
|
||||
return dummy.GetLength();
|
||||
}
|
||||
|
||||
EXPORT int SaveRamSave(Gigazoid *g, char *data, int length)
|
||||
{
|
||||
NewStateExternalBuffer saver(data, length);
|
||||
g->SyncBatteryRam<false>(&saver);
|
||||
return !saver.Overflow() && saver.GetLength() == length;
|
||||
}
|
||||
|
||||
EXPORT int SaveRamLoad(Gigazoid *g, const char *data, int length)
|
||||
{
|
||||
NewStateExternalBuffer loader(const_cast<char *>(data), length);
|
||||
if (g->SyncBatteryRam<true>(&loader))
|
||||
{
|
||||
return !loader.Overflow() && loader.GetLength() == length;
|
||||
}
|
||||
else
|
||||
{
|
||||
// couldn't find the magic signature at the top, so try a salvage load
|
||||
g->LoadLegacyBatteryRam(reinterpret_cast<const u8*>(data), length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT int BinStateSize(Gigazoid *g)
|
||||
{
|
||||
NewStateDummy dummy;
|
||||
|
|
|
@ -1,6 +1,15 @@
|
|||
#ifndef INSTANCE_H
|
||||
#define INSTANCE_H
|
||||
|
||||
struct FrontEndSettings
|
||||
{
|
||||
int cpuSaveType; // [0auto] 1eeprom 2sram 3flash 4eeprom+sensor 5none
|
||||
int flashSize; // [0x10000] 0x20000
|
||||
int enableRtc; // [false] true
|
||||
int mirroringEnable; // [false] true
|
||||
int skipBios; // [false] true
|
||||
};
|
||||
|
||||
#define FLASH_128K_SZ 0x20000
|
||||
|
||||
#define EEPROM_IDLE 0
|
||||
|
|
Loading…
Reference in New Issue