diff --git a/Makefile b/Makefile index fb280324..6724ed21 100755 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ include nall/Makefile -snes := bsnes +snes := snes +profile := asnes ui := qt # compiler @@ -55,19 +56,19 @@ ifeq ($(platform),osx) test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS $(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link)) else - $(strip $(cpp) -o out/$(snes) $(objects) $(link)) + $(strip $(cpp) -o out/$(profile) $(objects) $(link)) endif install: ifeq ($(platform),x) - install -D -m 755 out/$(snes) $(DESTDIR)$(prefix)/bin/$(snes) + install -D -m 755 out/$(profile) $(DESTDIR)$(prefix)/bin/$(profile) install -D -m 644 qt/data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png install -D -m 644 qt/data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop endif uninstall: ifeq ($(platform),x) - rm $(DESTDIR)$(prefix)/bin/$(snes) + rm $(DESTDIR)$(prefix)/bin/$(profile) rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop endif @@ -86,6 +87,6 @@ clean: ui_clean -@$(call delete,*.manifest) archive-all: - tar -cjf snes-`date +%Y%m%d`.tar.bz2 asnes bsnes libco nall obj out qt ruby Makefile sync.sh + tar -cjf bsnes-`date +%Y%m%d`.tar.bz2 libco nall obj out qt ruby snes Makefile sync.sh help:; diff --git a/asnes/info.hpp b/asnes/info.hpp deleted file mode 100755 index 56721fdf..00000000 --- a/asnes/info.hpp +++ /dev/null @@ -1,10 +0,0 @@ -namespace SNES { - namespace Info { - static const char Name[] = "asnes"; - static const char Version[] = "000.02"; - static const unsigned SerializerVersion = 12; - } -} - -//#define DEBUGGER -#define CHEAT_SYSTEM diff --git a/bsnes/Makefile b/bsnes/Makefile deleted file mode 100755 index d3517300..00000000 --- a/bsnes/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -snes_objects := libco -snes_objects += snes-system -snes_objects += snes-cartridge snes-cheat -snes_objects += snes-memory snes-cpucore snes-cpu snes-smpcore snes-smp snes-dsp snes-ppu -snes_objects += snes-supergameboy snes-superfx snes-sa1 -snes_objects += snes-bsx snes-srtc snes-sdd1 snes-spc7110 -snes_objects += snes-cx4 snes-dsp1 snes-dsp2 snes-dsp3 snes-dsp4 -snes_objects += snes-obc1 snes-st0010 snes-st0011 snes-st0018 -snes_objects += snes-msu1 snes-serial -objects += $(snes_objects) - -obj/libco.o : libco/libco.c libco/* -obj/libsnes.o: $(snes)/libsnes/libsnes.cpp $(snes)/libsnes/* - -obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/) -obj/snes-memory.o : $(snes)/memory/memory.cpp $(snes)/memory/* -obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/) -obj/snes-cpu.o : $(snes)/cpu/cpu.cpp $(snes)/cpu/* -obj/snes-smpcore.o : $(snes)/smp/core/core.cpp $(call rwildcard,$(snes)/smp/core/) -obj/snes-smp.o : $(snes)/smp/smp.cpp $(snes)/smp/* -obj/snes-dsp.o : $(snes)/dsp/dsp.cpp $(snes)/dsp/* -obj/snes-ppu.o : $(snes)/ppu/ppu.cpp $(snes)/ppu/* -obj/snes-cartridge.o: $(snes)/cartridge/cartridge.cpp $(snes)/cartridge/* -obj/snes-cheat.o : $(snes)/cheat/cheat.cpp $(snes)/cheat/* - -obj/snes-supergameboy.o: $(snes)/chip/supergameboy/supergameboy.cpp $(call rwildcard,$(snes)/chip/supergameboy/) -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-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/* -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-dsp1.o : $(snes)/chip/dsp1/dsp1.cpp $(snes)/chip/dsp1/* -obj/snes-dsp2.o : $(snes)/chip/dsp2/dsp2.cpp $(snes)/chip/dsp2/* -obj/snes-dsp3.o : $(snes)/chip/dsp3/dsp3.cpp $(snes)/chip/dsp3/* -obj/snes-dsp4.o : $(snes)/chip/dsp4/dsp4.cpp $(snes)/chip/dsp4/* -obj/snes-obc1.o : $(snes)/chip/obc1/obc1.cpp $(snes)/chip/obc1/* -obj/snes-st0010.o : $(snes)/chip/st0010/st0010.cpp $(snes)/chip/st0010/* -obj/snes-st0011.o : $(snes)/chip/st0011/st0011.cpp $(snes)/chip/st0011/* -obj/snes-st0018.o : $(snes)/chip/st0018/st0018.cpp $(snes)/chip/st0018/* -obj/snes-msu1.o : $(snes)/chip/msu1/msu1.cpp $(snes)/chip/msu1/* -obj/snes-serial.o : $(snes)/chip/serial/serial.cpp $(snes)/chip/serial/* - -########### -# library # -########### - -snes_objects := $(patsubst %,obj/%.o,$(snes_objects)) - -library: $(snes_objects) obj/libsnes.o -ifeq ($(platform),x) - ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o - $(cpp) -o out/libsnes.so -shared -Wl,-soname,libsnes.so.1 $(snes_objects) obj/libsnes.o -else ifeq ($(platform),osx) - ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o - $(cpp) -o out/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(snes_objects) obj/libsnes.o -else ifeq ($(platform),win) - $(cpp) -o out/snes.dll -shared -Wl,--out-implib,libsnes.a $(snes_objects) obj/libsnes.o -endif - -library-install: -ifeq ($(platform),x) - install -D -m 755 out/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a - install -D -m 755 out/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so - ldconfig -n $(DESTDIR)$(prefix)/lib -else ifeq ($(platform),osx) - cp out/libsnes.dylib /usr/local/lib/libsnes.dylib -endif - -library-uninstall: -ifeq ($(platform),x) - rm $(DESTDIR)$(prefix)/lib/libsnes.a - rm $(DESTDIR)$(prefix)/lib/libsnes.so -else ifeq ($(platform),osx) - rm /usr/local/lib/libsnes.dylib -endif diff --git a/bsnes/audio/audio.cpp b/bsnes/audio/audio.cpp deleted file mode 100755 index 4b2f6861..00000000 --- a/bsnes/audio/audio.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#ifdef SYSTEM_CPP - -Audio audio; - -void Audio::coprocessor_enable(bool state) { - coprocessor = state; - - dsp_rdoffset = cop_rdoffset = 0; - dsp_wroffset = cop_wroffset = 0; - dsp_length = cop_length = 0; - - r_sum_l = r_sum_r = 0; -} - -void Audio::coprocessor_frequency(double input_frequency) { - double output_frequency; - output_frequency = system.apu_frequency() / 768.0; - r_step = input_frequency / output_frequency; - r_frac = 0; -} - -void Audio::sample(int16 left, int16 right) { - if(coprocessor == false) { - system.interface->audio_sample(left, right); - } else { - dsp_buffer[dsp_wroffset] = ((uint16)left << 0) + ((uint16)right << 16); - dsp_wroffset = (dsp_wroffset + 1) & 32767; - dsp_length = (dsp_length + 1) & 32767; - flush(); - } -} - -void Audio::coprocessor_sample(int16 left, int16 right) { - if(r_frac >= 1.0) { - r_frac -= 1.0; - r_sum_l += left; - r_sum_r += right; - return; - } - - r_sum_l += left * r_frac; - r_sum_r += right * r_frac; - - uint16 output_left = sclamp<16>(int(r_sum_l / r_step)); - uint16 output_right = sclamp<16>(int(r_sum_r / r_step)); - - double first = 1.0 - r_frac; - r_sum_l = left * first; - r_sum_r = right * first; - r_frac = r_step - first; - - cop_buffer[cop_wroffset] = (output_left << 0) + (output_right << 16); - cop_wroffset = (cop_wroffset + 1) & 32767; - cop_length = (cop_length + 1) & 32767; - flush(); -} - -void Audio::init() { -} - -void Audio::flush() { - while(dsp_length > 0 && cop_length > 0) { - uint32 dsp_sample = dsp_buffer[dsp_rdoffset]; - uint32 cop_sample = cop_buffer[cop_rdoffset]; - - dsp_rdoffset = (dsp_rdoffset + 1) & 32767; - cop_rdoffset = (cop_rdoffset + 1) & 32767; - - dsp_length--; - cop_length--; - - int dsp_left = (int16)(dsp_sample >> 0); - int dsp_right = (int16)(dsp_sample >> 16); - - int cop_left = (int16)(cop_sample >> 0); - int cop_right = (int16)(cop_sample >> 16); - - system.interface->audio_sample( - sclamp<16>((dsp_left + cop_left ) / 2), - sclamp<16>((dsp_right + cop_right) / 2) - ); - } -} - -#endif diff --git a/bsnes/audio/audio.hpp b/bsnes/audio/audio.hpp deleted file mode 100755 index 3cd522fa..00000000 --- a/bsnes/audio/audio.hpp +++ /dev/null @@ -1,22 +0,0 @@ -class Audio { -public: - void coprocessor_enable(bool state); - void coprocessor_frequency(double frequency); - void sample(int16 left, int16 right); - void coprocessor_sample(int16 left, int16 right); - void init(); - -private: - bool coprocessor; - uint32 dsp_buffer[32768], cop_buffer[32768]; - unsigned dsp_rdoffset, cop_rdoffset; - unsigned dsp_wroffset, cop_wroffset; - unsigned dsp_length, cop_length; - - double r_step, r_frac; - int r_sum_l, r_sum_r; - - void flush(); -}; - -extern Audio audio; diff --git a/bsnes/cartridge/cartridge.cpp b/bsnes/cartridge/cartridge.cpp deleted file mode 100755 index c1a41e4f..00000000 --- a/bsnes/cartridge/cartridge.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include - -#include -#include - -#define CARTRIDGE_CPP -namespace SNES { - -#include "xml.cpp" -#include "serialization.cpp" - -namespace memory { - MappedRAM cartrom, cartram, cartrtc; - MappedRAM bsxflash, bsxram, bsxpram; - MappedRAM stArom, stAram; - MappedRAM stBrom, stBram; - MappedRAM gbrom, gbram, gbrtc; -}; - -Cartridge cartridge; - -void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) { - mode = cartridge_mode; - region = Region::NTSC; - ram_size = 0; - spc7110_data_rom_offset = 0x100000; - supergameboy_version = SuperGameBoyVersion::Version1; - supergameboy_ram_size = 0; - supergameboy_rtc_size = 0; - serial_baud_rate = 57600; - - has_bsx_slot = false; - has_superfx = false; - has_sa1 = false; - has_srtc = false; - has_sdd1 = false; - has_spc7110 = false; - has_spc7110rtc = false; - has_cx4 = false; - has_dsp1 = false; - has_dsp2 = false; - has_dsp3 = false; - has_dsp4 = false; - has_obc1 = false; - has_st0010 = false; - has_st0011 = false; - has_st0018 = false; - has_msu1 = false; - has_serial = false; - - parse_xml(xml_list); - - if(ram_size > 0) { - memory::cartram.map(allocate(ram_size, 0xff), ram_size); - } - - if(has_srtc || has_spc7110rtc) { - memory::cartrtc.map(allocate(20, 0xff), 20); - } - - if(mode == Mode::Bsx) { - memory::bsxram.map (allocate( 32 * 1024, 0xff), 32 * 1024); - memory::bsxpram.map(allocate(512 * 1024, 0xff), 512 * 1024); - } - - if(mode == Mode::SufamiTurbo) { - if(memory::stArom.data()) memory::stAram.map(allocate(128 * 1024, 0xff), 128 * 1024); - if(memory::stBrom.data()) memory::stBram.map(allocate(128 * 1024, 0xff), 128 * 1024); - } - - if(mode == Mode::SuperGameBoy) { - if(memory::gbrom.data()) { - if(supergameboy_ram_size) memory::gbram.map(allocate(supergameboy_ram_size, 0xff), supergameboy_ram_size); - if(supergameboy_rtc_size) memory::gbrtc.map(allocate(supergameboy_rtc_size, 0x00), supergameboy_rtc_size); - } - } - - memory::cartrom.write_protect(true); - memory::cartram.write_protect(false); - memory::cartrtc.write_protect(false); - memory::bsxflash.write_protect(true); - memory::bsxram.write_protect(false); - memory::bsxpram.write_protect(false); - memory::stArom.write_protect(true); - memory::stAram.write_protect(false); - memory::stBrom.write_protect(true); - memory::stBram.write_protect(false); - memory::gbrom.write_protect(true); - memory::gbram.write_protect(false); - memory::gbrtc.write_protect(false); - - unsigned checksum = ~0; foreach(n, memory::cartrom ) checksum = crc32_adjust(checksum, n); - if(memory::bsxflash.size() != 0 && memory::bsxflash.size() != ~0) foreach(n, memory::bsxflash) checksum = crc32_adjust(checksum, n); - if(memory::stArom.size() != 0 && memory::stArom.size() != ~0) foreach(n, memory::stArom ) checksum = crc32_adjust(checksum, n); - if(memory::stBrom.size() != 0 && memory::stBrom.size() != ~0) foreach(n, memory::stBrom ) checksum = crc32_adjust(checksum, n); - if(memory::gbrom.size() != 0 && memory::gbrom.size() != ~0) foreach(n, memory::gbrom ) checksum = crc32_adjust(checksum, n); - crc32 = ~checksum; - - sha256_ctx sha; - uint8_t shahash[32]; - sha256_init(&sha); - sha256_chunk(&sha, memory::cartrom.data(), memory::cartrom.size()); - sha256_final(&sha); - sha256_hash(&sha, shahash); - - string hash; - foreach(n, shahash) hash << strhex<2>(n); - sha256 = hash; - - bus.load_cart(); - system.serialize_init(); - loaded = true; -} - -void Cartridge::unload() { - memory::cartrom.reset(); - memory::cartram.reset(); - memory::cartrtc.reset(); - memory::bsxflash.reset(); - memory::bsxram.reset(); - memory::bsxpram.reset(); - memory::stArom.reset(); - memory::stAram.reset(); - memory::stBrom.reset(); - memory::stBram.reset(); - memory::gbrom.reset(); - memory::gbram.reset(); - memory::gbrtc.reset(); - - if(loaded == false) return; - bus.unload_cart(); - loaded = false; -} - -Cartridge::Cartridge() { - loaded = false; - unload(); -} - -Cartridge::~Cartridge() { - unload(); -} - -} diff --git a/bsnes/cartridge/cartridge.hpp b/bsnes/cartridge/cartridge.hpp deleted file mode 100755 index 8c849a33..00000000 --- a/bsnes/cartridge/cartridge.hpp +++ /dev/null @@ -1,118 +0,0 @@ -class Cartridge : property { -public: - enum class Mode : unsigned { - Normal, - BsxSlotted, - Bsx, - SufamiTurbo, - SuperGameBoy, - }; - - enum class Region : unsigned { - NTSC, - PAL, - }; - - enum class SuperGameBoyVersion : unsigned { - Version1, - Version2, - }; - - //assigned externally to point to file-system datafiles (msu1 and serial) - //example: "/path/to/filename.sfc" would set this to "/path/to/filename" - readwrite basename; - - readonly loaded; - readonly crc32; - readonly sha256; - - readonly mode; - readonly region; - readonly ram_size; - readonly spc7110_data_rom_offset; - readonly supergameboy_version; - readonly supergameboy_ram_size; - readonly supergameboy_rtc_size; - readonly serial_baud_rate; - - readonly has_bsx_slot; - readonly has_superfx; - readonly has_sa1; - readonly has_srtc; - readonly has_sdd1; - readonly has_spc7110; - readonly has_spc7110rtc; - readonly has_cx4; - readonly has_dsp1; - readonly has_dsp2; - readonly has_dsp3; - readonly has_dsp4; - readonly has_obc1; - readonly has_st0010; - readonly has_st0011; - readonly has_st0018; - readonly has_msu1; - readonly has_serial; - - struct Mapping { - Memory *memory; - MMIO *mmio; - Bus::MapMode mode; - unsigned banklo; - unsigned bankhi; - unsigned addrlo; - unsigned addrhi; - unsigned offset; - unsigned size; - - Mapping(); - Mapping(Memory&); - Mapping(MMIO&); - }; - array mapping; - - void load(Mode, const lstring&); - void unload(); - - void serialize(serializer&); - Cartridge(); - ~Cartridge(); - -private: - void parse_xml(const lstring&); - void parse_xml_cartridge(const char*); - void parse_xml_bsx(const char*); - void parse_xml_sufami_turbo(const char*, bool); - void parse_xml_gameboy(const char*); - - void xml_parse_rom(xml_element&); - void xml_parse_ram(xml_element&); - void xml_parse_superfx(xml_element&); - void xml_parse_sa1(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_necdsp(xml_element&); - void xml_parse_obc1(xml_element&); - void xml_parse_setadsp(xml_element&); - void xml_parse_setarisc(xml_element&); - void xml_parse_msu1(xml_element&); - void xml_parse_serial(xml_element&); - - void xml_parse_address(Mapping&, const string&); - void xml_parse_mode(Mapping&, const string&); -}; - -namespace memory { - extern MappedRAM cartrom, cartram, cartrtc; - extern MappedRAM bsxflash, bsxram, bsxpram; - extern MappedRAM stArom, stAram; - extern MappedRAM stBrom, stBram; - extern MappedRAM gbrom, gbram, gbrtc; -}; - -extern Cartridge cartridge; diff --git a/bsnes/cartridge/serialization.cpp b/bsnes/cartridge/serialization.cpp deleted file mode 100755 index 847b2354..00000000 --- a/bsnes/cartridge/serialization.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::serialize(serializer &s) { - if(memory::cartram.size() != 0 && memory::cartram.size() != ~0) { - s.array(memory::cartram.data(), memory::cartram.size()); - } - - if(memory::cartrtc.size() != 0 && memory::cartrtc.size() != ~0) { - s.array(memory::cartrtc.data(), memory::cartrtc.size()); - } - - if(memory::bsxram.size() != 0 && memory::bsxram.size() != ~0) { - s.array(memory::bsxram.data(), memory::bsxram.size()); - } - - if(memory::bsxpram.size() != 0 && memory::bsxpram.size() != ~0) { - s.array(memory::bsxpram.data(), memory::bsxpram.size()); - } - - if(memory::stAram.size() != 0 && memory::stAram.size() != ~0) { - s.array(memory::stAram.data(), memory::stAram.size()); - } - - if(memory::stBram.size() != 0 && memory::stBram.size() != ~0) { - s.array(memory::stBram.data(), memory::stBram.size()); - } - - if(memory::gbram.size() != 0 && memory::gbram.size() != ~0) { - s.array(memory::gbram.data(), memory::gbram.size()); - } - - if(memory::gbrtc.size() != 0 && memory::gbrtc.size() != ~0) { - s.array(memory::gbrtc.data(), memory::gbrtc.size()); - } -} - -#endif diff --git a/bsnes/cartridge/xml.cpp b/bsnes/cartridge/xml.cpp deleted file mode 100755 index 553183a7..00000000 --- a/bsnes/cartridge/xml.cpp +++ /dev/null @@ -1,671 +0,0 @@ -#ifdef CARTRIDGE_CPP - -void Cartridge::parse_xml(const lstring &list) { - mapping.reset(); - parse_xml_cartridge(list[0]); - - if(mode == Mode::BsxSlotted) { - parse_xml_bsx(list[1]); - } else if(mode == Mode::Bsx) { - parse_xml_bsx(list[1]); - } else if(mode == Mode::SufamiTurbo) { - parse_xml_sufami_turbo(list[1], 0); - parse_xml_sufami_turbo(list[2], 1); - } else if(mode == Mode::SuperGameBoy) { - parse_xml_gameboy(list[1]); - } -} - -void Cartridge::parse_xml_cartridge(const char *data) { - xml_element document = xml_parse(data); - if(document.element.size() == 0) return; - - foreach(head, document.element) { - if(head.name == "cartridge") { - foreach(attr, head.attribute) { - if(attr.name == "region") { - if(attr.content == "NTSC") region = Region::NTSC; - if(attr.content == "PAL") region = Region::PAL; - } - } - - foreach(node, head.element) { - if(node.name == "rom") xml_parse_rom(node); - if(node.name == "ram") xml_parse_ram(node); - if(node.name == "superfx") xml_parse_superfx(node); - if(node.name == "sa1") xml_parse_sa1(node); - if(node.name == "bsx") xml_parse_bsx(node); - if(node.name == "sufamiturbo") xml_parse_sufamiturbo(node); - if(node.name == "supergameboy") xml_parse_supergameboy(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 == "necdsp") xml_parse_necdsp(node); - if(node.name == "obc1") xml_parse_obc1(node); - if(node.name == "setadsp") xml_parse_setadsp(node); - if(node.name == "setarisc") xml_parse_setarisc(node); - if(node.name == "msu1") xml_parse_msu1(node); - if(node.name == "serial") xml_parse_serial(node); - } - } - } -} - -void Cartridge::parse_xml_bsx(const char *data) { -} - -void Cartridge::parse_xml_sufami_turbo(const char *data, bool slot) { -} - -void Cartridge::parse_xml_gameboy(const char *data) { - xml_element document = xml_parse(data); - if(document.element.size() == 0) return; - - foreach(head, document.element) { - if(head.name == "cartridge") { - foreach(attr, head.attribute) { - if(attr.name == "rtc") { - supergameboy_rtc_size = (attr.content == "true") ? 4 : 0; - } - } - - foreach(leaf, head.element) { - if(leaf.name == "ram") { - foreach(attr, leaf.attribute) { - if(attr.name == "size") { - supergameboy_ram_size = strhex(attr.content); - } - } - } - } - } - } -} - -void Cartridge::xml_parse_rom(xml_element &root) { - foreach(leaf, root.element) { - if(leaf.name == "map") { - Mapping m(memory::cartrom); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } -} - -void Cartridge::xml_parse_ram(xml_element &root) { - foreach(attr, root.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, root.element) { - if(leaf.name == "map") { - Mapping m(memory::cartram); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } -} - -void Cartridge::xml_parse_superfx(xml_element &root) { - has_superfx = true; - - foreach(node, root.element) { - if(node.name == "rom") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::fxrom); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "ram") { - foreach(attr, node.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::fxram); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(superfx); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_sa1(xml_element &root) { - has_sa1 = true; - - foreach(node, root.element) { - if(node.name == "rom") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::vsprom); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "iram") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::cpuiram); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "bwram") { - foreach(attr, node.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::cc1bwram); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(sa1); - 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; - - foreach(node, root.element) { - if(node.name == "slot") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(memory::bsxflash); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(bsxcart); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_sufamiturbo(xml_element &root) { - if(mode != Mode::SufamiTurbo) return; - - foreach(node, root.element) { - if(node.name == "slot") { - bool slotid = 0; - foreach(attr, node.attribute) { - if(attr.name == "id") { - if(attr.content == "A") slotid = 0; - if(attr.content == "B") slotid = 1; - } - } - - foreach(slot, node.element) { - if(slot.name == "rom") { - foreach(leaf, slot.element) { - if(leaf.name == "map") { - Mapping m(slotid == 0 ? memory::stArom : memory::stBrom); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - if(m.memory->size() > 0) mapping.append(m); - } - } - } else if(slot.name == "ram") { - foreach(leaf, slot.element) { - if(leaf.name == "map") { - Mapping m(slotid == 0 ? memory::stAram : memory::stBram); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - if(m.memory->size() > 0) mapping.append(m); - } - } - } - } - } - } -} - -void Cartridge::xml_parse_supergameboy(xml_element &root) { - if(mode != Mode::SuperGameBoy) return; - - foreach(attr, root.attribute) { - if(attr.name == "revision") { - if(attr.content == "1") supergameboy_version = SuperGameBoyVersion::Version1; - if(attr.content == "2") supergameboy_version = SuperGameBoyVersion::Version2; - } - } - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m((Memory&)supergameboy); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_srtc(xml_element &root) { - has_srtc = true; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(srtc); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_sdd1(xml_element &root) { - has_sdd1 = true; - - foreach(node, root.element) { - if(node.name == "mcu") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m((Memory&)sdd1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m((MMIO&)sdd1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_spc7110(xml_element &root) { - has_spc7110 = true; - - foreach(node, root.element) { - if(node.name == "dcu") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110dcu); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mcu") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110mcu); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - if(attr.name == "offset") spc7110_data_rom_offset = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "ram") { - foreach(attr, node.attribute) { - if(attr.name == "size") ram_size = strhex(attr.content); - } - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110ram); - 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 = strhex(attr.content); - if(attr.name == "size") m.size = strhex(attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "rtc") { - has_spc7110rtc = true; - - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(spc7110); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_cx4(xml_element &root) { - has_cx4 = true; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(cx4); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_necdsp(xml_element &root) { - unsigned program = 0; - - foreach(attr, root.attribute) { - if(attr.name == "program") { - if(attr.content == "DSP-1" || attr.content == "DSP-1A" || attr.content == "DSP-1B") { - program = 1; - has_dsp1 = true; - } else if(attr.content == "DSP-2") { - program = 2; - has_dsp2 = true; - } else if(attr.content == "DSP-3") { - program = 3; - has_dsp3 = true; - } else if(attr.content == "DSP-4") { - program = 4; - has_dsp4 = true; - } - } - } - - Memory *dr[5] = { 0, &dsp1dr, &dsp2dr, &dsp3, &dsp4 }; - Memory *sr[5] = { 0, &dsp1sr, &dsp2sr, &dsp3, &dsp4 }; - - foreach(node, root.element) { - if(node.name == "dr" && dr[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*dr[program]); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } else if(node.name == "sr" && sr[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*sr[program]); - foreach(attr, leaf.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; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(obc1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_setadsp(xml_element &root) { - unsigned program = 0; - - foreach(attr, root.attribute) { - if(attr.name == "program") { - if(attr.content == "ST-0010") { - program = 1; - has_st0010 = true; - } else if(attr.content == "ST-0011") { - program = 2; - has_st0011 = true; - } - } - } - - Memory *map[3] = { 0, &st0010, 0 }; - - foreach(node, root.element) { - if(node.name == "mmio" && map[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*map[program]); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_setarisc(xml_element &root) { - unsigned program = 0; - - foreach(attr, root.attribute) { - if(attr.name == "program") { - if(attr.content == "ST-0018") { - program = 1; - has_st0018 = true; - } - } - } - - MMIO *map[2] = { 0, &st0018 }; - - foreach(node, root.element) { - if(node.name == "mmio" && map[program]) { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(*map[program]); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_msu1(xml_element &root) { - has_msu1 = true; - - foreach(node, root.element) { - if(node.name == "mmio") { - foreach(leaf, node.element) { - if(leaf.name == "map") { - Mapping m(msu1); - foreach(attr, leaf.attribute) { - if(attr.name == "address") xml_parse_address(m, attr.content); - } - mapping.append(m); - } - } - } - } -} - -void Cartridge::xml_parse_serial(xml_element &root) { - has_serial = true; - - foreach(attr, root.attribute) { - if(attr.name == "baud") { - serial_baud_rate = strunsigned(attr.content); - } - } -} - -void Cartridge::xml_parse_address(Mapping &m, const string &data) { - lstring part; - part.split(":", data); - if(part.size() != 2) return; - - lstring subpart; - subpart.split("-", part[0]); - if(subpart.size() == 1) { - m.banklo = strhex(subpart[0]); - m.bankhi = m.banklo; - } else if(subpart.size() == 2) { - m.banklo = strhex(subpart[0]); - m.bankhi = strhex(subpart[1]); - } - - subpart.split("-", part[1]); - if(subpart.size() == 1) { - m.addrlo = strhex(subpart[0]); - m.addrhi = m.addrlo; - } else if(subpart.size() == 2) { - m.addrlo = strhex(subpart[0]); - m.addrhi = strhex(subpart[1]); - } -} - -void Cartridge::xml_parse_mode(Mapping &m, const string& data) { - if(data == "direct") m.mode = Bus::MapMode::Direct; - else if(data == "linear") m.mode = Bus::MapMode::Linear; - else if(data == "shadow") m.mode = Bus::MapMode::Shadow; -} - -Cartridge::Mapping::Mapping() { - memory = 0; - mmio = 0; - mode = Bus::MapMode::Direct; - banklo = bankhi = addrlo = addrhi = offset = size = 0; -} - -Cartridge::Mapping::Mapping(Memory &memory_) { - memory = &memory_; - mmio = 0; - mode = Bus::MapMode::Direct; - banklo = bankhi = addrlo = addrhi = offset = size = 0; -} - -Cartridge::Mapping::Mapping(MMIO &mmio_) { - memory = 0; - mmio = &mmio_; - mode = Bus::MapMode::Direct; - banklo = bankhi = addrlo = addrhi = offset = size = 0; -} - -#endif diff --git a/bsnes/cheat/cheat-inline.hpp b/bsnes/cheat/cheat-inline.hpp deleted file mode 100755 index a80f47f3..00000000 --- a/bsnes/cheat/cheat-inline.hpp +++ /dev/null @@ -1,2 +0,0 @@ -bool Cheat::active() const { return cheat_enabled; } -bool Cheat::exists(unsigned addr) const { return bitmask[addr >> 3] & 1 << (addr & 7); } diff --git a/bsnes/cheat/cheat.cpp b/bsnes/cheat/cheat.cpp deleted file mode 100755 index c97e9a96..00000000 --- a/bsnes/cheat/cheat.cpp +++ /dev/null @@ -1,194 +0,0 @@ -#include - -#define CHEAT_CPP -namespace SNES { - -Cheat cheat; - -bool Cheat::enabled() const { - return system_enabled; -} - -void Cheat::enable(bool state) { - system_enabled = state; - cheat_enabled = system_enabled && code_enabled; -} - -void Cheat::synchronize() { - memset(bitmask, 0x00, sizeof bitmask); - code_enabled = false; - - for(unsigned i = 0; i < size(); i++) { - const CheatCode &code = operator[](i); - if(code.enabled == false) continue; - - for(unsigned n = 0; n < code.addr.size(); n++) { - code_enabled = true; - - unsigned addr = mirror(code.addr[n]); - bitmask[addr >> 3] |= 1 << (addr & 7); - if((addr & 0xffe000) == 0x7e0000) { - //mirror $7e:0000-1fff to $00-3f|80-bf:0000-1fff - unsigned mirroraddr; - for(unsigned x = 0; x <= 0x3f; x++) { - mirroraddr = ((0x00 + x) << 16) + (addr & 0x1fff); - bitmask[mirroraddr >> 3] |= 1 << (mirroraddr & 7); - - mirroraddr = ((0x80 + x) << 16) + (addr & 0x1fff); - bitmask[mirroraddr >> 3] |= 1 << (mirroraddr & 7); - } - } - } - } - - cheat_enabled = system_enabled && code_enabled; -} - -bool Cheat::read(unsigned addr, uint8 &data) const { - addr = mirror(addr); - - for(unsigned i = 0; i < size(); i++) { - const CheatCode &code = operator[](i); - if(code.enabled == false) continue; - - for(unsigned n = 0; n < code.addr.size(); n++) { - if(addr == mirror(code.addr[n])) { - data = code.data[n]; - return true; - } - } - } - - return false; -} - -Cheat::Cheat() { - system_enabled = true; - synchronize(); -} - -//=============== -//encode / decode -//=============== - -bool Cheat::decode(const char *s, unsigned &addr, uint8 &data, Type &type) { - string t = s; - t.lower(); - - #define ischr(n) ((n >= '0' && n <= '9') || (n >= 'a' && n <= 'f')) - - if(strlen(t) == 8 || (strlen(t) == 9 && t[6] == ':')) { - //strip ':' - if(strlen(t) == 9 && t[6] == ':') t = string() << substr(t, 0, 6) << substr(t, 7); - //validate input - for(unsigned i = 0; i < 8; i++) if(!ischr(t[i])) return false; - - type = Type::ProActionReplay; - unsigned r = strhex((const char*)t); - addr = r >> 8; - data = r & 0xff; - return true; - } else if(strlen(t) == 9 && t[4] == '-') { - //strip '-' - t = string() << substr(t, 0, 4) << substr(t, 5); - //validate input - for(unsigned i = 0; i < 8; i++) if(!ischr(t[i])) return false; - - type = Type::GameGenie; - t.transform("df4709156bc8a23e", "0123456789abcdef"); - unsigned r = strhex((const char*)t); - //8421 8421 8421 8421 8421 8421 - //abcd efgh ijkl mnop qrst uvwx - //ijkl qrst opab cduv wxef ghmn - addr = (!!(r & 0x002000) << 23) | (!!(r & 0x001000) << 22) - | (!!(r & 0x000800) << 21) | (!!(r & 0x000400) << 20) - | (!!(r & 0x000020) << 19) | (!!(r & 0x000010) << 18) - | (!!(r & 0x000008) << 17) | (!!(r & 0x000004) << 16) - | (!!(r & 0x800000) << 15) | (!!(r & 0x400000) << 14) - | (!!(r & 0x200000) << 13) | (!!(r & 0x100000) << 12) - | (!!(r & 0x000002) << 11) | (!!(r & 0x000001) << 10) - | (!!(r & 0x008000) << 9) | (!!(r & 0x004000) << 8) - | (!!(r & 0x080000) << 7) | (!!(r & 0x040000) << 6) - | (!!(r & 0x020000) << 5) | (!!(r & 0x010000) << 4) - | (!!(r & 0x000200) << 3) | (!!(r & 0x000100) << 2) - | (!!(r & 0x000080) << 1) | (!!(r & 0x000040) << 0); - data = r >> 24; - return true; - } else { - return false; - } - - #undef ischr -} - -bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) { - char t[16]; - - if(type == Type::ProActionReplay) { - s = string(strhex<6>(addr), strhex<2>(data)); - return true; - } else if(type == Type::GameGenie) { - unsigned r = addr; - addr = (!!(r & 0x008000) << 23) | (!!(r & 0x004000) << 22) - | (!!(r & 0x002000) << 21) | (!!(r & 0x001000) << 20) - | (!!(r & 0x000080) << 19) | (!!(r & 0x000040) << 18) - | (!!(r & 0x000020) << 17) | (!!(r & 0x000010) << 16) - | (!!(r & 0x000200) << 15) | (!!(r & 0x000100) << 14) - | (!!(r & 0x800000) << 13) | (!!(r & 0x400000) << 12) - | (!!(r & 0x200000) << 11) | (!!(r & 0x100000) << 10) - | (!!(r & 0x000008) << 9) | (!!(r & 0x000004) << 8) - | (!!(r & 0x000002) << 7) | (!!(r & 0x000001) << 6) - | (!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4) - | (!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2) - | (!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0); - s = string(strhex<2>(data), strhex<2>(addr >> 16), "-", strhex<4>(addr & 0xffff)); - s.transform("0123456789abcdef", "df4709156bc8a23e"); - return true; - } else { - return false; - } -} - -//======== -//internal -//======== - -unsigned Cheat::mirror(unsigned addr) const { - //$00-3f|80-bf:0000-1fff -> $7e:0000-1fff - if((addr & 0x40e000) == 0x000000) return (0x7e0000 + (addr & 0x1fff)); - return addr; -} - -//========= -//CheatCode -//========= - -bool CheatCode::operator=(string s) { - addr.reset(); - data.reset(); - - lstring list; - list.split("+", s.replace(" ", "")); - - for(unsigned i = 0; i < list.size(); i++) { - unsigned addr_; - uint8 data_; - Cheat::Type type_; - if(Cheat::decode(list[i], addr_, data_, type_) == false) { - addr.reset(); - data.reset(); - return false; - } - - addr.append(addr_); - data.append(data_); - } - - return true; -} - -CheatCode::CheatCode() { - enabled = false; -} - -} diff --git a/bsnes/cheat/cheat.hpp b/bsnes/cheat/cheat.hpp deleted file mode 100755 index ac4b43ec..00000000 --- a/bsnes/cheat/cheat.hpp +++ /dev/null @@ -1,35 +0,0 @@ -struct CheatCode { - bool enabled; - array addr; - array data; - - bool operator=(string); - CheatCode(); -}; - -class Cheat : public linear_vector { -public: - enum class Type : unsigned { ProActionReplay, GameGenie }; - - bool enabled() const; - void enable(bool); - void synchronize(); - bool read(unsigned, uint8&) const; - - inline bool active() const; - inline bool exists(unsigned addr) const; - - Cheat(); - - static bool decode(const char*, unsigned&, uint8&, Type&); - static bool encode(string&, unsigned, uint8, Type); - -private: - uint8 bitmask[0x200000]; - bool system_enabled; - bool code_enabled; - bool cheat_enabled; - unsigned mirror(unsigned) const; -}; - -extern Cheat cheat; diff --git a/bsnes/chip/bsx/bsx.cpp b/bsnes/chip/bsx/bsx.cpp deleted file mode 100755 index 8a083103..00000000 --- a/bsnes/chip/bsx/bsx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#define BSX_CPP -namespace SNES { - #include "bsx_base.cpp" - #include "bsx_cart.cpp" - #include "bsx_flash.cpp" -} diff --git a/bsnes/chip/bsx/bsx.hpp b/bsnes/chip/bsx/bsx.hpp deleted file mode 100755 index 4e06b64c..00000000 --- a/bsnes/chip/bsx/bsx.hpp +++ /dev/null @@ -1,71 +0,0 @@ -class BSXBase : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - -private: - struct { - uint8 r2188, r2189, r218a, r218b; - uint8 r218c, r218d, r218e, r218f; - uint8 r2190, r2191, r2192, r2193; - uint8 r2194, r2195, r2196, r2197; - uint8 r2198, r2199, r219a, r219b; - uint8 r219c, r219d, r219e, r219f; - - uint8 r2192_counter; - uint8 r2192_hour, r2192_minute, r2192_second; - } regs; -}; - -class BSXCart : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - BSXCart(); - ~BSXCart(); - -private: - struct { - uint8 r[16]; - } regs; - - void update_memory_map(); -}; - -class BSXFlash : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - unsigned size() const; - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - -private: - struct { - unsigned command; - uint8 write_old; - uint8 write_new; - - bool flash_enable; - bool read_enable; - bool write_enable; - } regs; -}; - -extern BSXBase bsxbase; -extern BSXCart bsxcart; -extern BSXFlash bsxflash; diff --git a/bsnes/chip/bsx/bsx_base.cpp b/bsnes/chip/bsx/bsx_base.cpp deleted file mode 100755 index 2272c174..00000000 --- a/bsnes/chip/bsx/bsx_base.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#ifdef BSX_CPP - -BSXBase bsxbase; - -void BSXBase::init() { -} - -void BSXBase::enable() { - for(uint16 i = 0x2188; i <= 0x219f; i++) memory::mmio.map(i, *this); -} - -void BSXBase::power() { - reset(); -} - -void BSXBase::reset() { - memset(®s, 0x00, sizeof regs); -} - -uint8 BSXBase::mmio_read(unsigned addr) { - addr &= 0xffff; - - switch(addr) { - case 0x2188: return regs.r2188; - case 0x2189: return regs.r2189; - case 0x218a: return regs.r218a; - case 0x218c: return regs.r218c; - case 0x218e: return regs.r218e; - case 0x218f: return regs.r218f; - case 0x2190: return regs.r2190; - - case 0x2192: { - unsigned counter = regs.r2192_counter++; - if(regs.r2192_counter >= 18) regs.r2192_counter = 0; - - if(counter == 0) { - time_t rawtime; - time(&rawtime); - tm *t = localtime(&rawtime); - - regs.r2192_hour = t->tm_hour; - regs.r2192_minute = t->tm_min; - regs.r2192_second = t->tm_sec; - } - - switch(counter) { - case 0: return 0x00; //??? - case 1: return 0x00; //??? - case 2: return 0x00; //??? - case 3: return 0x00; //??? - case 4: return 0x00; //??? - case 5: return 0x01; - case 6: return 0x01; - case 7: return 0x00; - case 8: return 0x00; - case 9: return 0x00; - case 10: return regs.r2192_second; - case 11: return regs.r2192_minute; - case 12: return regs.r2192_hour; - case 13: return 0x00; //??? - case 14: return 0x00; //??? - case 15: return 0x00; //??? - case 16: return 0x00; //??? - case 17: return 0x00; //??? - } - } break; - - case 0x2193: return regs.r2193 & ~0x0c; - case 0x2194: return regs.r2194; - case 0x2196: return regs.r2196; - case 0x2197: return regs.r2197; - case 0x2199: return regs.r2199; - } - - return cpu.regs.mdr; -} - -void BSXBase::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - switch(addr) { - case 0x2188: { - regs.r2188 = data; - } break; - - case 0x2189: { - regs.r2189 = data; - } break; - - case 0x218a: { - regs.r218a = data; - } break; - - case 0x218b: { - regs.r218b = data; - } break; - - case 0x218c: { - regs.r218c = data; - } break; - - case 0x218e: { - regs.r218e = data; - } break; - - case 0x218f: { - regs.r218e >>= 1; - regs.r218e = regs.r218f - regs.r218e; - regs.r218f >>= 1; - } break; - - case 0x2191: { - regs.r2191 = data; - regs.r2192_counter = 0; - } break; - - case 0x2192: { - regs.r2190 = 0x80; - } break; - - case 0x2193: { - regs.r2193 = data; - } break; - - case 0x2194: { - regs.r2194 = data; - } break; - - case 0x2197: { - regs.r2197 = data; - } break; - - case 0x2199: { - regs.r2199 = data; - } break; - } -} - -#endif - diff --git a/bsnes/chip/bsx/bsx_cart.cpp b/bsnes/chip/bsx/bsx_cart.cpp deleted file mode 100755 index 6bd67269..00000000 --- a/bsnes/chip/bsx/bsx_cart.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef BSX_CPP - -BSXCart bsxcart; - -void BSXCart::init() { -} - -void BSXCart::enable() { -} - -void BSXCart::power() { - reset(); -} - -void BSXCart::reset() { - for(unsigned i = 0; i < 16; i++) regs.r[i] = 0x00; - regs.r[0x07] = 0x80; - regs.r[0x08] = 0x80; - - update_memory_map(); -} - -void BSXCart::update_memory_map() { - Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)memory::bsxpram; - - if((regs.r[0x02] & 0x80) == 0x00) { - //LoROM mapping - bus.map(Bus::MapMode::Linear, 0x00, 0x7d, 0x8000, 0xffff, cart); - bus.map(Bus::MapMode::Linear, 0x80, 0xff, 0x8000, 0xffff, cart); - } else { - //HiROM mapping - bus.map(Bus::MapMode::Shadow, 0x00, 0x3f, 0x8000, 0xffff, cart); - bus.map(Bus::MapMode::Linear, 0x40, 0x7d, 0x0000, 0xffff, cart); - bus.map(Bus::MapMode::Shadow, 0x80, 0xbf, 0x8000, 0xffff, cart); - bus.map(Bus::MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, cart); - } - - if(regs.r[0x03] & 0x80) { - bus.map(Bus::MapMode::Linear, 0x60, 0x6f, 0x0000, 0xffff, memory::bsxpram); - //bus.map(Bus::MapMode::Linear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram); - } - - if((regs.r[0x05] & 0x80) == 0x00) { - bus.map(Bus::MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::bsxpram); - } - - if((regs.r[0x06] & 0x80) == 0x00) { - bus.map(Bus::MapMode::Linear, 0x50, 0x5f, 0x0000, 0xffff, memory::bsxpram); - } - - if(regs.r[0x07] & 0x80) { - bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom); - } - - if(regs.r[0x08] & 0x80) { - bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom); - } - - bus.map(Bus::MapMode::Shadow, 0x20, 0x3f, 0x6000, 0x7fff, memory::bsxpram); - bus.map(Bus::MapMode::Linear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram); -} - -uint8 BSXCart::mmio_read(unsigned addr) { - if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO - uint8 n = (addr >> 16) & 15; - return regs.r[n]; - } - - if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM - return memory::bsxram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff)); - } - - return 0x00; -} - -void BSXCart::mmio_write(unsigned addr, uint8 data) { - if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO - uint8 n = (addr >> 16) & 15; - regs.r[n] = data; - if(n == 0x0e && data & 0x80) update_memory_map(); - return; - } - - if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM - return memory::bsxram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data); - } -} - -BSXCart::BSXCart() { -} - -BSXCart::~BSXCart() { -} - -#endif - diff --git a/bsnes/chip/bsx/bsx_flash.cpp b/bsnes/chip/bsx/bsx_flash.cpp deleted file mode 100755 index a4297a2b..00000000 --- a/bsnes/chip/bsx/bsx_flash.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#ifdef BSX_CPP - -BSXFlash bsxflash; - -void BSXFlash::init() {} -void BSXFlash::enable() {} - -void BSXFlash::power() { - reset(); -} - -void BSXFlash::reset() { - regs.command = 0; - regs.write_old = 0x00; - regs.write_new = 0x00; - - regs.flash_enable = false; - regs.read_enable = false; - regs.write_enable = false; - memory::bsxflash.write_protect(!regs.write_enable); -} - -unsigned BSXFlash::size() const { - return memory::bsxflash.size(); -} - -uint8 BSXFlash::read(unsigned addr) { - if(addr == 0x0002) { - if(regs.flash_enable) return 0x80; - } - - if(addr == 0x5555) { - if(regs.flash_enable) return 0x80; - } - - if(regs.read_enable && addr >= 0xff00 && addr <= 0xff13) { - //read flash cartridge vendor information - switch(addr - 0xff00) { - case 0x00: return 0x4d; - case 0x01: return 0x00; - case 0x02: return 0x50; - case 0x03: return 0x00; - case 0x04: return 0x00; - case 0x05: return 0x00; - case 0x06: return 0x2a; //0x2a = 8mbit, 0x2b = 16mbit (not known to exist, though BIOS recognizes ID) - case 0x07: return 0x00; - default: return 0x00; - } - } - - return memory::bsxflash.read(addr); -} - -void BSXFlash::write(unsigned addr, uint8 data) { - //there exist both read-only and read-write BS-X flash cartridges ... - //unfortunately, the vendor info is not stored inside memory dumps - //of BS-X flashcarts, so it is impossible to determine whether a - //given flashcart is writeable. - //however, it has been observed that LoROM-mapped BS-X carts always - //use read-write flashcarts, and HiROM-mapped BS-X carts always use - //read-only flashcarts. - //below is an unfortunately necessary workaround to this problem. - //if(cartridge.mapper() == Cartridge::BSCHiROM) return; - - if((addr & 0xff0000) == 0) { - regs.write_old = regs.write_new; - regs.write_new = data; - - if(regs.write_enable && regs.write_old == regs.write_new) { - return memory::bsxflash.write(addr, data); - } - } else { - if(regs.write_enable) { - return memory::bsxflash.write(addr, data); - } - } - - if(addr == 0x0000) { - regs.command <<= 8; - regs.command |= data; - - if((regs.command & 0xffff) == 0x38d0) { - regs.flash_enable = true; - regs.read_enable = true; - } - } - - if(addr == 0x2aaa) { - regs.command <<= 8; - regs.command |= data; - } - - if(addr == 0x5555) { - regs.command <<= 8; - regs.command |= data; - - if((regs.command & 0xffffff) == 0xaa5570) { - regs.write_enable = false; - } - - if((regs.command & 0xffffff) == 0xaa55a0) { - regs.write_old = 0x00; - regs.write_new = 0x00; - regs.flash_enable = true; - regs.write_enable = true; - } - - if((regs.command & 0xffffff) == 0xaa55f0) { - regs.flash_enable = false; - regs.read_enable = false; - regs.write_enable = false; - } - - memory::bsxflash.write_protect(!regs.write_enable); - } -} - -#endif - diff --git a/bsnes/chip/chip.hpp b/bsnes/chip/chip.hpp deleted file mode 100755 index 6893952f..00000000 --- a/bsnes/chip/chip.hpp +++ /dev/null @@ -1,31 +0,0 @@ -struct Coprocessor : Processor { - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); -}; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void Coprocessor::step(unsigned clocks) { - clock += clocks * (uint64)cpu.frequency; -} - -void Coprocessor::synchronize_cpu() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); -} diff --git a/bsnes/chip/cx4/cx4.cpp b/bsnes/chip/cx4/cx4.cpp deleted file mode 100755 index f6362e7c..00000000 --- a/bsnes/chip/cx4/cx4.cpp +++ /dev/null @@ -1,208 +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::enable() { -} - -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/chip/cx4/cx4.hpp b/bsnes/chip/cx4/cx4.hpp deleted file mode 100755 index f971f44d..00000000 --- a/bsnes/chip/cx4/cx4.hpp +++ /dev/null @@ -1,95 +0,0 @@ -class Cx4 : public Memory { -public: - void init(); - void enable(); - 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/chip/cx4/data.cpp b/bsnes/chip/cx4/data.cpp deleted file mode 100755 index 8538f602..00000000 --- a/bsnes/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/chip/cx4/functions.cpp b/bsnes/chip/cx4/functions.cpp deleted file mode 100755 index 7466ffb8..00000000 --- a/bsnes/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/chip/cx4/oam.cpp b/bsnes/chip/cx4/oam.cpp deleted file mode 100755 index dcda69e4..00000000 --- a/bsnes/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/chip/cx4/opcodes.cpp b/bsnes/chip/cx4/opcodes.cpp deleted file mode 100755 index 28f62c1d..00000000 --- a/bsnes/chip/cx4/opcodes.cpp +++ /dev/null @@ -1,227 +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; - - 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/chip/cx4/serialization.cpp b/bsnes/chip/cx4/serialization.cpp deleted file mode 100755 index 1b36a4eb..00000000 --- a/bsnes/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/chip/dsp1/dsp1.cpp b/bsnes/chip/dsp1/dsp1.cpp deleted file mode 100755 index ae71d3bf..00000000 --- a/bsnes/chip/dsp1/dsp1.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -#define DSP1_CPP -namespace SNES { - -DSP1 dsp1; -DSP1DR dsp1dr; -DSP1SR dsp1sr; - -#include "serialization.cpp" -#include "dsp1emu.cpp" - -void DSP1::init() { -} - -void DSP1::enable() { -} - -void DSP1::power() { - reset(); -} - -void DSP1::reset() { - dsp1.reset(); -} - -uint8 DSP1DR::read(unsigned addr) { return dsp1.dsp1.getDr(); } -void DSP1DR::write(unsigned addr, uint8 data) { dsp1.dsp1.setDr(data); } - -uint8 DSP1SR::read(unsigned addr) { return dsp1.dsp1.getSr(); } -void DSP1SR::write(unsigned addr, uint8 data) {} - -} diff --git a/bsnes/chip/dsp1/dsp1.hpp b/bsnes/chip/dsp1/dsp1.hpp deleted file mode 100755 index 5e373be2..00000000 --- a/bsnes/chip/dsp1/dsp1.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "dsp1emu.hpp" - -class DSP1 { -public: - void init(); - void enable(); - void power(); - void reset(); - - void serialize(serializer&); - -private: - Dsp1 dsp1; - friend class DSP1DR; - friend class DSP1SR; -}; - -class DSP1DR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class DSP1SR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP1 dsp1; -extern DSP1DR dsp1dr; -extern DSP1SR dsp1sr; diff --git a/bsnes/chip/dsp1/dsp1emu.cpp b/bsnes/chip/dsp1/dsp1emu.cpp deleted file mode 100755 index d933b11c..00000000 --- a/bsnes/chip/dsp1/dsp1emu.cpp +++ /dev/null @@ -1,1625 +0,0 @@ -#ifdef DSP1_CPP - -// DSP-1's emulation code -// -// Based on research by Overload, The Dumper, Neviksti and Andreas Naive -// Date: June 2006 - -////////////////////////////////////////////////////////////////// - -Dsp1::Dsp1() -{ - reset(); -} - -////////////////////////////////////////////////////////////////// - -uint8 Dsp1::getSr() -{ - mSrLowByteAccess = ~mSrLowByteAccess; - if (mSrLowByteAccess) - return 0; - else - return mSr; -} - -////////////////////////////////////////////////////////////////// - -uint8 Dsp1::getDr() -{ - uint8 oDr; - - fsmStep(true, oDr); - return oDr; -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::setDr(uint8 iDr) -{ - fsmStep(false, iDr); -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::reset() -{ - mSr = DRC|RQM; - mSrLowByteAccess = false; - mDr = 0x0080; // Only a supposition. Is this correct? - mFreeze = false; - mFsmMajorState = WAIT_COMMAND; - memset(&shared, 0, sizeof(SharedData)); // another supposition -} - -////////////////////////////////////////////////////////////////// - -// Though the DSP-1 is unaware of the type of operation (read or write) -// we need to know what is being done by the program, as the class -// is responsible for maintaining the binding between the -// "external" and "internal" representations of the DR (data register). - -void Dsp1::fsmStep(bool read, uint8 &data) -{ - if (0 == (mSr&RQM)) return; - // Now RQM would be cleared; however, as this code is not to be used in - // a multithread environment, we will simply fake RQM operation. - // (The only exception would be Op1A's freeze.) - - // binding - if (read) - { - if (mSr&DRS) - data = static_cast(mDr>>8); - else - data = static_cast(mDr); - } - else - { - if (mSr&DRS) - { - mDr &= 0x00ff; - mDr |= data<<8; - } - else - { - mDr &= 0xff00; - mDr |= data; - } - } - - - switch (mFsmMajorState) - { - case WAIT_COMMAND: - mCommand = static_cast(mDr); - if (!(mCommand & 0xc0)) // valid command? - { - switch(mCommand) - { - // freeze cases - case 0x1a: - case 0x2a: - case 0x3a: - mFreeze = true; - break; - // normal cases - default: - mDataCounter=0; - mFsmMajorState = READ_DATA; - mSr &= ~DRC; - break; - } - } - break; - case READ_DATA: - mSr ^= DRS; - if (!(mSr&DRS)) - { - mReadBuffer[mDataCounter++] = static_cast(mDr); - if (mDataCounter >= mCommandTable[mCommand].reads) - { - (this->*mCommandTable[mCommand].callback)(mReadBuffer, mWriteBuffer); - if (0 != mCommandTable[mCommand].writes) // any output? - { - mDataCounter = 0; - mDr = static_cast(mWriteBuffer[mDataCounter]); - mFsmMajorState = WRITE_DATA; - } - else - { - mDr = 0x0080; // valid command completion - mFsmMajorState = WAIT_COMMAND; - mSr |= DRC; - } - } - } - break; - case WRITE_DATA: - mSr ^= DRS; - if (!(mSr&DRS)) - { - ++mDataCounter; - if (mDataCounter >= mCommandTable[mCommand].writes) - { - if ((mCommand == 0x0a)&&(mDr != 0x8000)) - { - // works in continuous mode - mReadBuffer[0]++; // next raster line - (this->*mCommandTable[mCommand].callback)(mReadBuffer, mWriteBuffer); - mDataCounter = 0; - mDr = static_cast(mWriteBuffer[mDataCounter]); - } - else - { - mDr = 0x0080; // valid command completion - mFsmMajorState = WAIT_COMMAND; - mSr |= DRC; - } - } - else - { - mDr = static_cast(mWriteBuffer[mDataCounter]); - } - } - break; - } - - - - // Now RQM would be set (except when executing Op1A -command equals 0x1a, 0x2a or 0x3a-). - if (mFreeze) - mSr &= ~RQM; -} - -////////////////////////////////////////////////////////////////// - -// The info on this table follows Overload's docs. - -const Dsp1::Command Dsp1::mCommandTable[0x40] = { - {&Dsp1::multiply, 2, 1}, //0x00 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveA, 3, 3}, //0x03 - {&Dsp1::triangle, 2, 2}, //0x04 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memoryTest, 1, 1}, //0x0f - {&Dsp1::radius, 3, 2}, //0x08 - {&Dsp1::objectiveA, 3, 3}, //0x0d - {&Dsp1::raster, 1, 4}, // 0x0a. This will normally work in continuous mode - {&Dsp1::scalarA, 3, 1}, //0x0b - {&Dsp1::rotate, 3, 2}, //0x0c - {&Dsp1::objectiveA, 3, 3}, //0x0d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memoryTest, 1, 1}, //0x0f - - {&Dsp1::inverse, 2, 2}, //0x10 - {&Dsp1::attitudeB, 4, 0}, //0x11 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveB, 3, 3}, //0x13 - {&Dsp1::gyrate, 6, 3}, //0x14 - {&Dsp1::attitudeB, 4, 0}, //0x11 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memoryDump, 1, 1024}, //0x1f - {&Dsp1::range, 4, 1}, //0x18 - {&Dsp1::objectiveB, 3, 3}, //0x1d - {0, 0, 0}, // 0x1a; the chip freezes - {&Dsp1::scalarB, 3, 1}, //0x1b - {&Dsp1::polar, 6, 3}, //0x1c - {&Dsp1::objectiveB, 3, 3}, //0x1d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memoryDump, 1, 1024}, //0x1f - - {&Dsp1::multiply2, 2, 1}, //0x20 - {&Dsp1::attitudeC, 4, 0}, //0x21 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveC, 3, 3}, //0x23 - {&Dsp1::triangle, 2, 2}, //0x04 - {&Dsp1::attitudeC, 4, 0}, //0x21 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memorySize, 1, 1}, //0x2f - {&Dsp1::distance, 3, 1}, //0x28 - {&Dsp1::objectiveC, 3, 3}, //0x2d - {0, 0, 0}, // 0x1a; the chip freezes - {&Dsp1::scalarC, 3, 1}, //0x2b - {&Dsp1::rotate, 3, 2}, //0x0c - {&Dsp1::objectiveC, 3, 3}, //0x2d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memorySize, 1, 1}, //0x2f - - {&Dsp1::inverse, 2, 2}, //0x10 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::parameter, 7, 4}, //0x02 - {&Dsp1::subjectiveA, 3, 3}, //0x03 - {&Dsp1::gyrate, 6, 3}, //0x14 - {&Dsp1::attitudeA, 4, 0}, //0x01 - {&Dsp1::project, 3, 3}, //0x06 - {&Dsp1::memoryDump, 1, 1024}, //0x1f - {&Dsp1::range2, 4, 1}, //0x38 - {&Dsp1::objectiveA, 3, 3}, //0x0d - {0, 0, 0}, // 0x1a; the chip freezes - {&Dsp1::scalarA, 3, 1}, //0x0b - {&Dsp1::polar, 6, 3}, //0x1c - {&Dsp1::objectiveA, 3, 3}, //0x0d - {&Dsp1::target, 2, 2}, //0x0e - {&Dsp1::memoryDump, 1, 1024}, //0x1f -}; - -////////////////////////////////////////////////////////////////// - -void Dsp1::memoryTest(int16 *input, int16 *output) -{ - int16& Size = input[0]; - int16& Result = output[0]; - - Result = 0x0000; -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::memoryDump(int16 *input, int16 *output) -{ - memcpy(output, DataRom, 1024); -} - -////////////////////////////////////////////////////////////////// - -void Dsp1::memorySize(int16 *input, int16 *output) -{ - int16& Size = output[0]; - - Size = 0x0100; -} - -////////////////////////////////////////////////////////////////// - -// 16-bit multiplication - -void Dsp1::multiply(int16 *input, int16 *output) -{ - int16& Multiplicand = input[0]; - int16& Multiplier = input[1]; - int16& Product = output[0]; - - Product = Multiplicand * Multiplier >> 15; -} - -////////////////////////////////////////////////////////////////// - -// 16-bit multiplication. 'Alternative' method. Can anyone check this carefully? - -void Dsp1::multiply2(int16 *input, int16 *output) -{ - int16& Multiplicand = input[0]; - int16& Multiplier = input[1]; - int16& Product = output[0]; - - Product = (Multiplicand * Multiplier >> 15)+1; -} - -////////////////////////////////////////////////////////////////// - -// This command determines the inverse of a floating point decimal number. - -void Dsp1::inverse(int16 *input, int16 *output) -{ - int16& Coefficient = input[0]; - int16& Exponent = input[1]; - int16& iCoefficient = output[0]; - int16& iExponent = output[1]; - - inverse(Coefficient, Exponent, iCoefficient, iExponent); -} - -////////////////////////////////////////////////////////////////// - -// Vector component calculation. Determines the X and Y components for a -// two-dimensional vector whose size and direction is known. -// Y = Radius * sin(Angle) -// X = Radius * cos(Angle) - -void Dsp1::triangle(int16 *input, int16 *output) -{ - int16& Angle = input[0]; - int16& Radius = input[1]; - int16& Y = output[0]; - int16& X = output[1]; - - Y = sin(Angle) * Radius >> 15; - X = cos(Angle) * Radius >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Determines the squared norm of a vector (X,Y,Z) -// The output is Radius = X^2+Y^2+Z^2 (double integer) - -void Dsp1::radius(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& RadiusLow = output[0]; - int16& RadiusHigh = output[1]; - - int32 Radius; - - Radius = (X * X + Y * Y + Z * Z) << 1; - RadiusLow = static_cast(Radius); - RadiusHigh = static_cast(Radius>>16); -} - -////////////////////////////////////////////////////////////////// - -// Vector size comparison. This command compares the size of the vector (X,Y,Z) and the distance (R) -// from a particular point, and so may be used to determine if a point is within the sphere or radius R. -// The output is D = X^2+Y^2+Z^2-R^2 - -void Dsp1::range(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& Radius = input[3]; - int16& Range = output[0]; - - Range = (X * X + Y * Y + Z * Z - Radius * Radius) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Vector size comparison. 'Alternative' method. - -void Dsp1::range2(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& Radius = input[3]; - int16& Range = output[0]; - - Range = ((X * X + Y * Y + Z * Z - Radius * Radius) >> 15) + 1; -} - -////////////////////////////////////////////////////////////////// - -// This command calculates the norm of a (X,Y,Z) vector, or the distance from -// the point (X,Y,Z) to (0,0,0), as you prefer to see it. -// Distance = sqrt(X^2+Y^2+Z^2) -// The square root of a number 'a' is calculated by doing this: you -// write 'a' as b*2^2n, with 'b' between 1/4 and 1; then, you calculate -// c=sqrt(b) by using lineal interpolation between points of a -// look-up table and, finally, you output the result as c*2^n. - -void Dsp1::distance(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& Distance = output[0]; - - int32 Radius = X * X + Y * Y + Z * Z; - - if (Radius == 0) Distance = 0; - else - { - int16 C, E; - normalizeDouble(Radius, C, E); - if (E & 1) C = C * 0x4000 >> 15; - - int16 Pos = C * 0x0040 >> 15; - - int16 Node1 = DataRom[0x00d5 + Pos]; - int16 Node2 = DataRom[0x00d6 + Pos]; - - Distance = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1; - -#if DSP1_VERSION < 0x0102 - if (Pos & 1) Distance -= (Node2 - Node1); -#endif - Distance >>= (E >> 1); - } -} - -////////////////////////////////////////////////////////////////// - -// Determines the (X2, Y2) coordinates obtained by rotating (X1, Y1) -// clockwise for an angle 'Angle'. The official documentation says -// 'counterclockwise', but it's obviously wrong (surprise! :P) -// -// In matrix notation: -// |X2| |cos(Angle) sin(Angle)| |X1| -// | | = | | | | -// |Y2| |-sin(Angle cos(Angle)| |Y1| - -void Dsp1::rotate(int16 *input, int16 *output) -{ - int16& Angle = input[0]; - int16& X1 = input[1]; - int16& Y1 = input[2]; - int16& X2 = output[0]; - int16& Y2 = output[1]; - - X2 = (Y1 * sin(Angle) >> 15) + (X1 * cos(Angle) >> 15); - Y2 = (Y1 * cos(Angle) >> 15) - (X1 * sin(Angle) >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Calculate the coordinates (X2, Y2, Z2) obtained when rotating (X1, Y1, Z1) -// three-dimensionally. Rotation is done in the order of Az around the Z axis, -// Ay around the Y axis and Ax around the X axis. As occur with the "attitude" commands -// (see comments in the "gyrate" command), this doesn't match what explained in -// the official documentation, but it's coherent with what it is done in the "attitude" -// command (but not with the "gyrate" command). -// -// In matrix notation: -// |X2| |1 0 0 | |cosRy 0 -sinRy| | cosRz sinRz 0| |X1| -// |Y2| = |0 cosRx sinRx| | 0 1 0 | |-sinRz cosRz 0| |Y1| -// |Z2| |0 -sinRx cosRx| |sinRy 0 cosRy| | 0 0 1| |Z1| - -void Dsp1::polar(int16 *input, int16 *output) -{ - int16& Az = input[0]; - int16& Ay = input[1]; - int16& Ax = input[2]; - int16& X1 = input[3]; - int16& Y1 = input[4]; - int16& Z1 = input[5]; - int16& X2 = output[0]; - int16& Y2 = output[1]; - int16& Z2 = output[2]; - - int16 X, Y, Z; - - // Rotate Around Z - X = (Y1 * sin(Az) >> 15) + (X1 * cos(Az) >> 15); - Y = (Y1 * cos(Az) >> 15) - (X1 * sin(Az) >> 15); - X1 = X; Y1 = Y; - - // Rotate Around Y - Z = (X1 * sin(Ay) >> 15) + (Z1 * cos(Ay) >> 15); - X = (X1 * cos(Ay) >> 15) - (Z1 * sin(Ay) >> 15); - X2 = X; Z1 = Z; - - // Rotate Around X - Y = (Z1 * sin(Ax) >> 15) + (Y1 * cos(Ax) >> 15); - Z = (Z1 * cos(Ax) >> 15) - (Y1 * sin(Ax) >> 15); - Y2 = Y; Z2 = Z; -} - -////////////////////////////////////////////////////////////////// - -// Set up the elements of an "attitude matrix" (there are other ones): -// S | cosRz sinRz 0| |cosRy 0 -sinRy| |1 0 0 | -// MatrixA = - |-sinRz cosRz 0| | 0 1 0 | |0 cosRx sinRx| -// 2 | 0 0 1| |sinRy 0 cosRy| |0 -sinRx cosRx| -// This matrix is thought to be used within the following framework: -// let's suppose we define positive rotations around a system of orthogonal axes in this manner: -// a rotation of +90 degrees around axis3 converts axis2 into axis1 -// a rotation of +90 degrees around axis2 converts axis1 into axis3 -// a rotation of +90 degrees around axis1 converts axis3 into axis2 -// and let's suppose that we have defined a new orthonormal axes system (FLU) -// by doing the following operations about the standard one (XYZ): -// first rotating the XYZ system around Z by an angle Rz (obtaining X'Y'Z'), -// then rotating the resulting system around Y by an angle Ry (obtaining X''Y''Z'') -// and, finally, rotating the resulting system around X by an angle Rx (obtaining FLU) -// This FLU (forward/left/up) system represents an "attitude" and, then, the matrix here defined -// is the change of coordinates matrix that transform coordinates in the FLU -// system (the "object coordinates") into the standard XYZ system (the "global coordinates"), -// multiplied by a scale factor S/2, that is: -// |x| S |f| -// |y| * - = MatrixA * |l| -// |z| 2 |u| -// In a similar way, if we use the transpose of the matrix, we can transform global coordinates -// into object coordinates: -// |f| S |x| -// |l| * - = MatrixA_transposed * |y| -// |u| 2 |z| -// -// input[0]: S -// input[1]: Rz -// input[2]: Ry -// input[3]: Rx - -void Dsp1::attitudeA(int16 *input, int16 *output) -{ - int16& S = input[0]; - int16& Rz = input[1]; - int16& Ry = input[2]; - int16& Rx = input[3]; - - int16 SinRz = sin(Rz); - int16 CosRz = cos(Rz); - int16 SinRy = sin(Ry); - int16 CosRy = cos(Ry); - int16 SinRx = sin(Rx); - int16 CosRx = cos(Rx); - - S >>= 1; - - shared.MatrixA[0][0] = (S * CosRz >> 15) * CosRy >> 15; - shared.MatrixA[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixA[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixA[1][0] = -((S * SinRz >> 15) * CosRy >> 15); - shared.MatrixA[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixA[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixA[2][0] = S * SinRy >> 15; - shared.MatrixA[2][1] = -((S * SinRx >> 15) * CosRy >> 15); - shared.MatrixA[2][2] = (S * CosRx >> 15) * CosRy >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'attitudeA', but with a difference attitude matrix (matrixB) - -void Dsp1::attitudeB(int16 *input, int16 *output) -{ - int16& S = input[0]; - int16& Rz = input[1]; - int16& Ry = input[2]; - int16& Rx = input[3]; - - int16 SinRz = sin(Rz); - int16 CosRz = cos(Rz); - int16 SinRy = sin(Ry); - int16 CosRy = cos(Ry); - int16 SinRx = sin(Rx); - int16 CosRx = cos(Rx); - - S >>= 1; - - shared.MatrixB[0][0] = (S * CosRz >> 15) * CosRy >> 15; - shared.MatrixB[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixB[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixB[1][0] = -((S * SinRz >> 15) * CosRy >> 15); - shared.MatrixB[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixB[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixB[2][0] = S * SinRy >> 15; - shared.MatrixB[2][1] = -((S * SinRx >> 15) * CosRy >> 15); - shared.MatrixB[2][2] = (S * CosRx >> 15) * CosRy >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'attitudeA', but with a difference attitude matrix (matrixC) - -void Dsp1::attitudeC(int16 *input, int16 *output) -{ - int16& S = input[0]; - int16& Rz = input[1]; - int16& Ry = input[2]; - int16& Rx = input[3]; - - int16 SinRz = sin(Rz); - int16 CosRz = cos(Rz); - int16 SinRy = sin(Ry); - int16 CosRy = cos(Ry); - int16 SinRx = sin(Rx); - int16 CosRx = cos(Rx); - - S >>= 1; - - shared.MatrixC[0][0] = (S * CosRz >> 15) * CosRy >> 15; - shared.MatrixC[0][1] = ((S * SinRz >> 15) * CosRx >> 15) + (((S * CosRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixC[0][2] = ((S * SinRz >> 15) * SinRx >> 15) - (((S * CosRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixC[1][0] = -((S * SinRz >> 15) * CosRy >> 15); - shared.MatrixC[1][1] = ((S * CosRz >> 15) * CosRx >> 15) - (((S * SinRz >> 15) * SinRx >> 15) * SinRy >> 15); - shared.MatrixC[1][2] = ((S * CosRz >> 15) * SinRx >> 15) + (((S * SinRz >> 15) * CosRx >> 15) * SinRy >> 15); - - shared.MatrixC[2][0] = S * SinRy >> 15; - shared.MatrixC[2][1] = -((S * SinRx >> 15) * CosRy >> 15); - shared.MatrixC[2][2] = (S * CosRx >> 15) * CosRy >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Convert global coordinates (X,Y,Z) to object coordinates (F,L,U) -// See the comment in "attitudeA" for a explanation about the calculation. -// -// input[0]: X ; input[1]: Y ; input[2]: Z -// output[0]: F ; output[1]: L ; output[2]: U - -void Dsp1::objectiveA(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& F = output[0]; - int16& L = output[1]; - int16& U = output[2]; - - F = (shared.MatrixA[0][0] * X >> 15) + (shared.MatrixA[1][0] * Y >> 15) + (shared.MatrixA[2][0] * Z >> 15); - L = (shared.MatrixA[0][1] * X >> 15) + (shared.MatrixA[1][1] * Y >> 15) + (shared.MatrixA[2][1] * Z >> 15); - U = (shared.MatrixA[0][2] * X >> 15) + (shared.MatrixA[1][2] * Y >> 15) + (shared.MatrixA[2][2] * Z >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'objectiveA', but for the 'B' attitude - -void Dsp1::objectiveB(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& F = output[0]; - int16& L = output[1]; - int16& U = output[2]; - - F = (shared.MatrixB[0][0] * X >> 15) + (shared.MatrixB[1][0] * Y >> 15) + (shared.MatrixB[2][0] * Z >> 15); - L = (shared.MatrixB[0][1] * X >> 15) + (shared.MatrixB[1][1] * Y >> 15) + (shared.MatrixB[2][1] * Z >> 15); - U = (shared.MatrixB[0][2] * X >> 15) + (shared.MatrixB[1][2] * Y >> 15) + (shared.MatrixB[2][2] * Z >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'objectiveA', but for the 'C' attitude - -void Dsp1::objectiveC(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& F = output[0]; - int16& L = output[1]; - int16& U = output[2]; - - F = (shared.MatrixC[0][0] * X >> 15) + (shared.MatrixC[1][0] * Y >> 15) + (shared.MatrixC[2][0] * Z >> 15); - L = (shared.MatrixC[0][1] * X >> 15) + (shared.MatrixC[1][1] * Y >> 15) + (shared.MatrixC[2][1] * Z >> 15); - U = (shared.MatrixC[0][2] * X >> 15) + (shared.MatrixC[1][2] * Y >> 15) + (shared.MatrixC[2][2] * Z >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Convert object coordinates (F,L,U) to object coordinates (X,Y,Z) -// See the comment in "attitudeA" for a explanation about the calculation. -// -// input[0]: F ; input[1]: L ; input[2]: U -// output[0]: X ; output[1]: Y ; output[2]: Z - -void Dsp1::subjectiveA(int16 *input, int16 *output) -{ - int16& F = input[0]; - int16& L = input[1]; - int16& U = input[2]; - int16& X = output[0]; - int16& Y = output[1]; - int16& Z = output[2]; - - X = (shared.MatrixA[0][0] * F >> 15) + (shared.MatrixA[0][1] * L >> 15) + (shared.MatrixA[0][2] * U >> 15); - Y = (shared.MatrixA[1][0] * F >> 15) + (shared.MatrixA[1][1] * L >> 15) + (shared.MatrixA[1][2] * U >> 15); - Z = (shared.MatrixA[2][0] * F >> 15) + (shared.MatrixA[2][1] * L >> 15) + (shared.MatrixA[2][2] * U >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'subjectiveA', but for the 'B' attitude - -void Dsp1::subjectiveB(int16 *input, int16 *output) -{ - int16& F = input[0]; - int16& L = input[1]; - int16& U = input[2]; - int16& X = output[0]; - int16& Y = output[1]; - int16& Z = output[2]; - - X = (shared.MatrixB[0][0] * F >> 15) + (shared.MatrixB[0][1] * L >> 15) + (shared.MatrixB[0][2] * U >> 15); - Y = (shared.MatrixB[1][0] * F >> 15) + (shared.MatrixB[1][1] * L >> 15) + (shared.MatrixB[1][2] * U >> 15); - Z = (shared.MatrixB[2][0] * F >> 15) + (shared.MatrixB[2][1] * L >> 15) + (shared.MatrixB[2][2] * U >> 15); -} - -////////////////////////////////////////////////////////////////// - -// Same than 'subjectiveA', but for the 'C' attitude - -void Dsp1::subjectiveC(int16 *input, int16 *output) -{ - int16& F = input[0]; - int16& L = input[1]; - int16& U = input[2]; - int16& X = output[0]; - int16& Y = output[1]; - int16& Z = output[2]; - - X = (shared.MatrixC[0][0] * F >> 15) + (shared.MatrixC[0][1] * L >> 15) + (shared.MatrixC[0][2] * U >> 15); - Y = (shared.MatrixC[1][0] * F >> 15) + (shared.MatrixC[1][1] * L >> 15) + (shared.MatrixC[1][2] * U >> 15); - Z = (shared.MatrixC[2][0] * F >> 15) + (shared.MatrixC[2][1] * L >> 15) + (shared.MatrixC[2][2] * U >> 15); -} - -////////////////////////////////////////////////////////////////// - -// This command calculates the inner product (S) of a vector (X,Y,Z) and -// the first column of MatrixA. It should be noted that that first column -// represent the global coordinates of an unity vector in the forward -// direction in the object coordinate system (coordinates (1,0,0) in the FLU -// axes system). -// -// input[0]: X ; input[1]: Y ; input[2]: Z -// output[0]: S - -void Dsp1::scalarA(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& S = output[0]; - - S = (X * shared.MatrixA[0][0] + Y * shared.MatrixA[1][0] + Z * shared.MatrixA[2][0]) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'scalarA', but for the 'B' attitude - -void Dsp1::scalarB(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& S = output[0]; - - S = (X * shared.MatrixB[0][0] + Y * shared.MatrixB[1][0] + Z * shared.MatrixB[2][0]) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'scalarA', but for the 'C' attitude - -void Dsp1::scalarC(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& S = output[0]; - - S = (X * shared.MatrixC[0][0] + Y * shared.MatrixC[1][0] + Z * shared.MatrixC[2][0]) >> 15; -} - -////////////////////////////////////////////////////////////////// - -// This command determines the final attitude angles after the body with attitude angles (Ax, Ay, Az) with -// respect to the global coordinates is rotated by the minor angular displacements (DeltaF, DeltaL, DeltaU). -// It means that the XYZ axes are rotated by (Ax, Ay, Az) to obtain the FLU axes and, then, these -// are rotated by (DeltaF, DeltaL, DeltaU). The command calculates and return the new FLU angles respect to the -// XYZ system (Rx, Ry, Rz) -// The formulae are: -// Rx = Ax + (DeltaU*sin(Ay)+DeltaF*cos(Ay)) -// Ry = Ay + DeltaL - tan(Ax)*(DeltaU*cos(Ay)+DeltaF*sin(Ay)) -// Rz = Az + sec(Ax)*(DeltaU*cos(Ay)-DeltaF*sin(Ay)) -// -// Now the discussion: according to the official documentation, as described in various commands, you pass from -// XYZ to FLU by doing the rotations in the order Y, X, Z. In this command, the formulae are coherent with the -// fact that Y is the first axis to do a rotation around it. However, in the "attitude" command, while the official -// document describe it that way, we have discovered, when reverse engineering the command, that the calculated -// matrix do the rotation around Y in the second place. This incoherent behaviour of various commands is, in my -// opinion, a pretty severe implementation error. However, if you only use small "minor displacements", the error term -// introduced by that incoherence should be almost negligible. - -void Dsp1::gyrate(int16 *input, int16 *output) -{ - int16& Az = input[0]; - int16& Ax = input[1]; - int16& Ay = input[2]; - int16& U = input[3]; - int16& F = input[4]; - int16& L = input[5]; - int16& Rz = output[0]; - int16& Rx = output[1]; - int16& Ry = output[2]; - - int16 CSec, ESec, CSin, C, E; - int16 SinAy = sin(Ay); - int16 CosAy = cos(Ay); - - inverse(cos(Ax), 0, CSec, ESec); - - // Rotation Around Z - normalizeDouble(U * CosAy - F * SinAy, C, E); - - E = ESec - E; - - normalize(C * CSec >> 15, C, E); - - Rz = Az + denormalizeAndClip(C, E); - - // Rotation Around X - Rx = Ax + (U * SinAy >> 15) + (F * CosAy >> 15); - - // Rotation Around Y - normalizeDouble(U * CosAy + F * SinAy, C, E); - - E = ESec - E; - - normalize(sin(Ax), CSin, E); - - normalize(-(C * (CSec * CSin >> 15) >> 15), C, E); - - Ry = Ay + denormalizeAndClip(C, E) + L; -} - -////////////////////////////////////////////////////////////////// - -const int16 Dsp1::MaxAZS_Exp[16] = { - 0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca, - 0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4 -}; - -////////////////////////////////////////////////////////////////// - - -// Set-up the projection framework. Besides returning some values, it store in RAM some values that -// will be used by the other three projection commands (raster, target an project) -// Input: -// (Fx, Fy, Fz)-> coordinates of base point (global coordinates) -// Lfe-> distance between the base point and the viewpoint (center of projection) -// Les-> distance between the base point and the screen -// Aas-> azimuth angle (0 degrees is east; 90 degrees is north) -// Azs-> zenith angle (0 degrees is zenith) -// Output: -// Vof-> raster line of imaginary center (whatever it means ;) ) -// Vva-> raster line representing the horizon line -// (Cx, Cy)-> coordinates of the projection of the center of the screen over the ground (ground coordinates) - -void Dsp1::parameter(int16 *input, int16 *output) -{ - int16& Fx = input[0]; - int16& Fy = input[1]; - int16& Fz = input[2]; - int16& Lfe = input[3]; - int16& Les = input[4]; - int16& Aas = input[5]; - int16& Azs = input[6]; - int16& Vof = output[0]; - int16& Vva = output[1]; - int16& Cx = output[2]; - int16& Cy = output[3]; - - int16 CSec, C, E; - int16 LfeNx, LfeNy, LfeNz; - int16 LesNx, LesNy, LesNz; - - // Copy Zenith angle for clipping - int16 AZS = Azs; - - // Store Les and his coefficient and exponent when normalized - shared.Les = Les; - shared.E_Les=0; - normalize(Les, shared.C_Les, shared.E_Les); - - // Store Sine and Cosine of Azimuth and Zenith angle - shared.SinAas = sin(Aas); - shared.CosAas = cos(Aas); - shared.SinAzs = sin(Azs); - shared.CosAzs = cos(Azs); - - // normal vector to the screen (norm 1, points toward the center of projection) - shared.Nx = shared.SinAzs * -shared.SinAas >> 15; - shared.Ny = shared.SinAzs * shared.CosAas >> 15; - shared.Nz = shared.CosAzs * 0x7fff >> 15; - - // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen) - shared.Hx = shared.CosAas*0x7fff>>15; - shared.Hy = shared.SinAas*0x7fff>>15; - - // vertical vector of the screen (norm 1, points toward the top of the screen) - shared.Vx = shared.CosAzs*-shared.SinAas>>15; - shared.Vy = shared.CosAzs*shared.CosAas>>15; - shared.Vz = -shared.SinAzs*0x7fff>>15; - - LfeNx = Lfe*shared.Nx>>15; - LfeNy = Lfe*shared.Ny>>15; - LfeNz = Lfe*shared.Nz>>15; - - // Center of Projection - shared.CentreX = Fx+LfeNx; - shared.CentreY = Fy+LfeNy; - shared.CentreZ = Fz+LfeNz; - - LesNx = Les*shared.Nx>>15; - LesNy = Les*shared.Ny>>15; - LesNz = Les*shared.Nz>>15; - - // center of the screen (global coordinates) - shared.Gx=shared.CentreX-LesNx; - shared.Gy=shared.CentreY-LesNy; - shared.Gz=shared.CentreZ-LesNz; - - - E = 0; - normalize(shared.CentreZ, C, E); - - shared.CentreZ_C = C; - shared.CentreZ_E = E; - - // Determine clip boundary and clip Zenith angle if necessary - // (Why to clip? Maybe to avoid the screen can only show sky with no ground? Only a guess...) - int16 MaxAZS = MaxAZS_Exp[-E]; - - if (AZS < 0) { - MaxAZS = -MaxAZS; - if (AZS < MaxAZS + 1) AZS = MaxAZS + 1; - } else { - if (AZS > MaxAZS) AZS = MaxAZS; - } - - // Store Sine and Cosine of clipped Zenith angle - shared.SinAZS = sin(AZS); - shared.CosAZS = cos(AZS); - - // calculate the separation of (cx, cy) from the projection of - // the 'centre of projection' over the ground... (CentreZ*tg(AZS)) - inverse(shared.CosAZS, 0, shared.SecAZS_C1, shared.SecAZS_E1); - normalize(C * shared.SecAZS_C1 >> 15, C, E); - E += shared.SecAZS_E1; - C = denormalizeAndClip(C, E) * shared.SinAZS >> 15; - - // ... and then take into account the position of the centre of - // projection and the azimuth angle - shared.CentreX += C * shared.SinAas >> 15; - shared.CentreY -= C * shared.CosAas >> 15; - - Cx = shared.CentreX; - Cy = shared.CentreY; - - // Raster number of imaginary center and horizontal line - Vof = 0; - - if ((Azs != AZS) || (Azs == MaxAZS)) - { - // correct vof and vva when Azs is outside the 'non-clipping interval' - // we have only some few Taylor coefficients, so we cannot guess which ones - // are the approximated functions and, what is worse, we don't know why - // the own clipping stuff (and, particularly, this correction) is done - if (Azs == -32768) Azs = -32767; - - C = Azs - MaxAZS; - if (C >= 0) C--; - int16 Aux = ~(C << 2); - - // Vof += x+(1/3)*x^3, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000 - C = Aux * DataRom[0x0328] >> 15; - C = (C * Aux >> 15) + DataRom[0x0327]; - Vof -= (C * Aux >> 15) * Les >> 15; - - // CosAZS *= 1+(1/2)*x^2+(5/24)*x^24, where x ranges from 0 to PI/4 when Azs-MaxAZS goes from 0 to 0x2000 - C = Aux * Aux >> 15; - Aux = (C * DataRom[0x0324] >> 15) + DataRom[0x0325]; - shared.CosAZS += (C * Aux >> 15) * shared.CosAZS >> 15; - } - - // vertical offset of the screen with regard to the horizontal plane - // containing the centre of projection - shared.VOffset = Les * shared.CosAZS >> 15; - - // The horizon line (the line in the screen that is crossed by the horizon plane - // -the horizontal plane containing the 'centre of projection'-), - // will be at distance Les*cotg(AZS) from the centre of the screen. This is difficult - // to explain but easily seen in a graph. To better see it, consider it in this way: - // Les*tg(AZS-90), draw some lines and apply basic trigonometry. ;) - inverse(shared.SinAZS, 0, CSec, E); - normalize(shared.VOffset, C, E); - normalize(C * CSec >> 15, C, E); - - if (C == -32768) { C >>= 1; E++; } - - Vva = denormalizeAndClip(-C, E); - - // Store Secant of clipped Zenith angle - inverse(shared.CosAZS, 0, shared.SecAZS_C2, shared.SecAZS_E2); -} - -////////////////////////////////////////////////////////////////// - -// Calculates the matrix which transform an object situated on a raster line (Vs) into -// his projection over the ground. The modified SecAZS is used here, so -// i don't understand the fine details, but, basically, it's done -// this way: The vertical offset between the point of projection and the -// raster line is calculated (Vs*SinAzs>>15)+VOffset, then the height of -// the center of projection is measured in that units (*CentreZ_C). If, now -// you consider the "reference case" (center of projection at an unit of height), -// the projection of a thin strip containing the raster line will have the same -// width (as the raster line would be on the ground in this case, but will suffer a -// change of scale in height (as the ground and the vertical axis would form an angle of 180-Azs degrees). -// This scale factor, when the angle 'center of screen-center of projection-raster line' is small, -// can be aproximated by the one of the center of the screen, 1/cos(Azs).(**) (Here is when it's used -// SecAZS). By last, you have to consider the effect of the azimuth angle Aas, and you are done. -// -// Using matrix notation: -// |A B| Centre_ZS | cos(Aas) -sin(Aas)| |1 0| -// ProjectionMatrix = | | = ----------- * | | * | | -// |C D| Vs*sin(Azs) |sin(Aas) cos(Aas)| |0 sec(Azs)| -// -// (**) -// If Les=1, the vertical offset between the center -// of projection and the center of the screen is Cos(Azs); then, if the vertical -// offset is 1, the ratio of the projection over the ground respect to the -// line on the screen is 1/cos(Azs). - -void Dsp1::raster(int16 *input, int16 *output) -{ - int16& Vs = input[0]; - int16& An = output[0]; - int16& Bn = output[1]; - int16& Cn = output[2]; - int16& Dn = output[3]; - - int16 C, E, C1, E1; - - inverse((Vs * shared.SinAzs >> 15) + shared.VOffset, 7, C, E); - - E += shared.CentreZ_E; - C1 = C * shared.CentreZ_C >> 15; - - E1 = E + shared.SecAZS_E2; - - normalize(C1, C, E); - C = denormalizeAndClip(C, E); - - An = C * shared.CosAas >> 15; - Cn = C * shared.SinAas >> 15; - - normalize(C1 * shared.SecAZS_C2 >> 15, C, E1); - C = denormalizeAndClip(C, E1); - - Bn = C * -shared.SinAas >> 15; - Dn = C * shared.CosAas >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Calculate the projection over the ground of a selected point of screen -// It simply apply the projection matrix described in the "Raster" command -// to the vector (H,V) transposed, and add the result to the position of -// the centre of projection. -// The only special point to take into account is the directions on the screen: -// H is positive rightward, but V is positive downward; this is why -// the signs take that configuration - -void Dsp1::target(int16 *input, int16 *output) -{ - int16& H = input[0]; - int16& V = input[1]; - int16& X = output[0]; - int16& Y = output[1]; - - int16 C, E, C1, E1; - - inverse((V * shared.SinAzs >> 15) + shared.VOffset, 8, C, E); - - E += shared.CentreZ_E; - C1 = C * shared.CentreZ_C >> 15; - - E1 = E + shared.SecAZS_E1; - - H <<= 8; - normalize(C1, C, E); - C = denormalizeAndClip(C, E) * H >> 15; - - X = shared.CentreX + (C * shared.CosAas >> 15); - Y = shared.CentreY - (C * shared.SinAas >> 15); - - V <<= 8; - normalize(C1 * shared.SecAZS_C1 >> 15, C, E1); - C = denormalizeAndClip(C, E1) * V >> 15; - - X += C * -shared.SinAas >> 15; - Y += C * shared.CosAas >> 15; -} - -////////////////////////////////////////////////////////////////// - -// Calculation of the projection over the screen (H,V) of an object (X,Y,Z) and his -// 'enlargement ratio' (M). The positive directions on the screen are as described -// in the targe command. M is scaled down by 2^-7, that is, M==0x0100 means ratio 1:1 - - void Dsp1::project(int16 *input, int16 *output) -{ - int16& X = input[0]; - int16& Y = input[1]; - int16& Z = input[2]; - int16& H = output[0]; - int16& V = output[1]; - int16& M = output[2]; - - int32 aux, aux4; - int16 E, E2, E3, E4, E5, refE, E6, E7; - int16 C2, C4, C6, C8, C9, C10, C11, C12, C16, C17, C18, C19, C20, C21, C22, C23, C24, C25, C26; - int16 Px, Py, Pz; - - E4=E3=E2=E=E5=0; - - normalizeDouble(int32(X)-shared.Gx, Px, E4); - normalizeDouble(int32(Y)-shared.Gy, Py, E); - normalizeDouble(int32(Z)-shared.Gz, Pz, E3); - Px>>=1; E4--; // to avoid overflows when calculating the scalar products - Py>>=1; E--; - Pz>>=1; E3--; - - refE = (E>15); - C8=- (Py*shared.Ny>>15); - C9=- (Pz*shared.Nz>>15); - C12=C11+C8+C9; // this cannot overflow! - - aux4=C12; // de-normalization with 32-bits arithmetic - refE = 16-refE; // refE can be up to 3 - if (refE>=0) - aux4 <<=(refE); - else - aux4 >>=-(refE); - if (aux4==-1) aux4 = 0; // why? - aux4>>=1; - - aux = static_cast(shared.Les) + aux4; // Les - the scalar product of P with the normal vector of the screen - normalizeDouble(aux, C10, E2); - E2 = 15-E2; - - inverse(C10, 0, C4, E4); - C2=C4*shared.C_Les>>15; // scale factor - - - // H - E7=0; - C16= (Px*shared.Hx>>15); - C20= (Py*shared.Hy>>15); - C17=C16+C20; // scalar product of P with the normalized horizontal vector of the screen... - - C18=C17*C2>>15; // ... multiplied by the scale factor - normalize(C18, C19, E7); - H=denormalizeAndClip(C19, shared.E_Les-E2+refE+E7); - - // V - E6=0; - C21 = Px*shared.Vx>>15; - C22 = Py*shared.Vy>>15; - C23 = Pz*shared.Vz>>15; - C24=C21+C22+C23; // scalar product of P with the normalized vertical vector of the screen... - - C26=C24*C2>>15; // ... multiplied by the scale factor - normalize(C26, C25, E6); - V=denormalizeAndClip(C25, shared.E_Les-E2+refE+E6); - - // M - normalize(C2, C6, E4); - M=denormalizeAndClip(C6, E4+shared.E_Les-E2-7); // M is the scale factor divided by 2^7 -} - -////////////////////////////////////////////////////////////////// - -// Calculate the sine of the input parameter -// this is done by linear interpolation between -// the points of a look-up table - -int16 Dsp1::sin(int16 Angle) -{ - if (Angle < 0) { - if (Angle == -32768) return 0; - return -sin(-Angle); - } - int32 S = SinTable[Angle >> 8] + (MulTable[Angle & 0xff] * SinTable[0x40 + (Angle >> 8)] >> 15); - if (S > 32767) S = 32767; - return (int16) S; -} - -////////////////////////////////////////////////////////////////// - -// Calculate the cosine of the input parameter. -// It's used the same method than in sin(int16) - -int16 Dsp1::cos(int16 Angle) -{ - if (Angle < 0) { - if (Angle == -32768) return -32768; - Angle = -Angle; - } - int32 S = SinTable[0x40 + (Angle >> 8)] - (MulTable[Angle & 0xff] * SinTable[Angle >> 8] >> 15); - if (S < -32768) S = -32767; - return (int16) S; -} - -////////////////////////////////////////////////////////////////// - -// Determines the inverse of a floating point decimal number -// iCoefficient*2^iExponent = 1/(Coefficient*2^Exponent), with the output -// normalized (iCoefficient represents a number whose absolute value is between 1/2 and 1) -// To invert 'Coefficient' a first initial guess is taken from a look-up table -// and, then, two iterations of the Newton method (applied to the function -// f(x)=1/(2*x)-Coefficient) are done. This results in a close approximation (iCoefficient) to a number 'y' -// that verify Coefficient*y=1/2. This is why you have to correct the exponent by one -// unit at the end. - -void Dsp1::inverse(int16 Coefficient, int16 Exponent, int16 &iCoefficient, int16 &iExponent) -{ - // Step One: Division by Zero - if (Coefficient == 0x0000) - { - iCoefficient = 0x7fff; - iExponent = 0x002f; - } - else - { - int16 Sign = 1; - - // Step Two: Remove Sign - if (Coefficient < 0) - { - if (Coefficient < -32767) Coefficient = -32767; - Coefficient = -Coefficient; - Sign = -1; - } - - // Step Three: Normalize - while (Coefficient < 0x4000) - { - Coefficient <<= 1; - Exponent--; - } - - // Step Four: Special Case - if (Coefficient == 0x4000) - if (Sign == 1) iCoefficient = 0x7fff; - else { - iCoefficient = -0x4000; - Exponent--; - } - else { - // Step Five: Initial Guess - int16 i = DataRom[((Coefficient - 0x4000) >> 7) + 0x0065]; - - // Step Six: Iterate Newton's Method - i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; - i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; - - iCoefficient = i * Sign; - } - - iExponent = 1 - Exponent; - } -} - -////////////////////////////////////////////////////////////////// - -int16 Dsp1::denormalizeAndClip(int16 C, int16 E) -{ - if (E > 0) { - if (C > 0) return 32767; else if (C < 0) return -32767; - } else { - if (E < 0) return C * DataRom[0x0031 + E] >> 15; - } - return C; -} - -////////////////////////////////////////////////////////////////// - -// Normalize the input number (m), understood as ranging from -1 to 1, -// to the form: Coefficient*2^Exponent, -// where the absolute value of Coefficient is >= 1/2 -// (Coefficient>=0x4000 or Coefficient <= (int16)0xc001) - -void Dsp1::normalize(int16 m, int16 &Coefficient, int16 &Exponent) -{ - int16 i = 0x4000; - int16 e = 0; - - if (m < 0) - while ((m & i) && i) - { - i >>= 1; - e++; - } - else - while (!(m & i) && i) - { - i >>= 1; - e++; - } - - if (e > 0) - Coefficient = m * DataRom[0x21 + e] << 1; - else - Coefficient = m; - - Exponent -= e; -} - -////////////////////////////////////////////////////////////////// - -// Same than 'normalize' but with an int32 input - -void Dsp1::normalizeDouble(int32 Product, int16 &Coefficient, int16 &Exponent) -{ - int16 n = Product & 0x7fff; - int16 m = Product >> 15; - int16 i = 0x4000; - int16 e = 0; - - if (m < 0) - while ((m & i) && i) - { - i >>= 1; - e++; - } - else - while (!(m & i) && i) - { - i >>= 1; - e++; - } - - if (e > 0) - { - Coefficient = m * DataRom[0x0021 + e] << 1; - - if (e < 15) - Coefficient += n * DataRom[0x0040 - e] >> 15; - else - { - i = 0x4000; - - if (m < 0) - while ((n & i) && i) - { - i >>= 1; - e++; - } - else - while (!(n & i) && i) - { - i >>= 1; - e++; - } - - if (e > 15) - Coefficient = n * DataRom[0x0012 + e] << 1; - else - Coefficient += n; - } - } - else - Coefficient = m; - - Exponent = e; -} - -////////////////////////////////////////////////////////////////// - -// Shift to the right - -int16 Dsp1::shiftR(int16 C, int16 E) -{ - return (C * DataRom[0x0031 + E] >> 15); -} - -////////////////////////////////////////////////////////////////// - -// this is, indeed, only part of the Data ROM -const int16 Dsp1::SinTable[256] = { - 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, - 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, - 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, - 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, - 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, - 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, - 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, - -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2, - -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, - -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a, - -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, - -0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6, - -0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504, - -0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3, - -0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6, - -0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d, - -0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c, - -0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24, - -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4, - -0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4, - -0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de, - -0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b, - -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324}; - - ////////////////////////////////////////////////////////////////// - -// Optimised for Performance - const int16 Dsp1::MulTable[256] = { - 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, - 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0028, 0x002b, 0x002f, - 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, 0x0045, 0x0048, - 0x004b, 0x004e, 0x0051, 0x0054, 0x0057, 0x005b, 0x005e, 0x0061, - 0x0064, 0x0067, 0x006a, 0x006d, 0x0071, 0x0074, 0x0077, 0x007a, - 0x007d, 0x0080, 0x0083, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, - 0x0096, 0x0099, 0x009d, 0x00a0, 0x00a3, 0x00a6, 0x00a9, 0x00ac, - 0x00af, 0x00b3, 0x00b6, 0x00b9, 0x00bc, 0x00bf, 0x00c2, 0x00c5, - 0x00c9, 0x00cc, 0x00cf, 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00df, - 0x00e2, 0x00e5, 0x00e8, 0x00eb, 0x00ee, 0x00f1, 0x00f5, 0x00f8, - 0x00fb, 0x00fe, 0x0101, 0x0104, 0x0107, 0x010b, 0x010e, 0x0111, - 0x0114, 0x0117, 0x011a, 0x011d, 0x0121, 0x0124, 0x0127, 0x012a, - 0x012d, 0x0130, 0x0133, 0x0137, 0x013a, 0x013d, 0x0140, 0x0143, - 0x0146, 0x0149, 0x014d, 0x0150, 0x0153, 0x0156, 0x0159, 0x015c, - 0x015f, 0x0163, 0x0166, 0x0169, 0x016c, 0x016f, 0x0172, 0x0175, - 0x0178, 0x017c, 0x017f, 0x0182, 0x0185, 0x0188, 0x018b, 0x018e, - 0x0192, 0x0195, 0x0198, 0x019b, 0x019e, 0x01a1, 0x01a4, 0x01a8, - 0x01ab, 0x01ae, 0x01b1, 0x01b4, 0x01b7, 0x01ba, 0x01be, 0x01c1, - 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01d0, 0x01d4, 0x01d7, 0x01da, - 0x01dd, 0x01e0, 0x01e3, 0x01e6, 0x01ea, 0x01ed, 0x01f0, 0x01f3, - 0x01f6, 0x01f9, 0x01fc, 0x0200, 0x0203, 0x0206, 0x0209, 0x020c, - 0x020f, 0x0212, 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225, - 0x0228, 0x022c, 0x022f, 0x0232, 0x0235, 0x0238, 0x023b, 0x023e, - 0x0242, 0x0245, 0x0248, 0x024b, 0x024e, 0x0251, 0x0254, 0x0258, - 0x025b, 0x025e, 0x0261, 0x0264, 0x0267, 0x026a, 0x026e, 0x0271, - 0x0274, 0x0277, 0x027a, 0x027d, 0x0280, 0x0284, 0x0287, 0x028a, - 0x028d, 0x0290, 0x0293, 0x0296, 0x029a, 0x029d, 0x02a0, 0x02a3, - 0x02a6, 0x02a9, 0x02ac, 0x02b0, 0x02b3, 0x02b6, 0x02b9, 0x02bc, - 0x02bf, 0x02c2, 0x02c6, 0x02c9, 0x02cc, 0x02cf, 0x02d2, 0x02d5, - 0x02d8, 0x02db, 0x02df, 0x02e2, 0x02e5, 0x02e8, 0x02eb, 0x02ee, - 0x02f1, 0x02f5, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0304, 0x0307, - 0x030b, 0x030e, 0x0311, 0x0314, 0x0317, 0x031a, 0x031d, 0x0321}; - -////////////////////////////////////////////////////////////////// - -// Data ROM, as logged from a DSP-1B with the 0x1f command; -// it contains the tables and constants used by the commands. -// The tables used are: two shift tables (0x022-0x031 and 0x031-0x040 -this last one -// with an error in 0x03c which has survived to all the DSP-1 revisions-); a inverse -// table (used as initial guess) at 0x065-0x0e4; a square root table (used also -// as initial guess) at 0x0e5-0x115; two sin and cos tables (used as nodes to construct -// a interpolation curve) at, respectively, 0x116-0x197 and 0x196-0x215. -// As a curiosity, in the positions 0x21c-0x31c it's contained a -// 257-points arccos table that, apparently, have been not used anywhere -// (maybe for the MaxAZS_Exp table?). - const uint16 Dsp1::DataRom[1024] = { - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, - 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, - 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, - 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, - 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, - 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, - 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, - 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, - 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, - 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, - 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, - 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, - 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, - 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, - 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, - 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, - 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, - 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, - 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, - 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, - 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, - 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, - 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, - 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, - 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, - 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, - 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, - 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, - 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, - 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, - 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, - 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, - 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, - 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, - 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, - 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, - 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, - 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, - 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, - 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, - 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, - 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, - 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, - 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, - 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, - 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, - 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, - 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, - 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, - 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, - 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, - 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, - 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, - 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, - 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, - 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, - 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, - 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, - 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, - 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, - 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, - 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, - 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, - 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, - 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, - 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, - 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, - 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, - 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, - 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, - 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, - 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, - 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, - 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, - 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, - 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, - 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, - 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, - 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, - 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, - 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, - 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, - 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, - 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, - 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, - 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; - -////////////////////////////////////////////////////////////////// - -#endif diff --git a/bsnes/chip/dsp1/dsp1emu.hpp b/bsnes/chip/dsp1/dsp1emu.hpp deleted file mode 100755 index 9ae313ac..00000000 --- a/bsnes/chip/dsp1/dsp1emu.hpp +++ /dev/null @@ -1,129 +0,0 @@ -// DSP-1's emulation code -// -// Based on research by Overload, The Dumper, Neviksti and Andreas Naive -// Date: June 2006 - -#ifndef __DSP1EMUL_H -#define __DSP1EMUL_H - -#define DSP1_VERSION 0x0102 - -class Dsp1 -{ - public: - // The DSP-1 status register has 16 bits, but only - // the upper 8 bits can be accessed from an external device, so all these - // positions are referred to the upper byte (bits D8 to D15) - enum SrFlags {DRC=0x04, DRS=0x10, RQM=0x80}; - - // According to Overload's docs, these are the meanings of the flags: - // DRC: The Data Register Control (DRC) bit specifies the data transfer length to and from the host CPU. - // 0: Data transfer to and from the DSP-1 is 16 bits. - // 1: Data transfer to and from the DSP-1 is 8 bits. - // DRS: The Data Register Status (DRS) bit indicates the data transfer status in the case of transfering 16-bit data. - // 0: Data transfer has terminated. - // 1: Data transfer in progress. - // RQM: The Request for Master (RQM) indicates that the DSP1 is requesting host CPU for data read/write. - // 0: Internal Data Register Transfer. - // 1: External Data Register Transfer. - - Dsp1(); - uint8 getSr(); // return the status register's high byte - uint8 getDr(); - void setDr(uint8 iDr); - void reset(); - - void serialize(serializer&); - - private: - enum FsmMajorState {WAIT_COMMAND, READ_DATA, WRITE_DATA}; - enum MaxDataAccesses {MAX_READS=7, MAX_WRITES=1024}; - - struct Command { - void (Dsp1::*callback)(int16 *, int16 *); - unsigned int reads; - unsigned int writes; - }; - - static const Command mCommandTable[]; - static const int16 MaxAZS_Exp[16]; - static const int16 SinTable[]; - static const int16 MulTable[]; - static const uint16 DataRom[]; - - struct SharedData { // some RAM variables shared between commands - int16 MatrixA[3][3]; // attitude matrix A - int16 MatrixB[3][3]; - int16 MatrixC[3][3]; - int16 CentreX, CentreY, CentreZ; // center of projection - int16 CentreZ_C, CentreZ_E; - int16 VOffset; // vertical offset of the screen with regard to the centre of projection - int16 Les, C_Les, E_Les; - int16 SinAas, CosAas; - int16 SinAzs, CosAzs; - int16 SinAZS, CosAZS; - int16 SecAZS_C1, SecAZS_E1; - int16 SecAZS_C2, SecAZS_E2; - int16 Nx, Ny, Nz; // normal vector to the screen (norm 1, points toward the center of projection) - int16 Gx, Gy, Gz; // center of the screen (global coordinates) - int16 Hx, Hy; // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen) - int16 Vx, Vy, Vz; // vertical vector of the screen (norm 1, points toward the top of the screen) - - } shared; - - uint8 mSr; // status register - int mSrLowByteAccess; - uint16 mDr; // "internal" representation of the data register - unsigned mFsmMajorState; // current major state of the FSM - uint8 mCommand; // current command processed by the FSM - uint8 mDataCounter; // #uint16 read/writes counter used by the FSM - int16 mReadBuffer[MAX_READS]; - int16 mWriteBuffer[MAX_WRITES]; - bool mFreeze; // need explanation? ;) - - void fsmStep(bool read, uint8 &data); // FSM logic - - // commands - void memoryTest(int16 *input, int16 *output); - void memoryDump(int16 *input, int16 *output); - void memorySize(int16 *input, int16 *output); - void multiply(int16* input, int16* output); - void multiply2(int16* input, int16* output); - void inverse(int16 *input, int16 *output); - void triangle(int16 *input, int16 *output); - void radius(int16 *input, int16 *output); - void range(int16 *input, int16 *output); - void range2(int16 *input, int16 *output); - void distance(int16 *input, int16 *output); - void rotate(int16 *input, int16 *output); - void polar(int16 *input, int16 *output); - void attitudeA(int16 *input, int16 *output); - void attitudeB(int16 *input, int16 *output); - void attitudeC(int16 *input, int16 *output); - void objectiveA(int16 *input, int16 *output); - void objectiveB(int16 *input, int16 *output); - void objectiveC(int16 *input, int16 *output); - void subjectiveA(int16 *input, int16 *output); - void subjectiveB(int16 *input, int16 *output); - void subjectiveC(int16 *input, int16 *output); - void scalarA(int16 *input, int16 *output); - void scalarB(int16 *input, int16 *output); - void scalarC(int16 *input, int16 *output); - void gyrate(int16 *input, int16 *output); - void parameter(int16 *input, int16 *output); - void raster(int16 *input, int16 *output); - void target(int16 *input, int16 *output); - void project(int16 *input, int16 *output); - - // auxiliar functions - int16 sin(int16 Angle); - int16 cos(int16 Angle); - void inverse(int16 Coefficient, int16 Exponent, int16 &iCoefficient, int16 &iExponent); - int16 denormalizeAndClip(int16 C, int16 E); - void normalize(int16 m, int16 &Coefficient, int16 &Exponent); - void normalizeDouble(int32 Product, int16 &Coefficient, int16 &Exponent); - int16 shiftR(int16 C, int16 E); -}; - -#endif - diff --git a/bsnes/chip/dsp1/serialization.cpp b/bsnes/chip/dsp1/serialization.cpp deleted file mode 100755 index f7edb381..00000000 --- a/bsnes/chip/dsp1/serialization.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#ifdef DSP1_CPP - -void DSP1::serialize(serializer &s) { - dsp1.serialize(s); -} - -void Dsp1::serialize(serializer &s) { - for(unsigned i = 0; i < 3; i++) { - s.array(shared.MatrixA[i]); - s.array(shared.MatrixB[i]); - s.array(shared.MatrixC[i]); - } - - s.integer(shared.CentreX); - s.integer(shared.CentreY); - s.integer(shared.CentreZ); - s.integer(shared.CentreZ_C); - s.integer(shared.CentreZ_E); - s.integer(shared.VOffset); - s.integer(shared.Les); - s.integer(shared.C_Les); - s.integer(shared.E_Les); - s.integer(shared.SinAas); - s.integer(shared.CosAas); - s.integer(shared.SinAzs); - s.integer(shared.CosAzs); - s.integer(shared.SinAZS); - s.integer(shared.CosAZS); - s.integer(shared.SecAZS_C1); - s.integer(shared.SecAZS_E1); - s.integer(shared.SecAZS_C2); - s.integer(shared.SecAZS_E2); - s.integer(shared.Nx); - s.integer(shared.Ny); - s.integer(shared.Nz); - s.integer(shared.Gx); - s.integer(shared.Gy); - s.integer(shared.Gz); - s.integer(shared.Hx); - s.integer(shared.Hy); - s.integer(shared.Vx); - s.integer(shared.Vy); - s.integer(shared.Vz); - - s.integer(mSr); - s.integer(mSrLowByteAccess); - s.integer(mDr); - s.integer(mFsmMajorState); - s.integer(mCommand); - s.integer(mDataCounter); - s.array(mReadBuffer); - s.array(mWriteBuffer); - s.integer(mFreeze); -} - -#endif diff --git a/bsnes/chip/dsp2/dsp2.cpp b/bsnes/chip/dsp2/dsp2.cpp deleted file mode 100755 index bb33ba35..00000000 --- a/bsnes/chip/dsp2/dsp2.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include - -#define DSP2_CPP -namespace SNES { - -DSP2 dsp2; -DSP2DR dsp2dr; -DSP2SR dsp2sr; - -#include "serialization.cpp" -#include "opcodes.cpp" - -void DSP2::init() { -} - -void DSP2::enable() { -} - -void DSP2::power() { - reset(); -} - -void DSP2::reset() { - status.waiting_for_command = true; - status.in_count = 0; - status.in_index = 0; - status.out_count = 0; - status.out_index = 0; - - status.op05transparent = 0; - status.op05haslen = false; - status.op05len = 0; - status.op06haslen = false; - status.op06len = 0; - status.op09word1 = 0; - status.op09word2 = 0; - status.op0dhaslen = false; - status.op0doutlen = 0; - status.op0dinlen = 0; -} - -uint8 DSP2::read(unsigned addr) { - uint8 r = 0xff; - if(status.out_count) { - r = status.output[status.out_index++]; - status.out_index &= 511; - if(status.out_count == status.out_index) { - status.out_count = 0; - } - } - return r; -} - -void DSP2::write(unsigned addr, uint8 data) { - if(status.waiting_for_command) { - status.command = data; - status.in_index = 0; - status.waiting_for_command = false; - - switch(data) { - case 0x01: status.in_count = 32; break; - case 0x03: status.in_count = 1; break; - case 0x05: status.in_count = 1; break; - case 0x06: status.in_count = 1; break; - case 0x07: break; - case 0x08: break; - case 0x09: status.in_count = 4; break; - case 0x0d: status.in_count = 2; break; - case 0x0f: status.in_count = 0; break; - } - } else { - status.parameters[status.in_index++] = data; - status.in_index &= 511; - } - - if(status.in_count == status.in_index) { - status.waiting_for_command = true; - status.out_index = 0; - switch(status.command) { - case 0x01: { - status.out_count = 32; - op01(); - } break; - - case 0x03: { - op03(); - } break; - - case 0x05: { - if(status.op05haslen) { - status.op05haslen = false; - status.out_count = status.op05len; - op05(); - } else { - status.op05len = status.parameters[0]; - status.in_index = 0; - status.in_count = status.op05len * 2; - status.op05haslen = true; - if(data)status.waiting_for_command = false; - } - } break; - - case 0x06: { - if(status.op06haslen) { - status.op06haslen = false; - status.out_count = status.op06len; - op06(); - } else { - status.op06len = status.parameters[0]; - status.in_index = 0; - status.in_count = status.op06len; - status.op06haslen = true; - if(data)status.waiting_for_command = false; - } - } break; - - case 0x07: break; - case 0x08: break; - - case 0x09: { - op09(); - } break; - - case 0x0d: { - if(status.op0dhaslen) { - status.op0dhaslen = false; - status.out_count = status.op0doutlen; - op0d(); - } else { - status.op0dinlen = status.parameters[0]; - status.op0doutlen = status.parameters[1]; - status.in_index = 0; - status.in_count = (status.op0dinlen + 1) >> 1; - status.op0dhaslen = true; - if(data)status.waiting_for_command = false; - } - } break; - - case 0x0f: break; - } - } -} - -DSP2::DSP2() {} -DSP2::~DSP2() {} - -uint8 DSP2DR::read(unsigned addr) { return dsp2.read(addr); } -void DSP2DR::write(unsigned addr, uint8 data) { dsp2.write(addr, data); } - -uint8 DSP2SR::read(unsigned addr) { return 0x00; } -void DSP2SR::write(unsigned addr, uint8 data) {} - -} diff --git a/bsnes/chip/dsp2/dsp2.hpp b/bsnes/chip/dsp2/dsp2.hpp deleted file mode 100755 index bc14a5bf..00000000 --- a/bsnes/chip/dsp2/dsp2.hpp +++ /dev/null @@ -1,57 +0,0 @@ -class DSP2 { -public: - struct { - bool waiting_for_command; - unsigned command; - unsigned in_count, in_index; - unsigned out_count, out_index; - - uint8 parameters[512]; - uint8 output[512]; - - uint8 op05transparent; - bool op05haslen; - int op05len; - bool op06haslen; - int op06len; - uint16 op09word1; - uint16 op09word2; - bool op0dhaslen; - int op0doutlen; - int op0dinlen; - } status; - - void init(); - void enable(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - DSP2(); - ~DSP2(); - -protected: - void op01(); - void op03(); - void op05(); - void op06(); - void op09(); - void op0d(); -}; - -class DSP2DR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class DSP2SR : public Memory { - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP2 dsp2; -extern DSP2DR dsp2dr; -extern DSP2SR dsp2sr; diff --git a/bsnes/chip/dsp2/opcodes.cpp b/bsnes/chip/dsp2/opcodes.cpp deleted file mode 100755 index f015ac32..00000000 --- a/bsnes/chip/dsp2/opcodes.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#ifdef DSP2_CPP - -//convert bitmap to bitplane tile -void DSP2::op01() { -//op01 size is always 32 bytes input and output -//the hardware does strange things if you vary the size - -unsigned char c0, c1, c2, c3; -unsigned char *p1 = status.parameters; -unsigned char *p2a = status.output; -unsigned char *p2b = status.output + 16; //halfway - -//process 8 blocks of 4 bytes each - for(int j = 0; j < 8; j++) { - c0 = *p1++; - c1 = *p1++; - c2 = *p1++; - c3 = *p1++; - - *p2a++ = (c0 & 0x10) << 3 | - (c0 & 0x01) << 6 | - (c1 & 0x10) << 1 | - (c1 & 0x01) << 4 | - (c2 & 0x10) >> 1 | - (c2 & 0x01) << 2 | - (c3 & 0x10) >> 3 | - (c3 & 0x01); - - *p2a++ = (c0 & 0x20) << 2 | - (c0 & 0x02) << 5 | - (c1 & 0x20) | - (c1 & 0x02) << 3 | - (c2 & 0x20) >> 2 | - (c2 & 0x02) << 1 | - (c3 & 0x20) >> 4 | - (c3 & 0x02) >> 1; - - *p2b++ = (c0 & 0x40) << 1 | - (c0 & 0x04) << 4 | - (c1 & 0x40) >> 1 | - (c1 & 0x04) << 2 | - (c2 & 0x40) >> 3 | - (c2 & 0x04) | - (c3 & 0x40) >> 5 | - (c3 & 0x04) >> 2; - - *p2b++ = (c0 & 0x80) | - (c0 & 0x08) << 3 | - (c1 & 0x80) >> 2 | - (c1 & 0x08) << 1 | - (c2 & 0x80) >> 4 | - (c2 & 0x08) >> 1 | - (c3 & 0x80) >> 6 | - (c3 & 0x08) >> 3; - } -} - -//set transparent color -void DSP2::op03() { - status.op05transparent = status.parameters[0]; -} - -//replace bitmap using transparent color -void DSP2::op05() { -uint8 color; -// Overlay bitmap with transparency. -// Input: -// -// Bitmap 1: i[0] <=> i[size-1] -// Bitmap 2: i[size] <=> i[2*size-1] -// -// Output: -// -// Bitmap 3: o[0] <=> o[size-1] -// -// Processing: -// -// Process all 4-bit pixels (nibbles) in the bitmap -// -// if ( BM2_pixel == transparent_color ) -// pixelout = BM1_pixel -// else -// pixelout = BM2_pixel - -// The max size bitmap is limited to 255 because the size parameter is a byte -// I think size=0 is an error. The behavior of the chip on size=0 is to -// return the last value written to DR if you read DR on Op05 with -// size = 0. I don't think it's worth implementing this quirk unless it's -// proven necessary. - -unsigned char c1, c2; -unsigned char *p1 = status.parameters; -unsigned char *p2 = status.parameters + status.op05len; -unsigned char *p3 = status.output; - - color = status.op05transparent & 0x0f; - - for(int n = 0; n < status.op05len; n++) { - c1 = *p1++; - c2 = *p2++; - *p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0 : c2 & 0xf0 ) | - ( ((c2 & 0x0f) == color ) ? c1 & 0x0f : c2 & 0x0f ); - } -} - -//reverse bitmap -void DSP2::op06() { -// Input: -// size -// bitmap - -int i, j; - for(i = 0, j = status.op06len - 1; i < status.op06len; i++, j--) { - status.output[j] = (status.parameters[i] << 4) | (status.parameters[i] >> 4); - } -} - -//multiply -void DSP2::op09() { - status.out_count = 4; - - status.op09word1 = status.parameters[0] | (status.parameters[1] << 8); - status.op09word2 = status.parameters[2] | (status.parameters[3] << 8); - -uint32 r; - r = status.op09word1 * status.op09word2; - status.output[0] = r; - status.output[1] = r >> 8; - status.output[2] = r >> 16; - status.output[3] = r >> 24; -} - -//scale bitmap -void DSP2::op0d() { -// Bit accurate hardware algorithm - uses fixed point math -// This should match the DSP2 Op0D output exactly -// I wouldn't recommend using this unless you're doing hardware debug. -// In some situations it has small visual artifacts that -// are not readily apparent on a TV screen but show up clearly -// on a monitor. Use Overload's scaling instead. -// This is for hardware verification testing. -// -// One note: the HW can do odd byte scaling but since we divide -// by two to get the count of bytes this won't work well for -// odd byte scaling (in any of the current algorithm implementations). -// So far I haven't seen Dungeon Master use it. -// If it does we can adjust the parameters and code to work with it - -uint32 multiplier; // Any size int >= 32-bits -uint32 pixloc; // match size of multiplier -int i, j; -uint8 pixelarray[512]; - if(status.op0dinlen <= status.op0doutlen) { - multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1 - } else { - multiplier = (status.op0dinlen << 17) / ((status.op0doutlen << 1) + 1); - } - - pixloc = 0; - for(i = 0; i < status.op0doutlen * 2; i++) { - j = pixloc >> 16; - - if(j & 1) { - pixelarray[i] = (status.parameters[j >> 1] & 0x0f); - } else { - pixelarray[i] = (status.parameters[j >> 1] & 0xf0) >> 4; - } - - pixloc += multiplier; - } - - for(i = 0; i < status.op0doutlen; i++) { - status.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1]; - } -} - -#endif diff --git a/bsnes/chip/dsp2/serialization.cpp b/bsnes/chip/dsp2/serialization.cpp deleted file mode 100755 index d089b0fe..00000000 --- a/bsnes/chip/dsp2/serialization.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef DSP2_CPP - -void DSP2::serialize(serializer &s) { - s.integer(status.waiting_for_command); - s.integer(status.command); - s.integer(status.in_count); - s.integer(status.in_index); - s.integer(status.out_count); - s.integer(status.out_index); - - s.array(status.parameters); - s.array(status.output); - - s.integer(status.op05transparent); - s.integer(status.op05haslen); - s.integer(status.op05len); - s.integer(status.op06haslen); - s.integer(status.op06len); - s.integer(status.op09word1); - s.integer(status.op09word2); - s.integer(status.op0dhaslen); - s.integer(status.op0doutlen); - s.integer(status.op0dinlen); -} - -#endif diff --git a/bsnes/chip/dsp3/dsp3.cpp b/bsnes/chip/dsp3/dsp3.cpp deleted file mode 100755 index bf60c578..00000000 --- a/bsnes/chip/dsp3/dsp3.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include - -#define DSP3_CPP -namespace SNES { - -DSP3 dsp3; - -namespace DSP3i { - #define bool8 uint8 - #include "dsp3emu.c" - #undef bool8 -}; - -void DSP3::init() { -} - -void DSP3::enable() { -} - -void DSP3::power() { - reset(); -} - -void DSP3::reset() { - DSP3i::DSP3_Reset(); -} - -uint8 DSP3::read(unsigned addr) { - DSP3i::dsp3_address = addr & 0xffff; - DSP3i::DSP3GetByte(); - return DSP3i::dsp3_byte; -} - -void DSP3::write(unsigned addr, uint8 data) { - DSP3i::dsp3_address = addr & 0xffff; - DSP3i::dsp3_byte = data; - DSP3i::DSP3SetByte(); -} - -} diff --git a/bsnes/chip/dsp3/dsp3.hpp b/bsnes/chip/dsp3/dsp3.hpp deleted file mode 100755 index b3353e33..00000000 --- a/bsnes/chip/dsp3/dsp3.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class DSP3 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read (unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP3 dsp3; diff --git a/bsnes/chip/dsp3/dsp3emu.c b/bsnes/chip/dsp3/dsp3emu.c deleted file mode 100755 index 9e656776..00000000 --- a/bsnes/chip/dsp3/dsp3emu.c +++ /dev/null @@ -1,1146 +0,0 @@ -#ifdef DSP3_CPP - -//DSP-3 emulator code -//Copyright (c) 2003-2006 John Weidman, Kris Bleakley, Lancer, z80 gaiden - -uint16 DSP3_DataROM[1024] = { - 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100, - 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001, - 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, - 0x0000, 0x000f, 0x0400, 0x0200, 0x0140, 0x0400, 0x0200, 0x0040, - 0x007d, 0x007e, 0x007e, 0x007b, 0x007c, 0x007d, 0x007b, 0x007c, - 0x0002, 0x0020, 0x0030, 0x0000, 0x000d, 0x0019, 0x0026, 0x0032, - 0x003e, 0x004a, 0x0056, 0x0062, 0x006d, 0x0079, 0x0084, 0x008e, - 0x0098, 0x00a2, 0x00ac, 0x00b5, 0x00be, 0x00c6, 0x00ce, 0x00d5, - 0x00dc, 0x00e2, 0x00e7, 0x00ec, 0x00f1, 0x00f5, 0x00f8, 0x00fb, - 0x00fd, 0x00ff, 0x0100, 0x0100, 0x0100, 0x00ff, 0x00fd, 0x00fb, - 0x00f8, 0x00f5, 0x00f1, 0x00ed, 0x00e7, 0x00e2, 0x00dc, 0x00d5, - 0x00ce, 0x00c6, 0x00be, 0x00b5, 0x00ac, 0x00a2, 0x0099, 0x008e, - 0x0084, 0x0079, 0x006e, 0x0062, 0x0056, 0x004a, 0x003e, 0x0032, - 0x0026, 0x0019, 0x000d, 0x0000, 0xfff3, 0xffe7, 0xffdb, 0xffce, - 0xffc2, 0xffb6, 0xffaa, 0xff9e, 0xff93, 0xff87, 0xff7d, 0xff72, - 0xff68, 0xff5e, 0xff54, 0xff4b, 0xff42, 0xff3a, 0xff32, 0xff2b, - 0xff25, 0xff1e, 0xff19, 0xff14, 0xff0f, 0xff0b, 0xff08, 0xff05, - 0xff03, 0xff01, 0xff00, 0xff00, 0xff00, 0xff01, 0xff03, 0xff05, - 0xff08, 0xff0b, 0xff0f, 0xff13, 0xff18, 0xff1e, 0xff24, 0xff2b, - 0xff32, 0xff3a, 0xff42, 0xff4b, 0xff54, 0xff5d, 0xff67, 0xff72, - 0xff7c, 0xff87, 0xff92, 0xff9e, 0xffa9, 0xffb5, 0xffc2, 0xffce, - 0xffda, 0xffe7, 0xfff3, 0x002b, 0x007f, 0x0020, 0x00ff, 0xff00, - 0xffbe, 0x0000, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0x0045, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc5, 0x0003, 0x0004, 0x0005, 0x0047, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008, - 0x0009, 0x004a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x004e, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0x0053, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, - 0x0059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0060, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, - 0x002b, 0x002c, 0x0068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0071, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, - 0x003e, 0x003f, 0x0040, 0x0041, 0x007b, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0x0044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, - 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0050, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b, - 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x005d, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, - 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0x006b, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0044, 0x0000, 0x0000, - 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, - 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0x0054, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, - 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0065, - 0xffbe, 0x0000, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffc1, 0x0001, 0x0002, 0xfead, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc5, 0x0003, 0x0004, 0x0005, 0xfeaf, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffca, 0x0006, 0x0007, 0x0008, - 0x0009, 0xfeb2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffd0, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0xfeb6, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd7, 0x000f, 0x0010, 0x0011, - 0x0012, 0x0013, 0x0014, 0xfebb, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffdf, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, - 0xfec1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffe8, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0xfec8, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xfff2, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, - 0x002b, 0x002c, 0xfed0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfffd, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0xfed9, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffc7, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, - 0x003e, 0x003f, 0x0040, 0x0041, 0xfee3, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xffd4, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0xfeac, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffe2, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, - 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0xfeb8, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0xfff1, 0x0019, 0x001a, 0x001b, - 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0xfec5, 0x0000, 0x0000, 0x0000, 0x0000, - 0xffcb, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, - 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, - 0xfed3, 0x0000, 0x0000, 0x0000, 0xffdc, 0x0000, 0x0001, 0x0002, - 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, - 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0xfeac, 0x0000, 0x0000, - 0xffee, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, - 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, - 0x001f, 0x0020, 0xfebc, 0x0000, 0xffee, 0x0021, 0x0022, 0x0023, - 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, - 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0xfecd, - 0x0154, 0x0218, 0x0110, 0x00b0, 0x00cc, 0x00b0, 0x0088, 0x00b0, - 0x0044, 0x00b0, 0x0000, 0x00b0, 0x00fe, 0xff07, 0x0002, 0x00ff, - 0x00f8, 0x0007, 0x00fe, 0x00ee, 0x07ff, 0x0200, 0x00ef, 0xf800, - 0x0700, 0x00ee, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0001, - 0x0001, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, - 0xffff, 0x0000, 0x0000, 0x0001, 0x0001, 0x0001, 0x0001, 0x0000, - 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0x0001, 0x0000, 0x0001, - 0x0001, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, - 0xffff, 0x0001, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0xffff, - 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0044, 0x0088, 0x00cc, - 0x0110, 0x0154, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff -}; - -void (*SetDSP3)(); -void DSP3_Command(); - -uint16 DSP3_DR; -uint16 DSP3_SR; -uint16 DSP3_MemoryIndex; - -void DSP3_Reset() -{ - DSP3_DR = 0x0080; - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_Command; -} - -void DSP3_MemorySize() -{ - DSP3_DR = 0x0300; - SetDSP3 = &DSP3_Reset; -} - -void DSP3_TestMemory() -{ - DSP3_DR = 0x0000; - SetDSP3 = &DSP3_Reset; -} - -void DSP3_DumpDataROM() -{ - DSP3_DR = DSP3_DataROM[DSP3_MemoryIndex++]; - if (DSP3_MemoryIndex == 1024) - SetDSP3 = &DSP3_Reset; -} - -void DSP3_MemoryDump() -{ - DSP3_MemoryIndex = 0; - SetDSP3 = &DSP3_DumpDataROM; - DSP3_DumpDataROM(); -} - -int16 DSP3_WinLo; -int16 DSP3_WinHi; - -void DSP3_OP06() -{ - DSP3_WinLo = (uint8)(DSP3_DR); - DSP3_WinHi = (uint8)(DSP3_DR >> 8); - DSP3_Reset(); -} - -void DSP3_OP03() -{ - int16 Lo = (uint8)(DSP3_DR); - int16 Hi = (uint8)(DSP3_DR >> 8); - int16 Ofs = (DSP3_WinLo * Hi << 1) + (Lo << 1); - DSP3_DR = Ofs >> 1; - SetDSP3 = &DSP3_Reset; -} - -int16 DSP3_AddLo; -int16 DSP3_AddHi; - -void DSP3_OP07_B() -{ - int16 Ofs = (DSP3_WinLo * DSP3_AddHi << 1) + (DSP3_AddLo << 1); - DSP3_DR = Ofs >> 1; - SetDSP3 = &DSP3_Reset; -} - -void DSP3_OP07_A() -{ - int16 Lo = (uint8)(DSP3_DR); - int16 Hi = (uint8)(DSP3_DR >> 8); - - if (Lo & 1) Hi += (DSP3_AddLo & 1); - - DSP3_AddLo += Lo; - DSP3_AddHi += Hi; - - if (DSP3_AddLo < 0) - DSP3_AddLo += DSP3_WinLo; - else - if (DSP3_AddLo >= DSP3_WinLo) - DSP3_AddLo -= DSP3_WinLo; - - if (DSP3_AddHi < 0) - DSP3_AddHi += DSP3_WinHi; - else - if (DSP3_AddHi >= DSP3_WinHi) - DSP3_AddHi -= DSP3_WinHi; - - DSP3_DR = DSP3_AddLo | (DSP3_AddHi << 8) | ((DSP3_AddHi >> 8) & 0xff); - SetDSP3 = &DSP3_OP07_B; -} - -void DSP3_OP07() -{ - uint32 dataOfs = ((DSP3_DR << 1) + 0x03b2) & 0x03ff; - - DSP3_AddHi = DSP3_DataROM[dataOfs]; - DSP3_AddLo = DSP3_DataROM[dataOfs + 1]; - - SetDSP3 = &DSP3_OP07_A; - DSP3_SR = 0x0080; -} - -uint16 DSP3_Codewords; -uint16 DSP3_Outwords; -uint16 DSP3_Symbol; -uint16 DSP3_BitCount; -uint16 DSP3_Index; -uint16 DSP3_Codes[512]; -uint16 DSP3_BitsLeft; -uint16 DSP3_ReqBits; -uint16 DSP3_ReqData; -uint16 DSP3_BitCommand; -uint8 DSP3_BaseLength; -uint16 DSP3_BaseCodes; -uint16 DSP3_BaseCode; -uint8 DSP3_CodeLengths[8]; -uint16 DSP3_CodeOffsets[8]; -uint16 DSP3_LZCode; -uint8 DSP3_LZLength; - -uint16 DSP3_X; -uint16 DSP3_Y; - -void DSP3_Coordinate() -{ - DSP3_Index++; - - switch (DSP3_Index) - { - case 3: - { - if (DSP3_DR == 0xffff) - DSP3_Reset(); - break; - } - case 4: - { - DSP3_X = DSP3_DR; - break; - } - case 5: - { - DSP3_Y = DSP3_DR; - DSP3_DR = 1; - break; - } - case 6: - { - DSP3_DR = DSP3_X; - break; - } - case 7: - { - DSP3_DR = DSP3_Y; - DSP3_Index = 0; - break; - } - } -} - -uint8 DSP3_Bitmap[8]; -uint8 DSP3_Bitplane[8]; -uint16 DSP3_BMIndex; -uint16 DSP3_BPIndex; -uint16 DSP3_Count; - -void DSP3_Convert_A() -{ - if (DSP3_BMIndex < 8) - { - DSP3_Bitmap[DSP3_BMIndex++] = (uint8) (DSP3_DR); - DSP3_Bitmap[DSP3_BMIndex++] = (uint8) (DSP3_DR >> 8); - - if (DSP3_BMIndex == 8) - { - short i, j; - for (i=0; i < 8; i++) - for (j=0; j < 8; j++) - { - DSP3_Bitplane[j] <<= 1; - DSP3_Bitplane[j] |= (DSP3_Bitmap[i] >> j) & 1; - } - - DSP3_BPIndex = 0; - DSP3_Count--; - } - } - - if (DSP3_BMIndex == 8) - { - if (DSP3_BPIndex == 8) - { - if (!DSP3_Count) DSP3_Reset(); - DSP3_BMIndex = 0; - } - else - { - DSP3_DR = DSP3_Bitplane[DSP3_BPIndex++]; - DSP3_DR |= DSP3_Bitplane[DSP3_BPIndex++] << 8; - } - } -} - -void DSP3_Convert() -{ - DSP3_Count = DSP3_DR; - DSP3_BMIndex = 0; - SetDSP3 = &DSP3_Convert_A; -} - -bool DSP3_GetBits(uint8 Count) -{ - if (!DSP3_BitsLeft) - { - DSP3_BitsLeft = Count; - DSP3_ReqBits = 0; - } - - do { - if (!DSP3_BitCount) - { - DSP3_SR = 0xC0; - return false; - } - - DSP3_ReqBits <<= 1; - if (DSP3_ReqData & 0x8000) DSP3_ReqBits++; - DSP3_ReqData <<= 1; - - DSP3_BitCount--; - DSP3_BitsLeft--; - - } while (DSP3_BitsLeft); - - return true; -} - -void DSP3_Decode_Data() -{ - if (!DSP3_BitCount) - { - if (DSP3_SR & 0x40) - { - DSP3_ReqData = DSP3_DR; - DSP3_BitCount += 16; - } - else - { - DSP3_SR = 0xC0; - return; - } - } - - if (DSP3_LZCode == 1) - { - if (!DSP3_GetBits(1)) - return; - - if (DSP3_ReqBits) - DSP3_LZLength = 12; - else - DSP3_LZLength = 8; - - DSP3_LZCode++; - } - - if (DSP3_LZCode == 2) - { - if (!DSP3_GetBits(DSP3_LZLength)) - return; - - DSP3_LZCode = 0; - DSP3_Outwords--; - if (!DSP3_Outwords) SetDSP3 = &DSP3_Reset; - - DSP3_SR = 0x80; - DSP3_DR = DSP3_ReqBits; - return; - } - - if (DSP3_BaseCode == 0xffff) - { - if (!DSP3_GetBits(DSP3_BaseLength)) - return; - - DSP3_BaseCode = DSP3_ReqBits; - } - - if (!DSP3_GetBits(DSP3_CodeLengths[DSP3_BaseCode])) - return; - - DSP3_Symbol = DSP3_Codes[DSP3_CodeOffsets[DSP3_BaseCode] + DSP3_ReqBits]; - DSP3_BaseCode = 0xffff; - - if (DSP3_Symbol & 0xff00) - { - DSP3_Symbol += 0x7f02; - DSP3_LZCode++; - } - else - { - DSP3_Outwords--; - if (!DSP3_Outwords) - SetDSP3 = &DSP3_Reset; - } - - DSP3_SR = 0x80; - DSP3_DR = DSP3_Symbol; -} - -void DSP3_Decode_Tree() -{ - if (!DSP3_BitCount) - { - DSP3_ReqData = DSP3_DR; - DSP3_BitCount += 16; - } - - if (!DSP3_BaseCodes) - { - DSP3_GetBits(1); - if (DSP3_ReqBits) - { - DSP3_BaseLength = 3; - DSP3_BaseCodes = 8; - } - else - { - DSP3_BaseLength = 2; - DSP3_BaseCodes = 4; - } - } - - while (DSP3_BaseCodes) - { - if (!DSP3_GetBits(3)) - return; - - DSP3_ReqBits++; - - DSP3_CodeLengths[DSP3_Index] = (uint8) DSP3_ReqBits; - DSP3_CodeOffsets[DSP3_Index] = DSP3_Symbol; - DSP3_Index++; - - DSP3_Symbol += 1 << DSP3_ReqBits; - DSP3_BaseCodes--; - } - - DSP3_BaseCode = 0xffff; - DSP3_LZCode = 0; - - SetDSP3 = &DSP3_Decode_Data; - if (DSP3_BitCount) DSP3_Decode_Data(); -} - -void DSP3_Decode_Symbols() -{ - DSP3_ReqData = DSP3_DR; - DSP3_BitCount += 16; - - do { - - if (DSP3_BitCommand == 0xffff) - { - if (!DSP3_GetBits(2)) return; - DSP3_BitCommand = DSP3_ReqBits; - } - - switch (DSP3_BitCommand) - { - case 0: - { - if (!DSP3_GetBits(9)) return; - DSP3_Symbol = DSP3_ReqBits; - break; - } - case 1: - { - DSP3_Symbol++; - break; - } - case 2: - { - if (!DSP3_GetBits(1)) return; - DSP3_Symbol += 2 + DSP3_ReqBits; - break; - } - case 3: - { - if (!DSP3_GetBits(4)) return; - DSP3_Symbol += 4 + DSP3_ReqBits; - break; - } - } - - DSP3_BitCommand = 0xffff; - - DSP3_Codes[DSP3_Index++] = DSP3_Symbol; - DSP3_Codewords--; - - } while (DSP3_Codewords); - - DSP3_Index = 0; - DSP3_Symbol = 0; - DSP3_BaseCodes = 0; - - SetDSP3 = &DSP3_Decode_Tree; - if (DSP3_BitCount) DSP3_Decode_Tree(); -} - -void DSP3_Decode_A() -{ - DSP3_Outwords = DSP3_DR; - SetDSP3 = &DSP3_Decode_Symbols; - DSP3_BitCount = 0; - DSP3_BitsLeft = 0; - DSP3_Symbol = 0; - DSP3_Index = 0; - DSP3_BitCommand = 0xffff; - DSP3_SR = 0xC0; -} - -void DSP3_Decode() -{ - DSP3_Codewords = DSP3_DR; - SetDSP3 = &DSP3_Decode_A; -} - - -// Opcodes 1E/3E bit-perfect to 'dsp3-intro' log -// src: adapted from SD Gundam X/G-Next - -int16 op3e_x; -int16 op3e_y; - -int16 op1e_terrain[0x2000]; -int16 op1e_cost[0x2000]; -int16 op1e_weight[0x2000]; - -int16 op1e_cell; -int16 op1e_turn; -int16 op1e_search; - -int16 op1e_x; -int16 op1e_y; - -int16 op1e_min_radius; -int16 op1e_max_radius; - -int16 op1e_max_search_radius; -int16 op1e_max_path_radius; - -int16 op1e_lcv_radius; -int16 op1e_lcv_steps; -int16 op1e_lcv_turns; - -void DSP3_OP3E() -{ - op3e_x = (uint8)(DSP3_DR & 0x00ff); - op3e_y = (uint8)((DSP3_DR & 0xff00)>>8); - - DSP3_OP03(); - - op1e_terrain[ DSP3_DR ] = 0x00; - op1e_cost[ DSP3_DR ] = 0xff; - op1e_weight[ DSP3_DR ] = 0; - - op1e_max_search_radius = 0; - op1e_max_path_radius = 0; -} - -void DSP3_OP1E_A(); -void DSP3_OP1E_A1(); -void DSP3_OP1E_A2(); -void DSP3_OP1E_A3(); - -void DSP3_OP1E_B(); -void DSP3_OP1E_B1(); -void DSP3_OP1E_B2(); - -void DSP3_OP1E_C(); -void DSP3_OP1E_C1(); -void DSP3_OP1E_C2(); - -void DSP3_OP1E_D( int16, int16 *, int16 * ); -void DSP3_OP1E_D1( int16 move, int16 *lo, int16 *hi ); - -void DSP3_OP1E() -{ - int lcv; - - op1e_min_radius = (uint8)(DSP3_DR & 0x00ff); - op1e_max_radius = (uint8)((DSP3_DR & 0xff00)>>8); - - if( op1e_min_radius == 0 ) - op1e_min_radius++; - - if( op1e_max_search_radius >= op1e_min_radius ) - op1e_min_radius = op1e_max_search_radius+1; - - if( op1e_max_radius > op1e_max_search_radius ) - op1e_max_search_radius = op1e_max_radius; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_lcv_turns = 6; - op1e_turn = 0; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - - DSP3_OP1E_A(); -} - -void DSP3_OP1E_A() -{ - int lcv; - - if( op1e_lcv_steps == 0 ) { - op1e_lcv_radius++; - - op1e_lcv_steps = op1e_lcv_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_lcv_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_radius > op1e_max_radius ) { - op1e_turn++; - op1e_lcv_turns--; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_turns == 0 ) { - DSP3_DR = 0xffff; - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_OP1E_B; - return; - } - - DSP3_DR = (uint8)(op1e_x) | ((uint8)(op1e_y)<<8); - DSP3_OP03(); - - op1e_cell = DSP3_DR; - - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_OP1E_A1; -} - -void DSP3_OP1E_A1() -{ - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_OP1E_A2; -} - -void DSP3_OP1E_A2() -{ - op1e_terrain[ op1e_cell ] = (uint8)(DSP3_DR & 0x00ff); - - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_OP1E_A3; -} - -void DSP3_OP1E_A3() -{ - op1e_cost[ op1e_cell ] = (uint8)(DSP3_DR & 0x00ff); - - if( op1e_lcv_radius == 1 ) { - if( op1e_terrain[ op1e_cell ] & 1 ) { - op1e_weight[ op1e_cell ] = 0xff; - } else { - op1e_weight[ op1e_cell ] = op1e_cost[ op1e_cell ]; - } - } - else { - op1e_weight[ op1e_cell ] = 0xff; - } - - DSP3_OP1E_D( (int16)(op1e_turn+2), &op1e_x, &op1e_y ); - op1e_lcv_steps--; - - DSP3_SR = 0x0080; - DSP3_OP1E_A(); -} - - -void DSP3_OP1E_B() -{ - op1e_x = op3e_x; - op1e_y = op3e_y; - op1e_lcv_radius = 1; - - op1e_search = 0; - - DSP3_OP1E_B1(); - - SetDSP3 = &DSP3_OP1E_C; -} - - -void DSP3_OP1E_B1() -{ - while( op1e_lcv_radius < op1e_max_radius ) { - op1e_y--; - - op1e_lcv_turns = 6; - op1e_turn = 5; - - while( op1e_lcv_turns ) { - op1e_lcv_steps = op1e_lcv_radius; - - while( op1e_lcv_steps ) { - DSP3_OP1E_D1( op1e_turn, &op1e_x, &op1e_y ); - - if( 0 <= op1e_y && op1e_y < DSP3_WinHi && - 0 <= op1e_x && op1e_x < DSP3_WinLo ) { - DSP3_DR = (uint8)(op1e_x) | ((uint8)(op1e_y)<<8); - DSP3_OP03(); - - op1e_cell = DSP3_DR; - if( op1e_cost[ op1e_cell ] < 0x80 && - op1e_terrain[ op1e_cell ] < 0x40 ) { - DSP3_OP1E_B2(); - } // end cell perimeter - } - - op1e_lcv_steps--; - } // end search line - - op1e_turn--; - if( op1e_turn == 0 ) op1e_turn = 6; - - op1e_lcv_turns--; - } // end circle search - - op1e_lcv_radius++; - } // end radius search -} - - -void DSP3_OP1E_B2() -{ - int16 cell; - int16 path; - int16 x,y; - int16 lcv_turns; - - path = 0xff; - lcv_turns = 6; - - while( lcv_turns ) { - x = op1e_x; - y = op1e_y; - - DSP3_OP1E_D1( lcv_turns, &x, &y ); - - DSP3_DR = (uint8)(x) | ((uint8)(y)<<8); - DSP3_OP03(); - - cell = DSP3_DR; - - if( 0 <= y && y < DSP3_WinHi && - 0 <= x && x < DSP3_WinLo ) { - - if( op1e_terrain[ cell ] < 0x80 || op1e_weight[ cell ] == 0 ) { - if( op1e_weight[ cell ] < path ) { - path = op1e_weight[ cell ]; - } - } - } // end step travel - - lcv_turns--; - } // end while turns - - if( path != 0xff ) { - op1e_weight[ op1e_cell ] = path + op1e_cost[ op1e_cell ]; - } -} - - -void DSP3_OP1E_C() -{ - int lcv; - - op1e_min_radius = (uint8)(DSP3_DR & 0x00ff); - op1e_max_radius = (uint8)((DSP3_DR & 0xff00)>>8); - - if( op1e_min_radius == 0 ) - op1e_min_radius++; - - if( op1e_max_path_radius >= op1e_min_radius ) - op1e_min_radius = op1e_max_path_radius+1; - - if( op1e_max_radius > op1e_max_path_radius ) - op1e_max_path_radius = op1e_max_radius; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_lcv_turns = 6; - op1e_turn = 0; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - - DSP3_OP1E_C1(); -} - - -void DSP3_OP1E_C1() -{ - int lcv; - - if( op1e_lcv_steps == 0 ) { - op1e_lcv_radius++; - - op1e_lcv_steps = op1e_lcv_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_lcv_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_radius > op1e_max_radius ) { - op1e_turn++; - op1e_lcv_turns--; - - op1e_lcv_radius = op1e_min_radius; - op1e_lcv_steps = op1e_min_radius; - - op1e_x = op3e_x; - op1e_y = op3e_y; - - for( lcv = 0; lcv < op1e_min_radius; lcv++ ) - DSP3_OP1E_D( op1e_turn, &op1e_x, &op1e_y ); - } - - if( op1e_lcv_turns == 0 ) { - DSP3_DR = 0xffff; - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_Reset; - return; - } - - DSP3_DR = (uint8)(op1e_x) | ((uint8)(op1e_y)<<8); - DSP3_OP03(); - - op1e_cell = DSP3_DR; - - DSP3_SR = 0x0080; - SetDSP3 = &DSP3_OP1E_C2; -} - - -void DSP3_OP1E_C2() -{ - DSP3_DR = op1e_weight[ op1e_cell ]; - - DSP3_OP1E_D( (int16)(op1e_turn+2), &op1e_x, &op1e_y ); - op1e_lcv_steps--; - - DSP3_SR = 0x0084; - SetDSP3 = &DSP3_OP1E_C1; -} - - -void DSP3_OP1E_D( int16 move, int16 *lo, int16 *hi ) -{ - uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff; - int16 Lo; - int16 Hi; - - DSP3_AddHi = DSP3_DataROM[dataOfs]; - DSP3_AddLo = DSP3_DataROM[dataOfs + 1]; - - Lo = (uint8)(*lo); - Hi = (uint8)(*hi); - - if (Lo & 1) Hi += (DSP3_AddLo & 1); - - DSP3_AddLo += Lo; - DSP3_AddHi += Hi; - - if (DSP3_AddLo < 0) - DSP3_AddLo += DSP3_WinLo; - else - if (DSP3_AddLo >= DSP3_WinLo) - DSP3_AddLo -= DSP3_WinLo; - - if (DSP3_AddHi < 0) - DSP3_AddHi += DSP3_WinHi; - else - if (DSP3_AddHi >= DSP3_WinHi) - DSP3_AddHi -= DSP3_WinHi; - - *lo = DSP3_AddLo; - *hi = DSP3_AddHi; -} - - -void DSP3_OP1E_D1( int16 move, int16 *lo, int16 *hi ) -{ - //uint32 dataOfs = ((move << 1) + 0x03b2) & 0x03ff; - int16 Lo; - int16 Hi; - - const unsigned short HiAdd[] = { - 0x00, 0xFF, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, - 0x00, 0xFF, 0xFF, 0x00, 0x01, 0x00, 0xFF, 0x00 - }; - const unsigned short LoAdd[] = { - 0x00, 0x00, 0x01, 0x01, 0x00, 0xFF, 0xFF, 0x00 - }; - - if( (*lo) & 1 ) - DSP3_AddHi = HiAdd[ move + 8 ]; - else - DSP3_AddHi = HiAdd[ move + 0 ]; - DSP3_AddLo = LoAdd[ move ]; - - Lo = (uint8)(*lo); - Hi = (uint8)(*hi); - - if (Lo & 1) Hi += (DSP3_AddLo & 1); - - DSP3_AddLo += Lo; - DSP3_AddHi += Hi; - - *lo = DSP3_AddLo; - *hi = DSP3_AddHi; -} - - -void DSP3_OP10() -{ - if( DSP3_DR == 0xffff ) { - DSP3_Reset(); - } else { - // absorb 2 bytes - DSP3_DR = DSP3_DR; - } -} - - -void DSP3_OP0C_A() -{ - // absorb 2 bytes - - DSP3_DR = 0; - SetDSP3 = &DSP3_Reset; -} - - -void DSP3_OP0C() -{ - // absorb 2 bytes - - DSP3_DR = 0; - //SetDSP3 = &DSP3_OP0C_A; - SetDSP3 = &DSP3_Reset; -} - - -void DSP3_OP1C_C() -{ - // return 2 bytes - DSP3_DR = 0; - SetDSP3 = &DSP3_Reset; -} - - -void DSP3_OP1C_B() -{ - // absorb 2 bytes - - // return 2 bytes - DSP3_DR = 0; - SetDSP3 = &DSP3_OP1C_C; -} - - -void DSP3_OP1C_A() -{ - // absorb 2 bytes - - SetDSP3 = &DSP3_OP1C_B; -} - - -void DSP3_OP1C() -{ - // absorb 2 bytes - - SetDSP3 = &DSP3_OP1C_A; -} - - -void DSP3_Command() -{ - if (DSP3_DR < 0x40) - { - switch (DSP3_DR) - { - case 0x02: SetDSP3 = &DSP3_Coordinate; break; - case 0x03: SetDSP3 = &DSP3_OP03; break; - case 0x06: SetDSP3 = &DSP3_OP06; break; - case 0x07: SetDSP3 = &DSP3_OP07; return; - case 0x0c: SetDSP3 = &DSP3_OP0C; break; - case 0x0f: SetDSP3 = &DSP3_TestMemory; break; - case 0x10: SetDSP3 = &DSP3_OP10; break; - case 0x18: SetDSP3 = &DSP3_Convert; break; - case 0x1c: SetDSP3 = &DSP3_OP1C; break; - case 0x1e: SetDSP3 = &DSP3_OP1E; break; - case 0x1f: SetDSP3 = &DSP3_MemoryDump; break; - case 0x38: SetDSP3 = &DSP3_Decode; break; - case 0x3e: SetDSP3 = &DSP3_OP3E; break; - default: - return; - } - DSP3_SR = 0x0080; - DSP3_Index = 0; - } -} - -uint8 dsp3_byte; -uint16 dsp3_address; - -void DSP3SetByte() -{ - if (dsp3_address < 0xC000) - { - if (DSP3_SR & 0x04) - { - DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte; - (*SetDSP3)(); - } - else - { - DSP3_SR ^= 0x10; - - if (DSP3_SR & 0x10) - DSP3_DR = (DSP3_DR & 0xff00) + dsp3_byte; - else - { - DSP3_DR = (DSP3_DR & 0x00ff) + (dsp3_byte << 8); - (*SetDSP3)(); - } - } - } -} - -void DSP3GetByte() -{ - if (dsp3_address < 0xC000) - { - if (DSP3_SR & 0x04) - { - dsp3_byte = (uint8) DSP3_DR; - (*SetDSP3)(); - } - else - { - DSP3_SR ^= 0x10; - - if (DSP3_SR & 0x10) - dsp3_byte = (uint8) (DSP3_DR); - else - { - dsp3_byte = (uint8) (DSP3_DR >> 8); - (*SetDSP3)(); - } - } - - } - else - { - dsp3_byte = (uint8) DSP3_SR; - } -} - -void InitDSP3() -{ - DSP3_Reset(); -} - -#endif diff --git a/bsnes/chip/dsp4/dsp4.cpp b/bsnes/chip/dsp4/dsp4.cpp deleted file mode 100755 index c568c728..00000000 --- a/bsnes/chip/dsp4/dsp4.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include - -#define DSP4_CPP -namespace SNES { - -DSP4 dsp4; - -void DSP4::init() { -} - -void DSP4::enable() { -} - -namespace DSP4i { - inline uint16 READ_WORD(uint8 *addr) { - return (addr[0]) + (addr[1] << 8); - } - - inline uint32 READ_DWORD(uint8 *addr) { - return (addr[0]) + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24); - } - - inline void WRITE_WORD(uint8 *addr, uint16 data) { - addr[0] = data; - addr[1] = data >> 8; - } - - #define bool8 uint8 - #include "dsp4emu.c" - #undef bool8 -}; - -void DSP4::power() { - reset(); -} - -void DSP4::reset() { - DSP4i::InitDSP4(); -} - -uint8 DSP4::read(unsigned addr) { - addr &= 0xffff; - if(addr < 0xc000) { - DSP4i::dsp4_address = addr; - DSP4i::DSP4GetByte(); - return DSP4i::dsp4_byte; - } - return 0x80; -} - -void DSP4::write(unsigned addr, uint8 data) { - addr &= 0xffff; - if(addr < 0xc000) { - DSP4i::dsp4_address = addr; - DSP4i::dsp4_byte = data; - DSP4i::DSP4SetByte(); - } -} - -} diff --git a/bsnes/chip/dsp4/dsp4.hpp b/bsnes/chip/dsp4/dsp4.hpp deleted file mode 100755 index 7a261192..00000000 --- a/bsnes/chip/dsp4/dsp4.hpp +++ /dev/null @@ -1,12 +0,0 @@ -class DSP4 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read (unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern DSP4 dsp4; diff --git a/bsnes/chip/dsp4/dsp4emu.c b/bsnes/chip/dsp4/dsp4emu.c deleted file mode 100755 index 73c1ec3d..00000000 --- a/bsnes/chip/dsp4/dsp4emu.c +++ /dev/null @@ -1,2150 +0,0 @@ -#ifdef DSP4_CPP - -//DSP-4 emulator code -//Copyright (c) 2004-2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden - -/* -Due recognition and credit are given on Overload's DSP website. -Thank those contributors for their hard work on this chip. - - -Fixed-point math reminder: - -[sign, integer, fraction] -1.15.00 * 1.15.00 = 2.30.00 -> 1.30.00 (DSP) -> 1.31.00 (LSB is '0') -1.15.00 * 1.00.15 = 2.15.15 -> 1.15.15 (DSP) -> 1.15.16 (LSB is '0') -*/ - -#include "dsp4emu.h" - -struct DSP4_t DSP4; -struct DSP4_vars_t DSP4_vars; - -////////////////////////////////////////////////////////////// - -// input protocol - -static int16 DSP4_READ_WORD() -{ - int16 out; - - out = READ_WORD(DSP4.parameters + DSP4.in_index); - DSP4.in_index += 2; - - return out; -} - -static int32 DSP4_READ_DWORD() -{ - int32 out; - - out = READ_DWORD(DSP4.parameters + DSP4.in_index); - DSP4.in_index += 4; - - return out; -} - - -////////////////////////////////////////////////////////////// - -// output protocol - -#define DSP4_CLEAR_OUT() \ -{ DSP4.out_count = 0; DSP4.out_index = 0; } - -#define DSP4_WRITE_BYTE( d ) \ -{ WRITE_WORD( DSP4.output + DSP4.out_count, ( d ) ); DSP4.out_count++; } - -#define DSP4_WRITE_WORD( d ) \ -{ WRITE_WORD( DSP4.output + DSP4.out_count, ( d ) ); DSP4.out_count += 2; } - -#ifndef MSB_FIRST -#define DSP4_WRITE_16_WORD( d ) \ -{ memcpy(DSP4.output + DSP4.out_count, ( d ), 32); DSP4.out_count += 32; } -#else -#define DSP4_WRITE_16_WORD( d ) \ -{ int16 *p = ( d ), *end = ( d )+16; \ - for (; p != end; p++) \ - { \ - WRITE_WORD( DSP4.output + DSP4.out_count, *p ); \ - } \ - DSP4.out_count += 32; \ -} -#endif - -#ifdef PRINT_OP -#define DSP4_WRITE_DEBUG( x, d ) \ - WRITE_WORD( nop + x, d ); -#endif - -#ifdef DEBUG_DSP -#define DSP4_WRITE_DEBUG( x, d ) \ - WRITE_WORD( nop + x, d ); -#endif - -////////////////////////////////////////////////////////////// - -// used to wait for dsp i/o - -#define DSP4_WAIT( x ) \ - DSP4.in_index = 0; DSP4_vars.DSP4_Logic = x; return; - -////////////////////////////////////////////////////////////// - -// 1.7.8 -> 1.15.16 -#define SEX78( a ) ( ( (int32) ( (int16) (a) ) ) << 8 ) - -// 1.15.0 -> 1.15.16 -#define SEX16( a ) ( ( (int32) ( (int16) (a) ) ) << 16 ) - -#ifdef PRINT_OP -#define U16( a ) ( (uint16) ( a ) ) -#endif - -#ifdef DEBUG_DSP -#define U16( a ) ( (uint16) ( a ) ) -#endif - -////////////////////////////////////////////////////////////// - -// Attention: This lookup table is not verified -static const uint16 div_lut[64] = { 0x0000, 0x8000, 0x4000, 0x2aaa, 0x2000, 0x1999, 0x1555, 0x1249, 0x1000, 0x0e38, - 0x0ccc, 0x0ba2, 0x0aaa, 0x09d8, 0x0924, 0x0888, 0x0800, 0x0787, 0x071c, 0x06bc, - 0x0666, 0x0618, 0x05d1, 0x0590, 0x0555, 0x051e, 0x04ec, 0x04bd, 0x0492, 0x0469, - 0x0444, 0x0421, 0x0400, 0x03e0, 0x03c3, 0x03a8, 0x038e, 0x0375, 0x035e, 0x0348, - 0x0333, 0x031f, 0x030c, 0x02fa, 0x02e8, 0x02d8, 0x02c8, 0x02b9, 0x02aa, 0x029c, - 0x028f, 0x0282, 0x0276, 0x026a, 0x025e, 0x0253, 0x0249, 0x023e, 0x0234, 0x022b, - 0x0222, 0x0219, 0x0210, 0x0208, }; -int16 DSP4_Inverse(int16 value) -{ - // saturate bounds - if (value < 0) - { - value = 0; - } - if (value > 63) - { - value = 63; - } - - return div_lut[value]; -} - -////////////////////////////////////////////////////////////// - -// Prototype -void DSP4_OP0B(bool8 *draw, int16 sp_x, int16 sp_y, int16 sp_attr, bool8 size, bool8 stop); - -////////////////////////////////////////////////////////////// - -// OP00 -void DSP4_Multiply(int16 Multiplicand, int16 Multiplier, int32 *Product) -{ - *Product = (Multiplicand * Multiplier << 1) >> 1; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP01() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.world_dy = DSP4_READ_DWORD(); - DSP4_vars.world_dx = DSP4_READ_DWORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_xenv = DSP4_READ_DWORD(); - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - DSP4_vars.view_turnoff_x = 0; - DSP4_vars.view_turnoff_dx = 0; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // perspective projection of world (x,y,scroll) points - // based on the current projection lines - DSP4_vars.view_x2 = (int16)(( ( ( DSP4_vars.world_x + DSP4_vars.world_xenv ) >> 16 ) * DSP4_vars.distance >> 15 ) + ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 )); - DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - - // 1. World x-location before transformation - // 2. Viewer x-position at the next - // 3. World y-location before perspective projection - // 4. Viewer y-position below the horizon - // 5. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.poly_raster[0][0] - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg1) - // 2. vertical scroll offset ($210E) - // 3. horizontal scroll offset ($210D) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - //////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - // add deltas for projection lines - DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx); - DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy); - - // update projection lines - DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv); - DSP4_vars.world_y += DSP4_vars.world_dy; - - // update road turnoff position - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // check for termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // road turnoff - if( (uint16) DSP4_vars.distance == 0x8001 ) - { - DSP4.in_count = 6; - DSP4_WAIT(2) resume2: - - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_x = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_dx = DSP4_READ_WORD(); - - // factor in new changes - DSP4_vars.view_x1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - DSP4_vars.view_xofs1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - - // update stepping values - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - DSP4.in_count = 2; - DSP4_WAIT(1) - } - - // already have 2 bytes read - DSP4.in_count = 6; - DSP4_WAIT(3) resume3 : - - // inspect inputs - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // no envelope here - DSP4_vars.world_xenv = 0; - } - while (1); - - // terminate op - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP03() -{ - DSP4_vars.OAM_RowMax = 33; - memset(DSP4_vars.OAM_Row, 0, 64); -} - - -////////////////////////////////////////////////////////////// - - -void DSP4_OP05() -{ - DSP4_vars.OAM_index = 0; - DSP4_vars.OAM_bits = 0; - memset(DSP4_vars.OAM_attr, 0, 32); - DSP4_vars.sprite_count = 0; -} - - -////////////////////////////////////////////////////////////// - -void DSP4_OP06() -{ - DSP4_CLEAR_OUT(); - DSP4_WRITE_16_WORD(DSP4_vars.OAM_attr); -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP07() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - } - - //////////////////////////////////////////////////// - // sort inputs - - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = DSP4_vars.view_x1; - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // add shaping - DSP4_vars.view_x2 += DSP4_vars.view_dx; - DSP4_vars.view_y2 += DSP4_vars.view_dy; - - // vertical scroll calculation - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. Viewer x-position at the next - // 2. Viewer y-position below the horizon - // 3. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg2) - // 2. vertical scroll offset ($2110) - // 3. horizontal scroll offset ($210F) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - ///////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // check for opcode termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 10; - DSP4_WAIT(2) resume2 : - - // inspect inputs - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - } - while (1); - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP08() -{ - int16 win_left, win_right; - int16 view_x[2], view_y[2]; - int16 envelope[2][2]; - - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - } - - //////////////////////////////////////////////////// - // process initial inputs for two polygons - - // clip values - DSP4_vars.poly_clipRt[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipRt[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_clipRt[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipRt[1][1] = DSP4_READ_WORD(); - - DSP4_vars.poly_clipLf[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipLf[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_clipLf[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_clipLf[1][1] = DSP4_READ_WORD(); - - // unknown (constant) (ex. 1P/2P = $00A6, $00A6, $00A6, $00A6) - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - - // unknown (constant) (ex. 1P/2P = $00A5, $00A5, $00A7, $00A7) - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - - // polygon centering (left,right) - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][1] = DSP4_READ_WORD(); - - // HDMA pointer locations - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[1][1] = DSP4_READ_WORD(); - - // starting DSP4_vars.raster line below the horizon - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_bottom[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_bottom[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_bottom[1][1] = DSP4_READ_WORD(); - - // top boundary line to clip - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][1] = DSP4_READ_WORD(); - DSP4_vars.poly_top[1][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[1][1] = DSP4_READ_WORD(); - - // unknown - // (ex. 1P = $2FC8, $0034, $FF5C, $0035) - // - // (ex. 2P = $3178, $0034, $FFCC, $0035) - // (ex. 2P = $2FC8, $0034, $FFCC, $0035) - - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - DSP4_READ_WORD(); - - // look at guidelines for both polygon shapes - DSP4_vars.distance = DSP4_READ_WORD(); - view_x[0] = DSP4_READ_WORD(); - view_y[0] = DSP4_READ_WORD(); - view_x[1] = DSP4_READ_WORD(); - view_y[1] = DSP4_READ_WORD(); - - // envelope shaping guidelines (one frame only) - envelope[0][0] = DSP4_READ_WORD(); - envelope[0][1] = DSP4_READ_WORD(); - envelope[1][0] = DSP4_READ_WORD(); - envelope[1][1] = DSP4_READ_WORD(); - - // starting base values to project from - DSP4_vars.poly_start[0] = view_x[0]; - DSP4_vars.poly_start[1] = view_x[1]; - - // starting DSP4_vars.raster lines to begin drawing - DSP4_vars.poly_raster[0][0] = view_y[0]; - DSP4_vars.poly_raster[0][1] = view_y[0]; - DSP4_vars.poly_raster[1][0] = view_y[1]; - DSP4_vars.poly_raster[1][1] = view_y[1]; - - // starting distances - DSP4_vars.poly_plane[0] = DSP4_vars.distance; - DSP4_vars.poly_plane[1] = DSP4_vars.distance; - - // SR = 0x00 - - // re-center coordinates - win_left = DSP4_vars.poly_cx[0][0] - view_x[0] + envelope[0][0]; - win_right = DSP4_vars.poly_cx[0][1] - view_x[0] + envelope[0][1]; - - // saturate offscreen data for polygon #1 - if (win_left < DSP4_vars.poly_clipLf[0][0]) - { - win_left = DSP4_vars.poly_clipLf[0][0]; - } - if (win_left > DSP4_vars.poly_clipRt[0][0]) - { - win_left = DSP4_vars.poly_clipRt[0][0]; - } - if (win_right < DSP4_vars.poly_clipLf[0][1]) - { - win_right = DSP4_vars.poly_clipLf[0][1]; - } - if (win_right > DSP4_vars.poly_clipRt[0][1]) - { - win_right = DSP4_vars.poly_clipRt[0][1]; - } - - // SR = 0x80 - - // initial output for polygon #1 - DSP4_CLEAR_OUT(); - DSP4_WRITE_BYTE(win_left & 0xff); - DSP4_WRITE_BYTE(win_right & 0xff); - - - do - { - int16 polygon; - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // terminate op - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 16; - - DSP4_WAIT(2) resume2 : - - // look at guidelines for both polygon shapes - view_x[0] = DSP4_READ_WORD(); - view_y[0] = DSP4_READ_WORD(); - view_x[1] = DSP4_READ_WORD(); - view_y[1] = DSP4_READ_WORD(); - - // envelope shaping guidelines (one frame only) - envelope[0][0] = DSP4_READ_WORD(); - envelope[0][1] = DSP4_READ_WORD(); - envelope[1][0] = DSP4_READ_WORD(); - envelope[1][1] = DSP4_READ_WORD(); - - //////////////////////////////////////////////////// - // projection begins - - // init - DSP4_CLEAR_OUT(); - - - ////////////////////////////////////////////// - // solid polygon renderer - 2 shapes - - for (polygon = 0; polygon < 2; polygon++) - { - int32 left_inc, right_inc; - int16 x1_final, x2_final; - int16 env[2][2]; - int16 poly; - - // SR = 0x00 - - // # DSP4_vars.raster lines to draw - DSP4_vars.segments = DSP4_vars.poly_raster[polygon][0] - view_y[polygon]; - - // prevent overdraw - if (DSP4_vars.segments > 0) - { - // bump drawing cursor - DSP4_vars.poly_raster[polygon][0] = view_y[polygon]; - DSP4_vars.poly_raster[polygon][1] = view_y[polygon]; - } - else - DSP4_vars.segments = 0; - - // don't draw outside the window - if (view_y[polygon] < DSP4_vars.poly_top[polygon][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (view_y[polygon] >= DSP4_vars.poly_top[polygon][0]) - DSP4_vars.segments = view_y[polygon] - DSP4_vars.poly_top[polygon][0]; - } - - // SR = 0x80 - - // tell user how many DSP4_vars.raster structures to read in - DSP4_WRITE_WORD(DSP4_vars.segments); - - // normal parameters - poly = polygon; - - ///////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 win_left, win_right; - - // road turnoff selection - if( (uint16) envelope[ polygon ][ 0 ] == (uint16) 0xc001 ) - poly = 1; - else if( envelope[ polygon ][ 1 ] == 0x3fff ) - poly = 1; - - /////////////////////////////////////////////// - // left side of polygon - - // perspective correction on additional shaping parameters - env[0][0] = envelope[polygon][0] * DSP4_vars.poly_plane[poly] >> 15; - env[0][1] = envelope[polygon][0] * DSP4_vars.distance >> 15; - - // project new shapes (left side) - x1_final = view_x[poly] + env[0][0]; - x2_final = DSP4_vars.poly_start[poly] + env[0][1]; - - // interpolate between projected points with shaping - left_inc = (x2_final - x1_final) * DSP4_Inverse(DSP4_vars.segments) << 1; - if (DSP4_vars.segments == 1) - left_inc = -left_inc; - - /////////////////////////////////////////////// - // right side of polygon - - // perspective correction on additional shaping parameters - env[1][0] = envelope[polygon][1] * DSP4_vars.poly_plane[poly] >> 15;; - env[1][1] = envelope[polygon][1] * DSP4_vars.distance >> 15; - - // project new shapes (right side) - x1_final = view_x[poly] + env[1][0]; - x2_final = DSP4_vars.poly_start[poly] + env[1][1]; - - - // interpolate between projected points with shaping - right_inc = (x2_final - x1_final) * DSP4_Inverse(DSP4_vars.segments) << 1; - if (DSP4_vars.segments == 1) - right_inc = -right_inc; - - /////////////////////////////////////////////// - // update each point on the line - - win_left = SEX16(DSP4_vars.poly_cx[polygon][0] - DSP4_vars.poly_start[poly] + env[0][0]); - win_right = SEX16(DSP4_vars.poly_cx[polygon][1] - DSP4_vars.poly_start[poly] + env[1][0]); - - // update DSP4_vars.distance drawn into world - DSP4_vars.poly_plane[polygon] = DSP4_vars.distance; - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - int16 x_left, x_right; - - // project new coordinates - win_left += left_inc; - win_right += right_inc; - - // grab integer portion, drop fraction (no rounding) - x_left = (int16)(win_left >> 16); - x_right = (int16)(win_right >> 16); - - // saturate offscreen data - if (x_left < DSP4_vars.poly_clipLf[polygon][0]) - x_left = DSP4_vars.poly_clipLf[polygon][0]; - if (x_left > DSP4_vars.poly_clipRt[polygon][0]) - x_left = DSP4_vars.poly_clipRt[polygon][0]; - if (x_right < DSP4_vars.poly_clipLf[polygon][1]) - x_right = DSP4_vars.poly_clipLf[polygon][1]; - if (x_right > DSP4_vars.poly_clipRt[polygon][1]) - x_right = DSP4_vars.poly_clipRt[polygon][1]; - - // 1. HDMA memory pointer - // 2. Left window position ($2126/$2128) - // 3. Right window position ($2127/$2129) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[polygon][0]); - DSP4_WRITE_BYTE(x_left & 0xff); - DSP4_WRITE_BYTE(x_right & 0xff); - - - // update memory pointers - DSP4_vars.poly_ptr[polygon][0] -= 4; - DSP4_vars.poly_ptr[polygon][1] -= 4; - } // end rasterize line - } - - //////////////////////////////////////////////// - // Post-update - - // new projection spot to continue rasterizing from - DSP4_vars.poly_start[polygon] = view_x[poly]; - } // end polygon rasterizer - } - while (1); - - // unknown output - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(0); - - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP09() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - case 4: - goto resume4; break; - case 5: - goto resume5; break; - case 6: - goto resume6; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // grab screen information - DSP4_vars.viewport_cx = DSP4_READ_WORD(); - DSP4_vars.viewport_cy = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.viewport_left = DSP4_READ_WORD(); - DSP4_vars.viewport_right = DSP4_READ_WORD(); - DSP4_vars.viewport_top = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - - // starting DSP4_vars.raster line below the horizon - DSP4_vars.poly_bottom[0][0] = DSP4_vars.viewport_bottom - DSP4_vars.viewport_cy; - DSP4_vars.poly_raster[0][0] = 0x100; - - do - { - //////////////////////////////////////////////////// - // check for new sprites - - DSP4.in_count = 4; - DSP4_WAIT(1) resume1 : - - //////////////////////////////////////////////// - // DSP4_vars.raster overdraw check - - DSP4_vars.raster = DSP4_READ_WORD(); - - // continue updating the DSP4_vars.raster line where overdraw begins - if (DSP4_vars.raster < DSP4_vars.poly_raster[0][0]) - { - DSP4_vars.sprite_clipy = DSP4_vars.viewport_bottom - (DSP4_vars.poly_bottom[0][0] - DSP4_vars.raster); - DSP4_vars.poly_raster[0][0] = DSP4_vars.raster; - } - - ///////////////////////////////////////////////// - // identify sprite - - // op termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - goto terminate; - - - // no sprite - if (DSP4_vars.distance == 0x0000) - { - continue; - } - - //////////////////////////////////////////////////// - // process projection information - - // vehicle sprite - if ((uint16) DSP4_vars.distance == 0x9000) - { - int16 car_left, car_right, car_back; - int16 impact_left, impact_back; - int16 world_spx, world_spy; - int16 view_spx, view_spy; - uint16 energy; - - // we already have 4 bytes we want - DSP4.in_count = 14; - DSP4_WAIT(2) resume2 : - - // filter inputs - energy = DSP4_READ_WORD(); - impact_back = DSP4_READ_WORD(); - car_back = DSP4_READ_WORD(); - impact_left = DSP4_READ_WORD(); - car_left = DSP4_READ_WORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - car_right = DSP4_READ_WORD(); - - // calculate car's world (x,y) values - world_spx = car_right - car_left; - world_spy = car_back; - - // add in collision vector [needs bit-twiddling] - world_spx -= energy * (impact_left - car_left) >> 16; - world_spy -= energy * (car_back - impact_back) >> 16; - - // perspective correction for world (x,y) - view_spx = world_spx * DSP4_vars.distance >> 15; - view_spy = world_spy * DSP4_vars.distance >> 15; - - // convert to screen values - DSP4_vars.sprite_x = DSP4_vars.viewport_cx + view_spx; - DSP4_vars.sprite_y = DSP4_vars.viewport_bottom - (DSP4_vars.poly_bottom[0][0] - view_spy); - - // make the car's (x)-coordinate available - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(world_spx); - - // grab a few remaining vehicle values - DSP4.in_count = 4; - DSP4_WAIT(3) resume3 : - - // add vertical lift factor - DSP4_vars.sprite_y += DSP4_READ_WORD(); - } - // terrain sprite - else - { - int16 world_spx, world_spy; - int16 view_spx, view_spy; - - // we already have 4 bytes we want - DSP4.in_count = 10; - DSP4_WAIT(4) resume4 : - - // sort loop inputs - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_raster[0][1] = DSP4_READ_WORD(); - world_spx = DSP4_READ_WORD(); - world_spy = DSP4_READ_WORD(); - - // compute base DSP4_vars.raster line from the bottom - DSP4_vars.segments = DSP4_vars.poly_bottom[0][0] - DSP4_vars.raster; - - // perspective correction for world (x,y) - view_spx = world_spx * DSP4_vars.distance >> 15; - view_spy = world_spy * DSP4_vars.distance >> 15; - - // convert to screen values - DSP4_vars.sprite_x = DSP4_vars.viewport_cx + view_spx - DSP4_vars.poly_cx[0][0]; - DSP4_vars.sprite_y = DSP4_vars.viewport_bottom - DSP4_vars.segments + view_spy; - } - - // default sprite size: 16x16 - DSP4_vars.sprite_size = 1; - DSP4_vars.sprite_attr = DSP4_READ_WORD(); - - //////////////////////////////////////////////////// - // convert tile data to SNES OAM format - - do - { - uint16 header; - - int16 sp_x, sp_y, sp_attr, sp_dattr; - int16 sp_dx, sp_dy; - int16 pixels; - - bool8 draw; - - DSP4.in_count = 2; - DSP4_WAIT(5) resume5 : - - draw = TRUE; - - // opcode termination - DSP4_vars.raster = DSP4_READ_WORD(); - if (DSP4_vars.raster == -0x8000) - goto terminate; - - // stop code - if (DSP4_vars.raster == 0x0000 && !DSP4_vars.sprite_size) - break; - - // toggle sprite size - if (DSP4_vars.raster == 0x0000) - { - DSP4_vars.sprite_size = !DSP4_vars.sprite_size; - continue; - } - - // check for valid sprite header - header = DSP4_vars.raster; - header >>= 8; - if (header != 0x20 && - header != 0x2e && //This is for attractor sprite - header != 0x40 && - header != 0x60 && - header != 0xa0 && - header != 0xc0 && - header != 0xe0) - break; - - // read in rest of sprite data - DSP4.in_count = 4; - DSP4_WAIT(6) resume6 : - - draw = TRUE; - - ///////////////////////////////////// - // process tile data - - // sprite deltas - sp_dattr = DSP4_vars.raster; - sp_dy = DSP4_READ_WORD(); - sp_dx = DSP4_READ_WORD(); - - // update coordinates to screen space - sp_x = DSP4_vars.sprite_x + sp_dx; - sp_y = DSP4_vars.sprite_y + sp_dy; - - // update sprite nametable/attribute information - sp_attr = DSP4_vars.sprite_attr + sp_dattr; - - // allow partially visibile tiles - pixels = DSP4_vars.sprite_size ? 15 : 7; - - DSP4_CLEAR_OUT(); - - // transparent tile to clip off parts of a sprite (overdraw) - if (DSP4_vars.sprite_clipy - pixels <= sp_y && - sp_y <= DSP4_vars.sprite_clipy && - sp_x >= DSP4_vars.viewport_left - pixels && - sp_x <= DSP4_vars.viewport_right && - DSP4_vars.sprite_clipy >= DSP4_vars.viewport_top - pixels && - DSP4_vars.sprite_clipy <= DSP4_vars.viewport_bottom) - { - DSP4_OP0B(&draw, sp_x, DSP4_vars.sprite_clipy, 0x00EE, DSP4_vars.sprite_size, 0); - } - - - // normal sprite tile - if (sp_x >= DSP4_vars.viewport_left - pixels && - sp_x <= DSP4_vars.viewport_right && - sp_y >= DSP4_vars.viewport_top - pixels && - sp_y <= DSP4_vars.viewport_bottom && - sp_y <= DSP4_vars.sprite_clipy) - { - DSP4_OP0B(&draw, sp_x, sp_y, sp_attr, DSP4_vars.sprite_size, 0); - } - - - // no following OAM data - DSP4_OP0B(&draw, 0, 0x0100, 0, 0, 1); - } - while (1); - } - while (1); - - terminate : DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -const uint16 OP0A_Values[16] = { 0x0000, 0x0030, 0x0060, 0x0090, 0x00c0, 0x00f0, 0x0120, 0x0150, 0xfe80, - 0xfeb0, 0xfee0, 0xff10, 0xff40, 0xff70, 0xffa0, 0xffd0 }; - -void DSP4_OP0A(int16 n2, int16 *o1, int16 *o2, int16 *o3, int16 *o4) -{ - *o4 = OP0A_Values[(n2 & 0x000f)]; - *o3 = OP0A_Values[(n2 & 0x00f0) >> 4]; - *o2 = OP0A_Values[(n2 & 0x0f00) >> 8]; - *o1 = OP0A_Values[(n2 & 0xf000) >> 12]; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP0B(bool8 *draw, int16 sp_x, int16 sp_y, int16 sp_attr, bool8 size, bool8 stop) -{ - int16 Row1, Row2; - - // SR = 0x00 - - // align to nearest 8-pixel row - Row1 = (sp_y >> 3) & 0x1f; - Row2 = (Row1 + 1) & 0x1f; - - // check boundaries - if (!((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb))) - { - *draw = 0; - } - if (size) - { - if (DSP4_vars.OAM_Row[Row1] + 1 >= DSP4_vars.OAM_RowMax) - *draw = 0; - if (DSP4_vars.OAM_Row[Row2] + 1 >= DSP4_vars.OAM_RowMax) - *draw = 0; - } - else - { - if (DSP4_vars.OAM_Row[Row1] >= DSP4_vars.OAM_RowMax) - { - *draw = 0; - } - } - - // emulator fail-safe (unknown if this really exists) - if (DSP4_vars.sprite_count >= 128) - { - *draw = 0; - } - - // SR = 0x80 - - if (*draw) - { - // Row tiles - if (size) - { - DSP4_vars.OAM_Row[Row1] += 2; - DSP4_vars.OAM_Row[Row2] += 2; - } - else - { - DSP4_vars.OAM_Row[Row1]++; - } - - // yield OAM output - DSP4_WRITE_WORD(1); - - // pack OAM data: x,y,name,attr - DSP4_WRITE_BYTE(sp_x & 0xff); - DSP4_WRITE_BYTE(sp_y & 0xff); - DSP4_WRITE_WORD(sp_attr); - - DSP4_vars.sprite_count++; - - // OAM: size,msb data - // save post-oam table data for future retrieval - DSP4_vars.OAM_attr[DSP4_vars.OAM_index] |= ((sp_x <0 || sp_x> 255) << DSP4_vars.OAM_bits); - DSP4_vars.OAM_bits++; - - DSP4_vars.OAM_attr[DSP4_vars.OAM_index] |= (size << DSP4_vars.OAM_bits); - DSP4_vars.OAM_bits++; - - // move to next byte in buffer - if (DSP4_vars.OAM_bits == 16) - { - DSP4_vars.OAM_bits = 0; - DSP4_vars.OAM_index++; - } - } - else if (stop) - { - // yield no OAM output - DSP4_WRITE_WORD(0); - } -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP0D() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.world_dy = DSP4_READ_DWORD(); - DSP4_vars.world_dx = DSP4_READ_DWORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_xenv = SEX78(DSP4_READ_WORD()); - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // perspective projection of world (x,y,scroll) points - // based on the current projection lines - DSP4_vars.view_x2 = (int16)(( ( ( DSP4_vars.world_x + DSP4_vars.world_xenv ) >> 16 ) * DSP4_vars.distance >> 15 ) + ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 )); - DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. World x-location before transformation - // 2. Viewer x-position at the current - // 3. World y-location before perspective projection - // 4. Viewer y-position below the horizon - // 5. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg1) - // 2. vertical scroll offset ($210E) - // 3. horizontal scroll offset ($210D) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - ///////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - // add deltas for projection lines - DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx); - DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy); - - // update projection lines - DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv); - DSP4_vars.world_y += DSP4_vars.world_dy; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(1) resume1 : - - // inspect input - DSP4_vars.distance = DSP4_READ_WORD(); - - // terminate op - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 6; - DSP4_WAIT(2) resume2: - - // inspect inputs - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // no envelope here - DSP4_vars.world_xenv = 0; - } - while (1); - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP0E() -{ - DSP4_vars.OAM_RowMax = 16; - memset(DSP4_vars.OAM_Row, 0, 64); -} - - -////////////////////////////////////////////////////////////// - -void DSP4_OP0F() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - case 4: - goto resume4; break; - } - - //////////////////////////////////////////////////// - // process initial inputs - - // sort inputs - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.world_dy = DSP4_READ_DWORD(); - DSP4_vars.world_dx = DSP4_READ_DWORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_xenv = DSP4_READ_DWORD(); - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - DSP4_vars.view_turnoff_x = 0; - DSP4_vars.view_turnoff_dx = 0; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // perspective projection of world (x,y,scroll) points - // based on the current projection lines - DSP4_vars.view_x2 = (int16)(((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_y2 = (int16)((DSP4_vars.world_y >> 16) * DSP4_vars.distance >> 15); - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. World x-location before transformation - // 2. Viewer x-position at the next - // 3. World y-location before perspective projection - // 4. Viewer y-position below the horizon - // 5. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)((DSP4_vars.world_x + DSP4_vars.world_xenv) >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD((uint16)(DSP4_vars.world_y >> 16)); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.poly_raster[0][0] - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < 4; DSP4_vars.lcv++) - { - // grab inputs - DSP4.in_count = 4; - DSP4_WAIT(1); - resume1 : - for (;;) - { - int16 distance; - int16 color, red, green, blue; - - distance = DSP4_READ_WORD(); - color = DSP4_READ_WORD(); - - // U1+B5+G5+R5 - red = color & 0x1f; - green = (color >> 5) & 0x1f; - blue = (color >> 10) & 0x1f; - - // dynamic lighting - red = (red * distance >> 15) & 0x1f; - green = (green * distance >> 15) & 0x1f; - blue = (blue * distance >> 15) & 0x1f; - color = red | (green << 5) | (blue << 10); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(color); - break; - } - } - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer - // 2. vertical scroll offset ($210E) - // 3. horizontal scroll offset ($210D) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - //////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - // add deltas for projection lines - DSP4_vars.world_dx += SEX78(DSP4_vars.world_ddx); - DSP4_vars.world_dy += SEX78(DSP4_vars.world_ddy); - - // update projection lines - DSP4_vars.world_x += (DSP4_vars.world_dx + DSP4_vars.world_xenv); - DSP4_vars.world_y += DSP4_vars.world_dy; - - // update road turnoff position - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(2) resume2: - - // check for termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // road splice - if( (uint16) DSP4_vars.distance == 0x8001 ) - { - DSP4.in_count = 6; - DSP4_WAIT(3) resume3: - - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_x = DSP4_READ_WORD(); - DSP4_vars.view_turnoff_dx = DSP4_READ_WORD(); - - // factor in new changes - DSP4_vars.view_x1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - DSP4_vars.view_xofs1 += ( DSP4_vars.view_turnoff_x * DSP4_vars.distance >> 15 ); - - // update stepping values - DSP4_vars.view_turnoff_x += DSP4_vars.view_turnoff_dx; - - DSP4.in_count = 2; - DSP4_WAIT(2) - } - - // already have 2 bytes in queue - DSP4.in_count = 6; - DSP4_WAIT(4) resume4 : - - // inspect inputs - DSP4_vars.world_ddy = DSP4_READ_WORD(); - DSP4_vars.world_ddx = DSP4_READ_WORD(); - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // no envelope here - DSP4_vars.world_xenv = 0; - } - while (1); - - // terminate op - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - - -void DSP4_OP10() -{ - DSP4.waiting4command = FALSE; - - // op flow control - switch (DSP4_vars.DSP4_Logic) - { - case 1: - goto resume1; break; - case 2: - goto resume2; break; - case 3: - goto resume3; break; - } - - //////////////////////////////////////////////////// - // sort inputs - - DSP4_READ_WORD(); // 0x0000 - DSP4_vars.world_y = DSP4_READ_DWORD(); - DSP4_vars.poly_bottom[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_top[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_cx[1][0] = DSP4_READ_WORD(); - DSP4_vars.viewport_bottom = DSP4_READ_WORD(); - DSP4_vars.world_x = DSP4_READ_DWORD(); - DSP4_vars.poly_cx[0][0] = DSP4_READ_WORD(); - DSP4_vars.poly_ptr[0][0] = DSP4_READ_WORD(); - DSP4_vars.world_yofs = DSP4_READ_WORD(); - DSP4_vars.distance = DSP4_READ_WORD(); - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_yofsenv = DSP4_READ_WORD(); - - // initial (x,y,offset) at starting DSP4_vars.raster line - DSP4_vars.view_x1 = (int16)(DSP4_vars.world_x >> 16); - DSP4_vars.view_y1 = (int16)(DSP4_vars.world_y >> 16); - DSP4_vars.view_xofs1 = DSP4_vars.view_x1; - DSP4_vars.view_yofs1 = DSP4_vars.world_yofs; - - // first DSP4_vars.raster line - DSP4_vars.poly_raster[0][0] = DSP4_vars.poly_bottom[0][0]; - - do - { - //////////////////////////////////////////////////// - // process one iteration of projection - - // add shaping - DSP4_vars.view_x2 += DSP4_vars.view_dx; - DSP4_vars.view_y2 += DSP4_vars.view_dy; - - // vertical scroll calculation - DSP4_vars.view_xofs2 = DSP4_vars.view_x2; - DSP4_vars.view_yofs2 = (DSP4_vars.world_yofs * DSP4_vars.distance >> 15) + DSP4_vars.poly_bottom[0][0] - DSP4_vars.view_y2; - - // 1. Viewer x-position at the next - // 2. Viewer y-position below the horizon - // 3. Number of DSP4_vars.raster lines drawn in this iteration - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(DSP4_vars.view_x2); - DSP4_WRITE_WORD(DSP4_vars.view_y2); - - ////////////////////////////////////////////////////// - - // SR = 0x00 - - // determine # of DSP4_vars.raster lines used - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.view_y2; - - // prevent overdraw - if (DSP4_vars.view_y2 >= DSP4_vars.poly_raster[0][0]) - DSP4_vars.segments = 0; - else - DSP4_vars.poly_raster[0][0] = DSP4_vars.view_y2; - - // don't draw outside the window - if (DSP4_vars.view_y2 < DSP4_vars.poly_top[0][0]) - { - DSP4_vars.segments = 0; - - // flush remaining DSP4_vars.raster lines - if (DSP4_vars.view_y1 >= DSP4_vars.poly_top[0][0]) - DSP4_vars.segments = DSP4_vars.view_y1 - DSP4_vars.poly_top[0][0]; - } - - // SR = 0x80 - - DSP4_WRITE_WORD(DSP4_vars.segments); - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < 4; DSP4_vars.lcv++) - { - // grab inputs - DSP4.in_count = 4; - DSP4_WAIT(1); - resume1 : - for (;;) - { - int16 distance; - int16 color, red, green, blue; - - distance = DSP4_READ_WORD(); - color = DSP4_READ_WORD(); - - // U1+B5+G5+R5 - red = color & 0x1f; - green = (color >> 5) & 0x1f; - blue = (color >> 10) & 0x1f; - - // dynamic lighting - red = (red * distance >> 15) & 0x1f; - green = (green * distance >> 15) & 0x1f; - blue = (blue * distance >> 15) & 0x1f; - color = red | (green << 5) | (blue << 10); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(color); - break; - } - } - } - - ////////////////////////////////////////////////////// - - // scan next command if no SR check needed - if (DSP4_vars.segments) - { - int32 px_dx, py_dy; - int32 x_scroll, y_scroll; - - // SR = 0x00 - - // linear interpolation (lerp) between projected points - px_dx = (DSP4_vars.view_xofs2 - DSP4_vars.view_xofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - py_dy = (DSP4_vars.view_yofs2 - DSP4_vars.view_yofs1) * DSP4_Inverse(DSP4_vars.segments) << 1; - - // starting step values - x_scroll = SEX16(DSP4_vars.poly_cx[0][0] + DSP4_vars.view_xofs1); - y_scroll = SEX16(-DSP4_vars.viewport_bottom + DSP4_vars.view_yofs1 + DSP4_vars.view_yofsenv + DSP4_vars.poly_cx[1][0] - DSP4_vars.world_yofs); - - // SR = 0x80 - - // rasterize line - for (DSP4_vars.lcv = 0; DSP4_vars.lcv < DSP4_vars.segments; DSP4_vars.lcv++) - { - // 1. HDMA memory pointer (bg2) - // 2. vertical scroll offset ($2110) - // 3. horizontal scroll offset ($210F) - - DSP4_WRITE_WORD(DSP4_vars.poly_ptr[0][0]); - DSP4_WRITE_WORD((uint16)((y_scroll + 0x8000) >> 16)); - DSP4_WRITE_WORD((uint16)((x_scroll + 0x8000) >> 16)); - - // update memory address - DSP4_vars.poly_ptr[0][0] -= 4; - - // update screen values - x_scroll += px_dx; - y_scroll += py_dy; - } - } - - ///////////////////////////////////////////////////// - // Post-update - - // update new viewer (x,y,scroll) to last DSP4_vars.raster line drawn - DSP4_vars.view_x1 = DSP4_vars.view_x2; - DSP4_vars.view_y1 = DSP4_vars.view_y2; - DSP4_vars.view_xofs1 = DSP4_vars.view_xofs2; - DSP4_vars.view_yofs1 = DSP4_vars.view_yofs2; - - //////////////////////////////////////////////////// - // command check - - // scan next command - DSP4.in_count = 2; - DSP4_WAIT(2) resume2 : - - // check for opcode termination - DSP4_vars.distance = DSP4_READ_WORD(); - if (DSP4_vars.distance == -0x8000) - break; - - // already have 2 bytes in queue - DSP4.in_count = 10; - DSP4_WAIT(3) resume3 : - - - // inspect inputs - DSP4_vars.view_y2 = DSP4_READ_WORD(); - DSP4_vars.view_dy = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - DSP4_vars.view_x2 = DSP4_READ_WORD(); - DSP4_vars.view_dx = DSP4_READ_WORD() * DSP4_vars.distance >> 15; - } - while (1); - - DSP4.waiting4command = TRUE; -} - -////////////////////////////////////////////////////////////// - -void DSP4_OP11(int16 A, int16 B, int16 C, int16 D, int16 *M) -{ - // 0x155 = 341 = Horizontal Width of the Screen - *M = ((A * 0x0155 >> 2) & 0xf000) | - ((B * 0x0155 >> 6) & 0x0f00) | - ((C * 0x0155 >> 10) & 0x00f0) | - ((D * 0x0155 >> 14) & 0x000f); -} - - - - - -///////////////////////////////////////////////////////////// -//Processing Code -///////////////////////////////////////////////////////////// -uint8 dsp4_byte; -uint16 dsp4_address; - -void InitDSP4() -{ - memset(&DSP4, 0, sizeof(DSP4)); - DSP4.waiting4command = TRUE; -} - -void DSP4SetByte() -{ - // clear pending read - if (DSP4.out_index < DSP4.out_count) - { - DSP4.out_index++; - return; - } - - if (DSP4.waiting4command) - { - if (DSP4.half_command) - { - DSP4.command |= (dsp4_byte << 8); - DSP4.in_index = 0; - DSP4.waiting4command = FALSE; - DSP4.half_command = FALSE; - DSP4.out_count = 0; - DSP4.out_index = 0; - - DSP4_vars.DSP4_Logic = 0; - - - switch (DSP4.command) - { - case 0x0000: - DSP4.in_count = 4; break; - case 0x0001: - DSP4.in_count = 44; break; - case 0x0003: - DSP4.in_count = 0; break; - case 0x0005: - DSP4.in_count = 0; break; - case 0x0006: - DSP4.in_count = 0; break; - case 0x0007: - DSP4.in_count = 34; break; - case 0x0008: - DSP4.in_count = 90; break; - case 0x0009: - DSP4.in_count = 14; break; - case 0x000a: - DSP4.in_count = 6; break; - case 0x000b: - DSP4.in_count = 6; break; - case 0x000d: - DSP4.in_count = 42; break; - case 0x000e: - DSP4.in_count = 0; break; - case 0x000f: - DSP4.in_count = 46; break; - case 0x0010: - DSP4.in_count = 36; break; - case 0x0011: - DSP4.in_count = 8; break; - default: - DSP4.waiting4command = TRUE; - break; - } - } - else - { - DSP4.command = dsp4_byte; - DSP4.half_command = TRUE; - } - } - else - { - DSP4.parameters[DSP4.in_index] = dsp4_byte; - DSP4.in_index++; - } - - if (!DSP4.waiting4command && DSP4.in_count == DSP4.in_index) - { - // Actually execute the command - DSP4.waiting4command = TRUE; - DSP4.out_index = 0; - DSP4.in_index = 0; - - switch (DSP4.command) - { - // 16-bit multiplication - case 0x0000: - { - int16 multiplier, multiplicand; - int32 product; - - multiplier = DSP4_READ_WORD(); - multiplicand = DSP4_READ_WORD(); - - DSP4_Multiply(multiplicand, multiplier, &product); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD((uint16)(product)); - DSP4_WRITE_WORD((uint16)(product >> 16)); - } - break; - - // single-player track projection - case 0x0001: - DSP4_OP01(); break; - - // single-player selection - case 0x0003: - DSP4_OP03(); break; - - // clear OAM - case 0x0005: - DSP4_OP05(); break; - - // transfer OAM - case 0x0006: - DSP4_OP06(); break; - - // single-player track turnoff projection - case 0x0007: - DSP4_OP07(); break; - - // solid polygon projection - case 0x0008: - DSP4_OP08(); break; - - // sprite projection - case 0x0009: - DSP4_OP09(); break; - - // unknown - case 0x000A: - { - int16 in1a = DSP4_READ_WORD(); - int16 in2a = DSP4_READ_WORD(); - int16 in3a = DSP4_READ_WORD(); - int16 out1a, out2a, out3a, out4a; - - DSP4_OP0A(in2a, &out2a, &out1a, &out4a, &out3a); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(out1a); - DSP4_WRITE_WORD(out2a); - DSP4_WRITE_WORD(out3a); - DSP4_WRITE_WORD(out4a); - } - break; - - // set OAM - case 0x000B: - { - int16 sp_x = DSP4_READ_WORD(); - int16 sp_y = DSP4_READ_WORD(); - int16 sp_attr = DSP4_READ_WORD(); - bool8 draw = 1; - - DSP4_CLEAR_OUT(); - - DSP4_OP0B(&draw, sp_x, sp_y, sp_attr, 0, 1); - } - break; - - // multi-player track projection - case 0x000D: - DSP4_OP0D(); break; - - // multi-player selection - case 0x000E: - DSP4_OP0E(); break; - - // single-player track projection with lighting - case 0x000F: - DSP4_OP0F(); break; - - // single-player track turnoff projection with lighting - case 0x0010: - DSP4_OP10(); break; - - // unknown: horizontal mapping command - case 0x0011: - { - int16 a, b, c, d, m; - - - d = DSP4_READ_WORD(); - c = DSP4_READ_WORD(); - b = DSP4_READ_WORD(); - a = DSP4_READ_WORD(); - - DSP4_OP11(a, b, c, d, &m); - - DSP4_CLEAR_OUT(); - DSP4_WRITE_WORD(m); - - break; - } - - default: - break; - } - } -} - -void DSP4GetByte() -{ - if (DSP4.out_count) - { - dsp4_byte = (uint8) DSP4.output[DSP4.out_index&0x1FF]; - DSP4.out_index++; - if (DSP4.out_count == DSP4.out_index) - DSP4.out_count = 0; - } - else - { - dsp4_byte = 0xff; - } -} - -#endif diff --git a/bsnes/chip/dsp4/dsp4emu.h b/bsnes/chip/dsp4/dsp4emu.h deleted file mode 100755 index 834b33de..00000000 --- a/bsnes/chip/dsp4/dsp4emu.h +++ /dev/null @@ -1,108 +0,0 @@ -//DSP-4 emulator code -//Copyright (c) 2004-2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden - -#ifndef DSP4EMU_H -#define DSP4EMU_H - -#undef TRUE -#undef FALSE -#define TRUE true -#define FALSE false - -struct DSP4_t -{ - bool8 waiting4command; - bool8 half_command; - uint16 command; - uint32 in_count; - uint32 in_index; - uint32 out_count; - uint32 out_index; - uint8 parameters[512]; - uint8 output[512]; -}; - -extern struct DSP4_t DSP4; - -struct DSP4_vars_t -{ - // op control - int8 DSP4_Logic; // controls op flow - - - // projection format - int16 lcv; // loop-control variable - int16 distance; // z-position into virtual world - int16 raster; // current raster line - int16 segments; // number of raster lines drawn - - // 1.15.16 or 1.15.0 [sign, integer, fraction] - int32 world_x; // line of x-projection in world - int32 world_y; // line of y-projection in world - int32 world_dx; // projection line x-delta - int32 world_dy; // projection line y-delta - int16 world_ddx; // x-delta increment - int16 world_ddy; // y-delta increment - int32 world_xenv; // world x-shaping factor - int16 world_yofs; // world y-vertical scroll - - int16 view_x1; // current viewer-x - int16 view_y1; // current viewer-y - int16 view_x2; // future viewer-x - int16 view_y2; // future viewer-y - int16 view_dx; // view x-delta factor - int16 view_dy; // view y-delta factor - int16 view_xofs1; // current viewer x-vertical scroll - int16 view_yofs1; // current viewer y-vertical scroll - int16 view_xofs2; // future viewer x-vertical scroll - int16 view_yofs2; // future viewer y-vertical scroll - int16 view_yofsenv; // y-scroll shaping factor - int16 view_turnoff_x; // road turnoff data - int16 view_turnoff_dx; // road turnoff delta factor - - - // drawing area - - int16 viewport_cx; // x-center of viewport window - int16 viewport_cy; // y-center of render window - int16 viewport_left; // x-left of viewport - int16 viewport_right; // x-right of viewport - int16 viewport_top; // y-top of viewport - int16 viewport_bottom; // y-bottom of viewport - - - // sprite structure - - int16 sprite_x; // projected x-pos of sprite - int16 sprite_y; // projected y-pos of sprite - int16 sprite_attr; // obj attributes - bool8 sprite_size; // sprite size: 8x8 or 16x16 - int16 sprite_clipy; // visible line to clip pixels off - int16 sprite_count; - - // generic projection variables designed for - // two solid polygons + two polygon sides - - int16 poly_clipLf[2][2]; // left clip boundary - int16 poly_clipRt[2][2]; // right clip boundary - int16 poly_ptr[2][2]; // HDMA structure pointers - int16 poly_raster[2][2]; // current raster line below horizon - int16 poly_top[2][2]; // top clip boundary - int16 poly_bottom[2][2]; // bottom clip boundary - int16 poly_cx[2][2]; // center for left/right points - int16 poly_start[2]; // current projection points - int16 poly_plane[2]; // previous z-plane distance - - - // OAM - int16 OAM_attr[16]; // OAM (size,MSB) data - int16 OAM_index; // index into OAM table - int16 OAM_bits; // offset into OAM table - - int16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row) - int16 OAM_Row[32]; // current number of tiles per row -}; - -extern struct DSP4_vars_t DSP4_vars; - -#endif diff --git a/bsnes/chip/msu1/msu1.cpp b/bsnes/chip/msu1/msu1.cpp deleted file mode 100755 index 76ac88d6..00000000 --- a/bsnes/chip/msu1/msu1.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include - -#define MSU1_CPP -namespace SNES { - -MSU1 msu1; - -#include "serialization.cpp" - -void MSU1::Enter() { msu1.enter(); } - -void MSU1::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - int16 left = 0, right = 0; - - if(mmio.audio_play) { - if(audiofile.open()) { - if(audiofile.end()) { - if(!mmio.audio_repeat) mmio.audio_play = false; - audiofile.seek(mmio.audio_offset = 58); - } else { - mmio.audio_offset += 4; - left = audiofile.readl(2); - right = audiofile.readl(2); - } - } else { - mmio.audio_play = false; - } - } - - left = sclamp<16>((double)left * (double)mmio.audio_volume / 255.0); - right = sclamp<16>((double)right * (double)mmio.audio_volume / 255.0); - - audio.coprocessor_sample(left, right); - step(1); - synchronize_cpu(); - } -} - -void MSU1::init() { -} - -void MSU1::enable() { - audio.coprocessor_enable(true); - audio.coprocessor_frequency(44100.0); - - if(datafile.open()) datafile.close(); - datafile.open(string() << cartridge.basename() << ".msu", file::mode_read); -} - -void MSU1::power() { - reset(); -} - -void MSU1::reset() { - create(MSU1::Enter, 44100); - - mmio.data_offset = 0; - mmio.audio_offset = 0; - mmio.audio_track = 0; - mmio.audio_volume = 255; - mmio.data_busy = true; - mmio.audio_busy = true; - mmio.audio_repeat = false; - mmio.audio_play = false; -} - -uint8 MSU1::mmio_read(unsigned addr) { - addr &= 0xffff; - - if(addr == 0x2000) { - return (mmio.data_busy << 7) - | (mmio.audio_busy << 6) - | (mmio.audio_repeat << 5) - | (mmio.audio_play << 4) - | (Revision << 0); - } - - if(addr == 0x2001) { - if(mmio.data_busy) return 0x00; - mmio.data_offset++; - if(datafile.open()) return datafile.read(); - return 0x00; - } - - if(addr == 0x2002) return 'S'; - if(addr == 0x2003) return '-'; - if(addr == 0x2004) return 'M'; - if(addr == 0x2005) return 'S'; - if(addr == 0x2006) return 'U'; - if(addr == 0x2007) return '0' + Revision; - - return 0x00; -} - -void MSU1::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x2000) { - mmio.data_offset = (mmio.data_offset & 0xffffff00) | (data << 0); - } - - if(addr == 0x2001) { - mmio.data_offset = (mmio.data_offset & 0xffff00ff) | (data << 8); - } - - if(addr == 0x2002) { - mmio.data_offset = (mmio.data_offset & 0xff00ffff) | (data << 16); - } - - if(addr == 0x2003) { - mmio.data_offset = (mmio.data_offset & 0x00ffffff) | (data << 24); - if(datafile.open()) datafile.seek(mmio.data_offset); - mmio.data_busy = false; - } - - if(addr == 0x2004) { - mmio.audio_track = (mmio.audio_track & 0xff00) | (data << 0); - } - - if(addr == 0x2005) { - mmio.audio_track = (mmio.audio_track & 0x00ff) | (data << 8); - if(audiofile.open()) audiofile.close(); - char track[16]; - sprintf(track, "-%u", mmio.audio_track); - if(audiofile.open(string() << cartridge.basename() << track << ".wav", file::mode_read)) { - audiofile.seek(mmio.audio_offset = 58); //skip WAV header - } - mmio.audio_busy = false; - mmio.audio_repeat = false; - mmio.audio_play = false; - } - - if(addr == 0x2006) { - mmio.audio_volume = data; - } - - if(addr == 0x2007) { - mmio.audio_repeat = data & 2; - mmio.audio_play = data & 1; - } -} - -} diff --git a/bsnes/chip/msu1/msu1.hpp b/bsnes/chip/msu1/msu1.hpp deleted file mode 100755 index 473b75da..00000000 --- a/bsnes/chip/msu1/msu1.hpp +++ /dev/null @@ -1,39 +0,0 @@ -class MSU1 : public Coprocessor, public MMIO { -public: - static void Enter(); - void enter(); - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - void serialize(serializer&); - -private: - file datafile; - file audiofile; - - enum Flag { - DataBusy = 0x80, - AudioBusy = 0x40, - AudioRepeating = 0x20, - AudioPlaying = 0x10, - Revision = 0x01, - }; - - struct MMIO { - uint32 data_offset; - uint32 audio_offset; - uint16 audio_track; - uint8 audio_volume; - bool data_busy; - bool audio_busy; - bool audio_repeat; - bool audio_play; - } mmio; -}; - -extern MSU1 msu1; diff --git a/bsnes/chip/msu1/serialization.cpp b/bsnes/chip/msu1/serialization.cpp deleted file mode 100755 index cf0d639b..00000000 --- a/bsnes/chip/msu1/serialization.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef MSU1_CPP - -void MSU1::serialize(serializer &s) { - Processor::serialize(s); - - s.integer(mmio.data_offset); - s.integer(mmio.audio_offset); - s.integer(mmio.audio_track); - s.integer(mmio.audio_volume); - s.integer(mmio.data_busy); - s.integer(mmio.audio_busy); - s.integer(mmio.audio_repeat); - s.integer(mmio.audio_play); - - if(datafile.open()) datafile.close(); - if(datafile.open(string() << cartridge.basename() << ".msu", file::mode_read)) { - datafile.seek(mmio.data_offset); - } - - if(audiofile.open()) audiofile.close(); - char track[16]; - sprintf(track, "-%u", mmio.audio_track); - if(audiofile.open(string() << cartridge.basename() << track << ".wav", file::mode_read)) { - audiofile.seek(mmio.audio_offset); - } -} - -#endif diff --git a/bsnes/chip/obc1/obc1.cpp b/bsnes/chip/obc1/obc1.cpp deleted file mode 100755 index 4b79a4c2..00000000 --- a/bsnes/chip/obc1/obc1.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include - -#define OBC1_CPP -namespace SNES { - -OBC1 obc1; - -#include "serialization.cpp" - -void OBC1::init() { -} - -void OBC1::enable() { -} - -void OBC1::power() { - reset(); -} - -void OBC1::reset() { - for(unsigned i = 0x0000; i <= 0x1fff; i++) ram_write(i, 0xff); - - status.baseptr = (ram_read(0x1ff5) & 1) ? 0x1800 : 0x1c00; - status.address = (ram_read(0x1ff6) & 0x7f); - status.shift = (ram_read(0x1ff6) & 3) << 1; -} - -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); - } -} - -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; - } -} - -uint8 OBC1::ram_read(unsigned addr) { - return memory::cartram.read(addr & 0x1fff); -} - -void OBC1::ram_write(unsigned addr, uint8 data) { - memory::cartram.write(addr & 0x1fff, data); -} - -OBC1::OBC1() {} -OBC1::~OBC1() {} - -} diff --git a/bsnes/chip/obc1/obc1.hpp b/bsnes/chip/obc1/obc1.hpp deleted file mode 100755 index 4b5d4408..00000000 --- a/bsnes/chip/obc1/obc1.hpp +++ /dev/null @@ -1,26 +0,0 @@ -class OBC1 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - OBC1(); - ~OBC1(); - -private: - uint8 ram_read(unsigned addr); - void ram_write(unsigned addr, uint8 data); - - struct { - uint16 address; - uint16 baseptr; - uint16 shift; - } status; -}; - -extern OBC1 obc1; diff --git a/bsnes/chip/obc1/serialization.cpp b/bsnes/chip/obc1/serialization.cpp deleted file mode 100755 index 3d61aafc..00000000 --- a/bsnes/chip/obc1/serialization.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef OBC1_CPP - -void OBC1::serialize(serializer &s) { - s.integer(status.address); - s.integer(status.baseptr); - s.integer(status.shift); -} - -#endif diff --git a/bsnes/chip/sa1/bus/bus.cpp b/bsnes/chip/sa1/bus/bus.cpp deleted file mode 100755 index 4eb60e9b..00000000 --- a/bsnes/chip/sa1/bus/bus.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#ifdef SA1_CPP - -VBRBus vbrbus; -SA1Bus sa1bus; - -namespace memory { - StaticRAM iram(2048); - //accessed by: - VSPROM vsprom; //S-CPU + SA-1 - CPUIRAM cpuiram; //S-CPU - SA1IRAM sa1iram; //SA-1 - SA1BWRAM sa1bwram; //SA-1 - CC1BWRAM cc1bwram; //S-CPU - BitmapRAM bitmapram; //SA-1 -} - -//$230c (VDPL), $230d (VDPH) use this bus to read variable-length data. -//this is used both to avoid VBR-reads from accessing MMIO registers, and -//to avoid syncing the S-CPU and SA-1*; as both chips are able to access -//these ports. -//(* eg, memory::cartram is used directly, as memory::sa1bwram syncs to the S-CPU) -void VBRBus::init() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x07ff, memory::iram); - map(MapMode::Linear, 0x00, 0x3f, 0x3000, 0x37ff, memory::iram); - map(MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cartram); - map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::cartram); - map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x07ff, memory::iram); - map(MapMode::Linear, 0x80, 0xbf, 0x3000, 0x37ff, memory::iram); - map(MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cartram); - map(MapMode::Linear, 0x80, 0xbf, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, memory::vsprom); -} - -void SA1Bus::init() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x07ff, memory::sa1iram); - map(MapMode::Direct, 0x00, 0x3f, 0x2200, 0x23ff, memory::mmio); - map(MapMode::Linear, 0x00, 0x3f, 0x3000, 0x37ff, memory::sa1iram); - map(MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram); - map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0x40, 0x4f, 0x0000, 0xffff, memory::sa1bwram); - map(MapMode::Linear, 0x60, 0x6f, 0x0000, 0xffff, memory::bitmapram); - map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x07ff, memory::sa1iram); - map(MapMode::Direct, 0x80, 0xbf, 0x2200, 0x23ff, memory::mmio); - map(MapMode::Linear, 0x80, 0xbf, 0x3000, 0x37ff, memory::sa1iram); - map(MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram); - map(MapMode::Linear, 0x80, 0xbf, 0x8000, 0xffff, memory::vsprom); - map(MapMode::Linear, 0xc0, 0xff, 0x0000, 0xffff, memory::vsprom); -} - -//====== -//VSPROM -//====== - -//this class maps $00:[ff00-ffff] for the purpose of supporting: -//$2209.d6 IVSW (S-CPU IRQ vector selection) (0 = cart, 1 = SA-1) -//$2209.d4 NVSW (S-CPU NMI vector selection) (0 = cart, 1 = SA-1) -//when set, vector addresses are over-ridden with SA-1 register settings: -//SIV = S-CPU IRQ vector address override -//SNV = S-CPU NMI vector address override -// -//$00:[ffea-ffeb|ffee-ffef] are special cased on read; -//all other addresses return original mapped data. - -unsigned VSPROM::size() const { - return memory::cartrom.size(); -} - -uint8 VSPROM::read(unsigned addr) { - //use $7fex instead of $ffex due to linear mapping of 32k granularity ROM data - if((addr & 0xffffe0) == 0x007fe0) { - if(addr == 0x7fea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0; - if(addr == 0x7feb && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 8; - if(addr == 0x7fee && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 0; - if(addr == 0x7fef && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 8; - } - return memory::cartrom.read(addr); -} - -void VSPROM::write(unsigned addr, uint8 data) { -} - -//======= -//SA1IRAM -//======= - -unsigned SA1IRAM::size() const { - return memory::iram.size(); -} - -uint8 SA1IRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - return memory::iram.read(addr); -} - -void SA1IRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - memory::iram.write(addr, data); -} - -//======= -//CPUIRAM -//======= - -unsigned CPUIRAM::size() const { - return memory::iram.size(); -} - -uint8 CPUIRAM::read(unsigned addr) { - cpu.synchronize_coprocessor(); - return memory::iram.read(addr); -} - -void CPUIRAM::write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - memory::iram.write(addr, data); -} - -//======== -//SA1BWRAM -//======== - -unsigned SA1BWRAM::size() const { - return memory::cartram.size(); -} - -uint8 SA1BWRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - return memory::cartram.read(addr); -} - -void SA1BWRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - memory::cartram.write(addr, data); -} - -//======== -//CC1BWRAM -//======== - -unsigned CC1BWRAM::size() const { - return memory::cartram.size(); -} - -uint8 CC1BWRAM::read(unsigned addr) { - cpu.synchronize_coprocessor(); - if(dma) return sa1.dma_cc1_read(addr); - return memory::cartram.read(addr); -} - -void CC1BWRAM::write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - memory::cartram.write(addr, data); -} - -//========= -//BitmapRAM -//========= - -unsigned BitmapRAM::size() const { - return 0x100000; -} - -uint8 BitmapRAM::read(unsigned addr) { - sa1.synchronize_cpu(); - - if(sa1.mmio.bbf == 0) { - //4bpp - unsigned shift = addr & 1; - addr = (addr >> 1) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: return (memory::cartram.read(addr) >> 0) & 15; - case 1: return (memory::cartram.read(addr) >> 4) & 15; - } - } else { - //2bpp - unsigned shift = addr & 3; - addr = (addr >> 2) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: return (memory::cartram.read(addr) >> 0) & 3; - case 1: return (memory::cartram.read(addr) >> 2) & 3; - case 2: return (memory::cartram.read(addr) >> 4) & 3; - case 3: return (memory::cartram.read(addr) >> 6) & 3; - } - } -} - -void BitmapRAM::write(unsigned addr, uint8 data) { - sa1.synchronize_cpu(); - - if(sa1.mmio.bbf == 0) { - //4bpp - unsigned shift = addr & 1; - addr = (addr >> 1) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: data = (memory::cartram.read(addr) & 0xf0) | ((data & 15) << 0); break; - case 1: data = (memory::cartram.read(addr) & 0x0f) | ((data & 15) << 4); break; - } - } else { - //2bpp - unsigned shift = addr & 3; - addr = (addr >> 2) & (memory::cartram.size() - 1); - switch(shift) { default: - case 0: data = (memory::cartram.read(addr) & 0xfc) | ((data & 3) << 0); break; - case 1: data = (memory::cartram.read(addr) & 0xf3) | ((data & 3) << 2); break; - case 2: data = (memory::cartram.read(addr) & 0xcf) | ((data & 3) << 4); break; - case 3: data = (memory::cartram.read(addr) & 0x3f) | ((data & 3) << 6); break; - } - } - - memory::cartram.write(addr, data); -} - -#endif diff --git a/bsnes/chip/sa1/bus/bus.hpp b/bsnes/chip/sa1/bus/bus.hpp deleted file mode 100755 index 2aeb11de..00000000 --- a/bsnes/chip/sa1/bus/bus.hpp +++ /dev/null @@ -1,55 +0,0 @@ -struct VBRBus : Bus { - void init(); -}; - -struct SA1Bus : Bus { - void init(); -}; - -struct VSPROM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct CPUIRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct SA1IRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct SA1BWRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -struct CC1BWRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); - bool dma; -}; - -struct BitmapRAM : Memory { - unsigned size() const; - alwaysinline uint8 read(unsigned); - alwaysinline void write(unsigned, uint8); -}; - -namespace memory { - extern StaticRAM iram; - - extern VSPROM vsprom; - extern CPUIRAM cpuiram; - extern SA1IRAM sa1iram; - extern SA1BWRAM sa1bwram; - extern CC1BWRAM cc1bwram; - extern BitmapRAM bitmapram; -}; diff --git a/bsnes/chip/sa1/dma/dma.cpp b/bsnes/chip/sa1/dma/dma.cpp deleted file mode 100755 index aecb7358..00000000 --- a/bsnes/chip/sa1/dma/dma.cpp +++ /dev/null @@ -1,139 +0,0 @@ -#ifdef SA1_CPP - -//==================== -//direct data transfer -//==================== - -void SA1::dma_normal() { - while(mmio.dtc--) { - uint8 data = regs.mdr; - uint32 dsa = mmio.dsa++; - uint32 dda = mmio.dda++; - - //source and destination cannot be the same - if(mmio.sd == DMA::SourceBWRAM && mmio.dd == DMA::DestBWRAM) continue; - if(mmio.sd == DMA::SourceIRAM && mmio.dd == DMA::DestIRAM ) continue; - - switch(mmio.sd) { - case DMA::SourceROM: { - if((dsa & 0x408000) == 0x008000 || (dsa & 0xc00000) == 0xc00000) { - data = sa1bus.read(dsa); - } - } break; - - case DMA::SourceBWRAM: { - if((dsa & 0x40e000) == 0x006000 || (dsa & 0xf00000) == 0x400000) { - data = sa1bus.read(dsa); - } - } break; - - case DMA::SourceIRAM: { - data = memory::iram.read(dsa & 0x07ff); - } break; - } - - switch(mmio.dd) { - case DMA::DestBWRAM: { - if((dda & 0x40e000) == 0x006000 || (dda & 0xf00000) == 0x400000) { - sa1bus.write(dda, data); - } - } break; - - case DMA::DestIRAM: { - memory::iram.write(dda & 0x07ff, data); - } break; - } - } - - mmio.dma_irqfl = true; - if(mmio.dma_irqen) mmio.dma_irqcl = 0; -} - -//((byte & 6) << 3) + (byte & 1) explanation: -//transforms a byte index (0-7) into a planar index: -//result[] = { 0, 1, 16, 17, 32, 33, 48, 49 }; -//works for 2bpp, 4bpp and 8bpp modes - -//=========================== -//type-1 character conversion -//=========================== - -void SA1::dma_cc1() { - memory::cc1bwram.dma = true; - mmio.chdma_irqfl = true; - if(mmio.chdma_irqen) { - mmio.chdma_irqcl = 0; - cpu.regs.irq = 1; - } -} - -uint8 SA1::dma_cc1_read(unsigned addr) { - //16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp) - unsigned charmask = (1 << (6 - mmio.dmacb)) - 1; - - if((addr & charmask) == 0) { - //buffer next character to I-RAM - unsigned bpp = 2 << (2 - mmio.dmacb); - unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb; - unsigned bwmask = memory::cartram.size() - 1; - unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb); - unsigned ty = (tile >> mmio.dmasize); - unsigned tx = tile & ((1 << mmio.dmasize) - 1); - unsigned bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp; - - for(unsigned y = 0; y < 8; y++) { - uint64 data = 0; - for(unsigned byte = 0; byte < bpp; byte++) { - data |= (uint64)memory::cartram.read((bwaddr + byte) & bwmask) << (byte << 3); - } - bwaddr += bpl; - - uint8 out[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - for(unsigned x = 0; x < 8; x++) { - out[0] |= (data & 1) << (7 - x); data >>= 1; - out[1] |= (data & 1) << (7 - x); data >>= 1; - if(mmio.dmacb == 2) continue; - out[2] |= (data & 1) << (7 - x); data >>= 1; - out[3] |= (data & 1) << (7 - x); data >>= 1; - if(mmio.dmacb == 1) continue; - out[4] |= (data & 1) << (7 - x); data >>= 1; - out[5] |= (data & 1) << (7 - x); data >>= 1; - out[6] |= (data & 1) << (7 - x); data >>= 1; - out[7] |= (data & 1) << (7 - x); data >>= 1; - } - - for(unsigned byte = 0; byte < bpp; byte++) { - unsigned p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1); - memory::iram.write(p & 0x07ff, out[byte]); - } - } - } - - return memory::iram.read((mmio.dda + (addr & charmask)) & 0x07ff); -} - -//=========================== -//type-2 character conversion -//=========================== - -void SA1::dma_cc2() { - //select register file index (0-7 or 8-15) - const uint8 *brf = &mmio.brf[(dma.line & 1) << 3]; - unsigned bpp = 2 << (2 - mmio.dmacb); - unsigned addr = mmio.dda & 0x07ff; - addr &= ~((1 << (7 - mmio.dmacb)) - 1); - addr += (dma.line & 8) * bpp; - addr += (dma.line & 7) * 2; - - for(unsigned byte = 0; byte < bpp; byte++) { - uint8 output = 0; - for(unsigned bit = 0; bit < 8; bit++) { - output |= ((brf[bit] >> byte) & 1) << (7 - bit); - } - memory::iram.write(addr + ((byte & 6) << 3) + (byte & 1), output); - } - - dma.line = (dma.line + 1) & 15; -} - -#endif diff --git a/bsnes/chip/sa1/dma/dma.hpp b/bsnes/chip/sa1/dma/dma.hpp deleted file mode 100755 index 4d3cff7f..00000000 --- a/bsnes/chip/sa1/dma/dma.hpp +++ /dev/null @@ -1,11 +0,0 @@ -struct DMA { - enum CDEN { DmaNormal = 0, DmaCharConversion = 1 }; - enum SD { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 }; - enum DD { DestIRAM = 0, DestBWRAM = 1 }; - unsigned line; -} dma; - -void dma_normal(); -void dma_cc1(); -uint8 dma_cc1_read(unsigned addr); -void dma_cc2(); diff --git a/bsnes/chip/sa1/memory/memory.cpp b/bsnes/chip/sa1/memory/memory.cpp deleted file mode 100755 index b2779a35..00000000 --- a/bsnes/chip/sa1/memory/memory.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifdef SA1_CPP - -//ROM, I-RAM and MMIO registers are accessed at ~10.74MHz (2 clock ticks) -//BW-RAM is accessed at ~5.37MHz (4 clock ticks) -//tick() == 2 clock ticks -//note: bus conflict delays are not emulated at this time - -void SA1::op_io() { - tick(); -} - -uint8 SA1::op_read(unsigned addr) { - tick(); - if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick(); - return sa1bus.read(addr); -} - -void SA1::op_write(unsigned addr, uint8 data) { - tick(); - if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick(); - sa1bus.write(addr, data); -} - -#endif diff --git a/bsnes/chip/sa1/memory/memory.hpp b/bsnes/chip/sa1/memory/memory.hpp deleted file mode 100755 index d466c416..00000000 --- a/bsnes/chip/sa1/memory/memory.hpp +++ /dev/null @@ -1,5 +0,0 @@ -alwaysinline void op_io(); -alwaysinline uint8 op_read(unsigned addr); -alwaysinline void op_write(unsigned addr, uint8 data); - -uint8_t vbr_read(unsigned addr); diff --git a/bsnes/chip/sa1/mmio/mmio.cpp b/bsnes/chip/sa1/mmio/mmio.cpp deleted file mode 100755 index c36d019b..00000000 --- a/bsnes/chip/sa1/mmio/mmio.cpp +++ /dev/null @@ -1,631 +0,0 @@ -#ifdef SA1_CPP - -//BS-X flash carts, when present, are mapped to 0x400000+ -Memory& SA1::mmio_access(unsigned &addr) { - if(!memory::bsxflash.data()) return memory::vsprom; - if(addr < 0x400000) return memory::vsprom; - addr &= 0x3fffff; - return bsxflash; -} - -//(CCNT) SA-1 control -void SA1::mmio_w2200(uint8 data) { - if(mmio.sa1_resb && !(data & 0x80)) { - //reset SA-1 CPU - regs.pc.w = mmio.crv; - regs.pc.b = 0x00; - } - - mmio.sa1_irq = (data & 0x80); - mmio.sa1_rdyb = (data & 0x40); - mmio.sa1_resb = (data & 0x20); - mmio.sa1_nmi = (data & 0x10); - mmio.smeg = (data & 0x0f); - - if(mmio.sa1_irq) { - mmio.sa1_irqfl = true; - if(mmio.sa1_irqen) mmio.sa1_irqcl = 0; - } - - if(mmio.sa1_nmi) { - mmio.sa1_nmifl = true; - if(mmio.sa1_nmien) mmio.sa1_nmicl = 0; - } -} - -//(SIE) S-CPU interrupt enable -void SA1::mmio_w2201(uint8 data) { - if(!mmio.cpu_irqen && (data & 0x80)) { - if(mmio.cpu_irqfl) { - mmio.cpu_irqcl = 0; - cpu.regs.irq = 1; - } - } - - if(!mmio.chdma_irqen && (data & 0x20)) { - if(mmio.chdma_irqfl) { - mmio.chdma_irqcl = 0; - cpu.regs.irq = 1; - } - } - - mmio.cpu_irqen = (data & 0x80); - mmio.chdma_irqen = (data & 0x20); -} - -//(SIC) S-CPU interrupt clear -void SA1::mmio_w2202(uint8 data) { - mmio.cpu_irqcl = (data & 0x80); - mmio.chdma_irqcl = (data & 0x20); - - if(mmio.cpu_irqcl ) mmio.cpu_irqfl = false; - if(mmio.chdma_irqcl) mmio.chdma_irqfl = false; - - if(!mmio.cpu_irqfl && !mmio.chdma_irqfl) cpu.regs.irq = 0; -} - -//(CRV) SA-1 reset vector -void SA1::mmio_w2203(uint8 data) { mmio.crv = (mmio.crv & 0xff00) | data; } -void SA1::mmio_w2204(uint8 data) { mmio.crv = (data << 8) | (mmio.crv & 0xff); } - -//(CNV) SA-1 NMI vector -void SA1::mmio_w2205(uint8 data) { mmio.cnv = (mmio.cnv & 0xff00) | data; } -void SA1::mmio_w2206(uint8 data) { mmio.cnv = (data << 8) | (mmio.cnv & 0xff); } - -//(CIV) SA-1 IRQ vector -void SA1::mmio_w2207(uint8 data) { mmio.civ = (mmio.civ & 0xff00) | data; } -void SA1::mmio_w2208(uint8 data) { mmio.civ = (data << 8) | (mmio.civ & 0xff); } - -//(SCNT) S-CPU control -void SA1::mmio_w2209(uint8 data) { - mmio.cpu_irq = (data & 0x80); - mmio.cpu_ivsw = (data & 0x40); - mmio.cpu_nvsw = (data & 0x10); - mmio.cmeg = (data & 0x0f); - - if(mmio.cpu_irq) { - mmio.cpu_irqfl = true; - if(mmio.cpu_irqen) { - mmio.cpu_irqcl = 0; - cpu.regs.irq = 1; - } - } -} - -//(CIE) SA-1 interrupt enable -void SA1::mmio_w220a(uint8 data) { - if(!mmio.sa1_irqen && (data & 0x80) && mmio.sa1_irqfl ) mmio.sa1_irqcl = 0; - if(!mmio.timer_irqen && (data & 0x40) && mmio.timer_irqfl) mmio.timer_irqcl = 0; - if(!mmio.dma_irqen && (data & 0x20) && mmio.dma_irqfl ) mmio.dma_irqcl = 0; - if(!mmio.sa1_nmien && (data & 0x10) && mmio.sa1_nmifl ) mmio.sa1_nmicl = 0; - - mmio.sa1_irqen = (data & 0x80); - mmio.timer_irqen = (data & 0x40); - mmio.dma_irqen = (data & 0x20); - mmio.sa1_nmien = (data & 0x10); -} - -//(CIC) SA-1 interrupt clear -void SA1::mmio_w220b(uint8 data) { - mmio.sa1_irqcl = (data & 0x80); - mmio.timer_irqcl = (data & 0x40); - mmio.dma_irqcl = (data & 0x20); - mmio.sa1_nmicl = (data & 0x10); - - if(mmio.sa1_irqcl) mmio.sa1_irqfl = false; - if(mmio.timer_irqcl) mmio.timer_irqfl = false; - if(mmio.dma_irqcl) mmio.dma_irqfl = false; - if(mmio.sa1_nmicl) mmio.sa1_nmifl = false; -} - -//(SNV) S-CPU NMI vector -void SA1::mmio_w220c(uint8 data) { mmio.snv = (mmio.snv & 0xff00) | data; } -void SA1::mmio_w220d(uint8 data) { mmio.snv = (data << 8) | (mmio.snv & 0xff); } - -//(SIV) S-CPU IRQ vector -void SA1::mmio_w220e(uint8 data) { mmio.siv = (mmio.siv & 0xff00) | data; } -void SA1::mmio_w220f(uint8 data) { mmio.siv = (data << 8) | (mmio.siv & 0xff); } - -//(TMC) H/V timer control -void SA1::mmio_w2210(uint8 data) { - mmio.hvselb = (data & 0x80); - mmio.ven = (data & 0x02); - mmio.hen = (data & 0x01); -} - -//(CTR) SA-1 timer restart -void SA1::mmio_w2211(uint8 data) { - status.vcounter = 0; - status.hcounter = 0; -} - -//(HCNT) H-count -void SA1::mmio_w2212(uint8 data) { mmio.hcnt = (mmio.hcnt & 0xff00) | (data << 0); } -void SA1::mmio_w2213(uint8 data) { mmio.hcnt = (mmio.hcnt & 0x00ff) | (data << 8); } - -//(VCNT) V-count -void SA1::mmio_w2214(uint8 data) { mmio.vcnt = (mmio.vcnt & 0xff00) | (data << 0); } -void SA1::mmio_w2215(uint8 data) { mmio.vcnt = (mmio.vcnt & 0x00ff) | (data << 8); } - -//(CXB) Super MMC bank C -void SA1::mmio_w2220(uint8 data) { - mmio.cbmode = (data & 0x80); - mmio.cb = (data & 0x07); - - unsigned addr = mmio.cb << 20; - Memory &access = mmio_access(addr); - - if(mmio.cbmode == 0) { - bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::vsprom, 0x000000); - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, memory::vsprom, 0x000000); - } else { - bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x1f, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xc0, 0xcf, 0x0000, 0xffff, access, addr); -} - -//(DXB) Super MMC bank D -void SA1::mmio_w2221(uint8 data) { - mmio.dbmode = (data & 0x80); - mmio.db = (data & 0x07); - - unsigned addr = mmio.db << 20; - Memory &access = mmio_access(addr); - - if(mmio.dbmode == 0) { - bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, memory::vsprom, 0x100000); - sa1bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, memory::vsprom, 0x100000); - } else { - bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0x20, 0x3f, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xd0, 0xdf, 0x0000, 0xffff, access, addr); -} - -//(EXB) Super MMC bank E -void SA1::mmio_w2222(uint8 data) { - mmio.ebmode = (data & 0x80); - mmio.eb = (data & 0x07); - - unsigned addr = mmio.eb << 20; - Memory &access = mmio_access(addr); - - if(mmio.ebmode == 0) { - bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::vsprom, 0x200000); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, memory::vsprom, 0x200000); - } else { - bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0x9f, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xe0, 0xef, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xe0, 0xef, 0x0000, 0xffff, access, addr); -} - -//(FXB) Super MMC bank F -void SA1::mmio_w2223(uint8 data) { - mmio.fbmode = (data & 0x80); - mmio.fb = (data & 0x07); - - unsigned addr = mmio.fb << 20; - Memory &access = mmio_access(addr); - - if(mmio.fbmode == 0) { - bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, memory::vsprom, 0x300000); - sa1bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, memory::vsprom, 0x300000); - } else { - bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xa0, 0xbf, 0x8000, 0xffff, access, addr); - } - - bus.map(Bus::MapMode::Linear, 0xf0, 0xff, 0x0000, 0xffff, access, addr); - sa1bus.map(Bus::MapMode::Linear, 0xf0, 0xff, 0x0000, 0xffff, access, addr); -} - -//(BMAPS) S-CPU BW-RAM address mapping -void SA1::mmio_w2224(uint8 data) { - mmio.sbm = (data & 0x1f); - - bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000); - bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cc1bwram, mmio.sbm * 0x2000, 0x2000); -} - -//(BMAP) SA-1 BW-RAM address mapping -void SA1::mmio_w2225(uint8 data) { - mmio.sw46 = (data & 0x80); - mmio.cbm = (data & 0x7f); - - if(mmio.sw46 == 0) { - //$[40-43]:[0000-ffff] x 32 projection - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000); - } else { - //$[60-6f]:[0000-ffff] x 128 projection - sa1bus.map(Bus::MapMode::Linear, 0x00, 0x3f, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000); - sa1bus.map(Bus::MapMode::Linear, 0x80, 0xbf, 0x6000, 0x7fff, memory::bitmapram, mmio.cbm * 0x2000, 0x2000); - } -} - -//(SWBE) S-CPU BW-RAM write enable -void SA1::mmio_w2226(uint8 data) { - mmio.swen = (data & 0x80); -} - -//(CWBE) SA-1 BW-RAM write enable -void SA1::mmio_w2227(uint8 data) { - mmio.cwen = (data & 0x80); -} - -//(BWPA) BW-RAM write-protected area -void SA1::mmio_w2228(uint8 data) { - mmio.bwp = (data & 0x0f); -} - -//(SIWP) S-CPU I-RAM write protection -void SA1::mmio_w2229(uint8 data) { - mmio.siwp = data; -} - -//(CIWP) SA-1 I-RAM write protection -void SA1::mmio_w222a(uint8 data) { - mmio.ciwp = data; -} - -//(DCNT) DMA control -void SA1::mmio_w2230(uint8 data) { - mmio.dmaen = (data & 0x80); - mmio.dprio = (data & 0x40); - mmio.cden = (data & 0x20); - mmio.cdsel = (data & 0x10); - mmio.dd = (data & 0x04); - mmio.sd = (data & 0x03); - - if(mmio.dmaen == 0) dma.line = 0; -} - -//(CDMA) character conversion DMA parameters -void SA1::mmio_w2231(uint8 data) { - mmio.chdend = (data & 0x80); - mmio.dmasize = (data >> 2) & 7; - mmio.dmacb = (data & 0x03); - - if(mmio.chdend) memory::cc1bwram.dma = false; - if(mmio.dmasize > 5) mmio.dmasize = 5; - if(mmio.dmacb > 2) mmio.dmacb = 2; -} - -//(SDA) DMA source device start address -void SA1::mmio_w2232(uint8 data) { mmio.dsa = (mmio.dsa & 0xffff00) | (data << 0); } -void SA1::mmio_w2233(uint8 data) { mmio.dsa = (mmio.dsa & 0xff00ff) | (data << 8); } -void SA1::mmio_w2234(uint8 data) { mmio.dsa = (mmio.dsa & 0x00ffff) | (data << 16); } - -//(DDA) DMA destination start address -void SA1::mmio_w2235(uint8 data) { - mmio.dda = (mmio.dda & 0xffff00) | (data << 0); -} - -void SA1::mmio_w2236(uint8 data) { - mmio.dda = (mmio.dda & 0xff00ff) | (data << 8); - - if(mmio.dmaen == true) { - if(mmio.cden == 0 && mmio.dd == DMA::DestIRAM) { - dma_normal(); - } else if(mmio.cden == 1 && mmio.cdsel == 1) { - dma_cc1(); - } - } -} - -void SA1::mmio_w2237(uint8 data) { - mmio.dda = (mmio.dda & 0x00ffff) | (data << 16); - - if(mmio.dmaen == true) { - if(mmio.cden == 0 && mmio.dd == DMA::DestBWRAM) { - dma_normal(); - } - } -} - -//(DTC) DMA terminal counter -void SA1::mmio_w2238(uint8 data) { mmio.dtc = (mmio.dtc & 0xff00) | (data << 0); } -void SA1::mmio_w2239(uint8 data) { mmio.dtc = (mmio.dtc & 0x00ff) | (data << 8); } - -//(BBF) BW-RAM bitmap format -void SA1::mmio_w223f(uint8 data) { - mmio.bbf = (data & 0x80); -} - -//(BRF) bitmap register files -void SA1::mmio_w2240(uint8 data) { mmio.brf[ 0] = data; } -void SA1::mmio_w2241(uint8 data) { mmio.brf[ 1] = data; } -void SA1::mmio_w2242(uint8 data) { mmio.brf[ 2] = data; } -void SA1::mmio_w2243(uint8 data) { mmio.brf[ 3] = data; } -void SA1::mmio_w2244(uint8 data) { mmio.brf[ 4] = data; } -void SA1::mmio_w2245(uint8 data) { mmio.brf[ 5] = data; } -void SA1::mmio_w2246(uint8 data) { mmio.brf[ 6] = data; } -void SA1::mmio_w2247(uint8 data) { mmio.brf[ 7] = data; - if(mmio.dmaen == true) { - if(mmio.cden == 1 && mmio.cdsel == 0) { - dma_cc2(); - } - } -} - -void SA1::mmio_w2248(uint8 data) { mmio.brf[ 8] = data; } -void SA1::mmio_w2249(uint8 data) { mmio.brf[ 9] = data; } -void SA1::mmio_w224a(uint8 data) { mmio.brf[10] = data; } -void SA1::mmio_w224b(uint8 data) { mmio.brf[11] = data; } -void SA1::mmio_w224c(uint8 data) { mmio.brf[12] = data; } -void SA1::mmio_w224d(uint8 data) { mmio.brf[13] = data; } -void SA1::mmio_w224e(uint8 data) { mmio.brf[14] = data; } -void SA1::mmio_w224f(uint8 data) { mmio.brf[15] = data; - if(mmio.dmaen == true) { - if(mmio.cden == 1 && mmio.cdsel == 0) { - dma_cc2(); - } - } -} - -//(MCNT) arithmetic control -void SA1::mmio_w2250(uint8 data) { - mmio.acm = (data & 0x02); - mmio.md = (data & 0x01); - - if(mmio.acm) mmio.mr = 0; -} - -//(MAL) multiplicand / dividend low -void SA1::mmio_w2251(uint8 data) { - mmio.ma = (mmio.ma & 0xff00) | data; -} - -//(MAH) multiplicand / dividend high -void SA1::mmio_w2252(uint8 data) { - mmio.ma = (data << 8) | (mmio.ma & 0x00ff); -} - -//(MBL) multiplier / divisor low -void SA1::mmio_w2253(uint8 data) { - mmio.mb = (mmio.mb & 0xff00) | data; -} - -//(MBH) multiplier / divisor high -//multiplication / cumulative sum only resets MB -//division resets both MA and MB -void SA1::mmio_w2254(uint8 data) { - mmio.mb = (data << 8) | (mmio.mb & 0x00ff); - - if(mmio.acm == 0) { - if(mmio.md == 0) { - //signed multiplication - mmio.mr = (int16)mmio.ma * (int16)mmio.mb; - mmio.mb = 0; - } else { - //unsigned division - if(mmio.mb == 0) { - mmio.mr = 0; - } else { - int16 quotient = (int16)mmio.ma / (uint16)mmio.mb; - uint16 remainder = (int16)mmio.ma % (uint16)mmio.mb; - mmio.mr = (remainder << 16) | quotient; - } - mmio.ma = 0; - mmio.mb = 0; - } - } else { - //sigma (accumulative multiplication) - mmio.mr += (int16)mmio.ma * (int16)mmio.mb; - mmio.overflow = (mmio.mr >= (1ULL << 40)); - mmio.mr &= (1ULL << 40) - 1; - mmio.mb = 0; - } -} - -//(VBD) variable-length bit processing -void SA1::mmio_w2258(uint8 data) { - mmio.hl = (data & 0x80); - mmio.vb = (data & 0x0f); - if(mmio.vb == 0) mmio.vb = 16; - - if(mmio.hl == 0) { - //fixed mode - mmio.vbit += mmio.vb; - mmio.va += (mmio.vbit >> 3); - mmio.vbit &= 7; - } -} - -//(VDA) variable-length bit game pak ROM start address -void SA1::mmio_w2259(uint8 data) { mmio.va = (mmio.va & 0xffff00) | (data << 0); } -void SA1::mmio_w225a(uint8 data) { mmio.va = (mmio.va & 0xff00ff) | (data << 8); } -void SA1::mmio_w225b(uint8 data) { mmio.va = (mmio.va & 0x00ffff) | (data << 16); mmio.vbit = 0; } - -//(SFR) S-CPU flag read -uint8 SA1::mmio_r2300() { - uint8 data; - data = mmio.cpu_irqfl << 7; - data |= mmio.cpu_ivsw << 6; - data |= mmio.chdma_irqfl << 5; - data |= mmio.cpu_nvsw << 4; - data |= mmio.cmeg; - return data; -} - -//(CFR) SA-1 flag read -uint8 SA1::mmio_r2301() { - uint8 data; - data = mmio.sa1_irqfl << 7; - data |= mmio.timer_irqfl << 6; - data |= mmio.dma_irqfl << 5; - data |= mmio.sa1_nmifl << 4; - data |= mmio.smeg; - return data; -} - -//(HCR) hcounter read -uint8 SA1::mmio_r2302() { - //latch counters - mmio.hcr = status.hcounter >> 2; - mmio.vcr = status.vcounter; - return mmio.hcr >> 0; } -uint8 SA1::mmio_r2303() { return mmio.hcr >> 8; } - -//(VCR) vcounter read -uint8 SA1::mmio_r2304() { return mmio.vcr >> 0; } -uint8 SA1::mmio_r2305() { return mmio.vcr >> 8; } - -//(MR) arithmetic result -uint8 SA1::mmio_r2306() { return mmio.mr >> 0; } -uint8 SA1::mmio_r2307() { return mmio.mr >> 8; } -uint8 SA1::mmio_r2308() { return mmio.mr >> 16; } -uint8 SA1::mmio_r2309() { return mmio.mr >> 24; } -uint8 SA1::mmio_r230a() { return mmio.mr >> 32; } - -//(OF) arithmetic overflow flag -uint8 SA1::mmio_r230b() { return mmio.overflow << 7; } - -//(VDPL) variable-length data read port low -uint8 SA1::mmio_r230c() { - uint32 data = (vbrbus.read(mmio.va + 0) << 0) - | (vbrbus.read(mmio.va + 1) << 8) - | (vbrbus.read(mmio.va + 2) << 16); - data >>= mmio.vbit; - return data >> 0; -} - -//(VDPH) variable-length data read port high -uint8 SA1::mmio_r230d() { - uint32 data = (vbrbus.read(mmio.va + 0) << 0) - | (vbrbus.read(mmio.va + 1) << 8) - | (vbrbus.read(mmio.va + 2) << 16); - data >>= mmio.vbit; - - if(mmio.hl == 1) { - //auto-increment mode - mmio.vbit += mmio.vb; - mmio.va += (mmio.vbit >> 3); - mmio.vbit &= 7; - } - - return data >> 8; -} - -//(VC) version code register -uint8 SA1::mmio_r230e() { - return 0x01; //true value unknown -} - -uint8 SA1::mmio_read(unsigned addr) { - (co_active() == cpu.thread ? cpu.synchronize_coprocessor() : synchronize_cpu()); - addr &= 0xffff; - - switch(addr) { - case 0x2300: return mmio_r2300(); - case 0x2301: return mmio_r2301(); - case 0x2302: return mmio_r2302(); - case 0x2303: return mmio_r2303(); - case 0x2304: return mmio_r2304(); - case 0x2305: return mmio_r2305(); - case 0x2306: return mmio_r2306(); - case 0x2307: return mmio_r2307(); - case 0x2308: return mmio_r2308(); - case 0x2309: return mmio_r2309(); - case 0x230a: return mmio_r230a(); - case 0x230b: return mmio_r230b(); - case 0x230c: return mmio_r230c(); - case 0x230d: return mmio_r230d(); - case 0x230e: return mmio_r230e(); - } - - return 0x00; -} - -void SA1::mmio_write(unsigned addr, uint8 data) { - (co_active() == cpu.thread ? cpu.synchronize_coprocessor() : synchronize_cpu()); - addr &= 0xffff; - - switch(addr) { - case 0x2200: return mmio_w2200(data); - case 0x2201: return mmio_w2201(data); - case 0x2202: return mmio_w2202(data); - case 0x2203: return mmio_w2203(data); - case 0x2204: return mmio_w2204(data); - case 0x2205: return mmio_w2205(data); - case 0x2206: return mmio_w2206(data); - case 0x2207: return mmio_w2207(data); - case 0x2208: return mmio_w2208(data); - case 0x2209: return mmio_w2209(data); - case 0x220a: return mmio_w220a(data); - case 0x220b: return mmio_w220b(data); - case 0x220c: return mmio_w220c(data); - case 0x220d: return mmio_w220d(data); - case 0x220e: return mmio_w220e(data); - case 0x220f: return mmio_w220f(data); - - case 0x2210: return mmio_w2210(data); - case 0x2211: return mmio_w2211(data); - case 0x2212: return mmio_w2212(data); - case 0x2213: return mmio_w2213(data); - case 0x2214: return mmio_w2214(data); - case 0x2215: return mmio_w2215(data); - - case 0x2220: return mmio_w2220(data); - case 0x2221: return mmio_w2221(data); - case 0x2222: return mmio_w2222(data); - case 0x2223: return mmio_w2223(data); - case 0x2224: return mmio_w2224(data); - case 0x2225: return mmio_w2225(data); - case 0x2226: return mmio_w2226(data); - case 0x2227: return mmio_w2227(data); - case 0x2228: return mmio_w2228(data); - case 0x2229: return mmio_w2229(data); - case 0x222a: return mmio_w222a(data); - - case 0x2230: return mmio_w2230(data); - case 0x2231: return mmio_w2231(data); - case 0x2232: return mmio_w2232(data); - case 0x2233: return mmio_w2233(data); - case 0x2234: return mmio_w2234(data); - case 0x2235: return mmio_w2235(data); - case 0x2236: return mmio_w2236(data); - case 0x2237: return mmio_w2237(data); - case 0x2238: return mmio_w2238(data); - case 0x2239: return mmio_w2239(data); - - case 0x223f: return mmio_w223f(data); - case 0x2240: return mmio_w2240(data); - case 0x2241: return mmio_w2241(data); - case 0x2242: return mmio_w2242(data); - case 0x2243: return mmio_w2243(data); - case 0x2244: return mmio_w2244(data); - case 0x2245: return mmio_w2245(data); - case 0x2246: return mmio_w2246(data); - case 0x2247: return mmio_w2247(data); - case 0x2248: return mmio_w2248(data); - case 0x2249: return mmio_w2249(data); - case 0x224a: return mmio_w224a(data); - case 0x224b: return mmio_w224b(data); - case 0x224c: return mmio_w224c(data); - case 0x224d: return mmio_w224d(data); - case 0x224e: return mmio_w224e(data); - case 0x224f: return mmio_w224f(data); - - case 0x2250: return mmio_w2250(data); - case 0x2251: return mmio_w2251(data); - case 0x2252: return mmio_w2252(data); - case 0x2253: return mmio_w2253(data); - case 0x2254: return mmio_w2254(data); - - case 0x2258: return mmio_w2258(data); - case 0x2259: return mmio_w2259(data); - case 0x225a: return mmio_w225a(data); - case 0x225b: return mmio_w225b(data); - } -} - -#endif diff --git a/bsnes/chip/sa1/mmio/mmio.hpp b/bsnes/chip/sa1/mmio/mmio.hpp deleted file mode 100755 index e63ad1fa..00000000 --- a/bsnes/chip/sa1/mmio/mmio.hpp +++ /dev/null @@ -1,256 +0,0 @@ -uint8 mmio_read(unsigned addr); -void mmio_write(unsigned addr, uint8 data); -Memory& mmio_access(unsigned &addr); - -struct MMIO { - //$2200 CCNT - bool sa1_irq; - bool sa1_rdyb; - bool sa1_resb; - bool sa1_nmi; - uint8 smeg; - - //$2201 SIE - bool cpu_irqen; - bool chdma_irqen; - - //$2202 SIC - bool cpu_irqcl; - bool chdma_irqcl; - - //$2203,$2204 CRV - uint16 crv; - - //$2205,$2206 CNV - uint16 cnv; - - //$2207,$2208 CIV - uint16 civ; - - //$2209 SCNT - bool cpu_irq; - bool cpu_ivsw; - bool cpu_nvsw; - uint8 cmeg; - - //$220a CIE - bool sa1_irqen; - bool timer_irqen; - bool dma_irqen; - bool sa1_nmien; - - //$220b CIC - bool sa1_irqcl; - bool timer_irqcl; - bool dma_irqcl; - bool sa1_nmicl; - - //$220c,$220d SNV - uint16 snv; - - //$220e,$220f SIV - uint16 siv; - - //$2210 TMC - bool hvselb; - bool ven; - bool hen; - - //$2212,$2213 - uint16 hcnt; - - //$2214,$2215 - uint16 vcnt; - - //$2220 CXB - bool cbmode; - uint8 cb; - - //$2221 DXB - bool dbmode; - uint8 db; - - //$2222 EXB - bool ebmode; - uint8 eb; - - //$2223 FXB - bool fbmode; - uint8 fb; - - //$2224 BMAPS - uint8 sbm; - - //$2225 BMAP - bool sw46; - uint8 cbm; - - //$2226 SBWE - bool swen; - - //$2227 CBWE - bool cwen; - - //$2228 BWPA - uint8 bwp; - - //$2229 SIWP - uint8 siwp; - - //$222a CIWP - uint8 ciwp; - - //$2230 DCNT - bool dmaen; - bool dprio; - bool cden; - bool cdsel; - bool dd; - uint8 sd; - - //$2231 CDMA - bool chdend; - uint8 dmasize; - uint8 dmacb; - - //$2232-$2234 SDA - uint32 dsa; - - //$2235-$2237 DDA - uint32 dda; - - //$2238,$2239 DTC - uint16 dtc; - - //$223f BBF - bool bbf; - - //$2240-224f BRF - uint8 brf[16]; - - //$2250 MCNT - bool acm; - bool md; - - //$2251,$2252 MA - uint16 ma; - - //$2253,$2254 MB - uint16 mb; - - //$2258 VBD - bool hl; - uint8 vb; - - //$2259-$225b VDA - uint32 va; - uint8 vbit; - - //$2300 SFR - bool cpu_irqfl; - bool chdma_irqfl; - - //$2301 CFR - bool sa1_irqfl; - bool timer_irqfl; - bool dma_irqfl; - bool sa1_nmifl; - - //$2302,$2303 HCR - uint16 hcr; - - //$2304,$2305 VCR - uint16 vcr; - - //$2306-230a MR - uint64 mr; - - //$230b OF - bool overflow; -} mmio; - -void mmio_w2200(uint8); //CCNT -void mmio_w2201(uint8); //SIE -void mmio_w2202(uint8); //SIC -void mmio_w2203(uint8); //CRVL -void mmio_w2204(uint8); //CRVH -void mmio_w2205(uint8); //CNVL -void mmio_w2206(uint8); //CNVH -void mmio_w2207(uint8); //CIVL -void mmio_w2208(uint8); //CIVH -void mmio_w2209(uint8); //SCNT -void mmio_w220a(uint8); //CIE -void mmio_w220b(uint8); //CIC -void mmio_w220c(uint8); //SNVL -void mmio_w220d(uint8); //SNVH -void mmio_w220e(uint8); //SIVL -void mmio_w220f(uint8); //SIVH -void mmio_w2210(uint8); //TMC -void mmio_w2211(uint8); //CTR -void mmio_w2212(uint8); //HCNTL -void mmio_w2213(uint8); //HCNTH -void mmio_w2214(uint8); //VCNTL -void mmio_w2215(uint8); //VCNTH -void mmio_w2220(uint8); //CXB -void mmio_w2221(uint8); //DXB -void mmio_w2222(uint8); //EXB -void mmio_w2223(uint8); //FXB -void mmio_w2224(uint8); //BMAPS -void mmio_w2225(uint8); //BMAP -void mmio_w2226(uint8); //SBWE -void mmio_w2227(uint8); //CBWE -void mmio_w2228(uint8); //BWPA -void mmio_w2229(uint8); //SIWP -void mmio_w222a(uint8); //CIWP -void mmio_w2230(uint8); //DCNT -void mmio_w2231(uint8); //CDMA -void mmio_w2232(uint8); //SDAL -void mmio_w2233(uint8); //SDAH -void mmio_w2234(uint8); //SDAB -void mmio_w2235(uint8); //DDAL -void mmio_w2236(uint8); //DDAH -void mmio_w2237(uint8); //DDAB -void mmio_w2238(uint8); //DTCL -void mmio_w2239(uint8); //DTCH -void mmio_w223f(uint8); //BBF -void mmio_w2240(uint8); //BRF0 -void mmio_w2241(uint8); //BRF1 -void mmio_w2242(uint8); //BRF2 -void mmio_w2243(uint8); //BRF3 -void mmio_w2244(uint8); //BRF4 -void mmio_w2245(uint8); //BRF5 -void mmio_w2246(uint8); //BRF6 -void mmio_w2247(uint8); //BRF7 -void mmio_w2248(uint8); //BRF8 -void mmio_w2249(uint8); //BRF9 -void mmio_w224a(uint8); //BRFA -void mmio_w224b(uint8); //BRFB -void mmio_w224c(uint8); //BRFC -void mmio_w224d(uint8); //BRFD -void mmio_w224e(uint8); //BRFE -void mmio_w224f(uint8); //BRFF -void mmio_w2250(uint8); //MCNT -void mmio_w2251(uint8); //MAL -void mmio_w2252(uint8); //MAH -void mmio_w2253(uint8); //MBL -void mmio_w2254(uint8); //MBH -void mmio_w2258(uint8); //VBD -void mmio_w2259(uint8); //VDAL -void mmio_w225a(uint8); //VDAH -void mmio_w225b(uint8); //VDAB - -uint8 mmio_r2300(); //SFR -uint8 mmio_r2301(); //CFR -uint8 mmio_r2302(); //HCRL -uint8 mmio_r2303(); //HCRH -uint8 mmio_r2304(); //VCRL -uint8 mmio_r2305(); //VCRH -uint8 mmio_r2306(); //MR [00-07] -uint8 mmio_r2307(); //MR [08-15] -uint8 mmio_r2308(); //MR [16-23] -uint8 mmio_r2309(); //MR [24-31] -uint8 mmio_r230a(); //MR [32-40] -uint8 mmio_r230b(); //OF -uint8 mmio_r230c(); //VDPL -uint8 mmio_r230d(); //VDPH -uint8 mmio_r230e(); //VC diff --git a/bsnes/chip/sa1/sa1.cpp b/bsnes/chip/sa1/sa1.cpp deleted file mode 100755 index 5c24a1f7..00000000 --- a/bsnes/chip/sa1/sa1.cpp +++ /dev/null @@ -1,329 +0,0 @@ -#include - -#define SA1_CPP -namespace SNES { - -SA1 sa1; - -#include "serialization.cpp" -#include "bus/bus.cpp" -#include "dma/dma.cpp" -#include "memory/memory.cpp" -#include "mmio/mmio.cpp" - -void SA1::Enter() { sa1.enter(); } - -void SA1::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(mmio.sa1_rdyb || mmio.sa1_resb) { - //SA-1 co-processor is asleep - tick(); - synchronize_cpu(); - continue; - } - - if(status.interrupt_pending) { - status.interrupt_pending = false; - interrupt(status.interrupt_vector); - } - - (this->*opcode_table[op_readpc()])(); - } -} - -void SA1::last_cycle() { - if(mmio.sa1_nmi && !mmio.sa1_nmicl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.cnv; - mmio.sa1_nmifl = true; - mmio.sa1_nmicl = 1; - regs.wai = false; - } else if(!regs.p.i) { - if(mmio.timer_irqen && !mmio.timer_irqcl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.civ; - mmio.timer_irqfl = true; - regs.wai = false; - } else if(mmio.dma_irqen && !mmio.dma_irqcl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.civ; - mmio.dma_irqfl = true; - regs.wai = false; - } else if(mmio.sa1_irq && !mmio.sa1_irqcl) { - status.interrupt_pending = true; - status.interrupt_vector = mmio.civ; - mmio.sa1_irqfl = true; - regs.wai = false; - } - } -} - -void SA1::interrupt(uint16 vector) { - SA1::op_read(regs.pc.d); - SA1::op_io(); - if(!regs.e) op_writestack(regs.pc.b); - op_writestack(regs.pc.h); - op_writestack(regs.pc.l); - op_writestack(regs.e ? (regs.p & ~0x10) : regs.p); - regs.pc.w = vector; - regs.pc.b = 0x00; - regs.p.i = 1; - regs.p.d = 0; -} - -bool SA1::interrupt_pending() { - return status.interrupt_pending; -} - -void SA1::tick() { - step(2); - if(++status.tick_counter == 0) synchronize_cpu(); - - //adjust counters: - //note that internally, status counters are in clocks; - //whereas MMIO register counters are in dots (4 clocks = 1 dot) - if(mmio.hvselb == 0) { - //HV timer - status.hcounter += 2; - if(status.hcounter >= 1364) { - status.hcounter = 0; - if(++status.vcounter >= status.scanlines) status.vcounter = 0; - } - } else { - //linear timer - status.hcounter += 2; - status.vcounter += (status.hcounter >> 11); - status.hcounter &= 0x07ff; - status.vcounter &= 0x01ff; - } - - //test counters for timer IRQ - switch((mmio.ven << 1) + (mmio.hen << 0)) { - case 0: break; - case 1: if(status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break; - case 2: if(status.vcounter == mmio.vcnt && status.hcounter == 0) trigger_irq(); break; - case 3: if(status.vcounter == mmio.hcnt && status.hcounter == (mmio.hcnt << 2)) trigger_irq(); break; - } -} - -void SA1::trigger_irq() { - mmio.timer_irqfl = true; - if(mmio.timer_irqen) mmio.timer_irqcl = 0; -} - -void SA1::init() { -} - -void SA1::enable() { -} - -void SA1::power() { - regs.a = regs.x = regs.y = 0x0000; - regs.s = 0x01ff; - vbrbus.init(); - sa1bus.init(); - reset(); -} - -void SA1::reset() { - create(SA1::Enter, system.cpu_frequency()); - - memory::cc1bwram.dma = false; - for(unsigned addr = 0; addr < memory::iram.size(); addr++) { - memory::iram.write(addr, 0x00); - } - - regs.pc.d = 0x000000; - regs.x.h = 0x00; - regs.y.h = 0x00; - regs.s.h = 0x01; - regs.d = 0x0000; - regs.db = 0x00; - regs.p = 0x34; - regs.e = 1; - regs.mdr = 0x00; - regs.wai = false; - CPUcore::update_table(); - - status.tick_counter = 0; - - status.interrupt_pending = false; - status.interrupt_vector = 0x0000; - - status.scanlines = (system.region() == System::Region::NTSC ? 262 : 312); - status.vcounter = 0; - status.hcounter = 0; - - dma.line = 0; - - //$2200 CCNT - mmio.sa1_irq = false; - mmio.sa1_rdyb = false; - mmio.sa1_resb = true; - mmio.sa1_nmi = false; - mmio.smeg = 0; - - //$2201 SIE - mmio.cpu_irqen = false; - mmio.chdma_irqen = false; - - //$2202 SIC - mmio.cpu_irqcl = false; - mmio.chdma_irqcl = false; - - //$2203,$2204 CRV - mmio.crv = 0x0000; - - //$2205,$2206 CNV - mmio.cnv = 0x0000; - - //$2207,$2208 CIV - mmio.civ = 0x0000; - - //$2209 SCNT - mmio.cpu_irq = false; - mmio.cpu_ivsw = false; - mmio.cpu_nvsw = false; - mmio.cmeg = 0; - - //$220a CIE - mmio.sa1_irqen = false; - mmio.timer_irqen = false; - mmio.dma_irqen = false; - mmio.sa1_nmien = false; - - //$220b CIC - mmio.sa1_irqcl = false; - mmio.timer_irqcl = false; - mmio.dma_irqcl = false; - mmio.sa1_nmicl = false; - - //$220c,$220d SNV - mmio.snv = 0x0000; - - //$220e,$220f SIV - mmio.siv = 0x0000; - - //$2210 - mmio.hvselb = false; - mmio.ven = false; - mmio.hen = false; - - //$2212,$2213 HCNT - mmio.hcnt = 0x0000; - - //$2214,$2215 VCNT - mmio.vcnt = 0x0000; - - //$2220-2223 CXB, DXB, EXB, FXB - mmio.cbmode = 0; - mmio.dbmode = 0; - mmio.ebmode = 0; - mmio.fbmode = 0; - - mmio.cb = 0x00; - mmio.db = 0x01; - mmio.eb = 0x02; - mmio.fb = 0x03; - - //$2224 BMAPS - mmio.sbm = 0x00; - - //$2225 BMAP - mmio.sw46 = false; - mmio.cbm = 0x00; - - //$2226 SWBE - mmio.swen = false; - - //$2227 CWBE - mmio.cwen = false; - - //$2228 BWPA - mmio.bwp = 0x0f; - - //$2229 SIWP - mmio.siwp = 0x00; - - //$222a CIWP - mmio.ciwp = 0x00; - - //$2230 DCNT - mmio.dmaen = false; - mmio.dprio = false; - mmio.cden = false; - mmio.cdsel = false; - mmio.dd = 0; - mmio.sd = 0; - - //$2231 CDMA - mmio.chdend = false; - mmio.dmasize = 0; - mmio.dmacb = 0; - - //$2232-$2234 SDA - mmio.dsa = 0x000000; - - //$2235-$2237 DDA - mmio.dda = 0x000000; - - //$2238,$2239 DTC - mmio.dtc = 0x0000; - - //$223f BBF - mmio.bbf = 0; - - //$2240-$224f BRF - for(unsigned i = 0; i < 16; i++) { - mmio.brf[i] = 0x00; - } - - //$2250 MCNT - mmio.acm = 0; - mmio.md = 0; - - //$2251,$2252 MA - mmio.ma = 0x0000; - - //$2253,$2254 MB - mmio.mb = 0x0000; - - //$2258 VBD - mmio.hl = false; - mmio.vb = 16; - - //$2259-$225b - mmio.va = 0x000000; - mmio.vbit = 0; - - //$2300 SFR - mmio.cpu_irqfl = false; - mmio.chdma_irqfl = false; - - //$2301 CFR - mmio.sa1_irqfl = false; - mmio.timer_irqfl = false; - mmio.dma_irqfl = false; - mmio.sa1_nmifl = false; - - //$2302,$2303 HCR - mmio.hcr = 0x0000; - - //$2304,$2305 VCR - mmio.vcr = 0x0000; - - //$2306-$230a MR - mmio.mr = 0; - - //$230b - mmio.overflow = false; -} - -SA1::SA1() { -} - -} diff --git a/bsnes/chip/sa1/sa1.hpp b/bsnes/chip/sa1/sa1.hpp deleted file mode 100755 index be0597a9..00000000 --- a/bsnes/chip/sa1/sa1.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "bus/bus.hpp" - -class SA1 : public Coprocessor, public CPUcore, public MMIO { -public: - #include "dma/dma.hpp" - #include "memory/memory.hpp" - #include "mmio/mmio.hpp" - - struct Status { - uint8 tick_counter; - - bool interrupt_pending; - uint16 interrupt_vector; - - uint16 scanlines; - uint16 vcounter; - uint16 hcounter; - } status; - - static void Enter(); - void enter(); - void interrupt(uint16 vector); - void tick(); - - alwaysinline void trigger_irq(); - alwaysinline void last_cycle(); - alwaysinline bool interrupt_pending(); - - void init(); - void enable(); - void power(); - void reset(); - - void serialize(serializer&); - SA1(); -}; - -extern SA1 sa1; -extern SA1Bus sa1bus; diff --git a/bsnes/chip/sa1/serialization.cpp b/bsnes/chip/sa1/serialization.cpp deleted file mode 100755 index 032be0bd..00000000 --- a/bsnes/chip/sa1/serialization.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#ifdef SA1_CPP - -void SA1::serialize(serializer &s) { - Processor::serialize(s); - CPUcore::core_serialize(s); - - //sa1.hpp - s.integer(status.tick_counter); - - s.integer(status.interrupt_pending); - s.integer(status.interrupt_vector); - - s.integer(status.scanlines); - s.integer(status.vcounter); - s.integer(status.hcounter); - - //bus/bus.hpp - s.array(memory::iram.data(), memory::iram.size()); - - s.integer(memory::cc1bwram.dma); - - //dma/dma.hpp - s.integer(dma.line); - - //mmio/mmio.hpp - s.integer(mmio.sa1_irq); - s.integer(mmio.sa1_rdyb); - s.integer(mmio.sa1_resb); - s.integer(mmio.sa1_nmi); - s.integer(mmio.smeg); - - s.integer(mmio.cpu_irqen); - s.integer(mmio.chdma_irqen); - - s.integer(mmio.cpu_irqcl); - s.integer(mmio.chdma_irqcl); - - s.integer(mmio.crv); - - s.integer(mmio.cnv); - - s.integer(mmio.civ); - - s.integer(mmio.cpu_irq); - s.integer(mmio.cpu_ivsw); - s.integer(mmio.cpu_nvsw); - s.integer(mmio.cmeg); - - s.integer(mmio.sa1_irqen); - s.integer(mmio.timer_irqen); - s.integer(mmio.dma_irqen); - s.integer(mmio.sa1_nmien); - - s.integer(mmio.sa1_irqcl); - s.integer(mmio.timer_irqcl); - s.integer(mmio.dma_irqcl); - s.integer(mmio.sa1_nmicl); - - s.integer(mmio.snv); - - s.integer(mmio.siv); - - s.integer(mmio.hvselb); - s.integer(mmio.ven); - s.integer(mmio.hen); - - s.integer(mmio.hcnt); - - s.integer(mmio.vcnt); - - s.integer(mmio.cbmode); - s.integer(mmio.cb); - - s.integer(mmio.dbmode); - s.integer(mmio.db); - - s.integer(mmio.ebmode); - s.integer(mmio.eb); - - s.integer(mmio.fbmode); - s.integer(mmio.fb); - - s.integer(mmio.sbm); - - s.integer(mmio.sw46); - s.integer(mmio.cbm); - - s.integer(mmio.swen); - - s.integer(mmio.cwen); - - s.integer(mmio.bwp); - - s.integer(mmio.siwp); - - s.integer(mmio.ciwp); - - s.integer(mmio.dmaen); - s.integer(mmio.dprio); - s.integer(mmio.cden); - s.integer(mmio.cdsel); - s.integer(mmio.dd); - s.integer(mmio.sd); - - s.integer(mmio.chdend); - s.integer(mmio.dmasize); - s.integer(mmio.dmacb); - - s.integer(mmio.dsa); - - s.integer(mmio.dda); - - s.integer(mmio.dtc); - - s.integer(mmio.bbf); - - s.array(mmio.brf); - - s.integer(mmio.acm); - s.integer(mmio.md); - - s.integer(mmio.ma); - - s.integer(mmio.mb); - - s.integer(mmio.hl); - s.integer(mmio.vb); - - s.integer(mmio.va); - s.integer(mmio.vbit); - - s.integer(mmio.cpu_irqfl); - s.integer(mmio.chdma_irqfl); - - s.integer(mmio.sa1_irqfl); - s.integer(mmio.timer_irqfl); - s.integer(mmio.dma_irqfl); - s.integer(mmio.sa1_nmifl); - - s.integer(mmio.hcr); - - s.integer(mmio.vcr); - - s.integer(mmio.mr); - - s.integer(mmio.overflow); -} - -#endif diff --git a/bsnes/chip/sdd1/sdd1.cpp b/bsnes/chip/sdd1/sdd1.cpp deleted file mode 100755 index 4a2eabfe..00000000 --- a/bsnes/chip/sdd1/sdd1.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include - -#define SDD1_CPP -namespace SNES { - -SDD1 sdd1; - -#include "serialization.cpp" -#include "sdd1emu.cpp" - -void SDD1::init() {} - -void SDD1::enable() { - //hook S-CPU DMA MMIO registers to gather information for struct dma[]; - //buffer address and transfer size information for use in SDD1::read() - for(unsigned i = 0x4300; i <= 0x437f; i++) { - cpu_mmio[i & 0x7f] = memory::mmio.mmio[i - 0x2000]; - memory::mmio.map(i, *this); - } -} - -void SDD1::power() { - reset(); -} - -void SDD1::reset() { - sdd1_enable = 0x00; - xfer_enable = 0x00; - - mmc[0] = 0 << 20; - mmc[1] = 1 << 20; - mmc[2] = 2 << 20; - mmc[3] = 3 << 20; - - for(unsigned i = 0; i < 8; i++) { - dma[i].addr = 0; - dma[i].size = 0; - } - - buffer.ready = false; -} - -uint8 SDD1::mmio_read(unsigned addr) { - addr &= 0xffff; - - if((addr & 0x4380) == 0x4300) { - return cpu_mmio[addr & 0x7f]->mmio_read(addr); - } - - switch(addr) { - case 0x4804: return mmc[0] >> 20; - case 0x4805: return mmc[1] >> 20; - case 0x4806: return mmc[2] >> 20; - case 0x4807: return mmc[3] >> 20; - } - - return cpu.regs.mdr; -} - -void SDD1::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if((addr & 0x4380) == 0x4300) { - unsigned channel = (addr >> 4) & 7; - switch(addr & 15) { - case 2: dma[channel].addr = (dma[channel].addr & 0xffff00) + (data << 0); break; - case 3: dma[channel].addr = (dma[channel].addr & 0xff00ff) + (data << 8); break; - case 4: dma[channel].addr = (dma[channel].addr & 0x00ffff) + (data << 16); break; - - case 5: dma[channel].size = (dma[channel].size & 0xff00) + (data << 0); break; - case 6: dma[channel].size = (dma[channel].size & 0x00ff) + (data << 8); break; - } - return cpu_mmio[addr & 0x7f]->mmio_write(addr, data); - } - - switch(addr) { - case 0x4800: sdd1_enable = data; break; - case 0x4801: xfer_enable = data; break; - - case 0x4804: mmc[0] = data << 20; break; - case 0x4805: mmc[1] = data << 20; break; - case 0x4806: mmc[2] = data << 20; break; - case 0x4807: mmc[3] = data << 20; break; - } -} - -//SDD1::read() is mapped to $[c0-ff]:[0000-ffff] -//the design is meant to be as close to the hardware design as possible, thus this code -//avoids adding S-DD1 hooks inside S-CPU::DMA emulation. -// -//the real S-DD1 cannot see $420b (DMA enable) writes, as they are not placed on the bus. -//however, $43x0-$43xf writes (DMAx channel settings) most likely do appear on the bus. -//the S-DD1 also requires fixed addresses for transfers, which wouldn't be necessary if -//it could see $420b writes (eg it would know when the transfer should begin.) -// -//the hardware needs a way to distinguish program code after $4801 writes from DMA -//decompression that follows soon after. -// -//the only plausible design for hardware would be for the S-DD1 to spy on DMAx settings, -//and begin spooling decompression on writes to $4801 that activate a channel. after that, -//it feeds decompressed data only when the ROM read address matches the DMA channel address. -// -//the actual S-DD1 transfer can occur on any channel, but it is most likely limited to -//one transfer per $420b write (for spooling purposes). however, this is not known for certain. -uint8 SDD1::read(unsigned addr) { - if(sdd1_enable & xfer_enable) { - //at least one channel has S-DD1 decompression enabled ... - for(unsigned i = 0; i < 8; i++) { - if(sdd1_enable & xfer_enable & (1 << i)) { - //S-DD1 always uses fixed transfer mode, so address will not change during transfer - if(addr == dma[i].addr) { - if(!buffer.ready) { - //first byte read for channel performs full decompression. - //this really should stream byte-by-byte, but it's not necessary since the size is known - buffer.offset = 0; - buffer.size = dma[i].size ? dma[i].size : 65536; - - //sdd1emu calls this function; it needs to access uncompressed data; - //so temporarily disable decompression mode for decompress() call. - uint8 temp = sdd1_enable; - sdd1_enable = false; - sdd1emu.decompress(addr, buffer.size, buffer.data); - sdd1_enable = temp; - - buffer.ready = true; - } - - //fetch a decompressed byte; once buffer is depleted, disable channel and invalidate buffer - uint8 data = buffer.data[(uint16)buffer.offset++]; - if(buffer.offset >= buffer.size) { - buffer.ready = false; - xfer_enable &= ~(1 << i); - } - - return data; - } //address matched - } //channel enabled - } //channel loop - } //S-DD1 decompressor enabled - - //S-DD1 decompression mode inactive; return ROM data - return memory::cartrom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff)); -} - -void SDD1::write(unsigned addr, uint8 data) { -} - -SDD1::SDD1() { -} - -SDD1::~SDD1() { -} - -} diff --git a/bsnes/chip/sdd1/sdd1.hpp b/bsnes/chip/sdd1/sdd1.hpp deleted file mode 100755 index fd95f6b9..00000000 --- a/bsnes/chip/sdd1/sdd1.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "sdd1emu.hpp" - -class SDD1 : public MMIO, public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - SDD1(); - ~SDD1(); - -private: - MMIO *cpu_mmio[0x80]; //bus spying hooks to glean information for struct dma[] - - uint8 sdd1_enable; //channel bit-mask - uint8 xfer_enable; //channel bit-mask - unsigned mmc[4]; //memory map controller ROM indices - - struct { - unsigned addr; //$43x2-$43x4 -- DMA transfer address - uint16 size; //$43x5-$43x6 -- DMA transfer size - } dma[8]; - - SDD1emu sdd1emu; - struct { - uint8 data[65536]; //pointer to decompressed S-DD1 data - uint16 offset; //read index into S-DD1 decompression buffer - unsigned size; //length of data buffer; reads decrement counter, set ready to false at 0 - bool ready; //true when data[] is valid; false to invoke sdd1emu.decompress() - } buffer; -}; - -extern SDD1 sdd1; diff --git a/bsnes/chip/sdd1/sdd1emu.cpp b/bsnes/chip/sdd1/sdd1emu.cpp deleted file mode 100755 index a7eb3646..00000000 --- a/bsnes/chip/sdd1/sdd1emu.cpp +++ /dev/null @@ -1,452 +0,0 @@ -#ifdef SDD1_CPP - -/************************************************************************ - -S-DD1'algorithm emulation code ------------------------------- - -Author: Andreas Naive -Date: August 2003 -Last update: October 2004 - -This code is Public Domain. There is no copyright holded by the author. -Said this, the author wish to explicitly emphasize his inalienable moral rights -over this piece of intelectual work and the previous research that made it -possible, as recognized by most of the copyright laws around the world. - -This code is provided 'as-is', with no warranty, expressed or implied. -No responsability is assumed by the author in connection with it. - -The author is greatly indebted with The Dumper, without whose help and -patience providing him with real S-DD1 data the research would have never been -possible. He also wish to note that in the very beggining of his research, -Neviksti had done some steps in the right direction. By last, the author is -indirectly indebted to all the people that worked and contributed in the -S-DD1 issue in the past. - -An algorithm's documentation is available as a separate document. -The implementation is obvious when the algorithm is -understood. - -************************************************************************/ - -typedef uint8 bool8; -#define SDD1_read(__addr) (sdd1.read(__addr)) - -//////////////////////////////////////////////////// - - -void SDD1_IM::prepareDecomp(uint32 in_buf) { - - byte_ptr=in_buf; - bit_count=4; - -} - -//////////////////////////////////////////////////// - - -uint8 SDD1_IM::getCodeword(uint8 code_len) { - - uint8 codeword; - uint8 comp_count; - - codeword = (SDD1_read(byte_ptr))<>(9-bit_count); - bit_count+=code_len; - } - - if (bit_count & 0x08) { - byte_ptr++; - bit_count&=0x07; - } - - return codeword; - -} - -////////////////////////////////////////////////////// - - -SDD1_GCD::SDD1_GCD(SDD1_IM *associatedIM) : - IM(associatedIM) -{ - -} - -////////////////////////////////////////////////////// - - -void SDD1_GCD::getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind) { - - const uint8 run_count[] = { - 0x00, 0x00, 0x01, 0x00, 0x03, 0x01, 0x02, 0x00, - 0x07, 0x03, 0x05, 0x01, 0x06, 0x02, 0x04, 0x00, - 0x0f, 0x07, 0x0b, 0x03, 0x0d, 0x05, 0x09, 0x01, - 0x0e, 0x06, 0x0a, 0x02, 0x0c, 0x04, 0x08, 0x00, - 0x1f, 0x0f, 0x17, 0x07, 0x1b, 0x0b, 0x13, 0x03, - 0x1d, 0x0d, 0x15, 0x05, 0x19, 0x09, 0x11, 0x01, - 0x1e, 0x0e, 0x16, 0x06, 0x1a, 0x0a, 0x12, 0x02, - 0x1c, 0x0c, 0x14, 0x04, 0x18, 0x08, 0x10, 0x00, - 0x3f, 0x1f, 0x2f, 0x0f, 0x37, 0x17, 0x27, 0x07, - 0x3b, 0x1b, 0x2b, 0x0b, 0x33, 0x13, 0x23, 0x03, - 0x3d, 0x1d, 0x2d, 0x0d, 0x35, 0x15, 0x25, 0x05, - 0x39, 0x19, 0x29, 0x09, 0x31, 0x11, 0x21, 0x01, - 0x3e, 0x1e, 0x2e, 0x0e, 0x36, 0x16, 0x26, 0x06, - 0x3a, 0x1a, 0x2a, 0x0a, 0x32, 0x12, 0x22, 0x02, - 0x3c, 0x1c, 0x2c, 0x0c, 0x34, 0x14, 0x24, 0x04, - 0x38, 0x18, 0x28, 0x08, 0x30, 0x10, 0x20, 0x00, - 0x7f, 0x3f, 0x5f, 0x1f, 0x6f, 0x2f, 0x4f, 0x0f, - 0x77, 0x37, 0x57, 0x17, 0x67, 0x27, 0x47, 0x07, - 0x7b, 0x3b, 0x5b, 0x1b, 0x6b, 0x2b, 0x4b, 0x0b, - 0x73, 0x33, 0x53, 0x13, 0x63, 0x23, 0x43, 0x03, - 0x7d, 0x3d, 0x5d, 0x1d, 0x6d, 0x2d, 0x4d, 0x0d, - 0x75, 0x35, 0x55, 0x15, 0x65, 0x25, 0x45, 0x05, - 0x79, 0x39, 0x59, 0x19, 0x69, 0x29, 0x49, 0x09, - 0x71, 0x31, 0x51, 0x11, 0x61, 0x21, 0x41, 0x01, - 0x7e, 0x3e, 0x5e, 0x1e, 0x6e, 0x2e, 0x4e, 0x0e, - 0x76, 0x36, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06, - 0x7a, 0x3a, 0x5a, 0x1a, 0x6a, 0x2a, 0x4a, 0x0a, - 0x72, 0x32, 0x52, 0x12, 0x62, 0x22, 0x42, 0x02, - 0x7c, 0x3c, 0x5c, 0x1c, 0x6c, 0x2c, 0x4c, 0x0c, - 0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, - 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, - 0x70, 0x30, 0x50, 0x10, 0x60, 0x20, 0x40, 0x00, - }; - - uint8 codeword=IM->getCodeword(code_num); - - if (codeword & 0x80) { - *LPSind=1; - *MPScount=run_count[codeword>>(code_num^0x07)]; - } - else { - *MPScount=(1<getRunCount(code_num, &MPScount, &LPSind); - - if (MPScount) { - bit=0; - MPScount--; - } - else { - bit=1; - LPSind=0; - } - - if (MPScount || LPSind) (*endOfRun)=0; - else (*endOfRun)=1; - - return bit; - -} - -///////////////////////////////////////////////// - - -SDD1_PEM::SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1, - SDD1_BG *associatedBG2, SDD1_BG *associatedBG3, - SDD1_BG *associatedBG4, SDD1_BG *associatedBG5, - SDD1_BG *associatedBG6, SDD1_BG *associatedBG7) { - - BG[0]=associatedBG0; - BG[1]=associatedBG1; - BG[2]=associatedBG2; - BG[3]=associatedBG3; - BG[4]=associatedBG4; - BG[5]=associatedBG5; - BG[6]=associatedBG6; - BG[7]=associatedBG7; - -} - -///////////////////////////////////////////////////////// - - -const SDD1_PEM::state SDD1_PEM::evolution_table[]={ - { 0,25,25}, - { 0, 2, 1}, - { 0, 3, 1}, - { 0, 4, 2}, - { 0, 5, 3}, - { 1, 6, 4}, - { 1, 7, 5}, - { 1, 8, 6}, - { 1, 9, 7}, - { 2,10, 8}, - { 2,11, 9}, - { 2,12,10}, - { 2,13,11}, - { 3,14,12}, - { 3,15,13}, - { 3,16,14}, - { 3,17,15}, - { 4,18,16}, - { 4,19,17}, - { 5,20,18}, - { 5,21,19}, - { 6,22,20}, - { 6,23,21}, - { 7,24,22}, - { 7,24,23}, - { 0,26, 1}, - { 1,27, 2}, - { 2,28, 4}, - { 3,29, 8}, - { 4,30,12}, - { 5,31,16}, - { 6,32,18}, - { 7,24,22} - }; - -////////////////////////////////////////////////////// - - -void SDD1_PEM::prepareDecomp(void) { - - for (uint8 i=0; i<32; i++) { - contextInfo[i].status=0; - contextInfo[i].MPS=0; - } - -} - -///////////////////////////////////////////////////////// - - -uint8 SDD1_PEM::getBit(uint8 context) { - - bool8 endOfRun; - uint8 bit; - - SDD1_ContextInfo *pContInfo=&contextInfo[context]; - uint8 currStatus = pContInfo->status; - const state *pState=&SDD1_PEM::evolution_table[currStatus]; - uint8 currentMPS=pContInfo->MPS; - - bit=(BG[pState->code_num])->getBit(&endOfRun); - - if (endOfRun) - if (bit) { - if (!(currStatus & 0xfe)) (pContInfo->MPS)^=0x01; - (pContInfo->status)=pState->nextIfLPS; - } - else - (pContInfo->status)=pState->nextIfMPS; - - return bit^currentMPS; - -} - -////////////////////////////////////////////////////////////// - - -SDD1_CM::SDD1_CM(SDD1_PEM *associatedPEM) : - PEM(associatedPEM) -{ - -} - -////////////////////////////////////////////////////////////// - - -void SDD1_CM::prepareDecomp(uint32 first_byte) { - - bitplanesInfo = SDD1_read(first_byte) & 0xc0; - contextBitsInfo = SDD1_read(first_byte) & 0x30; - bit_number=0; - for (int i=0; i<8; i++) prevBitplaneBits[i]=0; - switch (bitplanesInfo) { - case 0x00: - currBitplane = 1; - break; - case 0x40: - currBitplane = 7; - break; - case 0x80: - currBitplane = 3; - } - -} - -///////////////////////////////////////////////////////////// - - -uint8 SDD1_CM::getBit(void) { - - uint8 currContext; - uint16 *context_bits; - - switch (bitplanesInfo) { - case 0x00: - currBitplane ^= 0x01; - break; - case 0x40: - currBitplane ^= 0x01; - if (!(bit_number & 0x7f)) currBitplane = ((currBitplane+2) & 0x07); - break; - case 0x80: - currBitplane ^= 0x01; - if (!(bit_number & 0x7f)) currBitplane ^= 0x02; - break; - case 0xc0: - currBitplane = bit_number & 0x07; - } - - context_bits = &prevBitplaneBits[currBitplane]; - - currContext=(currBitplane & 0x01)<<4; - switch (contextBitsInfo) { - case 0x00: - currContext|=((*context_bits & 0x01c0)>>5)|(*context_bits & 0x0001); - break; - case 0x10: - currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0001); - break; - case 0x20: - currContext|=((*context_bits & 0x00c0)>>5)|(*context_bits & 0x0001); - break; - case 0x30: - currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0003); - } - - uint8 bit=PEM->getBit(currContext); - - *context_bits <<= 1; - *context_bits |= bit; - - bit_number++; - - return bit; - -} - -////////////////////////////////////////////////// - - -SDD1_OL::SDD1_OL(SDD1_CM *associatedCM) : - CM(associatedCM) -{ - -} - -/////////////////////////////////////////////////// - - -void SDD1_OL::prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf) { - - bitplanesInfo = SDD1_read(first_byte) & 0xc0; - length=out_len; - buffer=out_buf; - -} - -/////////////////////////////////////////////////// - - -void SDD1_OL::launch(void) { - - uint8 i; - uint8 register1, register2; - - switch (bitplanesInfo) { - case 0x00: - case 0x40: - case 0x80: - i=1; - do { //if length==0, we output 2^16 bytes - if (!i) { - *(buffer++)=register2; - i=~i; - } - else { - for (register1=register2=0, i=0x80; i; i>>=1) { - if (CM->getBit()) register1 |= i; - if (CM->getBit()) register2 |= i; - } - *(buffer++)=register1; - } - } while (--length); - break; - case 0xc0: - do { - for (register1=0, i=0x01; i; i<<=1) { - if (CM->getBit()) register1 |= i; - } - *(buffer++)=register1; - } while (--length); - } - -} - -/////////////////////////////////////////////////////// - - -void SDD1emu::decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf) { - - IM.prepareDecomp(in_buf); - BG0.prepareDecomp(); - BG1.prepareDecomp(); - BG2.prepareDecomp(); - BG3.prepareDecomp(); - BG4.prepareDecomp(); - BG5.prepareDecomp(); - BG6.prepareDecomp(); - BG7.prepareDecomp(); - PEM.prepareDecomp(); - CM.prepareDecomp(in_buf); - OL.prepareDecomp(in_buf, out_len, out_buf); - - OL.launch(); - -} - -//////////////////////////////////////////////////////////// - - -SDD1emu::SDD1emu() : - GCD(&IM), - BG0(&GCD, 0), BG1(&GCD, 1), BG2(&GCD, 2), BG3(&GCD, 3), - BG4(&GCD, 4), BG5(&GCD, 5), BG6(&GCD, 6), BG7(&GCD, 7), - PEM(&BG0, &BG1, &BG2, &BG3, &BG4, &BG5, &BG6, &BG7), - CM(&PEM), - OL(&CM) -{ - -} - -/////////////////////////////////////////////////////////// - -#endif diff --git a/bsnes/chip/sdd1/sdd1emu.hpp b/bsnes/chip/sdd1/sdd1emu.hpp deleted file mode 100755 index 04f82bf5..00000000 --- a/bsnes/chip/sdd1/sdd1emu.hpp +++ /dev/null @@ -1,164 +0,0 @@ -/************************************************************************ - -S-DD1'algorithm emulation code ------------------------------- - -Author: Andreas Naive -Date: August 2003 -Last update: October 2004 - -This code is Public Domain. There is no copyright holded by the author. -Said this, the author wish to explicitly emphasize his inalienable moral rights -over this piece of intelectual work and the previous research that made it -possible, as recognized by most of the copyright laws around the world. - -This code is provided 'as-is', with no warranty, expressed or implied. -No responsability is assumed by the author in connection with it. - -The author is greatly indebted with The Dumper, without whose help and -patience providing him with real S-DD1 data the research would have never been -possible. He also wish to note that in the very beggining of his research, -Neviksti had done some steps in the right direction. By last, the author is -indirectly indebted to all the people that worked and contributed in the -S-DD1 issue in the past. - -An algorithm's documentation is available as a separate document. -The implementation is obvious when the algorithm is -understood. - -************************************************************************/ - -#define bool8 uint8 - -class SDD1_IM { //Input Manager - - public: - SDD1_IM(void) {} - void prepareDecomp(uint32 in_buf); - uint8 getCodeword(const uint8 code_len); - - private: - uint32 byte_ptr; - uint8 bit_count; - -}; - -//////////////////////////////////////////////////// - - -class SDD1_GCD { //Golomb-Code Decoder - - public: - SDD1_GCD(SDD1_IM *associatedIM); - void getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind); - - private: - SDD1_IM *const IM; - -}; - -////////////////////////////////////////////////////// - - -class SDD1_BG { // Bits Generator - - public: - SDD1_BG(SDD1_GCD *associatedGCD, uint8 code); - void prepareDecomp(void); - uint8 getBit(bool8 *endOfRun); - - private: - const uint8 code_num; - uint8 MPScount; - bool8 LPSind; - SDD1_GCD *const GCD; - -}; - -//////////////////////////////////////////////// - - -class SDD1_PEM { //Probability Estimation Module - - public: - SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1, - SDD1_BG *associatedBG2, SDD1_BG *associatedBG3, - SDD1_BG *associatedBG4, SDD1_BG *associatedBG5, - SDD1_BG *associatedBG6, SDD1_BG *associatedBG7); - void prepareDecomp(void); - uint8 getBit(uint8 context); - - private: - struct state { - uint8 code_num; - uint8 nextIfMPS; - uint8 nextIfLPS; - }; - static const state evolution_table[]; - struct SDD1_ContextInfo { - uint8 status; - uint8 MPS; - } contextInfo[32]; - SDD1_BG * BG[8]; - -}; - -/////////////////////////////////////////////////// - - -class SDD1_CM { //Context Model - - public: - SDD1_CM(SDD1_PEM *associatedPEM); - void prepareDecomp(uint32 first_byte); - uint8 getBit(void); - - private: - uint8 bitplanesInfo; - uint8 contextBitsInfo; - uint8 bit_number; - uint8 currBitplane; - uint16 prevBitplaneBits[8]; - SDD1_PEM *const PEM; - -}; - -/////////////////////////////////////////////////// - - -class SDD1_OL { //Output Logic - - public: - SDD1_OL(SDD1_CM *associatedCM); - void prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf); - void launch(void); - - private: - uint8 bitplanesInfo; - uint16 length; - uint8 *buffer; - SDD1_CM *const CM; - -}; - -///////////////////////////////////////////////////////// - - -class SDD1emu { - - public: - SDD1emu(void); - void decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf); - - private: - SDD1_IM IM; - SDD1_GCD GCD; - SDD1_BG BG0; SDD1_BG BG1; SDD1_BG BG2; SDD1_BG BG3; - SDD1_BG BG4; SDD1_BG BG5; SDD1_BG BG6; SDD1_BG BG7; - SDD1_PEM PEM; - SDD1_CM CM; - SDD1_OL OL; - -}; - -#undef bool8 diff --git a/bsnes/chip/sdd1/serialization.cpp b/bsnes/chip/sdd1/serialization.cpp deleted file mode 100755 index 87da13f3..00000000 --- a/bsnes/chip/sdd1/serialization.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifdef SDD1_CPP - -void SDD1::serialize(serializer &s) { - s.integer(sdd1_enable); - s.integer(xfer_enable); - s.array(mmc); - - for(unsigned n = 0; n < 8; n++) { - s.integer(dma[n].addr); - s.integer(dma[n].size); - } - - s.array(buffer.data); - s.integer(buffer.offset); - s.integer(buffer.size); - s.integer(buffer.ready); -} - -#endif diff --git a/bsnes/chip/serial/serial.cpp b/bsnes/chip/serial/serial.cpp deleted file mode 100755 index b9404adb..00000000 --- a/bsnes/chip/serial/serial.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include - -#define SERIAL_CPP -namespace SNES { - -Serial serial; - -#include "serialization.cpp" - -static void snesserial_tick(unsigned clocks) { serial.add_clocks(clocks * 8); } -static uint8 snesserial_read() { return serial.read(); } -static void snesserial_write(uint8 data) { serial.write(data); } - -void Serial::Enter() { serial.enter(); } - -void Serial::enter() { - latch = 0; - add_clocks(256 * 8); //warm-up - if(snesserial_main) snesserial_main(snesserial_tick, snesserial_read, snesserial_write); - while(true) add_clocks(frequency); //snesserial_main() fallback -} - -void Serial::add_clocks(unsigned clocks) { - step(clocks); - synchronize_cpu(); -} - -uint8 Serial::read() { - while(cpu.joylatch() == 0) add_clocks(1); - while(cpu.joylatch() == 1) add_clocks(1); - add_clocks(4); - - uint8 data = 0; - for(unsigned i = 0; i < 8; i++) { - add_clocks(8); - data = (cpu.joylatch() << 7) | (data >> 1); - } - - return data; -} - -void Serial::write(uint8 data) { - latch = 1; - add_clocks(8); - - for(unsigned i = 0; i < 8; i++) { - latch = (data & 1) ^ 1; - data >>= 1; - add_clocks(8); - } - - latch = 0; - add_clocks(8); -} - -uint8 Serial::mmio_read(unsigned addr) { - cpu.synchronize_coprocessor(); - switch(addr & 1) { default: - case 0: return r4016->mmio_read(addr); - case 1: return r4017->mmio_read(addr); - } -} - -void Serial::mmio_write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - switch(addr & 1) { default: - case 0: r4016->mmio_write(addr, data); break; - case 1: r4017->mmio_write(addr, data); break; - } -} - -void Serial::init() { -} - -void Serial::enable() { - r4016 = memory::mmio.mmio[0x4016 - 0x2000]; - r4017 = memory::mmio.mmio[0x4017 - 0x2000]; - memory::mmio.mmio[0x4016 - 0x2000] = this; - memory::mmio.mmio[0x4017 - 0x2000] = this; - - if(opened()) close(); - string name = notdir(cartridge.basename()); - string path = dir(cartridge.basename()); - if(open(name, path)) { - snesserial_main = sym("snesserial_main"); - } -} - -void Serial::power() { - reset(); -} - -void Serial::reset() { - create(Serial::Enter, cartridge.serial_baud_rate() * 8); -} - -} diff --git a/bsnes/chip/serial/serial.hpp b/bsnes/chip/serial/serial.hpp deleted file mode 100755 index adb499ed..00000000 --- a/bsnes/chip/serial/serial.hpp +++ /dev/null @@ -1,25 +0,0 @@ -class Serial : public Coprocessor, public MMIO, public library, public property { -public: - static void Enter(); - void enter(); - void init(); - void enable(); - void power(); - void reset(); - void serialize(serializer&); - - readonly latch; - - void add_clocks(unsigned clocks); - uint8 read(); - void write(uint8 data); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - -private: - MMIO *r4016, *r4017; - function snesserial_main; -}; - -extern Serial serial; diff --git a/bsnes/chip/serial/serialization.cpp b/bsnes/chip/serial/serialization.cpp deleted file mode 100755 index 8b2a318a..00000000 --- a/bsnes/chip/serial/serialization.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef SERIAL_CPP - -void Serial::serialize(serializer &s) { - Processor::serialize(s); - s.integer((bool&)latch); -} - -#endif diff --git a/bsnes/chip/spc7110/decomp.cpp b/bsnes/chip/spc7110/decomp.cpp deleted file mode 100755 index 212fb0af..00000000 --- a/bsnes/chip/spc7110/decomp.cpp +++ /dev/null @@ -1,511 +0,0 @@ -#ifdef SPC7110_CPP - -uint8 SPC7110Decomp::read() { - if(decomp_buffer_length == 0) { - //decompress at least (decomp_buffer_size / 2) bytes to the buffer - switch(decomp_mode) { - case 0: mode0(false); break; - case 1: mode1(false); break; - case 2: mode2(false); break; - default: return 0x00; - } - } - - uint8 data = decomp_buffer[decomp_buffer_rdoffset++]; - decomp_buffer_rdoffset &= decomp_buffer_size - 1; - decomp_buffer_length--; - return data; -} - -void SPC7110Decomp::write(uint8 data) { - decomp_buffer[decomp_buffer_wroffset++] = data; - decomp_buffer_wroffset &= decomp_buffer_size - 1; - decomp_buffer_length++; -} - -uint8 SPC7110Decomp::dataread() { - unsigned size = memory::cartrom.size() - cartridge.spc7110_data_rom_offset(); - while(decomp_offset >= size) decomp_offset -= size; - return memory::cartrom.read(cartridge.spc7110_data_rom_offset() + decomp_offset++); -} - -void SPC7110Decomp::init(unsigned mode, unsigned offset, unsigned index) { - decomp_mode = mode; - decomp_offset = offset; - - decomp_buffer_rdoffset = 0; - decomp_buffer_wroffset = 0; - decomp_buffer_length = 0; - - //reset context states - for(unsigned i = 0; i < 32; i++) { - context[i].index = 0; - context[i].invert = 0; - } - - switch(decomp_mode) { - case 0: mode0(true); break; - case 1: mode1(true); break; - case 2: mode2(true); break; - } - - //decompress up to requested output data index - while(index--) read(); -} - -// - -void SPC7110Decomp::mode0(bool init) { - static uint8 val, in, span; - static int out, inverts, lps, in_count; - - if(init == true) { - out = inverts = lps = 0; - span = 0xff; - val = dataread(); - in = dataread(); - in_count = 8; - return; - } - - while(decomp_buffer_length < (decomp_buffer_size >> 1)) { - for(unsigned bit = 0; bit < 8; bit++) { - //get context - uint8 mask = (1 << (bit & 3)) - 1; - uint8 con = mask + ((inverts & mask) ^ (lps & mask)); - if(bit > 3) con += 15; - - //get prob and mps - unsigned prob = probability(con); - unsigned mps = (((out >> 15) & 1) ^ context[con].invert); - - //get bit - unsigned flag_lps; - if(val <= span - prob) { //mps - span = span - prob; - out = (out << 1) + mps; - flag_lps = 0; - } else { //lps - val = val - (span - (prob - 1)); - span = prob - 1; - out = (out << 1) + 1 - mps; - flag_lps = 1; - } - - //renormalize - unsigned shift = 0; - while(span < 0x7f) { - shift++; - - span = (span << 1) + 1; - val = (val << 1) + (in >> 7); - - in <<= 1; - if(--in_count == 0) { - in = dataread(); - in_count = 8; - } - } - - //update processing info - lps = (lps << 1) + flag_lps; - inverts = (inverts << 1) + context[con].invert; - - //update context state - if(flag_lps & toggle_invert(con)) context[con].invert ^= 1; - if(flag_lps) context[con].index = next_lps(con); - else if(shift) context[con].index = next_mps(con); - } - - //save byte - write(out); - } -} - -void SPC7110Decomp::mode1(bool init) { - static int pixelorder[4], realorder[4]; - static uint8 in, val, span; - static int out, inverts, lps, in_count; - - if(init == true) { - for(unsigned i = 0; i < 4; i++) pixelorder[i] = i; - out = inverts = lps = 0; - span = 0xff; - val = dataread(); - in = dataread(); - in_count = 8; - return; - } - - while(decomp_buffer_length < (decomp_buffer_size >> 1)) { - for(unsigned pixel = 0; pixel < 8; pixel++) { - //get first symbol context - unsigned a = ((out >> (1 * 2)) & 3); - unsigned b = ((out >> (7 * 2)) & 3); - unsigned c = ((out >> (8 * 2)) & 3); - unsigned con = (a == b) ? (b != c) : (b == c) ? 2 : 4 - (a == c); - - //update pixel order - unsigned m, n; - for(m = 0; m < 4; m++) if(pixelorder[m] == a) break; - for(n = m; n > 0; n--) pixelorder[n] = pixelorder[n - 1]; - pixelorder[0] = a; - - //calculate the real pixel order - for(m = 0; m < 4; m++) realorder[m] = pixelorder[m]; - - //rotate reference pixel c value to top - for(m = 0; m < 4; m++) if(realorder[m] == c) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = c; - - //rotate reference pixel b value to top - for(m = 0; m < 4; m++) if(realorder[m] == b) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = b; - - //rotate reference pixel a value to top - for(m = 0; m < 4; m++) if(realorder[m] == a) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = a; - - //get 2 symbols - for(unsigned bit = 0; bit < 2; bit++) { - //get prob - unsigned prob = probability(con); - - //get symbol - unsigned flag_lps; - if(val <= span - prob) { //mps - span = span - prob; - flag_lps = 0; - } else { //lps - val = val - (span - (prob - 1)); - span = prob - 1; - flag_lps = 1; - } - - //renormalize - unsigned shift = 0; - while(span < 0x7f) { - shift++; - - span = (span << 1) + 1; - val = (val << 1) + (in >> 7); - - in <<= 1; - if(--in_count == 0) { - in = dataread(); - in_count = 8; - } - } - - //update processing info - lps = (lps << 1) + flag_lps; - inverts = (inverts << 1) + context[con].invert; - - //update context state - if(flag_lps & toggle_invert(con)) context[con].invert ^= 1; - if(flag_lps) context[con].index = next_lps(con); - else if(shift) context[con].index = next_mps(con); - - //get next context - con = 5 + (con << 1) + ((lps ^ inverts) & 1); - } - - //get pixel - b = realorder[(lps ^ inverts) & 3]; - out = (out << 2) + b; - } - - //turn pixel data into bitplanes - unsigned data = morton_2x8(out); - write(data >> 8); - write(data >> 0); - } -} - -void SPC7110Decomp::mode2(bool init) { - static int pixelorder[16], realorder[16]; - static uint8 bitplanebuffer[16], buffer_index; - static uint8 in, val, span; - static int out0, out1, inverts, lps, in_count; - - if(init == true) { - for(unsigned i = 0; i < 16; i++) pixelorder[i] = i; - buffer_index = 0; - out0 = out1 = inverts = lps = 0; - span = 0xff; - val = dataread(); - in = dataread(); - in_count = 8; - return; - } - - while(decomp_buffer_length < (decomp_buffer_size >> 1)) { - for(unsigned pixel = 0; pixel < 8; pixel++) { - //get first symbol context - unsigned a = ((out0 >> (0 * 4)) & 15); - unsigned b = ((out0 >> (7 * 4)) & 15); - unsigned c = ((out1 >> (0 * 4)) & 15); - unsigned con = 0; - unsigned refcon = (a == b) ? (b != c) : (b == c) ? 2 : 4 - (a == c); - - //update pixel order - unsigned m, n; - for(m = 0; m < 16; m++) if(pixelorder[m] == a) break; - for(n = m; n > 0; n--) pixelorder[n] = pixelorder[n - 1]; - pixelorder[0] = a; - - //calculate the real pixel order - for(m = 0; m < 16; m++) realorder[m] = pixelorder[m]; - - //rotate reference pixel c value to top - for(m = 0; m < 16; m++) if(realorder[m] == c) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = c; - - //rotate reference pixel b value to top - for(m = 0; m < 16; m++) if(realorder[m] == b) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = b; - - //rotate reference pixel a value to top - for(m = 0; m < 16; m++) if(realorder[m] == a) break; - for(n = m; n > 0; n--) realorder[n] = realorder[n - 1]; - realorder[0] = a; - - //get 4 symbols - for(unsigned bit = 0; bit < 4; bit++) { - //get prob - unsigned prob = probability(con); - - //get symbol - unsigned flag_lps; - if(val <= span - prob) { //mps - span = span - prob; - flag_lps = 0; - } else { //lps - val = val - (span - (prob - 1)); - span = prob - 1; - flag_lps = 1; - } - - //renormalize - unsigned shift = 0; - while(span < 0x7f) { - shift++; - - span = (span << 1) + 1; - val = (val << 1) + (in >> 7); - - in <<= 1; - if(--in_count == 0) { - in = dataread(); - in_count = 8; - } - } - - //update processing info - lps = (lps << 1) + flag_lps; - unsigned invertbit = context[con].invert; - inverts = (inverts << 1) + invertbit; - - //update context state - if(flag_lps & toggle_invert(con)) context[con].invert ^= 1; - if(flag_lps) context[con].index = next_lps(con); - else if(shift) context[con].index = next_mps(con); - - //get next context - con = mode2_context_table[con][flag_lps ^ invertbit] + (con == 1 ? refcon : 0); - } - - //get pixel - b = realorder[(lps ^ inverts) & 0x0f]; - out1 = (out1 << 4) + ((out0 >> 28) & 0x0f); - out0 = (out0 << 4) + b; - } - - //convert pixel data into bitplanes - unsigned data = morton_4x8(out0); - write(data >> 24); - write(data >> 16); - bitplanebuffer[buffer_index++] = data >> 8; - bitplanebuffer[buffer_index++] = data >> 0; - - if(buffer_index == 16) { - for(unsigned i = 0; i < 16; i++) write(bitplanebuffer[i]); - buffer_index = 0; - } - } -} - -// - -const uint8 SPC7110Decomp::evolution_table[53][4] = { -//{ prob, nextlps, nextmps, toggle invert }, - - { 0x5a, 1, 1, 1 }, - { 0x25, 6, 2, 0 }, - { 0x11, 8, 3, 0 }, - { 0x08, 10, 4, 0 }, - { 0x03, 12, 5, 0 }, - { 0x01, 15, 5, 0 }, - - { 0x5a, 7, 7, 1 }, - { 0x3f, 19, 8, 0 }, - { 0x2c, 21, 9, 0 }, - { 0x20, 22, 10, 0 }, - { 0x17, 23, 11, 0 }, - { 0x11, 25, 12, 0 }, - { 0x0c, 26, 13, 0 }, - { 0x09, 28, 14, 0 }, - { 0x07, 29, 15, 0 }, - { 0x05, 31, 16, 0 }, - { 0x04, 32, 17, 0 }, - { 0x03, 34, 18, 0 }, - { 0x02, 35, 5, 0 }, - - { 0x5a, 20, 20, 1 }, - { 0x48, 39, 21, 0 }, - { 0x3a, 40, 22, 0 }, - { 0x2e, 42, 23, 0 }, - { 0x26, 44, 24, 0 }, - { 0x1f, 45, 25, 0 }, - { 0x19, 46, 26, 0 }, - { 0x15, 25, 27, 0 }, - { 0x11, 26, 28, 0 }, - { 0x0e, 26, 29, 0 }, - { 0x0b, 27, 30, 0 }, - { 0x09, 28, 31, 0 }, - { 0x08, 29, 32, 0 }, - { 0x07, 30, 33, 0 }, - { 0x05, 31, 34, 0 }, - { 0x04, 33, 35, 0 }, - { 0x04, 33, 36, 0 }, - { 0x03, 34, 37, 0 }, - { 0x02, 35, 38, 0 }, - { 0x02, 36, 5, 0 }, - - { 0x58, 39, 40, 1 }, - { 0x4d, 47, 41, 0 }, - { 0x43, 48, 42, 0 }, - { 0x3b, 49, 43, 0 }, - { 0x34, 50, 44, 0 }, - { 0x2e, 51, 45, 0 }, - { 0x29, 44, 46, 0 }, - { 0x25, 45, 24, 0 }, - - { 0x56, 47, 48, 1 }, - { 0x4f, 47, 49, 0 }, - { 0x47, 48, 50, 0 }, - { 0x41, 49, 51, 0 }, - { 0x3c, 50, 52, 0 }, - { 0x37, 51, 43, 0 }, -}; - -const uint8 SPC7110Decomp::mode2_context_table[32][2] = { -//{ next 0, next 1 }, - - { 1, 2 }, - - { 3, 8 }, - { 13, 14 }, - - { 15, 16 }, - { 17, 18 }, - { 19, 20 }, - { 21, 22 }, - { 23, 24 }, - { 25, 26 }, - { 25, 26 }, - { 25, 26 }, - { 25, 26 }, - { 25, 26 }, - { 27, 28 }, - { 29, 30 }, - - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - { 31, 31 }, - - { 31, 31 }, -}; - -uint8 SPC7110Decomp::probability (unsigned n) { return evolution_table[context[n].index][0]; } -uint8 SPC7110Decomp::next_lps (unsigned n) { return evolution_table[context[n].index][1]; } -uint8 SPC7110Decomp::next_mps (unsigned n) { return evolution_table[context[n].index][2]; } -bool SPC7110Decomp::toggle_invert(unsigned n) { return evolution_table[context[n].index][3]; } - -unsigned SPC7110Decomp::morton_2x8(unsigned data) { - //reverse morton lookup: de-interleave two 8-bit values - //15, 13, 11, 9, 7, 5, 3, 1 -> 15- 8 - //14, 12, 10, 8, 6, 4, 2, 0 -> 7- 0 - return morton16[0][(data >> 0) & 255] + morton16[1][(data >> 8) & 255]; -} - -unsigned SPC7110Decomp::morton_4x8(unsigned data) { - //reverse morton lookup: de-interleave four 8-bit values - //31, 27, 23, 19, 15, 11, 7, 3 -> 31-24 - //30, 26, 22, 18, 14, 10, 6, 2 -> 23-16 - //29, 25, 21, 17, 13, 9, 5, 1 -> 15- 8 - //28, 24, 20, 16, 12, 8, 4, 0 -> 7- 0 - return morton32[0][(data >> 0) & 255] + morton32[1][(data >> 8) & 255] - + morton32[2][(data >> 16) & 255] + morton32[3][(data >> 24) & 255]; -} - -// - -void SPC7110Decomp::reset() { - //mode 3 is invalid; this is treated as a special case to always return 0x00 - //set to mode 3 so that reading decomp port before starting first decomp will return 0x00 - decomp_mode = 3; - - decomp_buffer_rdoffset = 0; - decomp_buffer_wroffset = 0; - decomp_buffer_length = 0; -} - -SPC7110Decomp::SPC7110Decomp() { - decomp_buffer = new uint8_t[decomp_buffer_size]; - reset(); - - //initialize reverse morton lookup tables - for(unsigned i = 0; i < 256; i++) { - #define map(x, y) (((i >> x) & 1) << y) - //2x8-bit - morton16[1][i] = map(7, 15) + map(6, 7) + map(5, 14) + map(4, 6) - + map(3, 13) + map(2, 5) + map(1, 12) + map(0, 4); - morton16[0][i] = map(7, 11) + map(6, 3) + map(5, 10) + map(4, 2) - + map(3, 9) + map(2, 1) + map(1, 8) + map(0, 0); - //4x8-bit - morton32[3][i] = map(7, 31) + map(6, 23) + map(5, 15) + map(4, 7) - + map(3, 30) + map(2, 22) + map(1, 14) + map(0, 6); - morton32[2][i] = map(7, 29) + map(6, 21) + map(5, 13) + map(4, 5) - + map(3, 28) + map(2, 20) + map(1, 12) + map(0, 4); - morton32[1][i] = map(7, 27) + map(6, 19) + map(5, 11) + map(4, 3) - + map(3, 26) + map(2, 18) + map(1, 10) + map(0, 2); - morton32[0][i] = map(7, 25) + map(6, 17) + map(5, 9) + map(4, 1) - + map(3, 24) + map(2, 16) + map(1, 8) + map(0, 0); - #undef map - } -} - -SPC7110Decomp::~SPC7110Decomp() { - delete[] decomp_buffer; -} - -#endif diff --git a/bsnes/chip/spc7110/decomp.hpp b/bsnes/chip/spc7110/decomp.hpp deleted file mode 100755 index 2b67605f..00000000 --- a/bsnes/chip/spc7110/decomp.hpp +++ /dev/null @@ -1,46 +0,0 @@ -class SPC7110Decomp { -public: - uint8 read(); - void init(unsigned mode, unsigned offset, unsigned index); - void reset(); - - void serialize(serializer&); - SPC7110Decomp(); - ~SPC7110Decomp(); - -private: - unsigned decomp_mode; - unsigned decomp_offset; - - //read() will spool chunks half the size of decomp_buffer_size - enum { decomp_buffer_size = 64 }; //must be >= 64, and must be a power of two - uint8 *decomp_buffer; - unsigned decomp_buffer_rdoffset; - unsigned decomp_buffer_wroffset; - unsigned decomp_buffer_length; - - void write(uint8 data); - uint8 dataread(); - - void mode0(bool init); - void mode1(bool init); - void mode2(bool init); - - static const uint8 evolution_table[53][4]; - static const uint8 mode2_context_table[32][2]; - - struct ContextState { - uint8 index; - uint8 invert; - } context[32]; - - uint8 probability(unsigned n); - uint8 next_lps(unsigned n); - uint8 next_mps(unsigned n); - bool toggle_invert(unsigned n); - - unsigned morton16[2][256]; - unsigned morton32[4][256]; - unsigned morton_2x8(unsigned data); - unsigned morton_4x8(unsigned data); -}; diff --git a/bsnes/chip/spc7110/serialization.cpp b/bsnes/chip/spc7110/serialization.cpp deleted file mode 100755 index 2e77d524..00000000 --- a/bsnes/chip/spc7110/serialization.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifdef SPC7110_CPP - -void SPC7110Decomp::serialize(serializer &s) { - s.integer(decomp_mode); - s.integer(decomp_offset); - - s.array(decomp_buffer, decomp_buffer_size); - s.integer(decomp_buffer_rdoffset); - s.integer(decomp_buffer_wroffset); - s.integer(decomp_buffer_length); - - for(unsigned n = 0; n < 32; n++) { - s.integer(context[n].index); - s.integer(context[n].invert); - } -} - -void SPC7110::serialize(serializer &s) { - s.integer(r4801); - s.integer(r4802); - s.integer(r4803); - s.integer(r4804); - s.integer(r4805); - s.integer(r4806); - s.integer(r4807); - s.integer(r4808); - s.integer(r4809); - s.integer(r480a); - s.integer(r480b); - s.integer(r480c); - decomp.serialize(s); - - s.integer(r4811); - s.integer(r4812); - s.integer(r4813); - s.integer(r4814); - s.integer(r4815); - s.integer(r4816); - s.integer(r4817); - s.integer(r4818); - s.integer(r481x); - s.integer(r4814_latch); - s.integer(r4815_latch); - - s.integer(r4820); - s.integer(r4821); - s.integer(r4822); - s.integer(r4823); - s.integer(r4824); - s.integer(r4825); - s.integer(r4826); - s.integer(r4827); - s.integer(r4828); - s.integer(r4829); - s.integer(r482a); - s.integer(r482b); - s.integer(r482c); - s.integer(r482d); - s.integer(r482e); - s.integer(r482f); - - s.integer(r4830); - s.integer(r4831); - s.integer(r4832); - s.integer(r4833); - s.integer(r4834); - - s.integer(dx_offset); - s.integer(ex_offset); - s.integer(fx_offset); - - s.integer(r4840); - s.integer(r4841); - s.integer(r4842); - - s.integer(rtc_state); - s.integer(rtc_mode); - s.integer(rtc_index); -} - -#endif diff --git a/bsnes/chip/spc7110/spc7110.cpp b/bsnes/chip/spc7110/spc7110.cpp deleted file mode 100755 index 3559a631..00000000 --- a/bsnes/chip/spc7110/spc7110.cpp +++ /dev/null @@ -1,682 +0,0 @@ -#include - -#define SPC7110_CPP -namespace SNES { - -SPC7110 spc7110; -SPC7110MCU spc7110mcu; -SPC7110DCU spc7110dcu; -SPC7110RAM spc7110ram; - -#include "serialization.cpp" -#include "decomp.cpp" - -const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -void SPC7110::init() {} -void SPC7110::enable() {} - -void SPC7110::power() { - reset(); -} - -void SPC7110::reset() { - r4801 = 0x00; - r4802 = 0x00; - r4803 = 0x00; - r4804 = 0x00; - r4805 = 0x00; - r4806 = 0x00; - r4807 = 0x00; - r4808 = 0x00; - r4809 = 0x00; - r480a = 0x00; - r480b = 0x00; - r480c = 0x00; - - decomp.reset(); - - r4811 = 0x00; - r4812 = 0x00; - r4813 = 0x00; - r4814 = 0x00; - r4815 = 0x00; - r4816 = 0x00; - r4817 = 0x00; - r4818 = 0x00; - - r481x = 0x00; - r4814_latch = false; - r4815_latch = false; - - r4820 = 0x00; - r4821 = 0x00; - r4822 = 0x00; - r4823 = 0x00; - r4824 = 0x00; - r4825 = 0x00; - r4826 = 0x00; - r4827 = 0x00; - r4828 = 0x00; - r4829 = 0x00; - r482a = 0x00; - r482b = 0x00; - r482c = 0x00; - r482d = 0x00; - r482e = 0x00; - r482f = 0x00; - - r4830 = 0x00; - mmio_write(0x4831, 0); - mmio_write(0x4832, 1); - mmio_write(0x4833, 2); - r4834 = 0x00; - - r4840 = 0x00; - r4841 = 0x00; - r4842 = 0x00; - - if(cartridge.has_spc7110rtc()) { - rtc_state = RTCS_Inactive; - rtc_mode = RTCM_Linear; - rtc_index = 0; - } -} - -unsigned SPC7110::datarom_addr(unsigned addr) { - unsigned size = memory::cartrom.size() - cartridge.spc7110_data_rom_offset(); - while(addr >= size) addr -= size; - return cartridge.spc7110_data_rom_offset() + addr; -} - -unsigned SPC7110::data_pointer() { return r4811 + (r4812 << 8) + (r4813 << 16); } -unsigned SPC7110::data_adjust() { return r4814 + (r4815 << 8); } -unsigned SPC7110::data_increment() { return r4816 + (r4817 << 8); } -void SPC7110::set_data_pointer(unsigned addr) { r4811 = addr; r4812 = addr >> 8; r4813 = addr >> 16; } -void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; } - -void SPC7110::update_time(int offset) { - time_t rtc_time - = (memory::cartrtc.read(16) << 0) - | (memory::cartrtc.read(17) << 8) - | (memory::cartrtc.read(18) << 16) - | (memory::cartrtc.read(19) << 24); - time_t current_time = time(0) - offset; - - //sizeof(time_t) is platform-dependent; though memory::cartrtc needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by - //accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow - //memory::cartrtc timestamp to remain valid for up to ~34 years from the last update, even if - //time_t overflows. calculation should be valid regardless of number representation, time_t size, - //or whether time_t is signed or unsigned. - time_t diff - = (current_time >= rtc_time) - ? (current_time - rtc_time) - : (std::numeric_limits::max() - rtc_time + current_time + 1); //compensate for overflow - if(diff > std::numeric_limits::max() / 2) diff = 0; //compensate for underflow - - bool update = true; - if(memory::cartrtc.read(13) & 1) update = false; //do not update if CR0 timer disable flag is set - if(memory::cartrtc.read(15) & 3) update = false; //do not update if CR2 timer disable flags are set - - if(diff > 0 && update == true) { - unsigned second = memory::cartrtc.read( 0) + memory::cartrtc.read( 1) * 10; - unsigned minute = memory::cartrtc.read( 2) + memory::cartrtc.read( 3) * 10; - unsigned hour = memory::cartrtc.read( 4) + memory::cartrtc.read( 5) * 10; - unsigned day = memory::cartrtc.read( 6) + memory::cartrtc.read( 7) * 10; - unsigned month = memory::cartrtc.read( 8) + memory::cartrtc.read( 9) * 10; - unsigned year = memory::cartrtc.read(10) + memory::cartrtc.read(11) * 10; - unsigned weekday = memory::cartrtc.read(12); - - day--; - month--; - year += (year >= 90) ? 1900 : 2000; //range = 1990-2089 - - second += diff; - while(second >= 60) { - second -= 60; - - minute++; - if(minute < 60) continue; - minute = 0; - - hour++; - if(hour < 24) continue; - hour = 0; - - day++; - weekday = (weekday + 1) % 7; - unsigned days = months[month % 12]; - if(days == 28) { - bool leapyear = false; - if((year % 4) == 0) { - leapyear = true; - if((year % 100) == 0 && (year % 400) != 0) leapyear = false; - } - if(leapyear) days++; - } - if(day < days) continue; - day = 0; - - month++; - if(month < 12) continue; - month = 0; - - year++; - } - - day++; - month++; - year %= 100; - - memory::cartrtc.write( 0, second % 10); - memory::cartrtc.write( 1, second / 10); - memory::cartrtc.write( 2, minute % 10); - memory::cartrtc.write( 3, minute / 10); - memory::cartrtc.write( 4, hour % 10); - memory::cartrtc.write( 5, hour / 10); - memory::cartrtc.write( 6, day % 10); - memory::cartrtc.write( 7, day / 10); - memory::cartrtc.write( 8, month % 10); - memory::cartrtc.write( 9, month / 10); - memory::cartrtc.write(10, year % 10); - memory::cartrtc.write(11, (year / 10) % 10); - memory::cartrtc.write(12, weekday % 7); - } - - memory::cartrtc.write(16, current_time >> 0); - memory::cartrtc.write(17, current_time >> 8); - memory::cartrtc.write(18, current_time >> 16); - memory::cartrtc.write(19, current_time >> 24); -} - -uint8 SPC7110::mmio_read(unsigned addr) { - addr &= 0xffff; - - switch(addr) { - //================== - //decompression unit - //================== - - case 0x4800: { - uint16 counter = (r4809 + (r480a << 8)); - counter--; - r4809 = counter; - r480a = counter >> 8; - return decomp.read(); - } - case 0x4801: return r4801; - case 0x4802: return r4802; - case 0x4803: return r4803; - case 0x4804: return r4804; - case 0x4805: return r4805; - case 0x4806: return r4806; - case 0x4807: return r4807; - case 0x4808: return r4808; - case 0x4809: return r4809; - case 0x480a: return r480a; - case 0x480b: return r480b; - case 0x480c: { - uint8 status = r480c; - r480c &= 0x7f; - return status; - } - - //============== - //data port unit - //============== - - case 0x4810: { - if(r481x != 0x07) return 0x00; - - unsigned addr = data_pointer(); - unsigned adjust = data_adjust(); - if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend - - unsigned adjustaddr = addr; - if(r4818 & 2) { - adjustaddr += adjust; - set_data_adjust(adjust + 1); - } - - uint8 data = memory::cartrom.read(datarom_addr(adjustaddr)); - if(!(r4818 & 2)) { - unsigned increment = (r4818 & 1) ? data_increment() : 1; - if(r4818 & 4) increment = (int16)increment; //16-bit sign extend - - if((r4818 & 16) == 0) { - set_data_pointer(addr + increment); - } else { - set_data_adjust(adjust + increment); - } - } - - return data; - } - case 0x4811: return r4811; - case 0x4812: return r4812; - case 0x4813: return r4813; - case 0x4814: return r4814; - case 0x4815: return r4815; - case 0x4816: return r4816; - case 0x4817: return r4817; - case 0x4818: return r4818; - case 0x481a: { - if(r481x != 0x07) return 0x00; - - unsigned addr = data_pointer(); - unsigned adjust = data_adjust(); - if(r4818 & 8) adjust = (int16)adjust; //16-bit sign extend - - uint8 data = memory::cartrom.read(datarom_addr(addr + adjust)); - if((r4818 & 0x60) == 0x60) { - if((r4818 & 16) == 0) { - set_data_pointer(addr + adjust); - } else { - set_data_adjust(adjust + adjust); - } - } - - return data; - } - - //========= - //math unit - //========= - - case 0x4820: return r4820; - case 0x4821: return r4821; - case 0x4822: return r4822; - case 0x4823: return r4823; - case 0x4824: return r4824; - case 0x4825: return r4825; - case 0x4826: return r4826; - case 0x4827: return r4827; - case 0x4828: return r4828; - case 0x4829: return r4829; - case 0x482a: return r482a; - case 0x482b: return r482b; - case 0x482c: return r482c; - case 0x482d: return r482d; - case 0x482e: return r482e; - case 0x482f: { - uint8 status = r482f; - r482f &= 0x7f; - return status; - } - - //=================== - //memory mapping unit - //=================== - - case 0x4830: return r4830; - case 0x4831: return r4831; - case 0x4832: return r4832; - case 0x4833: return r4833; - case 0x4834: return r4834; - - //==================== - //real-time clock unit - //==================== - - case 0x4840: return r4840; - case 0x4841: { - if(rtc_state == RTCS_Inactive || rtc_state == RTCS_ModeSelect) return 0x00; - - r4842 = 0x80; - uint8 data = memory::cartrtc.read(rtc_index); - rtc_index = (rtc_index + 1) & 15; - return data; - } - case 0x4842: { - uint8 status = r4842; - r4842 &= 0x7f; - return status; - } - } - - return cpu.regs.mdr; -} - -void SPC7110::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - switch(addr) { - //================== - //decompression unit - //================== - - case 0x4801: r4801 = data; break; - case 0x4802: r4802 = data; break; - case 0x4803: r4803 = data; break; - case 0x4804: r4804 = data; break; - case 0x4805: r4805 = data; break; - case 0x4806: { - r4806 = data; - - unsigned table = (r4801 + (r4802 << 8) + (r4803 << 16)); - unsigned index = (r4804 << 2); - unsigned length = (r4809 + (r480a << 8)); - unsigned addr = datarom_addr(table + index); - unsigned mode = (memory::cartrom.read(addr + 0)); - unsigned offset = (memory::cartrom.read(addr + 1) << 16) - + (memory::cartrom.read(addr + 2) << 8) - + (memory::cartrom.read(addr + 3) << 0); - - decomp.init(mode, offset, (r4805 + (r4806 << 8)) << mode); - r480c = 0x80; - } break; - - case 0x4807: r4807 = data; break; - case 0x4808: r4808 = data; break; - case 0x4809: r4809 = data; break; - case 0x480a: r480a = data; break; - case 0x480b: r480b = data; break; - - //============== - //data port unit - //============== - - case 0x4811: r4811 = data; r481x |= 0x01; break; - case 0x4812: r4812 = data; r481x |= 0x02; break; - case 0x4813: r4813 = data; r481x |= 0x04; break; - case 0x4814: { - r4814 = data; - r4814_latch = true; - if(!r4815_latch) break; - if(!(r4818 & 2)) break; - if(r4818 & 0x10) break; - - if((r4818 & 0x60) == 0x20) { - unsigned increment = data_adjust() & 0xff; - if(r4818 & 8) increment = (int8)increment; //8-bit sign extend - set_data_pointer(data_pointer() + increment); - } else if((r4818 & 0x60) == 0x40) { - unsigned increment = data_adjust(); - if(r4818 & 8) increment = (int16)increment; //16-bit sign extend - set_data_pointer(data_pointer() + increment); - } - } break; - case 0x4815: { - r4815 = data; - r4815_latch = true; - if(!r4814_latch) break; - if(!(r4818 & 2)) break; - if(r4818 & 0x10) break; - - if((r4818 & 0x60) == 0x20) { - unsigned increment = data_adjust() & 0xff; - if(r4818 & 8) increment = (int8)increment; //8-bit sign extend - set_data_pointer(data_pointer() + increment); - } else if((r4818 & 0x60) == 0x40) { - unsigned increment = data_adjust(); - if(r4818 & 8) increment = (int16)increment; //16-bit sign extend - set_data_pointer(data_pointer() + increment); - } - } break; - case 0x4816: r4816 = data; break; - case 0x4817: r4817 = data; break; - case 0x4818: { - if(r481x != 0x07) break; - - r4818 = data; - r4814_latch = r4815_latch = false; - } break; - - //========= - //math unit - //========= - - case 0x4820: r4820 = data; break; - case 0x4821: r4821 = data; break; - case 0x4822: r4822 = data; break; - case 0x4823: r4823 = data; break; - case 0x4824: r4824 = data; break; - case 0x4825: { - r4825 = data; - - if(r482e & 1) { - //signed 16-bit x 16-bit multiplication - int16 r0 = (int16)(r4824 + (r4825 << 8)); - int16 r1 = (int16)(r4820 + (r4821 << 8)); - - signed result = r0 * r1; - r4828 = result; - r4829 = result >> 8; - r482a = result >> 16; - r482b = result >> 24; - } else { - //unsigned 16-bit x 16-bit multiplication - uint16 r0 = (uint16)(r4824 + (r4825 << 8)); - uint16 r1 = (uint16)(r4820 + (r4821 << 8)); - - unsigned result = r0 * r1; - r4828 = result; - r4829 = result >> 8; - r482a = result >> 16; - r482b = result >> 24; - } - - r482f = 0x80; - } break; - case 0x4826: r4826 = data; break; - case 0x4827: { - r4827 = data; - - if(r482e & 1) { - //signed 32-bit x 16-bit division - int32 dividend = (int32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); - int16 divisor = (int16)(r4826 + (r4827 << 8)); - - int32 quotient; - int16 remainder; - - if(divisor) { - quotient = (int32)(dividend / divisor); - remainder = (int32)(dividend % divisor); - } else { - //illegal division by zero - quotient = 0; - remainder = dividend & 0xffff; - } - - r4828 = quotient; - r4829 = quotient >> 8; - r482a = quotient >> 16; - r482b = quotient >> 24; - - r482c = remainder; - r482d = remainder >> 8; - } else { - //unsigned 32-bit x 16-bit division - uint32 dividend = (uint32)(r4820 + (r4821 << 8) + (r4822 << 16) + (r4823 << 24)); - uint16 divisor = (uint16)(r4826 + (r4827 << 8)); - - uint32 quotient; - uint16 remainder; - - if(divisor) { - quotient = (uint32)(dividend / divisor); - remainder = (uint16)(dividend % divisor); - } else { - //illegal division by zero - quotient = 0; - remainder = dividend & 0xffff; - } - - r4828 = quotient; - r4829 = quotient >> 8; - r482a = quotient >> 16; - r482b = quotient >> 24; - - r482c = remainder; - r482d = remainder >> 8; - } - - r482f = 0x80; - } break; - - case 0x482e: { - //reset math unit - r4820 = r4821 = r4822 = r4823 = 0; - r4824 = r4825 = r4826 = r4827 = 0; - r4828 = r4829 = r482a = r482b = 0; - r482c = r482d = 0; - - r482e = data; - } break; - - //=================== - //memory mapping unit - //=================== - - case 0x4830: r4830 = data; break; - - case 0x4831: { - r4831 = data; - dx_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4832: { - r4832 = data; - ex_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4833: { - r4833 = data; - fx_offset = datarom_addr(data * 0x100000); - } break; - - case 0x4834: r4834 = data; break; - - //==================== - //real-time clock unit - //==================== - - case 0x4840: { - r4840 = data; - if(!(r4840 & 1)) { - //disable RTC - rtc_state = RTCS_Inactive; - update_time(); - } else { - //enable RTC - r4842 = 0x80; - rtc_state = RTCS_ModeSelect; - } - } break; - - case 0x4841: { - r4841 = data; - - switch(rtc_state) { - case RTCS_ModeSelect: { - if(data == RTCM_Linear || data == RTCM_Indexed) { - r4842 = 0x80; - rtc_state = RTCS_IndexSelect; - rtc_mode = (RTC_Mode)data; - rtc_index = 0; - } - } break; - - case RTCS_IndexSelect: { - r4842 = 0x80; - rtc_index = data & 15; - if(rtc_mode == RTCM_Linear) rtc_state = RTCS_Write; - } break; - - case RTCS_Write: { - r4842 = 0x80; - - //control register 0 - if(rtc_index == 13) { - //increment second counter - if(data & 2) update_time(+1); - - //round minute counter - if(data & 8) { - update_time(); - - unsigned second = memory::cartrtc.read( 0) + memory::cartrtc.read( 1) * 10; - //clear seconds - memory::cartrtc.write(0, 0); - memory::cartrtc.write(1, 0); - - if(second >= 30) update_time(+60); - } - } - - //control register 2 - if(rtc_index == 15) { - //disable timer and clear second counter - if((data & 1) && !(memory::cartrtc.read(15) & 1)) { - update_time(); - - //clear seconds - memory::cartrtc.write(0, 0); - memory::cartrtc.write(1, 0); - } - - //disable timer - if((data & 2) && !(memory::cartrtc.read(15) & 2)) { - update_time(); - } - } - - memory::cartrtc.write(rtc_index, data & 15); - rtc_index = (rtc_index + 1) & 15; - } break; - } //switch(rtc_state) - } break; - } -} - -SPC7110::SPC7110() { -} - -//========== -//SPC7110MCU -//========== - -unsigned SPC7110MCU::size() const { - return 0x300000; -} - -uint8 SPC7110MCU::read(unsigned addr) { - if(addr <= 0xdfffff) return memory::cartrom.read(spc7110.dx_offset + (addr & 0x0fffff)); - if(addr <= 0xefffff) return memory::cartrom.read(spc7110.ex_offset + (addr & 0x0fffff)); - if(addr <= 0xffffff) return memory::cartrom.read(spc7110.fx_offset + (addr & 0x0fffff)); - return cpu.regs.mdr; -} - -void SPC7110MCU::write(unsigned addr, uint8 data) { -} - -//========== -//SPC7110DCU -//========== - -uint8 SPC7110DCU::read(unsigned) { - return spc7110.mmio_read(0x4800); -} - -void SPC7110DCU::write(unsigned, uint8) { -} - -//========== -//SPC7110RAM -//========== - -unsigned SPC7110RAM::size() const { - return 0x2000; -} - -uint8 SPC7110RAM::read(unsigned addr) { - return memory::cartram.read(addr & 0x1fff); -} - -void SPC7110RAM::write(unsigned addr, uint8 data) { - if(spc7110.r4830 & 0x80) memory::cartram.write(addr & 0x1fff, data); -} - -} diff --git a/bsnes/chip/spc7110/spc7110.hpp b/bsnes/chip/spc7110/spc7110.hpp deleted file mode 100755 index 4d8b43c3..00000000 --- a/bsnes/chip/spc7110/spc7110.hpp +++ /dev/null @@ -1,159 +0,0 @@ -/***** - * SPC7110 emulator - version 0.04 (2010-02-14) - * Copyright (c) 2008-2010, byuu and neviksti - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * The software is provided "as is" and the author disclaims all warranties - * with regard to this software including all implied warranties of - * merchantibility and fitness, in no event shall the author be liable for - * any special, direct, indirect, or consequential damages or any damages - * whatsoever resulting from loss of use, data or profits, whether in an - * action of contract, negligence or other tortious action, arising out of - * or in connection with the use or performance of this software. - *****/ - -#include "decomp.hpp" - -class SPC7110 : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - unsigned datarom_addr(unsigned addr); - - unsigned data_pointer(); - unsigned data_adjust(); - unsigned data_increment(); - void set_data_pointer(unsigned addr); - void set_data_adjust(unsigned addr); - - void update_time(int offset = 0); - time_t create_time(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - //spc7110decomp - void decomp_init(); - uint8 decomp_read(); - - void serialize(serializer&); - SPC7110(); - -private: - //================== - //decompression unit - //================== - uint8 r4801; //compression table low - uint8 r4802; //compression table high - uint8 r4803; //compression table bank - uint8 r4804; //compression table index - uint8 r4805; //decompression buffer index low - uint8 r4806; //decompression buffer index high - uint8 r4807; //??? - uint8 r4808; //??? - uint8 r4809; //compression length low - uint8 r480a; //compression length high - uint8 r480b; //decompression control register - uint8 r480c; //decompression status - - SPC7110Decomp decomp; - - //============== - //data port unit - //============== - uint8 r4811; //data pointer low - uint8 r4812; //data pointer high - uint8 r4813; //data pointer 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 r481x; - - bool r4814_latch; - bool r4815_latch; - - //========= - //math 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 - uint8 r4823; //32-bit dividend B3 - uint8 r4824; //16-bit multiplier B0 - uint8 r4825; //16-bit multiplier B1 - uint8 r4826; //16-bit divisor B0 - uint8 r4827; //16-bit divisor B1 - uint8 r4828; //32-bit product B0, 32-bit quotient B0 - uint8 r4829; //32-bit product B1, 32-bit quotient B1 - uint8 r482a; //32-bit product B2, 32-bit quotient B2 - 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 control register - uint8 r482f; //math status - - //=================== - //memory mapping unit - //=================== - uint8 r4830; //SRAM write enable - uint8 r4831; //$[d0-df]:[0000-ffff] mapping - uint8 r4832; //$[e0-ef]:[0000-ffff] mapping - uint8 r4833; //$[f0-ff]:[0000-ffff] mapping - uint8 r4834; //??? - - unsigned dx_offset; - unsigned ex_offset; - unsigned fx_offset; - - //==================== - //real-time clock unit - //==================== - uint8 r4840; //RTC latch - uint8 r4841; //RTC index/data port - uint8 r4842; //RTC status - - enum RTC_State { RTCS_Inactive, RTCS_ModeSelect, RTCS_IndexSelect, RTCS_Write }; - enum RTC_Mode { RTCM_Linear = 0x03, RTCM_Indexed = 0x0c }; - unsigned rtc_state; - unsigned rtc_mode; - unsigned rtc_index; - - static const unsigned months[12]; - friend class SPC7110MCU; - friend class SPC7110DCU; - friend class SPC7110RAM; -}; - -class SPC7110MCU : public Memory { -public: - unsigned size() const; - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class SPC7110DCU : public Memory { -public: - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -class SPC7110RAM : public Memory { -public: - unsigned size() const; - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); -}; - -extern SPC7110 spc7110; -extern SPC7110MCU spc7110mcu; -extern SPC7110DCU spc7110dcu; -extern SPC7110RAM spc7110ram; diff --git a/bsnes/chip/srtc/serialization.cpp b/bsnes/chip/srtc/serialization.cpp deleted file mode 100755 index 538a1bd8..00000000 --- a/bsnes/chip/srtc/serialization.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef SRTC_CPP - -void SRTC::serialize(serializer &s) { - s.integer(rtc_mode); - s.integer(rtc_index); -} - -#endif diff --git a/bsnes/chip/srtc/srtc.cpp b/bsnes/chip/srtc/srtc.cpp deleted file mode 100755 index 965a0ef0..00000000 --- a/bsnes/chip/srtc/srtc.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include - -#define SRTC_CPP -namespace SNES { - -SRTC srtc; - -#include "serialization.cpp" - -const unsigned SRTC::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -void SRTC::init() { -} - -void SRTC::enable() { -} - -void SRTC::power() { - reset(); -} - -void SRTC::reset() { - rtc_mode = RtcRead; - rtc_index = -1; - update_time(); -} - -void SRTC::update_time() { - time_t rtc_time - = (memory::cartrtc.read(16) << 0) - | (memory::cartrtc.read(17) << 8) - | (memory::cartrtc.read(18) << 16) - | (memory::cartrtc.read(19) << 24); - time_t current_time = time(0); - - //sizeof(time_t) is platform-dependent; though memory::cartrtc needs to be platform-agnostic. - //yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by - //accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow - //memory::cartrtc timestamp to remain valid for up to ~34 years from the last update, even if - //time_t overflows. calculation should be valid regardless of number representation, time_t size, - //or whether time_t is signed or unsigned. - time_t diff - = (current_time >= rtc_time) - ? (current_time - rtc_time) - : (std::numeric_limits::max() - rtc_time + current_time + 1); //compensate for overflow - if(diff > std::numeric_limits::max() / 2) diff = 0; //compensate for underflow - - if(diff > 0) { - unsigned second = memory::cartrtc.read( 0) + memory::cartrtc.read( 1) * 10; - unsigned minute = memory::cartrtc.read( 2) + memory::cartrtc.read( 3) * 10; - unsigned hour = memory::cartrtc.read( 4) + memory::cartrtc.read( 5) * 10; - unsigned day = memory::cartrtc.read( 6) + memory::cartrtc.read( 7) * 10; - unsigned month = memory::cartrtc.read( 8); - unsigned year = memory::cartrtc.read( 9) + memory::cartrtc.read(10) * 10 + memory::cartrtc.read(11) * 100; - unsigned weekday = memory::cartrtc.read(12); - - day--; - month--; - year += 1000; - - second += diff; - while(second >= 60) { - second -= 60; - - minute++; - if(minute < 60) continue; - minute = 0; - - hour++; - if(hour < 24) continue; - hour = 0; - - day++; - weekday = (weekday + 1) % 7; - unsigned days = months[month % 12]; - if(days == 28) { - bool leapyear = false; - if((year % 4) == 0) { - leapyear = true; - if((year % 100) == 0 && (year % 400) != 0) leapyear = false; - } - if(leapyear) days++; - } - if(day < days) continue; - day = 0; - - month++; - if(month < 12) continue; - month = 0; - - year++; - } - - day++; - month++; - year -= 1000; - - memory::cartrtc.write( 0, second % 10); - memory::cartrtc.write( 1, second / 10); - memory::cartrtc.write( 2, minute % 10); - memory::cartrtc.write( 3, minute / 10); - memory::cartrtc.write( 4, hour % 10); - memory::cartrtc.write( 5, hour / 10); - memory::cartrtc.write( 6, day % 10); - memory::cartrtc.write( 7, day / 10); - memory::cartrtc.write( 8, month); - memory::cartrtc.write( 9, year % 10); - memory::cartrtc.write(10, (year / 10) % 10); - memory::cartrtc.write(11, year / 100); - memory::cartrtc.write(12, weekday % 7); - } - - memory::cartrtc.write(16, current_time >> 0); - memory::cartrtc.write(17, current_time >> 8); - memory::cartrtc.write(18, current_time >> 16); - memory::cartrtc.write(19, current_time >> 24); -} - -//returns day of week for specified date -//eg 0 = Sunday, 1 = Monday, ... 6 = Saturday -//usage: weekday(2008, 1, 1) returns weekday of January 1st, 2008 -unsigned SRTC::weekday(unsigned year, unsigned month, unsigned day) { - unsigned y = 1900, m = 1; //epoch is 1900-01-01 - unsigned sum = 0; //number of days passed since epoch - - year = max(1900, year); - month = max(1, min(12, month)); - day = max(1, min(31, day)); - - while(y < year) { - bool leapyear = false; - if((y % 4) == 0) { - leapyear = true; - if((y % 100) == 0 && (y % 400) != 0) leapyear = false; - } - sum += leapyear ? 366 : 365; - y++; - } - - while(m < month) { - unsigned days = months[m - 1]; - if(days == 28) { - bool leapyear = false; - if((y % 4) == 0) { - leapyear = true; - if((y % 100) == 0 && (y % 400) != 0) leapyear = false; - } - if(leapyear) days++; - } - sum += days; - m++; - } - - sum += day - 1; - return (sum + 1) % 7; //1900-01-01 was a Monday -} - -uint8 SRTC::mmio_read(unsigned addr) { - addr &= 0xffff; - - if(addr == 0x2800) { - if(rtc_mode != RtcRead) return 0x00; - - if(rtc_index < 0) { - update_time(); - rtc_index++; - return 0x0f; - } else if(rtc_index > 12) { - rtc_index = -1; - return 0x0f; - } else { - return memory::cartrtc.read(rtc_index++); - } - } - - return cpu.regs.mdr; -} - -void SRTC::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x2801) { - data &= 0x0f; //only the low four bits are used - - if(data == 0x0d) { - rtc_mode = RtcRead; - rtc_index = -1; - return; - } - - if(data == 0x0e) { - rtc_mode = RtcCommand; - return; - } - - if(data == 0x0f) return; //unknown behavior - - if(rtc_mode == RtcWrite) { - if(rtc_index >= 0 && rtc_index < 12) { - memory::cartrtc.write(rtc_index++, data); - - if(rtc_index == 12) { - //day of week is automatically calculated and written - unsigned day = memory::cartrtc.read( 6) + memory::cartrtc.read( 7) * 10; - unsigned month = memory::cartrtc.read( 8); - unsigned year = memory::cartrtc.read( 9) + memory::cartrtc.read(10) * 10 + memory::cartrtc.read(11) * 100; - year += 1000; - - memory::cartrtc.write(rtc_index++, weekday(year, month, day)); - } - } - } else if(rtc_mode == RtcCommand) { - if(data == 0) { - rtc_mode = RtcWrite; - rtc_index = 0; - } else if(data == 4) { - rtc_mode = RtcReady; - rtc_index = -1; - for(unsigned i = 0; i < 13; i++) memory::cartrtc.write(i, 0); - } else { - //unknown behavior - rtc_mode = RtcReady; - } - } - } -} - -SRTC::SRTC() { -} - -} diff --git a/bsnes/chip/srtc/srtc.hpp b/bsnes/chip/srtc/srtc.hpp deleted file mode 100755 index 7bbe7f47..00000000 --- a/bsnes/chip/srtc/srtc.hpp +++ /dev/null @@ -1,24 +0,0 @@ -class SRTC : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - void serialize(serializer&); - SRTC(); - -private: - static const unsigned months[12]; - enum RtcMode { RtcReady, RtcCommand, RtcRead, RtcWrite }; - unsigned rtc_mode; - signed rtc_index; - - void update_time(); - unsigned weekday(unsigned year, unsigned month, unsigned day); -}; - -extern SRTC srtc; diff --git a/bsnes/chip/st0010/data.hpp b/bsnes/chip/st0010/data.hpp deleted file mode 100755 index 52b251f9..00000000 --- a/bsnes/chip/st0010/data.hpp +++ /dev/null @@ -1,130 +0,0 @@ -#ifdef ST0010_CPP - -const int16 ST0010::sin_table[256] = { - 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2, - 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, - 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, - 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, - 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6, - 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504, - 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3, - 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5, - 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d, - 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b, - 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23, - 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3, - 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, - 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df, - 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b, - 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324, - 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2, - -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, - -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a, - -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, - -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6, - -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504, - -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3, - -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5, - -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d, - -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b, - -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23, - -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3, - -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3, - -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de, - -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b, - -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324 -}; - -const int16 ST0010::mode7_scale[176] = { - 0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3, - 0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b, - 0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8, - 0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6, - 0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5, - 0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d, - 0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c, - 0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e, - 0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063, - 0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a, - 0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052, - 0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c, - 0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047, - 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042, - 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e, - 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a, - 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037, - 0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034, - 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031, - 0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f, - 0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d, - 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b -}; - -const uint8 ST0010::arctan[32][32] = { - { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, - { 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, - 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf }, - { 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, - 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd }, - { 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8, - 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc }, - { 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5, - 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb }, - { 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, - 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9 }, - { 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0, - 0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8 }, - { 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae, - 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7 }, - { 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac, - 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5 }, - { 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa, - 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4 }, - { 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8, - 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3 }, - { 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6, - 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2 }, - { 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1 }, - { 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3, - 0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0 }, - { 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1, - 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf }, - { 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0, - 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae }, - { 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad }, - { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d, - 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac }, - { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c, - 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab }, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b, - 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa }, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a, - 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9 }, - { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, - 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8 }, - { 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7 }, - { 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98, - 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6 }, - { 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5 }, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4 }, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4 }, - { 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3 }, - { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2 }, - { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1 }, - { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, - 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1 }, - { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0 } -}; - -#endif diff --git a/bsnes/chip/st0010/opcodes.cpp b/bsnes/chip/st0010/opcodes.cpp deleted file mode 100755 index e6aa5419..00000000 --- a/bsnes/chip/st0010/opcodes.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#ifdef ST0010_CPP - -//ST-0010 emulation code - Copyright (C) 2003 The Dumper, Matthew Kendora, Overload, Feather -//bsnes port - Copyright (C) 2007 byuu - -void ST0010::op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta) { - if((x0 < 0) && (y0 < 0)) { - x1 = -x0; - y1 = -y0; - quadrant = -0x8000; - } else if(x0 < 0) { - x1 = y0; - y1 = -x0; - quadrant = -0x4000; - } else if(y0 < 0) { - x1 = -y0; - y1 = x0; - quadrant = 0x4000; - } else { - x1 = x0; - y1 = y0; - quadrant = 0x0000; - } - - while((x1 > 0x1f) || (y1 > 0x1f)) { - if(x1 > 1) { x1 >>= 1; } - if(y1 > 1) { y1 >>= 1; } - } - - if(y1 == 0) { quadrant += 0x4000; } - - theta = (arctan[y1][x1] << 8) ^ quadrant; -} - -// - -void ST0010::op_01() { - int16 x0 = readw(0x0000); - int16 y0 = readw(0x0002); - int16 x1, y1, quadrant, theta; - - op_01(x0, y0, x1, y1, quadrant, theta); - - writew(0x0000, x1); - writew(0x0002, y1); - writew(0x0004, quadrant); -//writew(0x0006, y0); //Overload's docs note this write occurs, SNES9x disagrees - writew(0x0010, theta); -} - -void ST0010::op_02() { - int16 positions = readw(0x0024); - uint16 *places = (uint16*)(ram + 0x0040); - uint16 *drivers = (uint16*)(ram + 0x0080); - - bool sorted; - uint16 temp; - if(positions > 1) { - do { - sorted = true; - for(int i = 0; i < positions - 1; i++) { - if(places[i] < places[i + 1]) { - temp = places[i + 1]; - places[i + 1] = places[i]; - places[i] = temp; - - temp = drivers[i + 1]; - drivers[i + 1] = drivers[i]; - drivers[i] = temp; - - sorted = false; - } - } - positions--; - } while(!sorted); - } -} - -void ST0010::op_03() { - int16 x0 = readw(0x0000); - int16 y0 = readw(0x0002); - int16 multiplier = readw(0x0004); - int32 x1, y1; - - x1 = x0 * multiplier << 1; - y1 = y0 * multiplier << 1; - - writed(0x0010, x1); - writed(0x0014, y1); -} - -void ST0010::op_04() { - int16 x = readw(0x0000); - int16 y = readw(0x0002); - int16 square; - //calculate the vector length of (x,y) - square = (int16)sqrt((double)(y * y + x * x)); - - writew(0x0010, square); -} - -void ST0010::op_05() { - int32 dx, dy; - int16 a1, b1, c1; - uint16 o1; - bool wrap = false; - - //target (x,y) coordinates - int16 ypos_max = readw(0x00c0); - int16 xpos_max = readw(0x00c2); - - //current coordinates and direction - int32 ypos = readd(0x00c4); - int32 xpos = readd(0x00c8); - uint16 rot = readw(0x00cc); - - //physics - uint16 speed = readw(0x00d4); - uint16 accel = readw(0x00d6); - uint16 speed_max = readw(0x00d8); - - //special condition acknowledgement - int16 system = readw(0x00da); - int16 flags = readw(0x00dc); - - //new target coordinates - int16 ypos_new = readw(0x00de); - int16 xpos_new = readw(0x00e0); - - //mask upper bit - xpos_new &= 0x7fff; - - //get the current distance - dx = xpos_max - (xpos >> 16); - dy = ypos_max - (ypos >> 16); - - //quirk: clear and move in9 - writew(0x00d2, 0xffff); - writew(0x00da, 0x0000); - - //grab the target angle - op_01(dy, dx, a1, b1, c1, (int16&)o1); - - //check for wrapping - if(abs(o1 - rot) > 0x8000) { - o1 += 0x8000; - rot += 0x8000; - wrap = true; - } - - uint16 old_speed = speed; - - //special case - if(abs(o1 - rot) == 0x8000) { - speed = 0x100; - } - - //slow down for sharp curves - else if(abs(o1 - rot) >= 0x1000) { - uint32 slow = abs(o1 - rot); - slow >>= 4; //scaling - speed -= slow; - } - - //otherwise accelerate - else { - speed += accel; - if(speed > speed_max) { - speed = speed_max; //clip speed - } - } - - //prevent negative/positive overflow - if(abs(old_speed - speed) > 0x8000) { - if(old_speed < speed) { speed = 0; } - else speed = 0xff00; - } - - //adjust direction by so many degrees - //be careful of negative adjustments - if((o1 > rot && (o1 - rot) > 0x80) || (o1 < rot && (rot - o1) >= 0x80)) { - if(o1 < rot) { rot -= 0x280; } - else if(o1 > rot) { rot += 0x280; } - } - - //turn off wrapping - if(wrap) { rot -= 0x8000; } - - //now check the distances (store for later) - dx = (xpos_max << 16) - xpos; - dy = (ypos_max << 16) - ypos; - dx >>= 16; - dy >>= 16; - - //if we're in so many units of the target, signal it - if((system && (dy <= 6 && dy >= -8) && (dx <= 126 && dx >= -128)) || (!system && (dx <= 6 && dx >= -8) && (dy <= 126 && dy >= -128))) { - //announce our new destination and flag it - xpos_max = xpos_new & 0x7fff; - ypos_max = ypos_new; - flags |= 0x08; - } - - //update position - xpos -= (cos(rot) * 0x400 >> 15) * (speed >> 8) << 1; - ypos -= (sin(rot) * 0x400 >> 15) * (speed >> 8) << 1; - - //quirk: mask upper byte - xpos &= 0x1fffffff; - ypos &= 0x1fffffff; - - writew(0x00c0, ypos_max); - writew(0x00c2, xpos_max); - writed(0x00c4, ypos); - writed(0x00c8, xpos); - writew(0x00cc, rot); - writew(0x00d4, speed); - writew(0x00dc, flags); -} - -void ST0010::op_06() { - int16 multiplicand = readw(0x0000); - int16 multiplier = readw(0x0002); - int32 product; - - product = multiplicand * multiplier << 1; - - writed(0x0010, product); -} - -void ST0010::op_07() { - int16 theta = readw(0x0000); - - int16 data; - for(int i = 0, offset = 0; i < 176; i++) { - data = mode7_scale[i] * cos(theta) >> 15; - writew(0x00f0 + offset, data); - writew(0x0510 + offset, data); - - data = mode7_scale[i] * sin(theta) >> 15; - writew(0x0250 + offset, data); - if(data) { data = ~data; } - writew(0x03b0 + offset, data); - - offset += 2; - } -} - -void ST0010::op_08() { - int16 x0 = readw(0x0000); - int16 y0 = readw(0x0002); - int16 theta = readw(0x0004); - int16 x1, y1; - - x1 = (y0 * sin(theta) >> 15) + (x0 * cos(theta) >> 15); - y1 = (y0 * cos(theta) >> 15) - (x0 * sin(theta) >> 15); - - writew(0x0010, x1); - writew(0x0012, y1); -} - -#endif diff --git a/bsnes/chip/st0010/serialization.cpp b/bsnes/chip/st0010/serialization.cpp deleted file mode 100755 index 5c21f644..00000000 --- a/bsnes/chip/st0010/serialization.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef ST0010_CPP - -void ST0010::serialize(serializer &s) { - s.array(ram); -} - -#endif diff --git a/bsnes/chip/st0010/st0010.cpp b/bsnes/chip/st0010/st0010.cpp deleted file mode 100755 index 295d0f5a..00000000 --- a/bsnes/chip/st0010/st0010.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include - -#define ST0010_CPP -namespace SNES { - -ST0010 st0010; - -#include "data.hpp" -#include "opcodes.cpp" -#include "serialization.cpp" - -void ST0010::init() { -} - -void ST0010::enable() { -} - -int16 ST0010::sin(int16 theta) { - return sin_table[(theta >> 8) & 0xff]; -} - -int16 ST0010::cos(int16 theta) { - return sin_table[((theta + 0x4000) >> 8) & 0xff]; -} - -uint8 ST0010::readb(uint16 addr) { - return ram[addr & 0xfff]; -} - -uint16 ST0010::readw(uint16 addr) { - return (readb(addr + 0) << 0) | - (readb(addr + 1) << 8); -} - -uint32 ST0010::readd(uint16 addr) { - return (readb(addr + 0) << 0) | - (readb(addr + 1) << 8) | - (readb(addr + 2) << 16) | - (readb(addr + 3) << 24); -} - -void ST0010::writeb(uint16 addr, uint8 data) { - ram[addr & 0xfff] = data; -} - -void ST0010::writew(uint16 addr, uint16 data) { - writeb(addr + 0, data >> 0); - writeb(addr + 1, data >> 8); -} - -void ST0010::writed(uint16 addr, uint32 data) { - writeb(addr + 0, data >> 0); - writeb(addr + 1, data >> 8); - writeb(addr + 2, data >> 16); - writeb(addr + 3, data >> 24); -} - -// - -void ST0010::power() { - reset(); -} - -void ST0010::reset() { - memset(ram, 0x00, sizeof ram); -} - -// - -uint8 ST0010::read(unsigned addr) { - return readb(addr); -} - -void ST0010::write(unsigned addr, uint8 data) { - writeb(addr, data); - - if((addr & 0xfff) == 0x0021 && (data & 0x80)) { - switch(ram[0x0020]) { - case 0x01: op_01(); break; - case 0x02: op_02(); break; - case 0x03: op_03(); break; - case 0x04: op_04(); break; - case 0x05: op_05(); break; - case 0x06: op_06(); break; - case 0x07: op_07(); break; - case 0x08: op_08(); break; - } - - ram[0x0021] &= ~0x80; - } -} - -} diff --git a/bsnes/chip/st0010/st0010.hpp b/bsnes/chip/st0010/st0010.hpp deleted file mode 100755 index cceb0666..00000000 --- a/bsnes/chip/st0010/st0010.hpp +++ /dev/null @@ -1,44 +0,0 @@ -class ST0010 : public Memory { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void serialize(serializer&); - -private: - uint8 ram[0x1000]; - static const int16 sin_table[256]; - static const int16 mode7_scale[176]; - static const uint8 arctan[32][32]; - - //interfaces to sin table - int16 sin(int16 theta); - int16 cos(int16 theta); - - //interfaces to ram buffer - uint8 readb (uint16 addr); - uint16 readw (uint16 addr); - uint32 readd (uint16 addr); - void writeb(uint16 addr, uint8 data); - void writew(uint16 addr, uint16 data); - void writed(uint16 addr, uint32 data); - - //opcodes - void op_01(); - void op_02(); - void op_03(); - void op_04(); - void op_05(); - void op_06(); - void op_07(); - void op_08(); - - void op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta); -}; - -extern ST0010 st0010; diff --git a/bsnes/chip/st0011/st0011.cpp b/bsnes/chip/st0011/st0011.cpp deleted file mode 100755 index fe8e9c23..00000000 --- a/bsnes/chip/st0011/st0011.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include - -#define ST0011_CPP -namespace SNES { - -ST0011 st0011; - -void ST0011::init() { -} - -void ST0011::enable() { -} - -void ST0011::power() { -} - -void ST0011::reset() { -} - -} diff --git a/bsnes/chip/st0011/st0011.hpp b/bsnes/chip/st0011/st0011.hpp deleted file mode 100755 index c605c075..00000000 --- a/bsnes/chip/st0011/st0011.hpp +++ /dev/null @@ -1,9 +0,0 @@ -class ST0011 { -public: - void init(); - void enable(); - void power(); - void reset(); -}; - -extern ST0011 st0011; diff --git a/bsnes/chip/st0018/st0018.cpp b/bsnes/chip/st0018/st0018.cpp deleted file mode 100755 index 03ef4d0f..00000000 --- a/bsnes/chip/st0018/st0018.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include - -#define ST0018_CPP -namespace SNES { - -ST0018 st0018; - -uint8 ST0018::mmio_read(unsigned addr) { - addr &= 0xffff; - if(addr == 0x3800) return regs.r3800; - if(addr == 0x3804) return regs.r3804; - return cpu.regs.mdr; -} - -void ST0018::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x3802) { - switch(regs.mode) { - case Waiting: { - switch(data) { - case 0x01: regs.r3800 = regs.r3800_01; break; - case 0xaa: op_board_upload(); break; - case 0xb2: op_b2(); break; - case 0xb3: op_b3(); break; - case 0xb4: op_b4(); break; - case 0xb5: op_b5(); break; - case 0xf1: op_query_chip(); break; - case 0xf2: op_query_chip(); break; - default: fprintf(stdout, "* ST018 w3802::%.2x\n", data); break; - } - } return; - - case BoardUpload: { - op_board_upload(data); - } return; - } - } - - if(addr == 0x3804) { - regs.w3804 <<= 8; - regs.w3804 |= data; - regs.w3804 &= 0xffffff; - return; - } -} - -void ST0018::init() { -} - -void ST0018::enable() { -} - -void ST0018::power() { - reset(); -} - -void ST0018::reset() { - regs.mode = Waiting; - regs.r3800 = 0x00; - regs.r3804 = 0x85; - regs.w3804 = 0; - for(unsigned i = 0; i < 97; i++) board[i] = 0; -} - -//=============== -//ST-0018 opcodes -//=============== - -void ST0018::op_board_upload() { - regs.mode = BoardUpload; - regs.counter = 0; - regs.r3800 = 0xe0; -} - -void ST0018::op_board_upload(uint8 data) { - board[regs.counter] = data; - regs.r3800 = 96 - regs.counter; - regs.counter++; - if(regs.counter >= 97) { - regs.mode = Waiting; - #if 0 - for(unsigned y = 0; y < 9; y++) { - for(unsigned x = 0; x < 9; x++) { - fprintf(stdout, "%.2x ", board[y * 9 + x]); - } - fprintf(stdout, "\n"); - } - for(unsigned n = 0; n < 16; n++) fprintf(stdout, "%.2x ", board[81 + n]); - fprintf(stdout, "\n\n"); - #endif - } -} - -void ST0018::op_b2() { - fprintf(stdout, "* ST018 w3802::b2\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 0; //unknown -} - -void ST0018::op_b3() { - fprintf(stdout, "* ST018 w3802::b3\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 1; //0 = player lost? -} - -void ST0018::op_b4() { - fprintf(stdout, "* ST018 w3802::b4\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 1; //0 = player won? -} - -void ST0018::op_b5() { - fprintf(stdout, "* ST018 w3802::b5\n"); - regs.r3800 = 0xe0; - regs.r3800_01 = 0; //1 = move will result in checkmate? -} - -void ST0018::op_query_chip() { - regs.r3800 = 0x00; -} - -} diff --git a/bsnes/chip/st0018/st0018.hpp b/bsnes/chip/st0018/st0018.hpp deleted file mode 100755 index 8a92e934..00000000 --- a/bsnes/chip/st0018/st0018.hpp +++ /dev/null @@ -1,51 +0,0 @@ -class ST0018 : public MMIO { -public: - void init(); - void enable(); - void power(); - void reset(); - - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - enum mode_t { Waiting, BoardUpload }; - struct regs_t { - mode_t mode; - - uint8 r3800; - uint8 r3800_01; - uint8 r3804; - - unsigned w3804; - unsigned counter; - } regs; - - enum PieceID { - Pawn = 0x00, //foot soldier - Lance = 0x04, //incense chariot - Knight = 0x08, //cassia horse - Silver = 0x0c, //silver general - Gold = 0x10, //gold general - Rook = 0x14, //flying chariot - Bishop = 0x18, //angle mover - King = 0x1c, //king - }; - - enum PieceFlag { - PlayerA = 0x20, - PlayerB = 0x40, - }; - - uint8 board[9 * 9 + 16]; - -private: - void op_board_upload(); - void op_board_upload(uint8 data); - void op_b2(); - void op_b3(); - void op_b4(); - void op_b5(); - void op_query_chip(); -}; - -extern ST0018 st0018; diff --git a/bsnes/chip/superfx/bus/bus.cpp b/bsnes/chip/superfx/bus/bus.cpp deleted file mode 100755 index 8e040308..00000000 --- a/bsnes/chip/superfx/bus/bus.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifdef SUPERFX_CPP - -SuperFXBus superfxbus; - -namespace memory { - SuperFXGSUROM gsurom; - SuperFXGSURAM gsuram; - SuperFXCPUROM fxrom; - SuperFXCPURAM fxram; -} - -void SuperFXBus::init() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x7fff, memory::gsurom); - map(MapMode::Linear, 0x00, 0x3f, 0x8000, 0xffff, memory::gsurom); - map(MapMode::Linear, 0x40, 0x5f, 0x0000, 0xffff, memory::gsurom); - map(MapMode::Linear, 0x60, 0x7f, 0x0000, 0xffff, memory::gsuram); -} - -//ROM / RAM access from the SuperFX CPU - -unsigned SuperFXGSUROM::size() const { - return memory::cartrom.size(); -} - -uint8 SuperFXGSUROM::read(unsigned addr) { - while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - return memory::cartrom.read(addr); -} - -void SuperFXGSUROM::write(unsigned addr, uint8 data) { - while(!superfx.regs.scmr.ron && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - memory::cartrom.write(addr, data); -} - -unsigned SuperFXGSURAM::size() const { - return memory::cartram.size(); -} - -uint8 SuperFXGSURAM::read(unsigned addr) { - while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - return memory::cartram.read(addr); -} - -void SuperFXGSURAM::write(unsigned addr, uint8 data) { - while(!superfx.regs.scmr.ran && scheduler.sync != Scheduler::SynchronizeMode::All) { - superfx.add_clocks(6); - superfx.synchronize_cpu(); - } - memory::cartram.write(addr, data); -} - -//ROM / RAM access from the S-CPU - -unsigned SuperFXCPUROM::size() const { - return memory::cartrom.size(); -} - -uint8 SuperFXCPUROM::read(unsigned addr) { - if(superfx.regs.sfr.g && superfx.regs.scmr.ron) { - static const uint8_t data[16] = { - 0x00, 0x01, 0x00, 0x01, 0x04, 0x01, 0x00, 0x01, - 0x00, 0x01, 0x08, 0x01, 0x00, 0x01, 0x0c, 0x01, - }; - return data[addr & 15]; - } - return memory::cartrom.read(addr); -} - -void SuperFXCPUROM::write(unsigned addr, uint8 data) { - memory::cartrom.write(addr, data); -} - -unsigned SuperFXCPURAM::size() const { - return memory::cartram.size(); -} - -uint8 SuperFXCPURAM::read(unsigned addr) { - if(superfx.regs.sfr.g && superfx.regs.scmr.ran) return cpu.regs.mdr; - return memory::cartram.read(addr); -} - -void SuperFXCPURAM::write(unsigned addr, uint8 data) { - memory::cartram.write(addr, data); -} - -#endif diff --git a/bsnes/chip/superfx/bus/bus.hpp b/bsnes/chip/superfx/bus/bus.hpp deleted file mode 100755 index dd615c65..00000000 --- a/bsnes/chip/superfx/bus/bus.hpp +++ /dev/null @@ -1,34 +0,0 @@ -struct SuperFXBus : Bus { - void init(); -}; - -struct SuperFXGSUROM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct SuperFXGSURAM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct SuperFXCPUROM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct SuperFXCPURAM : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -namespace memory { - extern SuperFXGSUROM gsurom; - extern SuperFXGSURAM gsuram; - extern SuperFXCPUROM fxrom; - extern SuperFXCPURAM fxram; -} diff --git a/bsnes/chip/superfx/core/core.cpp b/bsnes/chip/superfx/core/core.cpp deleted file mode 100755 index 229ad24e..00000000 --- a/bsnes/chip/superfx/core/core.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#ifdef SUPERFX_CPP - -#include "opcodes.cpp" -#include "opcode_table.cpp" - -uint8 SuperFX::color(uint8 source) { - if(regs.por.highnibble) return (regs.colr & 0xf0) | (source >> 4); - if(regs.por.freezehigh) return (regs.colr & 0xf0) | (source & 0x0f); - return source; -} - -void SuperFX::plot(uint8 x, uint8 y) { - uint8 color = regs.colr; - - if(regs.por.dither && regs.scmr.md != 3) { - if((x ^ y) & 1) color >>= 4; - color &= 0x0f; - } - - if(!regs.por.transparent) { - if(regs.scmr.md == 3) { - if(regs.por.freezehigh) { - if((color & 0x0f) == 0) return; - } else { - if(color == 0) return; - } - } else { - if((color & 0x0f) == 0) return; - } - } - - uint16 offset = (y << 5) + (x >> 3); - if(offset != pixelcache[0].offset) { - pixelcache_flush(pixelcache[1]); - pixelcache[1] = pixelcache[0]; - pixelcache[0].bitpend = 0x00; - pixelcache[0].offset = offset; - } - - x = (x & 7) ^ 7; - pixelcache[0].data[x] = color; - pixelcache[0].bitpend |= 1 << x; - if(pixelcache[0].bitpend == 0xff) { - pixelcache_flush(pixelcache[1]); - pixelcache[1] = pixelcache[0]; - pixelcache[0].bitpend = 0x00; - } -} - -uint8 SuperFX::rpix(uint8 x, uint8 y) { - pixelcache_flush(pixelcache[1]); - pixelcache_flush(pixelcache[0]); - - unsigned cn; //character number - switch(regs.por.obj ? 3 : regs.scmr.ht) { - case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; - case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; - case 2: cn = ((x & 0xf8) << 1) + ((x & 0xf8) << 0) + ((y & 0xf8) >> 3); break; - case 3: cn = ((y & 0x80) << 2) + ((x & 0x80) << 1) + ((y & 0x78) << 1) + ((x & 0x78) >> 3); break; - } - unsigned bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; - unsigned addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); - uint8 data = 0x00; - x = (x & 7) ^ 7; - - for(unsigned n = 0; n < bpp; n++) { - unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; - add_clocks(memory_access_speed); - data |= ((superfxbus.read(addr + byte) >> x) & 1) << n; - } - - return data; -} - -void SuperFX::pixelcache_flush(pixelcache_t &cache) { - if(cache.bitpend == 0x00) return; - - uint8 x = cache.offset << 3; - uint8 y = cache.offset >> 5; - - unsigned cn; //character number - switch(regs.por.obj ? 3 : regs.scmr.ht) { - case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; - case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; - case 2: cn = ((x & 0xf8) << 1) + ((x & 0xf8) << 0) + ((y & 0xf8) >> 3); break; - case 3: cn = ((y & 0x80) << 2) + ((x & 0x80) << 1) + ((y & 0x78) << 1) + ((x & 0x78) >> 3); break; - } - unsigned bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; - unsigned addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); - - for(unsigned n = 0; n < bpp; n++) { - unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; - uint8 data = 0x00; - for(unsigned x = 0; x < 8; x++) data |= ((cache.data[x] >> n) & 1) << x; - if(cache.bitpend != 0xff) { - add_clocks(memory_access_speed); - data &= cache.bitpend; - data |= superfxbus.read(addr + byte) & ~cache.bitpend; - } - add_clocks(memory_access_speed); - superfxbus.write(addr + byte, data); - } - - cache.bitpend = 0x00; -} - -#endif diff --git a/bsnes/chip/superfx/core/core.hpp b/bsnes/chip/superfx/core/core.hpp deleted file mode 100755 index 1c13f1ce..00000000 --- a/bsnes/chip/superfx/core/core.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#include "registers.hpp" - -uint8 color(uint8 source); -void plot(uint8 x, uint8 y); -uint8 rpix(uint8 x, uint8 y); -void pixelcache_flush(pixelcache_t &cache); - -void (SuperFX::*opcode_table[1024])(); -void initialize_opcode_table(); - -//opcodes.cpp -template void op_adc_i(); -template void op_adc_r(); -template void op_add_i(); -template void op_add_r(); -void op_alt1(); -void op_alt2(); -void op_alt3(); -template void op_and_i(); -template void op_and_r(); -void op_asr(); -void op_bge(); -void op_bcc(); -void op_bcs(); -void op_beq(); -template void op_bic_i(); -template void op_bic_r(); -void op_blt(); -void op_bmi(); -void op_bne(); -void op_bpl(); -void op_bra(); -void op_bvc(); -void op_bvs(); -void op_cache(); -void op_cmode(); -template void op_cmp_r(); -void op_color(); -template void op_dec_r(); -void op_div2(); -void op_fmult(); -template void op_from_r(); -void op_getb(); -void op_getbl(); -void op_getbh(); -void op_getbs(); -void op_getc(); -void op_hib(); -template void op_ibt_r(); -template void op_inc_r(); -template void op_iwt_r(); -template void op_jmp_r(); -template void op_ldb_ir(); -template void op_ldw_ir(); -template void op_link(); -template void op_ljmp_r(); -template void op_lm_r(); -template void op_lms_r(); -void op_lmult(); -void op_lob(); -void op_loop(); -void op_lsr(); -void op_merge(); -template void op_mult_i(); -template void op_mult_r(); -void op_nop(); -void op_not(); -template void op_or_i(); -template void op_or_r(); -void op_plot(); -void op_ramb(); -void op_rol(); -void op_romb(); -void op_ror(); -void op_rpix(); -template void op_sbc_r(); -void op_sbk(); -void op_sex(); -template void op_sm_r(); -template void op_sms_r(); -template void op_stb_ir(); -void op_stop(); -template void op_stw_ir(); -template void op_sub_i(); -template void op_sub_r(); -void op_swap(); -template void op_to_r(); -template void op_umult_i(); -template void op_umult_r(); -template void op_with_r(); -template void op_xor_i(); -template void op_xor_r(); diff --git a/bsnes/chip/superfx/core/opcode_table.cpp b/bsnes/chip/superfx/core/opcode_table.cpp deleted file mode 100755 index 79082531..00000000 --- a/bsnes/chip/superfx/core/opcode_table.cpp +++ /dev/null @@ -1,270 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::initialize_opcode_table() { - #define op4(id, name) \ - op(id+ 0, name< 1>) op(id+ 1, name< 2>) op(id+ 2, name< 3>) op(id+ 3, name< 4>) - - #define op6(id, name) \ - op(id+ 0, name< 8>) op(id+ 1, name< 9>) op(id+ 2, name<10>) op(id+ 3, name<11>) \ - op(id+ 4, name<12>) op(id+ 5, name<13>) - - #define op12(id, name) \ - op(id+ 0, name< 0>) op(id+ 1, name< 1>) op(id+ 2, name< 2>) op(id+ 3, name< 3>) \ - op(id+ 4, name< 4>) op(id+ 5, name< 5>) op(id+ 6, name< 6>) op(id+ 7, name< 7>) \ - op(id+ 8, name< 8>) op(id+ 9, name< 9>) op(id+10, name<10>) op(id+11, name<11>) - - #define op15l(id, name) \ - op(id+ 0, name< 0>) op(id+ 1, name< 1>) op(id+ 2, name< 2>) op(id+ 3, name< 3>) \ - op(id+ 4, name< 4>) op(id+ 5, name< 5>) op(id+ 6, name< 6>) op(id+ 7, name< 7>) \ - op(id+ 8, name< 8>) op(id+ 9, name< 9>) op(id+10, name<10>) op(id+11, name<11>) \ - op(id+12, name<12>) op(id+13, name<13>) op(id+14, name<14>) - - #define op15h(id, name) \ - op(id+ 0, name< 1>) op(id+ 1, name< 2>) op(id+ 2, name< 3>) op(id+ 3, name< 4>) \ - op(id+ 4, name< 5>) op(id+ 5, name< 6>) op(id+ 6, name< 7>) op(id+ 7, name< 8>) \ - op(id+ 8, name< 9>) op(id+ 9, name<10>) op(id+10, name<11>) op(id+11, name<12>) \ - op(id+12, name<13>) op(id+13, name<14>) op(id+14, name<15>) - - #define op16(id, name) \ - op(id+ 0, name< 0>) op(id+ 1, name< 1>) op(id+ 2, name< 2>) op(id+ 3, name< 3>) \ - op(id+ 4, name< 4>) op(id+ 5, name< 5>) op(id+ 6, name< 6>) op(id+ 7, name< 7>) \ - op(id+ 8, name< 8>) op(id+ 9, name< 9>) op(id+10, name<10>) op(id+11, name<11>) \ - op(id+12, name<12>) op(id+13, name<13>) op(id+14, name<14>) op(id+15, name<15>) - - //====== - // ALT0 - //====== - - #define op(id, name) opcode_table[ 0 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stw_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldw_ir) - op (0x4c, plot) - op (0x4d, swap) - op (0x4e, color) - op (0x4f, not) - op16 (0x50, add_r) - op16 (0x60, sub_r) - op (0x70, merge) - op15h(0x71, and_r) - op16 (0x80, mult_r) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, asr) - op (0x97, ror) - op6 (0x98, jmp_r) - op (0x9e, lob) - op (0x9f, fmult) - op16 (0xa0, ibt_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, or_r) - op15l(0xd0, inc_r) - op (0xdf, getc) - op15l(0xe0, dec_r) - op (0xef, getb) - op16 (0xf0, iwt_r) - #undef op - - //====== - // ALT1 - //====== - - #define op(id, name) opcode_table[256 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stb_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldb_ir) - op (0x4c, rpix) - op (0x4d, swap) - op (0x4e, cmode) - op (0x4f, not) - op16 (0x50, adc_r) - op16 (0x60, sbc_r) - op (0x70, merge) - op15h(0x71, bic_r) - op16 (0x80, umult_r) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, div2) - op (0x97, ror) - op6 (0x98, ljmp_r) - op (0x9e, lob) - op (0x9f, lmult) - op16 (0xa0, lms_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, xor_r) - op15l(0xd0, inc_r) - op (0xdf, getc) - op15l(0xe0, dec_r) - op (0xef, getbh) - op16 (0xf0, lm_r) - #undef op - - //====== - // ALT2 - //====== - - #define op(id, name) opcode_table[512 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stw_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldw_ir) - op (0x4c, plot) - op (0x4d, swap) - op (0x4e, color) - op (0x4f, not) - op16 (0x50, add_i) - op16 (0x60, sub_i) - op (0x70, merge) - op15h(0x71, and_i) - op16 (0x80, mult_i) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, asr) - op (0x97, ror) - op6 (0x98, jmp_r) - op (0x9e, lob) - op (0x9f, fmult) - op16 (0xa0, sms_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, or_i) - op15l(0xd0, inc_r) - op (0xdf, ramb) - op15l(0xe0, dec_r) - op (0xef, getbl) - op16 (0xf0, sm_r) - #undef op - - //====== - // ALT3 - //====== - - #define op(id, name) opcode_table[768 + id] = &SuperFX::op_##name; - op (0x00, stop) - op (0x01, nop) - op (0x02, cache) - op (0x03, lsr) - op (0x04, rol) - op (0x05, bra) - op (0x06, blt) - op (0x07, bge) - op (0x08, bne) - op (0x09, beq) - op (0x0a, bpl) - op (0x0b, bmi) - op (0x0c, bcc) - op (0x0d, bcs) - op (0x0e, bvc) - op (0x0f, bvs) - op16 (0x10, to_r) - op16 (0x20, with_r) - op12 (0x30, stb_ir) - op (0x3c, loop) - op (0x3d, alt1) - op (0x3e, alt2) - op (0x3f, alt3) - op12 (0x40, ldb_ir) - op (0x4c, rpix) - op (0x4d, swap) - op (0x4e, cmode) - op (0x4f, not) - op16 (0x50, adc_i) - op16 (0x60, cmp_r) - op (0x70, merge) - op15h(0x71, bic_i) - op16 (0x80, umult_i) - op (0x90, sbk) - op4 (0x91, link) - op (0x95, sex) - op (0x96, div2) - op (0x97, ror) - op6 (0x98, ljmp_r) - op (0x9e, lob) - op (0x9f, lmult) - op16 (0xa0, lms_r) - op16 (0xb0, from_r) - op (0xc0, hib) - op15h(0xc1, xor_i) - op15l(0xd0, inc_r) - op (0xdf, romb) - op15l(0xe0, dec_r) - op (0xef, getbs) - op16 (0xf0, lm_r) - #undef op - - #undef op4 - #undef op6 - #undef op12 - #undef op15l - #undef op15h - #undef op16 -} - -#endif diff --git a/bsnes/chip/superfx/core/opcodes.cpp b/bsnes/chip/superfx/core/opcodes.cpp deleted file mode 100755 index 7d2f13a2..00000000 --- a/bsnes/chip/superfx/core/opcodes.cpp +++ /dev/null @@ -1,661 +0,0 @@ -#ifdef SUPERFX_CPP - -//$00 stop -void SuperFX::op_stop() { - if(regs.cfgr.irq == 0) { - regs.sfr.irq = 1; - cpu.regs.irq = 1; - } - - regs.sfr.g = 0; - regs.pipeline = 0x01; - regs.reset(); -} - -//$01 nop -void SuperFX::op_nop() { - regs.reset(); -} - -//$02 cache -void SuperFX::op_cache() { - if(regs.cbr != (regs.r[15] & 0xfff0)) { - regs.cbr = regs.r[15] & 0xfff0; - cache_flush(); - } - regs.reset(); -} - -//$03 lsr -void SuperFX::op_lsr() { - regs.sfr.cy = (regs.sr() & 1); - regs.dr() = regs.sr() >> 1; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$04 rol -void SuperFX::op_rol() { - bool carry = (regs.sr() & 0x8000); - regs.dr() = (regs.sr() << 1) | regs.sfr.cy; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = carry; - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$05 bra e -void SuperFX::op_bra() { - regs.r[15] += (int8)pipe(); -} - -//$06 blt e -void SuperFX::op_blt() { - int e = (int8)pipe(); - if((regs.sfr.s ^ regs.sfr.ov) == 0) regs.r[15] += e; -} - -//$07 bge e -void SuperFX::op_bge() { - int e = (int8)pipe(); - if((regs.sfr.s ^ regs.sfr.ov) == 1) regs.r[15] += e; -} - -//$08 bne e -void SuperFX::op_bne() { - int e = (int8)pipe(); - if(regs.sfr.z == 0) regs.r[15] += e; -} - -//$09 beq e -void SuperFX::op_beq() { - int e = (int8)pipe(); - if(regs.sfr.z == 1) regs.r[15] += e; -} - -//$0a bpl e -void SuperFX::op_bpl() { - int e = (int8)pipe(); - if(regs.sfr.s == 0) regs.r[15] += e; -} - -//$0b bmi e -void SuperFX::op_bmi() { - int e = (int8)pipe(); - if(regs.sfr.s == 1) regs.r[15] += e; -} - -//$0c bcc e -void SuperFX::op_bcc() { - int e = (int8)pipe(); - if(regs.sfr.cy == 0) regs.r[15] += e; -} - -//$0d bcs e -void SuperFX::op_bcs() { - int e = (int8)pipe(); - if(regs.sfr.cy == 1) regs.r[15] += e; -} - -//$0e bvc e -void SuperFX::op_bvc() { - int e = (int8)pipe(); - if(regs.sfr.ov == 0) regs.r[15] += e; -} - -//$0f bvs e -void SuperFX::op_bvs() { - int e = (int8)pipe(); - if(regs.sfr.ov == 1) regs.r[15] += e; -} - -//$10-1f(b0): to rN -//$10-1f(b1): move rN -template void SuperFX::op_to_r() { - if(regs.sfr.b == 0) { - regs.dreg = n; - } else { - regs.r[n] = regs.sr(); - regs.reset(); - } -} - -//$20-2f: with rN -template void SuperFX::op_with_r() { - regs.sreg = n; - regs.dreg = n; - regs.sfr.b = 1; -} - -//$30-3b(alt0): stw (rN) -template void SuperFX::op_stw_ir() { - regs.ramaddr = regs.r[n]; - rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); - regs.reset(); -} - -//$30-3b(alt1): stb (rN) -template void SuperFX::op_stb_ir() { - regs.ramaddr = regs.r[n]; - rambuffer_write(regs.ramaddr, regs.sr()); - regs.reset(); -} - -//$3c loop -void SuperFX::op_loop() { - regs.r[12]--; - regs.sfr.s = (regs.r[12] & 0x8000); - regs.sfr.z = (regs.r[12] == 0); - if(!regs.sfr.z) regs.r[15] = regs.r[13]; - regs.reset(); -} - -//$3d alt1 -void SuperFX::op_alt1() { - regs.sfr.b = 0; - regs.sfr.alt1 = 1; -} - -//$3e alt2 -void SuperFX::op_alt2() { - regs.sfr.b = 0; - regs.sfr.alt2 = 1; -} - -//$3f alt3 -void SuperFX::op_alt3() { - regs.sfr.b = 0; - regs.sfr.alt1 = 1; - regs.sfr.alt2 = 1; -} - -//$40-4b(alt0): ldw (rN) -template void SuperFX::op_ldw_ir() { - regs.ramaddr = regs.r[n]; - uint16_t data; - data = rambuffer_read(regs.ramaddr ^ 0) << 0; - data |= rambuffer_read(regs.ramaddr ^ 1) << 8; - regs.dr() = data; - regs.reset(); -} - -//$40-4b(alt1): ldb (rN) -template void SuperFX::op_ldb_ir() { - regs.ramaddr = regs.r[n]; - regs.dr() = rambuffer_read(regs.ramaddr); - regs.reset(); -} - -//$4c(alt0): plot -void SuperFX::op_plot() { - plot(regs.r[1], regs.r[2]); - regs.r[1]++; - regs.reset(); -} - -//$4c(alt1): rpix -void SuperFX::op_rpix() { - regs.dr() = rpix(regs.r[1], regs.r[2]); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$4d: swap -void SuperFX::op_swap() { - regs.dr() = (regs.sr() >> 8) | (regs.sr() << 8); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$4e(alt0): color -void SuperFX::op_color() { - regs.colr = color(regs.sr()); - regs.reset(); -} - -//$4e(alt1): cmode -void SuperFX::op_cmode() { - regs.por = regs.sr(); - regs.reset(); -} - -//$4f: not -void SuperFX::op_not() { - regs.dr() = ~regs.sr(); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$50-5f(alt0): add rN -template void SuperFX::op_add_r() { - int r = regs.sr() + regs.r[n]; - regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$50-5f(alt1): adc rN -template void SuperFX::op_adc_r() { - int r = regs.sr() + regs.r[n] + regs.sfr.cy; - regs.sfr.ov = ~(regs.sr() ^ regs.r[n]) & (regs.r[n] ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$50-5f(alt2): add #N -template void SuperFX::op_add_i() { - int r = regs.sr() + n; - regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$50-5f(alt3): adc #N -template void SuperFX::op_adc_i() { - int r = regs.sr() + n + regs.sfr.cy; - regs.sfr.ov = ~(regs.sr() ^ n) & (n ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0x10000); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt0): sub rN -template void SuperFX::op_sub_r() { - int r = regs.sr() - regs.r[n]; - regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt1): sbc rN -template void SuperFX::op_sbc_r() { - int r = regs.sr() - regs.r[n] - !regs.sfr.cy; - regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt2): sub #N -template void SuperFX::op_sub_i() { - int r = regs.sr() - n; - regs.sfr.ov = (regs.sr() ^ n) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.dr() = r; - regs.reset(); -} - -//$60-6f(alt3): cmp rN -template void SuperFX::op_cmp_r() { - int r = regs.sr() - regs.r[n]; - regs.sfr.ov = (regs.sr() ^ regs.r[n]) & (regs.sr() ^ r) & 0x8000; - regs.sfr.s = (r & 0x8000); - regs.sfr.cy = (r >= 0); - regs.sfr.z = ((uint16_t)r == 0); - regs.reset(); -} - -//$70: merge -void SuperFX::op_merge() { - regs.dr() = (regs.r[7] & 0xff00) | (regs.r[8] >> 8); - regs.sfr.ov = (regs.dr() & 0xc0c0); - regs.sfr.s = (regs.dr() & 0x8080); - regs.sfr.cy = (regs.dr() & 0xe0e0); - regs.sfr.z = (regs.dr() & 0xf0f0); - regs.reset(); -} - -//$71-7f(alt0): and rN -template void SuperFX::op_and_r() { - regs.dr() = regs.sr() & regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$71-7f(alt1): bic rN -template void SuperFX::op_bic_r() { - regs.dr() = regs.sr() & ~regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$71-7f(alt2): and #N -template void SuperFX::op_and_i() { - regs.dr() = regs.sr() & n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$71-7f(alt3): bic #N -template void SuperFX::op_bic_i() { - regs.dr() = regs.sr() & ~n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$80-8f(alt0): mult rN -template void SuperFX::op_mult_r() { - regs.dr() = (int8)regs.sr() * (int8)regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$80-8f(alt1): umult rN -template void SuperFX::op_umult_r() { - regs.dr() = (uint8)regs.sr() * (uint8)regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$80-8f(alt2): mult #N -template void SuperFX::op_mult_i() { - regs.dr() = (int8)regs.sr() * (int8)n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$80-8f(alt3): umult #N -template void SuperFX::op_umult_i() { - regs.dr() = (uint8)regs.sr() * (uint8)n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - if(!regs.cfgr.ms0) add_clocks(2); -} - -//$90: sbk -void SuperFX::op_sbk() { - rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); - regs.reset(); -} - -//$91-94: link #N -template void SuperFX::op_link() { - regs.r[11] = regs.r[15] + n; - regs.reset(); -} - -//$95: sex -void SuperFX::op_sex() { - regs.dr() = (int8)regs.sr(); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$96(alt0): asr -void SuperFX::op_asr() { - regs.sfr.cy = (regs.sr() & 1); - regs.dr() = (int16_t)regs.sr() >> 1; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$96(alt1): div2 -void SuperFX::op_div2() { - regs.sfr.cy = (regs.sr() & 1); - regs.dr() = ((int16_t)regs.sr() >> 1) + ((regs.sr() + 1) >> 16); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$97: ror -void SuperFX::op_ror() { - bool carry = (regs.sr() & 1); - regs.dr() = (regs.sfr.cy << 15) | (regs.sr() >> 1); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = carry; - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$98-9d(alt0): jmp rN -template void SuperFX::op_jmp_r() { - regs.r[15] = regs.r[n]; - regs.reset(); -} - -//$98-9d(alt1): ljmp rN -template void SuperFX::op_ljmp_r() { - regs.pbr = regs.r[n] & 0x7f; - regs.r[15] = regs.sr(); - regs.cbr = regs.r[15] & 0xfff0; - cache_flush(); - regs.reset(); -} - -//$9e: lob -void SuperFX::op_lob() { - regs.dr() = regs.sr() & 0xff; - regs.sfr.s = (regs.dr() & 0x80); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$9f(alt0): fmult -void SuperFX::op_fmult() { - uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6]; - regs.dr() = result >> 16; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = (result & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - add_clocks(4 + (regs.cfgr.ms0 << 2)); -} - -//$9f(alt1): lmult -void SuperFX::op_lmult() { - uint32_t result = (int16_t)regs.sr() * (int16_t)regs.r[6]; - regs.r[4] = result; - regs.dr() = result >> 16; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.cy = (result & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - add_clocks(4 + (regs.cfgr.ms0 << 2)); -} - -//$a0-af(alt0): ibt rN,#pp -template void SuperFX::op_ibt_r() { - regs.r[n] = (int8)pipe(); - regs.reset(); -} - -//$a0-af(alt1): lms rN,(yy) -template void SuperFX::op_lms_r() { - regs.ramaddr = pipe() << 1; - uint16_t data; - data = rambuffer_read(regs.ramaddr ^ 0) << 0; - data |= rambuffer_read(regs.ramaddr ^ 1) << 8; - regs.r[n] = data; - regs.reset(); -} - -//$a0-af(alt2): sms (yy),rN -template void SuperFX::op_sms_r() { - regs.ramaddr = pipe() << 1; - rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8); - regs.reset(); -} - -//$b0-bf(b0): from rN -//$b0-bf(b1): moves rN -template void SuperFX::op_from_r() { - if(regs.sfr.b == 0) { - regs.sreg = n; - } else { - regs.dr() = regs.r[n]; - regs.sfr.ov = (regs.dr() & 0x80); - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); - } -} - -//$c0: hib -void SuperFX::op_hib() { - regs.dr() = regs.sr() >> 8; - regs.sfr.s = (regs.dr() & 0x80); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt0): or rN -template void SuperFX::op_or_r() { - regs.dr() = regs.sr() | regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt1): xor rN -template void SuperFX::op_xor_r() { - regs.dr() = regs.sr() ^ regs.r[n]; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt2): or #N -template void SuperFX::op_or_i() { - regs.dr() = regs.sr() | n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$c1-cf(alt3): xor #N -template void SuperFX::op_xor_i() { - regs.dr() = regs.sr() ^ n; - regs.sfr.s = (regs.dr() & 0x8000); - regs.sfr.z = (regs.dr() == 0); - regs.reset(); -} - -//$d0-de: inc rN -template void SuperFX::op_inc_r() { - regs.r[n]++; - regs.sfr.s = (regs.r[n] & 0x8000); - regs.sfr.z = (regs.r[n] == 0); - regs.reset(); -} - -//$df(alt0): getc -void SuperFX::op_getc() { - regs.colr = color(rombuffer_read()); - regs.reset(); -} - -//$df(alt2): ramb -void SuperFX::op_ramb() { - rambuffer_sync(); - regs.rambr = regs.sr(); - regs.reset(); -} - -//$df(alt3): romb -void SuperFX::op_romb() { - rombuffer_sync(); - regs.rombr = regs.sr() & 0x7f; - regs.reset(); -} - -//$e0-ee: dec rN -template void SuperFX::op_dec_r() { - regs.r[n]--; - regs.sfr.s = (regs.r[n] & 0x8000); - regs.sfr.z = (regs.r[n] == 0); - regs.reset(); -} - -//$ef(alt0): getb -void SuperFX::op_getb() { - regs.dr() = rombuffer_read(); - regs.reset(); -} - -//$ef(alt1): getbh -void SuperFX::op_getbh() { - regs.dr() = (rombuffer_read() << 8) | (regs.sr() & 0x00ff); - regs.reset(); -} - -//$ef(alt2): getbl -void SuperFX::op_getbl() { - regs.dr() = (regs.sr() & 0xff00) | (rombuffer_read() << 0); - regs.reset(); -} - -//$ef(alt3): getbs -void SuperFX::op_getbs() { - regs.dr() = (int8)rombuffer_read(); - regs.reset(); -} - -//$f0-ff(alt0): iwt rN,#xx -template void SuperFX::op_iwt_r() { - uint16_t data; - data = pipe() << 0; - data |= pipe() << 8; - regs.r[n] = data; - regs.reset(); -} - -//$f0-ff(alt1): lm rN,(xx) -template void SuperFX::op_lm_r() { - regs.ramaddr = pipe() << 0; - regs.ramaddr |= pipe() << 8; - uint16_t data; - data = rambuffer_read(regs.ramaddr ^ 0) << 0; - data |= rambuffer_read(regs.ramaddr ^ 1) << 8; - regs.r[n] = data; - regs.reset(); -} - -//$f0-ff(alt2): sm (xx),rN -template void SuperFX::op_sm_r() { - regs.ramaddr = pipe() << 0; - regs.ramaddr |= pipe() << 8; - rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8); - regs.reset(); -} - -#endif diff --git a/bsnes/chip/superfx/core/registers.hpp b/bsnes/chip/superfx/core/registers.hpp deleted file mode 100755 index ac193a8a..00000000 --- a/bsnes/chip/superfx/core/registers.hpp +++ /dev/null @@ -1,176 +0,0 @@ -//accepts a callback binding so r14 writes can trigger ROM buffering transparently -struct reg16_t { - uint16 data; - function on_modify; - - inline operator unsigned() const { return data; } - inline uint16 assign(uint16 i) { - if(on_modify) on_modify(i); - else data = i; - return data; - } - - inline unsigned operator++() { return assign(data + 1); } - inline unsigned operator--() { return assign(data - 1); } - inline unsigned operator++(int) { unsigned r = data; assign(data + 1); return r; } - inline unsigned operator--(int) { unsigned r = data; assign(data - 1); return r; } - inline unsigned operator = (unsigned i) { return assign(i); } - inline unsigned operator |= (unsigned i) { return assign(data | i); } - inline unsigned operator ^= (unsigned i) { return assign(data ^ i); } - inline unsigned operator &= (unsigned i) { return assign(data & i); } - inline unsigned operator <<= (unsigned i) { return assign(data << i); } - inline unsigned operator >>= (unsigned i) { return assign(data >> i); } - inline unsigned operator += (unsigned i) { return assign(data + i); } - inline unsigned operator -= (unsigned i) { return assign(data - i); } - inline unsigned operator *= (unsigned i) { return assign(data * i); } - inline unsigned operator /= (unsigned i) { return assign(data / i); } - inline unsigned operator %= (unsigned i) { return assign(data % i); } - - inline unsigned operator = (const reg16_t& i) { return assign(i); } - - reg16_t() : data(0) {} - reg16_t(const reg16_t&) = delete; -}; - -struct sfr_t { - bool irq; //interrupt flag - bool b; //WITH flag - bool ih; //immediate higher 8-bit flag - bool il; //immediate lower 8-bit flag - bool alt2; //ALT2 mode - bool alt1; //ALT2 instruction mode - bool r; //ROM r14 read flag - bool g; //GO flag - bool ov; //overflow flag - bool s; //sign flag - bool cy; //carry flag - bool z; //zero flag - - operator unsigned() const { - return (irq << 15) | (b << 12) | (ih << 11) | (il << 10) | (alt2 << 9) | (alt1 << 8) - | (r << 6) | (g << 5) | (ov << 4) | (s << 3) | (cy << 2) | (z << 1); - } - - sfr_t& operator=(uint16_t data) { - irq = data & 0x8000; - b = data & 0x1000; - ih = data & 0x0800; - il = data & 0x0400; - alt2 = data & 0x0200; - alt1 = data & 0x0100; - r = data & 0x0040; - g = data & 0x0020; - ov = data & 0x0010; - s = data & 0x0008; - cy = data & 0x0004; - z = data & 0x0002; - return *this; - } -}; - -struct scmr_t { - unsigned ht; - bool ron; - bool ran; - unsigned md; - - operator unsigned() const { - return ((ht >> 1) << 5) | (ron << 4) | (ran << 3) | ((ht & 1) << 2) | (md); - } - - scmr_t& operator=(uint8 data) { - ht = (bool)(data & 0x20) << 1; - ht |= (bool)(data & 0x04) << 0; - ron = data & 0x10; - ran = data & 0x08; - md = data & 0x03; - return *this; - } -}; - -struct por_t { - bool obj; - bool freezehigh; - bool highnibble; - bool dither; - bool transparent; - - operator unsigned() const { - return (obj << 4) | (freezehigh << 3) | (highnibble << 2) | (dither << 1) | (transparent); - } - - por_t& operator=(uint8 data) { - obj = data & 0x10; - freezehigh = data & 0x08; - highnibble = data & 0x04; - dither = data & 0x02; - transparent = data & 0x01; - return *this; - } -}; - -struct cfgr_t { - bool irq; - bool ms0; - - operator unsigned() const { - return (irq << 7) | (ms0 << 5); - } - - cfgr_t& operator=(uint8 data) { - irq = data & 0x80; - ms0 = data & 0x20; - return *this; - } -}; - -struct regs_t { - uint8 pipeline; - uint16 ramaddr; - - reg16_t r[16]; //general purpose registers - sfr_t sfr; //status flag register - uint8 pbr; //program bank register - uint8 rombr; //game pack ROM bank register - bool rambr; //game pack RAM bank register - uint16 cbr; //cache base register - uint8 scbr; //screen base register - scmr_t scmr; //screen mode register - uint8 colr; //color register - por_t por; //plot option register - bool bramr; //back-up RAM register - uint8 vcr; //version code register - cfgr_t cfgr; //config register - bool clsr; //clock select register - - unsigned romcl; //clock ticks until romdr is valid - uint8 romdr; //ROM buffer data register - - unsigned ramcl; //clock ticks until ramdr is valid - uint16 ramar; //RAM buffer address register - uint8 ramdr; //RAM buffer data register - - unsigned sreg, dreg; - reg16_t& sr() { return r[sreg]; } //source register (from) - reg16_t& dr() { return r[dreg]; } //destination register (to) - - void reset() { - sfr.b = 0; - sfr.alt1 = 0; - sfr.alt2 = 0; - - sreg = 0; - dreg = 0; - } -} regs; - -struct cache_t { - uint8 buffer[512]; - bool valid[32]; -} cache; - -struct pixelcache_t { - uint16 offset; - uint8 bitpend; - uint8 data[8]; -} pixelcache[2]; diff --git a/bsnes/chip/superfx/disasm/disasm.cpp b/bsnes/chip/superfx/disasm/disasm.cpp deleted file mode 100755 index c2d3e387..00000000 --- a/bsnes/chip/superfx/disasm/disasm.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::disassemble_opcode(char *output) { - *output = 0; - - if(!regs.sfr.alt2) { - if(!regs.sfr.alt1) { - disassemble_alt0(output); - } else { - disassemble_alt1(output); - } - } else { - if(!regs.sfr.alt1) { - disassemble_alt2(output); - } else { - disassemble_alt3(output); - } - } - - unsigned length = strlen(output); - while(length++ < 20) strcat(output, " "); -} - -#define case4(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3 -#define case6(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5 -#define case12(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \ - case id+ 8: case id+ 9: case id+10: case id+11 -#define case15(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \ - case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14 -#define case16(id) \ - case id+ 0: case id+ 1: case id+ 2: case id+ 3: case id+ 4: case id+ 5: case id+ 6: case id+ 7: \ - case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14: case id+15 - -#define op0 regs.pipeline -#define op1 superfxbus.read((regs.pbr << 16) + regs.r[15] + 0) -#define op2 superfxbus.read((regs.pbr << 16) + regs.r[15] + 1) - -void SuperFX::disassemble_alt0(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stw (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldw (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "plot"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "color"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "add r%u", op0 & 15); break; - case16(0x60): sprintf(t, "sub r%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "and r%u", op0 & 15); break; - case16(0x80): sprintf(t, "mult r%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "asr"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "jmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "fmult"); break; - case16(0xa0): sprintf(t, "ibt r%u,#$%.2x", op0 & 15, op1); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); - case15(0xc1): sprintf(t, "or r%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "getc"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getb"); break; - case16(0xf0): sprintf(t, "iwt r%u,#$%.2x%.2x", op0 & 15, op2, op1); break; - } - strcat(output, t); -} - -void SuperFX::disassemble_alt1(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stb (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldb (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "rpix"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "cmode"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "adc r%u", op0 & 15); break; - case16(0x60): sprintf(t, "sbc r%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "bic r%u", op0 & 15); break; - case16(0x80): sprintf(t, "umult r%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "div2"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "ljmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "lmult"); break; - case16(0xa0): sprintf(t, "lms r%u,(#$%.4x)", op0 & 15, op1 << 1); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); break; - case15(0xc1): sprintf(t, "xor r%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "getc"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getbh"); break; - case16(0xf0): sprintf(t, "lm r%u", op0 & 15); break; - } - strcat(output, t); -} - -void SuperFX::disassemble_alt2(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stw (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldw (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "plot"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "color"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "add #%u", op0 & 15); break; - case16(0x60): sprintf(t, "sub #%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "and #%u", op0 & 15); break; - case16(0x80): sprintf(t, "mult #%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "asr"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "jmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "fmult"); break; - case16(0xa0): sprintf(t, "sms r%u,(#$%.4x)", op0 & 15, op1 << 1); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); break; - case15(0xc1): sprintf(t, "or #%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "ramb"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getbl"); break; - case16(0xf0): sprintf(t, "sm r%u", op0 & 15); break; - } - strcat(output, t); -} - -void SuperFX::disassemble_alt3(char *output) { - char t[256] = ""; - switch(op0) { - case (0x00): sprintf(t, "stop"); break; - case (0x01): sprintf(t, "nop"); break; - case (0x02): sprintf(t, "cache"); break; - case (0x03): sprintf(t, "lsr"); break; - case (0x04): sprintf(t, "rol"); break; - case (0x05): sprintf(t, "bra %+d", (int8_t)op1); break; - case (0x06): sprintf(t, "blt %+d", (int8_t)op1); break; - case (0x07): sprintf(t, "bge %+d", (int8_t)op1); break; - case (0x08): sprintf(t, "bne %+d", (int8_t)op1); break; - case (0x09): sprintf(t, "beq %+d", (int8_t)op1); break; - case (0x0a): sprintf(t, "bpl %+d", (int8_t)op1); break; - case (0x0b): sprintf(t, "bmi %+d", (int8_t)op1); break; - case (0x0c): sprintf(t, "bcc %+d", (int8_t)op1); break; - case (0x0d): sprintf(t, "bcs %+d", (int8_t)op1); break; - case (0x0e): sprintf(t, "bvc %+d", (int8_t)op1); break; - case (0x0f): sprintf(t, "bvs %+d", (int8_t)op1); break; - case16(0x10): sprintf(t, "to r%u", op0 & 15); break; - case16(0x20): sprintf(t, "with r%u", op0 & 15); break; - case12(0x30): sprintf(t, "stb (r%u)", op0 & 15); break; - case (0x3c): sprintf(t, "loop"); break; - case (0x3d): sprintf(t, "alt1"); break; - case (0x3e): sprintf(t, "alt2"); break; - case (0x3f): sprintf(t, "alt3"); break; - case12(0x40): sprintf(t, "ldb (r%u)", op0 & 15); break; - case (0x4c): sprintf(t, "rpix"); break; - case (0x4d): sprintf(t, "swap"); break; - case (0x4e): sprintf(t, "cmode"); break; - case (0x4f): sprintf(t, "not"); break; - case16(0x50): sprintf(t, "adc #%u", op0 & 15); break; - case16(0x60): sprintf(t, "cmp r%u", op0 & 15); break; - case (0x70): sprintf(t, "merge"); break; - case15(0x71): sprintf(t, "bic #%u", op0 & 15); break; - case16(0x80): sprintf(t, "umult #%u", op0 & 15); break; - case (0x90): sprintf(t, "sbk"); break; - case4 (0x91): sprintf(t, "link #%u", op0 & 15); break; - case (0x95): sprintf(t, "sex"); break; - case (0x96): sprintf(t, "div2"); break; - case (0x97): sprintf(t, "ror"); break; - case6 (0x98): sprintf(t, "ljmp r%u", op0 & 15); break; - case (0x9e): sprintf(t, "lob"); break; - case (0x9f): sprintf(t, "lmult"); break; - case16(0xa0): sprintf(t, "lms r%u", op0 & 15); break; - case16(0xb0): sprintf(t, "from r%u", op0 & 15); break; - case (0xc0): sprintf(t, "hib"); break; - case15(0xc1): sprintf(t, "xor #%u", op0 & 15); break; - case15(0xd0): sprintf(t, "inc r%u", op0 & 15); break; - case (0xdf): sprintf(t, "romb"); break; - case15(0xe0): sprintf(t, "dec r%u", op0 & 15); break; - case (0xef): sprintf(t, "getbs"); break; - case16(0xf0): sprintf(t, "lm r%u", op0 & 15); break; - } - strcat(output, t); -} - -#undef case4 -#undef case6 -#undef case12 -#undef case15 -#undef case16 -#undef op0 -#undef op1 -#undef op2 - -#endif diff --git a/bsnes/chip/superfx/disasm/disasm.hpp b/bsnes/chip/superfx/disasm/disasm.hpp deleted file mode 100755 index 903615eb..00000000 --- a/bsnes/chip/superfx/disasm/disasm.hpp +++ /dev/null @@ -1,5 +0,0 @@ -void disassemble_opcode(char *output); -void disassemble_alt0(char *output); -void disassemble_alt1(char *output); -void disassemble_alt2(char *output); -void disassemble_alt3(char *output); diff --git a/bsnes/chip/superfx/memory/memory.cpp b/bsnes/chip/superfx/memory/memory.cpp deleted file mode 100755 index 9ae6091c..00000000 --- a/bsnes/chip/superfx/memory/memory.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifdef SUPERFX_CPP - -uint8 SuperFX::op_read(uint16 addr) { - uint16 offset = addr - regs.cbr; - if(offset < 512) { - if(cache.valid[offset >> 4] == false) { - unsigned dp = offset & 0xfff0; - unsigned sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0); - for(unsigned n = 0; n < 16; n++) { - add_clocks(memory_access_speed); - cache.buffer[dp++] = superfxbus.read(sp++); - } - cache.valid[offset >> 4] = true; - } else { - add_clocks(cache_access_speed); - } - return cache.buffer[offset]; - } - - if(regs.pbr <= 0x5f) { - //$[00-5f]:[0000-ffff] ROM - rombuffer_sync(); - add_clocks(memory_access_speed); - return superfxbus.read((regs.pbr << 16) + addr); - } else { - //$[60-7f]:[0000-ffff] RAM - rambuffer_sync(); - add_clocks(memory_access_speed); - return superfxbus.read((regs.pbr << 16) + addr); - } -} - -uint8 SuperFX::peekpipe() { - uint8 result = regs.pipeline; - regs.pipeline = op_read(regs.r[15]); - r15_modified = false; - return result; -} - -uint8 SuperFX::pipe() { - uint8 result = regs.pipeline; - regs.pipeline = op_read(++regs.r[15]); - r15_modified = false; - return result; -} - -void SuperFX::cache_flush() { - for(unsigned n = 0; n < 32; n++) cache.valid[n] = false; -} - -uint8 SuperFX::cache_mmio_read(uint16 addr) { - addr = (addr + regs.cbr) & 511; - return cache.buffer[addr]; -} - -void SuperFX::cache_mmio_write(uint16 addr, uint8 data) { - addr = (addr + regs.cbr) & 511; - cache.buffer[addr] = data; - if((addr & 15) == 15) cache.valid[addr >> 4] = true; -} - -void SuperFX::memory_reset() { - for(unsigned n = 0; n < 512; n++) cache.buffer[n] = 0x00; - for(unsigned n = 0; n < 32; n++) cache.valid[n] = false; - for(unsigned n = 0; n < 2; n++) { - pixelcache[n].offset = ~0; - pixelcache[n].bitpend = 0x00; - } -} - -#endif diff --git a/bsnes/chip/superfx/memory/memory.hpp b/bsnes/chip/superfx/memory/memory.hpp deleted file mode 100755 index 3b11a3f9..00000000 --- a/bsnes/chip/superfx/memory/memory.hpp +++ /dev/null @@ -1,9 +0,0 @@ -uint8 op_read(uint16 addr); -alwaysinline uint8 peekpipe(); -alwaysinline uint8 pipe(); - -void cache_flush(); -uint8 cache_mmio_read(uint16 addr); -void cache_mmio_write(uint16 addr, uint8 data); - -void memory_reset(); diff --git a/bsnes/chip/superfx/mmio/mmio.cpp b/bsnes/chip/superfx/mmio/mmio.cpp deleted file mode 100755 index 7bf43b1d..00000000 --- a/bsnes/chip/superfx/mmio/mmio.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#ifdef SUPERFX_CPP - -uint8 SuperFX::mmio_read(unsigned addr) { - cpu.synchronize_coprocessor(); - addr &= 0xffff; - - if(addr >= 0x3100 && addr <= 0x32ff) { - return cache_mmio_read(addr - 0x3100); - } - - if(addr >= 0x3000 && addr <= 0x301f) { - return regs.r[(addr >> 1) & 15] >> ((addr & 1) << 3); - } - - switch(addr) { - case 0x3030: { - return regs.sfr >> 0; - } - - case 0x3031: { - uint8 r = regs.sfr >> 8; - regs.sfr.irq = 0; - cpu.regs.irq = 0; - return r; - } - - case 0x3034: { - return regs.pbr; - } - - case 0x3036: { - return regs.rombr; - } - - case 0x303b: { - return regs.vcr; - } - - case 0x303c: { - return regs.rambr; - } - - case 0x303e: { - return regs.cbr >> 0; - } - - case 0x303f: { - return regs.cbr >> 8; - } - } - - return 0x00; -} - -void SuperFX::mmio_write(unsigned addr, uint8 data) { - cpu.synchronize_coprocessor(); - addr &= 0xffff; - - if(addr >= 0x3100 && addr <= 0x32ff) { - return cache_mmio_write(addr - 0x3100, data); - } - - if(addr >= 0x3000 && addr <= 0x301f) { - unsigned n = (addr >> 1) & 15; - if((addr & 1) == 0) { - regs.r[n] = (regs.r[n] & 0xff00) | data; - } else { - regs.r[n] = (data << 8) | (regs.r[n] & 0xff); - } - - if(addr == 0x301f) regs.sfr.g = 1; - return; - } - - switch(addr) { - case 0x3030: { - bool g = regs.sfr.g; - regs.sfr = (regs.sfr & 0xff00) | (data << 0); - if(g == 1 && regs.sfr.g == 0) { - regs.cbr = 0x0000; - cache_flush(); - } - } break; - - case 0x3031: { - regs.sfr = (data << 8) | (regs.sfr & 0x00ff); - } break; - - case 0x3033: { - regs.bramr = data; - } break; - - case 0x3034: { - regs.pbr = data & 0x7f; - cache_flush(); - } break; - - case 0x3037: { - regs.cfgr = data; - update_speed(); - } break; - - case 0x3038: { - regs.scbr = data; - } break; - - case 0x3039: { - regs.clsr = data; - update_speed(); - } break; - - case 0x303a: { - regs.scmr = data; - } break; - } -} - -#endif diff --git a/bsnes/chip/superfx/mmio/mmio.hpp b/bsnes/chip/superfx/mmio/mmio.hpp deleted file mode 100755 index 08cc85a9..00000000 --- a/bsnes/chip/superfx/mmio/mmio.hpp +++ /dev/null @@ -1,2 +0,0 @@ -uint8 mmio_read(unsigned addr); -void mmio_write(unsigned addr, uint8 data); diff --git a/bsnes/chip/superfx/serialization.cpp b/bsnes/chip/superfx/serialization.cpp deleted file mode 100755 index 67e5385b..00000000 --- a/bsnes/chip/superfx/serialization.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::serialize(serializer &s) { - Processor::serialize(s); - - //superfx.hpp - s.integer(clockmode); - s.integer(instruction_counter); - - //core/registers.hpp - s.integer(regs.pipeline); - s.integer(regs.ramaddr); - - s.integer(regs.r[ 0].data); - s.integer(regs.r[ 1].data); - s.integer(regs.r[ 2].data); - s.integer(regs.r[ 3].data); - s.integer(regs.r[ 4].data); - s.integer(regs.r[ 5].data); - s.integer(regs.r[ 6].data); - s.integer(regs.r[ 7].data); - s.integer(regs.r[ 8].data); - s.integer(regs.r[ 9].data); - s.integer(regs.r[10].data); - s.integer(regs.r[11].data); - s.integer(regs.r[12].data); - s.integer(regs.r[13].data); - s.integer(regs.r[14].data); - s.integer(regs.r[15].data); - - s.integer(regs.sfr.irq); - s.integer(regs.sfr.b); - s.integer(regs.sfr.ih); - s.integer(regs.sfr.il); - s.integer(regs.sfr.alt2); - s.integer(regs.sfr.alt1); - s.integer(regs.sfr.r); - s.integer(regs.sfr.g); - s.integer(regs.sfr.ov); - s.integer(regs.sfr.s); - s.integer(regs.sfr.cy); - s.integer(regs.sfr.z); - - s.integer(regs.pbr); - s.integer(regs.rombr); - s.integer(regs.rambr); - s.integer(regs.cbr); - s.integer(regs.scbr); - - s.integer(regs.scmr.ht); - s.integer(regs.scmr.ron); - s.integer(regs.scmr.ran); - s.integer(regs.scmr.md); - - s.integer(regs.colr); - - s.integer(regs.por.obj); - s.integer(regs.por.freezehigh); - s.integer(regs.por.highnibble); - s.integer(regs.por.dither); - s.integer(regs.por.transparent); - - s.integer(regs.bramr); - s.integer(regs.vcr); - - s.integer(regs.cfgr.irq); - s.integer(regs.cfgr.ms0); - - s.integer(regs.clsr); - - s.integer(regs.romcl); - s.integer(regs.romdr); - - s.integer(regs.ramcl); - s.integer(regs.ramar); - s.integer(regs.ramdr); - - s.integer(regs.sreg); - s.integer(regs.dreg); - - s.array(cache.buffer); - s.array(cache.valid); - - for(unsigned i = 0; i < 2; i++) { - s.integer(pixelcache[i].offset); - s.integer(pixelcache[i].bitpend); - s.array(pixelcache[i].data); - } - - //timing/timing.hpp - s.integer(cache_access_speed); - s.integer(memory_access_speed); - s.integer(r15_modified); -} - -#endif diff --git a/bsnes/chip/superfx/superfx.cpp b/bsnes/chip/superfx/superfx.cpp deleted file mode 100755 index 89eaf18b..00000000 --- a/bsnes/chip/superfx/superfx.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include - -#define SUPERFX_CPP -namespace SNES { - -#include "serialization.cpp" -#include "bus/bus.cpp" -#include "core/core.cpp" -#include "memory/memory.cpp" -#include "mmio/mmio.cpp" -#include "timing/timing.cpp" -#include "disasm/disasm.cpp" - -SuperFX superfx; - -void SuperFX::Enter() { superfx.enter(); } - -void SuperFX::enter() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(regs.sfr.g == 0) { - add_clocks(6); - synchronize_cpu(); - continue; - } - - (this->*opcode_table[(regs.sfr & 0x0300) + peekpipe()])(); - if(r15_modified == false) regs.r[15]++; - - if(++instruction_counter >= 128) { - instruction_counter = 0; - synchronize_cpu(); - } - } -} - -void SuperFX::init() { - initialize_opcode_table(); - regs.r[14].on_modify = { &SuperFX::r14_modify, this }; - regs.r[15].on_modify = { &SuperFX::r15_modify, this }; -} - -void SuperFX::enable() { -} - -void SuperFX::power() { - clockmode = config.superfx.speed; - reset(); -} - -void SuperFX::reset() { - create(SuperFX::Enter, system.cpu_frequency()); - superfxbus.init(); - instruction_counter = 0; - - for(unsigned n = 0; n < 16; n++) regs.r[n] = 0x0000; - regs.sfr = 0x0000; - regs.pbr = 0x00; - regs.rombr = 0x00; - regs.rambr = 0; - regs.cbr = 0x0000; - regs.scbr = 0x00; - regs.scmr = 0x00; - regs.colr = 0x00; - regs.por = 0x00; - regs.bramr = 0; - regs.vcr = 0x04; - regs.cfgr = 0x00; - regs.clsr = 0; - regs.pipeline = 0x01; //nop - regs.ramaddr = 0x0000; - regs.reset(); - - memory_reset(); - timing_reset(); -} - -} diff --git a/bsnes/chip/superfx/superfx.hpp b/bsnes/chip/superfx/superfx.hpp deleted file mode 100755 index ac2059fb..00000000 --- a/bsnes/chip/superfx/superfx.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "bus/bus.hpp" - -class SuperFX : public Coprocessor, public MMIO { -public: - #include "core/core.hpp" - #include "memory/memory.hpp" - #include "mmio/mmio.hpp" - #include "timing/timing.hpp" - #include "disasm/disasm.hpp" - - static void Enter(); - void enter(); - void init(); - void enable(); - void power(); - void reset(); - void serialize(serializer&); - -private: - unsigned clockmode; - unsigned instruction_counter; -}; - -extern SuperFX superfx; -extern SuperFXBus superfxbus; diff --git a/bsnes/chip/superfx/timing/timing.cpp b/bsnes/chip/superfx/timing/timing.cpp deleted file mode 100755 index aae7820b..00000000 --- a/bsnes/chip/superfx/timing/timing.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifdef SUPERFX_CPP - -void SuperFX::add_clocks(unsigned clocks) { - if(regs.romcl) { - regs.romcl -= min(clocks, regs.romcl); - if(regs.romcl == 0) { - regs.sfr.r = 0; - regs.romdr = superfxbus.read((regs.rombr << 16) + regs.r[14]); - } - } - - if(regs.ramcl) { - regs.ramcl -= min(clocks, regs.ramcl); - if(regs.ramcl == 0) { - superfxbus.write(0x700000 + (regs.rambr << 16) + regs.ramar, regs.ramdr); - } - } - - step(clocks); - synchronize_cpu(); -} - -void SuperFX::rombuffer_sync() { - if(regs.romcl) add_clocks(regs.romcl); -} - -void SuperFX::rombuffer_update() { - regs.sfr.r = 1; - regs.romcl = memory_access_speed; -} - -uint8 SuperFX::rombuffer_read() { - rombuffer_sync(); - return regs.romdr; -} - -void SuperFX::rambuffer_sync() { - if(regs.ramcl) add_clocks(regs.ramcl); -} - -uint8 SuperFX::rambuffer_read(uint16 addr) { - rambuffer_sync(); - return superfxbus.read(0x700000 + (regs.rambr << 16) + addr); -} - -void SuperFX::rambuffer_write(uint16 addr, uint8 data) { - rambuffer_sync(); - regs.ramcl = memory_access_speed; - regs.ramar = addr; - regs.ramdr = data; -} - -void SuperFX::r14_modify(uint16 data) { - regs.r[14].data = data; - rombuffer_update(); -} - -void SuperFX::r15_modify(uint16 data) { - regs.r[15].data = data; - r15_modified = true; -} - -void SuperFX::update_speed() { - //force SuperFX1 mode? - if(clockmode == 1) { - cache_access_speed = 2; - memory_access_speed = 6; - return; - } - - //force SuperFX2 mode? - if(clockmode == 2) { - cache_access_speed = 1; - memory_access_speed = 5; - regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode - return; - } - - //default: allow S-CPU to select mode - cache_access_speed = (regs.clsr ? 1 : 2); - memory_access_speed = (regs.clsr ? 5 : 6); - if(regs.clsr) regs.cfgr.ms0 = 0; //cannot use high-speed multiplication in 21MHz mode -} - -void SuperFX::timing_reset() { - update_speed(); - r15_modified = false; - - regs.romcl = 0; - regs.romdr = 0; - - regs.ramcl = 0; - regs.ramar = 0; - regs.ramdr = 0; -} - -#endif diff --git a/bsnes/chip/superfx/timing/timing.hpp b/bsnes/chip/superfx/timing/timing.hpp deleted file mode 100755 index 9ae7e8d4..00000000 --- a/bsnes/chip/superfx/timing/timing.hpp +++ /dev/null @@ -1,19 +0,0 @@ -unsigned cache_access_speed; -unsigned memory_access_speed; -bool r15_modified; - -void add_clocks(unsigned clocks); - -void rombuffer_sync(); -void rombuffer_update(); -uint8 rombuffer_read(); - -void rambuffer_sync(); -uint8 rambuffer_read(uint16 addr); -void rambuffer_write(uint16 addr, uint8 data); - -void r14_modify(uint16); -void r15_modify(uint16); - -void update_speed(); -void timing_reset(); diff --git a/bsnes/chip/supergameboy/serialization.cpp b/bsnes/chip/supergameboy/serialization.cpp deleted file mode 100755 index 727bdff4..00000000 --- a/bsnes/chip/supergameboy/serialization.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef SUPERGAMEBOY_CPP - -void SuperGameBoy::serialize(serializer &s) { - Processor::serialize(s); - s.integer(row); - if(sgb_serialize) sgb_serialize(s); -} - -#endif diff --git a/bsnes/chip/supergameboy/supergameboy.cpp b/bsnes/chip/supergameboy/supergameboy.cpp deleted file mode 100755 index eee2c8c9..00000000 --- a/bsnes/chip/supergameboy/supergameboy.cpp +++ /dev/null @@ -1,142 +0,0 @@ -#include - -#define SUPERGAMEBOY_CPP -namespace SNES { - -SuperGameBoy supergameboy; - -#include "serialization.cpp" - -void SuperGameBoy::Enter() { supergameboy.enter(); } - -void SuperGameBoy::enter() { - if(!sgb_run) while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - audio.coprocessor_sample(0, 0); - step(1); - synchronize_cpu(); - } - - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - unsigned samples = sgb_run(samplebuffer, 16); - for(unsigned i = 0; i < samples; i++) { - int16 left = samplebuffer[i] >> 0; - int16 right = samplebuffer[i] >> 16; - - //SNES audio is notoriously quiet; lower Game Boy samples to match SGB sound effects - audio.coprocessor_sample(left / 3, right / 3); - } - - step(samples); - synchronize_cpu(); - } -} - -void SuperGameBoy::save() { - if(sgb_save) sgb_save(); -} - -uint8 SuperGameBoy::mmio_read(unsigned addr) { - addr &= 0xffff; - - if(addr == 0x2181) return mmio[0]->mmio_read(addr); - if(addr == 0x2182) return mmio[1]->mmio_read(addr); - if(addr == 0x420b) return mmio[2]->mmio_read(addr); - - return 0x00; -} - -void SuperGameBoy::mmio_write(unsigned addr, uint8 data) { - addr &= 0xffff; - - if(addr == 0x2181) { - row = (row & 0xff00) | (data << 0); - mmio[0]->mmio_write(addr, data); - } - - if(addr == 0x2182) { - row = (row & 0x00ff) | (data << 8); - mmio[1]->mmio_write(addr, data); - } - - if(addr == 0x420b) { - if(data == 0x10 && sgb_row) { - if(row >= 0x5000 && row <= 0x6540) sgb_row((row - 0x5000) / 320); - if(row >= 0x6800 && row <= 0x7d40) sgb_row((row - 0x6800) / 320); - } - mmio[2]->mmio_write(addr, data); - } -} - -uint8 SuperGameBoy::read(unsigned addr) { - if(sgb_read) return sgb_read(addr); - return 0x00; -} - -void SuperGameBoy::write(unsigned addr, uint8 data) { - if(sgb_write) sgb_write(addr, data); -} - -void SuperGameBoy::init() { - if(open("supergameboy")) { - sgb_rom = sym("sgb_rom"); - sgb_ram = sym("sgb_ram"); - sgb_rtc = sym("sgb_rtc"); - sgb_init = sym("sgb_init"); - sgb_term = sym("sgb_term"); - sgb_power = sym("sgb_power"); - sgb_reset = sym("sgb_reset"); - sgb_row = sym("sgb_row"); - sgb_read = sym("sgb_read"); - sgb_write = sym("sgb_write"); - sgb_run = sym("sgb_run"); - sgb_save = sym("sgb_save"); - sgb_serialize = sym("sgb_serialize"); - } -} - -void SuperGameBoy::enable() { - mmio[0] = memory::mmio.mmio[0x2181 - 0x2000]; - mmio[1] = memory::mmio.mmio[0x2182 - 0x2000]; - mmio[2] = memory::mmio.mmio[0x420b - 0x2000]; - - memory::mmio.map(0x2181, *this); - memory::mmio.map(0x2182, *this); - memory::mmio.map(0x420b, *this); -} - -void SuperGameBoy::power() { - unsigned frequency = (cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1 ? system.cpu_frequency() / 10 : 2097152); - create(SuperGameBoy::Enter, frequency); - - audio.coprocessor_enable(true); - audio.coprocessor_frequency(cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1 ? 2147727.0 : 2097152.0); - - sgb_rom(memory::gbrom.data(), memory::gbrom.size() == -1U ? 0 : memory::gbrom.size()); - sgb_ram(memory::gbram.data(), memory::gbram.size() == -1U ? 0 : memory::gbram.size()); - sgb_rtc(memory::gbrtc.data(), memory::gbrtc.size() == -1U ? 0 : memory::gbrtc.size()); - - bool version = (cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1) ? 0 : 1; - if(sgb_init) sgb_init(version); - if(sgb_power) sgb_power(); -} - -void SuperGameBoy::reset() { - unsigned frequency = (cartridge.supergameboy_version() == Cartridge::SuperGameBoyVersion::Version1 ? system.cpu_frequency() / 10 : 2097152); - create(SuperGameBoy::Enter, frequency); - - if(sgb_reset) sgb_reset(); -} - -void SuperGameBoy::unload() { - if(sgb_term) sgb_term(); -} - -} diff --git a/bsnes/chip/supergameboy/supergameboy.hpp b/bsnes/chip/supergameboy/supergameboy.hpp deleted file mode 100755 index bf392b11..00000000 --- a/bsnes/chip/supergameboy/supergameboy.hpp +++ /dev/null @@ -1,43 +0,0 @@ -class SuperGameBoy : public Coprocessor, public MMIO, public Memory, public library { -public: - static void Enter(); - void enter(); - void save(); - - MMIO *mmio[3]; - uint8 mmio_read(unsigned addr); - void mmio_write(unsigned addr, uint8 data); - - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - void init(); - void enable(); - void power(); - void reset(); - void unload(); - - void serialize(serializer&); - -private: - uint32_t samplebuffer[4096]; - unsigned row; - - function sgb_rom; - function sgb_ram; - function sgb_rtc; - function sgb_init; - function sgb_term; - function sgb_power; - function sgb_reset; - function sgb_row; - function sgb_read; - function sgb_write; - function sgb_run; - function sgb_save; - function sgb_serialize; - - friend class Cartridge; -}; - -extern SuperGameBoy supergameboy; diff --git a/bsnes/config/config.cpp b/bsnes/config/config.cpp deleted file mode 100755 index 4c47ccd1..00000000 --- a/bsnes/config/config.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef SYSTEM_CPP - -Configuration config; - -Configuration::Configuration() { - controller_port1 = Input::Device::Joypad; - controller_port2 = Input::Device::Joypad; - expansion_port = System::ExpansionPortDevice::BSX; - region = System::Region::Autodetect; - - cpu.version = 2; - cpu.ntsc_frequency = 21477272; //315 / 88 * 6000000 - cpu.pal_frequency = 21281370; - cpu.wram_init_value = 0x55; - - smp.ntsc_frequency = 24607104; //32040.5 * 768 - smp.pal_frequency = 24607104; - - ppu1.version = 1; - ppu2.version = 3; - - superfx.speed = 0; //0 = auto-select, 1 = force 10.74MHz, 2 = force 21.48MHz -} - -#endif diff --git a/bsnes/config/config.hpp b/bsnes/config/config.hpp deleted file mode 100755 index 7188d209..00000000 --- a/bsnes/config/config.hpp +++ /dev/null @@ -1,34 +0,0 @@ -struct Configuration { - Input::Device controller_port1; - Input::Device controller_port2; - System::ExpansionPortDevice expansion_port; - System::Region region; - - struct CPU { - unsigned version; - unsigned ntsc_frequency; - unsigned pal_frequency; - unsigned wram_init_value; - } cpu; - - struct SMP { - unsigned ntsc_frequency; - unsigned pal_frequency; - } smp; - - struct PPU1 { - unsigned version; - } ppu1; - - struct PPU2 { - unsigned version; - } ppu2; - - struct SuperFX { - unsigned speed; - } superfx; - - Configuration(); -}; - -extern Configuration config; diff --git a/bsnes/debugger/debugger.cpp b/bsnes/debugger/debugger.cpp deleted file mode 100755 index dc70dfec..00000000 --- a/bsnes/debugger/debugger.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#ifdef SYSTEM_CPP - -Debugger debugger; - -void Debugger::breakpoint_test(Debugger::Breakpoint::Source source, Debugger::Breakpoint::Mode mode, unsigned addr, uint8 data) { - for(unsigned i = 0; i < Breakpoints; i++) { - if(breakpoint[i].enabled == false) continue; - - bool source_wram = ((breakpoint[i].addr & 0x40e000) == 0x000000) || ((breakpoint[i].addr & 0xffe000) == 0x7e0000); - bool offset_wram = ((addr & 0x40e000) == 0x000000) || ((addr & 0xffe000) == 0x7e0000); - - if(source == Debugger::Breakpoint::Source::CPUBus && source_wram && offset_wram) { - //shadow S-CPU WRAM addresses ($00-3f|80-bf:0000-1fff mirrors $7e:0000-1fff) - if((breakpoint[i].addr & 0x1fff) != (addr & 0x1fff)) continue; - } else { - if(breakpoint[i].addr != addr) continue; - } - - if(breakpoint[i].data != -1 && breakpoint[i].data != data) continue; - if(breakpoint[i].source != source) continue; - if(breakpoint[i].mode != mode) continue; - - breakpoint[i].counter++; - breakpoint_hit = i; - break_event = BreakEvent::BreakpointHit; - scheduler.exit(Scheduler::ExitReason::DebuggerEvent); - break; - } -} - -uint8 Debugger::read(Debugger::MemorySource source, unsigned addr) { - switch(source) { - case MemorySource::CPUBus: { - //do not read from memory-mapped registers that could affect program behavior - if(((addr - 0x2000) & 0x40c000) == 0x000000) break; //$00-3f:2000-5fff MMIO - return bus.read(addr & 0xffffff); - } break; - - case MemorySource::APURAM: { - return memory::apuram.read(addr & 0xffff); - } break; - - case MemorySource::VRAM: { - return memory::vram.read(addr & 0xffff); - } break; - - case MemorySource::OAM: { - if(addr & 0x0200) return memory::oam.read(0x0200 + (addr & 0x1f)); - return memory::oam.read(addr & 0x01ff); - } break; - - case MemorySource::CGRAM: { - return memory::cgram.read(addr & 0x01ff); - } break; - } - - return 0x00; -} - -void Debugger::write(Debugger::MemorySource source, unsigned addr, uint8 data) { - switch(source) { - case MemorySource::CPUBus: { - //do not write to memory-mapped registers that could affect program behavior - if(((addr - 0x2000) & 0x40c000) == 0x000000) break; //$00-3f:2000-5fff MMIO - memory::cartrom.write_protect(false); - bus.write(addr & 0xffffff, data); - memory::cartrom.write_protect(true); - } break; - - case MemorySource::APURAM: { - memory::apuram.write(addr & 0xffff, data); - } break; - - case MemorySource::VRAM: { - memory::vram.write(addr & 0xffff, data); - } break; - - case MemorySource::OAM: { - if(addr & 0x0200) memory::oam.write(0x0200 + (addr & 0x1f), data); - else memory::oam.write(addr & 0x01ff, data); - } break; - - case MemorySource::CGRAM: { - memory::cgram.write(addr & 0x01ff, data); - } break; - } -} - -Debugger::Debugger() { - break_event = BreakEvent::None; - - for(unsigned n = 0; n < Breakpoints; n++) { - breakpoint[n].enabled = false; - breakpoint[n].addr = 0; - breakpoint[n].data = -1; - breakpoint[n].mode = Breakpoint::Mode::Exec; - breakpoint[n].source = Breakpoint::Source::CPUBus; - breakpoint[n].counter = 0; - } - breakpoint_hit = 0; - - step_cpu = false; - step_smp = false; -} - -#endif diff --git a/bsnes/debugger/debugger.hpp b/bsnes/debugger/debugger.hpp deleted file mode 100755 index 28ee52eb..00000000 --- a/bsnes/debugger/debugger.hpp +++ /dev/null @@ -1,32 +0,0 @@ -class Debugger { -public: - enum class BreakEvent : unsigned { - None, - BreakpointHit, - CPUStep, - SMPStep, - } break_event; - - enum { Breakpoints = 8 }; - struct Breakpoint { - bool enabled; - unsigned addr; - signed data; //-1 = unused - enum class Mode : unsigned { Exec, Read, Write } mode; - enum class Source : unsigned { CPUBus, APURAM, VRAM, OAM, CGRAM } source; - unsigned counter; //number of times breakpoint has been hit since being set - } breakpoint[Breakpoints]; - unsigned breakpoint_hit; - void breakpoint_test(Breakpoint::Source source, Breakpoint::Mode mode, unsigned addr, uint8 data); - - bool step_cpu; - bool step_smp; - - enum class MemorySource : unsigned { CPUBus, APURAM, VRAM, OAM, CGRAM }; - uint8 read(MemorySource, unsigned addr); - void write(MemorySource, unsigned addr, uint8 data); - - Debugger(); -}; - -extern Debugger debugger; diff --git a/bsnes/dsp/brr.cpp b/bsnes/dsp/brr.cpp deleted file mode 100755 index abdf2a0d..00000000 --- a/bsnes/dsp/brr.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifdef DSP_CPP - -void DSP::brr_decode(voice_t &v) { - //state.t_brr_byte = ram[v.brr_addr + v.brr_offset] cached from previous clock cycle - int nybbles = (state.t_brr_byte << 8) + memory::apuram[(uint16)(v.brr_addr + v.brr_offset + 1)]; - - const int filter = (state.t_brr_header >> 2) & 3; - const int scale = (state.t_brr_header >> 4); - - //decode four samples - for(unsigned i = 0; i < 4; i++) { - //bits 12-15 = current nybble; sign extend, then shift right to 4-bit precision - //result: s = 4-bit sign-extended sample value - int s = (int16)nybbles >> 12; - nybbles <<= 4; //slide nybble so that on next loop iteration, bits 12-15 = current nybble - - if(scale <= 12) { - s <<= scale; - s >>= 1; - } else { - s &= ~0x7ff; - } - - //apply IIR filter (2 is the most commonly used) - const int p1 = v.buffer[v.buf_pos - 1]; - const int p2 = v.buffer[v.buf_pos - 2] >> 1; - - switch(filter) { - case 0: break; //no filter - - case 1: { - //s += p1 * 0.46875 - s += p1 >> 1; - s += (-p1) >> 5; - } break; - - case 2: { - //s += p1 * 0.953125 - p2 * 0.46875 - s += p1; - s -= p2; - s += p2 >> 4; - s += (p1 * -3) >> 6; - } break; - - case 3: { - //s += p1 * 0.8984375 - p2 * 0.40625 - s += p1; - s -= p2; - s += (p1 * -13) >> 7; - s += (p2 * 3) >> 4; - } break; - } - - //adjust and write sample - s = sclamp<16>(s); - s = (int16)(s << 1); - v.buffer.write(v.buf_pos++, s); - if(v.buf_pos >= brr_buf_size) v.buf_pos = 0; - } -} - -#endif diff --git a/bsnes/dsp/counter.cpp b/bsnes/dsp/counter.cpp deleted file mode 100755 index f65fdd26..00000000 --- a/bsnes/dsp/counter.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifdef DSP_CPP - -//counter_rate = number of samples per counter event -//all rates are evenly divisible by counter_range (0x7800, 30720, or 2048 * 5 * 3) -//note that rate[0] is a special case, which never triggers - -const uint16 DSP::counter_rate[32] = { - 0, 2048, 1536, - 1280, 1024, 768, - 640, 512, 384, - 320, 256, 192, - 160, 128, 96, - 80, 64, 48, - 40, 32, 24, - 20, 16, 12, - 10, 8, 6, - 5, 4, 3, - 2, - 1, -}; - -//counter_offset = counter offset from zero -//counters do not appear to be aligned at zero for all rates - -const uint16 DSP::counter_offset[32] = { - 0, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 536, 0, 1040, - 0, - 0, -}; - -inline void DSP::counter_tick() { - state.counter--; - if(state.counter < 0) state.counter = counter_range - 1; -} - -//return true if counter event should trigger - -inline bool DSP::counter_poll(unsigned rate) { - if(rate == 0) return false; - return (((unsigned)state.counter + counter_offset[rate]) % counter_rate[rate]) == 0; -} - -#endif diff --git a/bsnes/dsp/debugger/debugger.cpp b/bsnes/dsp/debugger/debugger.cpp deleted file mode 100755 index 078c0886..00000000 --- a/bsnes/dsp/debugger/debugger.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#ifdef DSP_CPP - -bool DSPDebugger::property(unsigned id, string &name, string &value) { - unsigned n = 0; - - if(id == n++) { name = "Main Volume - Left"; value = main_volume_left(); return true; } - if(id == n++) { name = "Main Volume - Right"; value = main_volume_right(); return true; } - if(id == n++) { name = "Echo Volume - Left"; value = echo_volume_left(); return true; } - if(id == n++) { name = "Echo Volume - Right"; value = echo_volume_right(); return true; } - if(id == n++) { name = "Key On"; value = string("0x", strhex<2>(key_on())); return true; } - if(id == n++) { name = "Key Off"; value = string("0x", strhex<2>(key_off())); return true; } - if(id == n++) { name = "Flag - Reset"; value = flag_reset(); return true; } - if(id == n++) { name = "Flag - Mute"; value = flag_mute(); return true; } - if(id == n++) { name = "Flag - Echo Disable"; value = flag_echo_disable(); return true; } - if(id == n++) { name = "Flag - Noise Clock"; value = flag_noise_clock(); return true; } - if(id == n++) { name = "Source End Block"; value = source_end_block(); return true; } - if(id == n++) { name = "Echo Feedback"; value = echo_feedback(); return true; } - if(id == n++) { name = "Pitch Modulation Enable"; value = string("0x", strhex<2>(pitch_modulation_enable())); return true; } - if(id == n++) { name = "Noise Enable"; value = string("0x", strhex<2>(noise_enable())); return true; } - if(id == n++) { name = "Echo Enable"; value = string("0x", strhex<2>(echo_enable())); return true; } - if(id == n++) { name = "Source Directory"; value = source_directory(); return true; } - if(id == n++) { name = "Echo Start Address"; value = echo_start_address(); return true; } - if(id == n++) { name = "Echo Directory"; value = echo_directory(); return true; } - - for(unsigned i = 0; i < 8; i++) { - if(id == n++) { - name = string("Coefficient ", i); - value = string("0x", strhex<2>(echo_filter_coefficient(i))); - return true; - } - } - - for(unsigned i = 0; i < 8; i++) { - if(id == n++) { - name = string("Voice ", i); - value = ""; - return true; - } - - if(id == n++) { name = "Volume - Left"; value = voice_volume_left(i); return true; } - if(id == n++) { name = "Volume - Right"; value = voice_volume_right(i); return true; } - if(id == n++) { name = "Pitch Height"; value = string("0x", strhex<4>(voice_pitch_height(i))); return true; } - if(id == n++) { name = "Source Number"; value = voice_source_number(i); return true; } - if(id == n++) { name = "ADSR1"; value = voice_adsr1(i); return true; } - if(id == n++) { name = "ADSR2"; value = voice_adsr2(i); return true; } - if(id == n++) { name = "GAIN"; value = voice_gain(i); return true; } - if(id == n++) { name = "ENVX"; value = voice_envx(i); return true; } - if(id == n++) { name = "OUTX"; value = voice_outx(i); return true; } - } - - return false; -} - -unsigned DSPDebugger::main_volume_left() { return state.regs[0x0c]; } -unsigned DSPDebugger::main_volume_right() { return state.regs[0x1c]; } -unsigned DSPDebugger::echo_volume_left() { return state.regs[0x2c]; } -unsigned DSPDebugger::echo_volume_right() { return state.regs[0x3c]; } -unsigned DSPDebugger::key_on() { return state.regs[0x4c]; } -unsigned DSPDebugger::key_off() { return state.regs[0x5c]; } -bool DSPDebugger::flag_reset() { return state.regs[0x6c] & 0x80; } -bool DSPDebugger::flag_mute() { return state.regs[0x6c] & 0x40; } -bool DSPDebugger::flag_echo_disable() { return state.regs[0x6c] & 0x20; } -unsigned DSPDebugger::flag_noise_clock() { return state.regs[0x6c] & 0x1f; } -unsigned DSPDebugger::source_end_block() { return state.regs[0x7c]; } -unsigned DSPDebugger::echo_feedback() { return state.regs[0x0d]; } -unsigned DSPDebugger::pitch_modulation_enable() { return state.regs[0x2d]; } -unsigned DSPDebugger::noise_enable() { return state.regs[0x3d]; } -unsigned DSPDebugger::echo_enable() { return state.regs[0x4d]; } -unsigned DSPDebugger::source_directory() { return state.regs[0x5d]; } -unsigned DSPDebugger::echo_start_address() { return state.regs[0x6d]; } -unsigned DSPDebugger::echo_directory() { return state.regs[0x7d]; } -unsigned DSPDebugger::echo_filter_coefficient(unsigned n) { return state.regs[(n << 4) + 0x0f]; } -unsigned DSPDebugger::voice_volume_left(unsigned n) { return state.regs[(n << 4) + 0x00]; } -unsigned DSPDebugger::voice_volume_right(unsigned n) { return state.regs[(n << 4) + 0x01]; } -unsigned DSPDebugger::voice_pitch_height(unsigned n) { return state.regs[(n << 4) + 0x02] + (state.regs[(n << 4) + 0x03] << 8); } -unsigned DSPDebugger::voice_source_number(unsigned n) { return state.regs[(n << 4) + 0x04]; } -unsigned DSPDebugger::voice_adsr1(unsigned n) { return state.regs[(n << 4) + 0x05]; } -unsigned DSPDebugger::voice_adsr2(unsigned n) { return state.regs[(n << 4) + 0x06]; } -unsigned DSPDebugger::voice_gain(unsigned n) { return state.regs[(n << 4) + 0x07]; } -unsigned DSPDebugger::voice_envx(unsigned n) { return state.regs[(n << 4) + 0x08]; } -unsigned DSPDebugger::voice_outx(unsigned n) { return state.regs[(n << 4) + 0x09]; } - -#endif diff --git a/bsnes/dsp/debugger/debugger.hpp b/bsnes/dsp/debugger/debugger.hpp deleted file mode 100755 index 5946bac9..00000000 --- a/bsnes/dsp/debugger/debugger.hpp +++ /dev/null @@ -1,37 +0,0 @@ -class DSPDebugger : public DSP, public ChipDebugger { -public: - bool property(unsigned id, string &name, string &value); - - //=========== - //DSPDebugger - //=========== - - unsigned main_volume_left(); - unsigned main_volume_right(); - unsigned echo_volume_left(); - unsigned echo_volume_right(); - unsigned key_on(); - unsigned key_off(); - bool flag_reset(); - bool flag_mute(); - bool flag_echo_disable(); - unsigned flag_noise_clock(); - unsigned source_end_block(); - unsigned echo_feedback(); - unsigned pitch_modulation_enable(); - unsigned noise_enable(); - unsigned echo_enable(); - unsigned source_directory(); - unsigned echo_start_address(); - unsigned echo_directory(); - unsigned echo_filter_coefficient(unsigned); - unsigned voice_volume_left(unsigned); - unsigned voice_volume_right(unsigned); - unsigned voice_pitch_height(unsigned); - unsigned voice_source_number(unsigned); - unsigned voice_adsr1(unsigned); - unsigned voice_adsr2(unsigned); - unsigned voice_gain(unsigned); - unsigned voice_envx(unsigned); - unsigned voice_outx(unsigned); -}; diff --git a/bsnes/dsp/dsp.cpp b/bsnes/dsp/dsp.cpp deleted file mode 100755 index ead2288b..00000000 --- a/bsnes/dsp/dsp.cpp +++ /dev/null @@ -1,350 +0,0 @@ -//S-DSP emulator -//note: this is basically a C++ cothreaded implementation of Shay Green's (blargg's) S-DSP emulator. -//the actual algorithms, timing information, tables, variable names, etc were all from him. - -#include - -#define DSP_CPP -namespace SNES { - -#if defined(DEBUGGER) - #include "debugger/debugger.cpp" - DSPDebugger dsp; -#else - DSP dsp; -#endif - -#include "serialization.cpp" - -#define REG(n) state.regs[r_##n] -#define VREG(n) state.regs[v.vidx + v_##n] - -#if !defined(DSP_STATE_MACHINE) - #define phase_start() while(true) { \ - if(scheduler.sync == Scheduler::SynchronizeMode::All) { \ - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); \ - } - #define phase(n) - #define tick() step(3 * 8); synchronize_smp() - #define phase_end() } -#else - #define phase_start() switch(phase_index) { - #define phase(n) case n: - #define tick() step(3 * 8); break - #define phase_end() } phase_index = (phase_index + 1) & 31; -#endif - -#include "gaussian.cpp" -#include "counter.cpp" -#include "envelope.cpp" -#include "brr.cpp" -#include "misc.cpp" -#include "voice.cpp" -#include "echo.cpp" - -/* timing */ - -void DSP::step(unsigned clocks) { - clock += clocks; -} - -void DSP::synchronize_smp() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread); -} - -void DSP::Enter() { dsp.enter(); } - -void DSP::enter() { - phase_start() - - phase(0) - voice_5(voice[0]); - voice_2(voice[1]); - tick(); - - phase(1) - voice_6(voice[0]); - voice_3(voice[1]); - tick(); - - phase(2) - voice_7(voice[0]); - voice_4(voice[1]); - voice_1(voice[3]); - tick(); - - phase(3) - voice_8(voice[0]); - voice_5(voice[1]); - voice_2(voice[2]); - tick(); - - phase(4) - voice_9(voice[0]); - voice_6(voice[1]); - voice_3(voice[2]); - tick(); - - phase(5) - voice_7(voice[1]); - voice_4(voice[2]); - voice_1(voice[4]); - tick(); - - phase(6) - voice_8(voice[1]); - voice_5(voice[2]); - voice_2(voice[3]); - tick(); - - phase(7) - voice_9(voice[1]); - voice_6(voice[2]); - voice_3(voice[3]); - tick(); - - phase(8) - voice_7(voice[2]); - voice_4(voice[3]); - voice_1(voice[5]); - tick(); - - phase(9) - voice_8(voice[2]); - voice_5(voice[3]); - voice_2(voice[4]); - tick(); - - phase(10) - voice_9(voice[2]); - voice_6(voice[3]); - voice_3(voice[4]); - tick(); - - phase(11) - voice_7(voice[3]); - voice_4(voice[4]); - voice_1(voice[6]); - tick(); - - phase(12) - voice_8(voice[3]); - voice_5(voice[4]); - voice_2(voice[5]); - tick(); - - phase(13) - voice_9(voice[3]); - voice_6(voice[4]); - voice_3(voice[5]); - tick(); - - phase(14) - voice_7(voice[4]); - voice_4(voice[5]); - voice_1(voice[7]); - tick(); - - phase(15) - voice_8(voice[4]); - voice_5(voice[5]); - voice_2(voice[6]); - tick(); - - phase(16) - voice_9(voice[4]); - voice_6(voice[5]); - voice_3(voice[6]); - tick(); - - phase(17) - voice_1(voice[0]); - voice_7(voice[5]); - voice_4(voice[6]); - tick(); - - phase(18) - voice_8(voice[5]); - voice_5(voice[6]); - voice_2(voice[7]); - tick(); - - phase(19) - voice_9(voice[5]); - voice_6(voice[6]); - voice_3(voice[7]); - tick(); - - phase(20) - voice_1(voice[1]); - voice_7(voice[6]); - voice_4(voice[7]); - tick(); - - phase(21) - voice_8(voice[6]); - voice_5(voice[7]); - voice_2(voice[0]); - tick(); - - phase(22) - voice_3a(voice[0]); - voice_9(voice[6]); - voice_6(voice[7]); - echo_22(); - tick(); - - phase(23) - voice_7(voice[7]); - echo_23(); - tick(); - - phase(24) - voice_8(voice[7]); - echo_24(); - tick(); - - phase(25) - voice_3b(voice[0]); - voice_9(voice[7]); - echo_25(); - tick(); - - phase(26) - echo_26(); - tick(); - - phase(27) - misc_27(); - echo_27(); - tick(); - - phase(28) - misc_28(); - echo_28(); - tick(); - - phase(29) - misc_29(); - echo_29(); - tick(); - - phase(30) - misc_30(); - voice_3c(voice[0]); - echo_30(); - tick(); - - phase(31) - voice_4(voice[0]); - voice_1(voice[2]); - tick(); - - phase_end() -} - -/* register interface for S-SMP $00f2,$00f3 */ - -uint8 DSP::read(uint8 addr) { - return state.regs[addr]; -} - -void DSP::write(uint8 addr, uint8 data) { - state.regs[addr] = data; - - if((addr & 0x0f) == v_envx) { - state.envx_buf = data; - } else if((addr & 0x0f) == v_outx) { - state.outx_buf = data; - } else if(addr == r_kon) { - state.new_kon = data; - } else if(addr == r_endx) { - //always cleared, regardless of data written - state.endx_buf = 0; - state.regs[r_endx] = 0; - } -} - -/* initialization */ - -void DSP::power() { - memset(&state.regs, 0, sizeof state.regs); - state.echo_hist_pos = 0; - state.every_other_sample = false; - state.kon = 0; - state.noise = 0; - state.counter = 0; - state.echo_offset = 0; - state.echo_length = 0; - state.new_kon = 0; - state.endx_buf = 0; - state.envx_buf = 0; - state.outx_buf = 0; - state.t_pmon = 0; - state.t_non = 0; - state.t_eon = 0; - state.t_dir = 0; - state.t_koff = 0; - state.t_brr_next_addr = 0; - state.t_adsr0 = 0; - state.t_brr_header = 0; - state.t_brr_byte = 0; - state.t_srcn = 0; - state.t_esa = 0; - state.t_echo_disabled = 0; - state.t_dir_addr = 0; - state.t_pitch = 0; - state.t_output = 0; - state.t_looped = 0; - state.t_echo_ptr = 0; - state.t_main_out[0] = state.t_main_out[1] = 0; - state.t_echo_out[0] = state.t_echo_out[1] = 0; - state.t_echo_in[0] = state.t_echo_in[1] = 0; - - for(unsigned i = 0; i < 8; i++) { - voice[i].buf_pos = 0; - voice[i].interp_pos = 0; - voice[i].brr_addr = 0; - voice[i].brr_offset = 1; - voice[i].vbit = 1 << i; - voice[i].vidx = i * 0x10; - voice[i].kon_delay = 0; - voice[i].env_mode = env_release; - voice[i].env = 0; - voice[i].t_envx_out = 0; - voice[i].hidden_env = 0; - } - - reset(); -} - -void DSP::reset() { - create(Enter, system.apu_frequency()); - - REG(flg) = 0xe0; - - state.noise = 0x4000; - state.echo_hist_pos = 0; - state.every_other_sample = 1; - state.echo_offset = 0; - state.counter = 0; - - phase_index = 0; -} - -DSP::DSP() { - static_assert(sizeof(int) >= 32 / 8, "int >= 32-bits"); - static_assert((int8)0x80 == -0x80, "8-bit sign extension"); - static_assert((int16)0x8000 == -0x8000, "16-bit sign extension"); - static_assert((uint16)0xffff0000 == 0, "16-bit unsigned clip"); - static_assert((-1 >> 1) == -1, "arithmetic shift right"); - - //-0x8000 <= n <= +0x7fff - assert(sclamp<16>(+0x8000) == +0x7fff); - assert(sclamp<16>(-0x8001) == -0x8000); -} - -DSP::~DSP() { -} - -} diff --git a/bsnes/dsp/dsp.hpp b/bsnes/dsp/dsp.hpp deleted file mode 100755 index 64c69ce2..00000000 --- a/bsnes/dsp/dsp.hpp +++ /dev/null @@ -1,181 +0,0 @@ -class DSP : public Processor { -public: - //synchronization - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_smp(); - - static void Enter(); - void enter(); - - uint8 read(uint8 addr); - void write(uint8 addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); - DSP(); - ~DSP(); - -protected: - //DSP_STATE_MACHINE variable - unsigned phase_index; - - //global registers - enum global_reg_t { - r_mvoll = 0x0c, r_mvolr = 0x1c, - r_evoll = 0x2c, r_evolr = 0x3c, - r_kon = 0x4c, r_koff = 0x5c, - r_flg = 0x6c, r_endx = 0x7c, - r_efb = 0x0d, r_pmon = 0x2d, - r_non = 0x3d, r_eon = 0x4d, - r_dir = 0x5d, r_esa = 0x6d, - r_edl = 0x7d, r_fir = 0x0f, //8 coefficients at 0x0f, 0x1f, ... 0x7f - }; - - //voice registers - enum voice_reg_t { - v_voll = 0x00, v_volr = 0x01, - v_pitchl = 0x02, v_pitchh = 0x03, - v_srcn = 0x04, v_adsr0 = 0x05, - v_adsr1 = 0x06, v_gain = 0x07, - v_envx = 0x08, v_outx = 0x09, - }; - - //internal envelope modes - enum env_mode_t { env_release, env_attack, env_decay, env_sustain }; - - //internal constants - enum { echo_hist_size = 8 }; - enum { brr_buf_size = 12 }; - enum { brr_block_size = 9 }; - - //global state - struct state_t { - uint8 regs[128]; - - modulo_array echo_hist[2]; //echo history keeps most recent 8 samples - int echo_hist_pos; - - bool every_other_sample; //toggles every sample - int kon; //KON value when last checked - int noise; - int counter; - int echo_offset; //offset from ESA in echo buffer - int echo_length; //number of bytes that echo_offset will stop at - - //hidden registers also written to when main register is written to - int new_kon; - int endx_buf; - int envx_buf; - int outx_buf; - - //temporary state between clocks - - //read once per sample - int t_pmon; - int t_non; - int t_eon; - int t_dir; - int t_koff; - - //read a few clocks ahead before used - int t_brr_next_addr; - int t_adsr0; - int t_brr_header; - int t_brr_byte; - int t_srcn; - int t_esa; - int t_echo_disabled; - - //internal state that is recalculated every sample - int t_dir_addr; - int t_pitch; - int t_output; - int t_looped; - int t_echo_ptr; - - //left/right sums - int t_main_out[2]; - int t_echo_out[2]; - int t_echo_in [2]; - } state; - - //voice state - struct voice_t { - modulo_array buffer; //decoded samples - int buf_pos; //place in buffer where next samples will be decoded - int interp_pos; //relative fractional position in sample (0x1000 = 1.0) - int brr_addr; //address of current BRR block - int brr_offset; //current decoding offset in BRR block - int vbit; //bitmask for voice: 0x01 for voice 0, 0x02 for voice 1, etc - int vidx; //voice channel register index: 0x00 for voice 0, 0x10 for voice 1, etc - int kon_delay; //KON delay/current setup phase - int env_mode; - int env; //current envelope level - int t_envx_out; - int hidden_env; //used by GAIN mode 7, very obscure quirk - } voice[8]; - - //gaussian - static const int16 gaussian_table[512]; - int gaussian_interpolate(const voice_t &v); - - //counter - enum { counter_range = 2048 * 5 * 3 }; //30720 (0x7800) - static const uint16 counter_rate[32]; - static const uint16 counter_offset[32]; - void counter_tick(); - bool counter_poll(unsigned rate); - - //envelope - void envelope_run(voice_t &v); - - //brr - void brr_decode(voice_t &v); - - //misc - void misc_27(); - void misc_28(); - void misc_29(); - void misc_30(); - - //voice - void voice_output(voice_t &v, bool channel); - void voice_1 (voice_t &v); - void voice_2 (voice_t &v); - void voice_3 (voice_t &v); - void voice_3a(voice_t &v); - void voice_3b(voice_t &v); - void voice_3c(voice_t &v); - void voice_4 (voice_t &v); - void voice_5 (voice_t &v); - void voice_6 (voice_t &v); - void voice_7 (voice_t &v); - void voice_8 (voice_t &v); - void voice_9 (voice_t &v); - - //echo - int calc_fir(int i, bool channel); - int echo_output(bool channel); - void echo_read(bool channel); - void echo_write(bool channel); - void echo_22(); - void echo_23(); - void echo_24(); - void echo_25(); - void echo_26(); - void echo_27(); - void echo_28(); - void echo_29(); - void echo_30(); - - friend class DSPDebugger; -}; - -#if defined(DEBUGGER) - #include "debugger/debugger.hpp" - extern DSPDebugger dsp; -#else - extern DSP dsp; -#endif diff --git a/bsnes/dsp/echo.cpp b/bsnes/dsp/echo.cpp deleted file mode 100755 index c0cf5f37..00000000 --- a/bsnes/dsp/echo.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#ifdef DSP_CPP - -int DSP::calc_fir(int i, bool channel) { - int s = state.echo_hist[channel][state.echo_hist_pos + i + 1]; - return (s * (int8)REG(fir + i * 0x10)) >> 6; -} - -int DSP::echo_output(bool channel) { - int output = (int16)((state.t_main_out[channel] * (int8)REG(mvoll + channel * 0x10)) >> 7) - + (int16)((state.t_echo_in [channel] * (int8)REG(evoll + channel * 0x10)) >> 7); - return sclamp<16>(output); -} - -void DSP::echo_read(bool channel) { - unsigned addr = state.t_echo_ptr + channel * 2; - uint8 lo = memory::apuram[(uint16)(addr + 0)]; - uint8 hi = memory::apuram[(uint16)(addr + 1)]; - int s = (int16)((hi << 8) + lo); - state.echo_hist[channel].write(state.echo_hist_pos, s >> 1); -} - -void DSP::echo_write(bool channel) { - if(!(state.t_echo_disabled & 0x20)) { - unsigned addr = state.t_echo_ptr + channel * 2; - int s = state.t_echo_out[channel]; - memory::apuram[(uint16)(addr + 0)] = s; - memory::apuram[(uint16)(addr + 1)] = s >> 8; - } - - state.t_echo_out[channel] = 0; -} - -void DSP::echo_22() { - //history - state.echo_hist_pos++; - if(state.echo_hist_pos >= echo_hist_size) state.echo_hist_pos = 0; - - state.t_echo_ptr = (uint16)((state.t_esa << 8) + state.echo_offset); - echo_read(0); - - //FIR - int l = calc_fir(0, 0); - int r = calc_fir(0, 1); - - state.t_echo_in[0] = l; - state.t_echo_in[1] = r; -} - -void DSP::echo_23() { - int l = calc_fir(1, 0) + calc_fir(2, 0); - int r = calc_fir(1, 1) + calc_fir(2, 1); - - state.t_echo_in[0] += l; - state.t_echo_in[1] += r; - - echo_read(1); -} - -void DSP::echo_24() { - int l = calc_fir(3, 0) + calc_fir(4, 0) + calc_fir(5, 0); - int r = calc_fir(3, 1) + calc_fir(4, 1) + calc_fir(5, 1); - - state.t_echo_in[0] += l; - state.t_echo_in[1] += r; -} - -void DSP::echo_25() { - int l = state.t_echo_in[0] + calc_fir(6, 0); - int r = state.t_echo_in[1] + calc_fir(6, 1); - - l = (int16)l; - r = (int16)r; - - l += (int16)calc_fir(7, 0); - r += (int16)calc_fir(7, 1); - - state.t_echo_in[0] = sclamp<16>(l) & ~1; - state.t_echo_in[1] = sclamp<16>(r) & ~1; -} - -void DSP::echo_26() { - //left output volumes - //(save sample for next clock so we can output both together) - state.t_main_out[0] = echo_output(0); - - //echo feedback - int l = state.t_echo_out[0] + (int16)((state.t_echo_in[0] * (int8)REG(efb)) >> 7); - int r = state.t_echo_out[1] + (int16)((state.t_echo_in[1] * (int8)REG(efb)) >> 7); - - state.t_echo_out[0] = sclamp<16>(l) & ~1; - state.t_echo_out[1] = sclamp<16>(r) & ~1; -} - -void DSP::echo_27() { - //output - int outl = state.t_main_out[0]; - int outr = echo_output(1); - state.t_main_out[0] = 0; - state.t_main_out[1] = 0; - - //TODO: global muting isn't this simple - //(turns DAC on and off or something, causing small ~37-sample pulse when first muted) - if(REG(flg) & 0x40) { - outl = 0; - outr = 0; - } - - //output sample to DAC - audio.sample(outl, outr); -} - -void DSP::echo_28() { - state.t_echo_disabled = REG(flg); -} - -void DSP::echo_29() { - state.t_esa = REG(esa); - - if(!state.echo_offset) state.echo_length = (REG(edl) & 0x0f) << 11; - - state.echo_offset += 4; - if(state.echo_offset >= state.echo_length) state.echo_offset = 0; - - //write left echo - echo_write(0); - - state.t_echo_disabled = REG(flg); -} - -void DSP::echo_30() { - //write right echo - echo_write(1); -} - -#endif diff --git a/bsnes/dsp/envelope.cpp b/bsnes/dsp/envelope.cpp deleted file mode 100755 index 9ae0d3e0..00000000 --- a/bsnes/dsp/envelope.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifdef DSP_CPP - -void DSP::envelope_run(voice_t &v) { - int env = v.env; - - if(v.env_mode == env_release) { //60% - env -= 0x8; - if(env < 0) env = 0; - v.env = env; - return; - } - - int rate; - int env_data = VREG(adsr1); - if(state.t_adsr0 & 0x80) { //99% ADSR - if(v.env_mode >= env_decay) { //99% - env--; - env -= env >> 8; - rate = env_data & 0x1f; - if(v.env_mode == env_decay) { //1% - rate = ((state.t_adsr0 >> 3) & 0x0e) + 0x10; - } - } else { //env_attack - rate = ((state.t_adsr0 & 0x0f) << 1) + 1; - env += rate < 31 ? 0x20 : 0x400; - } - } else { //GAIN - env_data = VREG(gain); - int mode = env_data >> 5; - if(mode < 4) { //direct - env = env_data << 4; - rate = 31; - } else { - rate = env_data & 0x1f; - if(mode == 4) { //4: linear decrease - env -= 0x20; - } else if(mode < 6) { //5: exponential decrease - env--; - env -= env >> 8; - } else { //6, 7: linear increase - env += 0x20; - if(mode > 6 && (unsigned)v.hidden_env >= 0x600) { - env += 0x8 - 0x20; //7: two-slope linear increase - } - } - } - } - - //sustain level - if((env >> 8) == (env_data >> 5) && v.env_mode == env_decay) v.env_mode = env_sustain; - v.hidden_env = env; - - //unsigned cast because linear decrease underflowing also triggers this - if((unsigned)env > 0x7ff) { - env = (env < 0 ? 0 : 0x7ff); - if(v.env_mode == env_attack) v.env_mode = env_decay; - } - - if(counter_poll(rate) == true) v.env = env; -} - -#endif diff --git a/bsnes/dsp/gaussian.cpp b/bsnes/dsp/gaussian.cpp deleted file mode 100755 index 80aed8ad..00000000 --- a/bsnes/dsp/gaussian.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#ifdef DSP_CPP - -const int16 DSP::gaussian_table[512] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, - 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, - 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, - 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 26, 27, 27, - 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 36, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 58, 59, 60, 61, 62, 64, 65, 66, 67, 69, 70, 71, 73, 74, 76, 77, - 78, 80, 81, 83, 84, 86, 87, 89, 90, 92, 94, 95, 97, 99, 100, 102, - 104, 106, 107, 109, 111, 113, 115, 117, 118, 120, 122, 124, 126, 128, 130, 132, - 134, 137, 139, 141, 143, 145, 147, 150, 152, 154, 156, 159, 161, 163, 166, 168, - 171, 173, 175, 178, 180, 183, 186, 188, 191, 193, 196, 199, 201, 204, 207, 210, - 212, 215, 218, 221, 224, 227, 230, 233, 236, 239, 242, 245, 248, 251, 254, 257, - 260, 263, 267, 270, 273, 276, 280, 283, 286, 290, 293, 297, 300, 304, 307, 311, - 314, 318, 321, 325, 328, 332, 336, 339, 343, 347, 351, 354, 358, 362, 366, 370, - 374, 378, 381, 385, 389, 393, 397, 401, 405, 410, 414, 418, 422, 426, 430, 434, - 439, 443, 447, 451, 456, 460, 464, 469, 473, 477, 482, 486, 491, 495, 499, 504, - 508, 513, 517, 522, 527, 531, 536, 540, 545, 550, 554, 559, 563, 568, 573, 577, - 582, 587, 592, 596, 601, 606, 611, 615, 620, 625, 630, 635, 640, 644, 649, 654, - 659, 664, 669, 674, 678, 683, 688, 693, 698, 703, 708, 713, 718, 723, 728, 732, - 737, 742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 806, 811, - 816, 821, 826, 831, 836, 841, 846, 851, 855, 860, 865, 870, 875, 880, 884, 889, - 894, 899, 904, 908, 913, 918, 923, 927, 932, 937, 941, 946, 951, 955, 960, 965, - 969, 974, 978, 983, 988, 992, 997, 1001, 1005, 1010, 1014, 1019, 1023, 1027, 1032, 1036, - 1040, 1045, 1049, 1053, 1057, 1061, 1066, 1070, 1074, 1078, 1082, 1086, 1090, 1094, 1098, 1102, - 1106, 1109, 1113, 1117, 1121, 1125, 1128, 1132, 1136, 1139, 1143, 1146, 1150, 1153, 1157, 1160, - 1164, 1167, 1170, 1174, 1177, 1180, 1183, 1186, 1190, 1193, 1196, 1199, 1202, 1205, 1207, 1210, - 1213, 1216, 1219, 1221, 1224, 1227, 1229, 1232, 1234, 1237, 1239, 1241, 1244, 1246, 1248, 1251, - 1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267, 1269, 1270, 1272, 1274, 1275, 1277, 1279, 1280, - 1282, 1283, 1284, 1286, 1287, 1288, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1297, 1298, - 1299, 1300, 1300, 1301, 1302, 1302, 1303, 1303, 1303, 1304, 1304, 1304, 1304, 1304, 1305, 1305, -}; - -int DSP::gaussian_interpolate(const voice_t &v) { - //make pointers into gaussian table based on fractional position between samples - int offset = (v.interp_pos >> 4) & 0xff; - const int16 *fwd = gaussian_table + 255 - offset; - const int16 *rev = gaussian_table + offset; //mirror left half of gaussian table - - offset = v.buf_pos + (v.interp_pos >> 12); - int output; - output = (fwd[ 0] * v.buffer[offset + 0]) >> 11; - output += (fwd[256] * v.buffer[offset + 1]) >> 11; - output += (rev[256] * v.buffer[offset + 2]) >> 11; - output = (int16)output; - output += (rev[ 0] * v.buffer[offset + 3]) >> 11; - return sclamp<16>(output) & ~1; -} - -#endif diff --git a/bsnes/dsp/misc.cpp b/bsnes/dsp/misc.cpp deleted file mode 100755 index 244fc51f..00000000 --- a/bsnes/dsp/misc.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifdef DSP_CPP - -void DSP::misc_27() { - state.t_pmon = REG(pmon) & ~1; //voice 0 doesn't support PMON -} - -void DSP::misc_28() { - state.t_non = REG(non); - state.t_eon = REG(eon); - state.t_dir = REG(dir); -} - -void DSP::misc_29() { - state.every_other_sample ^= 1; - if(state.every_other_sample) { - state.new_kon &= ~state.kon; //clears KON 63 clocks after it was last read - } -} - -void DSP::misc_30() { - if(state.every_other_sample) { - state.kon = state.new_kon; - state.t_koff = REG(koff); - } - - counter_tick(); - - //noise - if(counter_poll(REG(flg) & 0x1f) == true) { - int feedback = (state.noise << 13) ^ (state.noise << 14); - state.noise = (feedback & 0x4000) ^ (state.noise >> 1); - } -} - -#endif diff --git a/bsnes/dsp/serialization.cpp b/bsnes/dsp/serialization.cpp deleted file mode 100755 index da13be48..00000000 --- a/bsnes/dsp/serialization.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifdef DSP_CPP - -void DSP::serialize(serializer &s) { - Processor::serialize(s); - s.integer(phase_index); - - s.array(state.regs, 128); - state.echo_hist[0].serialize(s); - state.echo_hist[1].serialize(s); - s.integer(state.echo_hist_pos); - - s.integer(state.every_other_sample); - s.integer(state.kon); - s.integer(state.noise); - s.integer(state.counter); - s.integer(state.echo_offset); - s.integer(state.echo_length); - - s.integer(state.new_kon); - s.integer(state.endx_buf); - s.integer(state.envx_buf); - s.integer(state.outx_buf); - - s.integer(state.t_pmon); - s.integer(state.t_non); - s.integer(state.t_eon); - s.integer(state.t_dir); - s.integer(state.t_koff); - - s.integer(state.t_brr_next_addr); - s.integer(state.t_adsr0); - s.integer(state.t_brr_header); - s.integer(state.t_brr_byte); - s.integer(state.t_srcn); - s.integer(state.t_esa); - s.integer(state.t_echo_disabled); - - s.integer(state.t_dir_addr); - s.integer(state.t_pitch); - s.integer(state.t_output); - s.integer(state.t_looped); - s.integer(state.t_echo_ptr); - - s.integer(state.t_main_out[0]); - s.integer(state.t_main_out[1]); - s.integer(state.t_echo_out[0]); - s.integer(state.t_echo_out[1]); - s.integer(state.t_echo_in [0]); - s.integer(state.t_echo_in [1]); - - for(unsigned n = 0; n < 8; n++) { - voice[n].buffer.serialize(s); - s.integer(voice[n].buf_pos); - s.integer(voice[n].interp_pos); - s.integer(voice[n].brr_addr); - s.integer(voice[n].brr_offset); - s.integer(voice[n].vbit); - s.integer(voice[n].vidx); - s.integer(voice[n].kon_delay); - s.integer(voice[n].env_mode); - s.integer(voice[n].env); - s.integer(voice[n].t_envx_out); - s.integer(voice[n].hidden_env); - } -} - -#endif diff --git a/bsnes/dsp/voice.cpp b/bsnes/dsp/voice.cpp deleted file mode 100755 index 2e882f21..00000000 --- a/bsnes/dsp/voice.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#ifdef DSP_CPP - -inline void DSP::voice_output(voice_t &v, bool channel) { - //apply left/right volume - int amp = (state.t_output * (int8)VREG(voll + channel)) >> 7; - - //add to output total - state.t_main_out[channel] += amp; - state.t_main_out[channel] = sclamp<16>(state.t_main_out[channel]); - - //optionally add to echo total - if(state.t_eon & v.vbit) { - state.t_echo_out[channel] += amp; - state.t_echo_out[channel] = sclamp<16>(state.t_echo_out[channel]); - } -} - -void DSP::voice_1(voice_t &v) { - state.t_dir_addr = (state.t_dir << 8) + (state.t_srcn << 2); - state.t_srcn = VREG(srcn); -} - -void DSP::voice_2(voice_t &v) { - //read sample pointer (ignored if not needed) - uint16 addr = state.t_dir_addr; - if(!v.kon_delay) addr += 2; - uint8 lo = memory::apuram[(uint16)(addr + 0)]; - uint8 hi = memory::apuram[(uint16)(addr + 1)]; - state.t_brr_next_addr = ((hi << 8) + lo); - - state.t_adsr0 = VREG(adsr0); - - //read pitch, spread over two clocks - state.t_pitch = VREG(pitchl); -} - -void DSP::voice_3(voice_t &v) { - voice_3a(v); - voice_3b(v); - voice_3c(v); -} - -void DSP::voice_3a(voice_t &v) { - state.t_pitch += (VREG(pitchh) & 0x3f) << 8; -} - -void DSP::voice_3b(voice_t &v) { - state.t_brr_byte = memory::apuram[(uint16)(v.brr_addr + v.brr_offset)]; - state.t_brr_header = memory::apuram[(uint16)(v.brr_addr)]; -} - -void DSP::voice_3c(voice_t &v) { - //pitch modulation using previous voice's output - - if(state.t_pmon & v.vbit) { - state.t_pitch += ((state.t_output >> 5) * state.t_pitch) >> 10; - } - - if(v.kon_delay) { - //get ready to start BRR decoding on next sample - if(v.kon_delay == 5) { - v.brr_addr = state.t_brr_next_addr; - v.brr_offset = 1; - v.buf_pos = 0; - state.t_brr_header = 0; //header is ignored on this sample - } - - //envelope is never run during KON - v.env = 0; - v.hidden_env = 0; - - //disable BRR decoding until last three samples - v.interp_pos = 0; - v.kon_delay--; - if(v.kon_delay & 3) v.interp_pos = 0x4000; - - //pitch is never added during KON - state.t_pitch = 0; - } - - //gaussian interpolation - int output = gaussian_interpolate(v); - - //noise - if(state.t_non & v.vbit) { - output = (int16)(state.noise << 1); - } - - //apply envelope - state.t_output = ((output * v.env) >> 11) & ~1; - v.t_envx_out = v.env >> 4; - - //immediate silence due to end of sample or soft reset - if(REG(flg) & 0x80 || (state.t_brr_header & 3) == 1) { - v.env_mode = env_release; - v.env = 0; - } - - if(state.every_other_sample) { - //KOFF - if(state.t_koff & v.vbit) { - v.env_mode = env_release; - } - - //KON - if(state.kon & v.vbit) { - v.kon_delay = 5; - v.env_mode = env_attack; - } - } - - //run envelope for next sample - if(!v.kon_delay) envelope_run(v); -} - -void DSP::voice_4(voice_t &v) { - //decode BRR - state.t_looped = 0; - if(v.interp_pos >= 0x4000) { - brr_decode(v); - v.brr_offset += 2; - if(v.brr_offset >= 9) { - //start decoding next BRR block - v.brr_addr = (uint16)(v.brr_addr + 9); - if(state.t_brr_header & 1) { - v.brr_addr = state.t_brr_next_addr; - state.t_looped = v.vbit; - } - v.brr_offset = 1; - } - } - - //apply pitch - v.interp_pos = (v.interp_pos & 0x3fff) + state.t_pitch; - - //keep from getting too far ahead (when using pitch modulation) - if(v.interp_pos > 0x7fff) v.interp_pos = 0x7fff; - - //output left - voice_output(v, 0); -} - -void DSP::voice_5(voice_t &v) { - //output right - voice_output(v, 1); - - //ENDX, OUTX and ENVX won't update if you wrote to them 1-2 clocks earlier - state.endx_buf = REG(endx) | state.t_looped; - - //clear bit in ENDX if KON just began - if(v.kon_delay == 5) state.endx_buf &= ~v.vbit; -} - -void DSP::voice_6(voice_t &v) { - state.outx_buf = state.t_output >> 8; -} - -void DSP::voice_7(voice_t &v) { - //update ENDX - REG(endx) = (uint8)state.endx_buf; - state.envx_buf = v.t_envx_out; -} - -void DSP::voice_8(voice_t &v) { - //update OUTX - VREG(outx) = (uint8)state.outx_buf; -} - -void DSP::voice_9(voice_t &v) { - //update ENVX - VREG(envx) = (uint8)state.envx_buf; -} - -#endif diff --git a/bsnes/info.hpp b/bsnes/info.hpp deleted file mode 100755 index add71c68..00000000 --- a/bsnes/info.hpp +++ /dev/null @@ -1,11 +0,0 @@ -namespace SNES { - namespace Info { - static const char Name[] = "bsnes"; - static const char Version[] = "067.11"; - static const unsigned SerializerVersion = 12; - } -} - -//#define DEBUGGER -#define DSP_STATE_MACHINE -#define CHEAT_SYSTEM diff --git a/bsnes/input/input.cpp b/bsnes/input/input.cpp deleted file mode 100755 index dbd3ad71..00000000 --- a/bsnes/input/input.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#ifdef SYSTEM_CPP - -Input input; - -uint8 Input::port_read(bool portnumber) { - if(cartridge.has_serial() && portnumber == 1) { - return serial.latch(); - } - - port_t &p = port[portnumber]; - - switch(p.device) { - case Device::Joypad: { - if(cpu.joylatch() == 0) { - if(p.counter0 >= 16) return 1; - return system.interface->input_poll(portnumber, p.device, 0, p.counter0++); - } else { - return system.interface->input_poll(portnumber, p.device, 0, 0); - } - } //case Device::Joypad - - case Device::Multitap: { - if(cpu.joylatch()) return 2; //when latch is high -- data2 = 1, data1 = 0 - - unsigned deviceidx, deviceindex0, deviceindex1; - uint8 mask = (portnumber == 0 ? 0x40 : 0x80); - - if(cpu.pio() & mask) { - deviceidx = p.counter0; - if(deviceidx >= 16) return 3; - p.counter0++; - - deviceindex0 = 0; //controller 1 - deviceindex1 = 1; //controller 2 - } else { - deviceidx = p.counter1; - if(deviceidx >= 16) return 3; - p.counter1++; - - deviceindex0 = 2; //controller 3 - deviceindex1 = 3; //controller 4 - } - - return (system.interface->input_poll(portnumber, p.device, deviceindex0, deviceidx) << 0) - | (system.interface->input_poll(portnumber, p.device, deviceindex1, deviceidx) << 1); - } //case Device::Multitap - - case Device::Mouse: { - if(p.counter0 >= 32) return 1; - - int position_x = system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::X); //-n = left, 0 = center, +n = right - int position_y = system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::Y); //-n = up, 0 = center, +n = right - - bool direction_x = position_x < 0; //0 = right, 1 = left - bool direction_y = position_y < 0; //0 = down, 1 = up - - if(position_x < 0) position_x = -position_x; //abs(position_x) - if(position_y < 0) position_y = -position_y; //abs(position_x) - - position_x = min(127, position_x); //range = 0 - 127 - position_y = min(127, position_y); //range = 0 - 127 - - switch(p.counter0++) { default: - case 0: return 0; - case 1: return 0; - case 2: return 0; - case 3: return 0; - case 4: return 0; - case 5: return 0; - case 6: return 0; - case 7: return 0; - - case 8: return system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::Right); - case 9: return system.interface->input_poll(portnumber, p.device, 0, (unsigned)MouseID::Left); - case 10: return 0; //speed (0 = slow, 1 = normal, 2 = fast, 3 = unused) - case 11: return 0; // || - - case 12: return 0; //signature - case 13: return 0; // || - case 14: return 0; // || - case 15: return 1; // || - - case 16: return (direction_y) & 1; - case 17: return (position_y >> 6) & 1; - case 18: return (position_y >> 5) & 1; - case 19: return (position_y >> 4) & 1; - case 20: return (position_y >> 3) & 1; - case 21: return (position_y >> 2) & 1; - case 22: return (position_y >> 1) & 1; - case 23: return (position_y >> 0) & 1; - - case 24: return (direction_x) & 1; - case 25: return (position_x >> 6) & 1; - case 26: return (position_x >> 5) & 1; - case 27: return (position_x >> 4) & 1; - case 28: return (position_x >> 3) & 1; - case 29: return (position_x >> 2) & 1; - case 30: return (position_x >> 1) & 1; - case 31: return (position_x >> 0) & 1; - } - } //case Device::Mouse - - case Device::SuperScope: { - if(portnumber == 0) break; //Super Scope in port 1 not supported ... - if(p.counter0 >= 8) return 1; - - if(p.counter0 == 0) { - //turbo is a switch; toggle is edge sensitive - bool turbo = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Turbo); - if(turbo && !p.superscope.turbolock) { - p.superscope.turbo = !p.superscope.turbo; //toggle state - p.superscope.turbolock = true; - } else if(!turbo) { - p.superscope.turbolock = false; - } - - //trigger is a button - //if turbo is active, trigger is level sensitive; otherwise it is edge sensitive - p.superscope.trigger = false; - bool trigger = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Trigger); - if(trigger && (p.superscope.turbo || !p.superscope.triggerlock)) { - p.superscope.trigger = true; - p.superscope.triggerlock = true; - } else if(!trigger) { - p.superscope.triggerlock = false; - } - - //cursor is a button; it is always level sensitive - p.superscope.cursor = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Cursor); - - //pause is a button; it is always edge sensitive - p.superscope.pause = false; - bool pause = system.interface->input_poll(portnumber, p.device, 0, (unsigned)SuperScopeID::Pause); - if(pause && !p.superscope.pauselock) { - p.superscope.pause = true; - p.superscope.pauselock = true; - } else if(!pause) { - p.superscope.pauselock = false; - } - - p.superscope.offscreen = - p.superscope.x < 0 || p.superscope.x >= 256 - || p.superscope.y < 0 || p.superscope.y >= (ppu.overscan() ? 240 : 225); - } - - switch(p.counter0++) { - case 0: return p.superscope.trigger; - case 1: return p.superscope.cursor; - case 2: return p.superscope.turbo; - case 3: return p.superscope.pause; - case 4: return 0; - case 5: return 0; - case 6: return p.superscope.offscreen; - case 7: return 0; //noise (1 = yes) - } - } //case Device::SuperScope - - case Device::Justifier: - case Device::Justifiers: { - if(portnumber == 0) break; //Justifier in port 1 not supported ... - if(p.counter0 >= 32) return 1; - - if(p.counter0 == 0) { - p.justifier.trigger1 = system.interface->input_poll(portnumber, p.device, 0, (unsigned)JustifierID::Trigger); - p.justifier.start1 = system.interface->input_poll(portnumber, p.device, 0, (unsigned)JustifierID::Start); - - if(p.device == Device::Justifiers) { - p.justifier.trigger2 = system.interface->input_poll(portnumber, p.device, 1, (unsigned)JustifierID::Trigger); - p.justifier.start2 = system.interface->input_poll(portnumber, p.device, 1, (unsigned)JustifierID::Start); - } else { - p.justifier.x2 = -1; - p.justifier.y2 = -1; - - p.justifier.trigger2 = false; - p.justifier.start2 = false; - } - } - - switch(p.counter0++) { - case 0: return 0; - case 1: return 0; - case 2: return 0; - case 3: return 0; - case 4: return 0; - case 5: return 0; - case 6: return 0; - case 7: return 0; - case 8: return 0; - case 9: return 0; - case 10: return 0; - case 11: return 0; - - case 12: return 1; //signature - case 13: return 1; // || - case 14: return 1; // || - case 15: return 0; // || - - case 16: return 0; - case 17: return 1; - case 18: return 0; - case 19: return 1; - case 20: return 0; - case 21: return 1; - case 22: return 0; - case 23: return 1; - - case 24: return p.justifier.trigger1; - case 25: return p.justifier.trigger2; - case 26: return p.justifier.start1; - case 27: return p.justifier.start2; - case 28: return p.justifier.active; - - case 29: return 0; - case 30: return 0; - case 31: return 0; - } - } //case Device::Justifier(s) - } //switch(p.device) - - //no device connected - return 0; -} - -//scan all input; update cursor positions if needed -void Input::update() { - system.interface->input_poll(); - port_t &p = port[1]; - - switch(p.device) { - case Device::SuperScope: { - int x = system.interface->input_poll(1, p.device, 0, (unsigned)SuperScopeID::X); - int y = system.interface->input_poll(1, p.device, 0, (unsigned)SuperScopeID::Y); - x += p.superscope.x; - y += p.superscope.y; - p.superscope.x = max(-16, min(256 + 16, x)); - p.superscope.y = max(-16, min(240 + 16, y)); - - latchx = p.superscope.x; - latchy = p.superscope.y; - } break; - - case Device::Justifier: - case Device::Justifiers: { - int x1 = system.interface->input_poll(1, p.device, 0, (unsigned)JustifierID::X); - int y1 = system.interface->input_poll(1, p.device, 0, (unsigned)JustifierID::Y); - x1 += p.justifier.x1; - y1 += p.justifier.y1; - p.justifier.x1 = max(-16, min(256 + 16, x1)); - p.justifier.y1 = max(-16, min(240 + 16, y1)); - - int x2 = system.interface->input_poll(1, p.device, 1, (unsigned)JustifierID::X); - int y2 = system.interface->input_poll(1, p.device, 1, (unsigned)JustifierID::Y); - x2 += p.justifier.x2; - y2 += p.justifier.y2; - p.justifier.x2 = max(-16, min(256 + 16, x2)); - p.justifier.y2 = max(-16, min(240 + 16, y2)); - - if(p.justifier.active == 0) { - latchx = p.justifier.x1; - latchy = p.justifier.y1; - } else { - latchx = (p.device == Device::Justifiers ? p.justifier.x2 : -1); - latchy = (p.device == Device::Justifiers ? p.justifier.y2 : -1); - } - } break; - } - - if(latchy < 0 || latchy >= (ppu.overscan() ? 240 : 225) || latchx < 0 || latchx >= 256) { - //cursor is offscreen, set to invalid position so counters are not latched - latchx = ~0; - latchy = ~0; - } else { - //cursor is onscreen - latchx += 40; //offset trigger position to simulate hardware latching delay - latchx <<= 2; //dot -> clock conversion - latchx += 2; //align trigger on half-dot ala interrupts (speed optimization for sCPU::add_clocks) - } -} - -void Input::port_set_device(bool portnumber, Device device) { - port_t &p = port[portnumber]; - - p.device = device; - p.counter0 = 0; - p.counter1 = 0; - - //set iobit to true if device is capable of latching PPU counters - iobit = port[1].device == Device::SuperScope - || port[1].device == Device::Justifier - || port[1].device == Device::Justifiers; - latchx = -1; - latchy = -1; - - if(device == Device::SuperScope) { - p.superscope.x = 256 / 2; - p.superscope.y = 240 / 2; - - p.superscope.trigger = false; - p.superscope.cursor = false; - p.superscope.turbo = false; - p.superscope.pause = false; - p.superscope.offscreen = false; - - p.superscope.turbolock = false; - p.superscope.triggerlock = false; - p.superscope.pauselock = false; - } else if(device == Device::Justifier) { - p.justifier.active = 0; - p.justifier.x1 = 256 / 2; - p.justifier.y1 = 240 / 2; - p.justifier.x2 = -1; - p.justifier.y2 = -1; - - p.justifier.trigger1 = false; - p.justifier.trigger2 = false; - p.justifier.start1 = false; - p.justifier.start2 = false; - } else if(device == Device::Justifiers) { - p.justifier.active = 0; - p.justifier.x1 = 256 / 2 - 16; - p.justifier.y1 = 240 / 2; - p.justifier.x2 = 256 / 2 + 16; - p.justifier.y2 = 240 / 2; - - p.justifier.trigger1 = false; - p.justifier.trigger2 = false; - p.justifier.start1 = false; - p.justifier.start2 = false; - } -} - -void Input::poll() { - port[0].counter0 = 0; - port[0].counter1 = 0; - port[1].counter0 = 0; - port[1].counter1 = 0; - - port[1].justifier.active = !port[1].justifier.active; -} - -void Input::init() { -} - -#endif diff --git a/bsnes/input/input.hpp b/bsnes/input/input.hpp deleted file mode 100755 index e24ac2ed..00000000 --- a/bsnes/input/input.hpp +++ /dev/null @@ -1,87 +0,0 @@ -class Input { -public: - enum class Device : unsigned { - None, - Joypad, - Multitap, - Mouse, - SuperScope, - Justifier, - Justifiers, - }; - - enum class JoypadID : unsigned { - B = 0, Y = 1, Select = 2, Start = 3, - Up = 4, Down = 5, Left = 6, Right = 7, - A = 8, X = 9, L = 10, R = 11, - }; - - enum class MouseID : unsigned { - X = 0, Y = 1, Left = 2, Right = 3, - }; - - enum class SuperScopeID : unsigned { - X = 0, Y = 1, Trigger = 2, Cursor = 3, Turbo = 4, Pause = 5, - }; - - enum class JustifierID : unsigned { - X = 0, Y = 1, Trigger = 2, Start = 3, - }; - - uint8 port_read(bool port); - void port_set_device(bool port, Device device); - void init(); - void poll(); - void update(); - - //light guns (Super Scope, Justifier(s)) strobe IOBit whenever the CRT - //beam cannon is detected. this needs to be tested at the cycle level - //(hence inlining here for speed) to avoid 'dead space' during DRAM refresh. - //iobit is updated during port_set_device(), - //latchx, latchy are updated during update() (once per frame) - alwaysinline void tick() { - //only test if Super Scope or Justifier is connected - if(iobit && cpu.vcounter() == latchy && cpu.hcounter() == latchx) { - ppu.latch_counters(); - } - } - -private: - bool iobit; - int16_t latchx, latchy; - - struct port_t { - Device device; - unsigned counter0; //read counters - unsigned counter1; - - struct superscope_t { - int x, y; - - bool trigger; - bool cursor; - bool turbo; - bool pause; - bool offscreen; - - bool turbolock; - bool triggerlock; - bool pauselock; - } superscope; - - struct justifier_t { - bool active; - - int x1, x2; - int y1, y2; - - bool trigger1, trigger2; - bool start1, start2; - } justifier; - } port[2]; - - friend class System; - friend class Video; -}; - -extern Input input; diff --git a/bsnes/interface/interface.hpp b/bsnes/interface/interface.hpp deleted file mode 100755 index e9ec2635..00000000 --- a/bsnes/interface/interface.hpp +++ /dev/null @@ -1,7 +0,0 @@ -class Interface { -public: - virtual void video_refresh(const uint16_t *data, unsigned width, unsigned height) {} - virtual void audio_sample(uint16_t l_sample, uint16_t r_sample) {} - virtual void input_poll() {} - virtual int16_t input_poll(bool port, Input::Device device, unsigned index, unsigned id) { return 0; } -}; diff --git a/bsnes/libsnes/libsnes.cpp b/bsnes/libsnes/libsnes.cpp deleted file mode 100755 index 63fc6252..00000000 --- a/bsnes/libsnes/libsnes.cpp +++ /dev/null @@ -1,264 +0,0 @@ -#include "libsnes.hpp" -#include - -#include -using namespace nall; - -struct Interface : public SNES::Interface { - snes_video_refresh_t pvideo_refresh; - snes_audio_sample_t paudio_sample; - snes_input_poll_t pinput_poll; - snes_input_state_t pinput_state; - - void video_refresh(const uint16_t *data, unsigned width, unsigned height) { - if(pvideo_refresh) return pvideo_refresh(data, width, height); - } - - void audio_sample(uint16_t left, uint16_t right) { - if(paudio_sample) return paudio_sample(left, right); - } - - void input_poll() { - if(pinput_poll) return pinput_poll(); - } - - int16_t input_poll(bool port, SNES::Input::Device device, unsigned index, unsigned id) { - if(pinput_state) return pinput_state(port, (unsigned)device, index, id); - return 0; - } - - Interface() : pvideo_refresh(0), paudio_sample(0), pinput_poll(0), pinput_state(0) { - } -}; - -static Interface interface; - -unsigned snes_library_revision_major(void) { - return 1; -} - -unsigned snes_library_revision_minor(void) { - return 0; -} - -void snes_set_video_refresh(snes_video_refresh_t video_refresh) { - interface.pvideo_refresh = video_refresh; -} - -void snes_set_audio_sample(snes_audio_sample_t audio_sample) { - interface.paudio_sample = audio_sample; -} - -void snes_set_input_poll(snes_input_poll_t input_poll) { - interface.pinput_poll = input_poll; -} - -void snes_set_input_state(snes_input_state_t input_state) { - interface.pinput_state = input_state; -} - -void snes_set_controller_port_device(bool port, unsigned device) { - SNES::input.port_set_device(port, (SNES::Input::Device)device); -} - -void snes_init(void) { - SNES::system.init(&interface); - SNES::input.port_set_device(0, SNES::Input::Device::Joypad); - SNES::input.port_set_device(1, SNES::Input::Device::Joypad); -} - -void snes_term(void) { - SNES::system.term(); -} - -void snes_power(void) { - SNES::system.power(); -} - -void snes_reset(void) { - SNES::system.reset(); -} - -void snes_run(void) { - SNES::system.run(); -} - -unsigned snes_serialize_size(void) { - return SNES::system.serialize_size(); -} - -bool snes_serialize(uint8_t *data, unsigned size) { - SNES::system.runtosave(); - serializer s = SNES::system.serialize(); - if(s.size() > size) return false; - memcpy(data, s.data(), s.size()); - return true; -} - -bool snes_unserialize(const uint8_t *data, unsigned size) { - serializer s(data, size); - return SNES::system.unserialize(s); -} - -void snes_cheat_reset(void) { - SNES::cheat.reset(); - SNES::cheat.synchronize(); -} - -void snes_cheat_set(unsigned index, bool enabled, const char *code) { - SNES::cheat[index] = code; - SNES::cheat[index].enabled = enabled; - SNES::cheat.synchronize(); -} - -bool snes_load_cartridge_normal( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::Normal, { xmlrom }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_bsx_slotted( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(bsx_data) SNES::memory::bsxflash.copy(bsx_data, bsx_size); - string xmlbsx = (bsx_xml && *bsx_xml) ? string(bsx_xml) : snes_information(bsx_data, bsx_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::BsxSlotted, { xmlrom, xmlbsx }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_bsx( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(bsx_data) SNES::memory::bsxflash.copy(bsx_data, bsx_size); - string xmlbsx = (bsx_xml && *bsx_xml) ? string(bsx_xml) : snes_information(bsx_data, bsx_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::Bsx, { xmlrom, xmlbsx }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_sufami_turbo( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *sta_xml, const uint8_t *sta_data, unsigned sta_size, - const char *stb_xml, const uint8_t *stb_data, unsigned stb_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(sta_data) SNES::memory::stArom.copy(sta_data, sta_size); - string xmlsta = (sta_xml && *sta_xml) ? string(sta_xml) : snes_information(sta_data, sta_size).xml_memory_map; - if(stb_data) SNES::memory::stBrom.copy(stb_data, stb_size); - string xmlstb = (stb_xml && *stb_xml) ? string(stb_xml) : snes_information(stb_data, stb_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::SufamiTurbo, { xmlrom, xmlsta, xmlstb }); - SNES::system.power(); - return true; -} - -bool snes_load_cartridge_super_game_boy( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size -) { - snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : snes_information(rom_data, rom_size).xml_memory_map; - if(dmg_data) SNES::memory::gbrom.copy(dmg_data, dmg_size); - string xmldmg = (dmg_xml && *dmg_xml) ? string(dmg_xml) : snes_information(dmg_data, dmg_size).xml_memory_map; - SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, { xmlrom, xmldmg }); - SNES::system.power(); - return true; -} - -void snes_unload_cartridge(void) { - SNES::cartridge.unload(); -} - -bool snes_get_region(void) { - return SNES::system.region() == SNES::System::Region::NTSC ? 0 : 1; -} - -uint8_t* snes_get_memory_data(unsigned id) { - if(SNES::cartridge.loaded() == false) return 0; - - switch(id) { - case SNES_MEMORY_CARTRIDGE_RAM: - return SNES::memory::cartram.data(); - case SNES_MEMORY_CARTRIDGE_RTC: - return SNES::memory::cartrtc.data(); - case SNES_MEMORY_BSX_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - return SNES::memory::bsxram.data(); - case SNES_MEMORY_BSX_PRAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - return SNES::memory::bsxpram.data(); - case SNES_MEMORY_SUFAMI_TURBO_A_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - return SNES::memory::stAram.data(); - case SNES_MEMORY_SUFAMI_TURBO_B_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - return SNES::memory::stBram.data(); - case SNES_MEMORY_GAME_BOY_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbram.data(); - case SNES_MEMORY_GAME_BOY_RTC: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbrtc.data(); - } - - return 0; -} - -unsigned snes_get_memory_size(unsigned id) { - if(SNES::cartridge.loaded() == false) return 0; - unsigned size = 0; - - switch(id) { - case SNES_MEMORY_CARTRIDGE_RAM: - size = SNES::memory::cartram.size(); - break; - case SNES_MEMORY_CARTRIDGE_RTC: - size = SNES::memory::cartrtc.size(); - break; - case SNES_MEMORY_BSX_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - size = SNES::memory::bsxram.size(); - break; - case SNES_MEMORY_BSX_PRAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::Bsx) break; - size = SNES::memory::bsxpram.size(); - break; - case SNES_MEMORY_SUFAMI_TURBO_A_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - size = SNES::memory::stAram.size(); - break; - case SNES_MEMORY_SUFAMI_TURBO_B_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SufamiTurbo) break; - size = SNES::memory::stBram.size(); - break; - case SNES_MEMORY_GAME_BOY_RAM: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbram.size(); - break; - case SNES_MEMORY_GAME_BOY_RTC: - if(SNES::cartridge.mode() != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbrtc.size(); - break; - } - - if(size == -1U) size = 0; - return size; -} diff --git a/bsnes/libsnes/libsnes.hpp b/bsnes/libsnes/libsnes.hpp deleted file mode 100755 index d895adb8..00000000 --- a/bsnes/libsnes/libsnes.hpp +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef LIBSNES_HPP -#define LIBSNES_HPP - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define SNES_PORT_1 0 -#define SNES_PORT_2 1 - -#define SNES_DEVICE_NONE 0 -#define SNES_DEVICE_JOYPAD 1 -#define SNES_DEVICE_MULTITAP 2 -#define SNES_DEVICE_MOUSE 3 -#define SNES_DEVICE_SUPER_SCOPE 4 -#define SNES_DEVICE_JUSTIFIER 5 -#define SNES_DEVICE_JUSTIFIERS 6 - -#define SNES_DEVICE_ID_JOYPAD_B 0 -#define SNES_DEVICE_ID_JOYPAD_Y 1 -#define SNES_DEVICE_ID_JOYPAD_SELECT 2 -#define SNES_DEVICE_ID_JOYPAD_START 3 -#define SNES_DEVICE_ID_JOYPAD_UP 4 -#define SNES_DEVICE_ID_JOYPAD_DOWN 5 -#define SNES_DEVICE_ID_JOYPAD_LEFT 6 -#define SNES_DEVICE_ID_JOYPAD_RIGHT 7 -#define SNES_DEVICE_ID_JOYPAD_A 8 -#define SNES_DEVICE_ID_JOYPAD_X 9 -#define SNES_DEVICE_ID_JOYPAD_L 10 -#define SNES_DEVICE_ID_JOYPAD_R 11 - -#define SNES_DEVICE_ID_MOUSE_X 0 -#define SNES_DEVICE_ID_MOUSE_Y 1 -#define SNES_DEVICE_ID_MOUSE_LEFT 2 -#define SNES_DEVICE_ID_MOUSE_RIGHT 3 - -#define SNES_DEVICE_ID_SUPER_SCOPE_X 0 -#define SNES_DEVICE_ID_SUPER_SCOPE_Y 1 -#define SNES_DEVICE_ID_SUPER_SCOPE_TRIGGER 2 -#define SNES_DEVICE_ID_SUPER_SCOPE_CURSOR 3 -#define SNES_DEVICE_ID_SUPER_SCOPE_TURBO 4 -#define SNES_DEVICE_ID_SUPER_SCOPE_PAUSE 5 - -#define SNES_DEVICE_ID_JUSTIFIER_X 0 -#define SNES_DEVICE_ID_JUSTIFIER_Y 1 -#define SNES_DEVICE_ID_JUSTIFIER_TRIGGER 2 -#define SNES_DEVICE_ID_JUSTIFIER_START 3 - -#define SNES_REGION_NTSC 0 -#define SNES_REGION_PAL 1 - -#define SNES_MEMORY_CARTRIDGE_RAM 0 -#define SNES_MEMORY_CARTRIDGE_RTC 1 -#define SNES_MEMORY_BSX_RAM 2 -#define SNES_MEMORY_BSX_PRAM 3 -#define SNES_MEMORY_SUFAMI_TURBO_A_RAM 4 -#define SNES_MEMORY_SUFAMI_TURBO_B_RAM 5 -#define SNES_MEMORY_GAME_BOY_RAM 6 -#define SNES_MEMORY_GAME_BOY_RTC 7 - -typedef void (*snes_video_refresh_t)(const uint16_t *data, unsigned width, unsigned height); -typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right); -typedef void (*snes_input_poll_t)(void); -typedef int16_t (*snes_input_state_t)(bool port, unsigned device, unsigned index, unsigned id); - -unsigned snes_library_revision_major(void); -unsigned snes_library_revision_minor(void); - -void snes_set_video_refresh(snes_video_refresh_t); -void snes_set_audio_sample(snes_audio_sample_t); -void snes_set_input_poll(snes_input_poll_t); -void snes_set_input_state(snes_input_state_t); - -void snes_set_controller_port_device(bool port, unsigned device); - -void snes_init(void); -void snes_term(void); -void snes_power(void); -void snes_reset(void); -void snes_run(void); - -unsigned snes_serialize_size(void); -bool snes_serialize(uint8_t *data, unsigned size); -bool snes_unserialize(const uint8_t *data, unsigned size); - -void snes_cheat_reset(void); -void snes_cheat_set(unsigned index, bool enabled, const char *code); - -bool snes_load_cartridge_normal( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size -); - -bool snes_load_cartridge_bsx_slotted( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -); - -bool snes_load_cartridge_bsx( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *bsx_xml, const uint8_t *bsx_data, unsigned bsx_size -); - -bool snes_load_cartridge_sufami_turbo( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *sta_xml, const uint8_t *sta_data, unsigned sta_size, - const char *stb_xml, const uint8_t *stb_data, unsigned stb_size -); - -bool snes_load_cartridge_super_game_boy( - const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, - const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size -); - -void snes_unload_cartridge(void); - -bool snes_get_region(void); -uint8_t* snes_get_memory_data(unsigned id); -unsigned snes_get_memory_size(unsigned id); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/bsnes/memory/memory-inline.hpp b/bsnes/memory/memory-inline.hpp deleted file mode 100755 index d49f8d48..00000000 --- a/bsnes/memory/memory-inline.hpp +++ /dev/null @@ -1,69 +0,0 @@ -//Memory - -unsigned Memory::size() const { return 0; } - -//StaticRAM - -uint8* StaticRAM::data() { return data_; } -unsigned StaticRAM::size() const { return size_; } - -uint8 StaticRAM::read(unsigned addr) { return data_[addr]; } -void StaticRAM::write(unsigned addr, uint8 n) { data_[addr] = n; } -uint8& StaticRAM::operator[](unsigned addr) { return data_[addr]; } -const uint8& StaticRAM::operator[](unsigned addr) const { return data_[addr]; } - -StaticRAM::StaticRAM(unsigned n) : size_(n) { data_ = new uint8[size_]; } -StaticRAM::~StaticRAM() { delete[] data_; } - -//MappedRAM - -void MappedRAM::reset() { - if(data_) { - delete[] data_; - data_ = 0; - } - size_ = -1U; - write_protect_ = false; -} - -void MappedRAM::map(uint8 *source, unsigned length) { - reset(); - data_ = source; - size_ = data_ && length > 0 ? length : -1U; -} - -void MappedRAM::copy(const uint8 *data, unsigned size) { - if(!data_) { - size_ = (size & ~255) + ((bool)(size & 255) << 8); - data_ = new uint8[size_](); - } - memcpy(data_, data, min(size_, size)); -} - -void MappedRAM::write_protect(bool status) { write_protect_ = status; } -uint8* MappedRAM::data() { return data_; } -unsigned MappedRAM::size() const { return size_; } - -uint8 MappedRAM::read(unsigned addr) { return data_[addr]; } -void MappedRAM::write(unsigned addr, uint8 n) { if(!write_protect_) data_[addr] = n; } -const uint8& MappedRAM::operator[](unsigned addr) const { return data_[addr]; } -MappedRAM::MappedRAM() : data_(0), size_(-1U), write_protect_(false) {} - -//Bus - -uint8 Bus::read(unsigned addr) { - #if defined(CHEAT_SYSTEM) - if(cheat.active() && cheat.exists(addr)) { - uint8 r; - if(cheat.read(addr, r)) return r; - } - #endif - - Page &p = page[addr >> 8]; - return p.access->read(p.offset + addr); -} - -void Bus::write(unsigned addr, uint8 data) { - Page &p = page[addr >> 8]; - return p.access->write(p.offset + addr, data); -} diff --git a/bsnes/memory/memory.cpp b/bsnes/memory/memory.cpp deleted file mode 100755 index affd4f2e..00000000 --- a/bsnes/memory/memory.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include - -#define MEMORY_CPP -namespace SNES { - -Bus bus; - -#include "serialization.cpp" - -namespace memory { - MMIOAccess mmio; - StaticRAM wram(128 * 1024); - StaticRAM apuram(64 * 1024); - StaticRAM vram(64 * 1024); - StaticRAM oam(544); - StaticRAM cgram(512); - - UnmappedMemory memory_unmapped; - UnmappedMMIO mmio_unmapped; -}; - -unsigned UnmappedMemory::size() const { return 16 * 1024 * 1024; } -uint8 UnmappedMemory::read(unsigned) { return cpu.regs.mdr; } -void UnmappedMemory::write(unsigned, uint8) {} - -uint8 UnmappedMMIO::mmio_read(unsigned) { return cpu.regs.mdr; } -void UnmappedMMIO::mmio_write(unsigned, uint8) {} - -void MMIOAccess::map(unsigned addr, MMIO &access) { - //MMIO: $[00-3f]:[2000-5fff] - mmio[(addr - 0x2000) & 0x3fff] = &access; -} - -uint8 MMIOAccess::read(unsigned addr) { - return mmio[(addr - 0x2000) & 0x3fff]->mmio_read(addr); -} - -void MMIOAccess::write(unsigned addr, uint8 data) { - mmio[(addr - 0x2000) & 0x3fff]->mmio_write(addr, data); -} - -unsigned Bus::mirror(unsigned addr, unsigned size) { - unsigned base = 0; - if(size) { - unsigned mask = 1 << 23; - while(addr >= size) { - while(!(addr & mask)) mask >>= 1; - addr -= mask; - if(size > mask) { - size -= mask; - base += mask; - } - mask >>= 1; - } - base += addr; - } - return base; -} - -void Bus::map(unsigned addr, Memory &access, unsigned offset) { - page[addr >> 8].access = &access; - page[addr >> 8].offset = offset - addr; -} - -void Bus::map( - MapMode mode, - uint8 bank_lo, uint8 bank_hi, - uint16 addr_lo, uint16 addr_hi, - Memory &access, unsigned offset, unsigned size -) { - assert(bank_lo <= bank_hi); - assert(addr_lo <= addr_hi); - if(access.size() == -1U) return; - - uint8 page_lo = addr_lo >> 8; - uint8 page_hi = addr_hi >> 8; - unsigned index = 0; - - switch(mode) { - case MapMode::Direct: { - for(unsigned bank = bank_lo; bank <= bank_hi; bank++) { - for(unsigned page = page_lo; page <= page_hi; page++) { - map((bank << 16) + (page << 8), access, (bank << 16) + (page << 8)); - } - } - } break; - - case MapMode::Linear: { - for(unsigned bank = bank_lo; bank <= bank_hi; bank++) { - for(unsigned page = page_lo; page <= page_hi; page++) { - map((bank << 16) + (page << 8), access, mirror(offset + index, access.size())); - index += 256; - if(size) index %= size; - } - } - } break; - - case MapMode::Shadow: { - for(unsigned bank = bank_lo; bank <= bank_hi; bank++) { - index += page_lo * 256; - if(size) index %= size; - - for(unsigned page = page_lo; page <= page_hi; page++) { - map((bank << 16) + (page << 8), access, mirror(offset + index, access.size())); - index += 256; - if(size) index %= size; - } - - index += (255 - page_hi) * 256; - if(size) index %= size; - } - } break; - } -} - -bool Bus::load_cart() { - if(cartridge.loaded() == true) return false; - - map_reset(); - map_xml(); - map_system(); - return true; -} - -void Bus::unload_cart() { -} - -void Bus::map_reset() { - map(MapMode::Direct, 0x00, 0xff, 0x0000, 0xffff, memory::memory_unmapped); - map(MapMode::Direct, 0x00, 0x3f, 0x2000, 0x5fff, memory::mmio); - map(MapMode::Direct, 0x80, 0xbf, 0x2000, 0x5fff, memory::mmio); - for(unsigned i = 0x2000; i <= 0x5fff; i++) memory::mmio.map(i, memory::mmio_unmapped); -} - -void Bus::map_xml() { - foreach(m, cartridge.mapping) { - if(m.memory) { - map(m.mode, m.banklo, m.bankhi, m.addrlo, m.addrhi, *m.memory, m.offset, m.size); - } else if(m.mmio) { - for(unsigned i = m.addrlo; i <= m.addrhi; i++) memory::mmio.map(i, *m.mmio); - } - } -} - -void Bus::map_system() { - map(MapMode::Linear, 0x00, 0x3f, 0x0000, 0x1fff, memory::wram, 0x000000, 0x002000); - map(MapMode::Linear, 0x80, 0xbf, 0x0000, 0x1fff, memory::wram, 0x000000, 0x002000); - map(MapMode::Linear, 0x7e, 0x7f, 0x0000, 0xffff, memory::wram); -} - -void Bus::power() { - foreach(n, memory::wram) n = config.cpu.wram_init_value; -} - -void Bus::reset() { -} - -} diff --git a/bsnes/memory/memory.hpp b/bsnes/memory/memory.hpp deleted file mode 100755 index 1492d7d8..00000000 --- a/bsnes/memory/memory.hpp +++ /dev/null @@ -1,111 +0,0 @@ -struct Memory { - virtual inline unsigned size() const; - virtual uint8 read(unsigned addr) = 0; - virtual void write(unsigned addr, uint8 data) = 0; -}; - -struct MMIO { - virtual uint8 mmio_read(unsigned addr) = 0; - virtual void mmio_write(unsigned addr, uint8 data) = 0; -}; - -struct UnmappedMemory : Memory { - unsigned size() const; - uint8 read(unsigned); - void write(unsigned, uint8); -}; - -struct UnmappedMMIO : MMIO { - uint8 mmio_read(unsigned); - void mmio_write(unsigned, uint8); -}; - -struct StaticRAM : Memory { - inline uint8* data(); - inline unsigned size() const; - - inline uint8 read(unsigned addr); - inline void write(unsigned addr, uint8 n); - inline uint8& operator[](unsigned addr); - inline const uint8& operator[](unsigned addr) const; - - inline StaticRAM(unsigned size); - inline ~StaticRAM(); - -private: - uint8 *data_; - unsigned size_; -}; - -struct MappedRAM : Memory { - inline void reset(); - inline void map(uint8*, unsigned); - inline void copy(const uint8*, unsigned); - - inline void write_protect(bool status); - inline uint8* data(); - inline unsigned size() const; - - inline uint8 read(unsigned addr); - inline void write(unsigned addr, uint8 n); - inline const uint8& operator[](unsigned addr) const; - inline MappedRAM(); - -private: - uint8 *data_; - unsigned size_; - bool write_protect_; -}; - -struct MMIOAccess : Memory { - void map(unsigned addr, MMIO &access); - uint8 read(unsigned addr); - void write(unsigned addr, uint8 data); - - MMIO *mmio[0x4000]; -}; - -struct Bus { - unsigned mirror(unsigned addr, unsigned size); - void map(unsigned addr, Memory &access, unsigned offset); - enum class MapMode : unsigned { Direct, Linear, Shadow }; - void map(MapMode mode, - uint8 bank_lo, uint8 bank_hi, - uint16 addr_lo, uint16 addr_hi, - Memory &access, unsigned offset = 0, unsigned size = 0); - - alwaysinline uint8 read(unsigned addr); - alwaysinline void write(unsigned addr, uint8 data); - - bool load_cart(); - void unload_cart(); - - void power(); - void reset(); - - struct Page { - Memory *access; - unsigned offset; - } page[65536]; - - void serialize(serializer&); - -private: - void map_reset(); - void map_xml(); - void map_system(); -}; - -namespace memory { - extern MMIOAccess mmio; //S-CPU, S-PPU - extern StaticRAM wram; //S-CPU - extern StaticRAM apuram; //S-SMP, S-DSP - extern StaticRAM vram; //S-PPU - extern StaticRAM oam; //S-PPU - extern StaticRAM cgram; //S-PPU - - extern UnmappedMemory memory_unmapped; - extern UnmappedMMIO mmio_unmapped; -}; - -extern Bus bus; diff --git a/bsnes/memory/serialization.cpp b/bsnes/memory/serialization.cpp deleted file mode 100755 index 334a380a..00000000 --- a/bsnes/memory/serialization.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifdef MEMORY_CPP - -void Bus::serialize(serializer &s) { - s.array(memory::wram.data(), memory::wram.size()); - s.array(memory::apuram.data(), memory::apuram.size()); - s.array(memory::vram.data(), memory::vram.size()); - s.array(memory::oam.data(), memory::oam.size()); - s.array(memory::cgram.data(), memory::cgram.size()); -} - -#endif diff --git a/bsnes/ppu/counter/counter-inline.hpp b/bsnes/ppu/counter/counter-inline.hpp deleted file mode 100755 index 2c21b6d1..00000000 --- a/bsnes/ppu/counter/counter-inline.hpp +++ /dev/null @@ -1,85 +0,0 @@ -//this should only be called by CPU::PPUcounter::tick(); -//keeps track of previous counter positions in history table -void PPUcounter::tick() { - status.hcounter += 2; //increment by smallest unit of time - if(status.hcounter >= 1360 && status.hcounter == lineclocks()) { - status.hcounter = 0; - vcounter_tick(); - } - - history.index = (history.index + 1) & 2047; - history.field [history.index] = status.field; - history.vcounter[history.index] = status.vcounter; - history.hcounter[history.index] = status.hcounter; -} - -//this should only be called by PPU::PPUcounter::tick(n); -//allows stepping by more than the smallest unit of time -void PPUcounter::tick(unsigned clocks) { - status.hcounter += clocks; - if(status.hcounter >= lineclocks()) { - status.hcounter -= lineclocks(); - vcounter_tick(); - } -} - -//internal -void PPUcounter::vcounter_tick() { - if(++status.vcounter == 128) status.interlace = ppu.interlace(); - - if((system.region() == System::Region::NTSC && status.interlace == false && status.vcounter == 262) - || (system.region() == System::Region::NTSC && status.interlace == true && status.vcounter == 263) - || (system.region() == System::Region::NTSC && status.interlace == true && status.vcounter == 262 && status.field == 1) - || (system.region() == System::Region::PAL && status.interlace == false && status.vcounter == 312) - || (system.region() == System::Region::PAL && status.interlace == true && status.vcounter == 313) - || (system.region() == System::Region::PAL && status.interlace == true && status.vcounter == 312 && status.field == 1) - ) { - status.vcounter = 0; - status.field = !status.field; - } - if(scanline) scanline(); -} - -bool PPUcounter::field () const { return status.field; } -uint16 PPUcounter::vcounter() const { return status.vcounter; } -uint16 PPUcounter::hcounter() const { return status.hcounter; } - -bool PPUcounter::field (unsigned offset) const { return history.field [(history.index - (offset >> 1)) & 2047]; } -uint16 PPUcounter::vcounter(unsigned offset) const { return history.vcounter[(history.index - (offset >> 1)) & 2047]; } -uint16 PPUcounter::hcounter(unsigned offset) const { return history.hcounter[(history.index - (offset >> 1)) & 2047]; } - -//one PPU dot = 4 CPU clocks -// -//PPU dots 323 and 327 are 6 CPU clocks long. -//this does not apply to NTSC non-interlace scanline 240 on odd fields. this is -//because the PPU skips one dot to alter the color burst phase of the video signal. -// -//dot 323 range = { 1292, 1294, 1296 } -//dot 327 range = { 1310, 1312, 1314 } - -uint16 PPUcounter::hdot() const { - if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) { - return (hcounter() >> 2); - } else { - return (hcounter() - ((hcounter() > 1292) << 1) - ((hcounter() > 1310) << 1)) >> 2; - } -} - -uint16 PPUcounter::lineclocks() const { - if(system.region() == System::Region::NTSC && status.interlace == false && vcounter() == 240 && field() == 1) return 1360; - return 1364; -} - -void PPUcounter::reset() { - status.interlace = false; - status.field = 0; - status.vcounter = 0; - status.hcounter = 0; - history.index = 0; - - for(unsigned i = 0; i < 2048; i++) { - history.field [i] = 0; - history.vcounter[i] = 0; - history.hcounter[i] = 0; - } -} diff --git a/bsnes/ppu/counter/counter.hpp b/bsnes/ppu/counter/counter.hpp deleted file mode 100755 index b8d7aa7e..00000000 --- a/bsnes/ppu/counter/counter.hpp +++ /dev/null @@ -1,49 +0,0 @@ -//PPUcounter emulates the H/V latch counters of the S-PPU2. -// -//real hardware has the S-CPU maintain its own copy of these counters that are -//updated based on the state of the S-PPU Vblank and Hblank pins. emulating this -//would require full lock-step synchronization for every clock tick. -//to bypass this and allow the two to run out-of-order, both the CPU and PPU -//classes inherit PPUcounter and keep their own counters. -//the timers are kept in sync, as the only differences occur on V=240 and V=261, -//based on interlace. thus, we need only synchronize and fetch interlace at any -//point before this in the frame, which is handled internally by this class at -//V=128. - -class PPUcounter { -public: - alwaysinline void tick(); - alwaysinline void tick(unsigned clocks); - - alwaysinline bool field () const; - alwaysinline uint16 vcounter() const; - alwaysinline uint16 hcounter() const; - inline uint16 hdot() const; - inline uint16 lineclocks() const; - - alwaysinline bool field (unsigned offset) const; - alwaysinline uint16 vcounter(unsigned offset) const; - alwaysinline uint16 hcounter(unsigned offset) const; - - inline void reset(); - function scanline; - void serialize(serializer&); - -private: - inline void vcounter_tick(); - - struct { - bool interlace; - bool field; - uint16 vcounter; - uint16 hcounter; - } status; - - struct { - bool field[2048]; - uint16 vcounter[2048]; - uint16 hcounter[2048]; - - int32 index; - } history; -}; diff --git a/bsnes/scheduler/scheduler.cpp b/bsnes/scheduler/scheduler.cpp deleted file mode 100755 index e7549501..00000000 --- a/bsnes/scheduler/scheduler.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef SYSTEM_CPP - -Scheduler scheduler; - -void Scheduler::enter() { - host_thread = co_active(); - co_switch(thread); -} - -void Scheduler::exit(ExitReason reason) { - exit_reason = reason; - thread = co_active(); - co_switch(host_thread); -} - -void Scheduler::init() { - host_thread = co_active(); - thread = cpu.thread; - sync = SynchronizeMode::None; -} - -Scheduler::Scheduler() { - host_thread = 0; - thread = 0; - exit_reason = ExitReason::UnknownEvent; -} - -#endif diff --git a/bsnes/scheduler/scheduler.hpp b/bsnes/scheduler/scheduler.hpp deleted file mode 100755 index 335d8e9c..00000000 --- a/bsnes/scheduler/scheduler.hpp +++ /dev/null @@ -1,16 +0,0 @@ -struct Scheduler : property { - enum class SynchronizeMode : unsigned { None, CPU, All } sync; - enum class ExitReason : unsigned { UnknownEvent, FrameEvent, SynchronizeEvent, DebuggerEvent }; - readonly exit_reason; - - cothread_t host_thread; //program thread (used to exit emulation) - cothread_t thread; //active emulation thread (used to enter emulation) - - void enter(); - void exit(ExitReason); - - void init(); - Scheduler(); -}; - -extern Scheduler scheduler; diff --git a/bsnes/smp/snes_spc/Snes_Spc.cpp b/bsnes/smp/snes_spc/Snes_Spc.cpp deleted file mode 100755 index 50c8d1a4..00000000 --- a/bsnes/smp/snes_spc/Snes_Spc.cpp +++ /dev/null @@ -1,240 +0,0 @@ -// SPC emulation support: init, sample buffering, reset, SPC loading - -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Snes_Spc.h" - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -// Extra silence added at beginning, to handle cases where fast DSP falls -// behind and thus doesn't generate all the samples needed. -int const extra_samples = 2; - -int const stereo = 2; // for clarity - -char const Snes_Spc::signature [signature_size + 1] = - "SNES-SPC700 Sound File Data v0.30\x1A\x1A"; - -blargg_err_t Snes_Spc::init() -{ - RETURN_ERR( Spc_Core::init() ); - RETURN_ERR( buf.resize( sample_rate / 30 * stereo ) ); - reset_samples(); - - return blargg_ok; -} - -void Snes_Spc::reset_samples() -{ - user_out = NULL; - user_pos = 0; - user_size = 0; - - clocks_avail = 0; - memset( buf.begin(), 0, extra_samples * sizeof buf [0] ); - dsp().set_output( buf.begin() + extra_samples, buf.end() ); -} - -void Snes_Spc::reset() -{ - reset_samples(); - Spc_Core::reset(); -} - -void Snes_Spc::soft_reset() -{ - reset_samples(); - Spc_Core::soft_reset(); -} - -inline int Snes_Spc::raw_samples_avail() const -{ - return dsp().output_ptr() - buf.begin(); -} - -int Snes_Spc::samples_avail() const -{ - return (unsigned) clocks_avail / clocks_per_sample * stereo; -} - -int Snes_Spc::remove_samples( int count ) -{ - count = min( count, samples_avail() ); - int remain = raw_samples_avail() - count; - if ( remain < 0 ) - { - check( false ); - count += remain; - remain = 0; - } - - clocks_avail -= clocks_per_sample / stereo * count; - memmove( buf.begin(), buf.begin() + count, remain * sizeof buf [0] ); - dsp().set_output( buf.begin() + remain, buf.end() ); - - return count; -} - -int Snes_Spc::read_samples( sample_t out [], int count ) -{ - count = min( count, samples_avail() ); - - memcpy( out, buf.begin(), count * sizeof buf [0] ); - - remove_samples( count ); - - return count; -} - -// Keep track of number of samples we should have generated so far, since -// fast DSP might be slightly ahead or behind. -void Snes_Spc::end_frame( time_t end ) -{ - clocks_avail += end; - Spc_Core::end_frame( end ); - - int excess = samples_avail() - raw_samples_avail(); - - // Worst-case, DSP can be 6+36 clocks ahead, and clocks_avail%32==31, - // generating an extra 4 samples. - check( excess >= -4 - extra_samples ); - - if ( excess > 0 ) - { - // DSP should never get behind what's needed, given that it - // starts with extra_samples in buffer. - clocks_avail -= clocks_per_sample / stereo * excess; - check( false ); - } -} - -#if BLARGG_LEGACY - -void Snes_Spc::set_output( sample_t* out, int out_size ) -{ - user_out = out; - user_pos = 0; - user_size = out_size; -} - -int Snes_Spc::sample_count() const -{ - int more = read_samples( user_out + user_pos, user_size - user_pos ); - CONST_CAST(int&,user_pos) += more; - return user_pos; -} - -#endif - -blargg_err_t Snes_Spc::load_spc( void const* data, long size ) -{ - spc_file_t const* const spc = (spc_file_t const*) data; - - // be sure compiler didn't insert any padding into spc_file_t - assert( sizeof (spc_file_t) == spc_min_file_size + 0x80 ); - - // Check signature and file size - if ( size < signature_size || memcmp( spc, signature, 27 ) ) - return "Not an SPC file"; - - if ( size < spc_min_file_size ) - return "Corrupt SPC file"; - - reset(); - - // CPU registers - cpu().pc = spc->pch * 0x100 + spc->pcl; - cpu().a = spc->a; - cpu().x = spc->x; - cpu().y = spc->y; - cpu().psw = spc->psw; - cpu().sp = spc->sp; - - // RAM and registers - memcpy( ram(), spc->ram, 0x10000 ); - ram_loaded(); - static byte const new_ports [port_count] = { }; - load_regs( spc->ram + 0xF0, new_ports ); - - // DSP registers - dsp().load( spc->dsp ); - - return blargg_ok; -} - -void Snes_Spc::clear_echo() -{ - if ( !(dsp().read( Spc_Dsp::r_flg ) & 0x20) ) - { - int addr = 0x100 * dsp().read( Spc_Dsp::r_esa ); - int end = addr + 0x800 * (dsp().read( Spc_Dsp::r_edl ) & 0x0F); - - addr = max( addr, 0x200 ); - end = min( end, 0x10000 ); // if it wraps around, stop at end of RAM - - // 0xFF = STOP, so if this overwrites any code, SPC won't play, - // rather than behave strangely - memset( &ram() [addr], 0xFF, end - addr ); - } -} - - -//// Sample output - -blargg_err_t Snes_Spc::play( int count, sample_t out [] ) -{ - assert( count % 2 == 0 ); // must be even - - // Refill and empty buffer until satisfied - while ( count > 0 ) - { - if ( samples_avail() == 0 ) - end_frame( clocks_per_sample / stereo * (buf.size() - 16) ); - - int n; - if ( out ) - { - n = read_samples( out, count ); - out += n; - } - else - { - n = min( samples_avail(), count ); - remove_samples( n ); - } - - count -= n; - } - - return error(); -} - -blargg_err_t Snes_Spc::skip( int count ) -{ - assert( count % 2 == 0 ); - - count -= remove_samples( count ); - - int const final_skip = sample_rate * stereo; - - if ( count >= 2 * final_skip ) - { - end_frame_skip( clocks_per_sample / stereo * (count - final_skip) ); - clear_echo(); - - count = final_skip; - } - - return play( count, NULL ); -} diff --git a/bsnes/smp/snes_spc/Snes_Spc.h b/bsnes/smp/snes_spc/Snes_Spc.h deleted file mode 100755 index fb19c417..00000000 --- a/bsnes/smp/snes_spc/Snes_Spc.h +++ /dev/null @@ -1,141 +0,0 @@ -// SNES SPC-700 APU emulator/SPC music file player - -// snes_spc 0.9.5 -#ifndef BLARGG_SNES_SPC_H -#define BLARGG_SNES_SPC_H - -#include "spc.h" -#include "Spc_Core.h" -#include "blargg_endian.h" - -BLARGG_NAMESPACE_BEGIN - -struct spc_t : public Spc_Core { -public: - // Must be called once before using. OK to call more than once. - blargg_err_t init(); - - // Sample pairs generated per second - enum { sample_rate = 32000 }; - - // Number of samples in internal buffer. Increased by 2 (stereo) every 32 - // clocks of emulation. - int samples_avail() const; - - // Reads at most count samples from internal buffer and returns number - // actually read, less if samples_avail() < count - typedef short sample_t; - int read_samples( sample_t out [], int count ); - - // Removes samples without reading. Returns number actually removed. - int remove_samples( int count ); - -// Sound control - - // Mutes voices corresponding to non-zero bits in mask. - // Reduces emulation accuracy. - enum { voice_count = 8 }; - void mute_voices( int mask ); - - // If true, prevents channels and global volumes from being phase-negated. - // Only supported by fast DSP. - void disable_surround( bool disable = true ); - -// SPC music files - - // Loads SPC data into emulator - enum { spc_min_file_size = 0x10180 }; - enum { spc_file_size = 0x10200 }; - blargg_err_t load_spc( void const* in, long size ); - - // Clears echo region if appropriate. Useful after loading an SPC, as many have - // garbage in echo. - void clear_echo(); - - // Plays for count samples and write samples to out. Discards samples if out - // is NULL. Count must be a multiple of 2 since output is stereo. - blargg_err_t play( int count, sample_t out [] ); - - // Skips count samples. When using fast DSP, this is several times faster than - // simply calling play() and discarding samples. - blargg_err_t skip( int count ); - -// only available when using accurate DSP -#if !SPC_NO_COPY_STATE_FUNCS - - // Writes minimal header to spc_out - static void init_header( void* spc_out ); - - // Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out. - // Does not set up SPC header; use init_header() for that. - void save_spc( void* spc_out ); - - // Returns true if new key-on events occurred since last check. Useful for - // trimming silence while saving an SPC. - bool check_kon(); -#endif - - enum { signature_size = 35 }; - -public: - // "Overrides" - void reset(); - void soft_reset(); - void end_frame( time_t ); - - // Deprecated - BLARGG_DEPRECATED( void set_output( sample_t* out, int out_size ); ) - BLARGG_DEPRECATED( int sample_count() const; ) - -private: - struct spc_file_t - { - char signature [signature_size]; - byte has_id666; - byte version; - byte pcl, pch; - byte a; - byte x; - byte y; - byte psw; - byte sp; - char text [212]; - byte ram [0x10000]; - byte dsp [128]; - byte unused [0x40]; - byte ipl_rom [0x40]; - }; - - static char const signature [signature_size + 1]; - - int clocks_avail; - blargg_vector buf; - - sample_t* user_out; - BLARGG_MUTABLE int user_pos; - int user_size; - - int raw_samples_avail() const; - void reset_samples(); -}; - -inline void Snes_Spc::mute_voices( int mask ) -{ - dsp().mute_voices( mask ); -} - -inline void Snes_Spc::disable_surround( bool disable ) -{ - dsp().disable_surround( disable ); -} - -#if !SPC_NO_COPY_STATE_FUNCS -inline bool Snes_Spc::check_kon() -{ - return dsp().check_kon(); -} -#endif - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/Spc_Core.cpp b/bsnes/smp/snes_spc/Spc_Core.cpp deleted file mode 100755 index 268203b9..00000000 --- a/bsnes/smp/snes_spc/Spc_Core.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Core.h" - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void Spc_Core::set_tempo( int t ) -{ - #if !SPC_DISABLE_TEMPO - tempo = t; - - if ( !t ) - t = 1; - - int const timer2_rate = 1 << timer2_shift; - int rate = (timer2_rate * tempo_unit + (t >> 1)) / t; - if ( rate < timer2_rate / 4 ) - rate = timer2_rate / 4; // max 4x tempo - - prescaler_base = rate; - #endif -} - -blargg_err_t Spc_Core::init() -{ - BLARGG_CLEAR( ®s ); - BLARGG_CLEAR( ®s_in ); - - // Most SPC music doesn't need ROM, and almost all the rest only rely - // on these two bytes - BLARGG_CLEAR( &rom_ ); - rom_ [0x3E] = 0xFF; - rom_ [0x3F] = 0xC0; - - set_tempo( tempo_unit ); - dsp_.init( ram() ); - reset(); - - return blargg_ok; -} - -void Spc_Core::init_rom( byte const in [rom_size] ) -{ - memcpy( rom_, in, sizeof rom_ ); -} - -void Spc_Core::enable_rom( bool enable ) -{ - if ( rom_enabled != enable ) - { - rom_enabled = enable; - if ( enable ) - memcpy( hi_ram, &ram() [rom_addr], sizeof hi_ram ); - - memcpy( &ram() [rom_addr], (enable ? rom_ : hi_ram), rom_size ); - // TODO: ROM can still get overwritten when DSP writes to echo buffer - } -} - -void Spc_Core::ram_loaded() -{ - // ROM isn't swapped in anymore, since its area was overwritten with - // contents of RAM there - rom_enabled = false; - - // Put STOP instruction around memory to catch PC underflow/overflow - memset( padded_ram, padding_fill, ram_padding ); - memset( padded_ram + ram_padding + ram_size, padding_fill, ram_padding ); -} - -void Spc_Core::load_regs( byte const new_regs [reg_count], byte const ports [port_count] ) -{ - memcpy( regs, new_regs, reg_count ); - memcpy( regs_in, regs, reg_count ); - - // These always read back as 0 or are handled specially - // Commented registers are already copied from regs. - regs_in [r_test ] = 0; - regs_in [r_control ] = 0; - // r_dspaddr - regs_in [r_dspdata ] = 0xFF; // in case attempt is made to execute value - // r_cpuio0 - // r_cpuio1 - // r_cpuio2 - // r_cpuio3 - // 8 - // 9 - regs_in [r_t0target] = 0; - regs_in [r_t1target] = 0; - regs_in [r_t2target] = 0; - regs_in [r_t0out ] &= 0x0F; - regs_in [r_t1out ] &= 0x0F; - regs_in [r_t2out ] &= 0x0F; - - // RAM should always hold copy of regs_in - memcpy( ram() + regs_addr, regs_in, reg_count ); - - enable_rom( regs [r_control] & 0x80 ); - - for ( int i = 0; i < port_count; i++ ) - regs [r_cpuio0 + i] = ports [i]; -} - -void Spc_Core::reset_common( int timer_counter_init ) -{ - memset( &cpu_regs, 0, sizeof cpu_regs ); - cpu_regs.pc = rom_addr; - - cpu_error = NULL; - echo_accessed = 0; - spc_time = 0; - dsp_time = 0; - skipped_kon = 0; - skipped_koff = 0; - - #if SPC_LESS_ACCURATE - dsp_time = clocks_per_sample + 1; - #endif - - int i; - for ( i = 0; i < timer_count; i++ ) - { - timers [i].time = 1; - timers [i].divider = 0; - } - - byte new_regs [reg_count] = { }; - - new_regs [r_test ] = 0x0A; - new_regs [r_control] = 0x80; // ROM enabled - - for ( i = 0; i < timer_count; i++ ) - new_regs [r_t0out + i] = timer_counter_init; - - static byte const new_ports [port_count] = { }; - - load_regs( new_regs, new_ports ); -} - -void Spc_Core::soft_reset() -{ - reset_common( 0 ); - - dsp_.soft_reset(); -} - -void Spc_Core::reset() -{ - memset( ram(), 0xFF, 0x10000 ); - ram_loaded(); - - reset_common( 0x0F ); - - dsp_.reset(); -} - -const char* Spc_Core::error() -{ - const char* e = cpu_error; - cpu_error = NULL; - return e; -} - -bool Spc_Core::check_echo_access( int addr ) -{ - if ( !(dsp_.read( dsp_.r_flg ) & 0x20) ) - { - int start = 0x100 * dsp_.read( dsp_.r_esa ); - int size = 0x800 * (dsp_.read( dsp_.r_edl ) & 0x0F); - int end = start + (size ? size : 4); - if ( start <= addr && addr < end ) - { - if ( !echo_accessed ) - { - echo_accessed = true; - return true; - } - } - } - return false; -} - -// (n ? n : 256) & 0xFF -inline int if_0_then_256( int n ) -{ - return byte (n - 1) + 1; -} - -void Spc_Core::run_timer_( rel_time_t time, int index ) -{ - Timer& t = timers [index]; - check( time >= t.time ); - - int elapsed; // number of ticks, guaranteed at least 1 - int const timer01_shift = 3; - - #if SPC_DISABLE_TEMPO - { - int shift = timer2_shift; - if ( index < 2 ) - shift += timer01_shift; - - elapsed = ((time - t.time) >> shift) + 1; - t.time += elapsed << shift; - } - #else - { - int prescaler = prescaler_base; - if ( index < 2 ) - prescaler <<= timer01_shift; - - elapsed = (time - t.time) / prescaler + 1; - t.time += elapsed * prescaler; - } - #endif - - if ( regs [r_control] >> index & 1 ) - { - int period = if_0_then_256( regs [r_t0target + index] ); - - // Ticks until divider will output tick. If divider currently matches - // period, it will be 256 ticks until output tick, not 0. - int remain = if_0_then_256( period - t.divider ); - - // value divider will take, assuming no tick - int divider = t.divider + elapsed; - - // time relative to when tick will occur - int over = elapsed - remain; - if ( over >= 0 ) - { - // ticks elapsed in second stage - int elapsed2 = over / period; - - regs_in [r_t0out + index] = - (regs_in [r_t0out + index] + 1 + elapsed2) & 0x0F; - - // remaining count on divider - divider = over - elapsed2 * period; - } - - // Must mask for cases when divider has gone past target - t.divider = divider & 0xFF; - } -} diff --git a/bsnes/smp/snes_spc/Spc_Core.h b/bsnes/smp/snes_spc/Spc_Core.h deleted file mode 100755 index c3b5b27e..00000000 --- a/bsnes/smp/snes_spc/Spc_Core.h +++ /dev/null @@ -1,239 +0,0 @@ -#ifndef BLARGG_SPC_CORE_H -#define BLARGG_SPC_CORE_H - -#include "Spc_Dsp.h" -#include "blargg_endian.h" - -BLARGG_NAMESPACE_BEGIN - -class Spc_Core { -public: - typedef BOOST::uint8_t byte; - - // Must be called once before using. OK to call more than once. - blargg_err_t init(); - - // Sets IPL ROM data. Default IPL ROM is zero-filled. Most SPC music files - // don't need ROM, but a full emulator MUST provide this. - enum { rom_size = 0x40 }; - void init_rom( byte const rom [rom_size] ); - -// Reset - - // Use functions in order listed here - - // Resets to power-on state - void reset(); - - // Emulates pressing reset on SNES - void soft_reset(); - - // Pointer to 64K RAM - byte* ram(); - - // S-SMP CPU registers - struct regs_t - { - int pc; - int a; - int x; - int y; - int psw; - int sp; - }; - regs_t& cpu() { return cpu_regs; } - - // S-DSP - Spc_Dsp& dsp() { return dsp_; } - const Spc_Dsp& dsp() const { return dsp_; } - -// Emulation - - // 1024000 SPC clocks per second, sample pair every 32 clocks - typedef int time_t; - enum { clock_rate = 1024000 }; - enum { clocks_per_sample = 32 }; - - // Emulates port read/write at specified time - enum { port_count = 4 }; - int read_port ( time_t, int port ); - void write_port( time_t, int port, int data ); - - // Runs SPC to end_time and starts a new time frame at 0 - void end_frame( time_t end_time ); - -// Sound control - - // Sets tempo, where tempo_unit = normal, tempo_unit/2 = half speed, - // tempo_unit*2 = double speed, etc. - enum { tempo_unit = 0x100 }; - void set_tempo( int ); - -// State save/load (only available with accurate DSP) - -#if !SPC_NO_COPY_STATE_FUNCS - // Saves/loads state - enum { state_size = 67 * 1024 }; // maximum space needed when saving - typedef Spc_Dsp::copy_func_t copy_func_t; - void copy_state( unsigned char** io, copy_func_t ); -#endif - -protected: - - // Pointer to string describing CPU emulation error since last call, or NULL - // if none. Clears error after returning. - const char* error(); - - enum { regs_addr = 0xF0 }; - enum { reg_count = 0x10 }; - - // Saves registers in unified 16-byte format, and output ports - // separately - void save_regs( byte out [reg_count], byte out_ports [port_count] ); - - // Loads registers from unified 16-byte format. Most registers are - // last values S-SMP wrote. CPUIOx are last values S-CPU wrote to - // APUIOx. TxOUT are values to load into timer counters. DSPDATA is - // ignored. CONTROL is restored without disturbing CPUIOx and TxOUT. - void load_regs( byte const in [reg_count], byte const ports [port_count] ); - - void save_ram( byte out [65536] ); - - // Call after loading new data into entire RAM - void ram_loaded(); - - byte const* rom() const { return rom_; } - - void end_frame_skip( time_t ); - -public: - BLARGG_DISABLE_NOTHROW - - enum { skipping_time = 127 }; -private: - // Time relative to m_spc_time. Speeds up code a bit by eliminating need to - // constantly add m_spc_time to time from CPU. CPU uses time that ends at - // 0 to eliminate reloading end time every instruction. It pays off. - typedef int rel_time_t; - - // Main goal for emulator state is to have as little redundancy as possible. - // That means the last values written to each SMP register, and any internal - // state needed (e.g. timer prescaler and divider, but not counters, which - // are stored in regs_in). - - // Registers - enum { - r_test = 0x0, r_control = 0x1, - r_dspaddr = 0x2, r_dspdata = 0x3, - r_cpuio0 = 0x4, r_cpuio1 = 0x5, - r_cpuio2 = 0x6, r_cpuio3 = 0x7, - r_f8 = 0x8, r_f9 = 0x9, - r_t0target = 0xA, r_t1target = 0xB, r_t2target = 0xC, - r_t0out = 0xD, r_t1out = 0xE, r_t2out = 0xF - }; - byte regs [reg_count]; // last values SMP wrote - byte regs_in [reg_count]; // values SMP should read, except timers - - const char* cpu_error; - bool echo_accessed; - time_t spc_time; - rel_time_t dsp_time; - int tempo; - int skipped_kon; - int skipped_koff; - regs_t cpu_regs; - - // IPL ROM - enum { rom_addr = 0xFFC0 }; - bool rom_enabled; - byte rom_ [rom_size]; - byte hi_ram [rom_size]; - void enable_rom( bool enable ); - - // Timers - enum { timer2_shift = 4 }; - enum { timer_count = 3 }; - struct Timer - { - rel_time_t time; // time of next stage 0 tick - int divider; - }; - Timer timers [timer_count]; - int prescaler_base; - void adjust_timers( int offset ); - void run_timer_ ( rel_time_t, int index ); - void run_timer ( rel_time_t, int index ); - void enable_timers( rel_time_t, int mask ); - int read_timer ( rel_time_t, int index ); - - Spc_Dsp dsp_; - - // 64K RAM with padding for CPU emulator to hit if it goes outside - enum { padding_fill = 0xFF }; - enum { ram_padding = 0x100 }; - enum { ram_size = 0x10000 }; - byte padded_ram [ram_padding + ram_size + ram_padding]; - - void cpu_write_smp_reg_( rel_time_t, int data, int reg ); - void cpu_write_smp_reg ( rel_time_t, int data, int reg ); - void cpu_write_high ( rel_time_t, int data, int offset ); - void cpu_write ( rel_time_t, int data, int addr ); - - void dsp_write ( rel_time_t, int data ); - int dsp_read ( rel_time_t ); - - int cpu_read_smp_reg ( rel_time_t, int reg ); - int cpu_read ( rel_time_t, int addr ); - - unsigned cpu_mem_bit ( rel_time_t, byte const* pc ); - - void write_apuio( int port, int data ); - void reset_common( int timer_counter_init ); - bool check_echo_access ( int addr ); - void run_until_( time_t end_time ); -}; - -inline Spc_Core::byte* Spc_Core::ram() -{ - return &padded_ram [ram_padding]; -} - -inline int Spc_Core::read_port( time_t t, int port ) -{ - assert( (unsigned) port < port_count ); - run_until_( t ); - return regs [r_cpuio0 + port]; -} - -inline void Spc_Core::write_apuio( int port, int data ) -{ - regs_in [ r_cpuio0 + port] = data; - ram() [regs_addr + r_cpuio0 + port] = data; -} - -inline void Spc_Core::write_port( time_t t, int port, int data ) -{ - assert( (unsigned) port < port_count ); - run_until_( t ); - write_apuio( port, data ); -} - -inline void Spc_Core::end_frame_skip( rel_time_t end ) -{ - assert( end % clocks_per_sample == 0 ); - - skipped_kon = 0; - skipped_koff = 0; - - // Bump DSP by count, so it won't have to run at all - dsp_time += end; - end_frame( end ); - - // Write most recent KOFF/KONs - dsp_.write( Spc_Dsp::r_koff, skipped_koff & ~skipped_kon ); - dsp_.write( Spc_Dsp::r_kon , skipped_kon ); -} - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/Spc_Core_impl.cpp b/bsnes/smp/snes_spc/Spc_Core_impl.cpp deleted file mode 100755 index 05dd4a04..00000000 --- a/bsnes/smp/snes_spc/Spc_Core_impl.cpp +++ /dev/null @@ -1,455 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Core.h" - -//#include "spc_cpu_log.h" - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -// Note: SPC_MORE_ACCURACY exists mainly so I can run my validation tests, which -// do crazy echo buffer accesses. -#ifndef SPC_MORE_ACCURACY - #define SPC_MORE_ACCURACY 0 -#endif - - -//// Timers - -inline void Spc_Core::adjust_timers( int offset ) -{ - timers [0].time += offset; - timers [1].time += offset; - timers [2].time += offset; -} - -inline void Spc_Core::run_timer( rel_time_t time, int i ) -{ - if ( time >= timers [i].time ) - run_timer_( time, i ); -} - -inline void Spc_Core::enable_timers( rel_time_t time, int new_control ) -{ - for ( int i = 0; i < timer_count; i++ ) - { - int const bit = 1 << i; - - int changed = new_control ^ regs [r_control]; - if ( changed & bit ) - { - run_timer( time, i ); - - if ( new_control & bit ) - { - // Timer just enabled - regs_in [r_t0out + i] = 0; - timers [i].divider = 0; - } - } - } -} - -inline int Spc_Core::read_timer( rel_time_t time, int i ) -{ - run_timer( time, i ); - - int result = regs_in [r_t0out + i]; - regs_in [r_t0out + i] = 0; - return result; -} - - - -//// DSP - -#if SPC_LESS_ACCURATE - int const max_reg_time = 29; - - /* Fast DSP only runs every 32nd clock. By adjusting the end time based - on which register is being accessed, in most cases the register access - is emulated at the precise time. */ - static signed char const reg_times [256] = - { - -1, 0,-11,-10,-15,-11, -2, -2, 4, 3, 14, 14, 26, 26, 14, 22, - 2, 3, 0, 1,-12, 0, 1, 1, 7, 6, 14, 14, 27, 14, 14, 23, - 5, 6, 3, 4, -1, 3, 4, 4, 10, 9, 14, 14, 26, -5, 14, 23, - 8, 9, 6, 7, 2, 6, 7, 7, 13, 12, 14, 14, 27, -4, 14, 24, - 11, 12, 9, 10, 5, 9, 10, 10, 16, 15, 14, 14, -2, -4, 14, 24, - 14, 15, 12, 13, 8, 12, 13, 13, 19, 18, 14, 14, -2,-36, 14, 24, - 17, 18, 15, 16, 11, 15, 16, 16, 22, 21, 14, 14, 28, -3, 14, 25, - 20, 21, 18, 19, 14, 18, 19, 19, 25, 24, 14, 14, 14, 29, 14, 25, - - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - }; - - // not surrounded in block so else can be added - #define RUN_DSP( time, offset ) \ - int count = (time) - (offset) - dsp_time;\ - if ( count >= 0 )\ - {\ - int clock_count = (count & ~(clocks_per_sample - 1)) + clocks_per_sample;\ - dsp_time += clock_count;\ - dsp_.run( clock_count );\ - } -#else - #define RUN_DSP( time, ignored ) \ - {\ - int count = (time) - dsp_time;\ - if ( !SPC_MORE_ACCURACY || count )\ - {\ - assert( count > 0 );\ - dsp_time = (time);\ - dsp_.run( count );\ - }\ - } -#endif - -int Spc_Core::dsp_read( rel_time_t time ) -{ - RUN_DSP( time, reg_times [regs [r_dspaddr] & 0x7F] ); - - return dsp_.read( regs [r_dspaddr] & 0x7F ); -} - -inline void Spc_Core::dsp_write( rel_time_t time, int data ) -{ - RUN_DSP( time, reg_times [regs [r_dspaddr]] ) - #if SPC_LESS_ACCURATE - else if ( dsp_time == skipping_time ) - { - int r = regs [r_dspaddr]; - if ( r == Spc_Dsp::r_kon ) - skipped_kon |= data & ~dsp_.read( Spc_Dsp::r_koff ); - - if ( r == Spc_Dsp::r_koff ) - { - skipped_koff |= data; - skipped_kon &= ~data; - } - } - #endif - - if ( regs [r_dspaddr] <= 0x7F ) - dsp_.write( regs [r_dspaddr], data ); - else if ( !SPC_MORE_ACCURACY ) - dprintf( "SPC wrote to DSP register > $7F\n" ); -} - - -//// Memory access - -#if SPC_MORE_ACCURACY - #define MEM_ACCESS( time, addr ) \ - if ( time >= dsp_time )\ - { RUN_DSP( time, max_reg_time ); }\ - -#elif !defined (NDEBUG) - // Debug-only check for read/write within echo buffer, since this might result in - // inaccurate emulation due to the DSP not being caught up to the present. - #define MEM_ACCESS( time, addr ) check( !check_echo_access( (BOOST::uint16_t) addr ) ); - -#else - #define MEM_ACCESS( time, addr ) - -#endif - - -// Read/write handlers are divided into multiple functions to keep rarely-used -// functionality separate so often-used functionality can be optimized better -// by compiler. - -// If write isn't preceded by read, data has this added to it -int const no_read_before_write = 0x2000; - -void Spc_Core::cpu_write_smp_reg_( rel_time_t time, int data, int reg ) -{ - // Undo write to RAM, since most writes shouldn't affect value read back - ram() [regs_addr + reg] = regs_in [reg]; - - switch ( reg ) - { - case r_test: - if ( (byte) data != 0x0A ) - dprintf( "SPC wrote to TEST register\n" ); - break; - - case r_control: - if ( data & 0x10 ) - { - write_apuio( 0, 0 ); - write_apuio( 1, 0 ); - } - - if ( data & 0x20 ) - { - write_apuio( 2, 0 ); - write_apuio( 3, 0 ); - } - - enable_timers( time, data ); - - enable_rom( data & 0x80 ); - break; - - // Registers that act like RAM - case r_dspaddr: - case 0x8: - case 0x9: - ram() [regs_addr + reg] = data; - regs_in [ reg] = data; - break; - - case r_t0target: - case r_t1target: - case r_t2target: - run_timer( time, reg - r_t0target ); - break; - - case r_t0out: - case r_t1out: - case r_t2out: - if ( !SPC_MORE_ACCURACY ) - dprintf( "SPC wrote to counter %d\n", (int) reg - r_t0out ); - - if ( data < no_read_before_write / 2 ) - { - // This was a write which also reads one clock before. That read - // causes the counter to be cleared. - read_timer( time - 1, reg - r_t0out ); - } - break; - } - - regs [reg] = data; -} - -void Spc_Core::cpu_write_high( rel_time_t time, int data, int i ) -{ - // i = addr - rom_addr - - // $FFC0-$FFFF - if ( i < rom_size ) - { - hi_ram [i] = (byte) data; - if ( rom_enabled ) - ram() [i + rom_addr] = rom_ [i]; // restore overwritten ROM - } - // Wrapped around to beginning of RAM - else - { - assert( ram() [i + rom_addr] == (byte) data ); - ram() [i + rom_addr] = padding_fill; // restore overwritten padding - cpu_write( time, data, i + rom_addr - 0x10000 ); - } -} - -inline void Spc_Core::cpu_write_smp_reg( rel_time_t time, int data, int reg ) -{ - if ( reg == r_dspaddr ) // 64% - regs [r_dspaddr] = data; - - else if ( reg == r_dspdata ) // 35% - { - ram() [regs_addr + r_dspdata] = 0xFF; // needed for copy_state test to pass - dsp_write( time, data ); - } - - else // 1% - cpu_write_smp_reg_( time, data, reg ); -} - -void Spc_Core::cpu_write( rel_time_t time, int data, int addr ) -{ - // CPU can generate addresses beyond $FFFF, which need to wrap around - - MEM_ACCESS( time, addr ) - - // RAM - ram() [addr] = (byte) data; - int reg = addr - regs_addr; - if ( reg >= 0 ) // 64% - { - // $F0+ - - if ( reg < reg_count ) // 87% - { - // $F0-$FF - cpu_write_smp_reg( time, data, reg ); - return; - } - - reg -= rom_addr - regs_addr; - if ( reg >= 0 ) // 1% - { - // $FFC0+ - cpu_write_high( time, data, reg ); - } - } -} - - -//// CPU read - -inline int Spc_Core::cpu_read_smp_reg( rel_time_t time, int reg ) -{ - int result = regs_in [reg]; - - reg -= r_dspaddr; - if ( (unsigned) reg <= 1 ) // 4% - { - // dspaddr or dspdata - result = regs [r_dspaddr]; - - if ( (unsigned) reg == 1 ) // dspdata - result = dsp_read( time ); - } - return result; -} - -int Spc_Core::cpu_read( rel_time_t time, int addr ) -{ - // CPU can generate addresses beyond $FFFF, which need to wrap around - - MEM_ACCESS( time, addr ) - - // RAM - int result = ram() [addr]; - int reg = addr - regs_addr; - if ( reg >= 0 ) // 40% - { - // $F0+ - - reg -= 0x10; - if ( (unsigned) reg >= 0xFF00 ) // 21% - { - // $F0-$FF or $10000+ - - reg += 0x10 - r_t0out; - - // Timers - if ( (unsigned) reg < timer_count ) // 90% - { - // $FD-$FF - result = read_timer( time, reg ); - } - // Other registers - else if ( reg < 0 ) // 10% - { - // $F0-$FC - result = cpu_read_smp_reg( time, reg + r_t0out ); - } - else // 1% - { - // $10000+ - assert( reg + (r_t0out + regs_addr - 0x10000) < 0x100 ); - result = cpu_read( time, reg + (r_t0out + regs_addr - 0x10000) ); - } - } - } - - return result; -} - -#define READ( delay, addr ) cpu_read ( TIME( delay ), addr ) -#define WRITE( delay, addr, data ) cpu_write( TIME( delay ), data, addr ) - -#if SPC_MORE_ACCURACY - #define READ_TIMER( delay, addr, out )\ - { out = READ( delay, addr ); } - - #define WRITE_DP_FAST( offset, data ) \ - WRITE_DP( 0, offset, data ) -#else - // timers are by far the most common thing read from dp - #define READ_TIMER( delay, addr_, out )\ - {\ - rel_time_t time = TIME( delay );\ - int dp_addr = addr_;\ - int ti = dp_addr - (r_t0out + regs_addr);\ - if ( (unsigned) ti < timer_count )\ - {\ - out = read_timer( time, ti );\ - }\ - else\ - {\ - out = ram [dp_addr];\ - int i = dp_addr - regs_addr;\ - if ( (unsigned) i < 0x10 )\ - out = cpu_read_smp_reg( time, i );\ - }\ - } - - #define WRITE_DP_FAST( offset, data ) \ - {\ - int i = dp + offset;\ - ram [i] = (byte) data;\ - i -= regs_addr;\ - if ( (unsigned) i < 0x10 )\ - cpu_write_smp_reg( TIME( 0 ), data, i );\ - } -#endif - - -//// Run - -void Spc_Core::end_frame( time_t end_time ) -{ - // Catch CPU up to as close to end as possible. If final instruction - // would exceed end, does NOT execute it and leaves spc_time < end. - if ( end_time > spc_time ) - run_until_( end_time ); - - spc_time -= end_time; - - // Should have run at least to end_time, and at most 11 clocks over - // (for DIV YA,X) - assert( 0 <= spc_time && spc_time < 12 ); - - // Catch timers and DSP up to end_time - - for ( int i = 0; i < timer_count; i++ ) - run_timer( 0, i ); - - // This may still leave dsp_time < 0, in the case of the fast DSP, but - // that's fine - if ( dsp_time < 0 ) - { RUN_DSP( 0, max_reg_time ); } -} - -// Macro to put prefix into same file as body of function, so that debugger -// can properly step through -#define SPC_CPU_RUN_FUNC \ -void Spc_Core::run_until_( time_t end_time )\ -{\ - rel_time_t rel_time = spc_time - end_time;\ - check( rel_time <= 0 );\ - \ - spc_time -= rel_time;\ - dsp_time += rel_time;\ - adjust_timers( rel_time ); - - #include "Spc_Cpu_run.h" - - spc_time += rel_time; - dsp_time -= rel_time; - adjust_timers( -rel_time ); - check( spc_time >= end_time ); -} diff --git a/bsnes/smp/snes_spc/Spc_Dsp.cpp b/bsnes/smp/snes_spc/Spc_Dsp.cpp deleted file mode 100755 index 106980ac..00000000 --- a/bsnes/smp/snes_spc/Spc_Dsp.cpp +++ /dev/null @@ -1,706 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Dsp.h" - -#include "blargg_endian.h" - -/* Copyright (C) 2007-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -#ifdef BLARGG_ENABLE_OPTIMIZER - #include BLARGG_ENABLE_OPTIMIZER -#endif - -// if ( io < -32768 ) io = -32768; -// if ( io > 32767 ) io = 32767; -#define CLAMP16( io )\ -{\ - if ( (int16_t) io != io )\ - io = (io >> 31) ^ 0x7FFF;\ -} - -// Access global DSP register -#define REG(n) regs [r_##n] - -// Access voice DSP register -#define VREG(r,n) r [v_##n] - -#ifndef SPC_DSP_OUT_HOOK - #define SPC_DSP_OUT_HOOK( l, r ) \ - write_sample( l, r ) -#endif - -inline void Spc_Dsp::set_null_output() -{ - output_ptr_ = dummy_buf; - output_end = dummy_buf + 2; -} - -void Spc_Dsp::set_output( sample_t* begin, sample_t* end ) -{ - output_begin = begin; - - if ( begin == NULL ) - { - user_output_end = NULL; - set_null_output(); - } - else - { - // Size must be even - assert( (end - begin) % 2 == 0 ); - - output_ptr_ = begin; - output_end = end; - user_output_end = end; - } -} - -inline void Spc_Dsp::write_sample( int l, int r ) -{ - sample_t* out = output_ptr_; - out [0] = l; - out [1] = r; - out += 2; - output_ptr_ = out; - - if ( out >= output_end ) - { - set_null_output(); - if ( out != dummy_buf + 2 ) - { - if ( set_output_callback.f ) - set_output_callback.f( set_output_callback.data ); - else - dprintf( "DSP buffer overflowed\n" ); - } - } -} - -// Volume registers and efb are signed! Easy to forget int8_t cast. -// Prefixes are to avoid accidental use of locals with same names. - -// Interleaved gauss table (to improve cache coherency) -// interleaved_gauss [i] = gauss [(i & 1) * 256 + 255 - (i >> 1 & 0xFF)] -static short const interleaved_gauss [512] = -{ - 370,1305, 366,1305, 362,1304, 358,1304, 354,1304, 351,1304, 347,1304, 343,1303, - 339,1303, 336,1303, 332,1302, 328,1302, 325,1301, 321,1300, 318,1300, 314,1299, - 311,1298, 307,1297, 304,1297, 300,1296, 297,1295, 293,1294, 290,1293, 286,1292, - 283,1291, 280,1290, 276,1288, 273,1287, 270,1286, 267,1284, 263,1283, 260,1282, - 257,1280, 254,1279, 251,1277, 248,1275, 245,1274, 242,1272, 239,1270, 236,1269, - 233,1267, 230,1265, 227,1263, 224,1261, 221,1259, 218,1257, 215,1255, 212,1253, - 210,1251, 207,1248, 204,1246, 201,1244, 199,1241, 196,1239, 193,1237, 191,1234, - 188,1232, 186,1229, 183,1227, 180,1224, 178,1221, 175,1219, 173,1216, 171,1213, - 168,1210, 166,1207, 163,1205, 161,1202, 159,1199, 156,1196, 154,1193, 152,1190, - 150,1186, 147,1183, 145,1180, 143,1177, 141,1174, 139,1170, 137,1167, 134,1164, - 132,1160, 130,1157, 128,1153, 126,1150, 124,1146, 122,1143, 120,1139, 118,1136, - 117,1132, 115,1128, 113,1125, 111,1121, 109,1117, 107,1113, 106,1109, 104,1106, - 102,1102, 100,1098, 99,1094, 97,1090, 95,1086, 94,1082, 92,1078, 90,1074, - 89,1070, 87,1066, 86,1061, 84,1057, 83,1053, 81,1049, 80,1045, 78,1040, - 77,1036, 76,1032, 74,1027, 73,1023, 71,1019, 70,1014, 69,1010, 67,1005, - 66,1001, 65, 997, 64, 992, 62, 988, 61, 983, 60, 978, 59, 974, 58, 969, - 56, 965, 55, 960, 54, 955, 53, 951, 52, 946, 51, 941, 50, 937, 49, 932, - 48, 927, 47, 923, 46, 918, 45, 913, 44, 908, 43, 904, 42, 899, 41, 894, - 40, 889, 39, 884, 38, 880, 37, 875, 36, 870, 36, 865, 35, 860, 34, 855, - 33, 851, 32, 846, 32, 841, 31, 836, 30, 831, 29, 826, 29, 821, 28, 816, - 27, 811, 27, 806, 26, 802, 25, 797, 24, 792, 24, 787, 23, 782, 23, 777, - 22, 772, 21, 767, 21, 762, 20, 757, 20, 752, 19, 747, 19, 742, 18, 737, - 17, 732, 17, 728, 16, 723, 16, 718, 15, 713, 15, 708, 15, 703, 14, 698, - 14, 693, 13, 688, 13, 683, 12, 678, 12, 674, 11, 669, 11, 664, 11, 659, - 10, 654, 10, 649, 10, 644, 9, 640, 9, 635, 9, 630, 8, 625, 8, 620, - 8, 615, 7, 611, 7, 606, 7, 601, 6, 596, 6, 592, 6, 587, 6, 582, - 5, 577, 5, 573, 5, 568, 5, 563, 4, 559, 4, 554, 4, 550, 4, 545, - 4, 540, 3, 536, 3, 531, 3, 527, 3, 522, 3, 517, 2, 513, 2, 508, - 2, 504, 2, 499, 2, 495, 2, 491, 2, 486, 1, 482, 1, 477, 1, 473, - 1, 469, 1, 464, 1, 460, 1, 456, 1, 451, 1, 447, 1, 443, 1, 439, - 0, 434, 0, 430, 0, 426, 0, 422, 0, 418, 0, 414, 0, 410, 0, 405, - 0, 401, 0, 397, 0, 393, 0, 389, 0, 385, 0, 381, 0, 378, 0, 374, -}; - - -//// Counters - -#define RATE( rate, div )\ - (rate >= div ? rate / div * 8 - 1 : rate - 1) - -static unsigned const counter_mask [32] = -{ - RATE( 2,2), RATE(2048,4), RATE(1536,3), - RATE(1280,5), RATE(1024,4), RATE( 768,3), - RATE( 640,5), RATE( 512,4), RATE( 384,3), - RATE( 320,5), RATE( 256,4), RATE( 192,3), - RATE( 160,5), RATE( 128,4), RATE( 96,3), - RATE( 80,5), RATE( 64,4), RATE( 48,3), - RATE( 40,5), RATE( 32,4), RATE( 24,3), - RATE( 20,5), RATE( 16,4), RATE( 12,3), - RATE( 10,5), RATE( 8,4), RATE( 6,3), - RATE( 5,5), RATE( 4,4), RATE( 3,3), - RATE( 2,4), - RATE( 1,4) -}; -#undef RATE - -inline void Spc_Dsp::init_counter() -{ - // counters start out with this synchronization - m.counters [0] = 1; - m.counters [1] = 0; - m.counters [2] = -0x20u; - m.counters [3] = 0x0B; - - int n = 2; - for ( int i = 1; i < 32; i++ ) - { - m.counter_select [i] = &m.counters [n]; - if ( !--n ) - n = 3; - } - m.counter_select [ 0] = &m.counters [0]; - m.counter_select [30] = &m.counters [2]; -} - -inline void Spc_Dsp::run_counter( int i ) -{ - int n = m.counters [i]; - if ( !(n-- & 7) ) - n -= 6 - i; - m.counters [i] = n; -} - -#define READ_COUNTER( rate )\ - (*m.counter_select [rate] & counter_mask [rate]) - - -//// Emulation - -void Spc_Dsp::run( int clock_count ) -{ - int new_phase = m.phase + clock_count; - int count = new_phase >> 5; - m.phase = new_phase & 31; - if ( !count ) - return; - - byte* const ram = this->ram; - byte const* const dir = &ram [REG(dir) * 0x100]; - int const slow_gaussian = (REG(pmon) >> 1) | REG(non); - int const noise_rate = REG(flg) & 0x1F; - - // Global volume - int mvoll = (int8_t) REG(mvoll); - int mvolr = (int8_t) REG(mvolr); - if ( mvoll * mvolr < surround_threshold ) - mvoll = -mvoll; // eliminate surround - - do - { - // KON/KOFF reading - if ( (m.every_other_sample ^= 1) != 0 ) - { - m.new_kon &= ~m.kon; - m.kon = m.new_kon; - m.t_koff = REG(koff); - } - - run_counter( 1 ); - run_counter( 2 ); - run_counter( 3 ); - - // Noise - if ( !READ_COUNTER( noise_rate ) ) - { - int feedback = (m.noise << 13) ^ (m.noise << 14); - m.noise = (feedback & 0x4000) ^ (m.noise >> 1); - } - - // Voices - int pmon_input = 0; - int main_out_l = 0; - int main_out_r = 0; - int echo_out_l = 0; - int echo_out_r = 0; - voice_t* v = m.voices; - byte* v_regs = regs; - int vbit = 1; - do - { - #define SAMPLE_PTR(i) GET_LE16A( &dir [VREG(v_regs,srcn) * 4 + i * 2] ) - - int brr_header = ram [v->brr_addr]; - int kon_delay = v->kon_delay; - - // Pitch - int pitch = GET_LE16A( &VREG(v_regs,pitchl) ) & 0x3FFF; - if ( REG(pmon) & vbit ) - pitch += ((pmon_input >> 5) * pitch) >> 10; - - // KON phases - if ( --kon_delay >= 0 ) - { - v->kon_delay = kon_delay; - - // Get ready to start BRR decoding on next sample - if ( kon_delay == 4 ) - { - v->brr_addr = SAMPLE_PTR( 0 ); - v->brr_offset = 1; - v->buf_pos = v->buf; - brr_header = 0; // header is ignored on this sample - } - - // Envelope is never run during KON - v->env = 0; - v->hidden_env = 0; - - // Disable BRR decoding until last three samples - v->interp_pos = (kon_delay & 3 ? 0x4000 : 0); - - // Pitch is never added during KON - pitch = 0; - } - - int env = v->env; - - // Gaussian interpolation - { - int output = 0; - VREG(v_regs,envx) = (byte) (env >> 4); - if ( env ) - { - // Make pointers into gaussian based on fractional position between samples - int offset = (unsigned) v->interp_pos >> 3 & 0x1FE; - short const* fwd = interleaved_gauss + offset; - short const* rev = interleaved_gauss + 510 - offset; // mirror left half of gaussian - - int const* in = &v->buf_pos [(unsigned) v->interp_pos >> 12]; - - if ( !(slow_gaussian & vbit) ) // 99% - { - // Faster approximation when exact sample value isn't necessary for pitch mod - output = (fwd [0] * in [0] + - fwd [1] * in [1] + - rev [1] * in [2] + - rev [0] * in [3]) >> 11; - output = (output * env) >> 11; - } - else - { - output = (int16_t) (m.noise * 2); - if ( !(REG(non) & vbit) ) - { - output = (fwd [0] * in [0]) >> 11; - output += (fwd [1] * in [1]) >> 11; - output += (rev [1] * in [2]) >> 11; - output = (int16_t) output; - output += (rev [0] * in [3]) >> 11; - - CLAMP16( output ); - output &= ~1; - } - output = (output * env) >> 11 & ~1; - } - - // Output - int l = output * v->volume [0]; - int r = output * v->volume [1]; - - main_out_l += l; - main_out_r += r; - - if ( REG(eon) & vbit ) - { - echo_out_l += l; - echo_out_r += r; - } - } - - pmon_input = output; - VREG(v_regs,outx) = (byte) (output >> 8); - } - - // Soft reset or end of sample - if ( REG(flg) & 0x80 || (brr_header & 3) == 1 ) - { - v->env_mode = env_release; - env = 0; - } - - if ( m.every_other_sample ) - { - // KOFF - if ( m.t_koff & vbit ) - v->env_mode = env_release; - - // KON - if ( m.kon & vbit ) - { - v->kon_delay = 5; - v->env_mode = env_attack; - REG(endx) &= ~vbit; - } - } - - // Envelope - if ( !v->kon_delay ) - { - if ( v->env_mode == env_release ) // 97% - { - env -= 0x8; - v->env = env; - if ( env <= 0 ) - { - v->env = 0; - goto skip_brr; // no BRR decoding for you! - } - } - else // 3% - { - int rate; - int const adsr0 = VREG(v_regs,adsr0); - int env_data = VREG(v_regs,adsr1); - if ( adsr0 >= 0x80 ) // 97% ADSR - { - if ( v->env_mode > env_decay ) // 89% - { - env--; - env -= env >> 8; - rate = env_data & 0x1F; - - // optimized handling - v->hidden_env = env; - if ( READ_COUNTER( rate ) ) - goto exit_env; - v->env = env; - goto exit_env; - } - else if ( v->env_mode == env_decay ) - { - env--; - env -= env >> 8; - rate = (adsr0 >> 3 & 0x0E) + 0x10; - } - else // env_attack - { - rate = (adsr0 & 0x0F) * 2 + 1; - env += rate < 31 ? 0x20 : 0x400; - } - } - else // GAIN - { - int mode; - env_data = VREG(v_regs,gain); - mode = env_data >> 5; - if ( mode < 4 ) // direct - { - env = env_data * 0x10; - rate = 31; - } - else - { - rate = env_data & 0x1F; - if ( mode == 4 ) // 4: linear decrease - { - env -= 0x20; - } - else if ( mode < 6 ) // 5: exponential decrease - { - env--; - env -= env >> 8; - } - else // 6,7: linear increase - { - env += 0x20; - if ( mode > 6 && (unsigned) v->hidden_env >= 0x600 ) - env += 0x8 - 0x20; // 7: two-slope linear increase - } - } - } - - // Sustain level - if ( (env >> 8) == (env_data >> 5) && v->env_mode == env_decay ) - v->env_mode = env_sustain; - - v->hidden_env = env; - - // unsigned cast because linear decrease going negative also triggers this - if ( (unsigned) env > 0x7FF ) - { - env = (env < 0 ? 0 : 0x7FF); - if ( v->env_mode == env_attack ) - v->env_mode = env_decay; - } - - if ( !READ_COUNTER( rate ) ) - v->env = env; // nothing else is controlled by the counter - } - } - exit_env: - - { - // Apply pitch - int old_pos = v->interp_pos; - int interp_pos = (old_pos & 0x3FFF) + pitch; - if ( interp_pos > 0x7FFF ) - interp_pos = 0x7FFF; - v->interp_pos = interp_pos; - - // BRR decode if necessary - if ( old_pos >= 0x4000 ) - { - // Arrange the four input nybbles in 0xABCD order for easy decoding - int nybbles = ram [(v->brr_addr + v->brr_offset) & 0xFFFF] * 0x100 + - ram [(v->brr_addr + v->brr_offset + 1) & 0xFFFF]; - - // Advance read position - int const brr_block_size = 9; - int brr_offset = v->brr_offset; - if ( (brr_offset += 2) >= brr_block_size ) - { - // Next BRR block - int brr_addr = (v->brr_addr + brr_block_size) & 0xFFFF; - assert( brr_offset == brr_block_size ); - if ( brr_header & 1 ) - { - brr_addr = SAMPLE_PTR( 1 ); - if ( !v->kon_delay ) - REG(endx) |= vbit; - } - v->brr_addr = brr_addr; - brr_offset = 1; - } - v->brr_offset = brr_offset; - - // Decode - - // 0: >>1 1: <<0 2: <<1 ... 12: <<11 13-15: >>4 <<11 - static unsigned char const shifts [16 * 2] = { - 13,12,12,12,12,12,12,12,12,12,12, 12, 12, 16, 16, 16, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11, 11 - }; - int const scale = brr_header >> 4; - int const right_shift = shifts [scale]; - int const left_shift = shifts [scale + 16]; - - // Decode and write to next four samples in circular buffer - int* pos = v->buf_pos; - for ( int* end = pos + 4; pos < end; pos++ ) - { - // Extract upper nybble and scale appropriately - int s = ((int16_t) nybbles >> right_shift) << left_shift; - nybbles <<= 4; - - // Apply IIR filter (8 is the most commonly used) - int const filter = brr_header & 0x0C; - int const p1 = pos [brr_buf_size - 1]; - int const p2 = pos [brr_buf_size - 2] >> 1; - if ( filter >= 8 ) - { - s += p1; - s -= p2; - if ( filter == 8 ) // s += p1 * 0.953125 - p2 * 0.46875 - { - s += p2 >> 4; - s += (p1 * -3) >> 6; - } - else // s += p1 * 0.8984375 - p2 * 0.40625 - { - s += (p1 * -13) >> 7; - s += (p2 * 3) >> 4; - } - } - else if ( filter ) // s += p1 * 0.46875 - { - s += p1 >> 1; - s += (-p1) >> 5; - } - - // Adjust and write sample - CLAMP16( s ); - s = (int16_t) (s * 2); - pos [brr_buf_size] = pos [0] = s; // second copy simplifies wrap-around - } - - if ( pos >= &v->buf [brr_buf_size] ) - pos = v->buf; - v->buf_pos = pos; - } - } -skip_brr: - // Next voice - vbit <<= 1; - v_regs += 0x10; - v++; - } - while ( vbit < 0x100 ); - - // Echo position - int echo_offset = m.echo_offset; - byte* const echo_ptr = &ram [(REG(esa) * 0x100 + echo_offset) & 0xFFFF]; - if ( !echo_offset ) - m.echo_length = (REG(edl) & 0x0F) * 0x800; - echo_offset += 4; - if ( echo_offset >= m.echo_length ) - echo_offset = 0; - m.echo_offset = echo_offset; - - // FIR - int echo_in_l = GET_LE16SA( echo_ptr + 0 ); - int echo_in_r = GET_LE16SA( echo_ptr + 2 ); - - int (*echo_hist_pos) [2] = m.echo_hist_pos; - if ( ++echo_hist_pos >= &m.echo_hist [echo_hist_size] ) - echo_hist_pos = m.echo_hist; - m.echo_hist_pos = echo_hist_pos; - - echo_hist_pos [0] [0] = echo_hist_pos [8] [0] = echo_in_l; - echo_hist_pos [0] [1] = echo_hist_pos [8] [1] = echo_in_r; - - #define CALC_FIR_( i, in ) ((in) * (int8_t) REG(fir + i * 0x10)) - echo_in_l = CALC_FIR_( 7, echo_in_l ); - echo_in_r = CALC_FIR_( 7, echo_in_r ); - - #define CALC_FIR( i, ch ) CALC_FIR_( i, echo_hist_pos [i + 1] [ch] ) - #define DO_FIR( i )\ - echo_in_l += CALC_FIR( i, 0 );\ - echo_in_r += CALC_FIR( i, 1 ); - DO_FIR( 0 ); - DO_FIR( 1 ); - DO_FIR( 2 ); - #if defined (__MWERKS__) && __MWERKS__ < 0x3200 - __eieio(); // keeps compiler from stupidly "caching" things in memory - #endif - DO_FIR( 3 ); - DO_FIR( 4 ); - DO_FIR( 5 ); - DO_FIR( 6 ); - - // Echo out - if ( !(REG(flg) & 0x20) ) - { - int l = (echo_out_l >> 7) + ((echo_in_l * (int8_t) REG(efb)) >> 14); - int r = (echo_out_r >> 7) + ((echo_in_r * (int8_t) REG(efb)) >> 14); - - // just to help pass more validation tests - #if SPC_MORE_ACCURACY - l &= ~1; - r &= ~1; - #endif - - CLAMP16( l ); - CLAMP16( r ); - - SET_LE16A( echo_ptr + 0, l ); - SET_LE16A( echo_ptr + 2, r ); - } - - // Sound out - int l = (main_out_l * mvoll + echo_in_l * (int8_t) REG(evoll)) >> 14; - int r = (main_out_r * mvolr + echo_in_r * (int8_t) REG(evolr)) >> 14; - - CLAMP16( l ); - CLAMP16( r ); - - if ( (REG(flg) & 0x40) ) - { - l = 0; - r = 0; - } - - SPC_DSP_OUT_HOOK( l, r ); - } - while ( --count ); -} - - -//// Setup - -void Spc_Dsp::apply_output_enables() -{ - for ( int i = 0; i < voice_count; i++ ) - update_voice_vol( i * 0x10 ); -} - -void Spc_Dsp::init( void* ram_64k ) -{ - ram = (byte*) ram_64k; - disable_surround( false ); // must be before mute_voices - mute_voices( 0 ); - set_output( NULL, 0 ); - reset(); - - #ifndef NDEBUG - // be sure this sign-extends - assert( (int16_t) 0x8000 == -0x8000 ); - - // be sure right shift preserves sign - assert( (-1 >> 1) == -1 ); - - // check clamp macro - int i; - i = +0x8000; CLAMP16( i ); assert( i == +0x7FFF ); - i = -0x8001; CLAMP16( i ); assert( i == -0x8000 ); - - blargg_verify_byte_order(); - #endif -} - -void Spc_Dsp::soft_reset() -{ - require( ram ); // init() must have been called already - - REG(flg) = 0xE0; - - m.noise = 0x2000; - m.echo_hist_pos = m.echo_hist; - m.every_other_sample = 1; - m.echo_offset = 0; - m.phase = 0; - - init_counter(); -} - -void Spc_Dsp::load( byte const new_regs [register_count] ) -{ - memcpy( regs, new_regs, sizeof regs ); - BLARGG_CLEAR( &m ); - - for ( int i = voice_count; --i >= 0; ) - { - voice_t& v = m.voices [i]; - v.brr_offset = 1; - v.buf_pos = v.buf; - } - m.new_kon = REG(kon); - - soft_reset(); - REG(flg) = new_regs [r_flg]; // soft_reset() overwrites this - - apply_output_enables(); -} - -void Spc_Dsp::reset() -{ - static byte const initial_regs [register_count] = { - 0x45,0x8B,0x5A,0x9A,0xE4,0x82,0x1B,0x78,0x00,0x00,0xAA,0x96,0x89,0x0E,0xE0,0x80, - 0x2A,0x49,0x3D,0xBA,0x14,0xA0,0xAC,0xC5,0x00,0x00,0x51,0xBB,0x9C,0x4E,0x7B,0xFF, - 0xF4,0xFD,0x57,0x32,0x37,0xD9,0x42,0x22,0x00,0x00,0x5B,0x3C,0x9F,0x1B,0x87,0x9A, - 0x6F,0x27,0xAF,0x7B,0xE5,0x68,0x0A,0xD9,0x00,0x00,0x9A,0xC5,0x9C,0x4E,0x7B,0xFF, - 0xEA,0x21,0x78,0x4F,0xDD,0xED,0x24,0x14,0x00,0x00,0x77,0xB1,0xD1,0x36,0xC1,0x67, - 0x52,0x57,0x46,0x3D,0x59,0xF4,0x87,0xA4,0x00,0x00,0x7E,0x44,0x9C,0x4E,0x7B,0xFF, - 0x75,0xF5,0x06,0x97,0x10,0xC3,0x24,0xBB,0x00,0x00,0x7B,0x7A,0xE0,0x60,0x12,0x0F, - 0xF7,0x74,0x1C,0xE5,0x39,0x3D,0x73,0xC1,0x00,0x00,0x7A,0xB3,0xFF,0x4E,0x7B,0xFF - }; - - load( initial_regs ); -} diff --git a/bsnes/smp/snes_spc/Spc_Dsp.h b/bsnes/smp/snes_spc/Spc_Dsp.h deleted file mode 100755 index 0da18456..00000000 --- a/bsnes/smp/snes_spc/Spc_Dsp.h +++ /dev/null @@ -1,225 +0,0 @@ -// Fast SNES SPC-700 DSP emulator (about 3x speed of accurate one) - -// snes_spc 0.9.5 -#ifndef BLARGG_SPC_DSP_H -#define BLARGG_SPC_DSP_H - -#include "blargg_common.h" - -BLARGG_NAMESPACE_BEGIN - -struct Spc_Dsp { -public: - typedef BOOST::uint8_t byte; - -// Setup - - // Initializes DSP and has it use the 64K RAM provided - void init( void* ram_64k ); - - // Sets function that is called when output buffer is filled, or NULL for none - blargg_callback set_output_callback; - //void set_output_callback( void (*func)( void* user_data ), void* user_data ); - - // Sets destination for output samples. If begin is NULL, doesn't generate any. - typedef short sample_t; - void set_output( sample_t* begin, sample_t* end ); - - // Current position in output buffer, or NULL if no buffer set - sample_t* output_ptr() const; - - // Number of samples written to output buffer since last set, or 0 if no buffer set. - int sample_count() const; - -// Emulation - - // Resets DSP to power-on state - void reset(); - - // Emulates pressing reset switch on SNES - void soft_reset(); - - // Reads/writes DSP registers. For accuracy, you must first call spc_run_dsp() - // to catch the DSP up to present. - int read ( int addr ) const; - void write( int addr, int data ); - - // Runs DSP for specified number of clocks (~1024000 per second). Every 32 clocks - // a pair of samples is generated. - void run( int clock_count ); - -// Sound control - - // Mutes voices corresponding to non-zero bits in mask (overrides VxVOL with 0). - // Reduces emulation accuracy. - enum { voice_count = 8 }; - void mute_voices( int mask ) { mute_mask = mask; } - - // If true, prevents channels and global volumes from being phase-negated - void disable_surround( bool disable = true ); - -// State - - // Resets DSP and uses supplied values to initialize registers - enum { register_count = 128 }; - void load( byte const regs [register_count] ); - -// DSP register addresses - - // Global registers - enum { - r_mvoll = 0x0C, r_mvolr = 0x1C, - r_evoll = 0x2C, r_evolr = 0x3C, - r_kon = 0x4C, r_koff = 0x5C, - r_flg = 0x6C, r_endx = 0x7C, - r_efb = 0x0D, r_pmon = 0x2D, - r_non = 0x3D, r_eon = 0x4D, - r_dir = 0x5D, r_esa = 0x6D, - r_edl = 0x7D, - r_fir = 0x0F // 8 coefficients at 0x0F, 0x1F ... 0x7F - }; - - // Voice registers - enum { - v_voll = 0x00, v_volr = 0x01, - v_pitchl = 0x02, v_pitchh = 0x03, - v_srcn = 0x04, v_adsr0 = 0x05, - v_adsr1 = 0x06, v_gain = 0x07, - v_envx = 0x08, v_outx = 0x09 - }; - -public: - BLARGG_DISABLE_NOTHROW - - typedef BOOST::int8_t int8_t; - typedef BOOST::int16_t int16_t; - - enum { echo_hist_size = 8 }; - - enum env_mode_t { env_release, env_attack, env_decay, env_sustain }; - enum { brr_buf_size = 12 }; - struct voice_t - { - int buf [brr_buf_size*2];// decoded samples (twice the size to simplify wrap handling) - int* buf_pos; // place in buffer where next samples will be decoded - int interp_pos; // relative fractional position in sample (0x1000 = 1.0) - int brr_addr; // address of current BRR block - int brr_offset; // current decoding offset in BRR block - int kon_delay; // KON delay/current setup phase - env_mode_t env_mode; - int env; // current envelope level - int hidden_env; // used by GAIN mode 7, very obscure quirk - int volume [2]; // copy of volume from DSP registers, with surround disabled - }; -private: - // non-emulation state - byte* ram; // 64K shared RAM between DSP and SMP - int mute_mask; - int surround_threshold; - sample_t* output_begin; - sample_t* output_ptr_; - sample_t* output_end; - sample_t* user_output_end; - sample_t dummy_buf [2]; - - struct state_t - { - int every_other_sample; // toggles every sample - int kon; // KON value when last checked - int noise; - int echo_offset; // offset from ESA in echo buffer - int echo_length; // number of bytes that echo_offset will stop at - int phase; // next clock cycle to run (0-31) - unsigned counters [4]; - - int new_kon; - int t_koff; - - // Echo history keeps most recent 8 samples (twice the size to simplify wrap handling) - int (*echo_hist_pos) [2]; // &echo_hist [0 to 7] - int echo_hist [echo_hist_size * 2] [2]; - - unsigned* counter_select [32]; - voice_t voices [voice_count]; - }; - state_t m; - - byte regs [register_count]; - - void init_counter(); - void run_counter( int ); - void update_voice_vol( int addr ); - void set_null_output(); - void write_sample( int l, int r ); - void apply_output_enables(); -}; - -inline int Spc_Dsp::read( int addr ) const -{ - assert( (unsigned) addr < register_count ); - return regs [addr]; -} - -inline void Spc_Dsp::update_voice_vol( int addr ) -{ - int l = (int8_t) regs [addr + v_voll]; - int r = (int8_t) regs [addr + v_volr]; - - if ( l * r < surround_threshold ) - { - // signs differ, so negate those that are negative - l ^= l >> 7; - r ^= r >> 7; - } - - int index = addr >> 4; - voice_t& v = m.voices [index]; - int enabled = ~mute_mask >> index & 1; - v.volume [0] = l * enabled; - v.volume [1] = r * enabled; -} - -inline void Spc_Dsp::write( int addr, int data ) -{ - assert( (unsigned) addr < register_count ); - - regs [addr] = (byte) data; - int low = addr & 0x0F; - if ( low < 0x2 ) // voice volumes - { - update_voice_vol( low ^ addr /* addr & 0xF0 */ ); - } - else if ( low == 0xC ) - { - if ( addr == r_kon ) - m.new_kon = (byte) data; - - if ( addr == r_endx ) // always cleared, regardless of data written - regs [r_endx] = 0; - } -} - -inline void Spc_Dsp::disable_surround( bool disable ) -{ - surround_threshold = disable ? 0 : -0x4000; -} - -inline Spc_Dsp::sample_t* Spc_Dsp::output_ptr() const -{ - // Don't return pointer into dummy_buf - return (output_ptr_ != dummy_buf ? output_ptr_ : user_output_end); -} - -inline int Spc_Dsp::sample_count() const -{ - sample_t* p = output_ptr(); - return (p ? p - output_begin : 0); -} - -#define SPC_NO_COPY_STATE_FUNCS 1 - -#define SPC_LESS_ACCURATE 1 - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/Spc_Dsp_State.cpp b/bsnes/smp/snes_spc/Spc_Dsp_State.cpp deleted file mode 100755 index b92d453b..00000000 --- a/bsnes/smp/snes_spc/Spc_Dsp_State.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Dsp.h" - -#if !SPC_NO_COPY_STATE_FUNCS - -#include "blargg_endian.h" - -/* Copyright (C) 2007-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void SPC_State_Copier::copy( void* state, size_t size ) -{ - func( buf, state, size ); -} - -int SPC_State_Copier::copy_int( int state, int size ) -{ - byte s [2]; - SET_LE16( s, state ); - func( buf, &s, size ); - return GET_LE16( s ); -} - -void SPC_State_Copier::skip( int count ) -{ - if ( count > 0 ) - { - char temp [64]; - memset( temp, 0, sizeof temp ); - do - { - int n = sizeof temp; - if ( n > count ) - n = count; - count -= n; - func( buf, temp, n ); - } - while ( count ); - } -} - -void SPC_State_Copier::extra() -{ - int n = 0; - SPC_State_Copier& copier = *this; - SPC_COPY( uint8_t, n ); - skip( n ); -} - -void Spc_Dsp::copy_state( unsigned char** io, copy_func_t copy ) -{ - SPC_State_Copier copier( io, copy ); - - // DSP registers - copier.copy( regs, register_count ); - - // Internal state - - // Voices - int i; - for ( i = 0; i < voice_count; i++ ) - { - voice_t* v = &m.voices [i]; - - // BRR buffer - for ( int bi = 0; bi < brr_buf_size; bi++ ) - { - int s = v->buf [bi]; - SPC_COPY( int16_t, s ); - v->buf [bi] = v->buf [bi + brr_buf_size] = s; - } - - SPC_COPY( uint16_t, v->interp_pos ); - SPC_COPY( uint16_t, v->brr_addr ); - SPC_COPY( uint16_t, v->env ); - SPC_COPY( int16_t, v->hidden_env ); - SPC_COPY( uint8_t, v->buf_pos ); - SPC_COPY( uint8_t, v->brr_offset ); - SPC_COPY( uint8_t, v->kon_delay ); - { - int mode = v->env_mode; - SPC_COPY( uint8_t, mode ); - v->env_mode = (enum env_mode_t) mode; - } - SPC_COPY( uint8_t, v->t_envx_out ); - - copier.extra(); - } - - // Echo history - for ( i = 0; i < echo_hist_size; i++ ) - { - int j; - for ( j = 0; j < 2; j++ ) - { - int s = m.echo_hist_pos [i] [j]; - SPC_COPY( int16_t, s ); - m.echo_hist [i] [j] = s; // write back at offset 0 - } - } - m.echo_hist_pos = m.echo_hist; - memcpy( &m.echo_hist [echo_hist_size], m.echo_hist, echo_hist_size * sizeof m.echo_hist [0] ); - - // Misc - SPC_COPY( uint8_t, m.every_other_sample ); - SPC_COPY( uint8_t, m.kon ); - - SPC_COPY( uint16_t, m.noise ); - SPC_COPY( uint16_t, m.counter ); - SPC_COPY( uint16_t, m.echo_offset ); - SPC_COPY( uint16_t, m.echo_length ); - SPC_COPY( uint8_t, m.phase ); - - SPC_COPY( uint8_t, m.new_kon ); - SPC_COPY( uint8_t, m.endx_buf ); - SPC_COPY( uint8_t, m.envx_buf ); - SPC_COPY( uint8_t, m.outx_buf ); - - SPC_COPY( uint8_t, m.t_pmon ); - SPC_COPY( uint8_t, m.t_non ); - SPC_COPY( uint8_t, m.t_eon ); - SPC_COPY( uint8_t, m.t_dir ); - SPC_COPY( uint8_t, m.t_koff ); - - SPC_COPY( uint16_t, m.t_brr_next_addr ); - SPC_COPY( uint8_t, m.t_adsr0 ); - SPC_COPY( uint8_t, m.t_brr_header ); - SPC_COPY( uint8_t, m.t_brr_byte ); - SPC_COPY( uint8_t, m.t_srcn ); - SPC_COPY( uint8_t, m.t_esa ); - SPC_COPY( uint8_t, m.t_echo_enabled ); - - SPC_COPY( int16_t, m.t_main_out [0] ); - SPC_COPY( int16_t, m.t_main_out [1] ); - SPC_COPY( int16_t, m.t_echo_out [0] ); - SPC_COPY( int16_t, m.t_echo_out [1] ); - SPC_COPY( int16_t, m.t_echo_in [0] ); - SPC_COPY( int16_t, m.t_echo_in [1] ); - - SPC_COPY( uint16_t, m.t_dir_addr ); - SPC_COPY( uint16_t, m.t_pitch ); - SPC_COPY( int16_t, m.t_output ); - SPC_COPY( uint16_t, m.t_echo_ptr ); - SPC_COPY( uint8_t, m.t_looped ); - - copier.extra(); -} -#endif diff --git a/bsnes/smp/snes_spc/Spc_Filter.cpp b/bsnes/smp/snes_spc/Spc_Filter.cpp deleted file mode 100755 index 424e6198..00000000 --- a/bsnes/smp/snes_spc/Spc_Filter.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Spc_Filter.h" - -/* Copyright (C) 2007-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void Spc_Filter::clear() -{ - BLARGG_CLEAR( &ch ); -} - -Spc_Filter::Spc_Filter() -{ - enabled = true; - gain = gain_unit; - bass = bass_norm; - - clear(); -} - -void Spc_Filter::run( sample_t io [], int count ) -{ - require( (count & 1) == 0 ); // must be even - - int const gain = this->gain; - if ( enabled ) - { - int const bass = this->bass; - chan_t* c = &ch [2]; - do - { - // cache in registers - int sum = (--c)->sum; - int pp1 = c->pp1; - int p1 = c->p1; - - for ( int i = 0; i < count; i += 2 ) - { - // Low-pass filter (two point FIR with coeffs 0.25, 0.75) - int f = io [i] + p1; - p1 = io [i] * 3; - - // High-pass filter ("leaky integrator") - int delta = f - pp1; - pp1 = f; - int s = sum >> (gain_bits + 2); - sum += (delta * gain) - (sum >> bass); - - // Clamp to 16 bits - if ( (sample_t) s != s ) - s = (s >> 31) ^ 0x7FFF; - - io [i] = (sample_t) s; - } - - c->p1 = p1; - c->pp1 = pp1; - c->sum = sum; - ++io; - } - while ( c != ch ); - } - else if ( gain != gain_unit ) - { - sample_t* const end = io + count; - while ( io < end ) - { - int s = (*io * gain) >> gain_bits; - - // Clamp to 16 bits - if ( (sample_t) s != s ) - s = (s >> 31) ^ 0x7FFF; - - *io++ = (sample_t) s; - } - } -} diff --git a/bsnes/smp/snes_spc/Spc_State.cpp b/bsnes/smp/snes_spc/Spc_State.cpp deleted file mode 100755 index 90bceabf..00000000 --- a/bsnes/smp/snes_spc/Spc_State.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// SPC emulation state save/load: copy_state(), save_spc() -// Separate file to avoid linking in unless needed - -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "Snes_Spc.h" - -#if !SPC_NO_COPY_STATE_FUNCS - -#include - -/* Copyright (C) 2004-2010 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -void Snes_Spc::init_header( void* spc_out ) -{ - spc_file_t* const spc = (spc_file_t*) spc_out; - - spc->has_id666 = 26; // has none - spc->version = 30; - memcpy( spc, signature, sizeof spc->signature ); - memset( spc->text, 0, sizeof spc->text ); -} - -void Spc_Core::save_regs( byte out [reg_count], byte ports [port_count] ) -{ - memcpy( out, regs, reg_count ); - - int i; - for ( i = 0; i < port_count; i++ ) - out [r_cpuio0 + i] = regs_in [r_cpuio0 + i]; - - for ( i = 0; i < timer_count; i++ ) - out [r_t0out + i] = regs_in [r_t0out + i]; - - memcpy( ports, ®s [r_cpuio0], port_count ); -} - -void Spc_Core::save_ram( byte out [65536] ) -{ - memcpy( out, ram(), 65536 ); - - if ( rom_enabled ) - memcpy( out + rom_addr, hi_ram, sizeof hi_ram ); -} - -void Snes_Spc::save_spc( void* spc_out ) -{ - spc_file_t* const spc = (spc_file_t*) spc_out; - - // CPU - spc->pcl = (byte) (cpu().pc >> 0); - spc->pch = (byte) (cpu().pc >> 8); - spc->a = cpu().a; - spc->x = cpu().x; - spc->y = cpu().y; - spc->psw = cpu().psw; - spc->sp = cpu().sp; - - // RAM, ROM - save_ram( spc->ram ); - memset( spc->unused, 0, sizeof spc->unused ); - memcpy( spc->ipl_rom, rom(), sizeof spc->ipl_rom ); - - // SMP registers - byte out_ports [port_count]; // ignored - save_regs( &spc->ram [regs_addr], out_ports ); - - // DSP registers - for ( int i = 0; i < Spc_Dsp::register_count; i++ ) - spc->dsp [i] = dsp().read( i ); -} - -void Spc_Core::copy_state( unsigned char** io, copy_func_t copy ) -{ - SPC_State_Copier copier( io, copy ); - - // Make state data more readable by putting 64K RAM, 16 SMP registers, - // then DSP (with its 128 registers) first - - // RAM - - // Disable ROM so that entire RAM will be in ram(). If ROM was enabled, - // will get re-enabled by load_regs() below. - enable_rom( false ); - copier.copy( ram(), 0x10000 ); - - // SMP registers - { - byte new_regs [reg_count]; - byte out_ports [port_count]; - - save_regs( new_regs, out_ports ); - copier.copy( new_regs, sizeof new_regs ); - copier.copy( out_ports, sizeof out_ports ); - load_regs( new_regs, out_ports ); - } - - // CPU registers - SPC_COPY( uint16_t, cpu().pc ); - SPC_COPY( uint8_t, cpu().a ); - SPC_COPY( uint8_t, cpu().x ); - SPC_COPY( uint8_t, cpu().y ); - SPC_COPY( uint8_t, cpu().psw ); - SPC_COPY( uint8_t, cpu().sp ); - copier.extra(); - - SPC_COPY( int16_t, spc_time ); - SPC_COPY( int16_t, dsp_time ); - - // DSP - dsp().copy_state( io, copy ); - - // Timers - for ( int i = 0; i < timer_count; i++ ) - { - Timer* t = &timers [i]; - SPC_COPY( int16_t, t->time ); - SPC_COPY( uint8_t, t->divider ); - copier.extra(); - } - copier.extra(); -} -#endif diff --git a/bsnes/smp/snes_spc/blargg_common.cpp b/bsnes/smp/snes_spc/blargg_common.cpp deleted file mode 100755 index 73141343..00000000 --- a/bsnes/smp/snes_spc/blargg_common.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "blargg_common.h" - -/* Copyright (C) 2008-2009 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -BLARGG_NAMESPACE_BEGIN - -// defined here to avoid need for blargg_errors.cpp in simple programs -blargg_err_def_t blargg_err_memory = BLARGG_ERR_MEMORY; - -void blargg_vector_::init() -{ - begin_ = NULL; - size_ = 0; -} - -void blargg_vector_::clear() -{ - void* p = begin_; - begin_ = NULL; - size_ = 0; - free( p ); -} - -blargg_err_t blargg_vector_::resize_( size_t n, size_t elem_size ) -{ - if ( n != size_ ) - { - if ( n == 0 ) - { - // Simpler to handle explicitly. Realloc will handle a size of 0, - // but then we have to avoid raising an error for a NULL return. - clear(); - } - else - { - void* p = realloc( begin_, n * elem_size ); - CHECK_ALLOC( p ); - begin_ = p; - size_ = n; - } - } - return blargg_ok; -} - -BLARGG_NAMESPACE_END diff --git a/bsnes/smp/snes_spc/blargg_common.h b/bsnes/smp/snes_spc/blargg_common.h deleted file mode 100755 index 394ca726..00000000 --- a/bsnes/smp/snes_spc/blargg_common.h +++ /dev/null @@ -1,222 +0,0 @@ -// Sets up common environment for Shay Green's libraries. -// To change configuration options, modify blargg_config.h, not this file. - -// snes_spc 0.9.5 -#ifndef BLARGG_COMMON_H -#define BLARGG_COMMON_H - -#include -#include -#include - -typedef const char* blargg_err_t; // 0 on success, otherwise error string - -// Success; no error -int const blargg_ok = 0; - -// BLARGG_RESTRICT: equivalent to C99's restrict, where supported -#if __GNUC__ >= 3 || _MSC_VER >= 1100 - #define BLARGG_RESTRICT __restrict -#else - #define BLARGG_RESTRICT -#endif - -#if __cplusplus >= 199711 - #define BLARGG_MUTABLE mutable -#else - #define BLARGG_MUTABLE -#endif - -/* BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant). -I don't just use 'abcd' because that's implementation-dependent. */ -#define BLARGG_4CHAR( a, b, c, d ) \ - ((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF)) - -/* BLARGG_STATIC_ASSERT( expr ): Generates compile error if expr is 0. -Can be used at file, function, or class scope. */ -#ifdef _MSC_VER - // MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified - #define BLARGG_STATIC_ASSERT( expr ) \ - void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] ) -#else - // Others fail when declaring same function multiple times in class, - // so differentiate them by line - #define BLARGG_STATIC_ASSERT( expr ) \ - void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] ) -#endif - -/* Pure virtual functions cause a vtable entry to a "called pure virtual" -error handler, requiring linkage to the C++ runtime library. This macro is -used in place of the "= 0", and simply expands to its argument. During -development, it expands to "= 0", allowing detection of missing overrides. */ -#define BLARGG_PURE( def ) def - -/* My code depends on ASCII anywhere a character or string constant is -compared with data read from a file, and anywhere file data is read and -treated as a string. */ -#if '\n'!=0x0A || ' '!=0x20 || '0'!=0x30 || 'A'!=0x41 || 'a'!=0x61 - #error "ASCII character set required" -#endif - -/* My code depends on int being at least 32 bits. Almost everything these days -uses at least 32-bit ints, so it's hard to even find a system with 16-bit ints -to test with. The issue can't be gotten around by using a suitable blargg_int -everywhere either, because int is often converted to implicitly when doing -arithmetic on smaller types. */ -#if UINT_MAX < 0xFFFFFFFF - #error "int must be at least 32 bits" -#endif - -// In case compiler doesn't support these properly. Used rarely. -#define STATIC_CAST(T,expr) static_cast (expr) -#define CONST_CAST( T,expr) const_cast (expr) - -// User configuration can override the above macros if necessary -#include "blargg_config.h" - -#ifdef BLARGG_NAMESPACE - #define BLARGG_NAMESPACE_BEGIN namespace BLARGG_NAMESPACE { - #define BLARGG_NAMESPACE_END } - - BLARGG_NAMESPACE_BEGIN - BLARGG_NAMESPACE_END - using namespace BLARGG_NAMESPACE; -#else - #define BLARGG_NAMESPACE_BEGIN - #define BLARGG_NAMESPACE_END -#endif - -BLARGG_NAMESPACE_BEGIN - -/* BLARGG_DEPRECATED [_TEXT] for any declarations/text to be removed in a -future version. In GCC, we can let the compiler warn. In other compilers, -we strip it out unless BLARGG_LEGACY is true. */ -#if BLARGG_LEGACY - // Allow old client code to work without warnings - #define BLARGG_DEPRECATED_TEXT( text ) text - #define BLARGG_DEPRECATED( text ) text -#elif __GNUC__ >= 4 - // In GCC, we can mark declarations and let the compiler warn - #define BLARGG_DEPRECATED_TEXT( text ) text - #define BLARGG_DEPRECATED( text ) __attribute__ ((deprecated)) text -#else - // By default, deprecated items are removed, to avoid use in new code - #define BLARGG_DEPRECATED_TEXT( text ) - #define BLARGG_DEPRECATED( text ) -#endif - -/* BOOST::int8_t, BOOST::int32_t, etc. -I used BOOST since I originally was going to allow use of the boost library -for prividing the definitions. If I'm defining them, they must be scoped or -else they could conflict with the standard ones at global scope. Even if -HAVE_STDINT_H isn't defined, I can't assume the typedefs won't exist at -global scope already. */ -#if defined (HAVE_STDINT_H) || \ - UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF - #include - #define BOOST -#else - struct BOOST - { - typedef signed char int8_t; - typedef unsigned char uint8_t; - typedef short int16_t; - typedef unsigned short uint16_t; - typedef int int32_t; - typedef unsigned int uint32_t; - }; -#endif - -/* My code is not written with exceptions in mind, so either uses new (nothrow) -OR overrides operator new in my classes. The former is best since clients -creating objects will get standard exceptions on failure, but that causes it -to require the standard C++ library. So, when the client is using the C -interface, I override operator new to use malloc. */ - -// BLARGG_DISABLE_NOTHROW is put inside classes -#ifndef BLARGG_DISABLE_NOTHROW - // throw spec mandatory in ISO C++ if NULL can be returned - #if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300 - #define BLARGG_THROWS_NOTHING throw () - #else - #define BLARGG_THROWS_NOTHING - #endif - - #define BLARGG_DISABLE_NOTHROW \ - void* operator new ( size_t s ) BLARGG_THROWS_NOTHING { return malloc( s ); }\ - void operator delete( void* p ) BLARGG_THROWS_NOTHING { free( p ); } - - #define BLARGG_NEW new -#else - // BLARGG_NEW is used in place of new in library code - #include - #define BLARGG_NEW new (std::nothrow) -#endif - - class blargg_vector_ { - protected: - void* begin_; - size_t size_; - void init(); - blargg_err_t resize_( size_t n, size_t elem_size ); - public: - size_t size() const { return size_; } - void clear(); - }; - -// Very lightweight vector for POD types (no constructor/destructor) -template -class blargg_vector : public blargg_vector_ { - union T_must_be_pod { T t; }; // fails if T is not POD -public: - blargg_vector() { init(); } - ~blargg_vector() { clear(); } - - blargg_err_t resize( size_t n ) { return resize_( n, sizeof (T) ); } - - T* begin() { return static_cast (begin_); } - const T* begin() const { return static_cast (begin_); } - - T* end() { return static_cast (begin_) + size_; } - const T* end() const { return static_cast (begin_) + size_; } - - T& operator [] ( size_t n ) - { - assert( n < size_ ); - return static_cast (begin_) [n]; - } - - const T& operator [] ( size_t n ) const - { - assert( n < size_ ); - return static_cast (begin_) [n]; - } -}; - -// Callback function with user data. -// blargg_callback set_callback; // for user, this acts like... -// void set_callback( T func, void* user_data = NULL ); // ...this -// To call function, do set_callback.f( .. set_callback.data ... ); -template -struct blargg_callback -{ - T f; - void* data; - blargg_callback() { f = NULL; } - void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; } -}; - -#ifndef _WIN32 - // Not supported on any other platforms - #undef BLARGG_UTF8_PATHS -#endif - -BLARGG_DEPRECATED( typedef signed int blargg_long; ) -BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; ) -#if BLARGG_LEGACY - #define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT -#endif - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/blargg_config.h b/bsnes/smp/snes_spc/blargg_config.h deleted file mode 100755 index 2ede514b..00000000 --- a/bsnes/smp/snes_spc/blargg_config.h +++ /dev/null @@ -1,26 +0,0 @@ -// snes_spc 0.9.5 user configuration file. Don't replace when updating library. - -#ifndef BLARGG_CONFIG_H -#define BLARGG_CONFIG_H - -// Uncomment to use zlib for transparent decompression of gzipped files -//#define HAVE_ZLIB_H - -// Uncomment to enable platform-specific (and possibly non-portable) optimizations. -//#define BLARGG_NONPORTABLE 1 - -// Uncomment if automatic byte-order determination doesn't work -//#define BLARGG_BIG_ENDIAN 1 - -// Uncomment to enable the normal behavior of getting an out-of-memory exception -// when new fails while creating an object of a class from this library. Note -// that this does not enable exceptions when calling library functions, which -// ALWAYS report errors by blargg_err_t. -//#define BLARGG_DISABLE_NOTHROW - -// Use standard config.h if present -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#endif diff --git a/bsnes/smp/snes_spc/blargg_errors.cpp b/bsnes/smp/snes_spc/blargg_errors.cpp deleted file mode 100755 index 046a69d2..00000000 --- a/bsnes/smp/snes_spc/blargg_errors.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "blargg_errors.h" - -/* Copyright (C) 2009 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -BLARGG_NAMESPACE_BEGIN - -blargg_err_def_t blargg_err_generic = BLARGG_ERR_GENERIC; -// blargg_err_memory is defined in blargg_common.cpp -blargg_err_def_t blargg_err_caller = BLARGG_ERR_CALLER; -blargg_err_def_t blargg_err_internal = BLARGG_ERR_INTERNAL; -blargg_err_def_t blargg_err_limitation = BLARGG_ERR_LIMITATION; - -blargg_err_def_t blargg_err_file_missing = BLARGG_ERR_FILE_MISSING; -blargg_err_def_t blargg_err_file_read = BLARGG_ERR_FILE_READ; -blargg_err_def_t blargg_err_file_write = BLARGG_ERR_FILE_WRITE; -blargg_err_def_t blargg_err_file_io = BLARGG_ERR_FILE_IO; -blargg_err_def_t blargg_err_file_full = BLARGG_ERR_FILE_FULL; -blargg_err_def_t blargg_err_file_eof = BLARGG_ERR_FILE_EOF; - -blargg_err_def_t blargg_err_file_type = BLARGG_ERR_FILE_TYPE; -blargg_err_def_t blargg_err_file_feature = BLARGG_ERR_FILE_FEATURE; -blargg_err_def_t blargg_err_file_corrupt = BLARGG_ERR_FILE_CORRUPT; - -const char* blargg_err_str( blargg_err_t err ) -{ - if ( !err ) - return ""; - - if ( *err == BLARGG_ERR_TYPE("")[0] ) - return err + 1; - - return err; -} - -bool blargg_is_err_type( blargg_err_t err, const char type [] ) -{ - if ( err ) - { - // True if first strlen(type) characters of err match type - char const* p = err; - while ( *type && *type == *p ) - { - type++; - p++; - } - - if ( !*type ) - return true; - } - - return false; -} - -const char* blargg_err_details( blargg_err_t err ) -{ - const char* p = err; - if ( !p ) - { - p = ""; - } - else if ( *p == BLARGG_ERR_TYPE("")[0] ) - { - while ( *p && *p != ';' ) - p++; - - // Skip ; and space after it - if ( *p ) - { - p++; - - check( *p == ' ' ); - if ( *p ) - p++; - } - } - return p; -} - -int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const codes [] ) -{ - if ( !err ) - return 0; - - while ( codes->str && !blargg_is_err_type( err, codes->str ) ) - codes++; - - return codes->code; -} - -blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const codes [] ) -{ - if ( !code ) - return blargg_ok; - - while ( codes->str && codes->code != code ) - codes++; - - if ( !codes->str ) - return blargg_err_generic; - - return codes->str; -} - -BLARGG_NAMESPACE_END diff --git a/bsnes/smp/snes_spc/blargg_errors.h b/bsnes/smp/snes_spc/blargg_errors.h deleted file mode 100755 index 04269e29..00000000 --- a/bsnes/smp/snes_spc/blargg_errors.h +++ /dev/null @@ -1,84 +0,0 @@ -// Error strings and conversion functions - -// snes_spc 0.9.5 -#ifndef BLARGG_ERRORS_H -#define BLARGG_ERRORS_H - -#ifndef BLARGG_COMMON_H - #include "blargg_common.h" -#endif - -BLARGG_NAMESPACE_BEGIN - -typedef const char blargg_err_def_t []; - -// Basic errors -extern blargg_err_def_t blargg_err_generic; -extern blargg_err_def_t blargg_err_memory; -extern blargg_err_def_t blargg_err_caller; -extern blargg_err_def_t blargg_err_internal; -extern blargg_err_def_t blargg_err_limitation; - -// File low-level -extern blargg_err_def_t blargg_err_file_missing; // not found -extern blargg_err_def_t blargg_err_file_read; -extern blargg_err_def_t blargg_err_file_write; -extern blargg_err_def_t blargg_err_file_io; -extern blargg_err_def_t blargg_err_file_full; -extern blargg_err_def_t blargg_err_file_eof; - -// File high-level -extern blargg_err_def_t blargg_err_file_type; // wrong file type -extern blargg_err_def_t blargg_err_file_feature; -extern blargg_err_def_t blargg_err_file_corrupt; - -// C string describing error, or "" if err == NULL -const char* blargg_err_str( blargg_err_t err ); - -// True iff error is of given type, or false if err == NULL -bool blargg_is_err_type( blargg_err_t, const char type [] ); - -// Details of error without describing main cause, or "" if err == NULL -const char* blargg_err_details( blargg_err_t err ); - -// Converts error string to integer code using mapping table. Calls blargg_is_err_type() -// for each str and returns code on first match. Returns 0 if err == NULL. -struct blargg_err_to_code_t { - const char* str; - int code; -}; -int blargg_err_to_code( blargg_err_t err, blargg_err_to_code_t const [] ); - -// Converts error code back to string. If code == 0, returns NULL. If not in table, -// returns blargg_err_generic. -blargg_err_t blargg_code_to_err( int code, blargg_err_to_code_t const [] ); - -// Generates error string literal with details of cause -#define BLARGG_ERR( type, str ) (type "; " str) - -// Extra space to make it clear when blargg_err_str() isn't called to get -// printable version of error. At some point, I might prefix error strings -// with a code, to speed conversion to a code. -#define BLARGG_ERR_TYPE( str ) " " str - -// Error types to pass to BLARGG_ERR macro -#define BLARGG_ERR_GENERIC BLARGG_ERR_TYPE( "operation failed" ) -#define BLARGG_ERR_MEMORY BLARGG_ERR_TYPE( "out of memory" ) -#define BLARGG_ERR_CALLER BLARGG_ERR_TYPE( "internal usage bug" ) -#define BLARGG_ERR_INTERNAL BLARGG_ERR_TYPE( "internal bug" ) -#define BLARGG_ERR_LIMITATION BLARGG_ERR_TYPE( "exceeded limitation" ) - -#define BLARGG_ERR_FILE_MISSING BLARGG_ERR_TYPE( "file not found" ) -#define BLARGG_ERR_FILE_READ BLARGG_ERR_TYPE( "couldn't open file" ) -#define BLARGG_ERR_FILE_WRITE BLARGG_ERR_TYPE( "couldn't modify file" ) -#define BLARGG_ERR_FILE_IO BLARGG_ERR_TYPE( "read/write error" ) -#define BLARGG_ERR_FILE_FULL BLARGG_ERR_TYPE( "disk full" ) -#define BLARGG_ERR_FILE_EOF BLARGG_ERR_TYPE( "truncated file" ) - -#define BLARGG_ERR_FILE_TYPE BLARGG_ERR_TYPE( "wrong file type" ) -#define BLARGG_ERR_FILE_FEATURE BLARGG_ERR_TYPE( "unsupported file feature" ) -#define BLARGG_ERR_FILE_CORRUPT BLARGG_ERR_TYPE( "corrupt file" ) - -BLARGG_NAMESPACE_END - -#endif diff --git a/bsnes/smp/snes_spc/blargg_source.h b/bsnes/smp/snes_spc/blargg_source.h deleted file mode 100755 index a7d3e84a..00000000 --- a/bsnes/smp/snes_spc/blargg_source.h +++ /dev/null @@ -1,136 +0,0 @@ -/* Included at the beginning of library source files, AFTER all other #include -lines. Sets up helpful macros and services used in my source code. Since this -is only "active" in my source code, I don't have to worry about polluting the -global namespace with unprefixed names. */ - -// snes_spc 0.9.5 -#ifndef BLARGG_SOURCE_H -#define BLARGG_SOURCE_H - -#ifndef BLARGG_COMMON_H // optimization only - #include "blargg_common.h" -#endif -#include "blargg_errors.h" - -#include /* memcpy(), memset(), memmove() */ -#include /* offsetof() */ - -/* The following four macros are for debugging only. Some or all might be -defined to do nothing, depending on the circumstances. Described is what -happens when a particular macro is defined to do something. When defined to -do nothing, the macros do NOT evaluate their argument(s). */ - -/* If expr is false, prints file and line number, then aborts program. Meant -for checking internal state and consistency. A failed assertion indicates a bug -in MY code. - -void assert( bool expr ); */ -#include - -/* If expr is false, prints file and line number, then aborts program. Meant -for checking caller-supplied parameters and operations that are outside the -control of the module. A failed requirement probably indicates a bug in YOUR -code. - -void require( bool expr ); */ -#undef require -#define require( expr ) assert( expr ) - -/* Like printf() except output goes to debugging console/file. - -void dprintf( const char format [], ... ); */ -static inline void blargg_dprintf_( const char [], ... ) { } -#undef dprintf -#define dprintf (1) ? (void) 0 : blargg_dprintf_ - -/* If expr is false, prints file and line number to debug console/log, then -continues execution normally. Meant for flagging potential problems or things -that should be looked into, but that aren't serious problems. - -void check( bool expr ); */ -#undef check -#define check( expr ) ((void) 0) - -/* If expr yields non-NULL error string, returns it from current function, -otherwise continues normally. */ -#undef RETURN_ERR -#define RETURN_ERR( expr ) \ - do {\ - blargg_err_t blargg_return_err_ = (expr);\ - if ( blargg_return_err_ )\ - return blargg_return_err_;\ - } while ( 0 ) - -/* If ptr is NULL, returns out-of-memory error, otherwise continues normally. */ -#undef CHECK_ALLOC -#define CHECK_ALLOC( ptr ) \ - do {\ - if ( !(ptr) )\ - return blargg_err_memory;\ - } while ( 0 ) - -/* The usual min/max functions for built-in types. - -template T min( T x, T y ) { return x < y ? x : y; } -template T max( T x, T y ) { return x > y ? x : y; } */ -#define BLARGG_DEF_MIN_MAX( type ) \ - static inline type blargg_min( type x, type y ) { if ( y < x ) x = y; return x; }\ - static inline type blargg_max( type x, type y ) { if ( x < y ) x = y; return x; } - -BLARGG_DEF_MIN_MAX( int ) -BLARGG_DEF_MIN_MAX( unsigned ) -BLARGG_DEF_MIN_MAX( long ) -BLARGG_DEF_MIN_MAX( unsigned long ) -BLARGG_DEF_MIN_MAX( float ) -BLARGG_DEF_MIN_MAX( double ) - -#undef min -#define min blargg_min - -#undef max -#define max blargg_max - -// typedef unsigned char byte; -typedef unsigned char blargg_byte; -#undef byte -#define byte blargg_byte - -// Inform optimizer that if is unlikely to be taken -// if UNLIKELY( condition ) -#ifdef __GNUC__ - #define UNLIKELY( b ) (__builtin_expect( b, 0 )) -#else - #define UNLIKELY( b ) (b) -#endif - -#define BLARGG_CLEAR( p ) \ - memset( (p), 0, sizeof *(p) ) - -#ifndef BLARGG_EXPORT - #if defined (_WIN32) && BLARGG_BUILD_DLL - #define BLARGG_EXPORT __declspec(dllexport) - #elif defined (__GNUC__) - // can always set visibility, even when not building DLL - #define BLARGG_EXPORT __attribute__ ((visibility ("default"))) - #else - #define BLARGG_EXPORT - #endif -#endif - -#if BLARGG_LEGACY - #define BLARGG_CHECK_ALLOC CHECK_ALLOC - #define BLARGG_RETURN_ERR RETURN_ERR -#endif - -// Called after failed operation when overall operation may still complete OK. -// Only used by unit testing framework. -#undef ACK_FAILURE -#define ACK_FAILURE() ((void)0) - -/* BLARGG_SOURCE_BEGIN: If defined, #included, allowing redefition of dprintf etc. -and check */ -#ifdef BLARGG_SOURCE_BEGIN - #include BLARGG_SOURCE_BEGIN -#endif - -#endif diff --git a/bsnes/smp/snes_spc/spc.cpp b/bsnes/smp/snes_spc/spc.cpp deleted file mode 100755 index b0e77ad5..00000000 --- a/bsnes/smp/snes_spc/spc.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// snes_spc 0.9.5. http://www.slack.net/~ant/ - -#include "spc.h" - -#include "Snes_Spc.h" -#include "Spc_Filter.h" - -/* Copyright (C) 2004-2007 Shay Green. This module is free software; you -can redistribute it and/or modify it under the terms of the GNU Lesser -General Public License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. This -module is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more -details. You should have received a copy of the GNU Lesser General Public -License along with this module; if not, write to the Free Software Foundation, -Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include "blargg_source.h" - -spc_t* spc_new( void ) -{ - // be sure constants match - assert( spc_sample_rate == (int) spc_t::sample_rate ); - assert( spc_rom_size == (int) spc_t::rom_size ); - assert( spc_clock_rate == (int) spc_t::clock_rate ); - assert( spc_clocks_per_sample == (int) spc_t::clocks_per_sample ); - assert( spc_port_count == (int) spc_t::port_count ); - assert( spc_voice_count == (int) spc_t::voice_count ); - assert( spc_tempo_unit == (int) spc_t::tempo_unit ); - assert( spc_file_size == (int) spc_t::spc_file_size ); - #if !SPC_NO_COPY_STATE_FUNCS - assert( spc_state_size == (int) spc_t::state_size ); - #endif - - spc_t* s = new spc_t; - if ( s && s->init() ) - { - delete s; - s = 0; - } - return s; -} - -void spc_delete ( spc_t* s ) { delete s; } -void spc_init_rom ( spc_t* s, unsigned char const r [64] ) { s->init_rom( r ); } -int spc_read_samples ( spc_t* s, spc_sample_t out [], int n ) { return s->read_samples( out, n ); } -int spc_samples_avail ( spc_t const* s ) { return s->samples_avail(); } -void spc_reset ( spc_t* s ) { s->reset(); } -void spc_soft_reset ( spc_t* s ) { s->soft_reset(); } -int spc_read_port ( spc_t* s, spc_time_t t, int p ) { return s->read_port( t, p ); } -void spc_write_port ( spc_t* s, spc_time_t t, int p, int d ) { s->write_port( t, p, d ); } -void spc_end_frame ( spc_t* s, spc_time_t t ) { s->end_frame( t ); } -void spc_mute_voices ( spc_t* s, int mask ) { s->mute_voices( mask ); } -void spc_disable_surround( spc_t* s, int disable ) { s->disable_surround( disable ); } -void spc_set_tempo ( spc_t* s, int tempo ) { s->set_tempo( tempo ); } -spc_err_t spc_load_spc ( spc_t* s, void const* p, long n ) { return s->load_spc( p, n ); } -void spc_clear_echo ( spc_t* s ) { s->clear_echo(); } -spc_err_t spc_play ( spc_t* s, int count, short* out ) { return s->play( count, out ); } -spc_err_t spc_skip ( spc_t* s, int count ) { return s->skip( count ); } - -#if !SPC_NO_COPY_STATE_FUNCS -void spc_copy_state ( spc_t* s, unsigned char** p, spc_copy_func_t f ) { s->copy_state( p, f ); } -void spc_init_header ( void* spc_out ) { spc_t::init_header( spc_out ); } -void spc_save_spc ( spc_t* s, void* spc_out ) { s->save_spc( spc_out ); } -int spc_check_kon ( spc_t* s ) { return s->check_kon(); } -#endif - -#if BLARGG_LEGACY -void spc_set_output ( spc_t* s, spc_sample_t* p, int n ) { s->set_output( p, n ); } -int spc_sample_count ( spc_t const* s ) { return s->sample_count(); } -#endif - -SPC_Filter* spc_filter_new( void ) { return new SPC_Filter; } -void spc_filter_delete( SPC_Filter* f ) { delete f; } -void spc_filter_run( SPC_Filter* f, spc_sample_t* p, int s ) { f->run( p, s ); } -void spc_filter_clear( SPC_Filter* f ) { f->clear(); } -void spc_filter_set_gain( SPC_Filter* f, int gain ) { f->set_gain( gain ); } -void spc_filter_set_bass( SPC_Filter* f, int bass ) { f->set_bass( bass ); } diff --git a/bsnes/smp/snes_spc/spc.h b/bsnes/smp/snes_spc/spc.h deleted file mode 100755 index 4ef123b3..00000000 --- a/bsnes/smp/snes_spc/spc.h +++ /dev/null @@ -1,196 +0,0 @@ -/** SNES SPC-700 APU emulator and SPC music file player \file */ - -/* snes_spc 0.9.5 */ -#ifndef SPC_H -#define SPC_H - -#include - -#ifdef __cplusplus - extern "C" { -#endif - - -/** First parameter of most functions is spc_t*, or const spc_t* if nothing is -changed. Once one of these functions returns an error, the object should not -be used any further, other than to delete it. */ -typedef struct spc_t spc_t; - -/** Pointer to error, or NULL if function was successful. See error functions -below. */ -#ifndef spc_err_t /* (#ifndef allows better testing of library) */ - typedef const char* spc_err_t; -#endif - -enum { /** Sample pairs generated per second */ -spc_sample_rate = 32000 }; - - -/**** Creation/deletion ****/ - -/** Creates new SPC emulator. NULL if out of memory. */ -spc_t* spc_new( void ); - -/** Frees SPC emulator. OK to pass NULL. */ -void spc_delete( spc_t* ); - - -/**** SPC music file playback *****/ - -/** Loads SPC data into emulator */ -spc_err_t spc_load_spc( spc_t*, void const* spc_in, long size ); - -/** Clears echo region. Useful after loading an SPC as many have garbage in echo. */ -void spc_clear_echo( spc_t* ); - -/** Plays for count samples and writes samples to out. Discards samples if out -is NULL. Count must be a multiple of 2 since output is stereo. */ -spc_err_t spc_play( spc_t*, int count, short* out ); - -/** Skips count samples. Several times faster than spc_play(). */ -spc_err_t spc_skip( spc_t*, int count ); - - -/**** Sound options ****/ - -/** Mutes voices corresponding to non-zero bits in mask. */ -void spc_mute_voices( spc_t*, int mask ); -enum { spc_voice_count = 8 }; - -/** If true, prevents channels and global volumes from being phase-negated. -Some SPC music does this to achieve a pseudo-surround-sound effect that is -unpleasant to listen to through headphones. */ -void spc_disable_surround( spc_t*, int disable ); - -/** Sets music tempo, where spc_tempo_unit = normal, -spc_tempo_unit / 2 = half speed, etc. */ -void spc_set_tempo( spc_t*, int ); -enum { spc_tempo_unit = 0x100 }; - - -/**** Emulator use ****/ - -/** Clock count relative to current time frame */ -typedef int spc_time_t; - -enum { /** Number of clocks per second */ -spc_clock_rate = 1024000 }; - -enum { /** One sample pair is generated after this many clocks */ -spc_clocks_per_sample = 32 }; - -enum { spc_rom_size = 0x40 }; - -/** Sets IPL ROM data. Library does not include ROM data. Most SPC music files -don't need ROM, but a full emulator must provide this. */ -void spc_init_rom( spc_t*, const unsigned char rom [spc_rom_size] ); - -/** Resets SPC-700 to power-on state. */ -void spc_reset( spc_t* ); - -/** Emulates pressing reset switch on SNES. */ -void spc_soft_reset( spc_t* ); - -enum { spc_port_count = 4 /**< Number of ports, indexed from 0 */ }; - -/** Reads from port at specified time */ -int spc_read_port ( spc_t*, spc_time_t, int port ); - -/** Writes to port at specified time */ -void spc_write_port( spc_t*, spc_time_t, int port, int data ); - -/** Emulates to end_time, starts a new time frame at 0, and makes all resulting -samples available. */ -void spc_end_frame( spc_t*, spc_time_t end_time ); - -/** Number of samples available for reading. Always even. */ -int spc_samples_avail( const spc_t* ); - -/** 16-bit signed sample */ -typedef short spc_sample_t; - -/** Writes at most count samples to out, removes them from internal buffer, -and returns number of samples actually written. Output is in stereo, so -count must be even. */ -int spc_read_samples( spc_t*, spc_sample_t out [], int count ); - - -/**** State save/load ****/ - -/** Not available when using fast DSP */ - -/** Callback used for state save/load. Called with io value passed to -spc_copy_state(). State points to size bytes of data to save or load, -as desired. */ -typedef void (*spc_copy_func_t)( unsigned char** io, void* state, size_t size ); - -/** Saves/loads exact emulator state, using callback to save/load data. -The callback determines which action occurs. */ -void spc_copy_state( spc_t*, unsigned char** io, spc_copy_func_t ); -enum { spc_state_size = 67 * 1024 /**< maximum space needed when saving */ }; - -/** Writes minimal SPC file header to spc_out */ -void spc_init_header( void* spc_out ); - -/** Saves emulator state as SPC file data. Writes spc_file_size bytes to spc_out. -Does not set up SPC header; use spc_init_header() for that. */ -void spc_save_spc( spc_t*, void* spc_out ); -enum { spc_file_size = 0x10200 /**> spc_out must have this many bytes allocated */ }; - -/** Returns non-zero if new key-on events occurred since last check. Useful for -trimming silence while saving an SPC. */ -int spc_check_kon( spc_t* ); - - -/**** Sound filter ****/ - -/** Simple filter to more closely match sound output of SNES. Applies slight -high-pass and low-pass filtering. */ - -/** Filter functions take a pointer to this */ -typedef struct Spc_Filter Spc_Filter; - -/** Creates new filter. NULL if out of memory. */ -Spc_Filter* spc_filter_new( void ); - -/** Frees filter. OK to pass NULL. */ -void spc_filter_delete( Spc_Filter* ); - -/** Filters count samples of stereo sound in place. Count must be a multiple of 2. */ -void spc_filter_run( Spc_Filter*, spc_sample_t io [], int count ); - -/** Clears filter to silence */ -void spc_filter_clear( Spc_Filter* ); - -/** Sets gain (volume), where spc_filter_gain_unit is normal. Gains greater than -spc_filter_gain_unit are fine, since output is clamped to 16-bit sample range. */ -void spc_filter_set_gain( Spc_Filter*, int gain ); -enum { spc_filter_gain_unit = 0x100 }; - -/** Sets amount of bass (logarithmic scale) */ -void spc_filter_set_bass( Spc_Filter*, int bass ); -enum { - spc_filter_bass_none = 0, - spc_filter_bass_norm = 8, /**< normal amount of bass */ - spc_filter_bass_max = 31 -}; - - - - -/**** Deprecated ****/ - -/* Provided for compatibility with old code. May be removed from future release. */ - -typedef spc_t Snes_Spc; -typedef struct Spc_Filter SPC_Filter; - -void spc_set_output( spc_t*, spc_sample_t* out, int out_size ); - -int spc_sample_count( const spc_t* ); - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/bsnes/snes.hpp b/bsnes/snes.hpp deleted file mode 100755 index 9703e744..00000000 --- a/bsnes/snes.hpp +++ /dev/null @@ -1,86 +0,0 @@ -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -using namespace nall; - -#ifdef DEBUGGER - #define debugvirtual virtual -#else - #define debugvirtual -#endif - -namespace SNES { - typedef int8_t int8; - typedef int16_t int16; - typedef int32_t int32; - typedef int64_t int64; - typedef uint8_t uint8; - typedef uint16_t uint16; - typedef uint32_t uint32; - typedef uint64_t uint64; - - struct Processor { - cothread_t thread; - unsigned frequency; - int64 clock; - - inline void create(void (*entrypoint_)(), unsigned frequency_) { - if(thread) co_delete(thread); - thread = co_create(65536 * sizeof(void*), entrypoint_); - frequency = frequency_; - clock = 0; - } - - inline void serialize(serializer &s) { - s.integer(frequency); - s.integer(clock); - } - - inline Processor() : thread(0) {} - }; - - struct ChipDebugger { - virtual bool property(unsigned id, string &name, string &value) = 0; - }; - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #include - #include - #include -} - -namespace nall { - template<> struct has_size { enum { value = true }; }; - template<> struct has_size { enum { value = true }; }; -} - -#undef debugvirtual diff --git a/bsnes/sync.sh b/bsnes/sync.sh deleted file mode 100755 index 64964bc8..00000000 --- a/bsnes/sync.sh +++ /dev/null @@ -1,25 +0,0 @@ -synchronize() { - if [ -d ../asnes/"$1" ]; then - test -d "$1" && rm -r "$1" - cp -r ../asnes/"$1" ./"$1" - fi -} - -synchronize "audio" -synchronize "cartridge" -synchronize "cheat" -synchronize "chip" -synchronize "config" -synchronize "cpu/core" -synchronize "debugger" -synchronize "input" -synchronize "interface" -synchronize "libsnes" -synchronize "memory" -synchronize "ppu/counter" -synchronize "scheduler" -synchronize "smp/core" -synchronize "system" -synchronize "video" -synchronize "snes.hpp" -synchronize "Makefile" diff --git a/bsnes/system/serialization.cpp b/bsnes/system/serialization.cpp deleted file mode 100755 index da72b4bb..00000000 --- a/bsnes/system/serialization.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#ifdef SYSTEM_CPP - -serializer System::serialize() { - serializer s(serialize_size); - - unsigned signature = 0x31545342, version = Info::SerializerVersion, crc32 = cartridge.crc32(); - char description[512]; - memset(&description, 0, sizeof description); - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - serialize_all(s); - return s; -} - -bool System::unserialize(serializer &s) { - unsigned signature, version, crc32; - char description[512]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - if(signature != 0x31545342) return false; - if(version != Info::SerializerVersion) return false; -//if(crc32 != cartridge.crc32()) return false; - - reset(); - serialize_all(s); - return true; -} - -//======== -//internal -//======== - -void System::serialize(serializer &s) { - s.integer((unsigned&)region); - s.integer((unsigned&)expansion); -} - -void System::serialize_all(serializer &s) { - bus.serialize(s); - cartridge.serialize(s); - system.serialize(s); - cpu.serialize(s); - smp.serialize(s); - ppu.serialize(s); - dsp.serialize(s); - - if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) supergameboy.serialize(s); - if(cartridge.has_superfx()) superfx.serialize(s); - if(cartridge.has_sa1()) sa1.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_dsp1()) dsp1.serialize(s); - if(cartridge.has_dsp2()) dsp2.serialize(s); - if(cartridge.has_obc1()) obc1.serialize(s); - if(cartridge.has_st0010()) st0010.serialize(s); - if(cartridge.has_msu1()) msu1.serialize(s); - if(cartridge.has_serial()) serial.serialize(s); -} - -//called once upon cartridge load event: perform dry-run state save. -//determines exactly how many bytes are needed to save state for this cartridge, -//as amount varies per game (eg different RAM sizes, special chips, etc.) -void System::serialize_init() { - serializer s; - - unsigned signature = 0, version = 0, crc32 = 0; - char description[512]; - - s.integer(signature); - s.integer(version); - s.integer(crc32); - s.array(description); - - serialize_all(s); - serialize_size = s.size(); -} - -#endif diff --git a/bsnes/system/system.cpp b/bsnes/system/system.cpp deleted file mode 100755 index a2c8efc8..00000000 --- a/bsnes/system/system.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#include - -#define SYSTEM_CPP -namespace SNES { - -System system; - -#include -#include -#include - -#include