diff --git a/bsnes/snes/Makefile b/bsnes/snes/Makefile index c0ee05bb..3034da9d 100755 --- a/bsnes/snes/Makefile +++ b/bsnes/snes/Makefile @@ -5,7 +5,7 @@ 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-obc1 snes-st0018 snes-sufamiturbo -snes_objects += snes-msu1 snes-serial +snes_objects += snes-msu1 snes-serial snes-link objects += $(snes_objects) ifeq ($(profile),accuracy) @@ -54,3 +54,4 @@ obj/snes-st0018.o : $(snes)/chip/st0018/st0018.cpp $(snes)/chip/st0018/* obj/snes-sufamiturbo.o: $(snes)/chip/sufamiturbo/sufamiturbo.cpp $(snes)/chip/sufamiturbo/* obj/snes-msu1.o : $(snes)/chip/msu1/msu1.cpp $(snes)/chip/msu1/* obj/snes-serial.o : $(snes)/chip/serial/serial.cpp $(snes)/chip/serial/* +obj/snes-link.o : $(snes)/chip/link/link.cpp $(snes)/chip/link/* diff --git a/bsnes/snes/alt/smp/smp.hpp b/bsnes/snes/alt/smp/smp.hpp index a7c14741..613d663e 100755 --- a/bsnes/snes/alt/smp/smp.hpp +++ b/bsnes/snes/alt/smp/smp.hpp @@ -33,6 +33,7 @@ public: alwaysinline unsigned operator=(unsigned data) { n = data & 0x80; v = data & 0x40; p = data & 0x20; b = data & 0x10; h = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; + return data; } alwaysinline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); } diff --git a/bsnes/snes/cartridge/cartridge.cpp b/bsnes/snes/cartridge/cartridge.cpp index 4d2db951..3908cb9d 100755 --- a/bsnes/snes/cartridge/cartridge.cpp +++ b/bsnes/snes/cartridge/cartridge.cpp @@ -30,11 +30,12 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) { has_st0018 = false; has_msu1 = false; has_serial = false; + has_link = false; nvram.reset(); parse_xml(xml_list); -//print(xml_list[0], "\n\n"); + print(xml_list[0], "\n\n"); if(ram_size > 0) { ram.map(allocate(ram_size, 0xff), ram_size); diff --git a/bsnes/snes/cartridge/cartridge.hpp b/bsnes/snes/cartridge/cartridge.hpp index 9817ac41..f742c5a6 100755 --- a/bsnes/snes/cartridge/cartridge.hpp +++ b/bsnes/snes/cartridge/cartridge.hpp @@ -47,6 +47,7 @@ public: readonly has_st0018; readonly has_msu1; readonly has_serial; + readonly has_link; struct NonVolatileRAM { const string id; @@ -115,6 +116,7 @@ private: void xml_parse_setarisc(xml_element&); void xml_parse_msu1(xml_element&); void xml_parse_serial(xml_element&); + void xml_parse_link(xml_element&); void xml_parse_address(Mapping&, const string&); void xml_parse_mode(Mapping&, const string&); diff --git a/bsnes/snes/cartridge/xml.cpp b/bsnes/snes/cartridge/xml.cpp index 59801eff..c2bdf419 100755 --- a/bsnes/snes/cartridge/xml.cpp +++ b/bsnes/snes/cartridge/xml.cpp @@ -50,6 +50,7 @@ void Cartridge::parse_xml_cartridge(const char *data) { if(node.name == "setarisc") xml_parse_setarisc(node); if(node.name == "msu1") xml_parse_msu1(node); if(node.name == "serial") xml_parse_serial(node); + if(node.name == "link") xml_parse_link(node); } } } @@ -639,6 +640,25 @@ void Cartridge::xml_parse_serial(xml_element &root) { has_serial = true; } +void Cartridge::xml_parse_link(xml_element &root) { + has_link = true; + link.program = ""; + + foreach(attr, root.attribute) { + if(attr.name == "program") link.program = attr.content; + } + + foreach(node, root.element) { + if(node.name == "map") { + Mapping m({ &Link::read, &link }, { &Link::write, &link }); + foreach(attr, node.attribute) { + if(attr.name == "address") xml_parse_address(m, attr.content); + } + mapping.append(m); + } + } +} + void Cartridge::xml_parse_address(Mapping &m, const string &data) { lstring part; part.split(":", data); diff --git a/bsnes/snes/chip/chip.hpp b/bsnes/snes/chip/chip.hpp index fda6775f..85f13b8b 100755 --- a/bsnes/snes/chip/chip.hpp +++ b/bsnes/snes/chip/chip.hpp @@ -18,6 +18,7 @@ struct Coprocessor : Processor { #include #include #include +#include void Coprocessor::step(unsigned clocks) { clock += clocks * (uint64)cpu.frequency; diff --git a/bsnes/snes/chip/link/link.cpp b/bsnes/snes/chip/link/link.cpp new file mode 100755 index 00000000..e73f175f --- /dev/null +++ b/bsnes/snes/chip/link/link.cpp @@ -0,0 +1,45 @@ +#include + +#define LINK_HPP +namespace SNES { + +Link link; + +void Link::init() { +} + +void Link::load() { + if(opened()) close(); + string basename = system.interface->path(Cartridge::Slot::Base, ""); + string name = program != "" ? program : notdir(basename); + string path = dir(basename); + if(open(name, path)) { + link_power = sym("link_power"); + link_reset = sym("link_reset"); + 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(); +} + +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/snes/chip/link/link.hpp b/bsnes/snes/chip/link/link.hpp new file mode 100755 index 00000000..59816e3a --- /dev/null +++ b/bsnes/snes/chip/link/link.hpp @@ -0,0 +1,21 @@ +class Link : public Coprocessor, public library { +public: + string program; + + 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_read; + function link_write; +}; + +extern Link link; diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 9848141f..58a86ec5 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[] = "079"; + static const char Version[] = "079.01"; static const unsigned SerializerVersion = 20; } } diff --git a/bsnes/snes/system/system.cpp b/bsnes/snes/system/system.cpp index 2060160f..f082af7f 100755 --- a/bsnes/snes/system/system.cpp +++ b/bsnes/snes/system/system.cpp @@ -85,6 +85,7 @@ void System::init(Interface *interface_) { st0018.init(); msu1.init(); serial.init(); + link.init(); video.init(); audio.init(); @@ -124,6 +125,7 @@ void System::load() { if(cartridge.has_st0018()) st0018.load(); if(cartridge.has_msu1()) msu1.load(); if(cartridge.has_serial()) serial.load(); + if(cartridge.has_link()) link.load(); serialize_init(); cheat.init(); @@ -148,6 +150,7 @@ void System::unload() { if(cartridge.has_st0018()) st0018.unload(); if(cartridge.has_msu1()) msu1.unload(); if(cartridge.has_serial()) serial.unload(); + if(cartridge.has_link()) link.unload(); } void System::power() { @@ -184,6 +187,7 @@ void System::power() { if(cartridge.has_st0018()) st0018.power(); if(cartridge.has_msu1()) msu1.power(); if(cartridge.has_serial()) serial.power(); + if(cartridge.has_link()) link.power(); if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) cpu.coprocessors.append(&icd2); if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx); @@ -220,6 +224,7 @@ void System::reset() { if(cartridge.has_st0018()) st0018.reset(); if(cartridge.has_msu1()) msu1.reset(); if(cartridge.has_serial()) serial.reset(); + if(cartridge.has_link()) link.reset(); if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) cpu.coprocessors.append(&icd2); if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx);