From 98076d286d9d6fee08726d6ecbad02ef21a1b821 Mon Sep 17 00:00:00 2001 From: MrWint Date: Sat, 25 May 2019 18:58:49 +0200 Subject: [PATCH] return more informative load result --- libgambatte/include/gambatte.h | 5 +- libgambatte/include/loadres.h | 23 ++++++ libgambatte/src/cpu.h | 2 +- libgambatte/src/gambatte.cpp | 10 +-- libgambatte/src/mem/cartridge.cpp | 124 ++++++++++++++---------------- libgambatte/src/mem/cartridge.h | 3 +- libgambatte/src/memory.cpp | 6 +- libgambatte/src/memory.h | 2 +- output/dll/libgambatte.dll | Bin 143872 -> 142336 bytes 9 files changed, 95 insertions(+), 80 deletions(-) create mode 100644 libgambatte/include/loadres.h diff --git a/libgambatte/include/gambatte.h b/libgambatte/include/gambatte.h index 94bab7befb..a3553bc139 100644 --- a/libgambatte/include/gambatte.h +++ b/libgambatte/include/gambatte.h @@ -20,6 +20,7 @@ #define GAMBATTE_H #include "gbint.h" +#include "loadres.h" #include #include #include @@ -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); diff --git a/libgambatte/include/loadres.h b/libgambatte/include/loadres.h new file mode 100644 index 0000000000..6ee5e370b5 --- /dev/null +++ b/libgambatte/include/loadres.h @@ -0,0 +1,23 @@ +#ifndef GAMBATTE_LOADRES_H +#define GAMBATTE_LOADRES_H + +#include + +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 diff --git a/libgambatte/src/cpu.h b/libgambatte/src/cpu.h index 427847e95d..8d3d7c99a7 100644 --- a/libgambatte/src/cpu.h +++ b/libgambatte/src/cpu.h @@ -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); } diff --git a/libgambatte/src/gambatte.cpp b/libgambatte/src/gambatte.cpp index 818c09c48d..0c05ed4e1a 100644 --- a/libgambatte/src/gambatte.cpp +++ b/libgambatte/src/gambatte.cpp @@ -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); } diff --git a/libgambatte/src/mem/cartridge.cpp b/libgambatte/src/mem/cartridge.cpp index e062fb0c96..63e48171f3 100644 --- a/libgambatte/src/mem/cartridge.cpp +++ b/libgambatte/src/mem/cartridge.cpp @@ -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 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(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) { diff --git a/libgambatte/src/mem/cartridge.h b/libgambatte/src/mem/cartridge.h index 511c4438ae..934d44df7e 100644 --- a/libgambatte/src/mem/cartridge.h +++ b/libgambatte/src/mem/cartridge.h @@ -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(memptrs.romdata() + 0x134); } void setRTCCallback(std::uint32_t (*callback)()) { diff --git a/libgambatte/src/memory.cpp b/libgambatte/src/memory.cpp index 0b92460ca5..657a647fcf 100644 --- a/libgambatte/src/memory.cpp +++ b/libgambatte/src/memory.cpp @@ -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) { diff --git a/libgambatte/src/memory.h b/libgambatte/src/memory.h index 3ea2eec6ac..fcd7981730 100644 --- a/libgambatte/src/memory.h +++ b/libgambatte/src/memory.h @@ -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; diff --git a/output/dll/libgambatte.dll b/output/dll/libgambatte.dll index 980a355abd9a40816cef4cc19e6ec16b03e12ac9..4fac65dc3a39e0105e69397bffed25ce7456143c 100644 GIT binary patch delta 25769 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�K?u#B1denB!Y3UM6z%&e>2LSmBB9tOU!T; z05aE&9Kzoli8~5=6Zt2d=Zw##oJ%>F8fQu{C7O~<@n*ZZz+7a0!m>C`NL!Xxm=etG!9PRy$31NLQ~rtZUFsF|IIfGhQ)rDU(w2 zQvPEaV7}9Q!2E?-Z&_n`&eCq-(iCaRG*wzcT4GvKTCy`ulV(UWr6pODts1MrYO-3b z4(m+oV%+O}$d+JFv?tke|$YQlC$4O#LjCH(hUqwb(3oSRSw(v3zG4l$M>gGVRf{x6}TeHrzVNdXII#^?mDA z>$SESwhgu#+vm1EcAI^f{So^+_DE-XTzXFWwDkGu%hK;j-<)2NUYWixy(+yLXPLDA zFT(Q)?TgyCv>#}{*8W@DQ#VAHth4DR>*nhUbsKcMbd|anbmw%*`YHNb^tbC*>(}ac z>G$eu^>67v(zoh=(f2mQ8?=T};{(PgjIS9#!_XK~rlj1Ga!<;mDW9Y``=s8Jx;6Fw z)SA>|snxb~HcrjBIQXqx?Q7bT+E29?wZEd#fx0A}S$C7}7Tq%48l6Y?knVu4PIp{) zR@b8YLC5R+>l5_`{Z{=$`lt1;>QCxF)wlZ_9&eazxXrNAu-;H^c*0O?_?zKv!)Jyz z18?kaOfcT!G!`4T7#}h|W3;8_rp`@Wk-9#0TdFs;D)r^mcT)e6dLi}a)ZV5+rctI; zQ;w;?RAGA7^t$PksoC^{Db9SoIo&+fyvV%5yve-F{Fu4M{D%4O=4K4Xbr_H-mW7so zSiiIWZ0%)>vnAWiwwr9X*p}JW*>>0-$3Pshowhl@vR$(EuwQ4l+i$kdwclkgwR`N3 z+h4H1Y5&0fPx}>nuk@kmH>8hCpPqgj4N3x*5Ev4hK36|ize2xWzfJGeSLt8Yzpej3 z|E2y%Ju?h2j54Gc))?G|3d6I8*A1r(7Y$bpQO4m$ozZT***MpDm$B5i9i4v8*x)pt zHntf5ZRAt*cwy$JtW0sGTurG=eLHoc=}FT+P1WX8=3mVHEQyvBOO9o>Wtrt<+AG#6 zwna9<-eG?*ozpOBg8NGQhT%-=6XvJQkS>F9w0ln1{@u#q%YT|VFKgO0oK~S#YE@db zHd-rcn^P{OC{mrVsmZBUsD5_p9jR-e`Ug{=Og)tPR_X_-U!;DQdNs9=X_#q@$zr~uwBEGS^tkC6)2pTvrhk~eH-(us<}7ob`401X^G@^Q=4Z{XLEvWd1@jeiFUwHN zSc}Cn!IEzgEcaM8;r;llqW%cqv_;RjS{acS2((`;$e(r!^wW~(K`k_BDlS{#-6mv}d*F;0OMrjZGa2t9se=k!h9LYaVZzZn?#Bwj|sY zcERSex7#PDFHPr4@dkj=BU+~WTsKZ{g9V>4{M!(gVoKr48Fv9?Tkz7=>yE;$oYVR6 z2K=lG)2s9Y^uzR{^%}idKVE;cJ`Wbs$8?QJYf3X^n|7Gq^7fABuXo;PS)Nvr_F~$} zwC1!+X-aFH^#<#B>kRn2d#yXHd##78jn+?KwVbWLZ4_+wM%ygg9kzRHWwwWGPuX6F z&3}UIu3ZyphdtqhXfePQyCGPD7=k#_*Qm6T|lgg>jH^tTEGA zU|epz&*(KCFdi{}XgrUp^yBo- zdHQGcHTu89S)A8j*7q^w7^WH)8CJkylo~c0?lE`Gb=mg9JMY`AFesZ80ILK{E2#Go-6 zAhgw(0kLz8xez?hIJ*F{FEB2K^vjHekiW#Z7VdDPaVvUJZrp9$W30eLyw6x=tTxsd z4;kx?hm8%!qsHULlg1|F8RJ>wIb$BX^J*s4V0^2tQYjl^riZZ`rTL$Rq3nsNA+j)XZ3CR zOPIJhgVK;-NHioFtcF~}9ITTT8`i=)_h3S+G#oP28=Bw{&l)Zm+Oc#}!#)$SfJ&Bz zInRmLS036D|8UYU9+!r#bHG$7aVZHYi7D2UjFc>_wj3#oQ-qX~l(mu#)uc3}G^LzL zIg52^OG6R90$UYC-Cp)S}dlsk>A6q*kO>rXIKWEVQCb!m!bbweFmT LPh?^fU-7>HhoMe| delta 27187 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 G?EeBj{w87o