diff --git a/bsnes/nall/snes/cartridge.hpp b/bsnes/nall/snes/cartridge.hpp
index 2ecc36b1..66398603 100755
--- a/bsnes/nall/snes/cartridge.hpp
+++ b/bsnes/nall/snes/cartridge.hpp
@@ -408,7 +408,7 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
}
if(has_dsp1) {
- xml << " \n";
+ xml << " \n";
if(dsp1_mapper == DSP1LoROM1MB) {
xml << " \n";
xml << " \n";
@@ -437,11 +437,11 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
xml << " \n";
xml << " \n";
}
- xml << " \n";
+ xml << " \n";
}
if(has_dsp2) {
- xml << " \n";
+ xml << " \n";
xml << " \n";
xml << " \n";
xml << " \n";
@@ -450,11 +450,11 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
xml << " \n";
xml << " \n";
xml << " \n";
- xml << " \n";
+ xml << " \n";
}
if(has_dsp3) {
- xml << " \n";
+ xml << " \n";
xml << " \n";
xml << " \n";
xml << " \n";
@@ -463,11 +463,11 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
xml << " \n";
xml << " \n";
xml << " \n";
- xml << " \n";
+ xml << " \n";
}
if(has_dsp4) {
- xml << " \n";
+ xml << " \n";
xml << " \n";
xml << " \n";
xml << " \n";
@@ -476,7 +476,7 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
xml << " \n";
xml << " \n";
xml << " \n";
- xml << " \n";
+ xml << " \n";
}
if(has_obc1) {
@@ -489,12 +489,10 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
}
if(has_st010) {
- xml << " \n";
- xml << " \n";
- xml << " \n";
- xml << " \n";
- xml << " \n";
- xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
}
if(has_st011) {
diff --git a/bsnes/snes/Makefile b/bsnes/snes/Makefile
index b9d9bcda..5ddab5b0 100755
--- a/bsnes/snes/Makefile
+++ b/bsnes/snes/Makefile
@@ -2,7 +2,8 @@ snes_objects := snes-system
snes_objects += snes-cartridge snes-cheat
snes_objects += snes-memory snes-cpucore snes-smpcore
snes_objects += snes-cpu snes-smp snes-dsp snes-ppu
-snes_objects += snes-icd2 snes-superfx snes-sa1 snes-upd77c25
+snes_objects += snes-icd2 snes-superfx snes-sa1
+snes_objects += snes-necdsp snes-upd7725 snes-upd96050
snes_objects += snes-bsx snes-srtc snes-sdd1 snes-spc7110 snes-cx4
snes_objects += snes-obc1 snes-st0010 snes-st0011 snes-st0018
snes_objects += snes-msu1 snes-serial
@@ -44,7 +45,9 @@ obj/snes-cheat.o : $(snes)/cheat/cheat.cpp $(call rwildcard,$(snes)/cheat/)
obj/snes-icd2.o : $(snes)/chip/icd2/icd2.cpp $(call rwildcard,$(snes)/chip/icd2/)
obj/snes-superfx.o : $(snes)/chip/superfx/superfx.cpp $(call rwildcard,$(snes)/chip/superfx/)
obj/snes-sa1.o : $(snes)/chip/sa1/sa1.cpp $(call rwildcard,$(snes)/chip/sa1/)
-obj/snes-upd77c25.o: $(snes)/chip/upd77c25/upd77c25.cpp $(call rwildcard,$(snes)/chip/upd77c25/)
+obj/snes-necdsp.o : $(snes)/chip/necdsp/core/core.cpp $(call rwildcard,$(snes)/chip/necdsp/core/)
+obj/snes-upd7725.o : $(snes)/chip/necdsp/upd7725/upd7725.cpp $(call rwildcard,$(snes)/chip/necdsp/)
+obj/snes-upd96050.o: $(snes)/chip/necdsp/upd96050/upd96050.cpp $(call rwildcard,$(snes)/chip/necdsp/)
obj/snes-bsx.o : $(snes)/chip/bsx/bsx.cpp $(snes)/chip/bsx/*
obj/snes-srtc.o : $(snes)/chip/srtc/srtc.cpp $(snes)/chip/srtc/*
obj/snes-sdd1.o : $(snes)/chip/sdd1/sdd1.cpp $(snes)/chip/sdd1/*
diff --git a/bsnes/snes/cartridge/cartridge.cpp b/bsnes/snes/cartridge/cartridge.cpp
index 83965ec7..2aa25a41 100755
--- a/bsnes/snes/cartridge/cartridge.cpp
+++ b/bsnes/snes/cartridge/cartridge.cpp
@@ -28,7 +28,8 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
has_bsx_slot = false;
has_superfx = false;
has_sa1 = false;
- has_upd77c25 = false;
+ has_upd7725 = false;
+ has_upd96050 = false;
has_srtc = false;
has_sdd1 = false;
has_spc7110 = false;
diff --git a/bsnes/snes/cartridge/cartridge.hpp b/bsnes/snes/cartridge/cartridge.hpp
index 950ae302..39089555 100755
--- a/bsnes/snes/cartridge/cartridge.hpp
+++ b/bsnes/snes/cartridge/cartridge.hpp
@@ -35,7 +35,8 @@ public:
readonly has_bsx_slot;
readonly has_superfx;
readonly has_sa1;
- readonly has_upd77c25;
+ readonly has_upd7725;
+ readonly has_upd96050;
readonly has_srtc;
readonly has_sdd1;
readonly has_spc7110;
@@ -84,7 +85,8 @@ private:
void xml_parse_icd2(xml_element&);
void xml_parse_superfx(xml_element&);
void xml_parse_sa1(xml_element&);
- void xml_parse_upd77c25(xml_element&);
+ void xml_parse_upd7725(xml_element&);
+ void xml_parse_upd96050(xml_element&);
void xml_parse_bsx(xml_element&);
void xml_parse_sufamiturbo(xml_element&);
void xml_parse_supergameboy(xml_element&);
diff --git a/bsnes/snes/cartridge/xml.cpp b/bsnes/snes/cartridge/xml.cpp
index c6795cb1..e32f63b8 100755
--- a/bsnes/snes/cartridge/xml.cpp
+++ b/bsnes/snes/cartridge/xml.cpp
@@ -35,7 +35,8 @@ void Cartridge::parse_xml_cartridge(const char *data) {
if(node.name == "icd2") xml_parse_icd2(node);
if(node.name == "superfx") xml_parse_superfx(node);
if(node.name == "sa1") xml_parse_sa1(node);
- if(node.name == "upd77c25") xml_parse_upd77c25(node);
+ if(node.name == "upd7725") xml_parse_upd7725(node);
+ if(node.name == "upd96050") xml_parse_upd96050(node);
if(node.name == "bsx") xml_parse_bsx(node);
if(node.name == "sufamiturbo") xml_parse_sufamiturbo(node);
if(node.name == "srtc") xml_parse_srtc(node);
@@ -229,16 +230,16 @@ void Cartridge::xml_parse_sa1(xml_element &root) {
}
}
-void Cartridge::xml_parse_upd77c25(xml_element &root) {
- has_upd77c25 = true;
+void Cartridge::xml_parse_upd7725(xml_element &root) {
+ has_upd7725 = true;
bool program = false;
bool sha256 = false;
string xml_hash;
string rom_hash;
- for(unsigned n = 0; n < 2048; n++) upd77c25.programROM[n] = 0;
- for(unsigned n = 0; n < 1024; n++) upd77c25.dataROM[n] = 0;
+ for(unsigned n = 0; n < 2048; n++) upd7725.programROM[n] = 0;
+ for(unsigned n = 0; n < 1024; n++) upd7725.dataROM[n] = 0;
foreach(attr, root.attribute) {
if(attr.name == "program") {
@@ -248,10 +249,10 @@ void Cartridge::xml_parse_upd77c25(xml_element &root) {
program = true;
for(unsigned n = 0; n < 2048; n++) {
- upd77c25.programROM[n] = fp.readm(3);
+ upd7725.programROM[n] = fp.readm(3);
}
for(unsigned n = 0; n < 1024; n++) {
- upd77c25.dataROM[n] = fp.readm(2);
+ upd7725.dataROM[n] = fp.readm(2);
}
fp.seek(0);
@@ -277,7 +278,7 @@ void Cartridge::xml_parse_upd77c25(xml_element &root) {
if(node.name == "dr") {
foreach(leaf, node.element) {
if(leaf.name == "map") {
- Mapping m(upd77c25dr);
+ Mapping m(upd7725dr);
foreach(attr, leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
@@ -287,7 +288,7 @@ void Cartridge::xml_parse_upd77c25(xml_element &root) {
} else if(node.name == "sr") {
foreach(leaf, node.element) {
if(leaf.name == "map") {
- Mapping m(upd77c25sr);
+ Mapping m(upd7725sr);
foreach(attr, leaf.attribute) {
if(attr.name == "address") xml_parse_address(m, attr.content);
}
@@ -298,10 +299,75 @@ void Cartridge::xml_parse_upd77c25(xml_element &root) {
}
if(program == false) {
- system.interface->message("Warning: uPD77C25 program is missing.");
+ system.interface->message("Warning: uPD7725 program is missing.");
} else if(sha256 == true && xml_hash != rom_hash) {
system.interface->message({
- "Warning: uPD77C25 program SHA256 is incorrect.\n\n"
+ "Warning: uPD7725 program SHA256 is incorrect.\n\n"
+ "Expected:\n", xml_hash, "\n\n"
+ "Actual:\n", rom_hash
+ });
+ }
+}
+
+void Cartridge::xml_parse_upd96050(xml_element &root) {
+ has_upd96050 = true;
+
+ bool program = false;
+ bool sha256 = false;
+ string xml_hash;
+ string rom_hash;
+
+ for(unsigned n = 0; n < 16384; n++) upd96050.programROM[n] = 0;
+ for(unsigned n = 0; n < 2048; n++) upd96050.dataROM[n] = 0;
+
+ foreach(attr, root.attribute) {
+ if(attr.name == "program") {
+ file fp;
+ fp.open(string(dir(basename()), attr.content), file::mode::read);
+ if(fp.open() && fp.size() == 52 * 1024) {
+ program = true;
+
+ for(unsigned n = 0; n < 16384; n++) {
+ upd96050.programROM[n] = fp.readm(3);
+ }
+ for(unsigned n = 0; n < 1024; n++) {
+ upd96050.dataROM[n] = fp.readm(2);
+ }
+
+ fp.seek(0);
+ uint8 data[52 * 1024];
+ fp.read(data, 52 * 1024);
+ fp.close();
+
+ sha256_ctx sha;
+ uint8 shahash[32];
+ sha256_init(&sha);
+ sha256_chunk(&sha, data, 52 * 1024);
+ sha256_final(&sha);
+ sha256_hash(&sha, shahash);
+ foreach(n, shahash) rom_hash.append(hex<2>(n));
+ }
+ } else if(attr.name == "sha256") {
+ sha256 = true;
+ xml_hash = attr.content;
+ }
+ }
+
+ foreach(node, root.element) {
+ if(node.name == "map") {
+ Mapping m(upd96050);
+ foreach(attr, node.attribute) {
+ if(attr.name == "address") xml_parse_address(m, attr.content);
+ }
+ mapping.append(m);
+ }
+ }
+
+ if(program == false) {
+ system.interface->message("Warning: uPD96050 program is missing.");
+ } else if(sha256 == true && xml_hash != rom_hash) {
+ system.interface->message({
+ "Warning: uPD96050 program SHA256 is incorrect.\n\n"
"Expected:\n", xml_hash, "\n\n"
"Actual:\n", rom_hash
});
diff --git a/bsnes/snes/chip/chip.hpp b/bsnes/snes/chip/chip.hpp
index da46cc39..a73fada1 100755
--- a/bsnes/snes/chip/chip.hpp
+++ b/bsnes/snes/chip/chip.hpp
@@ -6,7 +6,9 @@ struct Coprocessor : Processor {
#include
#include
#include
-#include
+#include
+#include
+#include
#include
#include
#include
diff --git a/bsnes/snes/chip/upd77c25/upd77c25.cpp b/bsnes/snes/chip/necdsp/core/core.cpp
similarity index 72%
rename from bsnes/snes/chip/upd77c25/upd77c25.cpp
rename to bsnes/snes/chip/necdsp/core/core.cpp
index 8323eff9..bb634fef 100755
--- a/bsnes/snes/chip/upd77c25/upd77c25.cpp
+++ b/bsnes/snes/chip/necdsp/core/core.cpp
@@ -1,50 +1,27 @@
-//NEC uPD77C25 emulation core
-//author: byuu
-//license: public domain
-
-//unsupported components:
-//* serial input/output
-//* interrupts
-//* DMA
-
#include
-#define UPD77C25_CPP
+#define UPDCORE_CPP
namespace SNES {
-#include "serialization.cpp"
#include "disassembler.cpp"
+#include "serialization.cpp"
-UPD77C25 upd77c25;
-UPD77C25SR upd77c25sr;
-UPD77C25DR upd77c25dr;
-
-void UPD77C25::Enter() { upd77c25.enter(); }
-
-void UPD77C25::enter() {
- while(true) {
- if(scheduler.sync == Scheduler::SynchronizeMode::All) {
- scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
- }
-
- 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 uPDcore::exec() {
+ uint24 opcode = programROM[regs.pc];
+ regs.pc = regs.pc + 1;
+ 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 UPD77C25::exec_op(uint24 opcode) {
+void uPDcore::exec_op(uint24 opcode) {
uint2 pselect = opcode >> 20; //P select
uint4 alu = opcode >> 16; //ALU operation mode
uint1 asl = opcode >> 15; //accumulator select
@@ -162,17 +139,17 @@ void UPD77C25::exec_op(uint24 opcode) {
case 3: regs.dp = (regs.dp & 0xf0); break; //DPCLR
}
- regs.dp ^= dphm << 4;
+ regs.dp = regs.dp ^ (dphm << 4);
- if(rpdcr) regs.rp--;
+ if(rpdcr) regs.rp = regs.rp - 1;
}
-void UPD77C25::exec_rt(uint24 opcode) {
+void uPDcore::exec_rt(uint24 opcode) {
exec_op(opcode);
stack_pull();
}
-void UPD77C25::exec_jp(uint24 opcode) {
+void uPDcore::exec_jp(uint24 opcode) {
uint9 brch = opcode >> 13; //branch
uint11 na = opcode >> 2; //next address
@@ -225,7 +202,7 @@ void UPD77C25::exec_jp(uint24 opcode) {
if(r) regs.pc = na;
}
-void UPD77C25::exec_ld(uint24 opcode) {
+void uPDcore::exec_ld(uint24 opcode) {
uint16 id = opcode >> 6; //immediate data
uint4 dst = opcode >> 0; //destination
@@ -251,94 +228,47 @@ void UPD77C25::exec_ld(uint24 opcode) {
}
}
-void UPD77C25::stack_push() {
+void uPDcore::stack_push() {
+ regs.stack[7] = regs.stack[6];
+ regs.stack[6] = regs.stack[5];
+ regs.stack[5] = regs.stack[4];
+ regs.stack[4] = regs.stack[3];
regs.stack[3] = regs.stack[2];
regs.stack[2] = regs.stack[1];
regs.stack[1] = regs.stack[0];
regs.stack[0] = regs.pc;
}
-void UPD77C25::stack_pull() {
+void uPDcore::stack_pull() {
regs.pc = regs.stack[0];
regs.stack[0] = regs.stack[1];
regs.stack[1] = regs.stack[2];
regs.stack[2] = regs.stack[3];
- regs.stack[3] = 0x000;
+ regs.stack[3] = regs.stack[4];
+ regs.stack[4] = regs.stack[5];
+ regs.stack[5] = regs.stack[6];
+ regs.stack[6] = regs.stack[7];
+ regs.stack[7] = 0x0000;
}
-uint8 UPD77C25::read(bool mode) {
- cpu.synchronize_coprocessor();
- if(mode == 0) return regs.sr >> 8;
+uPDcore::uPDcore(unsigned pcbits, unsigned rpbits, unsigned dpbits) {
+ programROMSize = 1 << pcbits;
+ dataROMSize = 1 << rpbits;
+ dataRAMSize = 1 << dpbits;
- if(regs.sr.drc == 0) {
- //16-bit
- if(regs.sr.drs == 0) {
- regs.sr.drs = 1;
- return regs.dr >> 0;
- } else {
- regs.sr.rqm = 0;
- regs.sr.drs = 0;
- return regs.dr >> 8;
- }
- } else {
- //8-bit
- regs.sr.rqm = 0;
- return regs.dr >> 0;
- }
+ programROM = new uint24[programROMSize];
+ dataROM = new uint16[dataROMSize];
+ dataRAM = new uint16[dataRAMSize];
+
+ regs.pc.mask = programROMSize - 1;
+ regs.rp.mask = dataROMSize - 1;
+ regs.dp.mask = dataRAMSize - 1;
}
-void UPD77C25::write(bool mode, uint8 data) {
- cpu.synchronize_coprocessor();
- if(mode == 0) return;
-
- if(regs.sr.drc == 0) {
- //16-bit
- if(regs.sr.drs == 0) {
- regs.sr.drs = 1;
- regs.dr = (regs.dr & 0xff00) | (data << 0);
- } else {
- regs.sr.rqm = 0;
- regs.sr.drs = 0;
- regs.dr = (data << 8) | (regs.dr & 0x00ff);
- }
- } else {
- //8-bit
- regs.sr.rqm = 0;
- regs.dr = (regs.dr & 0xff00) | (data << 0);
- }
+uPDcore::~uPDcore() {
+ delete[] programROM;
+ delete[] dataROM;
+ delete[] dataRAM;
}
-void UPD77C25::init() {
-}
-
-void UPD77C25::enable() {
-}
-
-void UPD77C25::power() {
- for(unsigned i = 0; i < 256; i++) dataRAM[i] = 0x0000;
- reset();
-}
-
-void UPD77C25::reset() {
- create(UPD77C25::Enter, 8 * 1024 * 1024); //8.192MHz
-
- regs.pc = 0x000;
- regs.stack[0] = 0x000;
- regs.stack[1] = 0x000;
- regs.stack[2] = 0x000;
- regs.stack[3] = 0x000;
- regs.flaga = 0x00;
- regs.flagb = 0x00;
- regs.sr = 0x0000;
- regs.rp = 0x3ff;
- regs.siack = 0;
- regs.soack = 0;
-}
-
-uint8 UPD77C25SR::read(unsigned) { return upd77c25.read(0); }
-void UPD77C25SR::write(unsigned, uint8 data) { upd77c25.write(0, data); }
-
-uint8 UPD77C25DR::read(unsigned) { return upd77c25.read(1); }
-void UPD77C25DR::write(unsigned, uint8 data) { upd77c25.write(1, data); }
-
}
diff --git a/bsnes/snes/chip/necdsp/core/core.hpp b/bsnes/snes/chip/necdsp/core/core.hpp
new file mode 100755
index 00000000..6c8a362d
--- /dev/null
+++ b/bsnes/snes/chip/necdsp/core/core.hpp
@@ -0,0 +1,26 @@
+class uPDcore {
+public:
+ #include "registers.hpp"
+
+ uint24 *programROM;
+ uint16 *dataROM;
+ uint16 *dataRAM;
+
+ unsigned programROMSize;
+ unsigned dataROMSize;
+ unsigned dataRAMSize;
+
+ void exec();
+ void exec_op(uint24 opcode);
+ void exec_rt(uint24 opcode);
+ void exec_jp(uint24 opcode);
+ void exec_ld(uint24 opcode);
+ void stack_push();
+ void stack_pull();
+
+ string disassemble(uint11 ip);
+
+ void serialize(serializer&);
+ uPDcore(unsigned pcbits, unsigned rpbits, unsigned dpbits);
+ ~uPDcore();
+};
diff --git a/bsnes/snes/chip/upd77c25/disassembler.cpp b/bsnes/snes/chip/necdsp/core/disassembler.cpp
similarity index 98%
rename from bsnes/snes/chip/upd77c25/disassembler.cpp
rename to bsnes/snes/chip/necdsp/core/disassembler.cpp
index 009bb2b1..d16f5bd7 100755
--- a/bsnes/snes/chip/upd77c25/disassembler.cpp
+++ b/bsnes/snes/chip/necdsp/core/disassembler.cpp
@@ -1,4 +1,6 @@
-string UPD77C25::disassemble(uint11 ip) {
+#ifdef UPDCORE_CPP
+
+string uPDcore::disassemble(uint11 ip) {
string output = { hex<3>(ip), " " };
uint24 opcode = programROM[ip];
uint2 type = opcode >> 22;
@@ -203,3 +205,5 @@ string UPD77C25::disassemble(uint11 ip) {
return output;
}
+
+#endif
diff --git a/bsnes/snes/chip/necdsp/core/registers.hpp b/bsnes/snes/chip/necdsp/core/registers.hpp
new file mode 100755
index 00000000..698f356c
--- /dev/null
+++ b/bsnes/snes/chip/necdsp/core/registers.hpp
@@ -0,0 +1,66 @@
+struct Pointer {
+ uint16 data;
+ uint16 mask;
+
+ inline operator unsigned() const {
+ return data;
+ }
+
+ inline unsigned operator=(unsigned d) {
+ return data = d & mask;
+ }
+};
+
+struct Flag {
+ bool s1, s0, c, z, ov1, ov0;
+
+ inline operator unsigned() const {
+ return (s1 << 5) + (s0 << 4) + (c << 3) + (z << 2) + (ov1 << 1) + (ov0 << 0);
+ }
+
+ inline unsigned operator=(unsigned d) {
+ s1 = d & 0x20; s0 = d & 0x10; c = d & 0x08; z = d & 0x04; ov1 = d & 0x02; ov0 = d & 0x01;
+ return d;
+ }
+};
+
+struct Status {
+ bool rqm, usf1, usf0, drs, dma, drc, soc, sic, ei, p1, p0;
+
+ inline operator unsigned() const {
+ return (rqm << 15) + (usf1 << 14) + (usf0 << 13) + (drs << 12)
+ + (dma << 11) + (drc << 10) + (soc << 9) + (sic << 8)
+ + (ei << 7) + (p1 << 1) + (p0 << 0);
+ }
+
+ inline unsigned operator=(unsigned d) {
+ rqm = d & 0x8000; usf1 = d & 0x4000; usf0 = d & 0x2000; drs = d & 0x1000;
+ dma = d & 0x0800; drc = d & 0x0400; soc = d & 0x0200; sic = d & 0x0100;
+ ei = d & 0x0080; p1 = d & 0x0002; p0 = d & 0x0001;
+ return d;
+ }
+};
+
+//11,11,10,8 and 14,14,11,11
+
+struct Regs {
+ Pointer pc; //program counter
+ Pointer rp; //ROM pointer
+ Pointer dp; //data pointer
+ uint16 stack[8]; //LIFO
+ int16 k;
+ int16 l;
+ int16 m;
+ int16 n;
+ int16 a; //accumulator
+ int16 b; //accumulator
+ Flag flaga;
+ Flag flagb;
+ uint16 tr; //temporary register
+ uint16 trb; //temporary register
+ Status sr; //status register
+ uint16 dr; //data register
+ bool siack;
+ bool soack;
+ uint16 idb;
+} regs;
diff --git a/bsnes/snes/chip/upd77c25/serialization.cpp b/bsnes/snes/chip/necdsp/core/serialization.cpp
similarity index 76%
rename from bsnes/snes/chip/upd77c25/serialization.cpp
rename to bsnes/snes/chip/necdsp/core/serialization.cpp
index 0f55d424..8128b40a 100755
--- a/bsnes/snes/chip/upd77c25/serialization.cpp
+++ b/bsnes/snes/chip/necdsp/core/serialization.cpp
@@ -1,12 +1,19 @@
-#ifdef UPD77C25_CPP
+#ifdef UPDCORE_CPP
-void UPD77C25::serialize(serializer &s) {
- s.array(dataRAM);
+void uPDcore::serialize(serializer &s) {
+ s.array(dataRAM, dataRAMSize);
+
+ s.integer(regs.pc.data);
+ s.integer(regs.pc.mask);
+
+ s.integer(regs.rp.data);
+ s.integer(regs.rp.mask);
+
+ s.integer(regs.dp.data);
+ s.integer(regs.dp.mask);
+
+ s.array(regs.stack);
- s.integer(regs.pc);
- for(unsigned n = 0; n < 4; n++) s.integer(regs.stack[n]);
- s.integer(regs.rp);
- s.integer(regs.dp);
s.integer(regs.k);
s.integer(regs.l);
s.integer(regs.m);
diff --git a/bsnes/snes/chip/necdsp/upd7725/upd7725.cpp b/bsnes/snes/chip/necdsp/upd7725/upd7725.cpp
new file mode 100755
index 00000000..72ceb44b
--- /dev/null
+++ b/bsnes/snes/chip/necdsp/upd7725/upd7725.cpp
@@ -0,0 +1,112 @@
+#include
+
+#define UPD7725_CPP
+namespace SNES {
+
+uPD7725 upd7725;
+uPD7725SR upd7725sr;
+uPD7725DR upd7725dr;
+
+void uPD7725::Enter() { upd7725.enter(); }
+
+void uPD7725::enter() {
+ while(true) {
+ if(scheduler.sync == Scheduler::SynchronizeMode::All) {
+ scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
+ }
+
+ uPDcore::exec();
+ step(1);
+ synchronize_cpu();
+ }
+}
+
+uint8 uPD7725::read(bool mode) {
+ cpu.synchronize_coprocessor();
+ if(mode == 0) return regs.sr >> 8;
+
+ if(regs.sr.drc == 0) {
+ //16-bit
+ if(regs.sr.drs == 0) {
+ regs.sr.drs = 1;
+ return regs.dr >> 0;
+ } else {
+ regs.sr.rqm = 0;
+ regs.sr.drs = 0;
+ return regs.dr >> 8;
+ }
+ } else {
+ //8-bit
+ regs.sr.rqm = 0;
+ return regs.dr >> 0;
+ }
+}
+
+void uPD7725::write(bool mode, uint8 data) {
+ cpu.synchronize_coprocessor();
+ if(mode == 0) return;
+
+ if(regs.sr.drc == 0) {
+ //16-bit
+ if(regs.sr.drs == 0) {
+ regs.sr.drs = 1;
+ regs.dr = (regs.dr & 0xff00) | (data << 0);
+ } else {
+ regs.sr.rqm = 0;
+ regs.sr.drs = 0;
+ regs.dr = (data << 8) | (regs.dr & 0x00ff);
+ }
+ } else {
+ //8-bit
+ regs.sr.rqm = 0;
+ regs.dr = (regs.dr & 0xff00) | (data << 0);
+ }
+}
+
+void uPD7725::init() {
+}
+
+void uPD7725::enable() {
+}
+
+void uPD7725::power() {
+ for(unsigned i = 0; i < 256; i++) dataRAM[i] = 0x0000;
+ reset();
+}
+
+void uPD7725::reset() {
+ create(uPD7725::Enter, 8 * 1024 * 1024); //8.192MHz
+
+ regs.pc = 0x000;
+ regs.stack[0] = 0x000;
+ regs.stack[1] = 0x000;
+ regs.stack[2] = 0x000;
+ regs.stack[3] = 0x000;
+ regs.flaga = 0x00;
+ regs.flagb = 0x00;
+ regs.sr = 0x0000;
+ regs.rp = 0x3ff;
+ regs.siack = 0;
+ regs.soack = 0;
+}
+
+void uPD7725::serialize(serializer &s) {
+ Coprocessor::serialize(s);
+ uPDcore::serialize(s);
+}
+
+uPD7725::uPD7725() : uPDcore(11, 10, 8) {
+ //NEC uPD7725:
+ //8.192 MIPS (8.192MHz / 1)
+ //11-bit ProgramROM (2048 x 24-bit) w/4-level stack
+ //10-bit DataROM (1024 x 16-bit)
+ // 8-bit DataRAM ( 256 x 16-bit)
+}
+
+uint8 uPD7725SR::read(unsigned) { return upd7725.read(0); }
+void uPD7725SR::write(unsigned, uint8 data) { upd7725.write(0, data); }
+
+uint8 uPD7725DR::read(unsigned) { return upd7725.read(1); }
+void uPD7725DR::write(unsigned, uint8 data) { upd7725.write(1, data); }
+
+}
diff --git a/bsnes/snes/chip/necdsp/upd7725/upd7725.hpp b/bsnes/snes/chip/necdsp/upd7725/upd7725.hpp
new file mode 100755
index 00000000..32943e46
--- /dev/null
+++ b/bsnes/snes/chip/necdsp/upd7725/upd7725.hpp
@@ -0,0 +1,33 @@
+class uPD7725 : public Coprocessor, public uPDcore {
+public:
+ static void Enter();
+ void enter();
+ void init();
+ void enable();
+ void power();
+ void reset();
+
+ void serialize(serializer&);
+ uPD7725();
+
+private:
+ uint8 read(bool mode);
+ void write(bool mode, uint8 data);
+
+ friend class uPD7725SR;
+ friend class uPD7725DR;
+};
+
+class uPD7725SR : public Memory {
+ uint8 read(unsigned addr);
+ void write(unsigned addr, uint8 data);
+};
+
+class uPD7725DR : public Memory {
+ uint8 read(unsigned addr);
+ void write(unsigned addr, uint8 data);
+};
+
+extern uPD7725 upd7725;
+extern uPD7725SR upd7725sr;
+extern uPD7725DR upd7725dr;
diff --git a/bsnes/snes/chip/necdsp/upd96050/upd96050.cpp b/bsnes/snes/chip/necdsp/upd96050/upd96050.cpp
new file mode 100755
index 00000000..efaaee51
--- /dev/null
+++ b/bsnes/snes/chip/necdsp/upd96050/upd96050.cpp
@@ -0,0 +1,94 @@
+#include
+
+#define UPD96050_CPP
+namespace SNES {
+
+uPD96050 upd96050;
+
+void uPD96050::Enter() { upd96050.enter(); }
+
+void uPD96050::enter() {
+ while(true) {
+ if(scheduler.sync == Scheduler::SynchronizeMode::All) {
+ scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
+ }
+
+ uPDcore::exec();
+ step(2);
+ synchronize_cpu();
+ }
+}
+
+uint8 uPD96050::read(unsigned addr) {
+ cpu.synchronize_coprocessor();
+ regs.sr.rqm = 0;
+
+ bool hi = addr & 1;
+ addr = (addr >> 1) & 2047;
+
+ if(hi == false) {
+ return dataRAM[addr] >> 0;
+ } else {
+ return dataRAM[addr] >> 8;
+ }
+}
+
+void uPD96050::write(unsigned addr, uint8 data) {
+ cpu.synchronize_coprocessor();
+ regs.sr.rqm = 0;
+
+ bool hi = addr & 1;
+ addr = (addr >> 1) & 2047;
+
+ if(hi == false) {
+ dataRAM[addr] = (dataRAM[addr] & 0xff00) | (data << 0);
+ } else {
+ dataRAM[addr] = (dataRAM[addr] & 0x00ff) | (data << 8);
+ }
+}
+
+void uPD96050::init() {
+}
+
+void uPD96050::enable() {
+}
+
+void uPD96050::power() {
+ for(unsigned i = 0; i < 2048; i++) dataRAM[i] = 0x0000;
+ reset();
+}
+
+void uPD96050::reset() {
+ create(uPD96050::Enter, 20 * 1000 * 1000); //20MHz
+
+ regs.pc = 0x0000;
+ regs.stack[0] = 0x0000;
+ regs.stack[1] = 0x0000;
+ regs.stack[2] = 0x0000;
+ regs.stack[3] = 0x0000;
+ regs.stack[4] = 0x0000;
+ regs.stack[5] = 0x0000;
+ regs.stack[6] = 0x0000;
+ regs.stack[7] = 0x0000;
+ regs.flaga = 0x00;
+ regs.flagb = 0x00;
+ regs.sr = 0x0000;
+ regs.rp = 0x03ff;
+ regs.siack = 0;
+ regs.soack = 0;
+}
+
+void uPD96050::serialize(serializer &s) {
+ Coprocessor::serialize(s);
+ uPDcore::serialize(s);
+}
+
+uPD96050::uPD96050() : uPDcore(14, 11, 11) {
+ //NEC uPD96050:
+ //10MIPS (20MHz / 2)
+ //14-bit ProgramROM (16384 x 24-bit) w/8-level stack
+ //11-bit DataROM ( 2048 x 16-bit)
+ //11-bit DataRAM ( 2048 x 16-bit) w/battery backup
+}
+
+}
diff --git a/bsnes/snes/chip/necdsp/upd96050/upd96050.hpp b/bsnes/snes/chip/necdsp/upd96050/upd96050.hpp
new file mode 100755
index 00000000..21f1f5a3
--- /dev/null
+++ b/bsnes/snes/chip/necdsp/upd96050/upd96050.hpp
@@ -0,0 +1,17 @@
+class uPD96050 : public Coprocessor, public uPDcore, public Memory {
+public:
+ static void Enter();
+ void enter();
+ void init();
+ void enable();
+ void power();
+ void reset();
+
+ uint8 read(unsigned addr);
+ void write(unsigned addr, uint8 data);
+
+ void serialize(serializer&);
+ uPD96050();
+};
+
+extern uPD96050 upd96050;
diff --git a/bsnes/snes/chip/upd77c25/upd77c25.hpp b/bsnes/snes/chip/upd77c25/upd77c25.hpp
deleted file mode 100755
index 782661f4..00000000
--- a/bsnes/snes/chip/upd77c25/upd77c25.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-class UPD77C25 : public Coprocessor {
-public:
- static void Enter();
- void enter();
- void init();
- void enable();
- void power();
- void reset();
-
- void serialize(serializer &s);
-
- uint24 programROM[2048];
- uint16 dataROM[1024];
- uint16 dataRAM[256];
-
- string disassemble(uint11 ip);
-
-private:
- struct Flag {
- bool s1, s0, c, z, ov1, ov0;
-
- inline operator unsigned() const {
- return (s1 << 5) + (s0 << 4) + (c << 3) + (z << 2) + (ov1 << 1) + (ov0 << 0);
- }
-
- inline unsigned operator=(unsigned d) {
- s1 = d & 0x20; s0 = d & 0x10; c = d & 0x08; z = d & 0x04; ov1 = d & 0x02; ov0 = d & 0x01;
- return d;
- }
- };
-
- struct Status {
- bool rqm, usf1, usf0, drs, dma, drc, soc, sic, ei, p1, p0;
-
- inline operator unsigned() const {
- return (rqm << 15) + (usf1 << 14) + (usf0 << 13) + (drs << 12)
- + (dma << 11) + (drc << 10) + (soc << 9) + (sic << 8)
- + (ei << 7) + (p1 << 1) + (p0 << 0);
- }
-
- inline unsigned operator=(unsigned d) {
- rqm = d & 0x8000; usf1 = d & 0x4000; usf0 = d & 0x2000; drs = d & 0x1000;
- dma = d & 0x0800; drc = d & 0x0400; soc = d & 0x0200; sic = d & 0x0100;
- ei = d & 0x0080; p1 = d & 0x0002; p0 = d & 0x0001;
- return d;
- }
- };
-
- struct Regs {
- uint11 pc; //program counter
- uint11 stack[4]; //LIFO
- uint10 rp; //ROM pointer
- uint8 dp; //data pointer
- int16 k;
- int16 l;
- int16 m;
- int16 n;
- int16 a; //accumulator
- int16 b; //accumulator
- Flag flaga;
- Flag flagb;
- uint16 tr; //temporary register
- uint16 trb; //temporary register
- Status sr; //status register
- uint16 dr; //data register
- bool siack;
- bool soack;
- uint16 idb;
- } regs;
-
- void exec_op(uint24 opcode);
- void exec_rt(uint24 opcode);
- void exec_jp(uint24 opcode);
- void exec_ld(uint24 opcode);
-
- void stack_push();
- void stack_pull();
-
- uint8 read(bool mode);
- void write(bool mode, uint8 data);
-
- friend class UPD77C25SR;
- friend class UPD77C25DR;
-};
-
-class UPD77C25SR : public Memory {
- uint8 read(unsigned addr);
- void write(unsigned addr, uint8 data);
-};
-
-class UPD77C25DR : public Memory {
- uint8 read(unsigned addr);
- void write(unsigned addr, uint8 data);
-};
-
-extern UPD77C25 upd77c25;
-extern UPD77C25SR upd77c25sr;
-extern UPD77C25DR upd77c25dr;
diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp
index 12b51e88..cefda2d6 100755
--- a/bsnes/snes/snes.hpp
+++ b/bsnes/snes/snes.hpp
@@ -1,7 +1,7 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
- static const char Version[] = "073.04";
+ static const char Version[] = "073.05";
static const unsigned SerializerVersion = 16;
}
}
diff --git a/bsnes/snes/system/serialization.cpp b/bsnes/snes/system/serialization.cpp
index ed40fff9..aa0b21b0 100755
--- a/bsnes/snes/system/serialization.cpp
+++ b/bsnes/snes/system/serialization.cpp
@@ -60,7 +60,8 @@ void System::serialize_all(serializer &s) {
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
if(cartridge.has_superfx()) superfx.serialize(s);
if(cartridge.has_sa1()) sa1.serialize(s);
- if(cartridge.has_upd77c25()) upd77c25.serialize(s);
+ if(cartridge.has_upd7725()) upd7725.serialize(s);
+ if(cartridge.has_upd96050()) upd96050.serialize(s);
if(cartridge.has_srtc()) srtc.serialize(s);
if(cartridge.has_sdd1()) sdd1.serialize(s);
if(cartridge.has_spc7110()) spc7110.serialize(s);
diff --git a/bsnes/snes/system/system.cpp b/bsnes/snes/system/system.cpp
index 9df2fbf7..61c319d0 100755
--- a/bsnes/snes/system/system.cpp
+++ b/bsnes/snes/system/system.cpp
@@ -71,7 +71,8 @@ void System::init(Interface *interface_) {
icd2.init();
superfx.init();
sa1.init();
- upd77c25.init();
+ upd7725.init();
+ upd96050.init();
bsxbase.init();
bsxcart.init();
bsxflash.init();
@@ -123,7 +124,8 @@ void System::power() {
if(cartridge.has_superfx()) superfx.enable();
if(cartridge.has_sa1()) sa1.enable();
- if(cartridge.has_upd77c25()) upd77c25.enable();
+ if(cartridge.has_upd7725()) upd7725.enable();
+ if(cartridge.has_upd96050()) upd96050.enable();
if(cartridge.has_srtc()) srtc.enable();
if(cartridge.has_sdd1()) sdd1.enable();
if(cartridge.has_spc7110()) spc7110.enable();
@@ -147,7 +149,8 @@ void System::power() {
if(cartridge.has_superfx()) superfx.power();
if(cartridge.has_sa1()) sa1.power();
- if(cartridge.has_upd77c25()) upd77c25.power();
+ if(cartridge.has_upd7725()) upd7725.power();
+ if(cartridge.has_upd96050()) upd96050.power();
if(cartridge.has_srtc()) srtc.power();
if(cartridge.has_sdd1()) sdd1.power();
if(cartridge.has_spc7110()) spc7110.power();
@@ -162,7 +165,8 @@ void System::power() {
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) cpu.coprocessors.append(&icd2);
if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx);
if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1);
- if(cartridge.has_upd77c25()) cpu.coprocessors.append(&upd77c25);
+ if(cartridge.has_upd7725()) cpu.coprocessors.append(&upd7725);
+ if(cartridge.has_upd96050()) cpu.coprocessors.append(&upd96050);
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
if(cartridge.has_serial()) cpu.coprocessors.append(&serial);
@@ -187,7 +191,8 @@ void System::reset() {
if(cartridge.has_superfx()) superfx.reset();
if(cartridge.has_sa1()) sa1.reset();
- if(cartridge.has_upd77c25()) upd77c25.reset();
+ if(cartridge.has_upd7725()) upd7725.reset();
+ if(cartridge.has_upd96050()) upd96050.reset();
if(cartridge.has_srtc()) srtc.reset();
if(cartridge.has_sdd1()) sdd1.reset();
if(cartridge.has_spc7110()) spc7110.reset();
@@ -202,7 +207,8 @@ void System::reset() {
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) cpu.coprocessors.append(&icd2);
if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx);
if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1);
- if(cartridge.has_upd77c25()) cpu.coprocessors.append(&upd77c25);
+ if(cartridge.has_upd7725()) cpu.coprocessors.append(&upd7725);
+ if(cartridge.has_upd96050()) cpu.coprocessors.append(&upd96050);
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
if(cartridge.has_serial()) cpu.coprocessors.append(&serial);