mirror of https://github.com/bsnes-emu/bsnes.git
Update to v074r01 release.
byuu says: Changelog: - fixed libsnes to compile again, the GB RTC constant is there but doesn't do anything just yet (no serialize support in GameBoy core) - libsnes: added SNES_MEMORY_(WRAM,APURAM,VRAM,OAM,CGRAM) -- really only for the first one, it allows libsnes users to implement their own cheat search - you can now load the SGB BIOS without a game!! please be sure to enjoy the blinking cartridge icon emulation :D - necdsp (uPD7725,96050) - simplified code a bit: removed persistent regs.idb, simplified jumps, merged exec() with main loop, etc. - nall::function - fixed an initialization bug when copy-constructing objects - nall::vector - use calloc instead of malloc to help safeguard against uninitialized class data (potentially hides errors, but better than crashing in production)
This commit is contained in:
parent
20afa076ef
commit
a198e555dc
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -41,7 +41,7 @@ struct Cartridge : property<Cartridge> {
|
|||
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);
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace nall {
|
|||
};
|
||||
|
||||
template<typename L> struct lambda : container {
|
||||
L object;
|
||||
mutable L object;
|
||||
R operator()(P... p) const { return object(std::forward<P>(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); }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -48,5 +48,4 @@ struct Regs {
|
|||
uint16 dr; //data register
|
||||
uint16 si;
|
||||
uint16 so;
|
||||
uint16 idb;
|
||||
} regs;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "libsnes.hpp"
|
||||
#include <snes.hpp>
|
||||
#include <snes/snes.hpp>
|
||||
|
||||
#include <nall/snes/cartridge.hpp>
|
||||
#include <nall/gameboy/cartridge.hpp>
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
output := bgameboy
|
||||
include $(gameboy)/Makefile
|
||||
|
||||
ui_objects := ui-main ui-utility
|
||||
ui_objects += ruby phoenix
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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, "" });
|
||||
|
|
Loading…
Reference in New Issue