Gambatte core: unify DMG and CGB bios handling

This commit is contained in:
MrWint 2019-05-26 20:11:50 +02:00
parent d8c238c9fb
commit 7e851b19f3
9 changed files with 35 additions and 60 deletions

View File

@ -95,28 +95,21 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_load)}() returned non-zero (is this not a gb or gbc rom?)");
}
byte[] Bios;
if ((flags & LibGambatte.LoadFlags.FORCE_DMG) == LibGambatte.LoadFlags.FORCE_DMG)
{
byte[] Bios = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
Bios = comm.CoreFileProvider.GetFirmware("GB", "World", true, "BIOS Not Found, Cannot Load");
IsCgb = false;
if (LibGambatte.gambatte_loaddmgbios(GambatteState, Bios) != 0)
{
throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loaddmgbios)}() returned non-zero (bios error)");
}
}
else
{
byte[] Bios = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
Bios = comm.CoreFileProvider.GetFirmware("GBC", "World", true, "BIOS Not Found, Cannot Load");
IsCgb = true;
if (LibGambatte.gambatte_loadgbcbios(GambatteState, Bios) != 0)
{
throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadgbcbios)}() returned non-zero (bios error)");
}
}
if (LibGambatte.gambatte_loadbios(GambatteState, Bios, (uint)Bios.Length) != 0)
{
throw new InvalidOperationException($"{nameof(LibGambatte.gambatte_loadbios)}() returned non-zero (bios error)");
}
// set real default colors (before anyone mucks with them at all)
PutSettings((GambatteSettings)settings ?? new GambatteSettings());

View File

@ -60,22 +60,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public static extern int gambatte_load(IntPtr core, byte[] romdata, uint length, long now, LoadFlags flags, uint div);
/// <summary>
/// Load GB BIOS image.
/// Load GB(C) BIOS image.
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="biosdata">the bios data, can be disposed of once this function returns</param>
/// <param name="length">length of romdata in bytes</param>
/// <returns>0 on success, negative value on failure.</returns>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_loaddmgbios(IntPtr core, byte[] biosdata);
/// <summary>
/// Load GBC BIOS image.
/// </summary>
/// <param name="core">opaque state pointer</param>
/// <param name="biosdata">the bios data, can be disposed of once this function returns</param>
/// <returns>0 on success, negative value on failure.</returns>
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int gambatte_loadgbcbios(IntPtr core, byte[] biosdata);
public static extern int gambatte_loadbios(IntPtr core, byte[] biosdata, uint length);
/// <summary>
/// Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,

View File

@ -66,8 +66,7 @@ public:
*/
LoadRes load(char const *romfiledata, unsigned romfilelength, std::uint32_t now, unsigned flags, unsigned div);
int loadGBCBios(char const* biosfiledata);
int loadDMGBios(char const* biosfiledata);
int loadBios(char const* biosfiledata, std::size_t size);
/**
* Emulates until at least 'samples' audio samples are produced in the

View File

@ -35,15 +35,9 @@ GBEXPORT int gambatte_load(GB *g, char const *romfiledata, unsigned romfilelengt
return ret;
}
GBEXPORT int gambatte_loadgbcbios(GB* g, char const* biosfiledata)
GBEXPORT int gambatte_loadbios(GB* g, char const* biosfiledata, unsigned size)
{
int ret = g->loadGBCBios(biosfiledata);
return ret;
}
GBEXPORT int gambatte_loaddmgbios(GB* g, char const* biosfiledata)
{
int ret = g->loadDMGBios(biosfiledata);
int ret = g->loadBios(biosfiledata, size);
return ret;
}

View File

@ -95,8 +95,7 @@ public:
mem_.setCgbPalette(lut);
}
unsigned char* cgbBiosBuffer() { return mem_.cgbBiosBuffer(); }
unsigned char* dmgBiosBuffer() { return mem_.dmgBiosBuffer(); }
void setBios(char const *buffer, std::size_t size) { mem_.setBios(buffer, size); }
bool gbIsCgb() { return mem_.gbIsCgb(); }
unsigned char externalRead(unsigned short addr) {return mem_.peek(addr); }

View File

@ -148,13 +148,8 @@ LoadRes GB::load(char const *romfiledata, unsigned romfilelength, const std::uin
return loadres;
}
int GB::loadGBCBios(char const* biosfiledata) {
memcpy(p_->cpu.cgbBiosBuffer(), biosfiledata, 0x900);
return 0;
}
int GB::loadDMGBios(char const* biosfiledata) {
memcpy(p_->cpu.dmgBiosBuffer(), biosfiledata, 0x100);
int GB::loadBios(char const* biosfiledata, std::size_t size) {
p_->cpu.setBios(biosfiledata, size);
return 0;
}

View File

@ -30,6 +30,7 @@ Memory::Memory(unsigned short &sp, unsigned short &pc)
, execCallback_(0)
, cdCallback_(0)
, linkCallback_(0)
, bios_(0)
, getInput_(0)
, divLastUpdate_(0)
, lastOamDmaUpdate_(disabled_time)
@ -47,6 +48,9 @@ Memory::Memory(unsigned short &sp, unsigned short &pc)
intreq_.setEventTime<intevent_blit>(144 * 456ul);
intreq_.setEventTime<intevent_end>(0);
}
Memory::~Memory() {
delete []bios_;
}
void Memory::setStatePtrs(SaveState &state) {
state.mem.ioamhram.set(ioamhram_, sizeof ioamhram_);

View File

@ -34,6 +34,7 @@ class FilterInfo;
class Memory {
public:
explicit Memory(unsigned short &sp, unsigned short &pc);
~Memory();
bool loaded() const { return cart_.loaded(); }
unsigned char curRomBank() const { return cart_.curRomBank(); }
@ -46,8 +47,12 @@ public:
void saveSavedata(char *dest) { cart_.saveSavedata(dest); }
void updateInput();
unsigned char* cgbBiosBuffer() { return (unsigned char*)cgbBios_; }
unsigned char* dmgBiosBuffer() { return (unsigned char*)dmgBios_; }
void setBios(char const *buffer, std::size_t size) {
delete []bios_;
bios_ = new unsigned char[size];
memcpy(bios_, buffer, size);
biosSize_ = size;
}
bool gbIsCgb() { return gbIsCgb_; }
bool getMemoryArea(int which, unsigned char **data, int *length); // { return cart.getMemoryArea(which, data, length); }
@ -72,13 +77,10 @@ public:
void di() { intreq_.di(); }
unsigned readBios(unsigned p) {
if (gbIsCgb_) {
if (agbMode_ && p >= 0xF3 && p < 0x100) {
return (agbOverride[p - 0xF3] + cgbBios_[p]) & 0xFF;
}
return cgbBios_[p];
if(agbMode_ && p >= 0xF3 && p < 0x100) {
return (agbOverride[p-0xF3] + bios_[p]) & 0xFF;
}
return dmgBios_[p];
return bios_[p];
}
unsigned ff_read(unsigned p, unsigned long cc) {
@ -146,9 +148,8 @@ public:
unsigned read(unsigned p, unsigned long cc) {
if (readCallback_)
readCallback_(p, (cc - basetime_) >> 1);
bool biosRange = ((!gbIsCgb_ && p < 0x100) || (gbIsCgb_ && p < 0x900 && (p < 0x100 || p >= 0x200)));
if(biosMode_) {
if (biosRange)
if (p < biosSize_ && !(p >= 0x100 && p < 0x200))
return readBios(p);
}
else if(cdCallback_) {
@ -162,9 +163,8 @@ public:
unsigned read_excb(unsigned p, unsigned long cc, bool first) {
if (execCallback_)
execCallback_(p, (cc - basetime_) >> 1);
bool biosRange = ((!gbIsCgb_ && p < 0x100) || (gbIsCgb_ && p < 0x900 && (p < 0x100 || p >= 0x200)));
if (biosMode_) {
if(biosRange)
if(p < biosSize_ && !(p >= 0x100 && p < 0x200))
return readBios(p);
}
else if(cdCallback_) {
@ -176,8 +176,7 @@ public:
}
unsigned peek(unsigned p) {
bool biosRange = ((!gbIsCgb_ && p < 0x100) || (gbIsCgb_ && p < 0x900 && (p < 0x100 || p >= 0x200)));
if (biosMode_ && biosRange) {
if (biosMode_ && p < biosSize_ && !(p >= 0x100 && p < 0x200)) {
return readBios(p);
}
return cart_.rmem(p >> 12) ? cart_.rmem(p >> 12)[p] : nontrivial_peek(p);
@ -273,8 +272,8 @@ public:
private:
Cartridge cart_;
unsigned char ioamhram_[0x200];
unsigned char cgbBios_[0x900];
unsigned char dmgBios_[0x100];
unsigned char *bios_;
std::size_t biosSize_;
unsigned (*getInput_)();
unsigned long divLastUpdate_;
unsigned long lastOamDmaUpdate_;

Binary file not shown.