pizza: saverams

This commit is contained in:
nattthebear 2017-06-24 21:46:11 -04:00
parent 876a138e9b
commit 537b2a1616
10 changed files with 124 additions and 120 deletions

View File

@ -1255,6 +1255,7 @@
<Compile Include="CPUs\Z80\Z80A.cs" />
<Compile Include="SideBySideVideo.cs" />
<Compile Include="Sound\DualSyncSound.cs" />
<Compile Include="Waterbox\CustomSaverammer.cs" />
<Compile Include="Waterbox\ElfRunner.cs" />
<Compile Include="FileID.cs" />
<Compile Include="Consoles\PC Engine\MemoryMap.cs" />

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy
{
public abstract class LibPizza : LibWaterboxCore
public abstract class LibPizza : LibWaterboxCore, ICustomSaveram
{
[Flags]
public enum Buttons : uint
@ -32,5 +32,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy
public abstract bool Init(byte[] rom, int romlen, bool sgb, byte[] spc, int spclen);
[BizImport(CC)]
public abstract bool IsCGB();
[BizImport(CC)]
public abstract int GetSaveramSize();
[BizImport(CC)]
public abstract void PutSaveram(byte[] data, int size);
[BizImport(CC)]
public abstract void GetSaveram(byte[] data, int size);
}
}

View File

@ -0,0 +1,38 @@
using BizHawk.Emulation.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BizHawk.Emulation.Cores.Waterbox
{
internal class CustomSaverammer : ISaveRam
{
private readonly ICustomSaveram _s;
private readonly int _size;
public CustomSaverammer(ICustomSaveram s)
{
_s = s;
_size = s.GetSaveramSize();
}
public bool SaveRamModified => _size > 0;
public byte[] CloneSaveRam()
{
var ret = new byte[_size];
_s.GetSaveram(ret, ret.Length);
return ret;
}
public void StoreSaveRam(byte[] data)
{
if (data.Length != _size)
throw new InvalidOperationException("Wrong size saveram");
_s.PutSaveram(data, data.Length);
}
}
}

View File

@ -48,7 +48,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
}
[Flags]
public enum MemoryDomainFlags: int
public enum MemoryDomainFlags : int
{
None = 0,
/// <summary>
@ -166,11 +166,11 @@ namespace BizHawk.Emulation.Cores.Waterbox
Writable = (m.Flags & MemoryDomainFlags.Writable) != 0;
if ((m.Flags & MemoryDomainFlags.WordSize1) != 0)
WordSize = 1;
else if((m.Flags & MemoryDomainFlags.WordSize2) != 0)
else if ((m.Flags & MemoryDomainFlags.WordSize2) != 0)
WordSize = 2;
else if((m.Flags & MemoryDomainFlags.WordSize4) != 0)
else if ((m.Flags & MemoryDomainFlags.WordSize4) != 0)
WordSize = 4;
else if((m.Flags & MemoryDomainFlags.WordSize8) != 0)
else if ((m.Flags & MemoryDomainFlags.WordSize8) != 0)
WordSize = 8;
else
throw new InvalidOperationException("Unknown word size for memory domain");
@ -195,4 +195,14 @@ namespace BizHawk.Emulation.Cores.Waterbox
[BizImport(CC)]
public abstract void SetInputCallback(EmptyCallback callback);
}
/// <summary>
/// if a core implements this, it will be used for saveramming instead of memory domains
/// </summary>
interface ICustomSaveram
{
int GetSaveramSize();
void PutSaveram(byte[] data, int size);
void GetSaveram(byte[] data, int size);
}
}

View File

@ -79,6 +79,11 @@ namespace BizHawk.Emulation.Cores.Waterbox
var mdl = new MemoryDomainList(memoryDomains.Cast<MemoryDomain>().ToList());
mdl.MainMemory = mdl[primaryIndex];
_serviceProvider.Register<IMemoryDomains>(mdl);
var sr = _core as ICustomSaveram;
if (sr != null)
_serviceProvider.Register<ISaveRam>(new CustomSaverammer(sr)); // override the default implementation
_exe.Seal();
}
}

Binary file not shown.

View File

@ -24,6 +24,5 @@
/* prototypes */
char cartridge_load(const void* data, size_t sz);
void cartridge_term();
#endif

View File

@ -303,10 +303,9 @@ uint8_t mmu_read_no_cyc(uint16_t a)
return mmu.memory[a];
}
void mmu_restore_ram(char *fn)
{
/* save only if cartridge got a battery */
if (mmu.carttype == 0x03 ||
static int has_saveram(void)
{
return mmu.carttype == 0x03 ||
mmu.carttype == 0x06 ||
mmu.carttype == 0x09 ||
mmu.carttype == 0x0D ||
@ -317,31 +316,46 @@ void mmu_restore_ram(char *fn)
mmu.carttype == 0x1B ||
mmu.carttype == 0x1E ||
mmu.carttype == 0x22 ||
mmu.carttype == 0xFF)
{
FILE *fp = fopen(fn, "r+");
mmu.carttype == 0xFF;
}
/* it could be not present */
if (fp == NULL)
return;
int mmu_saveram_size(void)
{
return has_saveram() ? ram_sz : 0;
}
if (ram_sz <= 0x2000)
{
/* no need to put togheter pieces of ram banks */
fread(&mmu.memory[0xA000], ram_sz, 1, fp);
}
else
{
/* read entire file into ram buffer */
fread(mmu.ram_internal, 0x2000, 1, fp);
fread(ram, ram_sz, 1, fp);
void mmu_restore_saveram(const uint8_t* data, int sz)
{
if (sz == mmu_saveram_size())
{
if (ram_sz <= 0x2000)
{
memcpy(&mmu.memory[0xa000], data, ram_sz);
}
else
{
memcpy(ram, data, ram_sz);
if (mmu.ram_external_enabled)
memcpy(&mmu.memory[0xa000], &ram[0x2000 * mmu.ram_current_bank], 0x2000);
}
}
}
/* copy internal RAM to 0xA000 address */
memcpy(&mmu.memory[0xA000], mmu.ram_internal, 0x2000);
}
fclose(fp);
}
void mmu_save_saveram(uint8_t* dest, int sz)
{
if (sz == mmu_saveram_size())
{
if (ram_sz <= 0x2000)
{
memcpy(dest, &mmu.memory[0xa000], ram_sz);
}
else
{
memcpy(dest, ram, ram_sz);
if (mmu.ram_external_enabled)
memcpy(&dest[0x2000 * mmu.ram_current_bank], &mmu.memory[0xa000], 0x2000);
}
}
}
void mmu_restore_rtc(char *fn)
@ -367,56 +381,6 @@ void mmu_restore_rtc(char *fn)
}
}
void mmu_save_ram(char *fn)
{
/* save only if cartridge got a battery */
if (mmu.carttype == 0x03 ||
mmu.carttype == 0x06 ||
mmu.carttype == 0x09 ||
mmu.carttype == 0x0d ||
mmu.carttype == 0x0f ||
mmu.carttype == 0x10 ||
mmu.carttype == 0x13 ||
mmu.carttype == 0x17 ||
mmu.carttype == 0x1b ||
mmu.carttype == 0x1e ||
mmu.carttype == 0x22 ||
mmu.carttype == 0xff)
{
FILE *fp = fopen(fn, "w+");
if (fp == NULL)
{
printf("Error dumping RAM\n");
return;
}
if (ram_sz <= 0x2000)
{
/* no need to put togheter pieces of ram banks */
fwrite(&mmu.memory[0xA000], ram_sz, 1, fp);
}
else
{
/* yes, i need to put togheter pieces */
/* save current used bank */
if (mmu.ram_external_enabled)
memcpy(&ram[0x2000 * mmu.ram_current_bank],
&mmu.memory[0xA000], 0x2000);
else
memcpy(mmu.ram_internal,
&mmu.memory[0xA000], 0x2000);
/* dump the entire internal + external RAM */
fwrite(mmu.ram_internal, 0x2000, 1, fp);
fwrite(ram, ram_sz, 1, fp);
}
fclose(fp);
}
}
void mmu_save_rtc(char *fn)
{
/* save only if cartridge got a battery */
@ -440,15 +404,6 @@ void mmu_set_rumble_cb(mmu_rumble_cb_t cb)
mmu_rumble_cb = cb;
}
void mmu_term()
{
if (ram)
{
free(ram);
ram = NULL;
}
}
/* write 16 bit block on a memory address */
void mmu_write(uint16_t a, uint8_t v)
{
@ -699,10 +654,6 @@ void mmu_write(uint16_t a, uint8_t v)
if (mmu.ram_external_enabled)
return;
/* save current bank */
memcpy(mmu.ram_internal,
&mmu.memory[0xA000], 0x2000);
/* restore external ram bank */
memcpy(&mmu.memory[0xA000],
&ram[0x2000 * mmu.ram_current_bank],
@ -724,10 +675,6 @@ void mmu_write(uint16_t a, uint8_t v)
memcpy(&ram[0x2000 * mmu.ram_current_bank],
&mmu.memory[0xA000], 0x2000);
/* restore external ram bank */
memcpy(&mmu.memory[0xA000],
mmu.ram_internal, 0x2000);
/* clear external RAM eanbled flag */
mmu.ram_external_enabled = 0;
}
@ -807,10 +754,6 @@ void mmu_write(uint16_t a, uint8_t v)
if (mmu.ram_external_enabled)
return;
/* save current bank */
memcpy(mmu.ram_internal,
&mmu.memory[0xA000], 0x2000);
/* restore external ram bank */
memcpy(&mmu.memory[0xA000],
&ram[0x2000 * mmu.ram_current_bank],
@ -836,10 +779,6 @@ void mmu_write(uint16_t a, uint8_t v)
memcpy(&ram[0x2000 * mmu.ram_current_bank],
&mmu.memory[0xA000], 0x2000);
/* restore external ram bank */
memcpy(&mmu.memory[0xA000],
mmu.ram_internal, 0x2000);
/* clear external RAM eanbled flag */
mmu.ram_external_enabled = 0;
}
@ -921,9 +860,6 @@ void mmu_write(uint16_t a, uint8_t v)
/* save new current bank */
mmu.rom_current_bank = b;
/* re-apply cheats */
// mmu_apply_gg();
}
return;
@ -1135,8 +1071,3 @@ void mmu_write_no_cyc(uint16_t a, uint8_t v)
{
mmu.memory[a] = v;
}

View File

@ -37,8 +37,7 @@ typedef struct mmu_s {
uint8_t spare;
uint16_t spare2;
/* internal RAM */
uint8_t ram_internal[0x2000];
// cartridge RAM
uint8_t ram_external_enabled;
uint8_t ram_current_bank;
@ -101,13 +100,13 @@ void mmu_move(uint16_t d, uint16_t s);
uint8_t mmu_read_no_cyc(uint16_t a);
uint8_t mmu_read(uint16_t a);
unsigned int mmu_read_16(uint16_t a);
void mmu_restore_ram(char *fn);
int mmu_saveram_size(void);
void mmu_restore_saveram(const uint8_t* data, int sz);
void mmu_save_saveram(uint8_t* dest, int sz);
void mmu_restore_rtc(char *fn);
void mmu_save_ram(char *fn);
void mmu_save_rtc(char *fn);
void mmu_set_rumble_cb(mmu_rumble_cb_t cb);
void mmu_step();
void mmu_term();
void mmu_write_no_cyc(uint16_t a, uint8_t v);
void mmu_write(uint16_t a, uint8_t v);
void mmu_write_16(uint16_t a, uint16_t v);

View File

@ -148,6 +148,21 @@ EXPORT void GetMemoryAreas(MemoryArea *m)
m[0].Flags = MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_WORDSIZE1;
}
EXPORT int GetSaveramSize(void)
{
return mmu_saveram_size();
}
EXPORT void PutSaveram(const uint8_t* data, int size)
{
mmu_restore_saveram(data, size);
}
EXPORT void GetSaveram(uint8_t* data, int size)
{
mmu_save_saveram(data, size);
}
void frame_cb()
{
if (global_sgb)