diff --git a/bsnes/nall/snes/cartridge.hpp b/bsnes/nall/snes/cartridge.hpp
index e3c0e0c55..9d5914880 100755
--- a/bsnes/nall/snes/cartridge.hpp
+++ b/bsnes/nall/snes/cartridge.hpp
@@ -158,6 +158,17 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
xml << " \n";
xml << " \n";
xml << " \n";
+ } else if(has_cx4) {
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
+ xml << " \n";
} else if(has_spc7110) {
xml << " \n";
xml << " \n";
@@ -399,13 +410,6 @@ SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
xml << " \n";
}
- if(has_cx4) {
- xml << " \n";
- xml << " \n";
- xml << " \n";
- xml << " \n";
- }
-
if(has_dsp1) {
xml << " \n";
if(dsp1_mapper == DSP1LoROM1MB) {
diff --git a/bsnes/snes/Makefile b/bsnes/snes/Makefile
index 3034da9dc..341fc7c1d 100755
--- a/bsnes/snes/Makefile
+++ b/bsnes/snes/Makefile
@@ -2,8 +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-nss snes-icd2 snes-superfx snes-sa1 snes-necdsp
-snes_objects += snes-bsx snes-srtc snes-sdd1 snes-spc7110 snes-cx4
+snes_objects += snes-nss snes-icd2 snes-superfx snes-sa1 snes-necdsp snes-hitachidsp
+snes_objects += snes-bsx snes-srtc snes-sdd1 snes-spc7110
snes_objects += snes-obc1 snes-st0018 snes-sufamiturbo
snes_objects += snes-msu1 snes-serial snes-link
objects += $(snes_objects)
@@ -44,11 +44,11 @@ obj/snes-icd2.o : $(snes)/chip/icd2/icd2.cpp $(call rwildcard,$(snes)/chip
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-necdsp.o : $(snes)/chip/necdsp/necdsp.cpp $(call rwildcard,$(snes)/chip/necdsp/)
+obj/snes-hitachidsp.o : $(snes)/chip/hitachidsp/hitachidsp.cpp $(call rwildcard,$(snes)/chip/hitachidsp/)
obj/snes-bsx.o : $(snes)/chip/bsx/bsx.cpp $(call rwildcard,$(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/*
obj/snes-spc7110.o : $(snes)/chip/spc7110/spc7110.cpp $(snes)/chip/spc7110/*
-obj/snes-cx4.o : $(snes)/chip/cx4/cx4.cpp $(snes)/chip/cx4/*
obj/snes-obc1.o : $(snes)/chip/obc1/obc1.cpp $(snes)/chip/obc1/*
obj/snes-st0018.o : $(snes)/chip/st0018/st0018.cpp $(snes)/chip/st0018/*
obj/snes-sufamiturbo.o: $(snes)/chip/sufamiturbo/sufamiturbo.cpp $(snes)/chip/sufamiturbo/*
diff --git a/bsnes/snes/cartridge/cartridge.cpp b/bsnes/snes/cartridge/cartridge.cpp
index 3908cb9d4..571b0e2c2 100755
--- a/bsnes/snes/cartridge/cartridge.cpp
+++ b/bsnes/snes/cartridge/cartridge.cpp
@@ -21,11 +21,11 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
has_superfx = false;
has_sa1 = false;
has_necdsp = false;
+ has_hitachidsp = false;
has_srtc = false;
has_sdd1 = false;
has_spc7110 = false;
has_spc7110rtc = false;
- has_cx4 = false;
has_obc1 = false;
has_st0018 = false;
has_msu1 = false;
diff --git a/bsnes/snes/cartridge/cartridge.hpp b/bsnes/snes/cartridge/cartridge.hpp
index f742c5a64..42d2948a4 100755
--- a/bsnes/snes/cartridge/cartridge.hpp
+++ b/bsnes/snes/cartridge/cartridge.hpp
@@ -38,11 +38,11 @@ public:
readonly has_superfx;
readonly has_sa1;
readonly has_necdsp;
+ readonly has_hitachidsp;
readonly has_srtc;
readonly has_sdd1;
readonly has_spc7110;
readonly has_spc7110rtc;
- readonly has_cx4;
readonly has_obc1;
readonly has_st0018;
readonly has_msu1;
@@ -105,13 +105,13 @@ private:
void xml_parse_superfx(xml_element&);
void xml_parse_sa1(xml_element&);
void xml_parse_necdsp(xml_element&);
+ void xml_parse_hitachidsp(xml_element&);
void xml_parse_bsx(xml_element&);
void xml_parse_sufamiturbo(xml_element&);
void xml_parse_supergameboy(xml_element&);
void xml_parse_srtc(xml_element&);
void xml_parse_sdd1(xml_element&);
void xml_parse_spc7110(xml_element&);
- void xml_parse_cx4(xml_element&);
void xml_parse_obc1(xml_element&);
void xml_parse_setarisc(xml_element&);
void xml_parse_msu1(xml_element&);
diff --git a/bsnes/snes/cartridge/xml.cpp b/bsnes/snes/cartridge/xml.cpp
index 5a15b3eb2..4af339579 100755
--- a/bsnes/snes/cartridge/xml.cpp
+++ b/bsnes/snes/cartridge/xml.cpp
@@ -40,12 +40,12 @@ void Cartridge::parse_xml_cartridge(const char *data) {
if(node.name == "superfx") xml_parse_superfx(node);
if(node.name == "sa1") xml_parse_sa1(node);
if(node.name == "necdsp") xml_parse_necdsp(node);
+ if(node.name == "hitachidsp") xml_parse_hitachidsp(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);
if(node.name == "sdd1") xml_parse_sdd1(node);
if(node.name == "spc7110") xml_parse_spc7110(node);
- if(node.name == "cx4") xml_parse_cx4(node);
if(node.name == "obc1") xml_parse_obc1(node);
if(node.name == "setarisc") xml_parse_setarisc(node);
if(node.name == "msu1") xml_parse_msu1(node);
@@ -372,6 +372,81 @@ void Cartridge::xml_parse_necdsp(xml_element &root) {
}
}
+void Cartridge::xml_parse_hitachidsp(xml_element &root) {
+ has_hitachidsp = true;
+ hitachidsp.frequency = 20000000;
+
+ for(unsigned n = 0; n < 1024; n++) hitachidsp.dataROM[n] = 0x000000;
+
+ string program, sha256;
+
+ foreach(attr, root.attribute) {
+ if(attr.name == "frequency") {
+ hitachidsp.frequency = decimal(attr.content);
+ } else if(attr.name == "program") {
+ program = attr.content;
+ } else if(attr.name == "sha256") {
+ sha256 = attr.content;
+ }
+ }
+
+ string path = { dir(system.interface->path(Slot::Base, ".dsp")), program };
+ file fp;
+ if(fp.open(path, file::mode::read) == false) {
+ system.interface->message({ "Warning: Hitachi DSP program ", program, " is missing." });
+ } else if(fp.size() != 1024 * 3) {
+ system.interface->message({ "Warning: Hitachi DSP program ", program, " is of the wrong file size." });
+ fp.close();
+ } else {
+ for(unsigned n = 0; n < 1024; n++) hitachidsp.dataROM[n] = fp.readl(3);
+
+ if(sha256 != "") {
+ //XML file specified SHA256 sum for program. Verify file matches the hash.
+ fp.seek(0);
+ uint8 data[3072];
+ fp.read(data, 3072);
+
+ sha256_ctx sha;
+ uint8 hash[32];
+ sha256_init(&sha);
+ sha256_chunk(&sha, data, 3072);
+ sha256_final(&sha);
+ sha256_hash(&sha, hash);
+
+ string filehash;
+ foreach(n, hash) filehash.append(hex<2>(n));
+
+ if(sha256 != filehash) {
+ system.interface->message({ "Warning: Hitachi DSP program ", program, " SHA256 sum is incorrect." });
+ }
+ }
+
+ fp.close();
+ }
+
+ foreach(node, root.element) {
+ if(node.name == "rom") foreach(leaf, node.element) {
+ if(leaf.name == "map") {
+ Mapping m({ &HitachiDSP::rom_read, &hitachidsp }, { &HitachiDSP::rom_write, &hitachidsp });
+ foreach(attr, leaf.attribute) {
+ if(attr.name == "address") xml_parse_address(m, attr.content);
+ if(attr.name == "mode") xml_parse_mode(m, attr.content);
+ if(attr.name == "offset") m.offset = hex(attr.content);
+ if(attr.name == "size") m.size = hex(attr.content);
+ }
+ mapping.append(m);
+ }
+ }
+ if(node.name == "mmio") foreach(leaf, node.element) {
+ Mapping m({ &HitachiDSP::dsp_read, &hitachidsp }, { &HitachiDSP::dsp_write, &hitachidsp });
+ foreach(attr, leaf.attribute) {
+ if(attr.name == "address") xml_parse_address(m, attr.content);
+ }
+ mapping.append(m);
+ }
+ }
+}
+
void Cartridge::xml_parse_bsx(xml_element &root) {
if(mode != Mode::BsxSlotted && mode != Mode::Bsx) return;
@@ -580,20 +655,6 @@ void Cartridge::xml_parse_spc7110(xml_element &root) {
}
}
-void Cartridge::xml_parse_cx4(xml_element &root) {
- has_cx4 = true;
-
- foreach(node, root.element) {
- if(node.name == "map") {
- Mapping m({ &Cx4::read, &cx4 }, { &Cx4::write, &cx4 });
- foreach(attr, node.attribute) {
- if(attr.name == "address") xml_parse_address(m, attr.content);
- }
- mapping.append(m);
- }
- }
-}
-
void Cartridge::xml_parse_obc1(xml_element &root) {
has_obc1 = true;
diff --git a/bsnes/snes/chip/chip.hpp b/bsnes/snes/chip/chip.hpp
index 85f13b8b1..d3d1ad2cd 100755
--- a/bsnes/snes/chip/chip.hpp
+++ b/bsnes/snes/chip/chip.hpp
@@ -8,11 +8,11 @@ struct Coprocessor : Processor {
#include
#include
#include
+#include
#include
#include
#include
#include
-#include
#include
#include
#include
diff --git a/bsnes/snes/chip/cx4/cx4.cpp b/bsnes/snes/chip/cx4/cx4.cpp
deleted file mode 100755
index 16630f479..000000000
--- a/bsnes/snes/chip/cx4/cx4.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-//=============
-//Cx4 emulation
-//=============
-//Used in Rockman X2/X3 (Megaman X2/X3)
-//Portions (c) anomie, Overload, zsKnight, Nach, byuu
-
-#include
-
-#define CX4_CPP
-namespace SNES {
-
-Cx4 cx4;
-
-#include "serialization.cpp"
-#include "data.cpp"
-#include "functions.cpp"
-#include "oam.cpp"
-#include "opcodes.cpp"
-
-void Cx4::init() {
-}
-
-void Cx4::load() {
-}
-
-void Cx4::unload() {
-}
-
-uint32 Cx4::ldr(uint8 r) {
- uint16 addr = 0x0080 + (r * 3);
- return (reg[addr + 0] << 0)
- | (reg[addr + 1] << 8)
- | (reg[addr + 2] << 16);
-}
-
-void Cx4::str(uint8 r, uint32 data) {
- uint16 addr = 0x0080 + (r * 3);
- reg[addr + 0] = (data >> 0);
- reg[addr + 1] = (data >> 8);
- reg[addr + 2] = (data >> 16);
-}
-
-void Cx4::mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh) {
- int64 rx = x & 0xffffff;
- int64 ry = y & 0xffffff;
- if(rx & 0x800000)rx |= ~0x7fffff;
- if(ry & 0x800000)ry |= ~0x7fffff;
-
- rx *= ry;
-
- rl = (rx) & 0xffffff;
- rh = (rx >> 24) & 0xffffff;
-}
-
-uint32 Cx4::sin(uint32 rx) {
- r0 = rx & 0x1ff;
- if(r0 & 0x100)r0 ^= 0x1ff;
- if(r0 & 0x080)r0 ^= 0x0ff;
- if(rx & 0x100) {
- return sin_table[r0 + 0x80];
- } else {
- return sin_table[r0];
- }
-}
-
-uint32 Cx4::cos(uint32 rx) {
- return sin(rx + 0x080);
-}
-
-void Cx4::immediate_reg(uint32 start) {
- r0 = ldr(0);
- for(uint32 i = start; i < 48; i++) {
- if((r0 & 0x0fff) < 0x0c00) {
- ram[r0 & 0x0fff] = immediate_data[i];
- }
- r0++;
- }
- str(0, r0);
-}
-
-void Cx4::transfer_data() {
- uint32 src;
- uint16 dest, count;
-
- src = (reg[0x40]) | (reg[0x41] << 8) | (reg[0x42] << 16);
- count = (reg[0x43]) | (reg[0x44] << 8);
- dest = (reg[0x45]) | (reg[0x46] << 8);
-
- for(uint32 i=0;i> 2;
- return;
- }
-
- switch(data) {
- case 0x00: op00(); break;
- case 0x01: op01(); break;
- case 0x05: op05(); break;
- case 0x0d: op0d(); break;
- case 0x10: op10(); break;
- case 0x13: op13(); break;
- case 0x15: op15(); break;
- case 0x1f: op1f(); break;
- case 0x22: op22(); break;
- case 0x25: op25(); break;
- case 0x2d: op2d(); break;
- case 0x40: op40(); break;
- case 0x54: op54(); break;
- case 0x5c: op5c(); break;
- case 0x5e: op5e(); break;
- case 0x60: op60(); break;
- case 0x62: op62(); break;
- case 0x64: op64(); break;
- case 0x66: op66(); break;
- case 0x68: op68(); break;
- case 0x6a: op6a(); break;
- case 0x6c: op6c(); break;
- case 0x6e: op6e(); break;
- case 0x70: op70(); break;
- case 0x72: op72(); break;
- case 0x74: op74(); break;
- case 0x76: op76(); break;
- case 0x78: op78(); break;
- case 0x7a: op7a(); break;
- case 0x7c: op7c(); break;
- case 0x89: op89(); break;
- }
- }
-}
-
-void Cx4::writeb(uint16 addr, uint8 data) {
- write(addr, data);
-}
-
-void Cx4::writew(uint16 addr, uint16 data) {
- write(addr + 0, data >> 0);
- write(addr + 1, data >> 8);
-}
-
-void Cx4::writel(uint16 addr, uint32 data) {
- write(addr + 0, data >> 0);
- write(addr + 1, data >> 8);
- write(addr + 2, data >> 16);
-}
-
-uint8 Cx4::read(unsigned addr) {
- addr &= 0x1fff;
-
- if(addr < 0x0c00) {
- return ram[addr];
- }
-
- if(addr >= 0x1f00) {
- return reg[addr & 0xff];
- }
-
- return cpu.regs.mdr;
-}
-
-uint8 Cx4::readb(uint16 addr) {
- return read(addr);
-}
-
-uint16 Cx4::readw(uint16 addr) {
- return read(addr) | (read(addr + 1) << 8);
-}
-
-uint32 Cx4::readl(uint16 addr) {
- return read(addr) | (read(addr + 1) << 8) + (read(addr + 2) << 16);
-}
-
-void Cx4::power() {
- reset();
-}
-
-void Cx4::reset() {
- memset(ram, 0, 0x0c00);
- memset(reg, 0, 0x0100);
-}
-
-};
diff --git a/bsnes/snes/chip/cx4/cx4.hpp b/bsnes/snes/chip/cx4/cx4.hpp
deleted file mode 100755
index eb95527ca..000000000
--- a/bsnes/snes/chip/cx4/cx4.hpp
+++ /dev/null
@@ -1,96 +0,0 @@
-class Cx4 {
-public:
- void init();
- void load();
- void unload();
- void power();
- void reset();
-
- uint8 read(unsigned addr);
- void write(unsigned addr, uint8 data);
-
- void serialize(serializer&);
-
-private:
- uint8 ram[0x0c00];
- uint8 reg[0x0100];
- uint32 r0, r1, r2, r3, r4, r5, r6, r7,
- r8, r9, r10, r11, r12, r13, r14, r15;
-
- static const uint8 immediate_data[48];
- static const uint16 wave_data[40];
- static const uint32 sin_table[256];
-
- static const int16 SinTable[512];
- static const int16 CosTable[512];
-
- int16 C4WFXVal, C4WFYVal, C4WFZVal, C4WFX2Val, C4WFY2Val, C4WFDist, C4WFScale;
- int16 C41FXVal, C41FYVal, C41FAngleRes, C41FDist, C41FDistVal;
-
- void C4TransfWireFrame();
- void C4TransfWireFrame2();
- void C4CalcWireFrame();
- void C4DrawLine(int32 X1, int32 Y1, int16 Z1, int32 X2, int32 Y2, int16 Z2, uint8 Color);
- void C4DrawWireFrame();
- void C4DoScaleRotate(int row_padding);
-
-public:
- uint32 ldr(uint8 r);
- void str(uint8 r, uint32 data);
- void mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh);
- uint32 sin(uint32 rx);
- uint32 cos(uint32 rx);
-
- void transfer_data();
- void immediate_reg(uint32 num);
-
- void op00_00();
- void op00_03();
- void op00_05();
- void op00_07();
- void op00_08();
- void op00_0b();
- void op00_0c();
-
- void op00();
- void op01();
- void op05();
- void op0d();
- void op10();
- void op13();
- void op15();
- void op1f();
- void op22();
- void op25();
- void op2d();
- void op40();
- void op54();
- void op5c();
- void op5e();
- void op60();
- void op62();
- void op64();
- void op66();
- void op68();
- void op6a();
- void op6c();
- void op6e();
- void op70();
- void op72();
- void op74();
- void op76();
- void op78();
- void op7a();
- void op7c();
- void op89();
-
- uint8 readb(uint16 addr);
- uint16 readw(uint16 addr);
- uint32 readl(uint16 addr);
-
- void writeb(uint16 addr, uint8 data);
- void writew(uint16 addr, uint16 data);
- void writel(uint16 addr, uint32 data);
-};
-
-extern Cx4 cx4;
diff --git a/bsnes/snes/chip/cx4/data.cpp b/bsnes/snes/chip/cx4/data.cpp
deleted file mode 100755
index 8538f6026..000000000
--- a/bsnes/snes/chip/cx4/data.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-#ifdef CX4_CPP
-
-const uint8 Cx4::immediate_data[48] = {
- 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0xff, 0xff, 0x7f,
- 0x00, 0x80, 0x00, 0xff, 0x7f, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff,
- 0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0xfe, 0x00
-};
-
-const uint16 Cx4::wave_data[40] = {
- 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e,
- 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020a, 0x020c, 0x020e,
- 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e,
- 0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060a, 0x060c, 0x060e,
- 0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080a, 0x080c, 0x080e
-};
-
-const uint32 Cx4::sin_table[256] = {
- 0x000000, 0x000324, 0x000648, 0x00096c, 0x000c8f, 0x000fb2, 0x0012d5, 0x0015f6,
- 0x001917, 0x001c37, 0x001f56, 0x002273, 0x002590, 0x0028aa, 0x002bc4, 0x002edb,
- 0x0031f1, 0x003505, 0x003817, 0x003b26, 0x003e33, 0x00413e, 0x004447, 0x00474d,
- 0x004a50, 0x004d50, 0x00504d, 0x005347, 0x00563e, 0x005931, 0x005c22, 0x005f0e,
- 0x0061f7, 0x0064dc, 0x0067bd, 0x006a9b, 0x006d74, 0x007049, 0x007319, 0x0075e5,
- 0x0078ad, 0x007b70, 0x007e2e, 0x0080e7, 0x00839c, 0x00864b, 0x0088f5, 0x008b9a,
- 0x008e39, 0x0090d3, 0x009368, 0x0095f6, 0x00987f, 0x009b02, 0x009d7f, 0x009ff6,
- 0x00a267, 0x00a4d2, 0x00a736, 0x00a994, 0x00abeb, 0x00ae3b, 0x00b085, 0x00b2c8,
- 0x00b504, 0x00b73a, 0x00b968, 0x00bb8f, 0x00bdae, 0x00bfc7, 0x00c1d8, 0x00c3e2,
- 0x00c5e4, 0x00c7de, 0x00c9d1, 0x00cbbb, 0x00cd9f, 0x00cf7a, 0x00d14d, 0x00d318,
- 0x00d4db, 0x00d695, 0x00d848, 0x00d9f2, 0x00db94, 0x00dd2d, 0x00debe, 0x00e046,
- 0x00e1c5, 0x00e33c, 0x00e4aa, 0x00e60f, 0x00e76b, 0x00e8bf, 0x00ea09, 0x00eb4b,
- 0x00ec83, 0x00edb2, 0x00eed8, 0x00eff5, 0x00f109, 0x00f213, 0x00f314, 0x00f40b,
- 0x00f4fa, 0x00f5de, 0x00f6ba, 0x00f78b, 0x00f853, 0x00f912, 0x00f9c7, 0x00fa73,
- 0x00fb14, 0x00fbac, 0x00fc3b, 0x00fcbf, 0x00fd3a, 0x00fdab, 0x00fe13, 0x00fe70,
- 0x00fec4, 0x00ff0e, 0x00ff4e, 0x00ff84, 0x00ffb1, 0x00ffd3, 0x00ffec, 0x00fffb,
- 0x000000, 0xfffcdb, 0xfff9b7, 0xfff693, 0xfff370, 0xfff04d, 0xffed2a, 0xffea09,
- 0xffe6e8, 0xffe3c8, 0xffe0a9, 0xffdd8c, 0xffda6f, 0xffd755, 0xffd43b, 0xffd124,
- 0xffce0e, 0xffcafa, 0xffc7e8, 0xffc4d9, 0xffc1cc, 0xffbec1, 0xffbbb8, 0xffb8b2,
- 0xffb5af, 0xffb2af, 0xffafb2, 0xffacb8, 0xffa9c1, 0xffa6ce, 0xffa3dd, 0xffa0f1,
- 0xff9e08, 0xff9b23, 0xff9842, 0xff9564, 0xff928b, 0xff8fb6, 0xff8ce6, 0xff8a1a,
- 0xff8752, 0xff848f, 0xff81d1, 0xff7f18, 0xff7c63, 0xff79b4, 0xff770a, 0xff7465,
- 0xff71c6, 0xff6f2c, 0xff6c97, 0xff6a09, 0xff6780, 0xff64fd, 0xff6280, 0xff6009,
- 0xff5d98, 0xff5b2d, 0xff58c9, 0xff566b, 0xff5414, 0xff51c4, 0xff4f7a, 0xff4d37,
- 0xff4afb, 0xff48c5, 0xff4697, 0xff4470, 0xff4251, 0xff4038, 0xff3e27, 0xff3c1e,
- 0xff3a1b, 0xff3821, 0xff362e, 0xff3444, 0xff3260, 0xff3085, 0xff2eb2, 0xff2ce7,
- 0xff2b24, 0xff296a, 0xff27b7, 0xff260d, 0xff246b, 0xff22d2, 0xff2141, 0xff1fb9,
- 0xff1e3a, 0xff1cc3, 0xff1b55, 0xff19f0, 0xff1894, 0xff1740, 0xff15f6, 0xff14b4,
- 0xff137c, 0xff124d, 0xff1127, 0xff100a, 0xff0ef6, 0xff0dec, 0xff0ceb, 0xff0bf4,
- 0xff0b05, 0xff0a21, 0xff0945, 0xff0874, 0xff07ac, 0xff06ed, 0xff0638, 0xff058d,
- 0xff04eb, 0xff0453, 0xff03c4, 0xff0340, 0xff02c5, 0xff0254, 0xff01ec, 0xff018f,
- 0xff013b, 0xff00f1, 0xff00b1, 0xff007b, 0xff004e, 0xff002c, 0xff0013, 0xff0004
-};
-
-const int16 Cx4::SinTable[512] = {
- 0, 402, 804, 1206, 1607, 2009, 2410, 2811,
- 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
- 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
- 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
- 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
- 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
- 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
- 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
- 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
- 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
- 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
- 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
- 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
- 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
- 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
- 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765,
- 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
- 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
- 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
- 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
- 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
- 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
- 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
- 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
- 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
- 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
- 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
- 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
- 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
- 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
- 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
- 3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
- 0, -402, -804, -1206, -1607, -2009, -2410, -2811,
- -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
- -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
- -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
- -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
- -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
- -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
- -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
- -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
- -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
- -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
- -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
- -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
- -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
- -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
- -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
- -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
- -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
- -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
- -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
- -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
- -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
- -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
- -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
- -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
- -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
- -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
- -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
- -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
- -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
- -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
- -3211, -2811, -2410, -2009, -1607, -1206, -804, -402
-};
-
-const int16 Cx4::CosTable[512] = {
- 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
- 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
- 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
- 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
- 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
- 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
- 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
- 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
- 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
- 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
- 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
- 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
- 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
- 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
- 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
- 3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
- 0, -402, -804, -1206, -1607, -2009, -2410, -2811,
- -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
- -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
- -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
- -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
- -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
- -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
- -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
- -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
- -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
- -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
- -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
- -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
- -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
- -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
- -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
- -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
- -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
- -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
- -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
- -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
- -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
- -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
- -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
- -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
- -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
- -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
- -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
- -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
- -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
- -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
- -3211, -2811, -2410, -2009, -1607, -1206, -804, -402,
- 0, 402, 804, 1206, 1607, 2009, 2410, 2811,
- 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
- 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
- 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
- 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
- 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
- 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
- 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
- 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
- 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
- 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
- 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
- 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
- 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
- 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
- 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765
-};
-
-#endif
diff --git a/bsnes/snes/chip/cx4/functions.cpp b/bsnes/snes/chip/cx4/functions.cpp
deleted file mode 100755
index 7466ffb81..000000000
--- a/bsnes/snes/chip/cx4/functions.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-#ifdef CX4_CPP
-
-#include
-#define Tan(a) (CosTable[a] ? ((((int32)SinTable[a]) << 16) / CosTable[a]) : 0x80000000)
-#define sar(b, n) ((b) >> (n))
-#ifdef PI
-#undef PI
-#endif
-#define PI 3.1415926535897932384626433832795
-
-//Wireframe Helpers
-void Cx4::C4TransfWireFrame() {
- double c4x = (double)C4WFXVal;
- double c4y = (double)C4WFYVal;
- double c4z = (double)C4WFZVal - 0x95;
- double tanval, c4x2, c4y2, c4z2;
-
- //Rotate X
- tanval = -(double)C4WFX2Val * PI * 2 / 128;
- c4y2 = c4y * ::cos(tanval) - c4z * ::sin(tanval);
- c4z2 = c4y * ::sin(tanval) + c4z * ::cos(tanval);
-
- //Rotate Y
- tanval = -(double)C4WFY2Val * PI * 2 / 128;
- c4x2 = c4x * ::cos(tanval) + c4z2 * ::sin(tanval);
- c4z = c4x * -::sin(tanval) + c4z2 * ::cos(tanval);
-
- //Rotate Z
- tanval = -(double)C4WFDist * PI * 2 / 128;
- c4x = c4x2 * ::cos(tanval) - c4y2 * ::sin(tanval);
- c4y = c4x2 * ::sin(tanval) + c4y2 * ::cos(tanval);
-
- //Scale
- C4WFXVal = (int16)(c4x * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
- C4WFYVal = (int16)(c4y * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
-}
-
-void Cx4::C4CalcWireFrame() {
- C4WFXVal = C4WFX2Val - C4WFXVal;
- C4WFYVal = C4WFY2Val - C4WFYVal;
-
- if(abs(C4WFXVal) > abs(C4WFYVal)) {
- C4WFDist = abs(C4WFXVal) + 1;
- C4WFYVal = (256 * (long)C4WFYVal) / abs(C4WFXVal);
- C4WFXVal = (C4WFXVal < 0) ? -256 : 256;
- } else if(C4WFYVal != 0) {
- C4WFDist = abs(C4WFYVal) + 1;
- C4WFXVal = (256 * (long)C4WFXVal) / abs(C4WFYVal);
- C4WFYVal = (C4WFYVal < 0) ? -256 : 256;
- } else {
- C4WFDist = 0;
- }
-}
-
-void Cx4::C4TransfWireFrame2() {
- double c4x = (double)C4WFXVal;
- double c4y = (double)C4WFYVal;
- double c4z = (double)C4WFZVal;
- double tanval, c4x2, c4y2, c4z2;
-
- //Rotate X
- tanval = -(double)C4WFX2Val * PI * 2 / 128;
- c4y2 = c4y * ::cos(tanval) - c4z * ::sin(tanval);
- c4z2 = c4y * ::sin(tanval) + c4z * ::cos(tanval);
-
- //Rotate Y
- tanval = -(double)C4WFY2Val * PI * 2 / 128;
- c4x2 = c4x * ::cos(tanval) + c4z2 * ::sin(tanval);
- c4z = c4x * -::sin(tanval) + c4z2 * ::cos(tanval);
-
- //Rotate Z
- tanval = -(double)C4WFDist * PI * 2 / 128;
- c4x = c4x2 * ::cos(tanval) - c4y2 * ::sin(tanval);
- c4y = c4x2 * ::sin(tanval) + c4y2 * ::cos(tanval);
-
- //Scale
- C4WFXVal = (int16)(c4x * C4WFScale / 0x100);
- C4WFYVal = (int16)(c4y * C4WFScale / 0x100);
-}
-
-void Cx4::C4DrawWireFrame() {
- uint32 line = readl(0x1f80);
- uint32 point1, point2;
- int16 X1, Y1, Z1;
- int16 X2, Y2, Z2;
- uint8 Color;
-
- for(int32 i = ram[0x0295]; i > 0; i--, line += 5) {
- if(bus.read(line) == 0xff && bus.read(line + 1) == 0xff) {
- int32 tmp = line - 5;
- while(bus.read(tmp + 2) == 0xff && bus.read(tmp + 3) == 0xff && (tmp + 2) >= 0) { tmp -= 5; }
- point1 = (read(0x1f82) << 16) | (bus.read(tmp + 2) << 8) | bus.read(tmp + 3);
- } else {
- point1 = (read(0x1f82) << 16) | (bus.read(line) << 8) | bus.read(line + 1);
- }
- point2 = (read(0x1f82) << 16) | (bus.read(line + 2) << 8) | bus.read(line + 3);
-
- X1=(bus.read(point1 + 0) << 8) | bus.read(point1 + 1);
- Y1=(bus.read(point1 + 2) << 8) | bus.read(point1 + 3);
- Z1=(bus.read(point1 + 4) << 8) | bus.read(point1 + 5);
- X2=(bus.read(point2 + 0) << 8) | bus.read(point2 + 1);
- Y2=(bus.read(point2 + 2) << 8) | bus.read(point2 + 3);
- Z2=(bus.read(point2 + 4) << 8) | bus.read(point2 + 5);
- Color = bus.read(line + 4);
- C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color);
- }
-}
-
-void Cx4::C4DrawLine(int32 X1, int32 Y1, int16 Z1, int32 X2, int32 Y2, int16 Z2, uint8 Color) {
- //Transform coordinates
- C4WFXVal = (int16)X1;
- C4WFYVal = (int16)Y1;
- C4WFZVal = Z1;
- C4WFScale = read(0x1f90);
- C4WFX2Val = read(0x1f86);
- C4WFY2Val = read(0x1f87);
- C4WFDist = read(0x1f88);
- C4TransfWireFrame2();
- X1 = (C4WFXVal + 48) << 8;
- Y1 = (C4WFYVal + 48) << 8;
-
- C4WFXVal = (int16)X2;
- C4WFYVal = (int16)Y2;
- C4WFZVal = Z2;
- C4TransfWireFrame2();
- X2 = (C4WFXVal + 48) << 8;
- Y2 = (C4WFYVal + 48) << 8;
-
- //Get line info
- C4WFXVal = (int16)(X1 >> 8);
- C4WFYVal = (int16)(Y1 >> 8);
- C4WFX2Val = (int16)(X2 >> 8);
- C4WFY2Val = (int16)(Y2 >> 8);
- C4CalcWireFrame();
- X2 = (int16)C4WFXVal;
- Y2 = (int16)C4WFYVal;
-
- //Render line
- for(int32 i = C4WFDist ? C4WFDist : 1; i > 0; i--) {
- if(X1 > 0xff && Y1 > 0xff && X1 < 0x6000 && Y1 < 0x6000) {
- uint16 addr = (((Y1 >> 8) >> 3) << 8) - (((Y1 >> 8) >> 3) << 6) + (((X1 >> 8) >> 3) << 4) + ((Y1 >> 8) & 7) * 2;
- uint8 bit = 0x80 >> ((X1 >> 8) & 7);
- ram[addr + 0x300] &= ~bit;
- ram[addr + 0x301] &= ~bit;
- if(Color & 1) ram[addr + 0x300] |= bit;
- if(Color & 2) ram[addr + 0x301] |= bit;
- }
- X1 += X2;
- Y1 += Y2;
- }
-}
-
-void Cx4::C4DoScaleRotate(int row_padding) {
- int16 A, B, C, D;
-
- //Calculate matrix
- int32 XScale = readw(0x1f8f);
- int32 YScale = readw(0x1f92);
-
- if(XScale & 0x8000)XScale = 0x7fff;
- if(YScale & 0x8000)YScale = 0x7fff;
-
- if(readw(0x1f80) == 0) { //no rotation
- A = (int16)XScale;
- B = 0;
- C = 0;
- D = (int16)YScale;
- } else if(readw(0x1f80) == 128) { //90 degree rotation
- A = 0;
- B = (int16)(-YScale);
- C = (int16)XScale;
- D = 0;
- } else if(readw(0x1f80) == 256) { //180 degree rotation
- A = (int16)(-XScale);
- B = 0;
- C = 0;
- D = (int16)(-YScale);
- } else if(readw(0x1f80) == 384) { //270 degree rotation
- A = 0;
- B = (int16)YScale;
- C = (int16)(-XScale);
- D = 0;
- } else {
- A = (int16) sar(CosTable[readw(0x1f80) & 0x1ff] * XScale, 15);
- B = (int16)(-sar(SinTable[readw(0x1f80) & 0x1ff] * YScale, 15));
- C = (int16) sar(SinTable[readw(0x1f80) & 0x1ff] * XScale, 15);
- D = (int16) sar(CosTable[readw(0x1f80) & 0x1ff] * YScale, 15);
- }
-
- //Calculate Pixel Resolution
- uint8 w = read(0x1f89) & ~7;
- uint8 h = read(0x1f8c) & ~7;
-
- //Clear the output RAM
- memset(ram, 0, (w + row_padding / 4) * h / 2);
-
- int32 Cx = (int16)readw(0x1f83);
- int32 Cy = (int16)readw(0x1f86);
-
- //Calculate start position (i.e. (Ox, Oy) = (0, 0))
- //The low 12 bits are fractional, so (Cx<<12) gives us the Cx we want in
- //the function. We do Cx*A etc normally because the matrix parameters
- //already have the fractional parts.
- int32 LineX = (Cx << 12) - Cx * A - Cx * B;
- int32 LineY = (Cy << 12) - Cy * C - Cy * D;
-
- //Start loop
- uint32 X, Y;
- uint8 byte;
- int32 outidx = 0;
- uint8 bit = 0x80;
-
- for(int32 y = 0; y < h; y++) {
- X = LineX;
- Y = LineY;
- for(int32 x = 0; x < w; x++) {
- if((X >> 12) >= w || (Y >> 12) >= h) {
- byte = 0;
- } else {
- uint32 addr = (Y >> 12) * w + (X >> 12);
- byte = read(0x600 + (addr >> 1));
- if(addr & 1) { byte >>= 4; }
- }
-
- //De-bitplanify
- if(byte & 1) ram[outidx ] |= bit;
- if(byte & 2) ram[outidx + 1] |= bit;
- if(byte & 4) ram[outidx + 16] |= bit;
- if(byte & 8) ram[outidx + 17] |= bit;
-
- bit >>= 1;
- if(!bit) {
- bit = 0x80;
- outidx += 32;
- }
-
- X += A; //Add 1 to output x => add an A and a C
- Y += C;
- }
- outidx += 2 + row_padding;
- if(outidx & 0x10) {
- outidx &= ~0x10;
- } else {
- outidx -= w * 4 + row_padding;
- }
- LineX += B; //Add 1 to output y => add a B and a D
- LineY += D;
- }
-}
-
-#endif
diff --git a/bsnes/snes/chip/cx4/oam.cpp b/bsnes/snes/chip/cx4/oam.cpp
deleted file mode 100755
index dcda69e45..000000000
--- a/bsnes/snes/chip/cx4/oam.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-#ifdef CX4_CPP
-
-//Build OAM
-void Cx4::op00_00() {
- uint32 oamptr = ram[0x626] << 2;
- for(int32 i = 0x1fd; i > oamptr && i >= 0; i -= 4) {
- //clear oam-to-be
- if(i >= 0) ram[i] = 0xe0;
- }
-
- uint16 globalx, globaly;
- uint32 oamptr2;
- int16 sprx, spry;
- uint8 sprname, sprattr;
- uint8 sprcount;
-
- globalx = readw(0x621);
- globaly = readw(0x623);
- oamptr2 = 0x200 + (ram[0x626] >> 2);
-
- if(!ram[0x620]) return;
-
- sprcount = 128 - ram[0x626];
- uint8 offset = (ram[0x626] & 3) * 2;
- uint32 srcptr = 0x220;
-
- for(int i = ram[0x620]; i > 0 && sprcount > 0; i--, srcptr += 16) {
- sprx = readw(srcptr) - globalx;
- spry = readw(srcptr + 2) - globaly;
- sprname = ram[srcptr + 5];
- sprattr = ram[srcptr + 4] | ram[srcptr + 6];
-
- uint32 spraddr = readl(srcptr + 7);
- if(bus.read(spraddr)) {
- int16 x, y;
- for(int sprcnt = bus.read(spraddr++); sprcnt > 0 && sprcount > 0; sprcnt--, spraddr += 4) {
- x = (int8)bus.read(spraddr + 1);
- if(sprattr & 0x40) {
- x = -x - ((bus.read(spraddr) & 0x20) ? 16 : 8);
- }
- x += sprx;
- if(x >= -16 && x <= 272) {
- y = (int8)bus.read(spraddr + 2);
- if(sprattr & 0x80) {
- y = -y - ((bus.read(spraddr) & 0x20) ? 16 : 8);
- }
- y += spry;
- if(y >= -16 && y <= 224) {
- ram[oamptr ] = (uint8)x;
- ram[oamptr + 1] = (uint8)y;
- ram[oamptr + 2] = sprname + bus.read(spraddr + 3);
- ram[oamptr + 3] = sprattr ^ (bus.read(spraddr) & 0xc0);
- ram[oamptr2] &= ~(3 << offset);
- if(x & 0x100) ram[oamptr2] |= 1 << offset;
- if(bus.read(spraddr) & 0x20) ram[oamptr2] |= 2 << offset;
- oamptr += 4;
- sprcount--;
- offset = (offset + 2) & 6;
- if(!offset)oamptr2++;
- }
- }
- }
- } else if(sprcount > 0) {
- ram[oamptr ] = (uint8)sprx;
- ram[oamptr + 1] = (uint8)spry;
- ram[oamptr + 2] = sprname;
- ram[oamptr + 3] = sprattr;
- ram[oamptr2] &= ~(3 << offset);
- if(sprx & 0x100) ram[oamptr2] |= 3 << offset;
- else ram[oamptr2] |= 2 << offset;
- oamptr += 4;
- sprcount--;
- offset = (offset + 2) & 6;
- if(!offset) oamptr2++;
- }
- }
-}
-
-//Scale and Rotate
-void Cx4::op00_03() {
- C4DoScaleRotate(0);
-}
-
-//Transform Lines
-void Cx4::op00_05() {
- C4WFX2Val = read(0x1f83);
- C4WFY2Val = read(0x1f86);
- C4WFDist = read(0x1f89);
- C4WFScale = read(0x1f8c);
-
-//Transform Vertices
-uint32 ptr = 0;
- for(int32 i = readw(0x1f80); i > 0; i--, ptr += 0x10) {
- C4WFXVal = readw(ptr + 1);
- C4WFYVal = readw(ptr + 5);
- C4WFZVal = readw(ptr + 9);
- C4TransfWireFrame();
-
- //Displace
- writew(ptr + 1, C4WFXVal + 0x80);
- writew(ptr + 5, C4WFYVal + 0x50);
- }
-
- writew(0x600, 23);
- writew(0x602, 0x60);
- writew(0x605, 0x40);
- writew(0x600 + 8, 23);
- writew(0x602 + 8, 0x60);
- writew(0x605 + 8, 0x40);
-
- ptr = 0xb02;
- uint32 ptr2 = 0;
-
- for(int32 i = readw(0xb00); i > 0; i--, ptr += 2, ptr2 += 8) {
- C4WFXVal = readw((read(ptr + 0) << 4) + 1);
- C4WFYVal = readw((read(ptr + 0) << 4) + 5);
- C4WFX2Val = readw((read(ptr + 1) << 4) + 1);
- C4WFY2Val = readw((read(ptr + 1) << 4) + 5);
- C4CalcWireFrame();
- writew(ptr2 + 0x600, C4WFDist ? C4WFDist : 1);
- writew(ptr2 + 0x602, C4WFXVal);
- writew(ptr2 + 0x605, C4WFYVal);
- }
-}
-
-//Scale and Rotate
-void Cx4::op00_07() {
- C4DoScaleRotate(64);
-}
-
-//Draw Wireframe
-void Cx4::op00_08() {
- C4DrawWireFrame();
-}
-
-//Disintegrate
-void Cx4::op00_0b() {
- uint8 width, height;
- uint32 startx, starty;
- uint32 srcptr;
- uint32 x, y;
- int32 scalex, scaley;
- int32 cx, cy;
- int32 i, j;
-
- width = read(0x1f89);
- height = read(0x1f8c);
- cx = readw(0x1f80);
- cy = readw(0x1f83);
-
- scalex = (int16)readw(0x1f86);
- scaley = (int16)readw(0x1f8f);
- startx = -cx * scalex + (cx << 8);
- starty = -cy * scaley + (cy << 8);
- srcptr = 0x600;
-
- for(i = 0; i < (width * height) >> 1; i++) {
- write(i, 0);
- }
-
- for(y = starty, i = 0;i < height; i++, y += scaley) {
- for(x = startx, j = 0;j < width; j++, x += scalex) {
- if((x >> 8) < width && (y >> 8) < height && (y >> 8) * width + (x >> 8) < 0x2000) {
- uint8 pixel = (j & 1) ? (ram[srcptr] >> 4) : (ram[srcptr]);
- int32 index = (y >> 11) * width * 4 + (x >> 11) * 32 + ((y >> 8) & 7) * 2;
- uint8 mask = 0x80 >> ((x >> 8) & 7);
-
- if(pixel & 1) ram[index ] |= mask;
- if(pixel & 2) ram[index + 1] |= mask;
- if(pixel & 4) ram[index + 16] |= mask;
- if(pixel & 8) ram[index + 17] |= mask;
- }
- if(j & 1) srcptr++;
- }
- }
-}
-
-//Bitplane Wave
-void Cx4::op00_0c() {
- uint32 destptr = 0;
- uint32 waveptr = read(0x1f83);
- uint16 mask1 = 0xc0c0;
- uint16 mask2 = 0x3f3f;
-
- for(int j = 0; j < 0x10; j++) {
- do {
- int16 height = -((int8)read(waveptr + 0xb00)) - 16;
- for(int i = 0; i < 40; i++) {
- uint16 temp = readw(destptr + wave_data[i]) & mask2;
- if(height >= 0) {
- if(height < 8) {
- temp |= mask1 & readw(0xa00 + height * 2);
- } else {
- temp |= mask1 & 0xff00;
- }
- }
- writew(destptr + wave_data[i], temp);
- height++;
- }
- waveptr = (waveptr + 1) & 0x7f;
- mask1 = (mask1 >> 2) | (mask1 << 6);
- mask2 = (mask2 >> 2) | (mask2 << 6);
- } while(mask1 != 0xc0c0);
- destptr += 16;
-
- do {
- int16 height = -((int8)read(waveptr + 0xb00)) - 16;
- for(int i = 0; i < 40; i++) {
- uint16 temp = readw(destptr + wave_data[i]) & mask2;
- if(height >= 0) {
- if(height < 8) {
- temp |= mask1 & readw(0xa10 + height * 2);
- } else {
- temp |= mask1 & 0xff00;
- }
- }
- writew(destptr + wave_data[i], temp);
- height++;
- }
- waveptr = (waveptr + 1) & 0x7f;
- mask1 = (mask1 >> 2) | (mask1 << 6);
- mask2 = (mask2 >> 2) | (mask2 << 6);
- } while(mask1 != 0xc0c0);
- destptr += 16;
- }
-}
-
-#endif
diff --git a/bsnes/snes/chip/cx4/opcodes.cpp b/bsnes/snes/chip/cx4/opcodes.cpp
deleted file mode 100755
index 639097b14..000000000
--- a/bsnes/snes/chip/cx4/opcodes.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-#ifdef CX4_CPP
-
-//Sprite Functions
-void Cx4::op00() {
- switch(reg[0x4d]) {
- case 0x00: op00_00(); break;
- case 0x03: op00_03(); break;
- case 0x05: op00_05(); break;
- case 0x07: op00_07(); break;
- case 0x08: op00_08(); break;
- case 0x0b: op00_0b(); break;
- case 0x0c: op00_0c(); break;
- }
-}
-
-//Draw Wireframe
-void Cx4::op01() {
- memset(ram + 0x300, 0, 2304);
- C4DrawWireFrame();
-}
-
-//Propulsion
-void Cx4::op05() {
- int32 temp = 0x10000;
- if(readw(0x1f83)) {
- temp = sar((temp / readw(0x1f83)) * readw(0x1f81), 8);
- }
- writew(0x1f80, temp);
-}
-
-//Set Vector length
-void Cx4::op0d() {
- C41FXVal = readw(0x1f80);
- C41FYVal = readw(0x1f83);
- C41FDistVal = readw(0x1f86);
- double tanval = sqrt(((double)C41FYVal) * ((double)C41FYVal) + ((double)C41FXVal) * ((double)C41FXVal));
- tanval = (double)C41FDistVal / tanval;
- C41FYVal = (int16)(((double)C41FYVal * tanval) * 0.99);
- C41FXVal = (int16)(((double)C41FXVal * tanval) * 0.98);
- writew(0x1f89, C41FXVal);
- writew(0x1f8c, C41FYVal);
-}
-
-//Triangle
-void Cx4::op10() {
- r0 = ldr(0);
- r1 = ldr(1);
-
- r4 = r0 & 0x1ff;
- if(r1 & 0x8000)r1 |= ~0x7fff;
- else r1 &= 0x7fff;
-
- mul(cos(r4), r1, r5, r2);
- r5 = (r5 >> 16) & 0xff;
- r2 = (r2 << 8) + r5;
-
- mul(sin(r4), r1, r5, r3);
- r5 = (r5 >> 16) & 0xff;
- r3 = (r3 << 8) + r5;
-
- str(0, r0);
- str(1, r1);
- str(2, r2);
- str(3, r3);
- str(4, r4);
- str(5, r5);
-}
-
-//Triangle
-void Cx4::op13() {
- r0 = ldr(0);
- r1 = ldr(1);
-
- r4 = r0 & 0x1ff;
-
- mul(cos(r4), r1, r5, r2);
- r5 = (r5 >> 8) & 0xffff;
- r2 = (r2 << 16) + r5;
-
- mul(sin(r4), r1, r5, r3);
- r5 = (r5 >> 8) & 0xffff;
- r3 = (r3 << 16) + r5;
-
- str(0, r0);
- str(1, r1);
- str(2, r2);
- str(3, r3);
- str(4, r4);
- str(5, r5);
-}
-
-//Pythagorean
-void Cx4::op15() {
- C41FXVal = readw(0x1f80);
- C41FYVal = readw(0x1f83);
- C41FDist = (int16)sqrt((double)C41FXVal * (double)C41FXVal + (double)C41FYVal * (double)C41FYVal);
- writew(0x1f80, C41FDist);
-}
-
-//Calculate distance
-void Cx4::op1f() {
- C41FXVal = readw(0x1f80);
- C41FYVal = readw(0x1f83);
- if(!C41FXVal) {
- C41FAngleRes = (C41FYVal > 0) ? 0x080 : 0x180;
- } else {
- double tanval = ((double)C41FYVal) / ((double)C41FXVal);
- C41FAngleRes = (short)(atan(tanval) / (PI * 2) * 512);
- C41FAngleRes = C41FAngleRes;
- if(C41FXVal < 0) {
- C41FAngleRes += 0x100;
- }
- C41FAngleRes &= 0x1ff;
- }
- writew(0x1f86, C41FAngleRes);
-}
-
-//Trapezoid
-void Cx4::op22() {
- int16 angle1 = readw(0x1f8c) & 0x1ff;
- int16 angle2 = readw(0x1f8f) & 0x1ff;
- int32 tan1 = Tan(angle1);
- int32 tan2 = Tan(angle2);
- int16 y = readw(0x1f83) - readw(0x1f89);
- int16 left, right;
-
- for(int32 j = 0; j < 225; j++, y++) {
- if(y >= 0) {
- left = sar((int32)tan1 * y, 16) - readw(0x1f80) + readw(0x1f86);
- right = sar((int32)tan2 * y, 16) - readw(0x1f80) + readw(0x1f86) + readw(0x1f93);
-
- if(left < 0 && right < 0) {
- left = 1;
- right = 0;
- } else if(left < 0) {
- left = 0;
- } else if(right < 0) {
- right = 0;
- }
-
- if(left > 255 && right > 255) {
- left = 255;
- right = 254;
- } else if(left > 255) {
- left = 255;
- } else if(right > 255) {
- right = 255;
- }
- } else {
- left = 1;
- right = 0;
- }
- ram[j + 0x800] = (uint8)left;
- ram[j + 0x900] = (uint8)right;
- }
-}
-
-//Multiply
-void Cx4::op25() {
- r0 = ldr(0);
- r1 = ldr(1);
- mul(r0, r1, r0, r1);
- str(0, r0);
- str(1, r1);
-}
-
-//Transform Coords
-void Cx4::op2d() {
- C4WFXVal = readw(0x1f81);
- C4WFYVal = readw(0x1f84);
- C4WFZVal = readw(0x1f87);
- C4WFX2Val = read (0x1f89);
- C4WFY2Val = read (0x1f8a);
- C4WFDist = read (0x1f8b);
- C4WFScale = readw(0x1f90);
- C4TransfWireFrame2();
- writew(0x1f80, C4WFXVal);
- writew(0x1f83, C4WFYVal);
-}
-
-//Sum
-void Cx4::op40() {
- r0 = 0;
- for(uint32 i=0;i<0x800;i++) {
- r0 += ram[i];
- }
- str(0, r0);
-}
-
-//Square
-void Cx4::op54() {
- r0 = ldr(0);
- mul(r0, r0, r1, r2);
- str(1, r1);
- str(2, r2);
-}
-
-//Immediate Register
-void Cx4::op5c() {
- str(0, 0x000000);
- immediate_reg(0);
-}
-
-//Immediate Register (Multiple)
-void Cx4::op5e() { immediate_reg( 0); }
-void Cx4::op60() { immediate_reg( 3); }
-void Cx4::op62() { immediate_reg( 6); }
-void Cx4::op64() { immediate_reg( 9); }
-void Cx4::op66() { immediate_reg(12); }
-void Cx4::op68() { immediate_reg(15); }
-void Cx4::op6a() { immediate_reg(18); }
-void Cx4::op6c() { immediate_reg(21); }
-void Cx4::op6e() { immediate_reg(24); }
-void Cx4::op70() { immediate_reg(27); }
-void Cx4::op72() { immediate_reg(30); }
-void Cx4::op74() { immediate_reg(33); }
-void Cx4::op76() { immediate_reg(36); }
-void Cx4::op78() { immediate_reg(39); }
-void Cx4::op7a() { immediate_reg(42); }
-void Cx4::op7c() { immediate_reg(45); }
-
-//Immediate ROM
-void Cx4::op89() {
- str(0, 0x054336);
- str(1, 0xffffff);
-}
-
-#endif
diff --git a/bsnes/snes/chip/cx4/serialization.cpp b/bsnes/snes/chip/cx4/serialization.cpp
deleted file mode 100755
index 1b36a4eb3..000000000
--- a/bsnes/snes/chip/cx4/serialization.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifdef CX4_CPP
-
-void Cx4::serialize(serializer &s) {
- s.array(ram);
- s.array(reg);
-
- s.integer(r0);
- s.integer(r1);
- s.integer(r2);
- s.integer(r3);
- s.integer(r4);
- s.integer(r5);
- s.integer(r6);
- s.integer(r7);
- s.integer(r8);
- s.integer(r9);
- s.integer(r10);
- s.integer(r11);
- s.integer(r12);
- s.integer(r13);
- s.integer(r14);
- s.integer(r15);
-
- s.integer(C4WFXVal);
- s.integer(C4WFYVal);
- s.integer(C4WFZVal);
- s.integer(C4WFX2Val);
- s.integer(C4WFY2Val);
- s.integer(C4WFDist);
- s.integer(C4WFScale);
-
- s.integer(C41FXVal);
- s.integer(C41FYVal);
- s.integer(C41FAngleRes);
- s.integer(C41FDist);
- s.integer(C41FDistVal);
-}
-
-#endif
diff --git a/bsnes/snes/chip/hitachidsp/hitachidsp.cpp b/bsnes/snes/chip/hitachidsp/hitachidsp.cpp
new file mode 100755
index 000000000..62f4bfa2e
--- /dev/null
+++ b/bsnes/snes/chip/hitachidsp/hitachidsp.cpp
@@ -0,0 +1,79 @@
+#include
+
+#define HITACHIDSP_CPP
+namespace SNES {
+
+#include "memory.cpp"
+#include "opcodes.cpp"
+#include "registers.cpp"
+#include "serialization.cpp"
+HitachiDSP hitachidsp;
+
+void HitachiDSP::Enter() { hitachidsp.enter(); }
+
+void HitachiDSP::enter() {
+ while(true) {
+ if(scheduler.sync == Scheduler::SynchronizeMode::All) {
+ scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
+ }
+
+ switch(state) {
+ case State::Idle:
+ step(1);
+ break;
+ case State::DMA:
+ for(unsigned n = 0; n < regs.dma_length; n++) {
+ bus.write(regs.dma_target + n, bus.read(regs.dma_source + n));
+ step(2);
+ }
+ state = State::Idle;
+ break;
+ case State::Execute:
+ unsigned offset = regs.program_offset + regs.pc * 2;
+ opcode = bus_read(offset + 0) << 0;
+ opcode |= bus_read(offset + 1) << 8;
+ regs.pc = (regs.pc & 0xffff00) | ((regs.pc + 1) & 0x0000ff);
+ exec();
+ step(1);
+ break;
+ }
+
+ synchronize_cpu();
+ }
+}
+
+void HitachiDSP::init() {
+}
+
+void HitachiDSP::load() {
+}
+
+void HitachiDSP::unload() {
+}
+
+void HitachiDSP::power() {
+ reset();
+}
+
+void HitachiDSP::reset() {
+ create(HitachiDSP::Enter, frequency);
+ state = State::Idle;
+
+ regs.n = 0;
+ regs.z = 0;
+ regs.c = 0;
+
+ regs.dma_source = 0x000000;
+ regs.dma_length = 0x0000;
+ regs.dma_target = 0x000000;
+ regs.r1f48 = 0x00;
+ regs.program_offset = 0x000000;
+ regs.r1f4c = 0x00;
+ regs.page_number = 0x0000;
+ regs.program_counter = 0x00;
+ regs.r1f50 = 0x33;
+ regs.r1f51 = 0x00;
+ regs.r1f52 = 0x01;
+}
+
+}
diff --git a/bsnes/snes/chip/hitachidsp/hitachidsp.hpp b/bsnes/snes/chip/hitachidsp/hitachidsp.hpp
new file mode 100755
index 000000000..40853c02e
--- /dev/null
+++ b/bsnes/snes/chip/hitachidsp/hitachidsp.hpp
@@ -0,0 +1,48 @@
+//Hitachi HG51B169
+
+class HitachiDSP : public Coprocessor {
+public:
+ unsigned frequency;
+//uint16 programROM[2][256];
+ uint24 dataROM[1024];
+ uint8 dataRAM[3072];
+ uint24 stack[8];
+ uint16 opcode;
+ enum class State : unsigned { Idle, DMA, Execute } state;
+ #include "registers.hpp"
+
+ static void Enter();
+ void enter();
+
+ void init();
+ void load();
+ void unload();
+ void power();
+ void reset();
+
+ //memory.cpp
+ uint8 bus_read(unsigned addr);
+ void bus_write(unsigned addr, uint8 data);
+
+ uint8 rom_read(unsigned addr);
+ void rom_write(unsigned addr, uint8 data);
+
+ uint8 dsp_read(unsigned addr);
+ void dsp_write(unsigned addr, uint8 data);
+
+ //opcodes.cpp
+ void push();
+ void pull();
+ unsigned sa();
+ unsigned ri();
+ unsigned np();
+ void exec();
+
+ //registers.cpp
+ unsigned reg_read(unsigned n) const;
+ void reg_write(unsigned n, unsigned data);
+
+ void serialize(serializer&);
+};
+
+extern HitachiDSP hitachidsp;
diff --git a/bsnes/snes/chip/hitachidsp/memory.cpp b/bsnes/snes/chip/hitachidsp/memory.cpp
new file mode 100755
index 000000000..3c9c3af18
--- /dev/null
+++ b/bsnes/snes/chip/hitachidsp/memory.cpp
@@ -0,0 +1,133 @@
+#ifdef HITACHIDSP_CPP
+
+uint8 HitachiDSP::bus_read(unsigned addr) {
+ if((addr & 0x408000) == 0x008000) return bus.read(addr);
+ return 0x00;
+}
+
+void HitachiDSP::bus_write(unsigned addr, uint8 data) {
+ if((addr & 0x40e000) == 0x006000) return bus.write(addr, data);
+}
+
+uint8 HitachiDSP::rom_read(unsigned addr) {
+ if(co_active() == cpu.thread) {
+ if(state == State::Idle) return cartridge.rom.read(addr);
+ if((addr & 0x40ffe0) == 0x00ffe0) return regs.vector[addr & 0x1f];
+ return cpu.regs.mdr;
+ }
+ if(co_active() == hitachidsp.thread) {
+ return cartridge.rom.read(addr);
+ }
+ return cpu.regs.mdr;
+}
+
+void HitachiDSP::rom_write(unsigned addr, uint8 data) {
+}
+
+uint8 HitachiDSP::dsp_read(unsigned addr) {
+ addr &= 0x1fff;
+
+ //Data RAM
+ if((addr >= 0x0000 && addr <= 0x0bff) || (addr >= 0x1000 && addr <= 0x1bff)) {
+ return dataRAM[addr & 0x0fff];
+ }
+
+ //MMIO
+ switch(addr) {
+ case 0x1f40: return regs.dma_source >> 0;
+ case 0x1f41: return regs.dma_source >> 8;
+ case 0x1f42: return regs.dma_source >> 16;
+ case 0x1f43: return regs.dma_length >> 0;
+ case 0x1f44: return regs.dma_length >> 8;
+ case 0x1f45: return regs.dma_target >> 0;
+ case 0x1f46: return regs.dma_target >> 8;
+ case 0x1f47: return regs.dma_target >> 16;
+ case 0x1f48: return regs.r1f48;
+ case 0x1f49: return regs.program_offset >> 0;
+ case 0x1f4a: return regs.program_offset >> 8;
+ case 0x1f4b: return regs.program_offset >> 16;
+ case 0x1f4c: return regs.r1f4c;
+ case 0x1f4d: return regs.page_number >> 0;
+ case 0x1f4e: return regs.page_number >> 8;
+ case 0x1f4f: return regs.program_counter;
+ case 0x1f50: return regs.r1f50;
+ case 0x1f51: return regs.r1f51;
+ case 0x1f52: return regs.r1f52;
+ case 0x1f53: case 0x1f54: case 0x1f55: case 0x1f56:
+ case 0x1f57: case 0x1f58: case 0x1f59: case 0x1f5a:
+ case 0x1f5b: case 0x1f5c: case 0x1f5d: case 0x1f5e:
+ case 0x1f5f: return ((state != State::Idle) << 6) | ((state == State::Idle) << 1);
+ }
+
+ //Vector
+ if(addr >= 0x1f60 && addr <= 0x1f7f) {
+ return regs.vector[addr & 0x1f];
+ }
+
+ //GPRs
+ if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) {
+ unsigned index = (addr & 0x3f) / 3; //0..15
+ unsigned shift = ((addr & 0x3f) % 3) * 8; //0, 8, 16
+ return regs.gpr[index] >> shift;
+ }
+
+ return 0x00;
+}
+
+void HitachiDSP::dsp_write(unsigned addr, uint8 data) {
+ addr &= 0x1fff;
+
+ //Data RAM
+ if((addr >= 0x0000 && addr <= 0x0bff) || (addr >= 0x1000 && addr <= 0x1bff)) {
+ dataRAM[addr & 0x0fff] = data;
+ return;
+ }
+
+ //MMIO
+ switch(addr) {
+ case 0x1f40: regs.dma_source = (regs.dma_source & 0xffff00) | (data << 0); return;
+ case 0x1f41: regs.dma_source = (regs.dma_source & 0xff00ff) | (data << 8); return;
+ case 0x1f42: regs.dma_source = (regs.dma_source & 0x00ffff) | (data << 16); return;
+ case 0x1f43: regs.dma_length = (regs.dma_length & 0xff00) | (data << 0); return;
+ case 0x1f44: regs.dma_length = (regs.dma_length & 0x00ff) | (data << 8); return;
+ case 0x1f45: regs.dma_target = (regs.dma_target & 0xffff00) | (data << 0); return;
+ case 0x1f46: regs.dma_target = (regs.dma_target & 0xff00ff) | (data << 8); return;
+ case 0x1f47: regs.dma_target = (regs.dma_target & 0x00ffff) | (data << 16);
+ if(state == State::Idle) state = State::DMA;
+ return;
+ case 0x1f48: regs.r1f48 = data & 0x01; return;
+ case 0x1f49: regs.program_offset = (regs.program_offset & 0xffff00) | (data << 0); return;
+ case 0x1f4a: regs.program_offset = (regs.program_offset & 0xff00ff) | (data << 8); return;
+ case 0x1f4b: regs.program_offset = (regs.program_offset & 0x00ffff) | (data << 16); return;
+ case 0x1f4c: regs.r1f4c = data & 0x03; return;
+ case 0x1f4d: regs.page_number = (regs.page_number & 0x7f00) | ((data & 0xff) << 0); return;
+ case 0x1f4e: regs.page_number = (regs.page_number & 0x00ff) | ((data & 0x7f) << 8); return;
+ case 0x1f4f: regs.program_counter = data;
+ if(state == State::Idle) {
+ regs.pc = regs.page_number * 256 + regs.program_counter;
+ state = State::Execute;
+ }
+ return;
+ case 0x1f50: regs.r1f50 = data & 0x77; return;
+ case 0x1f51: regs.r1f51 = data & 0x01; return;
+ case 0x1f52: regs.r1f52 = data & 0x01; return;
+ }
+
+ //Vector
+ if(addr >= 0x1f60 && addr <= 0x1f7f) {
+ regs.vector[addr & 0x1f] = data;
+ return;
+ }
+
+ //GPRs
+ if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) {
+ unsigned index = (addr & 0x3f) / 3;
+ switch((addr & 0x3f) % 3) {
+ case 0: regs.gpr[index] = (regs.gpr[index] & 0xffff00) | (data << 0); return;
+ case 1: regs.gpr[index] = (regs.gpr[index] & 0xff00ff) | (data << 8); return;
+ case 2: regs.gpr[index] = (regs.gpr[index] & 0x00ffff) | (data << 16); return;
+ }
+ }
+}
+
+#endif
diff --git a/bsnes/snes/chip/hitachidsp/opcodes.cpp b/bsnes/snes/chip/hitachidsp/opcodes.cpp
new file mode 100755
index 000000000..2ace5a3c6
--- /dev/null
+++ b/bsnes/snes/chip/hitachidsp/opcodes.cpp
@@ -0,0 +1,353 @@
+#ifdef HITACHIDSP_CPP
+
+void HitachiDSP::push() {
+ stack[7] = stack[6];
+ stack[6] = stack[5];
+ stack[5] = stack[4];
+ stack[4] = stack[3];
+ stack[3] = stack[2];
+ stack[2] = stack[1];
+ stack[1] = stack[0];
+ stack[0] = regs.pc;
+}
+
+void HitachiDSP::pull() {
+ regs.pc = stack[0];
+ stack[0] = stack[1];
+ stack[1] = stack[2];
+ stack[2] = stack[3];
+ stack[3] = stack[4];
+ stack[4] = stack[5];
+ stack[5] = stack[6];
+ stack[6] = stack[7];
+ stack[7] = 0x0000;
+}
+
+//Shift-A: math opcodes can shift A register prior to ALU operation
+unsigned HitachiDSP::sa() {
+ switch(opcode & 0x0300) { default:
+ case 0x0000: return regs.a << 0;
+ case 0x0100: return regs.a << 1;
+ case 0x0200: return regs.a << 8;
+ case 0x0300: return regs.a << 16;
+ }
+}
+
+//Register-or-Immediate: most opcodes can load from a register or immediate
+unsigned HitachiDSP::ri() {
+ if(opcode & 0x0400) return opcode & 0xff;
+ return reg_read(opcode & 0xff);
+}
+
+//New-PC: determine jump target address; opcode.d9 = long jump flag (1 = yes)
+unsigned HitachiDSP::np() {
+ if(opcode & 0x0200) return (regs.p << 8) | (opcode & 0xff);
+ return (regs.pc & 0xffff00) | (opcode & 0xff);
+}
+
+void HitachiDSP::exec() {
+ if((opcode & 0xffff) == 0x0000) {
+ //0000 0000 0000 0000
+ //nop
+ }
+
+ else if((opcode & 0xdd00) == 0x0800) {
+ //00.0 10.0 .... ....
+ //jump i
+ if(opcode & 0x2000) push();
+ regs.pc = np();
+ }
+
+ else if((opcode & 0xdd00) == 0x0c00) {
+ //00.0 11.0 .... ....
+ //jumpeq i
+ if(regs.z) {
+ if(opcode & 0x2000) push();
+ regs.pc = np();
+ }
+ }
+
+ else if((opcode & 0xdd00) == 0x1000) {
+ //00.1 00.0 .... ....
+ //jumpge i
+ if(regs.c) {
+ if(opcode & 0x2000) push();
+ regs.pc = np();
+ }
+ }
+
+ else if((opcode & 0xdd00) == 0x1400) {
+ //00.1 01.0 .... ....
+ //jumpmi
+ if(regs.n) {
+ if(opcode & 0x2000) push();
+ regs.pc = np();
+ }
+ }
+
+ else if((opcode & 0xffff) == 0x1c00) {
+ //0001 1100 0000 0000
+ //loop/wait?
+ }
+
+ else if((opcode & 0xfffe) == 0x2500) {
+ //0010 0101 0000 000.
+ //skiplt/skipge
+ if(regs.c == (opcode & 1)) regs.pc++;
+ }
+
+ else if((opcode & 0xfffe) == 0x2600) {
+ //0010 0110 0000 000.
+ //skipne/skipeq
+ if(regs.z == (opcode & 1)) regs.pc++;
+ }
+
+ else if((opcode & 0xfffe) == 0x2700) {
+ //0010 0111 0000 000.
+ //skipmi/skippl
+ if(regs.n == (opcode & 1)) regs.pc++;
+ }
+
+ else if((opcode & 0xffff) == 0x3c00) {
+ //0011 1100 0000 0000
+ pull();
+ }
+
+ else if((opcode & 0xffff) == 0x4000) {
+ //0100 0000 0000 0000
+ //rdbus
+ regs.busdata = bus_read(regs.busaddr++);
+ }
+
+ else if((opcode & 0xf800) == 0x4800) {
+ //0100 1... .... ....
+ //rcmp a<= 0;
+ }
+
+ else if((opcode & 0xf800) == 0x5000) {
+ //0101 0... .... ....
+ //cmp a<= 0;
+ }
+
+ else if((opcode & 0xfb00) == 0x5900) {
+ //0101 1.01 .... ....
+ //sxb
+ regs.a = (int8)ri();
+ }
+
+ else if((opcode & 0xfb00) == 0x5a00) {
+ //0101 1.10 .... ....
+ //sxw
+ regs.a = (int16)ri();
+ }
+
+ else if((opcode & 0xfb00) == 0x6000) {
+ //0110 0.00 .... ....
+ //ld a,ri
+ regs.a = ri();
+ }
+
+ else if((opcode & 0xfb00) == 0x6100) {
+ //0110 0.01 .... ....
+ //ld ?,ri
+ }
+
+ else if((opcode & 0xfb00) == 0x6300) {
+ //0110 0.11 .... ....
+ //ld p,ri
+ regs.p = ri();
+ }
+
+ else if((opcode & 0xfb00) == 0x6800) {
+ //0110 1.00 .... ....
+ //rdraml
+ uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
+ if(target < 0xc00) regs.ramdata = (regs.ramdata & 0xffff00) | (dataRAM[target] << 0);
+ }
+
+ else if((opcode & 0xfb00) == 0x6900) {
+ //0110 1.01 .... ....
+ //rdramh
+ uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
+ if(target < 0xc00) regs.ramdata = (regs.ramdata & 0xff00ff) | (dataRAM[target] << 8);
+ }
+
+ else if((opcode & 0xfb00) == 0x6a00) {
+ //0110 1.10 .... ....
+ //rdramb
+ uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
+ if(target < 0xc00) regs.ramdata = (regs.ramdata & 0x00ffff) | (dataRAM[target] << 16);
+ }
+
+ else if((opcode & 0xffff) == 0x7000) {
+ //0111 0000 0000 0000
+ //rdrom
+ regs.romdata = dataROM[regs.a & 0x3ff];
+ }
+
+ else if((opcode & 0xff00) == 0x7c00) {
+ //0111 1100 .... ....
+ regs.p = (regs.p & 0xff00) | ((opcode & 0xff) << 0);
+ }
+
+ else if((opcode & 0xff00) == 0x7d00) {
+ //0111 1101 .... ....
+ regs.p = (regs.p & 0x00ff) | ((opcode & 0xff) << 8);
+ }
+
+ else if((opcode & 0xf800) == 0x8000) {
+ //1000 0... .... ....
+ //add a< 0xffffff;
+ }
+
+ else if((opcode & 0xf800) == 0x8800) {
+ //1000 1... .... ....
+ //rsb a<= 0;
+ }
+
+ else if((opcode & 0xf800) == 0x9000) {
+ //1001 0... .... ....
+ //sub a<= 0;
+ }
+
+ else if((opcode & 0xfb00) == 0x9800) {
+ //1001 1.00 .... ....
+ //mul a,ri
+ int64 x = (int24)regs.a;
+ int64 y = (int24)ri();
+ x *= y;
+ regs.accl = x >> 0ull;
+ regs.acch = x >> 24ull;
+ regs.n = regs.acch & 0x800000;
+ regs.z = x == 0;
+ }
+
+ else if((opcode & 0xf800) == 0xa800) {
+ //1010 1... .... ....
+ //xor a,ri
+ regs.a = sa() ^ ri();
+ regs.n = regs.a & 0x800000;
+ regs.z = regs.a == 0;
+ }
+
+ else if((opcode & 0xf800) == 0xb000) {
+ //1011 0... .... ....
+ //and a<> ri();
+ regs.n = regs.a & 0x800000;
+ regs.z = regs.a == 0;
+ }
+
+ else if((opcode & 0xfb00) == 0xc800) {
+ //1100 1.00 .... ....
+ //asr a,ri
+ regs.a = (int24)regs.a >> ri();
+ regs.n = regs.a & 0x800000;
+ regs.z = regs.a == 0;
+ }
+
+ else if((opcode & 0xfb00) == 0xd000) {
+ //1101 0.00 .... ....
+ //ror a,ri
+ uint24 length = ri();
+ regs.a = (regs.a >> length) | (regs.a << (24 - length));
+ regs.n = regs.a & 0x800000;
+ regs.z = regs.a == 0;
+ }
+
+ else if((opcode & 0xfb00) == 0xd800) {
+ //1101 1.00 .... ....
+ //shl a,ri
+ regs.a = regs.a << ri();
+ regs.n = regs.a & 0x800000;
+ regs.z = regs.a == 0;
+ }
+
+ else if((opcode & 0xff00) == 0xe000) {
+ //1110 0000 .... ....
+ //st r,a
+ reg_write(opcode & 0xff, regs.a);
+ }
+
+ else if((opcode & 0xfb00) == 0xe800) {
+ //1110 1.00 .... ....
+ //wrraml
+ uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
+ if(target < 0xc00) dataRAM[target] = regs.ramdata >> 0;
+ }
+
+ else if((opcode & 0xfb00) == 0xe900) {
+ //1110 1.01 .... ....
+ //wrramh
+ uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
+ if(target < 0xc00) dataRAM[target] = regs.ramdata >> 8;
+ }
+
+ else if((opcode & 0xfb00) == 0xea00) {
+ //1110 1.10 .... ....
+ //wrramb
+ uint24 target = ri() + (opcode & 0x0400 ? regs.ramaddr : (uint24)0);
+ if(target < 0xc00) dataRAM[target] = regs.ramdata >> 16;
+ }
+
+ else if((opcode & 0xff00) == 0xf000) {
+ //1111 0000 .... ....
+ //swap a,r
+ uint24 source = reg_read(opcode & 0xff);
+ uint24 target = regs.a;
+ regs.a = source;
+ reg_write(opcode & 0xff, target);
+ }
+
+ else if((opcode & 0xffff) == 0xfc00) {
+ //1111 1100 0000 0000
+ //halt
+ state = State::Idle;
+ }
+
+ else {
+ print("Hitachi DSP: invalid opcode @ ", hex<4>(regs.pc - 1), " = ", hex<4>(opcode), "\n");
+ state = State::Idle;
+ }
+}
+
+#endif
diff --git a/bsnes/snes/chip/hitachidsp/registers.cpp b/bsnes/snes/chip/hitachidsp/registers.cpp
new file mode 100755
index 000000000..396bdf3e6
--- /dev/null
+++ b/bsnes/snes/chip/hitachidsp/registers.cpp
@@ -0,0 +1,78 @@
+#ifdef HITACHIDSP_CPP
+
+unsigned HitachiDSP::reg_read(unsigned n) const {
+ switch(n) {
+ case 0x00: return regs.a;
+ case 0x01: return regs.acch;
+ case 0x02: return regs.accl;
+ case 0x03: return regs.busdata;
+ case 0x08: return regs.romdata;
+ case 0x0c: return regs.ramdata;
+ case 0x13: return regs.busaddr;
+ case 0x1c: return regs.ramaddr;
+ case 0x50: return 0x000000;
+ case 0x51: return 0xffffff;
+ case 0x52: return 0x00ff00;
+ case 0x53: return 0xff0000;
+ case 0x54: return 0x00ffff;
+ case 0x55: return 0xffff00;
+ case 0x56: return 0x800000;
+ case 0x57: return 0x7fffff;
+ case 0x58: return 0x008000;
+ case 0x59: return 0x007fff;
+ case 0x5a: return 0xff7fff;
+ case 0x5b: return 0xffff7f;
+ case 0x5c: return 0x010000;
+ case 0x5d: return 0xfeffff;
+ case 0x5e: return 0x000100;
+ case 0x5f: return 0x00feff;
+ case 0x60: return regs.gpr[ 0];
+ case 0x61: return regs.gpr[ 1];
+ case 0x62: return regs.gpr[ 2];
+ case 0x63: return regs.gpr[ 3];
+ case 0x64: return regs.gpr[ 4];
+ case 0x65: return regs.gpr[ 5];
+ case 0x66: return regs.gpr[ 6];
+ case 0x67: return regs.gpr[ 7];
+ case 0x68: return regs.gpr[ 8];
+ case 0x69: return regs.gpr[ 9];
+ case 0x6a: return regs.gpr[10];
+ case 0x6b: return regs.gpr[11];
+ case 0x6c: return regs.gpr[12];
+ case 0x6d: return regs.gpr[13];
+ case 0x6e: return regs.gpr[14];
+ case 0x6f: return regs.gpr[15];
+ }
+ return 0x000000;
+}
+
+void HitachiDSP::reg_write(unsigned n, unsigned data) {
+ switch(n) {
+ case 0x00: regs.a = data; return;
+ case 0x01: regs.acch = data; return;
+ case 0x02: regs.accl = data; return;
+ case 0x03: regs.busdata = data; return;
+ case 0x08: regs.romdata = data; return;
+ case 0x0c: regs.ramdata = data; return;
+ case 0x13: regs.busaddr = data; return;
+ case 0x1c: regs.ramaddr = data; return;
+ case 0x60: regs.gpr[ 0] = data; return;
+ case 0x61: regs.gpr[ 1] = data; return;
+ case 0x62: regs.gpr[ 2] = data; return;
+ case 0x63: regs.gpr[ 3] = data; return;
+ case 0x64: regs.gpr[ 4] = data; return;
+ case 0x65: regs.gpr[ 5] = data; return;
+ case 0x66: regs.gpr[ 6] = data; return;
+ case 0x67: regs.gpr[ 7] = data; return;
+ case 0x68: regs.gpr[ 8] = data; return;
+ case 0x69: regs.gpr[ 9] = data; return;
+ case 0x6a: regs.gpr[10] = data; return;
+ case 0x6b: regs.gpr[11] = data; return;
+ case 0x6c: regs.gpr[12] = data; return;
+ case 0x6d: regs.gpr[13] = data; return;
+ case 0x6e: regs.gpr[14] = data; return;
+ case 0x6f: regs.gpr[15] = data; return;
+ }
+}
+
+#endif
diff --git a/bsnes/snes/chip/hitachidsp/registers.hpp b/bsnes/snes/chip/hitachidsp/registers.hpp
new file mode 100755
index 000000000..73d2370f8
--- /dev/null
+++ b/bsnes/snes/chip/hitachidsp/registers.hpp
@@ -0,0 +1,31 @@
+struct Registers {
+ uint24 pc;
+ uint16 p;
+ bool n;
+ bool z;
+ bool c;
+
+ uint24 a;
+ uint24 acch;
+ uint24 accl;
+ uint24 busdata;
+ uint24 romdata;
+ uint24 ramdata;
+ uint24 busaddr;
+ uint24 ramaddr;
+ uint24 gpr[16];
+
+ //MMIO
+ uint24 dma_source; //$1f40-$1f42
+ uint24 dma_length; //$1f43-$1f44
+ uint24 dma_target; //$1f45-$1f47
+ uint8 r1f48; //$1f48
+ uint24 program_offset; //$1f49-$1f4b
+ uint8 r1f4c; //$1f4c
+ uint16 page_number; //$1f4d-$1f4e
+ uint8 program_counter; //$1f4f
+ uint8 r1f50; //$1f50
+ uint8 r1f51; //$1f51
+ uint8 r1f52; //$1f52
+ uint8 vector[32]; //$1f60-$1f7f
+} regs;
diff --git a/bsnes/snes/chip/hitachidsp/serialization.cpp b/bsnes/snes/chip/hitachidsp/serialization.cpp
new file mode 100755
index 000000000..5a50ae0da
--- /dev/null
+++ b/bsnes/snes/chip/hitachidsp/serialization.cpp
@@ -0,0 +1,41 @@
+#ifdef HITACHIDSP_CPP
+
+void HitachiDSP::serialize(serializer &s) {
+ Processor::serialize(s);
+
+ s.array(dataRAM);
+ foreach(n, stack) s.integer(n);
+ s.integer(opcode);
+ s.integer((unsigned&)state);
+
+ s.integer(regs.pc);
+ s.integer(regs.p);
+ s.integer(regs.n);
+ s.integer(regs.z);
+ s.integer(regs.c);
+
+ s.integer(regs.a);
+ s.integer(regs.acch);
+ s.integer(regs.accl);
+ s.integer(regs.busdata);
+ s.integer(regs.romdata);
+ s.integer(regs.ramdata);
+ s.integer(regs.busaddr);
+ s.integer(regs.ramaddr);
+ foreach(n, regs.gpr) s.integer(n);
+
+ s.integer(regs.dma_source);
+ s.integer(regs.dma_length);
+ s.integer(regs.dma_target);
+ s.integer(regs.r1f48);
+ s.integer(regs.program_offset);
+ s.integer(regs.r1f4c);
+ s.integer(regs.page_number);
+ s.integer(regs.program_counter);
+ s.integer(regs.r1f50);
+ s.integer(regs.r1f51);
+ s.integer(regs.r1f52);
+ s.array(regs.vector);
+}
+
+#endif
diff --git a/bsnes/snes/chip/necdsp/necdsp.hpp b/bsnes/snes/chip/necdsp/necdsp.hpp
index b22eef8ca..3c041cf76 100755
--- a/bsnes/snes/chip/necdsp/necdsp.hpp
+++ b/bsnes/snes/chip/necdsp/necdsp.hpp
@@ -1,3 +1,6 @@
+//NEC uPD7725
+//NEC uPD96050
+
class NECDSP : public Coprocessor {
public:
enum class Revision : unsigned { uPD7725, uPD96050 } revision;
diff --git a/bsnes/snes/chip/necdsp/serialization.cpp b/bsnes/snes/chip/necdsp/serialization.cpp
index b7a166199..a06510f83 100755
--- a/bsnes/snes/chip/necdsp/serialization.cpp
+++ b/bsnes/snes/chip/necdsp/serialization.cpp
@@ -1,6 +1,8 @@
#ifdef NECDSP_CPP
void NECDSP::serialize(serializer &s) {
+ Processor::serialize(s);
+
s.array(dataRAM);
s.array(regs.stack);
diff --git a/bsnes/snes/chip/obc1/obc1.cpp b/bsnes/snes/chip/obc1/obc1.cpp
index e5e1f3420..6f0da8c3f 100755
--- a/bsnes/snes/chip/obc1/obc1.cpp
+++ b/bsnes/snes/chip/obc1/obc1.cpp
@@ -3,9 +3,8 @@
#define OBC1_CPP
namespace SNES {
-OBC1 obc1;
-
#include "serialization.cpp"
+OBC1 obc1;
void OBC1::init() {
}
@@ -30,45 +29,46 @@ void OBC1::reset() {
uint8 OBC1::read(unsigned addr) {
addr &= 0x1fff;
- if((addr & 0x1ff8) != 0x1ff0) return ram_read(addr);
- switch(addr) { default: //never used, avoids compiler warning
- case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0);
- case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1);
- case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2);
- case 0x1ff3: return ram_read(status.baseptr + (status.address << 2) + 3);
- case 0x1ff4: return ram_read(status.baseptr + (status.address >> 2) + 0x200);
- case 0x1ff5: case 0x1ff6: case 0x1ff7: return ram_read(addr);
+ switch(addr) {
+ case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0);
+ case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1);
+ case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2);
+ case 0x1ff3: return ram_read(status.baseptr + (status.address << 2) + 3);
+ case 0x1ff4: return ram_read(status.baseptr + (status.address >> 2) + 0x200);
}
+
+ return ram_read(addr);
}
void OBC1::write(unsigned addr, uint8 data) {
addr &= 0x1fff;
- if((addr & 0x1ff8) != 0x1ff0) return ram_write(addr, data);
switch(addr) {
- case 0x1ff0: ram_write(status.baseptr + (status.address << 2) + 0, data); break;
- case 0x1ff1: ram_write(status.baseptr + (status.address << 2) + 1, data); break;
- case 0x1ff2: ram_write(status.baseptr + (status.address << 2) + 2, data); break;
- case 0x1ff3: ram_write(status.baseptr + (status.address << 2) + 3, data); break;
- case 0x1ff4: {
- uint8 temp = ram_read(status.baseptr + (status.address >> 2) + 0x200);
- temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift);
- ram_write(status.baseptr + (status.address >> 2) + 0x200, temp);
- } break;
- case 0x1ff5: {
- status.baseptr = (data & 1) ? 0x1800 : 0x1c00;
- ram_write(addr, data);
- } break;
- case 0x1ff6: {
- status.address = (data & 0x7f);
- status.shift = (data & 3) << 1;
- ram_write(addr, data);
- } break;
- case 0x1ff7: {
- ram_write(addr, data);
- } break;
+ case 0x1ff0: ram_write(status.baseptr + (status.address << 2) + 0, data); return;
+ case 0x1ff1: ram_write(status.baseptr + (status.address << 2) + 1, data); return;
+ case 0x1ff2: ram_write(status.baseptr + (status.address << 2) + 2, data); return;
+ case 0x1ff3: ram_write(status.baseptr + (status.address << 2) + 3, data); return;
+ case 0x1ff4: {
+ uint8 temp = ram_read(status.baseptr + (status.address >> 2) + 0x200);
+ temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift);
+ ram_write(status.baseptr + (status.address >> 2) + 0x200, temp);
+ } return;
+ case 0x1ff5:
+ status.baseptr = (data & 1) ? 0x1800 : 0x1c00;
+ ram_write(addr, data);
+ return;
+ case 0x1ff6:
+ status.address = (data & 0x7f);
+ status.shift = (data & 3) << 1;
+ ram_write(addr, data);
+ return;
+ case 0x1ff7:
+ ram_write(addr, data);
+ return;
}
+
+ return ram_write(addr, data);
}
uint8 OBC1::ram_read(unsigned addr) {
@@ -79,7 +79,4 @@ void OBC1::ram_write(unsigned addr, uint8 data) {
cartridge.ram.write(addr & 0x1fff, data);
}
-OBC1::OBC1() {}
-OBC1::~OBC1() {}
-
}
diff --git a/bsnes/snes/chip/obc1/obc1.hpp b/bsnes/snes/chip/obc1/obc1.hpp
index b9ced5d5e..686adbc98 100755
--- a/bsnes/snes/chip/obc1/obc1.hpp
+++ b/bsnes/snes/chip/obc1/obc1.hpp
@@ -10,8 +10,6 @@ public:
void write(unsigned addr, uint8 data);
void serialize(serializer&);
- OBC1();
- ~OBC1();
private:
uint8 ram_read(unsigned addr);
diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp
index ab1f2885d..ec18e2d65 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[] = "079.03";
- static const unsigned SerializerVersion = 20;
+ static const char Version[] = "079.04";
+ static const unsigned SerializerVersion = 21;
}
}
@@ -44,6 +44,8 @@ namespace SNES {
typedef int32_t int32;
typedef int64_t int64;
+ typedef int_t<24> int24;
+
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
diff --git a/bsnes/snes/system/serialization.cpp b/bsnes/snes/system/serialization.cpp
index 693247dd4..660ce8f49 100755
--- a/bsnes/snes/system/serialization.cpp
+++ b/bsnes/snes/system/serialization.cpp
@@ -62,10 +62,10 @@ void System::serialize_all(serializer &s) {
if(cartridge.has_superfx()) superfx.serialize(s);
if(cartridge.has_sa1()) sa1.serialize(s);
if(cartridge.has_necdsp()) necdsp.serialize(s);
+ if(cartridge.has_hitachidsp()) hitachidsp.serialize(s);
if(cartridge.has_srtc()) srtc.serialize(s);
if(cartridge.has_sdd1()) sdd1.serialize(s);
if(cartridge.has_spc7110()) spc7110.serialize(s);
- if(cartridge.has_cx4()) cx4.serialize(s);
if(cartridge.has_obc1()) obc1.serialize(s);
if(cartridge.has_msu1()) msu1.serialize(s);
if(cartridge.has_serial()) serial.serialize(s);
diff --git a/bsnes/snes/system/system.cpp b/bsnes/snes/system/system.cpp
index ee014da5d..1efd2013f 100755
--- a/bsnes/snes/system/system.cpp
+++ b/bsnes/snes/system/system.cpp
@@ -74,13 +74,13 @@ void System::init(Interface *interface_) {
superfx.init();
sa1.init();
necdsp.init();
+ hitachidsp.init();
bsxsatellaview.init();
bsxcartridge.init();
bsxflash.init();
srtc.init();
sdd1.init();
spc7110.init();
- cx4.init();
obc1.init();
st0018.init();
msu1.init();
@@ -117,10 +117,10 @@ void System::load() {
if(cartridge.has_superfx()) superfx.load();
if(cartridge.has_sa1()) sa1.load();
if(cartridge.has_necdsp()) necdsp.load();
+ if(cartridge.has_hitachidsp()) hitachidsp.load();
if(cartridge.has_srtc()) srtc.load();
if(cartridge.has_sdd1()) sdd1.load();
if(cartridge.has_spc7110()) spc7110.load();
- if(cartridge.has_cx4()) cx4.load();
if(cartridge.has_obc1()) obc1.load();
if(cartridge.has_st0018()) st0018.load();
if(cartridge.has_msu1()) msu1.load();
@@ -142,10 +142,10 @@ void System::unload() {
if(cartridge.has_superfx()) superfx.unload();
if(cartridge.has_sa1()) sa1.unload();
if(cartridge.has_necdsp()) necdsp.unload();
+ if(cartridge.has_hitachidsp()) hitachidsp.unload();
if(cartridge.has_srtc()) srtc.unload();
if(cartridge.has_sdd1()) sdd1.unload();
if(cartridge.has_spc7110()) spc7110.unload();
- if(cartridge.has_cx4()) cx4.unload();
if(cartridge.has_obc1()) obc1.unload();
if(cartridge.has_st0018()) st0018.unload();
if(cartridge.has_msu1()) msu1.unload();
@@ -179,10 +179,10 @@ void System::power() {
if(cartridge.has_superfx()) superfx.power();
if(cartridge.has_sa1()) sa1.power();
if(cartridge.has_necdsp()) necdsp.power();
+ if(cartridge.has_hitachidsp()) hitachidsp.power();
if(cartridge.has_srtc()) srtc.power();
if(cartridge.has_sdd1()) sdd1.power();
if(cartridge.has_spc7110()) spc7110.power();
- if(cartridge.has_cx4()) cx4.power();
if(cartridge.has_obc1()) obc1.power();
if(cartridge.has_st0018()) st0018.power();
if(cartridge.has_msu1()) msu1.power();
@@ -193,6 +193,7 @@ void System::power() {
if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx);
if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1);
if(cartridge.has_necdsp()) cpu.coprocessors.append(&necdsp);
+ if(cartridge.has_hitachidsp()) cpu.coprocessors.append(&hitachidsp);
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
if(cartridge.has_serial()) cpu.coprocessors.append(&serial);
if(cartridge.has_link()) cpu.coprocessors.append(&link);
@@ -217,10 +218,10 @@ void System::reset() {
if(cartridge.has_superfx()) superfx.reset();
if(cartridge.has_sa1()) sa1.reset();
if(cartridge.has_necdsp()) necdsp.reset();
+ if(cartridge.has_hitachidsp()) hitachidsp.reset();
if(cartridge.has_srtc()) srtc.reset();
if(cartridge.has_sdd1()) sdd1.reset();
if(cartridge.has_spc7110()) spc7110.reset();
- if(cartridge.has_cx4()) cx4.reset();
if(cartridge.has_obc1()) obc1.reset();
if(cartridge.has_st0018()) st0018.reset();
if(cartridge.has_msu1()) msu1.reset();
@@ -231,6 +232,7 @@ void System::reset() {
if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx);
if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1);
if(cartridge.has_necdsp()) cpu.coprocessors.append(&necdsp);
+ if(cartridge.has_hitachidsp()) cpu.coprocessors.append(&hitachidsp);
if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1);
if(cartridge.has_serial()) cpu.coprocessors.append(&serial);
if(cartridge.has_link()) cpu.coprocessors.append(&link);