diff --git a/bsnes/Makefile b/bsnes/Makefile index 7bec1a5b..15a1c429 100755 --- a/bsnes/Makefile +++ b/bsnes/Makefile @@ -1,7 +1,7 @@ include nall/Makefile snes := snes gameboy := gameboy -profile := accuracy +profile := compatibility ui := ui # compiler @@ -48,8 +48,6 @@ all: build; obj/libco.o: libco/libco.c libco/* -include $(snes)/Makefile -include $(gameboy)/Makefile include $(ui)/Makefile objects := $(patsubst %,obj/%.o,$(objects)) @@ -57,15 +55,17 @@ objects := $(patsubst %,obj/%.o,$(objects)) # targets build: ui_build $(objects) ifeq ($(platform),osx) - test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS - $(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link)) + test -d ../$(output).app || mkdir -p ../$(output).app/Contents/MacOS + $(strip $(cpp) -o ../$(output).app/Contents/MacOS/$(output) $(objects) $(link)) else - $(strip $(cpp) -o out/bsnes $(objects) $(link)) + $(strip $(cpp) -o out/$(output) $(objects) $(link)) endif install: ifeq ($(platform),x) - install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes + install -D -m 755 out/$(output) $(DESTDIR)$(prefix)/bin/$(output) +endif +ifeq ($(output),bsnes) install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop test -d ~/.bsnes || mkdir ~/.bsnes @@ -75,7 +75,9 @@ endif uninstall: ifeq ($(platform),x) - rm $(DESTDIR)$(prefix)/bin/bsnes + rm $(DESTDIR)$(prefix)/bin/$(output) +endif +ifeq ($(output),bsnes) rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop endif diff --git a/bsnes/gameboy/cartridge/cartridge.cpp b/bsnes/gameboy/cartridge/cartridge.cpp index 81862973..adf9a2ff 100755 --- a/bsnes/gameboy/cartridge/cartridge.cpp +++ b/bsnes/gameboy/cartridge/cartridge.cpp @@ -16,13 +16,14 @@ namespace GameBoy { #include "serialization.cpp" Cartridge cartridge; -void Cartridge::load(const string &xml, uint8_t *data, unsigned size) { +void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) { + if(size == 0) size = 32768; + romdata = new uint8[romsize = size](); + if(data) memcpy(romdata, data, size); + //uint32_t crc = crc32_calculate(data, size); //print("CRC32 = ", hex<4>(crc), "\n"); - romdata = new uint8[romsize = size]; - memcpy(romdata, data, size); - info.mapper = Mapper::Unknown; info.ram = false; info.battery = false; diff --git a/bsnes/gameboy/cartridge/cartridge.hpp b/bsnes/gameboy/cartridge/cartridge.hpp index 2ce22a90..922829ed 100755 --- a/bsnes/gameboy/cartridge/cartridge.hpp +++ b/bsnes/gameboy/cartridge/cartridge.hpp @@ -41,7 +41,7 @@ struct Cartridge : property { uint8_t *ramdata; unsigned ramsize; - void load(const string &xml, uint8_t *data, unsigned size); + void load(const string &xml, const uint8_t *data, unsigned size); void unload(); uint8 rom_read(unsigned addr); diff --git a/bsnes/nall/function.hpp b/bsnes/nall/function.hpp index 645991fb..35b76881 100755 --- a/bsnes/nall/function.hpp +++ b/bsnes/nall/function.hpp @@ -27,7 +27,7 @@ namespace nall { }; template struct lambda : container { - L object; + mutable L object; R operator()(P... p) const { return object(std::forward

(p)...); } container* copy() const { return new lambda(object); } lambda(const L& object) : object(object) {} @@ -46,7 +46,7 @@ namespace nall { return *this; } - function(const function &source) { operator=(source); } + function(const function &source) : callback(0) { operator=(source); } function() : callback(0) {} function(void *function) : callback(0) { if(function) callback = new global((R (*)(P...))function); } function(R (*function)(P...)) { callback = new global(function); } diff --git a/bsnes/nall/vector.hpp b/bsnes/nall/vector.hpp index 543c7b69..c6ef24f2 100755 --- a/bsnes/nall/vector.hpp +++ b/bsnes/nall/vector.hpp @@ -46,7 +46,7 @@ namespace nall { void reserve(unsigned newsize) { newsize = bit::round(newsize); //round to nearest power of two (for amortized growth) - T *poolcopy = (T*)malloc(newsize * sizeof(T)); + T *poolcopy = (T*)calloc(newsize, sizeof(T)); for(unsigned i = 0; i < min(objectsize, newsize); i++) new(poolcopy + i) T(pool[i]); for(unsigned i = 0; i < objectsize; i++) pool[i].~T(); free(pool); diff --git a/bsnes/snes/chip/necdsp/disassembler.cpp b/bsnes/snes/chip/necdsp/disassembler.cpp index c28aaa15..5f77e86c 100755 --- a/bsnes/snes/chip/necdsp/disassembler.cpp +++ b/bsnes/snes/chip/necdsp/disassembler.cpp @@ -48,46 +48,44 @@ string NECDSP::disassemble(uint14 ip) { case 1: output << "b"; break; } - if(1||dst) { - output << "\n mov "; + output << "\n mov "; - switch(src) { - case 0: output << "trb,"; break; - case 1: output << "a,"; break; - case 2: output << "b,"; break; - case 3: output << "tr,"; break; - case 4: output << "dp,"; break; - case 5: output << "rp,"; break; - case 6: output << "ro,"; break; - case 7: output << "sgn,"; break; - case 8: output << "dr,"; break; - case 9: output << "drnf,"; break; - case 10: output << "sr,"; break; - case 11: output << "sim,"; break; - case 12: output << "sil,"; break; - case 13: output << "k,"; break; - case 14: output << "l,"; break; - case 15: output << "mem,"; break; - } + switch(src) { + case 0: output << "trb,"; break; + case 1: output << "a,"; break; + case 2: output << "b,"; break; + case 3: output << "tr,"; break; + case 4: output << "dp,"; break; + case 5: output << "rp,"; break; + case 6: output << "ro,"; break; + case 7: output << "sgn,"; break; + case 8: output << "dr,"; break; + case 9: output << "drnf,"; break; + case 10: output << "sr,"; break; + case 11: output << "sim,"; break; + case 12: output << "sil,"; break; + case 13: output << "k,"; break; + case 14: output << "l,"; break; + case 15: output << "mem,"; break; + } - switch(dst) { - case 0: output << "non"; break; - case 1: output << "a"; break; - case 2: output << "b"; break; - case 3: output << "tr"; break; - case 4: output << "dp"; break; - case 5: output << "rp"; break; - case 6: output << "dr"; break; - case 7: output << "sr"; break; - case 8: output << "sol"; break; - case 9: output << "som"; break; - case 10: output << "k"; break; - case 11: output << "klr"; break; - case 12: output << "klm"; break; - case 13: output << "l"; break; - case 14: output << "trb"; break; - case 15: output << "mem"; break; - } + switch(dst) { + case 0: output << "non"; break; + case 1: output << "a"; break; + case 2: output << "b"; break; + case 3: output << "tr"; break; + case 4: output << "dp"; break; + case 5: output << "rp"; break; + case 6: output << "dr"; break; + case 7: output << "sr"; break; + case 8: output << "sol"; break; + case 9: output << "som"; break; + case 10: output << "k"; break; + case 11: output << "klr"; break; + case 12: output << "klm"; break; + case 13: output << "l"; break; + case 14: output << "trb"; break; + case 15: output << "mem"; break; } if(dpl) { @@ -132,9 +130,12 @@ string NECDSP::disassemble(uint14 ip) { if(type == 2) { //JP uint9 brch = opcode >> 13; uint11 na = opcode >> 2; + uint8 bank = opcode >> 0; + + uint14 jp = (regs.pc & 0x2000) | (bank << 11) | (na << 0); switch(brch) { - case 0x000: output << "jmpso "; break; + case 0x000: output << "jmpso "; jp = 0; break; case 0x080: output << "jnca "; break; case 0x082: output << "jca "; break; case 0x084: output << "jncb "; break; @@ -169,14 +170,14 @@ string NECDSP::disassemble(uint14 ip) { case 0x0ba: output << "jsoak "; break; case 0x0bc: output << "jnrqm "; break; case 0x0be: output << "jrqm "; break; - case 0x100: output << "ljmp "; break; - case 0x101: output << "hjmp "; break; - case 0x140: output << "lcall "; break; - case 0x141: output << "hcall "; break; + case 0x100: output << "ljmp "; jp &= ~0x2000; break; + case 0x101: output << "hjmp "; jp |= 0x2000; break; + case 0x140: output << "lcall "; jp &= ~0x2000; break; + case 0x141: output << "hcall "; jp |= 0x2000; break; default: output << "?????? "; break; } - output << "$" << hex<4>(na); + output << "$" << hex<4>(jp); } if(type == 3) { //LD diff --git a/bsnes/snes/chip/necdsp/necdsp.cpp b/bsnes/snes/chip/necdsp/necdsp.cpp index fed77758..10be8421 100755 --- a/bsnes/snes/chip/necdsp/necdsp.cpp +++ b/bsnes/snes/chip/necdsp/necdsp.cpp @@ -16,26 +16,26 @@ void NECDSP::enter() { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } - exec(); +static uint16 lastpc = 0xfff; +if(lastpc != regs.pc) print(disassemble(lastpc = regs.pc), "\n"); + + uint24 opcode = programROM[regs.pc++]; + switch(opcode >> 22) { + case 0: exec_op(opcode); break; + case 1: exec_rt(opcode); break; + case 2: exec_jp(opcode); break; + case 3: exec_ld(opcode); break; + } + + int32 result = (int32)regs.k * regs.l; //sign + 30-bit result + regs.m = result >> 15; //store sign + top 15-bits + regs.n = result << 1; //store low 15-bits + zero + step(1); synchronize_cpu(); } } -void NECDSP::exec() { - uint24 opcode = programROM[regs.pc++]; - switch(opcode >> 22) { - case 0: exec_op(opcode); break; - case 1: exec_rt(opcode); break; - case 2: exec_jp(opcode); break; - case 3: exec_ld(opcode); break; - } - - int32 result = (int32)regs.k * regs.l; //sign + 30-bit result - regs.m = result >> 15; //store sign + top 15-bits - regs.n = result << 1; //store low 15-bits + zero -} - void NECDSP::exec_op(uint24 opcode) { uint2 pselect = opcode >> 20; //P select uint4 alu = opcode >> 16; //ALU operation mode @@ -46,23 +46,24 @@ void NECDSP::exec_op(uint24 opcode) { uint4 src = opcode >> 4; //move source uint4 dst = opcode >> 0; //move destination + uint16 idb; switch(src) { - case 0: regs.idb = regs.trb; break; - case 1: regs.idb = regs.a; break; - case 2: regs.idb = regs.b; break; - case 3: regs.idb = regs.tr; break; - case 4: regs.idb = regs.dp; break; - case 5: regs.idb = regs.rp; break; - case 6: regs.idb = dataROM[regs.rp]; break; - case 7: regs.idb = 0x8000 - regs.flaga.s1; break; - case 8: regs.idb = regs.dr; regs.sr.rqm = 1; break; - case 9: regs.idb = regs.dr; break; - case 10: regs.idb = regs.sr; break; - case 11: regs.idb = regs.si; break; //MSB - case 12: regs.idb = regs.si; break; //LSB - case 13: regs.idb = regs.k; break; - case 14: regs.idb = regs.l; break; - case 15: regs.idb = dataRAM[regs.dp]; break; + case 0: idb = regs.trb; break; + case 1: idb = regs.a; break; + case 2: idb = regs.b; break; + case 3: idb = regs.tr; break; + case 4: idb = regs.dp; break; + case 5: idb = regs.rp; break; + case 6: idb = dataROM[regs.rp]; break; + case 7: idb = 0x8000 - regs.flaga.s1; break; + case 8: idb = regs.dr; regs.sr.rqm = 1; break; + case 9: idb = regs.dr; break; + case 10: idb = regs.sr; break; + case 11: idb = regs.si; break; //MSB + case 12: idb = regs.si; break; //LSB + case 13: idb = regs.k; break; + case 14: idb = regs.l; break; + case 15: idb = dataRAM[regs.dp]; break; } if(alu) { @@ -72,7 +73,7 @@ void NECDSP::exec_op(uint24 opcode) { switch(pselect) { case 0: p = dataRAM[regs.dp]; break; - case 1: p = regs.idb; break; + case 1: p = idb; break; case 2: p = regs.m; break; case 3: p = regs.n; break; } @@ -146,7 +147,7 @@ void NECDSP::exec_op(uint24 opcode) { } } - exec_ld((regs.idb << 6) + dst); + exec_ld((idb << 6) + dst); switch(dpl) { case 1: regs.dp = (regs.dp & 0xf0) + ((regs.dp + 1) & 0x0f); break; //DPINC @@ -169,55 +170,54 @@ void NECDSP::exec_jp(uint24 opcode) { uint11 na = opcode >> 2; //next address uint2 bank = opcode >> 0; //bank address - uint16 jps = (regs.pc & 0x2000) | (bank << 11) | (na << 0); - uint16 jpl = (bank << 11) | (na << 0); + uint14 jp = (regs.pc & 0x2000) | (bank << 11) | (na << 0); switch(brch) { case 0x000: regs.pc = regs.so; return; //JMPSO - case 0x080: if(regs.flaga.c == 0) regs.pc = jps; return; //JNCA - case 0x082: if(regs.flaga.c == 1) regs.pc = jps; return; //JCA - case 0x084: if(regs.flagb.c == 0) regs.pc = jps; return; //JNCB - case 0x086: if(regs.flagb.c == 1) regs.pc = jps; return; //JCB + case 0x080: if(regs.flaga.c == 0) regs.pc = jp; return; //JNCA + case 0x082: if(regs.flaga.c == 1) regs.pc = jp; return; //JCA + case 0x084: if(regs.flagb.c == 0) regs.pc = jp; return; //JNCB + case 0x086: if(regs.flagb.c == 1) regs.pc = jp; return; //JCB - case 0x088: if(regs.flaga.z == 0) regs.pc = jps; return; //JNZA - case 0x08a: if(regs.flaga.z == 1) regs.pc = jps; return; //JZA - case 0x08c: if(regs.flagb.z == 0) regs.pc = jps; return; //JNZB - case 0x08e: if(regs.flagb.z == 1) regs.pc = jps; return; //JZB + case 0x088: if(regs.flaga.z == 0) regs.pc = jp; return; //JNZA + case 0x08a: if(regs.flaga.z == 1) regs.pc = jp; return; //JZA + case 0x08c: if(regs.flagb.z == 0) regs.pc = jp; return; //JNZB + case 0x08e: if(regs.flagb.z == 1) regs.pc = jp; return; //JZB - case 0x090: if(regs.flaga.ov0 == 0) regs.pc = jps; return; //JNOVA0 - case 0x092: if(regs.flaga.ov0 == 1) regs.pc = jps; return; //JOVA0 - case 0x094: if(regs.flagb.ov0 == 0) regs.pc = jps; return; //JNOVB0 - case 0x096: if(regs.flagb.ov0 == 1) regs.pc = jps; return; //JOVB0 + case 0x090: if(regs.flaga.ov0 == 0) regs.pc = jp; return; //JNOVA0 + case 0x092: if(regs.flaga.ov0 == 1) regs.pc = jp; return; //JOVA0 + case 0x094: if(regs.flagb.ov0 == 0) regs.pc = jp; return; //JNOVB0 + case 0x096: if(regs.flagb.ov0 == 1) regs.pc = jp; return; //JOVB0 - case 0x098: if(regs.flaga.ov1 == 0) regs.pc = jps; return; //JNOVA1 - case 0x09a: if(regs.flaga.ov1 == 1) regs.pc = jps; return; //JOVA1 - case 0x09c: if(regs.flagb.ov1 == 0) regs.pc = jps; return; //JNOVB1 - case 0x09e: if(regs.flagb.ov1 == 1) regs.pc = jps; return; //JOVB1 + case 0x098: if(regs.flaga.ov1 == 0) regs.pc = jp; return; //JNOVA1 + case 0x09a: if(regs.flaga.ov1 == 1) regs.pc = jp; return; //JOVA1 + case 0x09c: if(regs.flagb.ov1 == 0) regs.pc = jp; return; //JNOVB1 + case 0x09e: if(regs.flagb.ov1 == 1) regs.pc = jp; return; //JOVB1 - case 0x0a0: if(regs.flaga.s0 == 0) regs.pc = jps; return; //JNSA0 - case 0x0a2: if(regs.flaga.s0 == 1) regs.pc = jps; return; //JSA0 - case 0x0a4: if(regs.flagb.s0 == 0) regs.pc = jps; return; //JNSB0 - case 0x0a6: if(regs.flagb.s0 == 1) regs.pc = jps; return; //JSB0 + case 0x0a0: if(regs.flaga.s0 == 0) regs.pc = jp; return; //JNSA0 + case 0x0a2: if(regs.flaga.s0 == 1) regs.pc = jp; return; //JSA0 + case 0x0a4: if(regs.flagb.s0 == 0) regs.pc = jp; return; //JNSB0 + case 0x0a6: if(regs.flagb.s0 == 1) regs.pc = jp; return; //JSB0 - case 0x0a8: if(regs.flaga.s1 == 0) regs.pc = jps; return; //JNSA1 - case 0x0aa: if(regs.flaga.s1 == 1) regs.pc = jps; return; //JSA1 - case 0x0ac: if(regs.flagb.s1 == 0) regs.pc = jps; return; //JNSB1 - case 0x0ae: if(regs.flagb.s1 == 1) regs.pc = jps; return; //JSB1 + case 0x0a8: if(regs.flaga.s1 == 0) regs.pc = jp; return; //JNSA1 + case 0x0aa: if(regs.flaga.s1 == 1) regs.pc = jp; return; //JSA1 + case 0x0ac: if(regs.flagb.s1 == 0) regs.pc = jp; return; //JNSB1 + case 0x0ae: if(regs.flagb.s1 == 1) regs.pc = jp; return; //JSB1 - case 0x0b0: if((regs.dp & 0x0f) == 0x00) regs.pc = jps; return; //JDPL0 - case 0x0b1: if((regs.dp & 0x0f) != 0x00) regs.pc = jps; return; //JDPLN0 - case 0x0b2: if((regs.dp & 0x0f) == 0x0f) regs.pc = jps; return; //JDPLF - case 0x0b3: if((regs.dp & 0x0f) != 0x0f) regs.pc = jps; return; //JDPLNF + case 0x0b0: if((regs.dp & 0x0f) == 0x00) regs.pc = jp; return; //JDPL0 + case 0x0b1: if((regs.dp & 0x0f) != 0x00) regs.pc = jp; return; //JDPLN0 + case 0x0b2: if((regs.dp & 0x0f) == 0x0f) regs.pc = jp; return; //JDPLF + case 0x0b3: if((regs.dp & 0x0f) != 0x0f) regs.pc = jp; return; //JDPLNF - case 0x0bc: if(regs.sr.rqm == 0) regs.pc = jps; return; //JNRQM - case 0x0be: if(regs.sr.rqm == 1) regs.pc = jps; return; //JRQM + case 0x0bc: if(regs.sr.rqm == 0) regs.pc = jp; return; //JNRQM + case 0x0be: if(regs.sr.rqm == 1) regs.pc = jp; return; //JRQM - case 0x100: regs.pc = 0x0000 | jpl; return; //LJMP - case 0x101: regs.pc = 0x2000 | jpl; return; //HJMP + case 0x100: regs.pc = jp & ~0x2000; return; //LJMP + case 0x101: regs.pc = jp | 0x2000; return; //HJMP - case 0x140: regs.stack[regs.sp++] = regs.pc; regs.pc = 0x0000 | jpl; return; //LCALL - case 0x141: regs.stack[regs.sp++] = regs.pc; regs.pc = 0x2000 | jpl; return; //HCALL + case 0x140: regs.stack[regs.sp++] = regs.pc; regs.pc = jp & ~0x2000; return; //LCALL + case 0x141: regs.stack[regs.sp++] = regs.pc; regs.pc = jp | 0x2000; return; //HCALL } } @@ -225,8 +225,6 @@ void NECDSP::exec_ld(uint24 opcode) { uint16 id = opcode >> 6; //immediate data uint4 dst = opcode >> 0; //destination - regs.idb = id; - switch(dst) { case 0: break; case 1: regs.a = id; break; @@ -292,7 +290,6 @@ void NECDSP::reset() { regs.dr = 0x0000; regs.si = 0x0000; regs.so = 0x0000; - regs.idb = 0x0000; } NECDSP::NECDSP() { diff --git a/bsnes/snes/chip/necdsp/necdsp.hpp b/bsnes/snes/chip/necdsp/necdsp.hpp index 9ea82229..4d99f647 100755 --- a/bsnes/snes/chip/necdsp/necdsp.hpp +++ b/bsnes/snes/chip/necdsp/necdsp.hpp @@ -19,7 +19,6 @@ public: static void Enter(); void enter(); - void exec(); void exec_op(uint24 opcode); void exec_rt(uint24 opcode); void exec_jp(uint24 opcode); diff --git a/bsnes/snes/chip/necdsp/registers.hpp b/bsnes/snes/chip/necdsp/registers.hpp index 526bac52..ff5de61f 100755 --- a/bsnes/snes/chip/necdsp/registers.hpp +++ b/bsnes/snes/chip/necdsp/registers.hpp @@ -48,5 +48,4 @@ struct Regs { uint16 dr; //data register uint16 si; uint16 so; - uint16 idb; } regs; diff --git a/bsnes/snes/chip/necdsp/serialization.cpp b/bsnes/snes/chip/necdsp/serialization.cpp index 64480827..b7a16619 100755 --- a/bsnes/snes/chip/necdsp/serialization.cpp +++ b/bsnes/snes/chip/necdsp/serialization.cpp @@ -48,7 +48,6 @@ void NECDSP::serialize(serializer &s) { s.integer(regs.dr); s.integer(regs.si); s.integer(regs.so); - s.integer(regs.idb); } #endif diff --git a/bsnes/snes/libsnes/libsnes.cpp b/bsnes/snes/libsnes/libsnes.cpp index 3eebaedf..8a6f6ee2 100755 --- a/bsnes/snes/libsnes/libsnes.cpp +++ b/bsnes/snes/libsnes/libsnes.cpp @@ -1,7 +1,8 @@ #include "libsnes.hpp" -#include +#include #include +#include using namespace nall; struct Interface : public SNES::Interface { @@ -38,7 +39,7 @@ unsigned snes_library_revision_major(void) { } unsigned snes_library_revision_minor(void) { - return 1; + return 2; } void snes_set_video_refresh(snes_video_refresh_t video_refresh) { @@ -178,9 +179,11 @@ bool snes_load_cartridge_super_game_boy( snes_cheat_reset(); if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; - if(dmg_data) SNES::memory::gbrom.copy(dmg_data, dmg_size); - string xmldmg = (dmg_xml && *dmg_xml) ? string(dmg_xml) : SNESCartridge(dmg_data, dmg_size).xmlMemoryMap; - SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { xmlrom, xmldmg }); + if(dmg_data) { + string xmldmg = (dmg_xml && *dmg_xml) ? string(dmg_xml) : GameBoyCartridge(dmg_data, dmg_size).xml; + GameBoy::cartridge.load(dmg_xml, dmg_data, dmg_size); + } + SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { xmlrom, "" }); SNES::system.power(); return true; } @@ -215,12 +218,21 @@ uint8_t* snes_get_memory_data(unsigned id) { return SNES::memory::stBram.data(); case SNES_MEMORY_GAME_BOY_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbram.data(); - case SNES_MEMORY_GAME_BOY_RTC: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbrtc.data(); + return GameBoy::cartridge.ramdata; + //case SNES_MEMORY_GAME_BOY_RTC: + // if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + // return GameBoy::cartridge.rtcdata; + + case SNES_MEMORY_WRAM: + return SNES::memory::wram.data(); + case SNES_MEMORY_APURAM: + return SNES::memory::apuram.data(); + case SNES_MEMORY_VRAM: + return SNES::memory::vram.data(); + case SNES_MEMORY_OAM: + return SNES::memory::oam.data(); + case SNES_MEMORY_CGRAM: + return SNES::memory::cgram.data(); } return 0; @@ -255,11 +267,27 @@ unsigned snes_get_memory_size(unsigned id) { break; case SNES_MEMORY_GAME_BOY_RAM: if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbram.size(); + size = GameBoy::cartridge.ramsize; break; - case SNES_MEMORY_GAME_BOY_RTC: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbrtc.size(); + //case SNES_MEMORY_GAME_BOY_RTC: + // if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; + // size = GameBoy::cartridge.rtcsize; + // break; + + case SNES_MEMORY_WRAM: + size = SNES::memory::wram.size(); + break; + case SNES_MEMORY_APURAM: + size = SNES::memory::apuram.size(); + break; + case SNES_MEMORY_VRAM: + size = SNES::memory::vram.size(); + break; + case SNES_MEMORY_OAM: + size = SNES::memory::oam.size(); + break; + case SNES_MEMORY_CGRAM: + size = SNES::memory::cgram.size(); break; } diff --git a/bsnes/snes/libsnes/libsnes.hpp b/bsnes/snes/libsnes/libsnes.hpp index 25328c10..82fe8e93 100755 --- a/bsnes/snes/libsnes/libsnes.hpp +++ b/bsnes/snes/libsnes/libsnes.hpp @@ -60,6 +60,12 @@ extern "C" { #define SNES_MEMORY_GAME_BOY_RAM 6 #define SNES_MEMORY_GAME_BOY_RTC 7 +#define SNES_MEMORY_WRAM 100 +#define SNES_MEMORY_APURAM 101 +#define SNES_MEMORY_VRAM 102 +#define SNES_MEMORY_OAM 103 +#define SNES_MEMORY_CGRAM 104 + typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height); typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right); typedef void (*snes_input_poll_t)(void); diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 492f63f5..06411d81 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -1,8 +1,8 @@ namespace SNES { namespace Info { static const char Name[] = "bsnes"; - static const char Version[] = "074"; - static const unsigned SerializerVersion = 16; + static const char Version[] = "074.01"; + static const unsigned SerializerVersion = 17; } } diff --git a/bsnes/ui-gameboy/Makefile b/bsnes/ui-gameboy/Makefile index c7c9db80..faa8c579 100755 --- a/bsnes/ui-gameboy/Makefile +++ b/bsnes/ui-gameboy/Makefile @@ -1,3 +1,6 @@ +output := bgameboy +include $(gameboy)/Makefile + ui_objects := ui-main ui-utility ui_objects += ruby phoenix diff --git a/bsnes/ui/Makefile b/bsnes/ui/Makefile index 71f14855..19d1d902 100755 --- a/bsnes/ui/Makefile +++ b/bsnes/ui/Makefile @@ -1,3 +1,7 @@ +output := bsnes +include $(snes)/Makefile +include $(gameboy)/Makefile + ui_objects := ui-main ui-general ui-settings ui-tools ui-input ui-utility ui-cartridge ui-debugger ui_objects += ruby phoenix ui_objects += $(if $(call streq,$(platform),win),resource) diff --git a/bsnes/ui/cartridge/cartridge.cpp b/bsnes/ui/cartridge/cartridge.cpp index 37b00d64..1116c1c7 100755 --- a/bsnes/ui/cartridge/cartridge.cpp +++ b/bsnes/ui/cartridge/cartridge.cpp @@ -57,18 +57,21 @@ bool Cartridge::loadSuperGameBoy(const char *basename, const char *slotname) { unload(); if(loadCartridge(SNES::memory::cartrom, baseXML, basename) == false) return false; + unsigned size = 0; + uint8_t *data = 0; + file fp; if(fp.open(slotname, file::mode::read)) { - unsigned size = fp.size(); - uint8_t *data = new uint8_t[size]; + data = new uint8_t[size = fp.size()]; fp.read(data, size); fp.close(); - - GameBoyCartridge info(data, size); - GameBoy::cartridge.load(info.xml, data, size); - delete[] data; } + //note: it is safe to pass below two functions null pointers + GameBoyCartridge info(data, size); + GameBoy::cartridge.load(info.xml, data, size); + if(data) delete[] data; + SNES::cartridge.basename = baseName = nall::basename(basename); slotAName = nall::basename(slotname); SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { baseXML, "" });