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);