pizza: saverams
This commit is contained in:
parent
876a138e9b
commit
537b2a1616
|
@ -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" />
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
@ -24,6 +24,5 @@
|
|||
|
||||
/* prototypes */
|
||||
char cartridge_load(const void* data, size_t sz);
|
||||
void cartridge_term();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue