return more informative load result

This commit is contained in:
MrWint 2019-05-25 18:58:49 +02:00
parent a3ee854022
commit 98076d286d
9 changed files with 95 additions and 80 deletions

View File

@ -20,6 +20,7 @@
#define GAMBATTE_H
#include "gbint.h"
#include "loadres.h"
#include <string>
#include <sstream>
#include <cstdint>
@ -48,7 +49,7 @@ class GB {
public:
GB();
~GB();
enum LoadFlag {
FORCE_DMG = 1, /**< Treat the ROM as not having CGB support regardless of what its header advertises. */
GBA_CGB = 2, /**< Use GBA intial CPU register values when in CGB mode. */
@ -61,7 +62,7 @@ public:
* @param flags ORed combination of LoadFlags.
* @return 0 on success, negative value on failure.
*/
int load(const char *romfiledata, unsigned romfilelength, std::uint32_t now, unsigned flags, unsigned div);
LoadRes load(const char *romfiledata, unsigned romfilelength, std::uint32_t now, unsigned flags, unsigned div);
int loadGBCBios(const char* biosfiledata);
int loadDMGBios(const char* biosfiledata);

View File

@ -0,0 +1,23 @@
#ifndef GAMBATTE_LOADRES_H
#define GAMBATTE_LOADRES_H
#include <string>
namespace gambatte {
enum LoadRes {
LOADRES_BAD_FILE_OR_UNKNOWN_MBC = -0x7FFF,
LOADRES_IO_ERROR,
LOADRES_UNSUPPORTED_MBC_HUC3 = -0x1FE,
LOADRES_UNSUPPORTED_MBC_TAMA5,
LOADRES_UNSUPPORTED_MBC_POCKET_CAMERA,
LOADRES_UNSUPPORTED_MBC_MBC7 = -0x122,
LOADRES_UNSUPPORTED_MBC_MBC6 = -0x120,
LOADRES_UNSUPPORTED_MBC_MBC4 = -0x117,
LOADRES_UNSUPPORTED_MBC_MMM01 = -0x10D,
LOADRES_OK = 0
};
}
#endif

View File

@ -104,7 +104,7 @@ public:
memory.setLinkCallback(callback);
}
int load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
LoadRes load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
return memory.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat);
}

View File

@ -140,13 +140,13 @@ void GB::setLinkCallback(void(*callback)()) {
p_->cpu.setLinkCallback(callback);
}
int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_t now, const unsigned flags, const unsigned div) {
LoadRes GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_t now, unsigned const flags, const unsigned div) {
//if (p_->cpu.loaded())
// p_->cpu.saveSavedata();
const int failed = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT);
LoadRes const loadres = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT);
if (!failed) {
if (loadres == LOADRES_OK) {
SaveState state;
p_->cpu.setStatePtrs(state);
p_->loadflags = flags;
@ -155,7 +155,7 @@ int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_
//p_->cpu.loadSavedata();
}
return failed;
return loadres;
}
int GB::loadGBCBios(const char* biosfiledata) {
@ -223,7 +223,7 @@ const std::string GB::romTitle() const {
if (p_->cpu.loaded()) {
char title[0x11];
std::memcpy(title, p_->cpu.romTitle(), 0x10);
title[(title[0xF] & 0x80) ? 0xF : 0x10] = '\0';
title[title[0xF] & 0x80 ? 0xF : 0x10] = '\0';
return std::string(title);
}

View File

@ -525,7 +525,23 @@ static unsigned pow2ceil(unsigned n) {
return n;
}
int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
static bool isMbc2(unsigned char h147) { return h147 == 5 || h147 == 6; }
static unsigned numRambanksFromH14x(unsigned char h147, unsigned char h149) {
switch (h149) {
case 0x00: return isMbc2(h147) ? 1 : 0;
case 0x01:
case 0x02: return 1;
}
return 4;
}
static bool presumedMulti64Mbc1(unsigned char const header[], unsigned const rombanks) {
return header[0x147] == 1 && header[0x149] == 0 && rombanks == 64;
}
LoadRes Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, bool const forceDmg, bool const multicartCompat) {
//const std::auto_ptr<File> rom(newFileInstance(romfile));
//if (rom->fail())
@ -542,39 +558,39 @@ int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bo
if (romfilelength >= sizeof header)
std::memcpy(header, romfiledata, sizeof header);
else
return -1;
return LOADRES_IO_ERROR;
switch (header[0x0147]) {
case 0x00: std::puts("Plain ROM loaded."); type = PLAIN; break;
case 0x01: std::puts("MBC1 ROM loaded."); type = MBC1; break;
case 0x02: std::puts("MBC1 ROM+RAM loaded."); type = MBC1; break;
case 0x03: std::puts("MBC1 ROM+RAM+BATTERY loaded."); type = MBC1; break;
case 0x05: std::puts("MBC2 ROM loaded."); type = MBC2; break;
case 0x06: std::puts("MBC2 ROM+BATTERY loaded."); type = MBC2; break;
case 0x08: std::puts("Plain ROM with additional RAM loaded."); type = PLAIN; break;
case 0x09: std::puts("Plain ROM with additional RAM and Battery loaded."); type = PLAIN; break;
case 0x0B: std::puts("MM01 ROM not supported."); return -1;
case 0x0C: std::puts("MM01 ROM not supported."); return -1;
case 0x0D: std::puts("MM01 ROM not supported."); return -1;
case 0x0F: std::puts("MBC3 ROM+TIMER+BATTERY loaded."); type = MBC3; break;
case 0x10: std::puts("MBC3 ROM+TIMER+RAM+BATTERY loaded."); type = MBC3; break;
case 0x11: std::puts("MBC3 ROM loaded."); type = MBC3; break;
case 0x12: std::puts("MBC3 ROM+RAM loaded."); type = MBC3; break;
case 0x13: std::puts("MBC3 ROM+RAM+BATTERY loaded."); type = MBC3; break;
case 0x15: std::puts("MBC4 ROM not supported."); return -1;
case 0x16: std::puts("MBC4 ROM not supported."); return -1;
case 0x17: std::puts("MBC4 ROM not supported."); return -1;
case 0x19: std::puts("MBC5 ROM loaded."); type = MBC5; break;
case 0x1A: std::puts("MBC5 ROM+RAM loaded."); type = MBC5; break;
case 0x1B: std::puts("MBC5 ROM+RAM+BATTERY loaded."); type = MBC5; break;
case 0x1C: std::puts("MBC5+RUMBLE ROM not supported."); type = MBC5; break;
case 0x1D: std::puts("MBC5+RUMBLE+RAM ROM not suported."); type = MBC5; break;
case 0x1E: std::puts("MBC5+RUMBLE+RAM+BATTERY ROM not supported."); type = MBC5; break;
case 0xFC: std::puts("Pocket Camera ROM not supported."); return -1;
case 0xFD: std::puts("Bandai TAMA5 ROM not supported."); return -1;
case 0xFE: std::puts("HuC3 ROM not supported."); return -1;
case 0xFF: std::puts("HuC1 ROM+RAM+BATTERY loaded."); type = HUC1; break;
default: std::puts("Wrong data-format, corrupt or unsupported ROM."); return -1;
case 0x00: type = PLAIN; break;
case 0x01:
case 0x02:
case 0x03: type = MBC1; break;
case 0x05:
case 0x06: type = MBC2; break;
case 0x08:
case 0x09: type = PLAIN; break;
case 0x0B:
case 0x0C:
case 0x0D: return LOADRES_UNSUPPORTED_MBC_MMM01;
case 0x0F:
case 0x10:
case 0x11:
case 0x12:
case 0x13: type = MBC3; break;
case 0x15:
case 0x16:
case 0x17: return LOADRES_UNSUPPORTED_MBC_MBC4;
case 0x19:
case 0x1A:
case 0x1B:
case 0x1C:
case 0x1D:
case 0x1E: type = MBC5; break;
case 0xFC: return LOADRES_UNSUPPORTED_MBC_POCKET_CAMERA;
case 0xFD: return LOADRES_UNSUPPORTED_MBC_TAMA5;
case 0xFE: return LOADRES_UNSUPPORTED_MBC_HUC3;
case 0xFF: type = HUC1; break;
default: return LOADRES_BAD_FILE_OR_UNKNOWN_MBC;
}
/*switch (header[0x0148]) {
@ -591,40 +607,15 @@ int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bo
case 0x53: rombanks = 80; break;
case 0x54: rombanks = 96; break;
default: return -1;
}
}*/
std::printf("rombanks: %u\n", rombanks);*/
switch (header[0x0149]) {
case 0x00: /*std::puts("No RAM");*/ rambanks = type == MBC2; break;
case 0x01: /*std::puts("2kB RAM");*/ /*rambankrom=1; break;*/
case 0x02: /*std::puts("8kB RAM");*/
rambanks = 1;
break;
case 0x03: /*std::puts("32kB RAM");*/
rambanks = 4;
break;
case 0x04: /*std::puts("128kB RAM");*/
rambanks = 16;
break;
case 0x05: /*std::puts("undocumented kB RAM");*/
rambanks = 16;
break;
default: /*std::puts("Wrong data-format, corrupt or unsupported ROM loaded.");*/
rambanks = 16;
break;
}
cgb = !forceDmg;
std::printf("cgb: %d\n", cgb);
}
std::printf("rambanks: %u\n", rambanks);
const std::size_t filesize = romfilelength; //rom->size();
rombanks = std::max(pow2ceil(filesize / 0x4000), 2u);
std::printf("rombanks: %u\n", static_cast<unsigned>(filesize / 0x4000));
rambanks = numRambanksFromH14x(header[0x147], header[0x149]);
cgb = !forceDmg;
}
std::size_t const filesize = romfilelength; //rom->size();
rombanks = std::max(pow2ceil(filesize / 0x4000), 2u);
mbc.reset();
memptrs.reset(rombanks, rambanks, cgb ? 8 : 2);
rtc.set(false, 0);
@ -641,8 +632,7 @@ int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bo
switch (type) {
case PLAIN: mbc.reset(new Mbc0(memptrs)); break;
case MBC1:
if (!rambanks && rombanks == 64 && multicartCompat) {
std::puts("Multi-ROM \"MBC1\" presumed");
if (multicartCompat && presumedMulti64Mbc1(memptrs.romdata(), rombanks)) {
mbc.reset(new Mbc1Multi64(memptrs));
} else
mbc.reset(new Mbc1(memptrs));
@ -654,7 +644,7 @@ int Cartridge::loadROM(const char *romfiledata, unsigned romfilelength, const bo
case HUC1: mbc.reset(new HuC1(memptrs)); break;
}
return 0;
return LOADRES_OK;
}
static bool hasBattery(const unsigned char headerByte0x147) {

View File

@ -19,6 +19,7 @@
#ifndef CARTRIDGE_H
#define CARTRIDGE_H
#include "loadres.h"
#include "memptrs.h"
#include "rtc.h"
#include "savestate.h"
@ -98,7 +99,7 @@ public:
bool getMemoryArea(int which, unsigned char **data, int *length) const;
int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
LoadRes loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
const char * romTitle() const { return reinterpret_cast<const char *>(memptrs.romdata() + 0x134); }
void setRTCCallback(std::uint32_t (*callback)()) {

View File

@ -1056,14 +1056,14 @@ void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsig
ioamhram[P - 0xFE00] = data;
}
int Memory::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
if (const int fail = cart.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
LoadRes Memory::loadROM(const char *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
if (LoadRes const fail = cart.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
return fail;
sound.init(cart.isCgb());
display.reset(ioamhram, cart.vramdata(), cart.isCgb());
return 0;
return LOADRES_OK;
}
unsigned Memory::fillSoundBuffer(const unsigned long cycleCounter) {

View File

@ -296,7 +296,7 @@ public:
unsigned long event(unsigned long cycleCounter);
unsigned long resetCounters(unsigned long cycleCounter);
int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
LoadRes loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
void setInputGetter(unsigned (*getInput)()) {
this->getInput = getInput;

Binary file not shown.