From 3302398907f370a3e4e90fa4d80e74dcc1f356de Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 29 May 2012 22:20:46 +1000 Subject: [PATCH] Update to v089r09 release. byuu says: Changelog: - SPC7110 data port emulation greatly improved - SPC7110 $480b.d1 emulated (but $4805-4806 does not work right for mode 2 decompression yet) - MSU1 audio output will be muted when the S-DSP FLG ($6c).d6 (mute) flag is set - MSU1 will read filenames from manifest now (defaults to msu1.rom and track-#.pcm if missing ... for now) - bugfixes with MSU1 load state and track seek (and $4804 was wrapping into $4805 to change the track#) - Link coprocessor removed (it was meant for ST018 HLE, which never happened) Notes for things I forgot but need to address: - $4813 needs to be uint7 for the set_data_offset() to not allow reading A23 as set ever (or we can mask) - AbsoluteInput when window doesn't have focus should return -32768, not 0 - need to support input ID lists that aren't linear (0-7), but arbitrary (0,1,6,7 or whatever) --- bsnes/emulator/emulator.hpp | 2 +- bsnes/sfc/Makefile | 3 +- bsnes/sfc/alt/dsp/SPC_DSP.h | 3 + bsnes/sfc/alt/dsp/dsp.cpp | 4 ++ bsnes/sfc/alt/dsp/dsp.hpp | 1 + bsnes/sfc/cartridge/cartridge.cpp | 2 +- bsnes/sfc/cartridge/cartridge.hpp | 3 +- bsnes/sfc/cartridge/markup.cpp | 49 ++++---------- bsnes/sfc/chip/chip.hpp | 1 - bsnes/sfc/chip/link/link.cpp | 56 ---------------- bsnes/sfc/chip/link/link.hpp | 23 ------- bsnes/sfc/chip/msu1/msu1.cpp | 81 +++++++++++++++++------- bsnes/sfc/chip/msu1/msu1.hpp | 4 ++ bsnes/sfc/chip/msu1/serialization.cpp | 13 ++-- bsnes/sfc/chip/spc7110/data.cpp | 61 ++++++++---------- bsnes/sfc/chip/spc7110/dcu.cpp | 6 +- bsnes/sfc/chip/spc7110/serialization.cpp | 3 - bsnes/sfc/chip/spc7110/spc7110.cpp | 40 +++++------- bsnes/sfc/chip/spc7110/spc7110.hpp | 60 +++++++++--------- bsnes/sfc/dsp/dsp.cpp | 4 ++ bsnes/sfc/dsp/dsp.hpp | 1 + bsnes/sfc/system/system.cpp | 6 -- 22 files changed, 168 insertions(+), 258 deletions(-) delete mode 100755 bsnes/sfc/chip/link/link.cpp delete mode 100755 bsnes/sfc/chip/link/link.hpp diff --git a/bsnes/emulator/emulator.hpp b/bsnes/emulator/emulator.hpp index 4e55060d..7dd97846 100755 --- a/bsnes/emulator/emulator.hpp +++ b/bsnes/emulator/emulator.hpp @@ -3,7 +3,7 @@ namespace Emulator { static const char Name[] = "bsnes"; - static const char Version[] = "089.08"; + static const char Version[] = "089.09"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; } diff --git a/bsnes/sfc/Makefile b/bsnes/sfc/Makefile index b9f7969b..806cf6d1 100755 --- a/bsnes/sfc/Makefile +++ b/bsnes/sfc/Makefile @@ -6,7 +6,7 @@ sfc_objects += sfc-sa1 sfc-superfx sfc_objects += sfc-armdsp sfc-hitachidsp sfc-necdsp sfc_objects += sfc-epsonrtc sfc-sharprtc sfc_objects += sfc-spc7110 sfc-sdd1 sfc-obc1 -sfc_objects += sfc-msu1 sfc-link +sfc_objects += sfc-msu1 objects += $(sfc_objects) ifeq ($(profile),accuracy) @@ -60,4 +60,3 @@ obj/sfc-sdd1.o : $(sfc)/chip/sdd1/sdd1.cpp $(sfc)/chip/sdd1/* obj/sfc-obc1.o : $(sfc)/chip/obc1/obc1.cpp $(sfc)/chip/obc1/* obj/sfc-msu1.o : $(sfc)/chip/msu1/msu1.cpp $(sfc)/chip/msu1/* -obj/sfc-link.o : $(sfc)/chip/link/link.cpp $(sfc)/chip/link/* diff --git a/bsnes/sfc/alt/dsp/SPC_DSP.h b/bsnes/sfc/alt/dsp/SPC_DSP.h index 4522ace9..62095a5b 100755 --- a/bsnes/sfc/alt/dsp/SPC_DSP.h +++ b/bsnes/sfc/alt/dsp/SPC_DSP.h @@ -231,6 +231,9 @@ private: void echo_30(); void soft_reset_common(); + +public: + bool mute() { return m.regs[r_flg] & 0x40; } }; #include diff --git a/bsnes/sfc/alt/dsp/dsp.cpp b/bsnes/sfc/alt/dsp/dsp.cpp index 7974b7d3..1648277e 100755 --- a/bsnes/sfc/alt/dsp/dsp.cpp +++ b/bsnes/sfc/alt/dsp/dsp.cpp @@ -31,6 +31,10 @@ void DSP::enter() { } } +bool DSP::mute() { + return spc_dsp.mute(); +} + uint8 DSP::read(uint8 addr) { return spc_dsp.read(addr); } diff --git a/bsnes/sfc/alt/dsp/dsp.hpp b/bsnes/sfc/alt/dsp/dsp.hpp index fc89d1a0..5114efb0 100755 --- a/bsnes/sfc/alt/dsp/dsp.hpp +++ b/bsnes/sfc/alt/dsp/dsp.hpp @@ -5,6 +5,7 @@ struct DSP : Thread { alwaysinline void step(unsigned clocks); alwaysinline void synchronize_smp(); + bool mute(); uint8 read(uint8 addr); void write(uint8 addr, uint8 data); diff --git a/bsnes/sfc/cartridge/cartridge.cpp b/bsnes/sfc/cartridge/cartridge.cpp index a9e65f19..8c8f671f 100755 --- a/bsnes/sfc/cartridge/cartridge.cpp +++ b/bsnes/sfc/cartridge/cartridge.cpp @@ -26,8 +26,8 @@ void Cartridge::load(const string &manifest) { has_sdd1 = false; has_obc1 = false; has_msu1 = false; - has_link = false; + this->manifest = manifest; parse_markup(manifest); //print(manifest, "\n\n"); diff --git a/bsnes/sfc/cartridge/cartridge.hpp b/bsnes/sfc/cartridge/cartridge.hpp index c14de4e0..fd86aab6 100755 --- a/bsnes/sfc/cartridge/cartridge.hpp +++ b/bsnes/sfc/cartridge/cartridge.hpp @@ -18,6 +18,7 @@ struct Cartridge : property { readonly loaded; readonly sha256; + readonly manifest; readonly region; @@ -37,7 +38,6 @@ struct Cartridge : property { readonly has_sdd1; readonly has_obc1; readonly has_msu1; - readonly has_link; struct Mapping { function read; @@ -95,7 +95,6 @@ private: void parse_markup_sdd1(XML::Node&); void parse_markup_obc1(XML::Node&); void parse_markup_msu1(XML::Node&); - void parse_markup_link(XML::Node&); }; extern Cartridge cartridge; diff --git a/bsnes/sfc/cartridge/markup.cpp b/bsnes/sfc/cartridge/markup.cpp index 2e00fe1e..5371b222 100755 --- a/bsnes/sfc/cartridge/markup.cpp +++ b/bsnes/sfc/cartridge/markup.cpp @@ -24,7 +24,6 @@ void Cartridge::parse_markup(const char *markup) { parse_markup_sdd1(cartridge["sdd1"]); parse_markup_obc1(cartridge["obc1"]); parse_markup_msu1(cartridge["msu1"]); - parse_markup_link(cartridge["link"]); } // @@ -294,7 +293,7 @@ void Cartridge::parse_markup_armdsp(XML::Node &root) { for(auto &node : root) { if(node.name != "map") continue; - Mapping m({ &ArmDSP::mmio_read, &armdsp }, { &ArmDSP::mmio_write, &armdsp }); + Mapping m({&ArmDSP::mmio_read, &armdsp}, {&ArmDSP::mmio_write, &armdsp}); parse_markup_map(m, node); mapping.append(m); } @@ -317,14 +316,14 @@ void Cartridge::parse_markup_hitachidsp(XML::Node &root) { if(node.name == "rom") { for(auto &leaf : node) { if(leaf.name != "map") continue; - Mapping m({ &HitachiDSP::rom_read, &hitachidsp }, { &HitachiDSP::rom_write, &hitachidsp }); + Mapping m({&HitachiDSP::rom_read, &hitachidsp}, {&HitachiDSP::rom_write, &hitachidsp}); parse_markup_map(m, leaf); mapping.append(m); } } if(node.name == "mmio") { for(auto &leaf : node) { - Mapping m({ &HitachiDSP::dsp_read, &hitachidsp }, { &HitachiDSP::dsp_write, &hitachidsp }); + Mapping m({&HitachiDSP::dsp_read, &hitachidsp}, {&HitachiDSP::dsp_write, &hitachidsp}); parse_markup_map(m, leaf); mapping.append(m); } @@ -362,21 +361,21 @@ void Cartridge::parse_markup_necdsp(XML::Node &root) { for(auto &node : root) { if(node.name == "dr") { for(auto &leaf : node) { - Mapping m({ &NECDSP::dr_read, &necdsp }, { &NECDSP::dr_write, &necdsp }); + Mapping m({&NECDSP::dr_read, &necdsp}, {&NECDSP::dr_write, &necdsp}); parse_markup_map(m, leaf); mapping.append(m); } } if(node.name == "sr") { for(auto &leaf : node) { - Mapping m({ &NECDSP::sr_read, &necdsp }, { &NECDSP::sr_write, &necdsp }); + Mapping m({&NECDSP::sr_read, &necdsp}, {&NECDSP::sr_write, &necdsp}); parse_markup_map(m, leaf); mapping.append(m); } } if(node.name == "dp") { for(auto &leaf : node) { - Mapping m({ &NECDSP::dp_read, &necdsp }, { &NECDSP::dp_write, &necdsp }); + Mapping m({&NECDSP::dp_read, &necdsp}, {&NECDSP::dp_write, &necdsp}); parse_markup_map(m, leaf); mapping.append(m); } @@ -466,14 +465,14 @@ void Cartridge::parse_markup_sdd1(XML::Node &root) { for(auto &node : root["mmio"]) { if(node.name != "map") continue; - Mapping m({ &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 }); + Mapping m({&SDD1::mmio_read, &sdd1}, {&SDD1::mmio_write, &sdd1}); parse_markup_map(m, node); mapping.append(m); } for(auto &node : root["mcu"]) { if(node.name != "map") continue; - Mapping m({ &SDD1::mcu_read, &sdd1 }, { &SDD1::mcu_write, &sdd1 }); + Mapping m({&SDD1::mcu_read, &sdd1}, {&SDD1::mcu_write, &sdd1}); parse_markup_map(m, node); mapping.append(m); } @@ -485,45 +484,19 @@ void Cartridge::parse_markup_obc1(XML::Node &root) { for(auto &node : root) { if(node.name != "map") continue; - Mapping m({ &OBC1::read, &obc1 }, { &OBC1::write, &obc1 }); + Mapping m({&OBC1::read, &obc1}, {&OBC1::write, &obc1}); parse_markup_map(m, node); mapping.append(m); } } void Cartridge::parse_markup_msu1(XML::Node &root) { - if(root.exists() == false) { - has_msu1 = file::exists({interface->path(0), "msu1.rom"}); - if(has_msu1) { - Mapping m({ &MSU1::mmio_read, &msu1 }, { &MSU1::mmio_write, &msu1 }); - m.banklo = 0x00, m.bankhi = 0x3f, m.addrlo = 0x2000, m.addrhi = 0x2007; - mapping.append(m); - m.banklo = 0x80, m.bankhi = 0xbf, m.addrlo = 0x2000, m.addrhi = 0x2007; - mapping.append(m); - } - return; - } - + if(root.exists() == false) return; has_msu1 = true; for(auto &node : root) { if(node.name != "map") continue; - Mapping m({ &MSU1::mmio_read, &msu1 }, { &MSU1::mmio_write, &msu1 }); - parse_markup_map(m, node); - mapping.append(m); - } -} - -void Cartridge::parse_markup_link(XML::Node &root) { - if(root.exists() == false) return; - has_link = true; - - link.frequency = max(1, numeral(root["frequency"].data)); - link.program = root["program"].data; - - for(auto &node : root) { - if(node.name != "map") continue; - Mapping m({ &Link::read, &link }, { &Link::write, &link }); + Mapping m({&MSU1::mmio_read, &msu1}, {&MSU1::mmio_write, &msu1}); parse_markup_map(m, node); mapping.append(m); } diff --git a/bsnes/sfc/chip/chip.hpp b/bsnes/sfc/chip/chip.hpp index a37240fa..390e0a98 100755 --- a/bsnes/sfc/chip/chip.hpp +++ b/bsnes/sfc/chip/chip.hpp @@ -23,7 +23,6 @@ struct Coprocessor : Thread { #include #include -#include void Coprocessor::step(unsigned clocks) { clock += clocks * (uint64)cpu.frequency; diff --git a/bsnes/sfc/chip/link/link.cpp b/bsnes/sfc/chip/link/link.cpp deleted file mode 100755 index 6e89c581..00000000 --- a/bsnes/sfc/chip/link/link.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include - -#define LINK_HPP -namespace SuperFamicom { - -Link link; - -void Link::Enter() { link.enter(); } - -void Link::enter() { - while(true) { - cpu.synchronize_coprocessors(); - unsigned clocks = 1; - if(link_run) clocks = link_run(); - step(clocks); - synchronize_cpu(); - } -} - -void Link::init() { -} - -void Link::load() { - if(opened()) close(); - if(open("link.so", interface->path(0))) { - link_power = sym("link_power"); - link_reset = sym("link_reset"); - link_run = sym("link_run" ); - link_read = sym("link_read" ); - link_write = sym("link_write"); - } -} - -void Link::unload() { - if(opened()) close(); -} - -void Link::power() { - if(link_power) link_power(); -} - -void Link::reset() { - if(link_reset) link_reset(); - create(Link::Enter, frequency); -} - -uint8 Link::read(unsigned addr) { - if(link_read) return link_read(addr); - return cpu.regs.mdr; -} - -void Link::write(unsigned addr, uint8 data) { - if(link_write) return link_write(addr, data); -} - -} diff --git a/bsnes/sfc/chip/link/link.hpp b/bsnes/sfc/chip/link/link.hpp deleted file mode 100755 index 6736888b..00000000 --- a/bsnes/sfc/chip/link/link.hpp +++ /dev/null @@ -1,23 +0,0 @@ -struct Link : Coprocessor, library { - string program; - - static void Enter(); - void enter(); - void init(); - void load(); - void unload(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - -private: - function link_power; - function link_reset; - function link_run; - function link_read; - function link_write; -}; - -extern Link link; diff --git a/bsnes/sfc/chip/msu1/msu1.cpp b/bsnes/sfc/chip/msu1/msu1.cpp index 768c2691..c93362eb 100755 --- a/bsnes/sfc/chip/msu1/msu1.cpp +++ b/bsnes/sfc/chip/msu1/msu1.cpp @@ -10,7 +10,10 @@ MSU1 msu1; void MSU1::Enter() { msu1.enter(); } void MSU1::enter() { - for(unsigned addr = 0; addr <= 7; addr++) mmio_write(addr, 0x00); + if(boot == true) { + boot = false; + for(unsigned addr = 0x2000; addr <= 0x2007; addr++) mmio_write(addr, 0x00); + } while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { @@ -42,6 +45,7 @@ void MSU1::enter() { signed rchannel = (double)right * (double)mmio.audio_volume / 255.0; left = sclamp<16>(lchannel); right = sclamp<16>(rchannel); + if(dsp.mute()) left = 0, right = 0; audio.coprocessor_sample(left, right); step(1); @@ -53,12 +57,12 @@ void MSU1::init() { } void MSU1::load() { - if(datafile.open()) datafile.close(); - datafile.open({interface->path(0), "msu1.rom"}, file::mode::read); + data_open(); } void MSU1::unload() { if(datafile.open()) datafile.close(); + if(audiofile.open()) audiofile.close(); } void MSU1::power() { @@ -68,6 +72,7 @@ void MSU1::power() { void MSU1::reset() { create(MSU1::Enter, 44100); + boot = true; mmio.data_offset = 0; mmio.audio_offset = 0; @@ -80,52 +85,80 @@ void MSU1::reset() { mmio.audio_error = false; } +void MSU1::data_open() { + if(datafile.open()) datafile.close(); + XML::Document document(cartridge.manifest()); + string name = document["cartridge"]["msu1"]["rom"]["name"].data; + if(name.empty()) name = "msu1.rom"; + if(datafile.open({interface->path(0), name}, file::mode::read)) { + datafile.seek(mmio.data_offset); + } +} + +void MSU1::audio_open() { + if(audiofile.open()) audiofile.close(); + XML::Document document(cartridge.manifest()); + string name = {"track-", mmio.audio_track, ".pcm"}; + for(auto &track : document["cartridge"]["msu1"]) { + if(track.name != "track") continue; + if(numeral(track["number"].data) != mmio.audio_track) continue; + name = track["name"].data; + break; + } + if(audiofile.open({interface->path(0), name}, file::mode::read)) { + audiofile.seek(mmio.audio_offset); + } +} + uint8 MSU1::mmio_read(unsigned addr) { cpu.synchronize_coprocessors(); + addr = 0x2000 | (addr & 7); - switch(addr & 7) { - case 0: + switch(addr) { + case 0x2000: return (mmio.data_busy << 7) | (mmio.audio_busy << 6) | (mmio.audio_repeat << 5) | (mmio.audio_play << 4) | (mmio.audio_error << 3) | (Revision << 0); - case 1: + case 0x2001: if(mmio.data_busy) return 0x00; mmio.data_offset++; if(datafile.open()) return datafile.read(); return 0x00; - case 2: return 'S'; - case 3: return '-'; - case 4: return 'M'; - case 5: return 'S'; - case 6: return 'U'; - case 7: return '1'; + case 0x2002: return 'S'; + case 0x2003: return '-'; + case 0x2004: return 'M'; + case 0x2005: return 'S'; + case 0x2006: return 'U'; + case 0x2007: return '1'; } } void MSU1::mmio_write(unsigned addr, uint8 data) { cpu.synchronize_coprocessors(); + addr = 0x2000 | (addr & 7); - switch(addr & 7) { - case 0: mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0); break; - case 1: mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8); break; - case 2: mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16); break; - case 3: mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24); + switch(addr) { + case 0x2000: mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0); break; + case 0x2001: mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8); break; + case 0x2002: mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16); break; + case 0x2003: mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24); if(datafile.open()) datafile.seek(mmio.data_offset); mmio.data_busy = false; break; - case 4: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0); - case 5: mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8); - if(audiofile.open()) audiofile.close(); - if(audiofile.open({interface->path(0), "track-", mmio.audio_track, ".pcm"}, file::mode::read)) { + case 0x2004: mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0); break; + case 0x2005: mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8); + mmio.audio_offset = 0; + audio_open(); + if(audiofile.open()) { uint32 header = audiofile.readm(4); if(header != 0x4d535531) { //verify 'MSU1' header audiofile.close(); } else { - mmio.audio_offset = 8; mmio.audio_loop_offset = 8 + audiofile.readl(4) * 4; + mmio.audio_offset = 8; } } mmio.audio_busy = false; @@ -133,10 +166,10 @@ void MSU1::mmio_write(unsigned addr, uint8 data) { mmio.audio_play = false; mmio.audio_error = !audiofile.open(); break; - case 6: + case 0x2006: mmio.audio_volume = data; break; - case 7: + case 0x2007: mmio.audio_repeat = data & 2; mmio.audio_play = data & 1; break; diff --git a/bsnes/sfc/chip/msu1/msu1.hpp b/bsnes/sfc/chip/msu1/msu1.hpp index dba55531..9cb7d94f 100755 --- a/bsnes/sfc/chip/msu1/msu1.hpp +++ b/bsnes/sfc/chip/msu1/msu1.hpp @@ -7,12 +7,16 @@ struct MSU1 : Coprocessor { void power(); void reset(); + void data_open(); + void audio_open(); + uint8 mmio_read(unsigned addr); void mmio_write(unsigned addr, uint8 data); void serialize(serializer&); private: + bool boot; file datafile; file audiofile; diff --git a/bsnes/sfc/chip/msu1/serialization.cpp b/bsnes/sfc/chip/msu1/serialization.cpp index df505f86..dff6bd38 100755 --- a/bsnes/sfc/chip/msu1/serialization.cpp +++ b/bsnes/sfc/chip/msu1/serialization.cpp @@ -3,6 +3,8 @@ void MSU1::serialize(serializer &s) { Thread::serialize(s); + s.integer(boot); + s.integer(mmio.data_offset); s.integer(mmio.audio_offset); s.integer(mmio.audio_loop_offset); @@ -16,15 +18,8 @@ void MSU1::serialize(serializer &s) { s.integer(mmio.audio_play); s.integer(mmio.audio_error); - if(datafile.open()) datafile.close(); - if(datafile.open({interface->path(0), "msu1.rom"}, file::mode::read)) { - datafile.seek(mmio.data_offset); - } - - if(audiofile.open()) audiofile.close(); - if(audiofile.open({interface->path(0), "track-", mmio.audio_track, ".pcm"}, file::mode::read)) { - audiofile.seek(mmio.audio_offset); - } + data_open(); + audio_open(); } #endif diff --git a/bsnes/sfc/chip/spc7110/data.cpp b/bsnes/sfc/chip/spc7110/data.cpp index 1d07a9b5..b89cfe73 100755 --- a/bsnes/sfc/chip/spc7110/data.cpp +++ b/bsnes/sfc/chip/spc7110/data.cpp @@ -12,58 +12,51 @@ uint8 SPC7110::datarom_read(unsigned addr) { return cartridge.rom.read(drom_base + Bus::mirror(offset, drom_size)); } -unsigned SPC7110::data_offset() { return r4811 | r4812 << 8 | r4813 << 16; } -unsigned SPC7110::data_adjust() { return r4814 | r4815 << 8; } -unsigned SPC7110::data_increment() { return r4816 | r4817 << 8; } +unsigned SPC7110::data_offset() { return r4811 | r4812 << 8 | r4813 << 16; } +unsigned SPC7110::data_adjust() { return r4814 | r4815 << 8; } +unsigned SPC7110::data_stride() { return r4816 | r4817 << 8; } void SPC7110::set_data_offset(unsigned addr) { r4811 = addr; r4812 = addr >> 8; r4813 = addr >> 16; } void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; } void SPC7110::data_port_read() { unsigned offset = data_offset(); - unsigned adjust = data_adjust(); + unsigned adjust = r4818 & 2 ? data_adjust() : 0; if(r4818 & 8) adjust = (int16)adjust; - if(r4818 & 2) offset += adjust; - r4810 = datarom_read(offset); + r4810 = datarom_read(offset + adjust); } -void SPC7110::data_port_increment_a() { +void SPC7110::data_port_increment_4810() { + unsigned offset = data_offset(); + unsigned stride = r4818 & 1 ? data_stride() : 1; unsigned adjust = data_adjust(); + if(r4818 & 4) stride = (int16)stride; if(r4818 & 8) adjust = (int16)adjust; - if(r4818 & 2) return set_data_adjust(adjust + 1); - - unsigned increment = r4818 & 1 ? data_increment() : 1u; - if(r4818 & 4) increment = (int16)increment; - - if((r4818 & 16) == 0) set_data_offset(data_offset() + increment); - if((r4818 & 16) != 0) set_data_adjust(adjust + increment); + if((r4818 & 16) == 0) set_data_offset(offset + stride); + if((r4818 & 16) != 0) set_data_adjust(adjust + stride); } -void SPC7110::data_port_increment_b() { - if(r4818 >> 5 != 3) return; - +void SPC7110::data_port_increment_4814() { + if(r4818 >> 5 != 1) return; unsigned offset = data_offset(); unsigned adjust = data_adjust(); if(r4818 & 8) adjust = (int16)adjust; - - if((r4818 & 16) == 0) set_data_offset(offset + adjust); - if((r4818 & 16) != 0) set_data_adjust(adjust + adjust); + set_data_offset(offset + adjust); } -void SPC7110::data_port_increment_c() { - if((r4818 & 2) == 0) return; - if(r4818 & 16) return; +void SPC7110::data_port_increment_4815() { + if(r4818 >> 5 != 2) return; + unsigned offset = data_offset(); + unsigned adjust = data_adjust(); + if(r4818 & 8) adjust = (int16)adjust; + set_data_offset(offset + adjust); +} - if(r4818 >> 5 == 1) { - unsigned increment = data_adjust() & 0xff; - if(r4818 & 8) increment = (int8)increment; - set_data_offset(data_offset() + increment); - } - - if(r4818 >> 5 == 2) { - unsigned increment = data_adjust(); - if(r4818 & 8) increment = (int16)increment; - set_data_offset(data_offset() + increment); - } +void SPC7110::data_port_increment_481a() { + if(r4818 >> 5 != 3) return; + unsigned offset = data_offset(); + unsigned adjust = data_adjust(); + if(r4818 & 8) adjust = (int16)adjust; + set_data_offset(offset + adjust); } #endif diff --git a/bsnes/sfc/chip/spc7110/dcu.cpp b/bsnes/sfc/chip/spc7110/dcu.cpp index e6342a3e..99d7ccad 100755 --- a/bsnes/sfc/chip/spc7110/dcu.cpp +++ b/bsnes/sfc/chip/spc7110/dcu.cpp @@ -26,8 +26,10 @@ void SPC7110::dcu_begin_transfer() { ctx.invert = 0; } - unsigned seek = (r4805 | r4806 << 8) << dcu_mode; - while(seek--) dcu_read(); + if(r480b & 2) { + unsigned seek = (r4805 | r4806 << 8) << dcu_mode; + while(seek--) dcu_read(); + } } uint8 SPC7110::dcu_read() { diff --git a/bsnes/sfc/chip/spc7110/serialization.cpp b/bsnes/sfc/chip/spc7110/serialization.cpp index 180959a6..33e4fc31 100755 --- a/bsnes/sfc/chip/spc7110/serialization.cpp +++ b/bsnes/sfc/chip/spc7110/serialization.cpp @@ -36,9 +36,6 @@ void SPC7110::serialize(serializer &s) { s.integer(r4818); s.integer(r481a); - s.integer(r4814_latch); - s.integer(r4815_latch); - s.integer(r4820); s.integer(r4821); s.integer(r4822); diff --git a/bsnes/sfc/chip/spc7110/spc7110.cpp b/bsnes/sfc/chip/spc7110/spc7110.cpp index 50fecbe6..22dd357d 100755 --- a/bsnes/sfc/chip/spc7110/spc7110.cpp +++ b/bsnes/sfc/chip/spc7110/spc7110.cpp @@ -68,9 +68,6 @@ void SPC7110::reset() { r4818 = 0x00; r481a = 0x00; - r4814_latch = false; - r4815_latch = false; - r4820 = 0x00; r4821 = 0x00; r4822 = 0x00; @@ -100,7 +97,7 @@ void SPC7110::reset() { uint8 SPC7110::mmio_read(unsigned addr) { cpu.synchronize_coprocessors(); - addr &= 0xffff; + addr = 0x4800 | (addr & 0x3f); switch(addr) { @@ -138,7 +135,7 @@ uint8 SPC7110::mmio_read(unsigned addr) { case 0x4810: { uint8 data = r4810; - data_port_increment_a(); + data_port_increment_4810(); data_port_read(); return data; } @@ -151,13 +148,13 @@ uint8 SPC7110::mmio_read(unsigned addr) { case 0x4817: return r4817; case 0x4818: return r4818; case 0x481a: { - data_port_increment_b(); + data_port_increment_481a(); return 0x00; } - //========= - //math unit - //========= + //===================== + //arithmetic logic unit + //===================== case 0x4820: return r4820; case 0x4821: return r4821; @@ -177,7 +174,7 @@ uint8 SPC7110::mmio_read(unsigned addr) { case 0x482f: return r482f; //=================== - //memory mapping unit + //memory control unit //=================== case 0x4830: return r4830; @@ -193,7 +190,7 @@ uint8 SPC7110::mmio_read(unsigned addr) { void SPC7110::mmio_write(unsigned addr, uint8 data) { cpu.synchronize_coprocessors(); - addr &= 0xffff; + addr = 0x4800 | (addr & 0x3f); switch(addr) { @@ -220,22 +217,15 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) { case 0x4811: r4811 = data; break; case 0x4812: r4812 = data; break; case 0x4813: r4813 = data & 0x7f; data_port_read(); break; - case 0x4814: - case 0x4815: { - if((addr & 1) == 0) r4814 = data, r4814_latch = true; - if((addr & 1) == 1) r4815 = data, r4815_latch = true; - if(r4814_latch && r4815_latch) data_port_increment_c(); - } break; + case 0x4814: r4814 = data; data_port_increment_4814(); break; + case 0x4815: r4815 = data; data_port_increment_4815(); break; case 0x4816: r4816 = data; break; case 0x4817: r4817 = data; break; - case 0x4818: r4818 = data & 0x7f; { - r4814_latch = r4815_latch = false; - data_port_read(); - } break; + case 0x4818: r4818 = data & 0x7f; data_port_read(); break; - //========= - //math unit - //========= + //===================== + //arithmetic logic unit + //===================== case 0x4820: r4820 = data; break; case 0x4821: r4821 = data; break; @@ -248,7 +238,7 @@ void SPC7110::mmio_write(unsigned addr, uint8 data) { case 0x482e: r482e = data & 0x01; break; //=================== - //memory mapping unit + //memory control unit //=================== case 0x4830: r4830 = data & 0x87; break; diff --git a/bsnes/sfc/chip/spc7110/spc7110.hpp b/bsnes/sfc/chip/spc7110/spc7110.hpp index 33ff6985..ea4c7153 100755 --- a/bsnes/sfc/chip/spc7110/spc7110.hpp +++ b/bsnes/sfc/chip/spc7110/spc7110.hpp @@ -59,16 +59,17 @@ struct SPC7110 : Coprocessor { unsigned data_offset(); unsigned data_adjust(); - unsigned data_increment(); + unsigned data_stride(); void set_data_offset(unsigned addr); void set_data_adjust(unsigned addr); void data_port_read(); - void data_port_increment_a(); - void data_port_increment_b(); - void data_port_increment_c(); + void data_port_increment_4810(); + void data_port_increment_4814(); + void data_port_increment_4815(); + void data_port_increment_481a(); //alu.cpp void alu_multiply(); @@ -78,16 +79,16 @@ private: //================== //decompression unit //================== - uint8 r4801; //compression table low - uint8 r4802; //compression table high - uint8 r4803; //compression table bank + uint8 r4801; //compression table B0 + uint8 r4802; //compression table B1 + uint8 r4803; //compression table B2 uint8 r4804; //compression table index - uint8 r4805; //decompression buffer index low - uint8 r4806; //decompression buffer index high + uint8 r4805; //decompression buffer index B0 + uint8 r4806; //decompression buffer index B1 uint8 r4807; //deinterleave length - uint8 r4809; //compression length low - uint8 r480a; //compression length high - uint8 r480b; //deinterleave enable + uint8 r4809; //compression counter B0 + uint8 r480a; //compression counter B1 + uint8 r480b; //decompression settings uint8 r480c; //decompression status uint2 dcu_mode; @@ -109,23 +110,20 @@ private: //============== //data port unit //============== - uint8 r4810; //data port A - uint8 r4811; //data offset low - uint8 r4812; //data offset high - uint8 r4813; //data offset bank - uint8 r4814; //data adjust low - uint8 r4815; //data adjust high - uint8 r4816; //data increment low - uint8 r4817; //data increment high - uint8 r4818; //data port control register - uint8 r481a; //data port B + uint8 r4810; //data port read + seek + uint8 r4811; //data offset B0 + uint8 r4812; //data offset B1 + uint8 r4813; //data offset B2 + uint8 r4814; //data adjust B0 + uint8 r4815; //data adjust B1 + uint8 r4816; //data stride B0 + uint8 r4817; //data stride B1 + uint8 r4818; //data port settings + uint8 r481a; //data port seek - bool r4814_latch; - bool r4815_latch; - - //========= - //math unit - //========= + //===================== + //arithmetic logic unit + //===================== uint8 r4820; //16-bit multiplicand B0, 32-bit dividend B0 uint8 r4821; //16-bit multiplicand B1, 32-bit dividend B1 uint8 r4822; //32-bit dividend B2 @@ -140,20 +138,20 @@ private: uint8 r482b; //32-bit product B3, 32-bit quotient B3 uint8 r482c; //16-bit remainder B0 uint8 r482d; //16-bit remainder B1 - uint8 r482e; //math sign extend mode + uint8 r482e; //math settings uint8 r482f; //math status unsigned mul_wait; unsigned div_wait; //=================== - //memory mapping unit + //memory control unit //=================== uint8 r4830; //bank 0 mapping + SRAM write enable uint8 r4831; //bank 1 mapping uint8 r4832; //bank 2 mapping uint8 r4833; //bank 3 mapping - uint8 r4834; //bank mapping control + uint8 r4834; //bank mapping settings }; extern SPC7110 spc7110; diff --git a/bsnes/sfc/dsp/dsp.cpp b/bsnes/sfc/dsp/dsp.cpp index 088fce59..81604b3f 100755 --- a/bsnes/sfc/dsp/dsp.cpp +++ b/bsnes/sfc/dsp/dsp.cpp @@ -199,6 +199,10 @@ void DSP::tick() { /* register interface for S-SMP $00f2,$00f3 */ +bool DSP::mute() { + return state.regs[r_flg] & 0x40; +} + uint8 DSP::read(uint8 addr) { return state.regs[addr]; } diff --git a/bsnes/sfc/dsp/dsp.hpp b/bsnes/sfc/dsp/dsp.hpp index 8700396c..41298911 100755 --- a/bsnes/sfc/dsp/dsp.hpp +++ b/bsnes/sfc/dsp/dsp.hpp @@ -3,6 +3,7 @@ struct DSP : Thread { alwaysinline void step(unsigned clocks); alwaysinline void synchronize_smp(); + bool mute(); uint8 read(uint8 addr); void write(uint8 addr, uint8 data); diff --git a/bsnes/sfc/system/system.cpp b/bsnes/sfc/system/system.cpp index 361e8995..c4b07513 100755 --- a/bsnes/sfc/system/system.cpp +++ b/bsnes/sfc/system/system.cpp @@ -80,7 +80,6 @@ void System::init() { sdd1.init(); obc1.init(); msu1.init(); - link.init(); video.init(); audio.init(); @@ -127,7 +126,6 @@ void System::load() { if(cartridge.has_sdd1()) sdd1.load(); if(cartridge.has_obc1()) obc1.load(); if(cartridge.has_msu1()) msu1.load(); - if(cartridge.has_link()) link.load(); serialize_init(); cheat.init(); @@ -151,7 +149,6 @@ void System::unload() { if(cartridge.has_sdd1()) sdd1.unload(); if(cartridge.has_obc1()) obc1.unload(); if(cartridge.has_msu1()) msu1.unload(); - if(cartridge.has_link()) link.unload(); } void System::power() { @@ -178,7 +175,6 @@ void System::power() { if(cartridge.has_sdd1()) sdd1.power(); if(cartridge.has_obc1()) obc1.power(); if(cartridge.has_msu1()) msu1.power(); - if(cartridge.has_link()) link.power(); reset(); } @@ -205,7 +201,6 @@ void System::reset() { if(cartridge.has_sdd1()) sdd1.reset(); if(cartridge.has_obc1()) obc1.reset(); if(cartridge.has_msu1()) msu1.reset(); - if(cartridge.has_link()) link.reset(); if(cartridge.has_gb_slot()) cpu.coprocessors.append(&icd2); if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1); @@ -217,7 +212,6 @@ void System::reset() { if(cartridge.has_sharprtc()) cpu.coprocessors.append(&sharprtc); if(cartridge.has_spc7110()) cpu.coprocessors.append(&spc7110); if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1); - if(cartridge.has_link()) cpu.coprocessors.append(&link); scheduler.init(); input.connect(0, config.controller_port1);