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