diff --git a/Makefile b/Makefile index 6724ed21..5a4406a7 100755 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ include nall/Makefile snes := snes -profile := asnes +profile := research ui := qt # compiler @@ -56,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/$(profile) $(objects) $(link)) + $(strip $(cpp) -o out/bsnes-$(profile) $(objects) $(link)) endif install: ifeq ($(platform),x) - install -D -m 755 out/$(profile) $(DESTDIR)$(prefix)/bin/$(profile) + install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes 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/$(profile) + rm $(DESTDIR)$(prefix)/bin/bsnes rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop endif diff --git a/qt/config.cpp b/qt/config.cpp index f502dfaf..cb5425cd 100755 --- a/qt/config.cpp +++ b/qt/config.cpp @@ -37,6 +37,7 @@ Configuration::Configuration() { //internal //======== + attach(system.profile = "", "system.profile"); attach(system.video = "", "system.video"); attach(system.audio = "", "system.audio"); attach(system.input = "", "system.input"); diff --git a/qt/config.hpp b/qt/config.hpp index a30ad275..07116f9d 100755 --- a/qt/config.hpp +++ b/qt/config.hpp @@ -1,6 +1,7 @@ class Configuration : public configuration { public: struct System { + string profile; string video, audio, input; bool crashedOnLastRun; unsigned speed; diff --git a/qt/data/icons-16x16/emblem-system.png b/qt/data/icons-16x16/emblem-system.png new file mode 100755 index 00000000..259ed26d Binary files /dev/null and b/qt/data/icons-16x16/emblem-system.png differ diff --git a/qt/resource/resource.qrc b/qt/resource/resource.qrc index e04489cb..95acae4c 100755 --- a/qt/resource/resource.qrc +++ b/qt/resource/resource.qrc @@ -17,6 +17,7 @@ ../data/icons-16x16/appointment-new.png ../data/icons-16x16/audio-volume-high.png ../data/icons-16x16/document-open.png + ../data/icons-16x16/emblem-system.png ../data/icons-16x16/folder.png ../data/icons-16x16/folder-new.png ../data/icons-16x16/go-up.png diff --git a/qt/settings/profile.cpp b/qt/settings/profile.cpp new file mode 100755 index 00000000..4fe2705d --- /dev/null +++ b/qt/settings/profile.cpp @@ -0,0 +1,92 @@ +#include "profile.moc" +ProfileSettingsWindow *profileSettingsWindow; + +ProfileSettingsWindow::ProfileSettingsWindow() { + layout = new QVBoxLayout; + layout->setMargin(Style::WindowMargin); + layout->setSpacing(0); + layout->setAlignment(Qt::AlignTop); + setLayout(layout); + + profileInfo = new QLabel( + "Profiles allow you to balance emulation accuracy against system performance.
" + "Note that you must restart bsnes for profile changes to take effect!
" + "Also, while save RAM is compatible between profiles, save states are not cross-compatible." + ); + layout->addWidget(profileInfo); + layout->addSpacing(Style::WidgetSpacing); + + profileResearch = new QRadioButton("Research"); + profileResearch->setStyleSheet("font-weight: bold; font-size: 12pt;"); + layout->addWidget(profileResearch); + + profileResearchInfo = new QLabel( + "System Requirements: A super-computer cooled by LN2.
" + "Maximum accuracy, no matter the cost.
" + "Use this mode for development purposes only." + ); + profileResearchInfo->setStyleSheet("margin-left: 22px;"); + layout->addWidget(profileResearchInfo); + layout->addSpacing(Style::WidgetSpacing); + + profileBaseline = new QRadioButton("Baseline (recommended)"); + profileBaseline->setStyleSheet("font-weight: bold; font-size: 12pt;"); + layout->addWidget(profileBaseline); + + profileBaselineInfo = new QLabel( + "System Requirements: Intel Core Solo or AMD Athlon 64 processor.
" + "Extreme accuracy with reasonable hardware requirements in mind.
" + "Very rarely, slight graphical glitches may appear." + ); + profileBaselineInfo->setStyleSheet("margin-left: 22px;"); + layout->addWidget(profileBaselineInfo); + layout->addSpacing(Style::WidgetSpacing); + + profilePerformance = new QRadioButton("Performance"); + profilePerformance->setStyleSheet("font-weight: bold; font-size: 12pt;"); + layout->addWidget(profilePerformance); + + profilePerformanceInfo = new QLabel( + "System Requirements: Intel Atom, Intel Pentium IV or AMD Athlon processor.
" + "High accuracy with reasonable sacrifices for performance.
" + "Sacrifices a small degree of compatibility to run full-speed on older hardware.
" + "Use this mode only if baseline is too slow, or if you are running on battery power." + ); + profilePerformanceInfo->setStyleSheet("margin-left: 22px;"); + layout->addWidget(profilePerformanceInfo); + + if(config().system.profile == "research") { + profileResearch->setChecked(true); + } else if(config().system.profile == "baseline") { + profileBaseline->setChecked(true); + } else if(config().system.profile == "performance") { + profilePerformance->setChecked(true); + } else { + config().system.profile = "baseline"; + profileBaseline->setChecked(true); + QMessageBox::information(0, "First-Run Notice", + "Note: bsnes contains multiple emulation profiles.

" + "If bsnes runs too slowly, you can double the speed by using the " + "'Performance' profile; or if you want even more accuracy, you can use the " + "'Research' profile.

" + "Feel free to experiment. You can select different profiles via:
" + "Settings -> Configuration -> Profile" + ); + } + + connect(profileResearch, SIGNAL(pressed()), this, SLOT(setResearchProfile())); + connect(profileBaseline, SIGNAL(pressed()), this, SLOT(setBaselineProfile())); + connect(profilePerformance, SIGNAL(pressed()), this, SLOT(setPerformanceProfile())); +} + +void ProfileSettingsWindow::setResearchProfile() { + config().system.profile = "research"; +} + +void ProfileSettingsWindow::setBaselineProfile() { + config().system.profile = "baseline"; +} + +void ProfileSettingsWindow::setPerformanceProfile() { + config().system.profile = "performance"; +} diff --git a/qt/settings/profile.moc.hpp b/qt/settings/profile.moc.hpp new file mode 100755 index 00000000..16f06e53 --- /dev/null +++ b/qt/settings/profile.moc.hpp @@ -0,0 +1,22 @@ +class ProfileSettingsWindow : public QWidget { + Q_OBJECT + +public: + QVBoxLayout *layout; + QLabel *profileInfo; + QRadioButton *profileResearch; + QLabel *profileResearchInfo; + QRadioButton *profileBaseline; + QLabel *profileBaselineInfo; + QRadioButton *profilePerformance; + QLabel *profilePerformanceInfo; + + ProfileSettingsWindow(); + +private slots: + void setResearchProfile(); + void setBaselineProfile(); + void setPerformanceProfile(); +}; + +extern ProfileSettingsWindow *profileSettingsWindow; diff --git a/qt/settings/settings.cpp b/qt/settings/settings.cpp index edb6ced7..ef67685b 100755 --- a/qt/settings/settings.cpp +++ b/qt/settings/settings.cpp @@ -1,5 +1,6 @@ #include "../ui-base.hpp" +#include "profile.cpp" #include "video.cpp" #include "audio.cpp" #include "input.cpp" @@ -21,12 +22,18 @@ SettingsWindow::SettingsWindow() { layout->setSpacing(Style::WidgetSpacing); setLayout(layout); + profileSettingsWindow = new ProfileSettingsWindow; videoSettingsWindow = new VideoSettingsWindow; audioSettingsWindow = new AudioSettingsWindow; inputSettingsWindow = new InputSettingsWindow; pathSettingsWindow = new PathSettingsWindow; advancedSettingsWindow = new AdvancedSettingsWindow; + profileArea = new QScrollArea; + profileArea->setWidget(profileSettingsWindow); + profileArea->setFrameStyle(0); + profileArea->setWidgetResizable(true); + videoArea = new QScrollArea; videoArea->setWidget(videoSettingsWindow); videoArea->setFrameStyle(0); @@ -53,6 +60,7 @@ SettingsWindow::SettingsWindow() { advancedArea->setWidgetResizable(true); tab = new QTabWidget; + tab->addTab(profileArea, QIcon(":/16x16/emblem-system.png"), "Profile"); tab->addTab(videoArea, QIcon(":/16x16/video-display.png"), "Video"); tab->addTab(audioArea, QIcon(":/16x16/audio-volume-high.png"), "Audio"); tab->addTab(inputArea, QIcon(":/16x16/input-gaming.png"), "Input"); diff --git a/qt/settings/settings.moc.hpp b/qt/settings/settings.moc.hpp index 3a271e76..f337112b 100755 --- a/qt/settings/settings.moc.hpp +++ b/qt/settings/settings.moc.hpp @@ -4,6 +4,7 @@ class SettingsWindow : public Window { public: QVBoxLayout *layout; QTabWidget *tab; + QScrollArea *profileArea; QScrollArea *videoArea; QScrollArea *audioArea; QScrollArea *inputArea; diff --git a/qt/ui-base.hpp b/qt/ui-base.hpp index 4156741e..9ca2d625 100755 --- a/qt/ui-base.hpp +++ b/qt/ui-base.hpp @@ -63,6 +63,7 @@ using namespace ruby; #include "movie/movie.hpp" #include "settings/settings.moc.hpp" +#include "settings/profile.moc.hpp" #include "settings/video.moc.hpp" #include "settings/audio.moc.hpp" #include "settings/input.moc.hpp" diff --git a/snes/Makefile b/snes/Makefile index 562a6165..06f9f91f 100755 --- a/snes/Makefile +++ b/snes/Makefile @@ -10,22 +10,22 @@ snes_objects += snes-obc1 snes-st0010 snes-st0011 snes-st0018 snes_objects += snes-msu1 snes-serial objects += $(snes_objects) -ifeq ($(profile),asnes) - flags += -DPROFILE_ASNES +ifeq ($(profile),research) + flags += -DPROFILE_RESEARCH snescpu := $(snes)/cpu snessmp := $(snes)/smp snesdsp := $(snes)/dsp snesppu := $(snes)/ppu -else ifeq ($(profile),bsnes) - flags += -DPROFILE_BSNES +else ifeq ($(profile),baseline) + flags += -DPROFILE_BASELINE snescpu := $(snes)/cpu snessmp := $(snes)/smp snesdsp := $(snes)/fast/dsp snesppu := $(snes)/fast/ppu -else ifeq ($(profile),csnes) - flags += -DPROFILE_CSNES +else ifeq ($(profile),performance) + flags += -DPROFILE_PERFORMANCE snescpu := $(snes)/fast/cpu - snessmp := $(snes)/fast/smp + snessmp := $(snes)/smp snesdsp := $(snes)/fast/dsp snesppu := $(snes)/fast/ppu endif @@ -37,10 +37,10 @@ obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/ obj/snes-memory.o : $(snes)/memory/memory.cpp $(call rwildcard,$(snes)/memory/) obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/) obj/snes-smpcore.o : $(snes)/smp/core/core.cpp $(call rwildcard,$(snes)/smp/core/) -obj/snes-cpu.o : $(snescpu)/cpu.cpp $(call rwildcard,$(snescpu)/cpu/) -obj/snes-smp.o : $(snessmp)/smp.cpp $(call rwildcard,$(snessmp)/smp/) -obj/snes-dsp.o : $(snesdsp)/dsp.cpp $(call rwildcard,$(snesdsp)/dsp/) -obj/snes-ppu.o : $(snesppu)/ppu.cpp $(call rwildcard,$(snesppu)/ppu/) +obj/snes-cpu.o : $(snescpu)/cpu.cpp $(call rwildcard,$(snescpu)/) +obj/snes-smp.o : $(snessmp)/smp.cpp $(call rwildcard,$(snessmp)/) +obj/snes-dsp.o : $(snesdsp)/dsp.cpp $(call rwildcard,$(snesdsp)/) +obj/snes-ppu.o : $(snesppu)/ppu.cpp $(call rwildcard,$(snesppu)/) obj/snes-cartridge.o: $(snes)/cartridge/cartridge.cpp $(call rwilddcard,$(snes)/cartridge/) obj/snes-cheat.o : $(snes)/cheat/cheat.cpp $(call rwildcard,$(snes)/cheat/) diff --git a/snes/chip/cx4/opcodes.cpp b/snes/chip/cx4/opcodes.cpp index 28f62c1d..639097b1 100755 --- a/snes/chip/cx4/opcodes.cpp +++ b/snes/chip/cx4/opcodes.cpp @@ -48,6 +48,7 @@ void Cx4::op10() { r4 = r0 & 0x1ff; if(r1 & 0x8000)r1 |= ~0x7fff; + else r1 &= 0x7fff; mul(cos(r4), r1, r5, r2); r5 = (r5 >> 16) & 0xff; diff --git a/snes/cpu/cpu.cpp b/snes/cpu/cpu.cpp index 378e0a34..cacfd652 100755 --- a/snes/cpu/cpu.cpp +++ b/snes/cpu/cpu.cpp @@ -26,11 +26,19 @@ void CPU::step(unsigned clocks) { } void CPU::synchronize_smp() { - if(smp.clock < 0) co_switch(smp.thread); + if(SMP::Threaded == true) { + if(smp.clock < 0) co_switch(smp.thread); + } else { + while(smp.clock < 0) smp.enter(); + } } void CPU::synchronize_ppu() { - if(ppu.clock < 0) co_switch(ppu.thread); + if(PPU::Threaded == true) { + if(ppu.clock < 0) co_switch(ppu.thread); + } else { + while(ppu.clock < 0) ppu.enter(); + } } void CPU::synchronize_coprocessor() { diff --git a/snes/cpu/cpu.hpp b/snes/cpu/cpu.hpp index 60ef1af8..2d55c10c 100755 --- a/snes/cpu/cpu.hpp +++ b/snes/cpu/cpu.hpp @@ -1,5 +1,6 @@ class CPU : public Processor, public CPUcore, public PPUcounter, public MMIO { public: + enum : bool { Threaded = true }; array coprocessors; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_smp(); @@ -12,6 +13,7 @@ public: alwaysinline uint8 port_read(uint8 port) { return apu_port[port & 3]; } alwaysinline void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; } + void enter(); void power(); void reset(); @@ -117,7 +119,6 @@ private: } alu; static void Enter(); - void enter(); void op_irq(); debugvirtual void op_step(); diff --git a/snes/dsp/dsp.cpp b/snes/dsp/dsp.cpp index 52edd1cf..079b76d5 100755 --- a/snes/dsp/dsp.cpp +++ b/snes/dsp/dsp.cpp @@ -30,7 +30,11 @@ void DSP::step(unsigned clocks) { } void DSP::synchronize_smp() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread); + if(SMP::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread); + } else { + while(clock >= 0) smp.enter(); + } } void DSP::Enter() { dsp.enter(); } diff --git a/snes/dsp/dsp.hpp b/snes/dsp/dsp.hpp index f2c47f4e..a8f13c2e 100755 --- a/snes/dsp/dsp.hpp +++ b/snes/dsp/dsp.hpp @@ -1,11 +1,13 @@ class DSP : public Processor { public: + enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_smp(); uint8 read(uint8 addr); void write(uint8 addr, uint8 data); + void enter(); void power(); void reset(); @@ -165,7 +167,6 @@ private: //dsp static void Enter(); - void enter(); void tick(); friend class DSPDebugger; diff --git a/snes/fast/cpu/core/algorithms.cpp b/snes/fast/cpu/core/algorithms.cpp deleted file mode 100755 index 9b6ba032..00000000 --- a/snes/fast/cpu/core/algorithms.cpp +++ /dev/null @@ -1,331 +0,0 @@ -#ifdef CPUCORE_CPP - -inline void CPUcore::op_adc_b() { - int result; - - if(!regs.p.d) { - result = regs.a.l + rd.l + regs.p.c; - } else { - result = (regs.a.l & 0x0f) + (rd.l & 0x0f) + (regs.p.c << 0); - if(result > 0x09) result += 0x06; - regs.p.c = result > 0x0f; - result = (regs.a.l & 0xf0) + (rd.l & 0xf0) + (regs.p.c << 4) + (result & 0x0f); - } - - regs.p.v = ~(regs.a.l ^ rd.l) & (regs.a.l ^ result) & 0x80; - if(regs.p.d && result > 0x9f) result += 0x60; - regs.p.c = result > 0xff; - regs.p.n = result & 0x80; - regs.p.z = (uint8_t)result == 0; - - regs.a.l = result; -} - -inline void CPUcore::op_adc_w() { - int result; - - if(!regs.p.d) { - result = regs.a.w + rd.w + regs.p.c; - } else { - result = (regs.a.w & 0x000f) + (rd.w & 0x000f) + (regs.p.c << 0); - if(result > 0x0009) result += 0x0006; - regs.p.c = result > 0x000f; - result = (regs.a.w & 0x00f0) + (rd.w & 0x00f0) + (regs.p.c << 4) + (result & 0x000f); - if(result > 0x009f) result += 0x0060; - regs.p.c = result > 0x00ff; - result = (regs.a.w & 0x0f00) + (rd.w & 0x0f00) + (regs.p.c << 8) + (result & 0x00ff); - if(result > 0x09ff) result += 0x0600; - regs.p.c = result > 0x0fff; - result = (regs.a.w & 0xf000) + (rd.w & 0xf000) + (regs.p.c << 12) + (result & 0x0fff); - } - - regs.p.v = ~(regs.a.w ^ rd.w) & (regs.a.w ^ result) & 0x8000; - if(regs.p.d && result > 0x9fff) result += 0x6000; - regs.p.c = result > 0xffff; - regs.p.n = result & 0x8000; - regs.p.z = (uint16_t)result == 0; - - regs.a.w = result; -} - -inline void CPUcore::op_and_b() { - regs.a.l &= rd.l; - regs.p.n = regs.a.l & 0x80; - regs.p.z = regs.a.l == 0; -} - -inline void CPUcore::op_and_w() { - regs.a.w &= rd.w; - regs.p.n = regs.a.w & 0x8000; - regs.p.z = regs.a.w == 0; -} - -inline void CPUcore::op_bit_b() { - regs.p.n = rd.l & 0x80; - regs.p.v = rd.l & 0x40; - regs.p.z = (rd.l & regs.a.l) == 0; -} - -inline void CPUcore::op_bit_w() { - regs.p.n = rd.w & 0x8000; - regs.p.v = rd.w & 0x4000; - regs.p.z = (rd.w & regs.a.w) == 0; -} - -inline void CPUcore::op_cmp_b() { - int r = regs.a.l - rd.l; - regs.p.n = r & 0x80; - regs.p.z = (uint8)r == 0; - regs.p.c = r >= 0; -} - -inline void CPUcore::op_cmp_w() { - int r = regs.a.w - rd.w; - regs.p.n = r & 0x8000; - regs.p.z = (uint16)r == 0; - regs.p.c = r >= 0; -} - -inline void CPUcore::op_cpx_b() { - int r = regs.x.l - rd.l; - regs.p.n = r & 0x80; - regs.p.z = (uint8)r == 0; - regs.p.c = r >= 0; -} - -inline void CPUcore::op_cpx_w() { - int r = regs.x.w - rd.w; - regs.p.n = r & 0x8000; - regs.p.z = (uint16)r == 0; - regs.p.c = r >= 0; -} - -inline void CPUcore::op_cpy_b() { - int r = regs.y.l - rd.l; - regs.p.n = r & 0x80; - regs.p.z = (uint8)r == 0; - regs.p.c = r >= 0; -} - -inline void CPUcore::op_cpy_w() { - int r = regs.y.w - rd.w; - regs.p.n = r & 0x8000; - regs.p.z = (uint16)r == 0; - regs.p.c = r >= 0; -} - -inline void CPUcore::op_eor_b() { - regs.a.l ^= rd.l; - regs.p.n = regs.a.l & 0x80; - regs.p.z = regs.a.l == 0; -} - -inline void CPUcore::op_eor_w() { - regs.a.w ^= rd.w; - regs.p.n = regs.a.w & 0x8000; - regs.p.z = regs.a.w == 0; -} - -inline void CPUcore::op_lda_b() { - regs.a.l = rd.l; - regs.p.n = regs.a.l & 0x80; - regs.p.z = regs.a.l == 0; -} - -inline void CPUcore::op_lda_w() { - regs.a.w = rd.w; - regs.p.n = regs.a.w & 0x8000; - regs.p.z = regs.a.w == 0; -} - -inline void CPUcore::op_ldx_b() { - regs.x.l = rd.l; - regs.p.n = regs.x.l & 0x80; - regs.p.z = regs.x.l == 0; -} - -inline void CPUcore::op_ldx_w() { - regs.x.w = rd.w; - regs.p.n = regs.x.w & 0x8000; - regs.p.z = regs.x.w == 0; -} - -inline void CPUcore::op_ldy_b() { - regs.y.l = rd.l; - regs.p.n = regs.y.l & 0x80; - regs.p.z = regs.y.l == 0; -} - -inline void CPUcore::op_ldy_w() { - regs.y.w = rd.w; - regs.p.n = regs.y.w & 0x8000; - regs.p.z = regs.y.w == 0; -} - -inline void CPUcore::op_ora_b() { - regs.a.l |= rd.l; - regs.p.n = regs.a.l & 0x80; - regs.p.z = regs.a.l == 0; -} - -inline void CPUcore::op_ora_w() { - regs.a.w |= rd.w; - regs.p.n = regs.a.w & 0x8000; - regs.p.z = regs.a.w == 0; -} - -inline void CPUcore::op_sbc_b() { - int result; - rd.l ^= 0xff; - - if(!regs.p.d) { - result = regs.a.l + rd.l + regs.p.c; - } else { - result = (regs.a.l & 0x0f) + (rd.l & 0x0f) + (regs.p.c << 0); - if(result <= 0x0f) result -= 0x06; - regs.p.c = result > 0x0f; - result = (regs.a.l & 0xf0) + (rd.l & 0xf0) + (regs.p.c << 4) + (result & 0x0f); - } - - regs.p.v = ~(regs.a.l ^ rd.l) & (regs.a.l ^ result) & 0x80; - if(regs.p.d && result <= 0xff) result -= 0x60; - regs.p.c = result > 0xff; - regs.p.n = result & 0x80; - regs.p.z = (uint8_t)result == 0; - - regs.a.l = result; -} - -inline void CPUcore::op_sbc_w() { - int result; - rd.w ^= 0xffff; - - if(!regs.p.d) { - result = regs.a.w + rd.w + regs.p.c; - } else { - result = (regs.a.w & 0x000f) + (rd.w & 0x000f) + (regs.p.c << 0); - if(result <= 0x000f) result -= 0x0006; - regs.p.c = result > 0x000f; - result = (regs.a.w & 0x00f0) + (rd.w & 0x00f0) + (regs.p.c << 4) + (result & 0x000f); - if(result <= 0x00ff) result -= 0x0060; - regs.p.c = result > 0x00ff; - result = (regs.a.w & 0x0f00) + (rd.w & 0x0f00) + (regs.p.c << 8) + (result & 0x00ff); - if(result <= 0x0fff) result -= 0x0600; - regs.p.c = result > 0x0fff; - result = (regs.a.w & 0xf000) + (rd.w & 0xf000) + (regs.p.c << 12) + (result & 0x0fff); - } - - regs.p.v = ~(regs.a.w ^ rd.w) & (regs.a.w ^ result) & 0x8000; - if(regs.p.d && result <= 0xffff) result -= 0x6000; - regs.p.c = result > 0xffff; - regs.p.n = result & 0x8000; - regs.p.z = (uint16_t)result == 0; - - regs.a.w = result; -} - -inline void CPUcore::op_inc_b() { - rd.l++; - regs.p.n = rd.l & 0x80; - regs.p.z = rd.l == 0; -} - -inline void CPUcore::op_inc_w() { - rd.w++; - regs.p.n = rd.w & 0x8000; - regs.p.z = rd.w == 0; -} - -inline void CPUcore::op_dec_b() { - rd.l--; - regs.p.n = rd.l & 0x80; - regs.p.z = rd.l == 0; -} - -inline void CPUcore::op_dec_w() { - rd.w--; - regs.p.n = rd.w & 0x8000; - regs.p.z = rd.w == 0; -} - -inline void CPUcore::op_asl_b() { - regs.p.c = rd.l & 0x80; - rd.l <<= 1; - regs.p.n = rd.l & 0x80; - regs.p.z = rd.l == 0; -} - -inline void CPUcore::op_asl_w() { - regs.p.c = rd.w & 0x8000; - rd.w <<= 1; - regs.p.n = rd.w & 0x8000; - regs.p.z = rd.w == 0; -} - -inline void CPUcore::op_lsr_b() { - regs.p.c = rd.l & 1; - rd.l >>= 1; - regs.p.n = rd.l & 0x80; - regs.p.z = rd.l == 0; -} - -inline void CPUcore::op_lsr_w() { - regs.p.c = rd.w & 1; - rd.w >>= 1; - regs.p.n = rd.w & 0x8000; - regs.p.z = rd.w == 0; -} - -inline void CPUcore::op_rol_b() { - unsigned carry = (unsigned)regs.p.c; - regs.p.c = rd.l & 0x80; - rd.l = (rd.l << 1) | carry; - regs.p.n = rd.l & 0x80; - regs.p.z = rd.l == 0; -} - -inline void CPUcore::op_rol_w() { - unsigned carry = (unsigned)regs.p.c; - regs.p.c = rd.w & 0x8000; - rd.w = (rd.w << 1) | carry; - regs.p.n = rd.w & 0x8000; - regs.p.z = rd.w == 0; -} - -inline void CPUcore::op_ror_b() { - unsigned carry = (unsigned)regs.p.c << 7; - regs.p.c = rd.l & 1; - rd.l = carry | (rd.l >> 1); - regs.p.n = rd.l & 0x80; - regs.p.z = rd.l == 0; -} - -inline void CPUcore::op_ror_w() { - unsigned carry = (unsigned)regs.p.c << 15; - regs.p.c = rd.w & 1; - rd.w = carry | (rd.w >> 1); - regs.p.n = rd.w & 0x8000; - regs.p.z = rd.w == 0; -} - -inline void CPUcore::op_trb_b() { - regs.p.z = (rd.l & regs.a.l) == 0; - rd.l &= ~regs.a.l; -} - -inline void CPUcore::op_trb_w() { - regs.p.z = (rd.w & regs.a.w) == 0; - rd.w &= ~regs.a.w; -} - -inline void CPUcore::op_tsb_b() { - regs.p.z = (rd.l & regs.a.l) == 0; - rd.l |= regs.a.l; -} - -inline void CPUcore::op_tsb_w() { - regs.p.z = (rd.w & regs.a.w) == 0; - rd.w |= regs.a.w; -} - -#endif diff --git a/snes/fast/cpu/core/core.cpp b/snes/fast/cpu/core/core.cpp deleted file mode 100755 index aae4ba67..00000000 --- a/snes/fast/cpu/core/core.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include - -#define CPUCORE_CPP -namespace SNES { - -#include "serialization.cpp" -#include "algorithms.cpp" -#include "disassembler/disassembler.cpp" - -#define L last_cycle(); -#define A 0 -#define X 1 -#define Y 2 -#define Z 3 -#define S 4 -#define D 5 -#define call(op) (this->*op)() - -#include "opcode_read.cpp" -#include "opcode_write.cpp" -#include "opcode_rmw.cpp" -#include "opcode_pc.cpp" -#include "opcode_misc.cpp" -#include "table.cpp" - -#undef L -#undef A -#undef X -#undef Y -#undef Z -#undef S -#undef D -#undef call - -//immediate, 2-cycle opcodes with I/O cycle will become bus read -//when an IRQ is to be triggered immediately after opcode completion. -//this affects the following opcodes: -// clc, cld, cli, clv, sec, sed, sei, -// tax, tay, txa, txy, tya, tyx, -// tcd, tcs, tdc, tsc, tsx, txs, -// inc, inx, iny, dec, dex, dey, -// asl, lsr, rol, ror, nop, xce. -alwaysinline void CPUcore::op_io_irq() { - if(interrupt_pending()) { - //modify I/O cycle to bus read cycle, do not increment PC - op_read(regs.pc.d); - } else { - op_io(); - } -} - -alwaysinline void CPUcore::op_io_cond2() { - if(regs.d.l != 0x00) { - op_io(); - } -} - -alwaysinline void CPUcore::op_io_cond4(uint16 x, uint16 y) { - if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) { - op_io(); - } -} - -alwaysinline void CPUcore::op_io_cond6(uint16 addr) { - if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) { - op_io(); - } -} - -CPUcore::CPUcore() { - initialize_opcode_table(); -} - -} diff --git a/snes/fast/cpu/core/core.hpp b/snes/fast/cpu/core/core.hpp deleted file mode 100755 index 6d1314aa..00000000 --- a/snes/fast/cpu/core/core.hpp +++ /dev/null @@ -1,217 +0,0 @@ -class CPUcore { -public: - #include "registers.hpp" - #include "memory.hpp" - #include "disassembler/disassembler.hpp" - - regs_t regs; - reg24_t aa, rd; - uint8_t sp, dp; - - virtual void op_io() = 0; - virtual uint8_t op_read(uint32_t addr) = 0; - virtual void op_write(uint32_t addr, uint8_t data) = 0; - virtual void last_cycle() = 0; - virtual bool interrupt_pending() = 0; - - void op_io_irq(); - void op_io_cond2(); - void op_io_cond4(uint16 x, uint16 y); - void op_io_cond6(uint16 addr); - - void op_adc_b(); - void op_adc_w(); - void op_and_b(); - void op_and_w(); - void op_bit_b(); - void op_bit_w(); - void op_cmp_b(); - void op_cmp_w(); - void op_cpx_b(); - void op_cpx_w(); - void op_cpy_b(); - void op_cpy_w(); - void op_eor_b(); - void op_eor_w(); - void op_lda_b(); - void op_lda_w(); - void op_ldx_b(); - void op_ldx_w(); - void op_ldy_b(); - void op_ldy_w(); - void op_ora_b(); - void op_ora_w(); - void op_sbc_b(); - void op_sbc_w(); - - void op_inc_b(); - void op_inc_w(); - void op_dec_b(); - void op_dec_w(); - void op_asl_b(); - void op_asl_w(); - void op_lsr_b(); - void op_lsr_w(); - void op_rol_b(); - void op_rol_w(); - void op_ror_b(); - void op_ror_w(); - void op_trb_b(); - void op_trb_w(); - void op_tsb_b(); - void op_tsb_w(); - - template void op_read_const_b(); - template void op_read_const_w(); - void op_read_bit_const_b(); - void op_read_bit_const_w(); - template void op_read_addr_b(); - template void op_read_addr_w(); - template void op_read_addrx_b(); - template void op_read_addrx_w(); - template void op_read_addry_b(); - template void op_read_addry_w(); - template void op_read_long_b(); - template void op_read_long_w(); - template void op_read_longx_b(); - template void op_read_longx_w(); - template void op_read_dp_b(); - template void op_read_dp_w(); - template void op_read_dpr_b(); - template void op_read_dpr_w(); - template void op_read_idp_b(); - template void op_read_idp_w(); - template void op_read_idpx_b(); - template void op_read_idpx_w(); - template void op_read_idpy_b(); - template void op_read_idpy_w(); - template void op_read_ildp_b(); - template void op_read_ildp_w(); - template void op_read_ildpy_b(); - template void op_read_ildpy_w(); - template void op_read_sr_b(); - template void op_read_sr_w(); - template void op_read_isry_b(); - template void op_read_isry_w(); - - template void op_write_addr_b(); - template void op_write_addr_w(); - template void op_write_addrr_b(); - template void op_write_addrr_w(); - template void op_write_longr_b(); - template void op_write_longr_w(); - template void op_write_dp_b(); - template void op_write_dp_w(); - template void op_write_dpr_b(); - template void op_write_dpr_w(); - void op_sta_idp_b(); - void op_sta_idp_w(); - void op_sta_ildp_b(); - void op_sta_ildp_w(); - void op_sta_idpx_b(); - void op_sta_idpx_w(); - void op_sta_idpy_b(); - void op_sta_idpy_w(); - void op_sta_ildpy_b(); - void op_sta_ildpy_w(); - void op_sta_sr_b(); - void op_sta_sr_w(); - void op_sta_isry_b(); - void op_sta_isry_w(); - - template void op_adjust_imm_b(); - template void op_adjust_imm_w(); - void op_asl_imm_b(); - void op_asl_imm_w(); - void op_lsr_imm_b(); - void op_lsr_imm_w(); - void op_rol_imm_b(); - void op_rol_imm_w(); - void op_ror_imm_b(); - void op_ror_imm_w(); - template void op_adjust_addr_b(); - template void op_adjust_addr_w(); - template void op_adjust_addrx_b(); - template void op_adjust_addrx_w(); - template void op_adjust_dp_b(); - template void op_adjust_dp_w(); - template void op_adjust_dpx_b(); - template void op_adjust_dpx_w(); - - template void op_branch(); - void op_bra(); - void op_brl(); - void op_jmp_addr(); - void op_jmp_long(); - void op_jmp_iaddr(); - void op_jmp_iaddrx(); - void op_jmp_iladdr(); - void op_jsr_addr(); - void op_jsr_long_e(); - void op_jsr_long_n(); - void op_jsr_iaddrx_e(); - void op_jsr_iaddrx_n(); - void op_rti_e(); - void op_rti_n(); - void op_rts(); - void op_rtl_e(); - void op_rtl_n(); - - void op_nop(); - void op_wdm(); - void op_xba(); - template void op_move_b(); - template void op_move_w(); - template void op_interrupt_e(); - template void op_interrupt_n(); - void op_stp(); - void op_wai(); - void op_xce(); - template void op_flag(); - template void op_pflag_e(); - template void op_pflag_n(); - template void op_transfer_b(); - template void op_transfer_w(); - void op_tcs_e(); - void op_tcs_n(); - void op_tsx_b(); - void op_tsx_w(); - void op_txs_e(); - void op_txs_n(); - template void op_push_b(); - template void op_push_w(); - void op_phd_e(); - void op_phd_n(); - void op_phb(); - void op_phk(); - void op_php(); - template void op_pull_b(); - template void op_pull_w(); - void op_pld_e(); - void op_pld_n(); - void op_plb(); - void op_plp_e(); - void op_plp_n(); - void op_pea_e(); - void op_pea_n(); - void op_pei_e(); - void op_pei_n(); - void op_per_e(); - void op_per_n(); - - void (CPUcore::**opcode_table)(); - void (CPUcore::*op_table[256 * 5])(); - void initialize_opcode_table(); - void update_table(); - - enum { - table_EM = 0, // 8-bit accumulator, 8-bit index (emulation mode) - table_MX = 256, // 8-bit accumulator, 8-bit index - table_Mx = 512, // 8-bit accumulator, 16-bit index - table_mX = 768, //16-bit accumulator, 8-bit index - table_mx = 1024, //16-bit accumulator, 16-bit index - }; - - void core_serialize(serializer&); - CPUcore(); -}; diff --git a/snes/fast/cpu/core/disassembler/disassembler.cpp b/snes/fast/cpu/core/disassembler/disassembler.cpp deleted file mode 100755 index 030b3ab5..00000000 --- a/snes/fast/cpu/core/disassembler/disassembler.cpp +++ /dev/null @@ -1,483 +0,0 @@ -#ifdef CPUCORE_CPP - -uint8 CPUcore::dreadb(uint32 addr) { - if((addr & 0x40ffff) >= 0x2000 && (addr & 0x40ffff) <= 0x5fff) { - //$[00-3f|80-bf]:[2000-5fff] - //do not read MMIO registers within debugger - return 0x00; - } - return bus.read(addr); -} - -uint16 CPUcore::dreadw(uint32 addr) { - uint16 r; - r = dreadb((addr + 0) & 0xffffff) << 0; - r |= dreadb((addr + 1) & 0xffffff) << 8; - return r; -} - -uint32 CPUcore::dreadl(uint32 addr) { - uint32 r; - r = dreadb((addr + 0) & 0xffffff) << 0; - r |= dreadb((addr + 1) & 0xffffff) << 8; - r |= dreadb((addr + 2) & 0xffffff) << 16; - return r; -} - -uint32 CPUcore::decode(uint8 offset_type, uint32 addr) { - uint32 r = 0; - - switch(offset_type) { - case OPTYPE_DP: - r = (regs.d + (addr & 0xffff)) & 0xffff; - break; - case OPTYPE_DPX: - r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff; - break; - case OPTYPE_DPY: - r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff; - break; - case OPTYPE_IDP: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr); - break; - case OPTYPE_IDPX: - addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr); - break; - case OPTYPE_IDPY: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr) + regs.y; - break; - case OPTYPE_ILDP: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = dreadl(addr); - break; - case OPTYPE_ILDPY: - addr = (regs.d + (addr & 0xffff)) & 0xffff; - r = dreadl(addr) + regs.y; - break; - case OPTYPE_ADDR: - r = (regs.db << 16) + (addr & 0xffff); - break; - case OPTYPE_ADDR_PC: - r = (regs.pc.b << 16) + (addr & 0xffff); - break; - case OPTYPE_ADDRX: - r = (regs.db << 16) + (addr & 0xffff) + regs.x; - break; - case OPTYPE_ADDRY: - r = (regs.db << 16) + (addr & 0xffff) + regs.y; - break; - case OPTYPE_IADDR_PC: - r = (regs.pc.b << 16) + (addr & 0xffff); - break; - case OPTYPE_IADDRX: - r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff); - break; - case OPTYPE_ILADDR: - r = addr; - break; - case OPTYPE_LONG: - r = addr; - break; - case OPTYPE_LONGX: - r = (addr + regs.x); - break; - case OPTYPE_SR: - r = (regs.s + (addr & 0xff)) & 0xffff; - break; - case OPTYPE_ISRY: - addr = (regs.s + (addr & 0xff)) & 0xffff; - r = (regs.db << 16) + dreadw(addr) + regs.y; - break; - case OPTYPE_RELB: - r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff); - r += int8(addr); - break; - case OPTYPE_RELW: - r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff); - r += int16(addr); - break; - } - - return(r & 0xffffff); -} - -void CPUcore::disassemble_opcode(char *output, uint32 addr) { - static reg24_t pc; - char t[256]; - char *s = output; - - if(false /* in_opcode() == true */) { - strcpy(s, "?????? "); - return; - } - - pc.d = addr; - sprintf(s, "%.6x ", (uint32)pc.d); - - uint8 op = dreadb(pc.d); pc.w++; - uint8 op0 = dreadb(pc.d); pc.w++; - uint8 op1 = dreadb(pc.d); pc.w++; - uint8 op2 = dreadb(pc.d); - - #define op8 ((op0)) - #define op16 ((op0) | (op1 << 8)) - #define op24 ((op0) | (op1 << 8) | (op2 << 16)) - #define a8 (regs.e || regs.p.m) - #define x8 (regs.e || regs.p.x) - - switch(op) { - case 0x00: sprintf(t, "brk #$%.2x ", op8); break; - case 0x01: sprintf(t, "ora ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x02: sprintf(t, "cop #$%.2x ", op8); break; - case 0x03: sprintf(t, "ora $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x04: sprintf(t, "tsb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x05: sprintf(t, "ora $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x06: sprintf(t, "asl $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x07: sprintf(t, "ora [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x08: sprintf(t, "php "); break; - case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8); - else sprintf(t, "ora #$%.4x ", op16); break; - case 0x0a: sprintf(t, "asl a "); break; - case 0x0b: sprintf(t, "phd "); break; - case 0x0c: sprintf(t, "tsb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0d: sprintf(t, "ora $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0e: sprintf(t, "asl $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x0f: sprintf(t, "ora $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x10: sprintf(t, "bpl $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x11: sprintf(t, "ora ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x12: sprintf(t, "ora ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x13: sprintf(t, "ora ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x14: sprintf(t, "trb $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x15: sprintf(t, "ora $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x16: sprintf(t, "asl $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x17: sprintf(t, "ora [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x18: sprintf(t, "clc "); break; - case 0x19: sprintf(t, "ora $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x1a: sprintf(t, "inc "); break; - case 0x1b: sprintf(t, "tcs "); break; - case 0x1c: sprintf(t, "trb $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x1d: sprintf(t, "ora $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x1e: sprintf(t, "asl $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x1f: sprintf(t, "ora $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x20: sprintf(t, "jsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; - case 0x21: sprintf(t, "and ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x22: sprintf(t, "jsl $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x23: sprintf(t, "and $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x24: sprintf(t, "bit $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x25: sprintf(t, "and $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x26: sprintf(t, "rol $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x27: sprintf(t, "and [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x28: sprintf(t, "plp "); break; - case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8); - else sprintf(t, "and #$%.4x ", op16); break; - case 0x2a: sprintf(t, "rol a "); break; - case 0x2b: sprintf(t, "pld "); break; - case 0x2c: sprintf(t, "bit $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2d: sprintf(t, "and $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2e: sprintf(t, "rol $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x2f: sprintf(t, "and $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x30: sprintf(t, "bmi $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x31: sprintf(t, "and ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x32: sprintf(t, "and ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x33: sprintf(t, "and ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x34: sprintf(t, "bit $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x35: sprintf(t, "and $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x36: sprintf(t, "rol $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x37: sprintf(t, "and [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x38: sprintf(t, "sec "); break; - case 0x39: sprintf(t, "and $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x3a: sprintf(t, "dec "); break; - case 0x3b: sprintf(t, "tsc "); break; - case 0x3c: sprintf(t, "bit $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3d: sprintf(t, "and $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3e: sprintf(t, "rol $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x3f: sprintf(t, "and $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x40: sprintf(t, "rti "); break; - case 0x41: sprintf(t, "eor ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x42: sprintf(t, "wdm "); break; - case 0x43: sprintf(t, "eor $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break; - case 0x45: sprintf(t, "eor $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x46: sprintf(t, "lsr $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x47: sprintf(t, "eor [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x48: sprintf(t, "pha "); break; - case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8); - else sprintf(t, "eor #$%.4x ", op16); break; - case 0x4a: sprintf(t, "lsr a "); break; - case 0x4b: sprintf(t, "phk "); break; - case 0x4c: sprintf(t, "jmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break; - case 0x4d: sprintf(t, "eor $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x4e: sprintf(t, "lsr $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x4f: sprintf(t, "eor $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x50: sprintf(t, "bvc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x51: sprintf(t, "eor ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x52: sprintf(t, "eor ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x53: sprintf(t, "eor ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break; - case 0x55: sprintf(t, "eor $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x56: sprintf(t, "lsr $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x57: sprintf(t, "eor [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x58: sprintf(t, "cli "); break; - case 0x59: sprintf(t, "eor $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x5a: sprintf(t, "phy "); break; - case 0x5b: sprintf(t, "tcd "); break; - case 0x5c: sprintf(t, "jml $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x5d: sprintf(t, "eor $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x5e: sprintf(t, "lsr $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x5f: sprintf(t, "eor $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x60: sprintf(t, "rts "); break; - case 0x61: sprintf(t, "adc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x62: sprintf(t, "per $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x63: sprintf(t, "adc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x64: sprintf(t, "stz $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x65: sprintf(t, "adc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x66: sprintf(t, "ror $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x67: sprintf(t, "adc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x68: sprintf(t, "pla "); break; - case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8); - else sprintf(t, "adc #$%.4x ", op16); break; - case 0x6a: sprintf(t, "ror a "); break; - case 0x6b: sprintf(t, "rtl "); break; - case 0x6c: sprintf(t, "jmp ($%.4x) [%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break; - case 0x6d: sprintf(t, "adc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x6e: sprintf(t, "ror $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x6f: sprintf(t, "adc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x70: sprintf(t, "bvs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x71: sprintf(t, "adc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x72: sprintf(t, "adc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x73: sprintf(t, "adc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x74: sprintf(t, "stz $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x75: sprintf(t, "adc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x76: sprintf(t, "ror $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x77: sprintf(t, "adc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x78: sprintf(t, "sei "); break; - case 0x79: sprintf(t, "adc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x7a: sprintf(t, "ply "); break; - case 0x7b: sprintf(t, "tdc "); break; - case 0x7c: sprintf(t, "jmp ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; - case 0x7d: sprintf(t, "adc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x7e: sprintf(t, "ror $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x7f: sprintf(t, "adc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0x80: sprintf(t, "bra $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x81: sprintf(t, "sta ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0x82: sprintf(t, "brl $%.4x [%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break; - case 0x83: sprintf(t, "sta $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0x84: sprintf(t, "sty $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x85: sprintf(t, "sta $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x86: sprintf(t, "stx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0x87: sprintf(t, "sta [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0x88: sprintf(t, "dey "); break; - case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8); - else sprintf(t, "bit #$%.4x ", op16); break; - case 0x8a: sprintf(t, "txa "); break; - case 0x8b: sprintf(t, "phb "); break; - case 0x8c: sprintf(t, "sty $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8d: sprintf(t, "sta $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8e: sprintf(t, "stx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x8f: sprintf(t, "sta $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0x90: sprintf(t, "bcc $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0x91: sprintf(t, "sta ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0x92: sprintf(t, "sta ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0x93: sprintf(t, "sta ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0x94: sprintf(t, "sty $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x95: sprintf(t, "sta $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0x96: sprintf(t, "stx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; - case 0x97: sprintf(t, "sta [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0x98: sprintf(t, "tya "); break; - case 0x99: sprintf(t, "sta $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0x9a: sprintf(t, "txs "); break; - case 0x9b: sprintf(t, "txy "); break; - case 0x9c: sprintf(t, "stz $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0x9d: sprintf(t, "sta $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x9e: sprintf(t, "stz $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0x9f: sprintf(t, "sta $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8); - else sprintf(t, "ldy #$%.4x ", op16); break; - case 0xa1: sprintf(t, "lda ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8); - else sprintf(t, "ldx #$%.4x ", op16); break; - case 0xa3: sprintf(t, "lda $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xa4: sprintf(t, "ldy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa5: sprintf(t, "lda $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa6: sprintf(t, "ldx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xa7: sprintf(t, "lda [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xa8: sprintf(t, "tay "); break; - case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8); - else sprintf(t, "lda #$%.4x ", op16); break; - case 0xaa: sprintf(t, "tax "); break; - case 0xab: sprintf(t, "plb "); break; - case 0xac: sprintf(t, "ldy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xad: sprintf(t, "lda $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xae: sprintf(t, "ldx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xaf: sprintf(t, "lda $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xb0: sprintf(t, "bcs $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xb1: sprintf(t, "lda ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xb2: sprintf(t, "lda ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xb3: sprintf(t, "lda ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xb4: sprintf(t, "ldy $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xb5: sprintf(t, "lda $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xb6: sprintf(t, "ldx $%.2x,y [%.6x]", op8, decode(OPTYPE_DPY, op8)); break; - case 0xb7: sprintf(t, "lda [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xb8: sprintf(t, "clv "); break; - case 0xb9: sprintf(t, "lda $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xba: sprintf(t, "tsx "); break; - case 0xbb: sprintf(t, "tyx "); break; - case 0xbc: sprintf(t, "ldy $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xbd: sprintf(t, "lda $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xbe: sprintf(t, "ldx $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xbf: sprintf(t, "lda $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8); - else sprintf(t, "cpy #$%.4x ", op16); break; - case 0xc1: sprintf(t, "cmp ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xc2: sprintf(t, "rep #$%.2x ", op8); break; - case 0xc3: sprintf(t, "cmp $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xc4: sprintf(t, "cpy $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc5: sprintf(t, "cmp $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc6: sprintf(t, "dec $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xc7: sprintf(t, "cmp [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xc8: sprintf(t, "iny "); break; - case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8); - else sprintf(t, "cmp #$%.4x ", op16); break; - case 0xca: sprintf(t, "dex "); break; - case 0xcb: sprintf(t, "wai "); break; - case 0xcc: sprintf(t, "cpy $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xcd: sprintf(t, "cmp $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xce: sprintf(t, "dec $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xcf: sprintf(t, "cmp $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xd0: sprintf(t, "bne $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xd1: sprintf(t, "cmp ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xd2: sprintf(t, "cmp ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xd3: sprintf(t, "cmp ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xd4: sprintf(t, "pei ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xd5: sprintf(t, "cmp $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xd6: sprintf(t, "dec $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xd7: sprintf(t, "cmp [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xd8: sprintf(t, "cld "); break; - case 0xd9: sprintf(t, "cmp $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xda: sprintf(t, "phx "); break; - case 0xdb: sprintf(t, "stp "); break; - case 0xdc: sprintf(t, "jmp [$%.4x] [%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break; - case 0xdd: sprintf(t, "cmp $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xde: sprintf(t, "dec $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xdf: sprintf(t, "cmp $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8); - else sprintf(t, "cpx #$%.4x ", op16); break; - case 0xe1: sprintf(t, "sbc ($%.2x,x) [%.6x]", op8, decode(OPTYPE_IDPX, op8)); break; - case 0xe2: sprintf(t, "sep #$%.2x ", op8); break; - case 0xe3: sprintf(t, "sbc $%.2x,s [%.6x]", op8, decode(OPTYPE_SR, op8)); break; - case 0xe4: sprintf(t, "cpx $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe5: sprintf(t, "sbc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe6: sprintf(t, "inc $%.2x [%.6x]", op8, decode(OPTYPE_DP, op8)); break; - case 0xe7: sprintf(t, "sbc [$%.2x] [%.6x]", op8, decode(OPTYPE_ILDP, op8)); break; - case 0xe8: sprintf(t, "inx "); break; - case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8); - else sprintf(t, "sbc #$%.4x ", op16); break; - case 0xea: sprintf(t, "nop "); break; - case 0xeb: sprintf(t, "xba "); break; - case 0xec: sprintf(t, "cpx $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xed: sprintf(t, "sbc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xee: sprintf(t, "inc $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xef: sprintf(t, "sbc $%.6x [%.6x]", op24, decode(OPTYPE_LONG, op24)); break; - case 0xf0: sprintf(t, "beq $%.4x [%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break; - case 0xf1: sprintf(t, "sbc ($%.2x),y [%.6x]", op8, decode(OPTYPE_IDPY, op8)); break; - case 0xf2: sprintf(t, "sbc ($%.2x) [%.6x]", op8, decode(OPTYPE_IDP, op8)); break; - case 0xf3: sprintf(t, "sbc ($%.2x,s),y [%.6x]", op8, decode(OPTYPE_ISRY, op8)); break; - case 0xf4: sprintf(t, "pea $%.4x [%.6x]", op16, decode(OPTYPE_ADDR, op16)); break; - case 0xf5: sprintf(t, "sbc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xf6: sprintf(t, "inc $%.2x,x [%.6x]", op8, decode(OPTYPE_DPX, op8)); break; - case 0xf7: sprintf(t, "sbc [$%.2x],y [%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break; - case 0xf8: sprintf(t, "sed "); break; - case 0xf9: sprintf(t, "sbc $%.4x,y [%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break; - case 0xfa: sprintf(t, "plx "); break; - case 0xfb: sprintf(t, "xce "); break; - case 0xfc: sprintf(t, "jsr ($%.4x,x) [%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break; - case 0xfd: sprintf(t, "sbc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xfe: sprintf(t, "inc $%.4x,x [%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break; - case 0xff: sprintf(t, "sbc $%.6x,x [%.6x]", op24, decode(OPTYPE_LONGX, op24)); break; - } - - #undef op8 - #undef op16 - #undef op24 - #undef a8 - #undef x8 - - strcat(s, t); - strcat(s, " "); - - sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ", - regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db); - strcat(s, t); - - if(regs.e) { - sprintf(t, "%c%c%c%c%c%c%c%c", - regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v', - regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b', - regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i', - regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'); - } else { - sprintf(t, "%c%c%c%c%c%c%c%c", - regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v', - regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x', - regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i', - regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c'); - } - - strcat(s, t); - strcat(s, " "); - - sprintf(t, "V:%3d H:%4d", cpu.vcounter(), cpu.hcounter()); - strcat(s, t); -} - -//opcode_length() retrieves the length of the next opcode -//to be executed. It is used by the debugger to step over, -//disable and proceed cpu opcodes. -// -//5 and 6 are special cases, 5 is used for #consts based on -//the A register size, 6 for the X/Y register size. the -//rest are literal sizes. There's no need to test for -//emulation mode, as regs.p.m/regs.p.x should *always* be -//set in emulation mode. - -uint8 CPUcore::opcode_length() { - uint8 op, len; - static uint8 op_len_tbl[256] = { - //0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f - - 2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n - 3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x3n - - 1,2,2,2, 3,2,2,2, 1,5,1,1, 3,3,3,4, //0x4n - 2,2,2,2, 3,2,2,2, 1,3,1,1, 4,3,3,4, //0x5n - 1,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x6n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x7n - - 2,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x8n - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x9n - 6,2,6,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xan - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xbn - - 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xcn - 2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xdn - 6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen - 2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn - }; - - if(false /* in_opcode() == true */) { - return 0; - } - - op = dreadb(regs.pc.d); - len = op_len_tbl[op]; - if(len == 5) return (regs.e || regs.p.m) ? 2 : 3; - if(len == 6) return (regs.e || regs.p.x) ? 2 : 3; - return len; -} - -#endif diff --git a/snes/fast/cpu/core/disassembler/disassembler.hpp b/snes/fast/cpu/core/disassembler/disassembler.hpp deleted file mode 100755 index b0ee6f04..00000000 --- a/snes/fast/cpu/core/disassembler/disassembler.hpp +++ /dev/null @@ -1,30 +0,0 @@ -enum { - OPTYPE_DP = 0, //dp - OPTYPE_DPX, //dp,x - OPTYPE_DPY, //dp,y - OPTYPE_IDP, //(dp) - OPTYPE_IDPX, //(dp,x) - OPTYPE_IDPY, //(dp),y - OPTYPE_ILDP, //[dp] - OPTYPE_ILDPY, //[dp],y - OPTYPE_ADDR, //addr - OPTYPE_ADDRX, //addr,x - OPTYPE_ADDRY, //addr,y - OPTYPE_IADDRX, //(addr,x) - OPTYPE_ILADDR, //[addr] - OPTYPE_LONG, //long - OPTYPE_LONGX, //long, x - OPTYPE_SR, //sr,s - OPTYPE_ISRY, //(sr,s),y - OPTYPE_ADDR_PC, //pbr:addr - OPTYPE_IADDR_PC, //pbr:(addr) - OPTYPE_RELB, //relb - OPTYPE_RELW, //relw -}; - -void disassemble_opcode(char *output, uint32 addr); -uint8 dreadb(uint32 addr); -uint16 dreadw(uint32 addr); -uint32 dreadl(uint32 addr); -uint32 decode(uint8 offset_type, uint32 addr); -uint8 opcode_length(); diff --git a/snes/fast/cpu/core/memory.hpp b/snes/fast/cpu/core/memory.hpp deleted file mode 100755 index 49926578..00000000 --- a/snes/fast/cpu/core/memory.hpp +++ /dev/null @@ -1,77 +0,0 @@ -alwaysinline uint8_t op_readpc() { - return op_read((regs.pc.b << 16) + regs.pc.w++); -} - -alwaysinline uint8_t op_readstack() { - regs.e ? regs.s.l++ : regs.s.w++; - return op_read(regs.s.w); -} - -alwaysinline uint8_t op_readstackn() { - return op_read(++regs.s.w); -} - -alwaysinline uint8_t op_readaddr(uint32_t addr) { - return op_read(addr & 0xffff); -} - -alwaysinline uint8_t op_readlong(uint32_t addr) { - return op_read(addr & 0xffffff); -} - -alwaysinline uint8_t op_readdbr(uint32_t addr) { - return op_read(((regs.db << 16) + addr) & 0xffffff); -} - -alwaysinline uint8_t op_readpbr(uint32_t addr) { - return op_read((regs.pc.b << 16) + (addr & 0xffff)); -} - -alwaysinline uint8_t op_readdp(uint32_t addr) { - if(regs.e && regs.d.l == 0x00) { - return op_read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff)); - } else { - return op_read((regs.d + (addr & 0xffff)) & 0xffff); - } -} - -alwaysinline uint8_t op_readsp(uint32_t addr) { - return op_read((regs.s + (addr & 0xffff)) & 0xffff); -} - -alwaysinline void op_writestack(uint8_t data) { - op_write(regs.s.w, data); - regs.e ? regs.s.l-- : regs.s.w--; -} - -alwaysinline void op_writestackn(uint8_t data) { - op_write(regs.s.w--, data); -} - -alwaysinline void op_writeaddr(uint32_t addr, uint8_t data) { - op_write(addr & 0xffff, data); -} - -alwaysinline void op_writelong(uint32_t addr, uint8_t data) { - op_write(addr & 0xffffff, data); -} - -alwaysinline void op_writedbr(uint32_t addr, uint8_t data) { - op_write(((regs.db << 16) + addr) & 0xffffff, data); -} - -alwaysinline void op_writepbr(uint32_t addr, uint8_t data) { - op_write((regs.pc.b << 16) + (addr & 0xffff), data); -} - -alwaysinline void op_writedp(uint32_t addr, uint8_t data) { - if(regs.e && regs.d.l == 0x00) { - op_write((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff), data); - } else { - op_write((regs.d + (addr & 0xffff)) & 0xffff, data); - } -} - -alwaysinline void op_writesp(uint32_t addr, uint8_t data) { - op_write((regs.s + (addr & 0xffff)) & 0xffff, data); -} diff --git a/snes/fast/cpu/core/opcode_misc.cpp b/snes/fast/cpu/core/opcode_misc.cpp deleted file mode 100755 index 8087fe66..00000000 --- a/snes/fast/cpu/core/opcode_misc.cpp +++ /dev/null @@ -1,338 +0,0 @@ -#ifdef CPUCORE_CPP - -void CPUcore::op_nop() { -L op_io_irq(); -} - -void CPUcore::op_wdm() { -L op_readpc(); -} - -void CPUcore::op_xba() { - op_io(); -L op_io(); - regs.a.l ^= regs.a.h; - regs.a.h ^= regs.a.l; - regs.a.l ^= regs.a.h; - regs.p.n = (regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -template void CPUcore::op_move_b() { - dp = op_readpc(); - sp = op_readpc(); - regs.db = dp; - rd.l = op_readlong((sp << 16) | regs.x.w); - op_writelong((dp << 16) | regs.y.w, rd.l); - op_io(); - regs.x.l += adjust; - regs.y.l += adjust; -L op_io(); - if(regs.a.w--) regs.pc.w -= 3; -} - -template void CPUcore::op_move_w() { - dp = op_readpc(); - sp = op_readpc(); - regs.db = dp; - rd.l = op_readlong((sp << 16) | regs.x.w); - op_writelong((dp << 16) | regs.y.w, rd.l); - op_io(); - regs.x.w += adjust; - regs.y.w += adjust; -L op_io(); - if(regs.a.w--) regs.pc.w -= 3; -} - -template void CPUcore::op_interrupt_e() { - op_readpc(); - op_writestack(regs.pc.h); - op_writestack(regs.pc.l); - op_writestack(regs.p); - rd.l = op_readlong(vectorE + 0); - regs.pc.b = 0; - regs.p.i = 1; - regs.p.d = 0; -L rd.h = op_readlong(vectorE + 1); - regs.pc.w = rd.w; -} - -template void CPUcore::op_interrupt_n() { - op_readpc(); - op_writestack(regs.pc.b); - op_writestack(regs.pc.h); - op_writestack(regs.pc.l); - op_writestack(regs.p); - rd.l = op_readlong(vectorN + 0); - regs.pc.b = 0x00; - regs.p.i = 1; - regs.p.d = 0; -L rd.h = op_readlong(vectorN + 1); - regs.pc.w = rd.w; -} - -void CPUcore::op_stp() { - while(regs.wai = true) { -L op_io(); - } -} - -void CPUcore::op_wai() { - regs.wai = true; - while(regs.wai) { -L op_io(); - } - op_io(); -} - -void CPUcore::op_xce() { -L op_io_irq(); - bool carry = regs.p.c; - regs.p.c = regs.e; - regs.e = carry; - if(regs.e) { - regs.p |= 0x30; - regs.s.h = 0x01; - } - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } - update_table(); -} - -template void CPUcore::op_flag() { -L op_io_irq(); - regs.p = (regs.p & ~mask) | value; -} - -template void CPUcore::op_pflag_e() { - rd.l = op_readpc(); -L op_io(); - regs.p = (mode ? regs.p | rd.l : regs.p & ~rd.l); - regs.p |= 0x30; - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } - update_table(); -} - -template void CPUcore::op_pflag_n() { - rd.l = op_readpc(); -L op_io(); - regs.p = (mode ? regs.p | rd.l : regs.p & ~rd.l); - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } - update_table(); -} - -template void CPUcore::op_transfer_b() { -L op_io_irq(); - regs.r[to].l = regs.r[from].l; - regs.p.n = (regs.r[to].l & 0x80); - regs.p.z = (regs.r[to].l == 0); -} - -template void CPUcore::op_transfer_w() { -L op_io_irq(); - regs.r[to].w = regs.r[from].w; - regs.p.n = (regs.r[to].w & 0x8000); - regs.p.z = (regs.r[to].w == 0); -} - -void CPUcore::op_tcs_e() { -L op_io_irq(); - regs.s.l = regs.a.l; -} - -void CPUcore::op_tcs_n() { -L op_io_irq(); - regs.s.w = regs.a.w; -} - -void CPUcore::op_tsx_b() { -L op_io_irq(); - regs.x.l = regs.s.l; - regs.p.n = (regs.x.l & 0x80); - regs.p.z = (regs.x.l == 0); -} - -void CPUcore::op_tsx_w() { -L op_io_irq(); - regs.x.w = regs.s.w; - regs.p.n = (regs.x.w & 0x8000); - regs.p.z = (regs.x.w == 0); -} - -void CPUcore::op_txs_e() { -L op_io_irq(); - regs.s.l = regs.x.l; -} - -void CPUcore::op_txs_n() { -L op_io_irq(); - regs.s.w = regs.x.w; -} - -template void CPUcore::op_push_b() { - op_io(); -L op_writestack(regs.r[n].l); -} - -template void CPUcore::op_push_w() { - op_io(); - op_writestack(regs.r[n].h); -L op_writestack(regs.r[n].l); -} - -void CPUcore::op_phd_e() { - op_io(); - op_writestackn(regs.d.h); -L op_writestackn(regs.d.l); - regs.s.h = 0x01; -} - -void CPUcore::op_phd_n() { - op_io(); - op_writestackn(regs.d.h); -L op_writestackn(regs.d.l); -} - -void CPUcore::op_phb() { - op_io(); -L op_writestack(regs.db); -} - -void CPUcore::op_phk() { - op_io(); -L op_writestack(regs.pc.b); -} - -void CPUcore::op_php() { - op_io(); -L op_writestack(regs.p); -} - -template void CPUcore::op_pull_b() { - op_io(); - op_io(); -L regs.r[n].l = op_readstack(); - regs.p.n = (regs.r[n].l & 0x80); - regs.p.z = (regs.r[n].l == 0); -} - -template void CPUcore::op_pull_w() { - op_io(); - op_io(); - regs.r[n].l = op_readstack(); -L regs.r[n].h = op_readstack(); - regs.p.n = (regs.r[n].w & 0x8000); - regs.p.z = (regs.r[n].w == 0); -} - -void CPUcore::op_pld_e() { - op_io(); - op_io(); - regs.d.l = op_readstackn(); -L regs.d.h = op_readstackn(); - regs.p.n = (regs.d.w & 0x8000); - regs.p.z = (regs.d.w == 0); - regs.s.h = 0x01; -} - -void CPUcore::op_pld_n() { - op_io(); - op_io(); - regs.d.l = op_readstackn(); -L regs.d.h = op_readstackn(); - regs.p.n = (regs.d.w & 0x8000); - regs.p.z = (regs.d.w == 0); -} - -void CPUcore::op_plb() { - op_io(); - op_io(); -L regs.db = op_readstack(); - regs.p.n = (regs.db & 0x80); - regs.p.z = (regs.db == 0); -} - -void CPUcore::op_plp_e() { - op_io(); - op_io(); -L regs.p = op_readstack() | 0x30; - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } - update_table(); -} - -void CPUcore::op_plp_n() { - op_io(); - op_io(); -L regs.p = op_readstack(); - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } - update_table(); -} - -void CPUcore::op_pea_e() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_writestackn(aa.h); -L op_writestackn(aa.l); - regs.s.h = 0x01; -} - -void CPUcore::op_pea_n() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_writestackn(aa.h); -L op_writestackn(aa.l); -} - -void CPUcore::op_pei_e() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - op_writestackn(aa.h); -L op_writestackn(aa.l); - regs.s.h = 0x01; -} - -void CPUcore::op_pei_n() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - op_writestackn(aa.h); -L op_writestackn(aa.l); -} - -void CPUcore::op_per_e() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); - rd.w = regs.pc.d + (int16)aa.w; - op_writestackn(rd.h); -L op_writestackn(rd.l); - regs.s.h = 0x01; -} - -void CPUcore::op_per_n() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); - rd.w = regs.pc.d + (int16)aa.w; - op_writestackn(rd.h); -L op_writestackn(rd.l); -} - -#endif diff --git a/snes/fast/cpu/core/opcode_pc.cpp b/snes/fast/cpu/core/opcode_pc.cpp deleted file mode 100755 index 3b4543f3..00000000 --- a/snes/fast/cpu/core/opcode_pc.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#ifdef CPUCORE_CPP - -template void CPUcore::op_branch() { - if((bool)(regs.p & bit) != val) { -L rd.l = op_readpc(); - } else { - rd.l = op_readpc(); - aa.w = regs.pc.d + (int8)rd.l; - op_io_cond6(aa.w); -L op_io(); - regs.pc.w = aa.w; - } -} - -void CPUcore::op_bra() { - rd.l = op_readpc(); - aa.w = regs.pc.d + (int8)rd.l; - op_io_cond6(aa.w); -L op_io(); - regs.pc.w = aa.w; -} - -void CPUcore::op_brl() { - rd.l = op_readpc(); - rd.h = op_readpc(); -L op_io(); - regs.pc.w = regs.pc.d + (int16)rd.w; -} - -void CPUcore::op_jmp_addr() { - rd.l = op_readpc(); -L rd.h = op_readpc(); - regs.pc.w = rd.w; -} - -void CPUcore::op_jmp_long() { - rd.l = op_readpc(); - rd.h = op_readpc(); -L rd.b = op_readpc(); - regs.pc.d = rd.d & 0xffffff; -} - -void CPUcore::op_jmp_iaddr() { - aa.l = op_readpc(); - aa.h = op_readpc(); - rd.l = op_readaddr(aa.w + 0); -L rd.h = op_readaddr(aa.w + 1); - regs.pc.w = rd.w; -} - -void CPUcore::op_jmp_iaddrx() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); - rd.l = op_readpbr(aa.w + regs.x.w + 0); -L rd.h = op_readpbr(aa.w + regs.x.w + 1); - regs.pc.w = rd.w; -} - -void CPUcore::op_jmp_iladdr() { - aa.l = op_readpc(); - aa.h = op_readpc(); - rd.l = op_readaddr(aa.w + 0); - rd.h = op_readaddr(aa.w + 1); -L rd.b = op_readaddr(aa.w + 2); - regs.pc.d = rd.d & 0xffffff; -} - -void CPUcore::op_jsr_addr() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); - regs.pc.w--; - op_writestack(regs.pc.h); -L op_writestack(regs.pc.l); - regs.pc.w = aa.w; -} - -void CPUcore::op_jsr_long_e() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_writestackn(regs.pc.b); - op_io(); - aa.b = op_readpc(); - regs.pc.w--; - op_writestackn(regs.pc.h); -L op_writestackn(regs.pc.l); - regs.pc.d = aa.d & 0xffffff; - regs.s.h = 0x01; -} - -void CPUcore::op_jsr_long_n() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_writestackn(regs.pc.b); - op_io(); - aa.b = op_readpc(); - regs.pc.w--; - op_writestackn(regs.pc.h); -L op_writestackn(regs.pc.l); - regs.pc.d = aa.d & 0xffffff; -} - -void CPUcore::op_jsr_iaddrx_e() { - aa.l = op_readpc(); - op_writestackn(regs.pc.h); - op_writestackn(regs.pc.l); - aa.h = op_readpc(); - op_io(); - rd.l = op_readpbr(aa.w + regs.x.w + 0); -L rd.h = op_readpbr(aa.w + regs.x.w + 1); - regs.pc.w = rd.w; - regs.s.h = 0x01; -} - -void CPUcore::op_jsr_iaddrx_n() { - aa.l = op_readpc(); - op_writestackn(regs.pc.h); - op_writestackn(regs.pc.l); - aa.h = op_readpc(); - op_io(); - rd.l = op_readpbr(aa.w + regs.x.w + 0); -L rd.h = op_readpbr(aa.w + regs.x.w + 1); - regs.pc.w = rd.w; -} - -void CPUcore::op_rti_e() { - op_io(); - op_io(); - regs.p = op_readstack() | 0x30; - rd.l = op_readstack(); -L rd.h = op_readstack(); - regs.pc.w = rd.w; -} - -void CPUcore::op_rti_n() { - op_io(); - op_io(); - regs.p = op_readstack(); - if(regs.p.x) { - regs.x.h = 0x00; - regs.y.h = 0x00; - } - rd.l = op_readstack(); - rd.h = op_readstack(); -L rd.b = op_readstack(); - regs.pc.d = rd.d & 0xffffff; - update_table(); -} - -void CPUcore::op_rts() { - op_io(); - op_io(); - rd.l = op_readstack(); - rd.h = op_readstack(); -L op_io(); - regs.pc.w = ++rd.w; -} - -void CPUcore::op_rtl_e() { - op_io(); - op_io(); - rd.l = op_readstackn(); - rd.h = op_readstackn(); -L rd.b = op_readstackn(); - regs.pc.b = rd.b; - regs.pc.w = ++rd.w; - regs.s.h = 0x01; -} - -void CPUcore::op_rtl_n() { - op_io(); - op_io(); - rd.l = op_readstackn(); - rd.h = op_readstackn(); -L rd.b = op_readstackn(); - regs.pc.b = rd.b; - regs.pc.w = ++rd.w; -} - -#endif diff --git a/snes/fast/cpu/core/opcode_read.cpp b/snes/fast/cpu/core/opcode_read.cpp deleted file mode 100755 index 61a7feb3..00000000 --- a/snes/fast/cpu/core/opcode_read.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#ifdef CPUCORE_CPP - -template void CPUcore::op_read_const_b() { -L rd.l = op_readpc(); - call(op); -} - -template void CPUcore::op_read_const_w() { - rd.l = op_readpc(); -L rd.h = op_readpc(); - call(op); -} - -void CPUcore::op_read_bit_const_b() { -L rd.l = op_readpc(); - regs.p.z = ((rd.l & regs.a.l) == 0); -} - -void CPUcore::op_read_bit_const_w() { - rd.l = op_readpc(); -L rd.h = op_readpc(); - regs.p.z = ((rd.w & regs.a.w) == 0); -} - -template void CPUcore::op_read_addr_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); -L rd.l = op_readdbr(aa.w); - call(op); -} - -template void CPUcore::op_read_addr_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - rd.l = op_readdbr(aa.w + 0); -L rd.h = op_readdbr(aa.w + 1); - call(op); -} - -template void CPUcore::op_read_addrx_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io_cond4(aa.w, aa.w + regs.x.w); -L rd.l = op_readdbr(aa.w + regs.x.w); - call(op); -} - -template void CPUcore::op_read_addrx_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io_cond4(aa.w, aa.w + regs.x.w); - rd.l = op_readdbr(aa.w + regs.x.w + 0); -L rd.h = op_readdbr(aa.w + regs.x.w + 1); - call(op); -} - -template void CPUcore::op_read_addry_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io_cond4(aa.w, aa.w + regs.y.w); -L rd.l = op_readdbr(aa.w + regs.y.w); - call(op); -} - -template void CPUcore::op_read_addry_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io_cond4(aa.w, aa.w + regs.y.w); - rd.l = op_readdbr(aa.w + regs.y.w + 0); -L rd.h = op_readdbr(aa.w + regs.y.w + 1); - call(op); -} - -template void CPUcore::op_read_long_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - aa.b = op_readpc(); -L rd.l = op_readlong(aa.d); - call(op); -} - -template void CPUcore::op_read_long_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - aa.b = op_readpc(); - rd.l = op_readlong(aa.d + 0); -L rd.h = op_readlong(aa.d + 1); - call(op); -} - -template void CPUcore::op_read_longx_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - aa.b = op_readpc(); -L rd.l = op_readlong(aa.d + regs.x.w); - call(op); -} - -template void CPUcore::op_read_longx_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - aa.b = op_readpc(); - rd.l = op_readlong(aa.d + regs.x.w + 0); -L rd.h = op_readlong(aa.d + regs.x.w + 1); - call(op); -} - -template void CPUcore::op_read_dp_b() { - dp = op_readpc(); - op_io_cond2(); -L rd.l = op_readdp(dp); - call(op); -} - -template void CPUcore::op_read_dp_w() { - dp = op_readpc(); - op_io_cond2(); - rd.l = op_readdp(dp + 0); -L rd.h = op_readdp(dp + 1); - call(op); -} - -template void CPUcore::op_read_dpr_b() { - dp = op_readpc(); - op_io_cond2(); - op_io(); -L rd.l = op_readdp(dp + regs.r[n].w); - call(op); -} - -template void CPUcore::op_read_dpr_w() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - rd.l = op_readdp(dp + regs.r[n].w + 0); -L rd.h = op_readdp(dp + regs.r[n].w + 1); - call(op); -} - -template void CPUcore::op_read_idp_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); -L rd.l = op_readdbr(aa.w); - call(op); -} - -template void CPUcore::op_read_idp_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - rd.l = op_readdbr(aa.w + 0); -L rd.h = op_readdbr(aa.w + 1); - call(op); -} - -template void CPUcore::op_read_idpx_b() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - aa.l = op_readdp(dp + regs.x.w + 0); - aa.h = op_readdp(dp + regs.x.w + 1); -L rd.l = op_readdbr(aa.w); - call(op); -} - -template void CPUcore::op_read_idpx_w() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - aa.l = op_readdp(dp + regs.x.w + 0); - aa.h = op_readdp(dp + regs.x.w + 1); - rd.l = op_readdbr(aa.w + 0); -L rd.h = op_readdbr(aa.w + 1); - call(op); -} - -template void CPUcore::op_read_idpy_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - op_io_cond4(aa.w, aa.w + regs.y.w); -L rd.l = op_readdbr(aa.w + regs.y.w); - call(op); -} - -template void CPUcore::op_read_idpy_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - op_io_cond4(aa.w, aa.w + regs.y.w); - rd.l = op_readdbr(aa.w + regs.y.w + 0); -L rd.h = op_readdbr(aa.w + regs.y.w + 1); - call(op); -} - -template void CPUcore::op_read_ildp_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); -L rd.l = op_readlong(aa.d); - call(op); -} - -template void CPUcore::op_read_ildp_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); - rd.l = op_readlong(aa.d + 0); -L rd.h = op_readlong(aa.d + 1); - call(op); -} - -template void CPUcore::op_read_ildpy_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); -L rd.l = op_readlong(aa.d + regs.y.w); - call(op); -} - -template void CPUcore::op_read_ildpy_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); - rd.l = op_readlong(aa.d + regs.y.w + 0); -L rd.h = op_readlong(aa.d + regs.y.w + 1); - call(op); -} - -template void CPUcore::op_read_sr_b() { - sp = op_readpc(); - op_io(); -L rd.l = op_readsp(sp); - call(op); -} - -template void CPUcore::op_read_sr_w() { - sp = op_readpc(); - op_io(); - rd.l = op_readsp(sp + 0); -L rd.h = op_readsp(sp + 1); - call(op); -} - -template void CPUcore::op_read_isry_b() { - sp = op_readpc(); - op_io(); - aa.l = op_readsp(sp + 0); - aa.h = op_readsp(sp + 1); - op_io(); -L rd.l = op_readdbr(aa.w + regs.y.w); - call(op); -} - -template void CPUcore::op_read_isry_w() { - sp = op_readpc(); - op_io(); - aa.l = op_readsp(sp + 0); - aa.h = op_readsp(sp + 1); - op_io(); - rd.l = op_readdbr(aa.w + regs.y.w + 0); -L rd.h = op_readdbr(aa.w + regs.y.w + 1); - call(op); -} - -#endif diff --git a/snes/fast/cpu/core/opcode_rmw.cpp b/snes/fast/cpu/core/opcode_rmw.cpp deleted file mode 100755 index fed939e1..00000000 --- a/snes/fast/cpu/core/opcode_rmw.cpp +++ /dev/null @@ -1,169 +0,0 @@ -#ifdef CPUCORE_CPP - -template void CPUcore::op_adjust_imm_b() { -L op_io_irq(); - regs.r[n].l += adjust; - regs.p.n = (regs.r[n].l & 0x80); - regs.p.z = (regs.r[n].l == 0); -} - -template void CPUcore::op_adjust_imm_w() { -L op_io_irq(); - regs.r[n].w += adjust; - regs.p.n = (regs.r[n].w & 0x8000); - regs.p.z = (regs.r[n].w == 0); -} - -void CPUcore::op_asl_imm_b() { -L op_io_irq(); - regs.p.c = (regs.a.l & 0x80); - regs.a.l <<= 1; - regs.p.n = (regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -void CPUcore::op_asl_imm_w() { -L op_io_irq(); - regs.p.c = (regs.a.w & 0x8000); - regs.a.w <<= 1; - regs.p.n = (regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -void CPUcore::op_lsr_imm_b() { -L op_io_irq(); - regs.p.c = (regs.a.l & 0x01); - regs.a.l >>= 1; - regs.p.n = (regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -void CPUcore::op_lsr_imm_w() { -L op_io_irq(); - regs.p.c = (regs.a.w & 0x0001); - regs.a.w >>= 1; - regs.p.n = (regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -void CPUcore::op_rol_imm_b() { -L op_io_irq(); - bool carry = regs.p.c; - regs.p.c = (regs.a.l & 0x80); - regs.a.l = (regs.a.l << 1) | carry; - regs.p.n = (regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -void CPUcore::op_rol_imm_w() { -L op_io_irq(); - bool carry = regs.p.c; - regs.p.c = (regs.a.w & 0x8000); - regs.a.w = (regs.a.w << 1) | carry; - regs.p.n = (regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -void CPUcore::op_ror_imm_b() { -L op_io_irq(); - bool carry = regs.p.c; - regs.p.c = (regs.a.l & 0x01); - regs.a.l = (carry << 7) | (regs.a.l >> 1); - regs.p.n = (regs.a.l & 0x80); - regs.p.z = (regs.a.l == 0); -} - -void CPUcore::op_ror_imm_w() { -L op_io_irq(); - bool carry = regs.p.c; - regs.p.c = (regs.a.w & 0x0001); - regs.a.w = (carry << 15) | (regs.a.w >> 1); - regs.p.n = (regs.a.w & 0x8000); - regs.p.z = (regs.a.w == 0); -} - -template void CPUcore::op_adjust_addr_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - rd.l = op_readdbr(aa.w); - op_io(); - call(op); -L op_writedbr(aa.w, rd.l); -} - -template void CPUcore::op_adjust_addr_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - rd.l = op_readdbr(aa.w + 0); - rd.h = op_readdbr(aa.w + 1); - op_io(); - call(op); - op_writedbr(aa.w + 1, rd.h); -L op_writedbr(aa.w + 0, rd.l); -} - -template void CPUcore::op_adjust_addrx_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); - rd.l = op_readdbr(aa.w + regs.x.w); - op_io(); - call(op); -L op_writedbr(aa.w + regs.x.w, rd.l); -} - -template void CPUcore::op_adjust_addrx_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); - rd.l = op_readdbr(aa.w + regs.x.w + 0); - rd.h = op_readdbr(aa.w + regs.x.w + 1); - op_io(); - call(op); - op_writedbr(aa.w + regs.x.w + 1, rd.h); -L op_writedbr(aa.w + regs.x.w + 0, rd.l); -} - -template void CPUcore::op_adjust_dp_b() { - dp = op_readpc(); - op_io_cond2(); - rd.l = op_readdp(dp); - op_io(); - call(op); -L op_writedp(dp, rd.l); -} - -template void CPUcore::op_adjust_dp_w() { - dp = op_readpc(); - op_io_cond2(); - rd.l = op_readdp(dp + 0); - rd.h = op_readdp(dp + 1); - op_io(); - call(op); - op_writedp(dp + 1, rd.h); -L op_writedp(dp + 0, rd.l); -} - -template void CPUcore::op_adjust_dpx_b() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - rd.l = op_readdp(dp + regs.x.w); - op_io(); - call(op); -L op_writedp(dp + regs.x.w, rd.l); -} - -template void CPUcore::op_adjust_dpx_w() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - rd.l = op_readdp(dp + regs.x.w + 0); - rd.h = op_readdp(dp + regs.x.w + 1); - op_io(); - call(op); - op_writedp(dp + regs.x.w + 1, rd.h); -L op_writedp(dp + regs.x.w + 0, rd.l); -} - -#endif diff --git a/snes/fast/cpu/core/opcode_write.cpp b/snes/fast/cpu/core/opcode_write.cpp deleted file mode 100755 index de85e672..00000000 --- a/snes/fast/cpu/core/opcode_write.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#ifdef CPUCORE_CPP - -template void CPUcore::op_write_addr_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); -L op_writedbr(aa.w, regs.r[n]); -} - -template void CPUcore::op_write_addr_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_writedbr(aa.w + 0, regs.r[n] >> 0); -L op_writedbr(aa.w + 1, regs.r[n] >> 8); -} - -template void CPUcore::op_write_addrr_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); -L op_writedbr(aa.w + regs.r[i], regs.r[n]); -} - -template void CPUcore::op_write_addrr_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - op_io(); - op_writedbr(aa.w + regs.r[i] + 0, regs.r[n] >> 0); -L op_writedbr(aa.w + regs.r[i] + 1, regs.r[n] >> 8); -} - -template void CPUcore::op_write_longr_b() { - aa.l = op_readpc(); - aa.h = op_readpc(); - aa.b = op_readpc(); -L op_writelong(aa.d + regs.r[i], regs.a.l); -} - -template void CPUcore::op_write_longr_w() { - aa.l = op_readpc(); - aa.h = op_readpc(); - aa.b = op_readpc(); - op_writelong(aa.d + regs.r[i] + 0, regs.a.l); -L op_writelong(aa.d + regs.r[i] + 1, regs.a.h); -} - -template void CPUcore::op_write_dp_b() { - dp = op_readpc(); - op_io_cond2(); -L op_writedp(dp, regs.r[n]); -} - -template void CPUcore::op_write_dp_w() { - dp = op_readpc(); - op_io_cond2(); - op_writedp(dp + 0, regs.r[n] >> 0); -L op_writedp(dp + 1, regs.r[n] >> 8); -} - -template void CPUcore::op_write_dpr_b() { - dp = op_readpc(); - op_io_cond2(); - op_io(); -L op_writedp(dp + regs.r[i], regs.r[n]); -} - -template void CPUcore::op_write_dpr_w() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - op_writedp(dp + regs.r[i] + 0, regs.r[n] >> 0); -L op_writedp(dp + regs.r[i] + 1, regs.r[n] >> 8); -} - -void CPUcore::op_sta_idp_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); -L op_writedbr(aa.w, regs.a.l); -} - -void CPUcore::op_sta_idp_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - op_writedbr(aa.w + 0, regs.a.l); -L op_writedbr(aa.w + 1, regs.a.h); -} - -void CPUcore::op_sta_ildp_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); -L op_writelong(aa.d, regs.a.l); -} - -void CPUcore::op_sta_ildp_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); - op_writelong(aa.d + 0, regs.a.l); -L op_writelong(aa.d + 1, regs.a.h); -} - -void CPUcore::op_sta_idpx_b() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - aa.l = op_readdp(dp + regs.x.w + 0); - aa.h = op_readdp(dp + regs.x.w + 1); -L op_writedbr(aa.w, regs.a.l); -} - -void CPUcore::op_sta_idpx_w() { - dp = op_readpc(); - op_io_cond2(); - op_io(); - aa.l = op_readdp(dp + regs.x.w + 0); - aa.h = op_readdp(dp + regs.x.w + 1); - op_writedbr(aa.w + 0, regs.a.l); -L op_writedbr(aa.w + 1, regs.a.h); -} - -void CPUcore::op_sta_idpy_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - op_io(); -L op_writedbr(aa.w + regs.y.w, regs.a.l); -} - -void CPUcore::op_sta_idpy_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - op_io(); - op_writedbr(aa.w + regs.y.w + 0, regs.a.l); -L op_writedbr(aa.w + regs.y.w + 1, regs.a.h); -} - -void CPUcore::op_sta_ildpy_b() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); -L op_writelong(aa.d + regs.y.w, regs.a.l); -} - -void CPUcore::op_sta_ildpy_w() { - dp = op_readpc(); - op_io_cond2(); - aa.l = op_readdp(dp + 0); - aa.h = op_readdp(dp + 1); - aa.b = op_readdp(dp + 2); - op_writelong(aa.d + regs.y.w + 0, regs.a.l); -L op_writelong(aa.d + regs.y.w + 1, regs.a.h); -} - -void CPUcore::op_sta_sr_b() { - sp = op_readpc(); - op_io(); -L op_writesp(sp, regs.a.l); -} - -void CPUcore::op_sta_sr_w() { - sp = op_readpc(); - op_io(); - op_writesp(sp + 0, regs.a.l); -L op_writesp(sp + 1, regs.a.h); -} - -void CPUcore::op_sta_isry_b() { - sp = op_readpc(); - op_io(); - aa.l = op_readsp(sp + 0); - aa.h = op_readsp(sp + 1); - op_io(); -L op_writedbr(aa.w + regs.y.w, regs.a.l); -} - -void CPUcore::op_sta_isry_w() { - sp = op_readpc(); - op_io(); - aa.l = op_readsp(sp + 0); - aa.h = op_readsp(sp + 1); - op_io(); - op_writedbr(aa.w + regs.y.w + 0, regs.a.l); -L op_writedbr(aa.w + regs.y.w + 1, regs.a.h); -} - -#endif diff --git a/snes/fast/cpu/core/registers.hpp b/snes/fast/cpu/core/registers.hpp deleted file mode 100755 index 1305d334..00000000 --- a/snes/fast/cpu/core/registers.hpp +++ /dev/null @@ -1,81 +0,0 @@ -struct flag_t { - bool n, v, m, x, d, i, z, c; - - inline operator unsigned() const { - return (n << 7) + (v << 6) + (m << 5) + (x << 4) - + (d << 3) + (i << 2) + (z << 1) + (c << 0); - } - - inline unsigned operator=(uint8 data) { - n = data & 0x80; v = data & 0x40; m = data & 0x20; x = data & 0x10; - d = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; - return data; - } - - inline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); } - inline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); } - inline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); } - - flag_t() : n(0), v(0), m(0), x(0), d(0), i(0), z(0), c(0) {} -}; - -struct reg16_t { - union { - uint16 w; - struct { uint8 order_lsb2(l, h); }; - }; - - inline operator unsigned() const { return w; } - inline unsigned operator = (unsigned i) { return w = i; } - inline unsigned operator |= (unsigned i) { return w |= i; } - inline unsigned operator ^= (unsigned i) { return w ^= i; } - inline unsigned operator &= (unsigned i) { return w &= i; } - inline unsigned operator <<= (unsigned i) { return w <<= i; } - inline unsigned operator >>= (unsigned i) { return w >>= i; } - inline unsigned operator += (unsigned i) { return w += i; } - inline unsigned operator -= (unsigned i) { return w -= i; } - inline unsigned operator *= (unsigned i) { return w *= i; } - inline unsigned operator /= (unsigned i) { return w /= i; } - inline unsigned operator %= (unsigned i) { return w %= i; } - - reg16_t() : w(0) {} -}; - -struct reg24_t { - union { - uint32 d; - struct { uint16 order_lsb2(w, wh); }; - struct { uint8 order_lsb4(l, h, b, bh); }; - }; - - inline operator unsigned() const { return d; } - inline unsigned operator = (unsigned i) { return d = uclip<24>(i); } - inline unsigned operator |= (unsigned i) { return d = uclip<24>(d | i); } - inline unsigned operator ^= (unsigned i) { return d = uclip<24>(d ^ i); } - inline unsigned operator &= (unsigned i) { return d = uclip<24>(d & i); } - inline unsigned operator <<= (unsigned i) { return d = uclip<24>(d << i); } - inline unsigned operator >>= (unsigned i) { return d = uclip<24>(d >> i); } - inline unsigned operator += (unsigned i) { return d = uclip<24>(d + i); } - inline unsigned operator -= (unsigned i) { return d = uclip<24>(d - i); } - inline unsigned operator *= (unsigned i) { return d = uclip<24>(d * i); } - inline unsigned operator /= (unsigned i) { return d = uclip<24>(d / i); } - inline unsigned operator %= (unsigned i) { return d = uclip<24>(d % i); } - - reg24_t() : d(0) {} -}; - -struct regs_t { - reg24_t pc; - reg16_t r[6], &a, &x, &y, &z, &s, &d; - flag_t p; - uint8 db; - bool e; - - bool irq; //IRQ pin (0 = low, 1 = trigger) - bool wai; //raised during wai, cleared after interrupt triggered - uint8 mdr; //memory data register - - regs_t() : a(r[0]), x(r[1]), y(r[2]), z(r[3]), s(r[4]), d(r[5]), db(0), e(false), irq(false), wai(false), mdr(0) { - z = 0; - } -}; diff --git a/snes/fast/cpu/core/serialization.cpp b/snes/fast/cpu/core/serialization.cpp deleted file mode 100755 index 467765bd..00000000 --- a/snes/fast/cpu/core/serialization.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef CPUCORE_CPP - -void CPUcore::core_serialize(serializer &s) { - s.integer(regs.pc.d); - - s.integer(regs.a.w); - s.integer(regs.x.w); - s.integer(regs.y.w); - s.integer(regs.z.w); - s.integer(regs.s.w); - s.integer(regs.d.w); - - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.m); - s.integer(regs.p.x); - s.integer(regs.p.d); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); - - s.integer(regs.db); - s.integer(regs.e); - s.integer(regs.irq); - s.integer(regs.wai); - s.integer(regs.mdr); - - s.integer(aa.d); - s.integer(rd.d); - s.integer(sp); - s.integer(dp); - - update_table(); -} - -#endif diff --git a/snes/fast/cpu/core/table.cpp b/snes/fast/cpu/core/table.cpp deleted file mode 100755 index 6575a4db..00000000 --- a/snes/fast/cpu/core/table.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#ifdef CPUCORE_CPP - -void CPUcore::initialize_opcode_table() { - #define opA( id, name ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_Mx + id] = op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name; - #define opAII(id, name, x, y ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_Mx + id] = op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name; - #define opE( id, name ) op_table[table_EM + id] = &CPUcore::op_##name##_e; op_table[table_MX + id] = op_table[table_Mx + id] = op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_n; - #define opEI( id, name, x ) op_table[table_EM + id] = &CPUcore::op_##name##_e; op_table[table_MX + id] = op_table[table_Mx + id] = op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_n; - #define opEII(id, name, x, y ) op_table[table_EM + id] = &CPUcore::op_##name##_e; op_table[table_MX + id] = op_table[table_Mx + id] = op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_n; - #define opM( id, name ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_Mx + id] = &CPUcore::op_##name##_b; op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w; - #define opMI( id, name, x ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_Mx + id] = &CPUcore::op_##name##_b; op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w; - #define opMII(id, name, x, y ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_Mx + id] = &CPUcore::op_##name##_b; op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w; - #define opMF( id, name, fn ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_Mx + id] = &CPUcore::op_##name##_b<&CPUcore::op_##fn##_b>; op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w<&CPUcore::op_##fn##_w>; - #define opMFI(id, name, fn, x) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_Mx + id] = &CPUcore::op_##name##_b<&CPUcore::op_##fn##_b, x>; op_table[table_mX + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w<&CPUcore::op_##fn##_w, x>; - #define opX( id, name ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_mX + id] = &CPUcore::op_##name##_b; op_table[table_Mx + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w; - #define opXI( id, name, x ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_mX + id] = &CPUcore::op_##name##_b; op_table[table_Mx + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w; - #define opXII(id, name, x, y ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_mX + id] = &CPUcore::op_##name##_b; op_table[table_Mx + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w; - #define opXF( id, name, fn ) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_mX + id] = &CPUcore::op_##name##_b<&CPUcore::op_##fn##_b>; op_table[table_Mx + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w<&CPUcore::op_##fn##_w>; - #define opXFI(id, name, fn, x) op_table[table_EM + id] = op_table[table_MX + id] = op_table[table_mX + id] = &CPUcore::op_##name##_b<&CPUcore::op_##fn##_b, x>; op_table[table_Mx + id] = op_table[table_mx + id] = &CPUcore::op_##name##_w<&CPUcore::op_##fn##_w, x>; - - opEII(0x00, interrupt, 0xfffe, 0xffe6) - opMF (0x01, read_idpx, ora) - opEII(0x02, interrupt, 0xfff4, 0xffe4) - opMF (0x03, read_sr, ora) - opMF (0x04, adjust_dp, tsb) - opMF (0x05, read_dp, ora) - opMF (0x06, adjust_dp, asl) - opMF (0x07, read_ildp, ora) - opA (0x08, php) - opMF (0x09, read_const, ora) - opM (0x0a, asl_imm) - opE (0x0b, phd) - opMF (0x0c, adjust_addr, tsb) - opMF (0x0d, read_addr, ora) - opMF (0x0e, adjust_addr, asl) - opMF (0x0f, read_long, ora) - opAII(0x10, branch, 0x80, false) - opMF (0x11, read_idpy, ora) - opMF (0x12, read_idp, ora) - opMF (0x13, read_isry, ora) - opMF (0x14, adjust_dp, trb) - opMFI(0x15, read_dpr, ora, X) - opMF (0x16, adjust_dpx, asl) - opMF (0x17, read_ildpy, ora) - opAII(0x18, flag, 0x01, 0x00) - opMF (0x19, read_addry, ora) - opMII(0x1a, adjust_imm, A, +1) - opE (0x1b, tcs) - opMF (0x1c, adjust_addr, trb) - opMF (0x1d, read_addrx, ora) - opMF (0x1e, adjust_addrx, asl) - opMF (0x1f, read_longx, ora) - opA (0x20, jsr_addr) - opMF (0x21, read_idpx, and) - opE (0x22, jsr_long) - opMF (0x23, read_sr, and) - opMF (0x24, read_dp, bit) - opMF (0x25, read_dp, and) - opMF (0x26, adjust_dp, rol) - opMF (0x27, read_ildp, and) - opE (0x28, plp) - opMF (0x29, read_const, and) - opM (0x2a, rol_imm) - opE (0x2b, pld) - opMF (0x2c, read_addr, bit) - opMF (0x2d, read_addr, and) - opMF (0x2e, adjust_addr, rol) - opMF (0x2f, read_long, and) - opAII(0x30, branch, 0x80, true) - opMF (0x31, read_idpy, and) - opMF (0x32, read_idp, and) - opMF (0x33, read_isry, and) - opMFI(0x34, read_dpr, bit, X) - opMFI(0x35, read_dpr, and, X) - opMF (0x36, adjust_dpx, rol) - opMF (0x37, read_ildpy, and) - opAII(0x38, flag, 0x01, 0x01) - opMF (0x39, read_addry, and) - opMII(0x3a, adjust_imm, A, -1) - opAII(0x3b, transfer_w, S, A) - opMF (0x3c, read_addrx, bit) - opMF (0x3d, read_addrx, and) - opMF (0x3e, adjust_addrx, rol) - opMF (0x3f, read_longx, and) - opE (0x40, rti) - opMF (0x41, read_idpx, eor) - opA (0x42, wdm) - opMF (0x43, read_sr, eor) - opXI (0x44, move, -1) - opMF (0x45, read_dp, eor) - opMF (0x46, adjust_dp, lsr) - opMF (0x47, read_ildp, eor) - opMI (0x48, push, A) - opMF (0x49, read_const, eor) - opM (0x4a, lsr_imm) - opA (0x4b, phk) - opA (0x4c, jmp_addr) - opMF (0x4d, read_addr, eor) - opMF (0x4e, adjust_addr, lsr) - opMF (0x4f, read_long, eor) - opAII(0x50, branch, 0x40, false) - opMF (0x51, read_idpy, eor) - opMF (0x52, read_idp, eor) - opMF (0x53, read_isry, eor) - opXI (0x54, move, +1) - opMFI(0x55, read_dpr, eor, X) - opMF (0x56, adjust_dpx, lsr) - opMF (0x57, read_ildpy, eor) - opAII(0x58, flag, 0x04, 0x00) - opMF (0x59, read_addry, eor) - opXI (0x5a, push, Y) - opAII(0x5b, transfer_w, A, D) - opA (0x5c, jmp_long) - opMF (0x5d, read_addrx, eor) - opMF (0x5e, adjust_addrx, lsr) - opMF (0x5f, read_longx, eor) - opA (0x60, rts) - opMF (0x61, read_idpx, adc) - opE (0x62, per) - opMF (0x63, read_sr, adc) - opMI (0x64, write_dp, Z) - opMF (0x65, read_dp, adc) - opMF (0x66, adjust_dp, ror) - opMF (0x67, read_ildp, adc) - opMI (0x68, pull, A) - opMF (0x69, read_const, adc) - opM (0x6a, ror_imm) - opE (0x6b, rtl) - opA (0x6c, jmp_iaddr) - opMF (0x6d, read_addr, adc) - opMF (0x6e, adjust_addr, ror) - opMF (0x6f, read_long, adc) - opAII(0x70, branch, 0x40, true) - opMF (0x71, read_idpy, adc) - opMF (0x72, read_idp, adc) - opMF (0x73, read_isry, adc) - opMII(0x74, write_dpr, Z, X) - opMFI(0x75, read_dpr, adc, X) - opMF (0x76, adjust_dpx, ror) - opMF (0x77, read_ildpy, adc) - opAII(0x78, flag, 0x04, 0x04) - opMF (0x79, read_addry, adc) - opXI (0x7a, pull, Y) - opAII(0x7b, transfer_w, D, A) - opA (0x7c, jmp_iaddrx) - opMF (0x7d, read_addrx, adc) - opMF (0x7e, adjust_addrx, ror) - opMF (0x7f, read_longx, adc) - opA (0x80, bra) - opM (0x81, sta_idpx) - opA (0x82, brl) - opM (0x83, sta_sr) - opXI (0x84, write_dp, Y) - opMI (0x85, write_dp, A) - opXI (0x86, write_dp, X) - opM (0x87, sta_ildp) - opXII(0x88, adjust_imm, Y, -1) - opM (0x89, read_bit_const) - opMII(0x8a, transfer, X, A) - opA (0x8b, phb) - opXI (0x8c, write_addr, Y) - opMI (0x8d, write_addr, A) - opXI (0x8e, write_addr, X) - opMI (0x8f, write_longr, Z) - opAII(0x90, branch, 0x01, false) - opM (0x91, sta_idpy) - opM (0x92, sta_idp) - opM (0x93, sta_isry) - opXII(0x94, write_dpr, Y, X) - opMII(0x95, write_dpr, A, X) - opXII(0x96, write_dpr, X, Y) - opM (0x97, sta_ildpy) - opMII(0x98, transfer, Y, A) - opMII(0x99, write_addrr, A, Y) - opE (0x9a, txs) - opXII(0x9b, transfer, X, Y) - opMI (0x9c, write_addr, Z) - opMII(0x9d, write_addrr, A, X) - opMII(0x9e, write_addrr, Z, X) - opMI (0x9f, write_longr, X) - opXF (0xa0, read_const, ldy) - opMF (0xa1, read_idpx, lda) - opXF (0xa2, read_const, ldx) - opMF (0xa3, read_sr, lda) - opXF (0xa4, read_dp, ldy) - opMF (0xa5, read_dp, lda) - opXF (0xa6, read_dp, ldx) - opMF (0xa7, read_ildp, lda) - opXII(0xa8, transfer, A, Y) - opMF (0xa9, read_const, lda) - opXII(0xaa, transfer, A, X) - opA (0xab, plb) - opXF (0xac, read_addr, ldy) - opMF (0xad, read_addr, lda) - opXF (0xae, read_addr, ldx) - opMF (0xaf, read_long, lda) - opAII(0xb0, branch, 0x01, true) - opMF (0xb1, read_idpy, lda) - opMF (0xb2, read_idp, lda) - opMF (0xb3, read_isry, lda) - opXFI(0xb4, read_dpr, ldy, X) - opMFI(0xb5, read_dpr, lda, X) - opXFI(0xb6, read_dpr, ldx, Y) - opMF (0xb7, read_ildpy, lda) - opAII(0xb8, flag, 0x40, 0x00) - opMF (0xb9, read_addry, lda) - opX (0xba, tsx) - opXII(0xbb, transfer, Y, X) - opXF (0xbc, read_addrx, ldy) - opMF (0xbd, read_addrx, lda) - opXF (0xbe, read_addry, ldx) - opMF (0xbf, read_longx, lda) - opXF (0xc0, read_const, cpy) - opMF (0xc1, read_idpx, cmp) - opEI (0xc2, pflag, 0) - opMF (0xc3, read_sr, cmp) - opXF (0xc4, read_dp, cpy) - opMF (0xc5, read_dp, cmp) - opMF (0xc6, adjust_dp, dec) - opMF (0xc7, read_ildp, cmp) - opXII(0xc8, adjust_imm, Y, +1) - opMF (0xc9, read_const, cmp) - opXII(0xca, adjust_imm, X, -1) - opA (0xcb, wai) - opXF (0xcc, read_addr, cpy) - opMF (0xcd, read_addr, cmp) - opMF (0xce, adjust_addr, dec) - opMF (0xcf, read_long, cmp) - opAII(0xd0, branch, 0x02, false) - opMF (0xd1, read_idpy, cmp) - opMF (0xd2, read_idp, cmp) - opMF (0xd3, read_isry, cmp) - opE (0xd4, pei) - opMFI(0xd5, read_dpr, cmp, X) - opMF (0xd6, adjust_dpx, dec) - opMF (0xd7, read_ildpy, cmp) - opAII(0xd8, flag, 0x08, 0x00) - opMF (0xd9, read_addry, cmp) - opXI (0xda, push, X) - opA (0xdb, stp) - opA (0xdc, jmp_iladdr) - opMF (0xdd, read_addrx, cmp) - opMF (0xde, adjust_addrx, dec) - opMF (0xdf, read_longx, cmp) - opXF (0xe0, read_const, cpx) - opMF (0xe1, read_idpx, sbc) - opEI (0xe2, pflag, 1) - opMF (0xe3, read_sr, sbc) - opXF (0xe4, read_dp, cpx) - opMF (0xe5, read_dp, sbc) - opMF (0xe6, adjust_dp, inc) - opMF (0xe7, read_ildp, sbc) - opXII(0xe8, adjust_imm, X, +1) - opMF (0xe9, read_const, sbc) - opA (0xea, nop) - opA (0xeb, xba) - opXF (0xec, read_addr, cpx) - opMF (0xed, read_addr, sbc) - opMF (0xee, adjust_addr, inc) - opMF (0xef, read_long, sbc) - opAII(0xf0, branch, 0x02, true) - opMF (0xf1, read_idpy, sbc) - opMF (0xf2, read_idp, sbc) - opMF (0xf3, read_isry, sbc) - opE (0xf4, pea) - opMFI(0xf5, read_dpr, sbc, X) - opMF (0xf6, adjust_dpx, inc) - opMF (0xf7, read_ildpy, sbc) - opAII(0xf8, flag, 0x08, 0x08) - opMF (0xf9, read_addry, sbc) - opXI (0xfa, pull, X) - opA (0xfb, xce) - opE (0xfc, jsr_iaddrx) - opMF (0xfd, read_addrx, sbc) - opMF (0xfe, adjust_addrx, inc) - opMF (0xff, read_longx, sbc) - - #undef opA - #undef opAII - #undef opE - #undef opEI - #undef opEII - #undef opM - #undef opMI - #undef opMII - #undef opMF - #undef opMFI - #undef opX - #undef opXI - #undef opXII - #undef opXF - #undef opXFI -} - -void CPUcore::update_table() { - if(regs.e) { - opcode_table = &op_table[table_EM]; - } else if(regs.p.m) { - if(regs.p.x) { - opcode_table = &op_table[table_MX]; - } else { - opcode_table = &op_table[table_Mx]; - } - } else { - if(regs.p.x) { - opcode_table = &op_table[table_mX]; - } else { - opcode_table = &op_table[table_mx]; - } - } -} - -#endif diff --git a/snes/fast/cpu/cpu.cpp b/snes/fast/cpu/cpu.cpp index cb836768..b6b5790b 100755 --- a/snes/fast/cpu/cpu.cpp +++ b/snes/fast/cpu/cpu.cpp @@ -5,6 +5,7 @@ namespace SNES { CPU cpu; +#include "serialization.cpp" #include "dma.cpp" #include "memory.cpp" #include "mmio.cpp" @@ -20,11 +21,19 @@ void CPU::step(unsigned clocks) { } void CPU::synchronize_smp() { - while(smp.clock < 0) smp.run(); + if(SMP::Threaded == true) { + if(smp.clock < 0) co_switch(smp.thread); + } else { + while(smp.clock < 0) smp.enter(); + } } void CPU::synchronize_ppu() { - if(ppu.clock < 0) co_switch(ppu.thread); + if(PPU::Threaded == true) { + if(ppu.clock < 0) co_switch(ppu.thread); + } else { + while(ppu.clock < 0) ppu.enter(); + } } void CPU::synchronize_coprocessor() { @@ -139,9 +148,6 @@ void CPU::reset() { dma_reset(); } -void CPU::serialize(serializer &s) { -} - CPU::CPU() : queue(512, { &CPU::queue_event, this }) { PPUcounter::scanline = { &CPU::scanline, this }; } diff --git a/snes/fast/cpu/cpu.hpp b/snes/fast/cpu/cpu.hpp index d478484b..940564f8 100755 --- a/snes/fast/cpu/cpu.hpp +++ b/snes/fast/cpu/cpu.hpp @@ -1,7 +1,6 @@ -#include - class CPU : public Processor, public CPUcore, public PPUcounter, public MMIO { public: + enum : bool { Threaded = true }; array coprocessors; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_smp(); @@ -20,6 +19,7 @@ public: uint8 op_read(unsigned addr); void op_write(unsigned addr, uint8 data); + void enter(); void power(); void reset(); @@ -30,7 +30,6 @@ public: private: //cpu static void Enter(); - void enter(); void op_irq(uint16 vector); //timing diff --git a/snes/fast/cpu/mmio.cpp b/snes/fast/cpu/mmio.cpp index 49598fe2..14a3c785 100755 --- a/snes/fast/cpu/mmio.cpp +++ b/snes/fast/cpu/mmio.cpp @@ -102,7 +102,7 @@ void CPU::mmio_write(unsigned addr, uint8 data) { if((addr & 0xffc0) == 0x2140) { synchronize_smp(); - smp.port_write(addr & 3, data); + port_write(addr & 3, data); return; } diff --git a/snes/fast/cpu/serialization.cpp b/snes/fast/cpu/serialization.cpp new file mode 100755 index 00000000..5e19a7bf --- /dev/null +++ b/snes/fast/cpu/serialization.cpp @@ -0,0 +1,84 @@ +#ifdef CPU_CPP + +void CPU::serialize(serializer &s) { + Processor::serialize(s); + CPUcore::core_serialize(s); + PPUcounter::serialize(s); + + queue.serialize(s); + s.array(port_data); + + for(unsigned i = 0; i < 8; i++) { + s.integer(channel[i].dma_enabled); + s.integer(channel[i].hdma_enabled); + + s.integer(channel[i].direction); + s.integer(channel[i].indirect); + s.integer(channel[i].unused); + s.integer(channel[i].reverse_transfer); + s.integer(channel[i].fixed_transfer); + s.integer(channel[i].transfer_mode); + + s.integer(channel[i].dest_addr); + s.integer(channel[i].source_addr); + s.integer(channel[i].source_bank); + + s.integer(channel[i].transfer_size); + + s.integer(channel[i].indirect_bank); + s.integer(channel[i].hdma_addr); + s.integer(channel[i].line_counter); + s.integer(channel[i].unknown); + + s.integer(channel[i].hdma_completed); + s.integer(channel[i].hdma_do_transfer); + } + + s.integer(status.nmi_valid); + s.integer(status.nmi_line); + s.integer(status.nmi_transition); + s.integer(status.nmi_pending); + + s.integer(status.irq_valid); + s.integer(status.irq_line); + s.integer(status.irq_transition); + s.integer(status.irq_pending); + + s.integer(status.irq_lock); + s.integer(status.hdma_pending); + + s.integer(status.wram_addr); + + s.integer(status.joypad_strobe_latch); + + s.integer(status.nmi_enabled); + s.integer(status.virq_enabled); + s.integer(status.hirq_enabled); + s.integer(status.auto_joypad_poll_enabled); + + s.integer(status.pio); + + s.integer(status.wrmpya); + s.integer(status.wrmpyb); + s.integer(status.wrdiva); + s.integer(status.wrdivb); + + s.integer(status.htime); + s.integer(status.vtime); + + s.integer(status.rom_speed); + + s.integer(status.rddiv); + s.integer(status.rdmpy); + + s.integer(status.joy1l); + s.integer(status.joy1h); + s.integer(status.joy2l); + s.integer(status.joy2h); + s.integer(status.joy3l); + s.integer(status.joy3h); + s.integer(status.joy4l); + s.integer(status.joy4h); +} + +#endif diff --git a/snes/fast/dsp/dsp.cpp b/snes/fast/dsp/dsp.cpp index 6e7dec7b..3c18b714 100755 --- a/snes/fast/dsp/dsp.cpp +++ b/snes/fast/dsp/dsp.cpp @@ -5,9 +5,7 @@ namespace SNES { DSP dsp; -#if !defined(PROFILE_CSNES) - #include "../snes_spc/SPC_DSP.cpp" -#endif +#include "../snes_spc/SPC_DSP.cpp" #include "serialization.cpp" @@ -16,9 +14,14 @@ void DSP::step(unsigned clocks) { } void DSP::synchronize_smp() { + if(SMP::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread); + } else { + while(clock >= 0) smp.enter(); + } } -void DSP::run() { +void DSP::enter() { spc_dsp.run(1); step(24); diff --git a/snes/fast/dsp/dsp.hpp b/snes/fast/dsp/dsp.hpp index 3bcebee4..b8992d6b 100755 --- a/snes/fast/dsp/dsp.hpp +++ b/snes/fast/dsp/dsp.hpp @@ -1,16 +1,15 @@ -#if !defined(PROFILE_CSNES) - #include "../snes_spc/SPC_DSP.h" -#endif +#include "../snes_spc/SPC_DSP.h" class DSP : public Processor { public: + enum : bool { Threaded = false }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_smp(); - void run(); uint8 read(uint8 addr); void write(uint8 addr, uint8 data); + void enter(); void power(); void reset(); diff --git a/snes/fast/dsp/serialization.cpp b/snes/fast/dsp/serialization.cpp index 8a0a1f74..0565a1b5 100755 --- a/snes/fast/dsp/serialization.cpp +++ b/snes/fast/dsp/serialization.cpp @@ -1,8 +1,31 @@ #ifdef DSP_CPP +static void dsp_state_save(unsigned char **out, void *in, size_t size) { + memcpy(*out, in, size); + *out += size; +} + +static void dsp_state_load(unsigned char **in, void *out, size_t size) { + memcpy(out, *in, size); + *in += size; +} + void DSP::serialize(serializer &s) { Processor::serialize(s); s.array(samplebuffer); + + unsigned char state[SPC_DSP::state_size]; + unsigned char *p = state; + memset(&state, 0, SPC_DSP::state_size); + if(s.mode() == serializer::Save) { + spc_dsp.copy_state(&p, dsp_state_save); + s.array(state); + } else if(s.mode() == serializer::Load) { + s.array(state); + spc_dsp.copy_state(&p, dsp_state_load); + } else { + s.array(state); + } } #endif diff --git a/snes/fast/ppu/ppu.cpp b/snes/fast/ppu/ppu.cpp index adacaf5a..15e283c6 100755 --- a/snes/fast/ppu/ppu.cpp +++ b/snes/fast/ppu/ppu.cpp @@ -20,7 +20,11 @@ void PPU::step(unsigned clocks) { } void PPU::synchronize_cpu() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + if(CPU::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + } else { + while(clock >= 0) cpu.enter(); + } } void PPU::Enter() { ppu.enter(); } diff --git a/snes/fast/ppu/ppu.hpp b/snes/fast/ppu/ppu.hpp index 39ff71c8..b51f6245 100755 --- a/snes/fast/ppu/ppu.hpp +++ b/snes/fast/ppu/ppu.hpp @@ -1,5 +1,9 @@ class PPU : public Processor, public PPUcounter, public MMIO { public: + enum : bool { Threaded = true }; + alwaysinline void step(unsigned clocks); + alwaysinline void synchronize_cpu(); + #include "memory/memory.hpp" #include "mmio/mmio.hpp" #include "render/render.hpp" @@ -10,12 +14,7 @@ public: uint8 ppu1_version; uint8 ppu2_version; - //synchronization - alwaysinline void step(unsigned clocks); - alwaysinline void synchronize_cpu(); - static void Enter(); - void enter(); void add_clocks(unsigned clocks); uint8 region; @@ -56,6 +55,7 @@ public: void scanline(); void render_scanline(); void frame(); + void enter(); void power(); void reset(); diff --git a/snes/fast/smp/core/algorithms.cpp b/snes/fast/smp/core/algorithms.cpp deleted file mode 100755 index 30a21076..00000000 --- a/snes/fast/smp/core/algorithms.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#ifdef SMPCORE_CPP - -uint8 SMPcore::op_adc(uint8 x, uint8 y) { - int r = x + y + regs.p.c; - regs.p.n = r & 0x80; - regs.p.v = ~(x ^ y) & (x ^ r) & 0x80; - regs.p.h = (x ^ y ^ r) & 0x10; - regs.p.z = (uint8)r == 0; - regs.p.c = r > 0xff; - return r; -} - -uint16 SMPcore::op_addw(uint16 x, uint16 y) { - uint16 r; - regs.p.c = 0; - r = op_adc(x, y); - r |= op_adc(x >> 8, y >> 8) << 8; - regs.p.z = r == 0; - return r; -} - -uint8 SMPcore::op_and(uint8 x, uint8 y) { - x &= y; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_cmp(uint8 x, uint8 y) { - int r = x - y; - regs.p.n = r & 0x80; - regs.p.z = (uint8)r == 0; - regs.p.c = r >= 0; - return x; -} - -uint16 SMPcore::op_cmpw(uint16 x, uint16 y) { - int r = x - y; - regs.p.n = r & 0x8000; - regs.p.z = (uint16)r == 0; - regs.p.c = r >= 0; - return x; -} - -uint8 SMPcore::op_eor(uint8 x, uint8 y) { - x ^= y; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_or(uint8 x, uint8 y) { - x |= y; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_sbc(uint8 x, uint8 y) { - int r = x - y - !regs.p.c; - regs.p.n = r & 0x80; - regs.p.v = (x ^ y) & (x ^ r) & 0x80; - regs.p.h = !((x ^ y ^ r) & 0x10); - regs.p.z = (uint8)r == 0; - regs.p.c = r >= 0; - return r; -} - -uint16 SMPcore::op_subw(uint16 x, uint16 y) { - uint16 r; - regs.p.c = 1; - r = op_sbc(x, y); - r |= op_sbc(x >> 8, y >> 8) << 8; - regs.p.z = r == 0; - return r; -} - -uint8 SMPcore::op_inc(uint8 x) { - x++; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_dec(uint8 x) { - x--; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_asl(uint8 x) { - regs.p.c = x & 0x80; - x <<= 1; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_lsr(uint8 x) { - regs.p.c = x & 0x01; - x >>= 1; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_rol(uint8 x) { - unsigned carry = (unsigned)regs.p.c; - regs.p.c = x & 0x80; - x = (x << 1) | carry; - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -uint8 SMPcore::op_ror(uint8 x) { - unsigned carry = (unsigned)regs.p.c << 7; - regs.p.c = x & 0x01; - x = carry | (x >> 1); - regs.p.n = x & 0x80; - regs.p.z = x == 0; - return x; -} - -#endif diff --git a/snes/fast/smp/core/core.cpp b/snes/fast/smp/core/core.cpp deleted file mode 100755 index 88243dad..00000000 --- a/snes/fast/smp/core/core.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include - -#define SMPCORE_CPP -namespace SNES { - -#include "serialization.cpp" -#include "algorithms.cpp" -#include "disassembler/disassembler.cpp" - -#define A 0 -#define X 1 -#define Y 2 -#define SP 3 - -#include "opcode_mov.cpp" -#include "opcode_pc.cpp" -#include "opcode_read.cpp" -#include "opcode_rmw.cpp" -#include "opcode_misc.cpp" -#include "table.cpp" - -#undef A -#undef X -#undef Y -#undef SP - -SMPcore::SMPcore() { - initialize_opcode_table(); -} - -} diff --git a/snes/fast/smp/core/core.hpp b/snes/fast/smp/core/core.hpp deleted file mode 100755 index 85e8c74a..00000000 --- a/snes/fast/smp/core/core.hpp +++ /dev/null @@ -1,118 +0,0 @@ -class SMPcore { -public: - #include "registers.hpp" - #include "memory.hpp" - #include "disassembler/disassembler.hpp" - - regs_t regs; - uint16 dp, sp, rd, wr, bit, ya; - - virtual void op_io() = 0; - virtual uint8 op_read(uint16 addr) = 0; - virtual void op_write(uint16 addr, uint8 data) = 0; - - uint8 op_adc (uint8 x, uint8 y); - uint16 op_addw(uint16 x, uint16 y); - uint8 op_and (uint8 x, uint8 y); - uint8 op_cmp (uint8 x, uint8 y); - uint16 op_cmpw(uint16 x, uint16 y); - uint8 op_eor (uint8 x, uint8 y); - uint8 op_inc (uint8 x); - uint8 op_dec (uint8 x); - uint8 op_or (uint8 x, uint8 y); - uint8 op_sbc (uint8 x, uint8 y); - uint16 op_subw(uint16 x, uint16 y); - uint8 op_asl (uint8 x); - uint8 op_lsr (uint8 x); - uint8 op_rol (uint8 x); - uint8 op_ror (uint8 x); - - template void op_mov_reg_reg(); - void op_mov_sp_x(); - template void op_mov_reg_const(); - void op_mov_a_ix(); - void op_mov_a_ixinc(); - template void op_mov_reg_dp(); - template void op_mov_reg_dpr(); - template void op_mov_reg_addr(); - template void op_mov_a_addrr(); - void op_mov_a_idpx(); - void op_mov_a_idpy(); - void op_mov_dp_dp(); - void op_mov_dp_const(); - void op_mov_ix_a(); - void op_mov_ixinc_a(); - template void op_mov_dp_reg(); - template void op_mov_dpr_reg(); - template void op_mov_addr_reg(); - template void op_mov_addrr_a(); - void op_mov_idpx_a(); - void op_mov_idpy_a(); - void op_movw_ya_dp(); - void op_movw_dp_ya(); - void op_mov1_c_bit(); - void op_mov1_bit_c(); - - void op_bra(); - template void op_branch(); - template void op_bitbranch(); - void op_cbne_dp(); - void op_cbne_dpx(); - void op_dbnz_dp(); - void op_dbnz_y(); - void op_jmp_addr(); - void op_jmp_iaddrx(); - void op_call(); - void op_pcall(); - template void op_tcall(); - void op_brk(); - void op_ret(); - void op_reti(); - - template void op_read_reg_const(); - template void op_read_a_ix(); - template void op_read_reg_dp(); - template void op_read_a_dpx(); - template void op_read_reg_addr(); - template void op_read_a_addrr(); - template void op_read_a_idpx(); - template void op_read_a_idpy(); - template void op_read_ix_iy(); - template void op_read_dp_dp(); - template void op_read_dp_const(); - template void op_read_ya_dp(); - void op_cmpw_ya_dp(); - template void op_and1_bit(); - void op_eor1_bit(); - void op_not1_bit(); - template void op_or1_bit(); - - template void op_adjust_reg(); - template void op_adjust_dp(); - template void op_adjust_dpx(); - template void op_adjust_addr(); - template void op_adjust_addr_a(); - template void op_adjustw_dp(); - - void op_nop(); - void op_wait(); - void op_xcn(); - void op_daa(); - void op_das(); - template void op_setbit(); - void op_notc(); - template void op_seti(); - template void op_setbit_dp(); - template void op_push_reg(); - void op_push_p(); - template void op_pop_reg(); - void op_pop_p(); - void op_mul_ya(); - void op_div_ya_x(); - - void (SMPcore::*opcode_table[256])(); - void initialize_opcode_table(); - - void core_serialize(serializer&); - SMPcore(); -}; diff --git a/snes/fast/smp/core/disassembler/disassembler.cpp b/snes/fast/smp/core/disassembler/disassembler.cpp deleted file mode 100755 index ee5663a3..00000000 --- a/snes/fast/smp/core/disassembler/disassembler.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#ifdef SMPCORE_CPP - -uint8 SMPcore::disassemble_read(uint16 addr) { - if(addr >= 0xffc0) { - #if defined(DEBUGGER) - if(smp.iplrom_enable()) return smp.iplrom[addr & 0x3f]; - #else - //unable to determine if IPLROM is enabled, assume that it is - return smp.iplrom[addr & 0x3f]; - #endif - } - return memory::apuram[addr]; -} - -uint16 SMPcore::relb(int8 offset, int op_len) { - uint16 pc = regs.pc + op_len; - return pc + offset; -} - -void SMPcore::disassemble_opcode(char *output, uint16 addr) { - char *s, t[512]; - uint8 op, op0, op1; - uint16 opw, opdp0, opdp1; - s = output; - - sprintf(s, "..%.4x ", addr); - - op = disassemble_read(addr + 0); - op0 = disassemble_read(addr + 1); - op1 = disassemble_read(addr + 2); - opw = (op0) | (op1 << 8); - opdp0 = ((unsigned)regs.p.p << 8) + op0; - opdp1 = ((unsigned)regs.p.p << 8) + op1; - - strcpy(t, " "); - - switch(op) { - case 0x00: sprintf(t, "nop"); break; - case 0x01: sprintf(t, "tcall 0"); break; - case 0x02: sprintf(t, "set0 $%.3x", opdp0); break; - case 0x03: sprintf(t, "bbs0 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x04: sprintf(t, "or a,$%.3x", opdp0); break; - case 0x05: sprintf(t, "or a,$%.4x", opw); break; - case 0x06: sprintf(t, "or a,(x)"); break; - case 0x07: sprintf(t, "or a,($%.3x+x)", opdp0); break; - case 0x08: sprintf(t, "or a,#$%.2x", op0); break; - case 0x09: sprintf(t, "or $%.3x,$%.3x", opdp1, opdp0); break; - case 0x0a: sprintf(t, "or1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x0b: sprintf(t, "asl $%.3x", opdp0); break; - case 0x0c: sprintf(t, "asl $%.4x", opw); break; - case 0x0d: sprintf(t, "push p"); break; - case 0x0e: sprintf(t, "tset $%.4x,a", opw); break; - case 0x0f: sprintf(t, "brk"); break; - case 0x10: sprintf(t, "bpl $%.4x", relb(op0, 2)); break; - case 0x11: sprintf(t, "tcall 1"); break; - case 0x12: sprintf(t, "clr0 $%.3x", opdp0); break; - case 0x13: sprintf(t, "bbc0 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x14: sprintf(t, "or a,$%.3x+x", opdp0); break; - case 0x15: sprintf(t, "or a,$%.4x+x", opw); break; - case 0x16: sprintf(t, "or a,$%.4x+y", opw); break; - case 0x17: sprintf(t, "or a,($%.3x)+y", opdp0); break; - case 0x18: sprintf(t, "or $%.3x,#$%.2x", opdp1, op0); break; - case 0x19: sprintf(t, "or (x),(y)"); break; - case 0x1a: sprintf(t, "decw $%.3x", opdp0); break; - case 0x1b: sprintf(t, "asl $%.3x+x", opdp0); break; - case 0x1c: sprintf(t, "asl a"); break; - case 0x1d: sprintf(t, "dec x"); break; - case 0x1e: sprintf(t, "cmp x,$%.4x", opw); break; - case 0x1f: sprintf(t, "jmp ($%.4x+x)", opw); break; - case 0x20: sprintf(t, "clrp"); break; - case 0x21: sprintf(t, "tcall 2"); break; - case 0x22: sprintf(t, "set1 $%.3x", opdp0); break; - case 0x23: sprintf(t, "bbs1 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x24: sprintf(t, "and a,$%.3x", opdp0); break; - case 0x25: sprintf(t, "and a,$%.4x", opw); break; - case 0x26: sprintf(t, "and a,(x)"); break; - case 0x27: sprintf(t, "and a,($%.3x+x)", opdp0); break; - case 0x28: sprintf(t, "and a,#$%.2x", op0); break; - case 0x29: sprintf(t, "and $%.3x,$%.3x", opdp1, opdp0); break; - case 0x2a: sprintf(t, "or1 c,!$%.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x2b: sprintf(t, "rol $%.3x", opdp0); break; - case 0x2c: sprintf(t, "rol $%.4x", opw); break; - case 0x2d: sprintf(t, "push a"); break; - case 0x2e: sprintf(t, "cbne $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x2f: sprintf(t, "bra $%.4x", relb(op0, 2)); break; - case 0x30: sprintf(t, "bmi $%.4x", relb(op0, 2)); break; - case 0x31: sprintf(t, "tcall 3"); break; - case 0x32: sprintf(t, "clr1 $%.3x", opdp0); break; - case 0x33: sprintf(t, "bbc1 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x34: sprintf(t, "and a,$%.3x+x", opdp0); break; - case 0x35: sprintf(t, "and a,$%.4x+x", opw); break; - case 0x36: sprintf(t, "and a,$%.4x+y", opw); break; - case 0x37: sprintf(t, "and a,($%.3x)+y", opdp0); break; - case 0x38: sprintf(t, "and $%.3x,#$%.2x", opdp1, op0); break; - case 0x39: sprintf(t, "and (x),(y)"); break; - case 0x3a: sprintf(t, "incw $%.3x", opdp0); break; - case 0x3b: sprintf(t, "rol $%.3x+x", opdp0); break; - case 0x3c: sprintf(t, "rol a"); break; - case 0x3d: sprintf(t, "inc x"); break; - case 0x3e: sprintf(t, "cmp x,$%.3x", opdp0); break; - case 0x3f: sprintf(t, "call $%.4x", opw); break; - case 0x40: sprintf(t, "setp"); break; - case 0x41: sprintf(t, "tcall 4"); break; - case 0x42: sprintf(t, "set2 $%.3x", opdp0); break; - case 0x43: sprintf(t, "bbs2 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x44: sprintf(t, "eor a,$%.3x", opdp0); break; - case 0x45: sprintf(t, "eor a,$%.4x", opw); break; - case 0x46: sprintf(t, "eor a,(x)"); break; - case 0x47: sprintf(t, "eor a,($%.3x+x)", opdp0); break; - case 0x48: sprintf(t, "eor a,#$%.2x", op0); break; - case 0x49: sprintf(t, "eor $%.3x,$%.3x", opdp1, opdp0); break; - case 0x4a: sprintf(t, "and1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x4b: sprintf(t, "lsr $%.3x", opdp0); break; - case 0x4c: sprintf(t, "lsr $%.4x", opw); break; - case 0x4d: sprintf(t, "push x"); break; - case 0x4e: sprintf(t, "tclr $%.4x,a", opw); break; - case 0x4f: sprintf(t, "pcall $ff%.2x", op0); break; - case 0x50: sprintf(t, "bvc $%.4x", relb(op0, 2)); break; - case 0x51: sprintf(t, "tcall 5"); break; - case 0x52: sprintf(t, "clr2 $%.3x", opdp0); break; - case 0x53: sprintf(t, "bbc2 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x54: sprintf(t, "eor a,$%.3x+x", opdp0); break; - case 0x55: sprintf(t, "eor a,$%.4x+x", opw); break; - case 0x56: sprintf(t, "eor a,$%.4x+y", opw); break; - case 0x57: sprintf(t, "eor a,($%.3x)+y", opdp0); break; - case 0x58: sprintf(t, "eor $%.3x,#$%.2x", opdp1, op0); break; - case 0x59: sprintf(t, "eor (x),(y)"); break; - case 0x5a: sprintf(t, "cmpw ya,$%.3x", opdp0); break; - case 0x5b: sprintf(t, "lsr $%.3x+x", opdp0); break; - case 0x5c: sprintf(t, "lsr a"); break; - case 0x5d: sprintf(t, "mov x,a"); break; - case 0x5e: sprintf(t, "cmp y,$%.4x", opw); break; - case 0x5f: sprintf(t, "jmp $%.4x", opw); break; - case 0x60: sprintf(t, "clrc"); break; - case 0x61: sprintf(t, "tcall 6"); break; - case 0x62: sprintf(t, "set3 $%.3x", opdp0); break; - case 0x63: sprintf(t, "bbs3 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x64: sprintf(t, "cmp a,$%.3x", opdp0); break; - case 0x65: sprintf(t, "cmp a,$%.4x", opw); break; - case 0x66: sprintf(t, "cmp a,(x)"); break; - case 0x67: sprintf(t, "cmp a,($%.3x+x)", opdp0); break; - case 0x68: sprintf(t, "cmp a,#$%.2x", op0); break; - case 0x69: sprintf(t, "cmp $%.3x,$%.3x", opdp1, opdp0); break; - case 0x6a: sprintf(t, "and1 c,!$%.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x6b: sprintf(t, "ror $%.3x", opdp0); break; - case 0x6c: sprintf(t, "ror $%.4x", opw); break; - case 0x6d: sprintf(t, "push y"); break; - case 0x6e: sprintf(t, "dbnz $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x6f: sprintf(t, "ret"); break; - case 0x70: sprintf(t, "bvs $%.4x", relb(op0, 2)); break; - case 0x71: sprintf(t, "tcall 7"); break; - case 0x72: sprintf(t, "clr3 $%.3x", opdp0); break; - case 0x73: sprintf(t, "bbc3 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x74: sprintf(t, "cmp a,$%.3x+x", opdp0); break; - case 0x75: sprintf(t, "cmp a,$%.4x+x", opw); break; - case 0x76: sprintf(t, "cmp a,$%.4x+y", opw); break; - case 0x77: sprintf(t, "cmp a,($%.3x)+y", opdp0); break; - case 0x78: sprintf(t, "cmp $%.3x,#$%.2x", opdp1, op0); break; - case 0x79: sprintf(t, "cmp (x),(y)"); break; - case 0x7a: sprintf(t, "addw ya,$%.3x", opdp0); break; - case 0x7b: sprintf(t, "ror $%.3x+x", opdp0); break; - case 0x7c: sprintf(t, "ror a"); break; - case 0x7d: sprintf(t, "mov a,x"); break; - case 0x7e: sprintf(t, "cmp y,$%.3x", opdp0); break; - case 0x7f: sprintf(t, "reti"); break; - case 0x80: sprintf(t, "setc"); break; - case 0x81: sprintf(t, "tcall 8"); break; - case 0x82: sprintf(t, "set4 $%.3x", opdp0); break; - case 0x83: sprintf(t, "bbs4 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x84: sprintf(t, "adc a,$%.3x", opdp0); break; - case 0x85: sprintf(t, "adc a,$%.4x", opw); break; - case 0x86: sprintf(t, "adc a,(x)"); break; - case 0x87: sprintf(t, "adc a,($%.3x+x)", opdp0); break; - case 0x88: sprintf(t, "adc a,#$%.2x", op0); break; - case 0x89: sprintf(t, "adc $%.3x,$%.3x", opdp1, opdp0); break; - case 0x8a: sprintf(t, "eor1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0x8b: sprintf(t, "dec $%.3x", opdp0); break; - case 0x8c: sprintf(t, "dec $%.4x", opw); break; - case 0x8d: sprintf(t, "mov y,#$%.2x", op0); break; - case 0x8e: sprintf(t, "pop p"); break; - case 0x8f: sprintf(t, "mov $%.3x,#$%.2x", opdp1, op0); break; - case 0x90: sprintf(t, "bcc $%.4x", relb(op0, 2)); break; - case 0x91: sprintf(t, "tcall 9"); break; - case 0x92: sprintf(t, "clr4 $%.3x", opdp0); break; - case 0x93: sprintf(t, "bbc4 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0x94: sprintf(t, "adc a,$%.3x+x", opdp0); break; - case 0x95: sprintf(t, "adc a,$%.4x+x", opw); break; - case 0x96: sprintf(t, "adc a,$%.4x+y", opw); break; - case 0x97: sprintf(t, "adc a,($%.3x)+y", opdp0); break; - case 0x98: sprintf(t, "adc $%.3x,#$%.2x", opdp1, op0); break; - case 0x99: sprintf(t, "adc (x),(y)"); break; - case 0x9a: sprintf(t, "subw ya,$%.3x", opdp0); break; - case 0x9b: sprintf(t, "dec $%.3x+x", opdp0); break; - case 0x9c: sprintf(t, "dec a"); break; - case 0x9d: sprintf(t, "mov x,sp"); break; - case 0x9e: sprintf(t, "div ya,x"); break; - case 0x9f: sprintf(t, "xcn a"); break; - case 0xa0: sprintf(t, "ei"); break; - case 0xa1: sprintf(t, "tcall 10"); break; - case 0xa2: sprintf(t, "set5 $%.3x", opdp0); break; - case 0xa3: sprintf(t, "bbs5 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0xa4: sprintf(t, "sbc a,$%.3x", opdp0); break; - case 0xa5: sprintf(t, "sbc a,$%.4x", opw); break; - case 0xa6: sprintf(t, "sbc a,(x)"); break; - case 0xa7: sprintf(t, "sbc a,($%.3x+x)", opdp0); break; - case 0xa8: sprintf(t, "sbc a,#$%.2x", op0); break; - case 0xa9: sprintf(t, "sbc $%.3x,$%.3x", opdp1, opdp0); break; - case 0xaa: sprintf(t, "mov1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0xab: sprintf(t, "inc $%.3x", opdp0); break; - case 0xac: sprintf(t, "inc $%.4x", opw); break; - case 0xad: sprintf(t, "cmp y,#$%.2x", op0); break; - case 0xae: sprintf(t, "pop a"); break; - case 0xaf: sprintf(t, "mov (x)+,a"); break; - case 0xb0: sprintf(t, "bcs $%.4x", relb(op0, 2)); break; - case 0xb1: sprintf(t, "tcall 11"); break; - case 0xb2: sprintf(t, "clr5 $%.3x", opdp0); break; - case 0xb3: sprintf(t, "bbc5 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0xb4: sprintf(t, "sbc a,$%.3x+x", opdp0); break; - case 0xb5: sprintf(t, "sbc a,$%.4x+x", opw); break; - case 0xb6: sprintf(t, "sbc a,$%.4x+y", opw); break; - case 0xb7: sprintf(t, "sbc a,($%.3x)+y", opdp0); break; - case 0xb8: sprintf(t, "sbc $%.3x,#$%.2x", opdp1, op0); break; - case 0xb9: sprintf(t, "sbc (x),(y)"); break; - case 0xba: sprintf(t, "movw ya,$%.3x", opdp0); break; - case 0xbb: sprintf(t, "inc $%.3x+x", opdp0); break; - case 0xbc: sprintf(t, "inc a"); break; - case 0xbd: sprintf(t, "mov sp,x"); break; - case 0xbe: sprintf(t, "das a"); break; - case 0xbf: sprintf(t, "mov a,(x)+"); break; - case 0xc0: sprintf(t, "di"); break; - case 0xc1: sprintf(t, "tcall 12"); break; - case 0xc2: sprintf(t, "set6 $%.3x", opdp0); break; - case 0xc3: sprintf(t, "bbs6 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0xc4: sprintf(t, "mov $%.3x,a", opdp0); break; - case 0xc5: sprintf(t, "mov $%.4x,a", opw); break; - case 0xc6: sprintf(t, "mov (x),a"); break; - case 0xc7: sprintf(t, "mov ($%.3x+x),a", opdp0); break; - case 0xc8: sprintf(t, "cmp x,#$%.2x", op0); break; - case 0xc9: sprintf(t, "mov $%.4x,x", opw); break; - case 0xca: sprintf(t, "mov1 $%.4x:%d,c", opw & 0x1fff, opw >> 13); break; - case 0xcb: sprintf(t, "mov $%.3x,y", opdp0); break; - case 0xcc: sprintf(t, "mov $%.4x,y", opw); break; - case 0xcd: sprintf(t, "mov x,#$%.2x", op0); break; - case 0xce: sprintf(t, "pop x"); break; - case 0xcf: sprintf(t, "mul ya"); break; - case 0xd0: sprintf(t, "bne $%.4x", relb(op0, 2)); break; - case 0xd1: sprintf(t, "tcall 13"); break; - case 0xd2: sprintf(t, "clr6 $%.3x", opdp0); break; - case 0xd3: sprintf(t, "bbc6 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0xd4: sprintf(t, "mov $%.3x+x,a", opdp0); break; - case 0xd5: sprintf(t, "mov $%.4x+x,a", opw); break; - case 0xd6: sprintf(t, "mov $%.4x+y,a", opw); break; - case 0xd7: sprintf(t, "mov ($%.3x)+y,a", opdp0); break; - case 0xd8: sprintf(t, "mov $%.3x,x", opdp0); break; - case 0xd9: sprintf(t, "mov $%.3x+y,x", opdp0); break; - case 0xda: sprintf(t, "movw $%.3x,ya", opdp0); break; - case 0xdb: sprintf(t, "mov $%.3x+x,y", opdp0); break; - case 0xdc: sprintf(t, "dec y"); break; - case 0xdd: sprintf(t, "mov a,y"); break; - case 0xde: sprintf(t, "cbne $%.3x+x,$%.4x", opdp0, relb(op1, 3)); break; - case 0xdf: sprintf(t, "daa a"); break; - case 0xe0: sprintf(t, "clrv"); break; - case 0xe1: sprintf(t, "tcall 14"); break; - case 0xe2: sprintf(t, "set7 $%.3x", opdp0); break; - case 0xe3: sprintf(t, "bbs7 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0xe4: sprintf(t, "mov a,$%.3x", opdp0); break; - case 0xe5: sprintf(t, "mov a,$%.4x", opw); break; - case 0xe6: sprintf(t, "mov a,(x)"); break; - case 0xe7: sprintf(t, "mov a,($%.3x+x)", opdp0); break; - case 0xe8: sprintf(t, "mov a,#$%.2x", op0); break; - case 0xe9: sprintf(t, "mov x,$%.4x", opw); break; - case 0xea: sprintf(t, "not1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break; - case 0xeb: sprintf(t, "mov y,$%.3x", opdp0); break; - case 0xec: sprintf(t, "mov y,$%.4x", opw); break; - case 0xed: sprintf(t, "notc"); break; - case 0xee: sprintf(t, "pop y"); break; - case 0xef: sprintf(t, "sleep"); break; - case 0xf0: sprintf(t, "beq $%.4x", relb(op0, 2)); break; - case 0xf1: sprintf(t, "tcall 15"); break; - case 0xf2: sprintf(t, "clr7 $%.3x", opdp0); break; - case 0xf3: sprintf(t, "bbc7 $%.3x,$%.4x", opdp0, relb(op1, 3)); break; - case 0xf4: sprintf(t, "mov a,$%.3x+x", opdp0); break; - case 0xf5: sprintf(t, "mov a,$%.4x+x", opw); break; - case 0xf6: sprintf(t, "mov a,$%.4x+y", opw); break; - case 0xf7: sprintf(t, "mov a,($%.3x)+y", opdp0); break; - case 0xf8: sprintf(t, "mov x,$%.3x", opdp0); break; - case 0xf9: sprintf(t, "mov x,$%.3x+y", opdp0); break; - case 0xfa: sprintf(t, "mov $%.3x,$%.3x", opdp1, opdp0); break; - case 0xfb: sprintf(t, "mov y,$%.3x+x", opdp0); break; - case 0xfc: sprintf(t, "inc y"); break; - case 0xfd: sprintf(t, "mov y,a"); break; - case 0xfe: sprintf(t, "dbnz y,$%.4x", relb(op0, 2)); break; - case 0xff: sprintf(t, "stop"); break; - } - - t[strlen(t)] = ' '; - strcat(s, t); - - sprintf(t, "A:%.2x X:%.2x Y:%.2x SP:01%.2x YA:%.4x ", - regs.a, regs.x, regs.y, regs.sp, (uint16)regs.ya); - strcat(s, t); - - sprintf(t, "%c%c%c%c%c%c%c%c", - regs.p.n ? 'N' : 'n', - regs.p.v ? 'V' : 'v', - regs.p.p ? 'P' : 'p', - regs.p.b ? 'B' : 'b', - regs.p.h ? 'H' : 'h', - regs.p.i ? 'I' : 'i', - regs.p.z ? 'Z' : 'z', - regs.p.c ? 'C' : 'c'); - strcat(s, t); -} - -#endif diff --git a/snes/fast/smp/core/disassembler/disassembler.hpp b/snes/fast/smp/core/disassembler/disassembler.hpp deleted file mode 100755 index a6e78e09..00000000 --- a/snes/fast/smp/core/disassembler/disassembler.hpp +++ /dev/null @@ -1,3 +0,0 @@ -void disassemble_opcode(char *output, uint16 addr); -inline uint8 disassemble_read(uint16 addr); -inline uint16 relb(int8 offset, int op_len); diff --git a/snes/fast/smp/core/memory.hpp b/snes/fast/smp/core/memory.hpp deleted file mode 100755 index 9af32956..00000000 --- a/snes/fast/smp/core/memory.hpp +++ /dev/null @@ -1,27 +0,0 @@ -alwaysinline uint8_t op_readpc() { - return op_read(regs.pc++); -} - -alwaysinline uint8_t op_readstack() { - return op_read(0x0100 | ++regs.sp); -} - -alwaysinline void op_writestack(uint8_t data) { - op_write(0x0100 | regs.sp--, data); -} - -alwaysinline uint8_t op_readaddr(uint16_t addr) { - return op_read(addr); -} - -alwaysinline void op_writeaddr(uint16_t addr, uint8_t data) { - op_write(addr, data); -} - -alwaysinline uint8_t op_readdp(uint8_t addr) { - return op_read(((unsigned)regs.p.p << 8) + addr); -} - -alwaysinline void op_writedp(uint8_t addr, uint8_t data) { - op_write(((unsigned)regs.p.p << 8) + addr, data); -} diff --git a/snes/fast/smp/core/opcode_misc.cpp b/snes/fast/smp/core/opcode_misc.cpp deleted file mode 100755 index 0f4d4ce3..00000000 --- a/snes/fast/smp/core/opcode_misc.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#ifdef SMPCORE_CPP - -void SMPcore::op_nop() { - op_io(); -} - -void SMPcore::op_wait() { - while(true) { - op_io(); - op_io(); - } -} - -void SMPcore::op_xcn() { - op_io(); - op_io(); - op_io(); - op_io(); - regs.a = (regs.a >> 4) | (regs.a << 4); - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -void SMPcore::op_daa() { - op_io(); - op_io(); - if(regs.p.c || (regs.a) > 0x99) { - regs.a += 0x60; - regs.p.c = 1; - } - if(regs.p.h || (regs.a & 15) > 0x09) { - regs.a += 0x06; - } - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -void SMPcore::op_das() { - op_io(); - op_io(); - if(!regs.p.c || (regs.a) > 0x99) { - regs.a -= 0x60; - regs.p.c = 0; - } - if(!regs.p.h || (regs.a & 15) > 0x09) { - regs.a -= 0x06; - } - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -template void SMPcore::op_setbit() { - op_io(); - regs.p = (regs.p & ~mask) | value; -} - -void SMPcore::op_notc() { - op_io(); - op_io(); - regs.p.c = !regs.p.c; -} - -template void SMPcore::op_seti() { - op_io(); - op_io(); - regs.p.i = value; -} - -template void SMPcore::op_setbit_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = (op ? rd | value : rd & ~value); - op_writedp(dp, rd); -} - -template void SMPcore::op_push_reg() { - op_io(); - op_io(); - op_writestack(regs.r[n]); -} - -void SMPcore::op_push_p() { - op_io(); - op_io(); - op_writestack(regs.p); -} - -template void SMPcore::op_pop_reg() { - op_io(); - op_io(); - regs.r[n] = op_readstack(); -} - -void SMPcore::op_pop_p() { - op_io(); - op_io(); - regs.p = op_readstack(); -} - -void SMPcore::op_mul_ya() { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - ya = regs.y * regs.a; - regs.a = ya; - regs.y = ya >> 8; - //result is set based on y (high-byte) only - regs.p.n = !!(regs.y & 0x80); - regs.p.z = (regs.y == 0); -} - -void SMPcore::op_div_ya_x() { - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - op_io(); - ya = regs.ya; - //overflow set if quotient >= 256 - regs.p.v = !!(regs.y >= regs.x); - regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); - if(regs.y < (regs.x << 1)) { - //if quotient is <= 511 (will fit into 9-bit result) - regs.a = ya / regs.x; - regs.y = ya % regs.x; - } else { - //otherwise, the quotient won't fit into regs.p.v + regs.a - //this emulates the odd behavior of the S-SMP in this case - regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x); - regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); - } - //result is set based on a (quotient) only - regs.p.n = !!(regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -#endif diff --git a/snes/fast/smp/core/opcode_mov.cpp b/snes/fast/smp/core/opcode_mov.cpp deleted file mode 100755 index e21593c8..00000000 --- a/snes/fast/smp/core/opcode_mov.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#ifdef SMPCORE_CPP - -template void SMPcore::op_mov_reg_reg() { - op_io(); - regs.r[to] = regs.r[from]; - regs.p.n = (regs.r[to] & 0x80); - regs.p.z = (regs.r[to] == 0); -} - -void SMPcore::op_mov_sp_x() { - op_io(); - regs.sp = regs.x; -} - -template void SMPcore::op_mov_reg_const() { - regs.r[n] = op_readpc(); - regs.p.n = (regs.r[n] & 0x80); - regs.p.z = (regs.r[n] == 0); -} - -void SMPcore::op_mov_a_ix() { - op_io(); - regs.a = op_readdp(regs.x); - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -void SMPcore::op_mov_a_ixinc() { - op_io(); - regs.a = op_readdp(regs.x++); - op_io(); - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -template void SMPcore::op_mov_reg_dp() { - sp = op_readpc(); - regs.r[n] = op_readdp(sp); - regs.p.n = (regs.r[n] & 0x80); - regs.p.z = (regs.r[n] == 0); -} - -template void SMPcore::op_mov_reg_dpr() { - sp = op_readpc(); - op_io(); - regs.r[n] = op_readdp(sp + regs.r[i]); - regs.p.n = (regs.r[n] & 0x80); - regs.p.z = (regs.r[n] == 0); -} - -template void SMPcore::op_mov_reg_addr() { - sp = op_readpc() << 0; - sp |= op_readpc() << 8; - regs.r[n] = op_readaddr(sp); - regs.p.n = (regs.r[n] & 0x80); - regs.p.z = (regs.r[n] == 0); -} - -template void SMPcore::op_mov_a_addrr() { - sp = op_readpc() << 0; - sp |= op_readpc() << 8; - op_io(); - regs.a = op_readaddr(sp + regs.r[i]); - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -void SMPcore::op_mov_a_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp = op_readdp(dp + 0) << 0; - sp |= op_readdp(dp + 1) << 8; - regs.a = op_readaddr(sp); - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -void SMPcore::op_mov_a_idpy() { - dp = op_readpc(); - op_io(); - sp = op_readdp(dp + 0) << 0; - sp |= op_readdp(dp + 1) << 8; - regs.a = op_readaddr(sp + regs.y); - regs.p.n = (regs.a & 0x80); - regs.p.z = (regs.a == 0); -} - -void SMPcore::op_mov_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - op_writedp(dp, rd); -} - -void SMPcore::op_mov_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, rd); -} - -void SMPcore::op_mov_ix_a() { - op_io(); - op_readdp(regs.x); - op_writedp(regs.x, regs.a); -} - -void SMPcore::op_mov_ixinc_a() { - op_io(); - op_io(); - op_writedp(regs.x++, regs.a); -} - -template void SMPcore::op_mov_dp_reg() { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp, regs.r[n]); -} - -template void SMPcore::op_mov_dpr_reg() { - dp = op_readpc(); - op_io(); - dp += regs.r[i]; - op_readdp(dp); - op_writedp(dp, regs.r[n]); -} - -template void SMPcore::op_mov_addr_reg() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - op_readaddr(dp); - op_writeaddr(dp, regs.r[n]); -} - -template void SMPcore::op_mov_addrr_a() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - op_io(); - dp += regs.r[i]; - op_readaddr(dp); - op_writeaddr(dp, regs.a); -} - -void SMPcore::op_mov_idpx_a() { - sp = op_readpc(); - op_io(); - sp += regs.x; - dp = op_readdp(sp + 0) << 0; - dp |= op_readdp(sp + 1) << 8; - op_readaddr(dp); - op_writeaddr(dp, regs.a); -} - -void SMPcore::op_mov_idpy_a() { - sp = op_readpc(); - dp = op_readdp(sp + 0) << 0; - dp |= op_readdp(sp + 1) << 8; - op_io(); - dp += regs.y; - op_readaddr(dp); - op_writeaddr(dp, regs.a); -} - -void SMPcore::op_movw_ya_dp() { - sp = op_readpc(); - regs.a = op_readdp(sp + 0); - op_io(); - regs.y = op_readdp(sp + 1); - regs.p.n = (regs.ya & 0x8000); - regs.p.z = (regs.ya == 0); -} - -void SMPcore::op_movw_dp_ya() { - dp = op_readpc(); - op_readdp(dp); - op_writedp(dp + 0, regs.a); - op_writedp(dp + 1, regs.y); -} - -void SMPcore::op_mov1_c_bit() { - sp = op_readpc() << 0; - sp |= op_readpc() << 8; - bit = sp >> 13; - sp &= 0x1fff; - rd = op_readaddr(sp); - regs.p.c = (rd & (1 << bit)); -} - -void SMPcore::op_mov1_bit_c() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - (regs.p.c) ? rd |= (1 << bit) : rd &= ~(1 << bit); - op_io(); - op_writeaddr(dp, rd); -} - -#endif diff --git a/snes/fast/smp/core/opcode_pc.cpp b/snes/fast/smp/core/opcode_pc.cpp deleted file mode 100755 index b69d8416..00000000 --- a/snes/fast/smp/core/opcode_pc.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#ifdef SMPCORE_CPP - -void SMPcore::op_bra() { - rd = op_readpc(); - op_io(); - op_io(); - regs.pc += (int8)rd; -} - -template void SMPcore::op_branch() { - rd = op_readpc(); - if((bool)(regs.p & flag) != value) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} - -template void SMPcore::op_bitbranch() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if((bool)(sp & mask) != value) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} - -void SMPcore::op_cbne_dp() { - dp = op_readpc(); - sp = op_readdp(dp); - rd = op_readpc(); - op_io(); - if(regs.a == sp) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} - -void SMPcore::op_cbne_dpx() { - dp = op_readpc(); - op_io(); - sp = op_readdp(dp + regs.x); - rd = op_readpc(); - op_io(); - if(regs.a == sp) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} - -void SMPcore::op_dbnz_dp() { - dp = op_readpc(); - wr = op_readdp(dp); - op_writedp(dp, --wr); - rd = op_readpc(); - if(wr == 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} - -void SMPcore::op_dbnz_y() { - rd = op_readpc(); - op_io(); - regs.y--; - op_io(); - if(regs.y == 0) return; - op_io(); - op_io(); - regs.pc += (int8)rd; -} - -void SMPcore::op_jmp_addr() { - rd = op_readpc() << 0; - rd |= op_readpc() << 8; - regs.pc = rd; -} - -void SMPcore::op_jmp_iaddrx() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - op_io(); - dp += regs.x; - rd = op_readaddr(dp + 0) << 0; - rd |= op_readaddr(dp + 1) << 8; - regs.pc = rd; -} - -void SMPcore::op_call() { - rd = op_readpc() << 0; - rd |= op_readpc() << 8; - op_io(); - op_io(); - op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); - regs.pc = rd; -} - -void SMPcore::op_pcall() { - rd = op_readpc(); - op_io(); - op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); - regs.pc = 0xff00 | rd; -} - -template void SMPcore::op_tcall() { - dp = 0xffde - (n << 1); - rd = op_readaddr(dp + 0) << 0; - rd |= op_readaddr(dp + 1) << 8; - op_io(); - op_io(); - op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); - regs.pc = rd; -} - -void SMPcore::op_brk() { - rd = op_readaddr(0xffde) << 0; - rd |= op_readaddr(0xffdf) << 8; - op_io(); - op_io(); - op_writestack(regs.pc >> 8); - op_writestack(regs.pc >> 0); - op_writestack(regs.p); - regs.pc = rd; - regs.p.b = 1; - regs.p.i = 0; -} - -void SMPcore::op_ret() { - rd = op_readstack() << 0; - rd |= op_readstack() << 8; - op_io(); - op_io(); - regs.pc = rd; -} - -void SMPcore::op_reti() { - regs.p = op_readstack(); - rd = op_readstack() << 0; - rd |= op_readstack() << 8; - op_io(); - op_io(); - regs.pc = rd; -} - -#endif diff --git a/snes/fast/smp/core/opcode_read.cpp b/snes/fast/smp/core/opcode_read.cpp deleted file mode 100755 index 2058cff2..00000000 --- a/snes/fast/smp/core/opcode_read.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#ifdef SMPCORE_CPP - -template -void SMPcore::op_read_reg_const() { - rd = op_readpc(); - regs.r[n] = (this->*op)(regs.r[n], rd); -} - -template -void SMPcore::op_read_a_ix() { - op_io(); - rd = op_readdp(regs.x); - regs.a = (this->*op)(regs.a, rd); -} - -template -void SMPcore::op_read_reg_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - regs.r[n] = (this->*op)(regs.r[n], rd); -} - -template -void SMPcore::op_read_a_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - regs.a = (this->*op)(regs.a, rd); -} - -template -void SMPcore::op_read_reg_addr() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - rd = op_readaddr(dp); - regs.r[n] = (this->*op)(regs.r[n], rd); -} - -template -void SMPcore::op_read_a_addrr() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - op_io(); - rd = op_readaddr(dp + regs.r[i]); - regs.a = (this->*op)(regs.a, rd); -} - -template -void SMPcore::op_read_a_idpx() { - dp = op_readpc() + regs.x; - op_io(); - sp = op_readdp(dp + 0) << 0; - sp |= op_readdp(dp + 1) << 8; - rd = op_readaddr(sp); - regs.a = (this->*op)(regs.a, rd); -} - -template -void SMPcore::op_read_a_idpy() { - dp = op_readpc(); - op_io(); - sp = op_readdp(dp + 0) << 0; - sp |= op_readdp(dp + 1) << 8; - rd = op_readaddr(sp + regs.y); - regs.a = (this->*op)(regs.a, rd); -} - -template -void SMPcore::op_read_ix_iy() { - op_io(); - rd = op_readdp(regs.y); - wr = op_readdp(regs.x); - wr = (this->*op)(wr, rd); - static uint8 (SMPcore::*cmp)(uint8, uint8) = &SMPcore::op_cmp; - (op != cmp) ? op_writedp(regs.x, wr) : op_io(); -} - -template -void SMPcore::op_read_dp_dp() { - sp = op_readpc(); - rd = op_readdp(sp); - dp = op_readpc(); - wr = op_readdp(dp); - wr = (this->*op)(wr, rd); - static uint8 (SMPcore::*cmp)(uint8, uint8) = &SMPcore::op_cmp; - (op != cmp) ? op_writedp(dp, wr) : op_io(); -} - -template -void SMPcore::op_read_dp_const() { - rd = op_readpc(); - dp = op_readpc(); - wr = op_readdp(dp); - wr = (this->*op)(wr, rd); - static uint8 (SMPcore::*cmp)(uint8, uint8) = &SMPcore::op_cmp; - (op != cmp) ? op_writedp(dp, wr) : op_io(); -} - -template -void SMPcore::op_read_ya_dp() { - dp = op_readpc(); - rd = op_readdp(dp + 0) << 0; - op_io(); - rd |= op_readdp(dp + 1) << 8; - regs.ya = (this->*op)(regs.ya, rd); -} - -void SMPcore::op_cmpw_ya_dp() { - dp = op_readpc(); - rd = op_readdp(dp + 0) << 0; - rd |= op_readdp(dp + 1) << 8; - op_cmpw(regs.ya, rd); -} - -template void SMPcore::op_and1_bit() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - regs.p.c = regs.p.c & ((bool)(rd & (1 << bit)) ^ op); -} - -void SMPcore::op_eor1_bit() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - op_io(); - regs.p.c = regs.p.c ^ (bool)(rd & (1 << bit)); -} - -void SMPcore::op_not1_bit() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - rd ^= 1 << bit; - op_writeaddr(dp, rd); -} - -template void SMPcore::op_or1_bit() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - bit = dp >> 13; - dp &= 0x1fff; - rd = op_readaddr(dp); - op_io(); - regs.p.c = regs.p.c | ((bool)(rd & (1 << bit)) ^ op); -} - -#endif diff --git a/snes/fast/smp/core/opcode_rmw.cpp b/snes/fast/smp/core/opcode_rmw.cpp deleted file mode 100755 index 103bd2db..00000000 --- a/snes/fast/smp/core/opcode_rmw.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#ifdef SMPCORE_CPP - -template -void SMPcore::op_adjust_reg() { - op_io(); - regs.r[n] = (this->*op)(regs.r[n]); -} - -template -void SMPcore::op_adjust_dp() { - dp = op_readpc(); - rd = op_readdp(dp); - rd = (this->*op)(rd); - op_writedp(dp, rd); -} - -template -void SMPcore::op_adjust_dpx() { - dp = op_readpc(); - op_io(); - rd = op_readdp(dp + regs.x); - rd = (this->*op)(rd); - op_writedp(dp + regs.x, rd); -} - -template -void SMPcore::op_adjust_addr() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - rd = op_readaddr(dp); - rd = (this->*op)(rd); - op_writeaddr(dp, rd); -} - -template -void SMPcore::op_adjust_addr_a() { - dp = op_readpc() << 0; - dp |= op_readpc() << 8; - rd = op_readaddr(dp); - regs.p.n = ((regs.a - rd) & 0x80); - regs.p.z = ((regs.a - rd) == 0); - op_readaddr(dp); - op_writeaddr(dp, (op ? rd | regs.a : rd & ~regs.a)); -} - -template -void SMPcore::op_adjustw_dp() { - dp = op_readpc(); - rd = op_readdp(dp) << 0; - rd += adjust; - op_writedp(dp++, rd); - rd += op_readdp(dp) << 8; - op_writedp(dp, rd >> 8); - regs.p.n = (rd & 0x8000); - regs.p.z = (rd == 0); -} - -#endif diff --git a/snes/fast/smp/core/registers.hpp b/snes/fast/smp/core/registers.hpp deleted file mode 100755 index baed447b..00000000 --- a/snes/fast/smp/core/registers.hpp +++ /dev/null @@ -1,44 +0,0 @@ -struct regya_t { - uint8_t &hi, &lo; - - inline operator uint16_t() const { - return (hi << 8) + lo; - } - - inline regya_t& operator=(uint16_t data) { - hi = data >> 8; - lo = data; - return *this; - } - - regya_t(uint8_t &hi_, uint8_t &lo_) : hi(hi_), lo(lo_) {} -}; - -struct flag_t { - bool n, v, p, b, h, i, z, c; - - inline operator unsigned() const { - return (n << 7) + (v << 6) + (p << 5) + (b << 4) - + (h << 3) + (i << 2) + (z << 1) + (c << 0); - } - - inline unsigned operator=(uint8_t data) { - n = data & 0x80; v = data & 0x40; p = data & 0x20; b = data & 0x10; - h = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01; - return data; - } - - inline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); } - inline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); } - inline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); } - - flag_t() : n(0), v(0), p(0), b(0), h(0), i(0), z(0), c(0) {} -}; - -struct regs_t { - uint16_t pc; - uint8_t r[4], &a, &x, &y, &sp; - regya_t ya; - flag_t p; - regs_t() : a(r[0]), x(r[1]), y(r[2]), sp(r[3]), ya(r[2], r[0]) {} -}; diff --git a/snes/fast/smp/core/serialization.cpp b/snes/fast/smp/core/serialization.cpp deleted file mode 100755 index 883d013c..00000000 --- a/snes/fast/smp/core/serialization.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef SMPCORE_CPP - -void SMPcore::core_serialize(serializer &s) { - s.integer(regs.pc); - s.integer(regs.a); - s.integer(regs.x); - s.integer(regs.y); - s.integer(regs.sp); - s.integer(regs.p.n); - s.integer(regs.p.v); - s.integer(regs.p.p); - s.integer(regs.p.b); - s.integer(regs.p.h); - s.integer(regs.p.i); - s.integer(regs.p.z); - s.integer(regs.p.c); - - s.integer(dp); - s.integer(sp); - s.integer(rd); - s.integer(wr); - s.integer(bit); - s.integer(ya); -} - -#endif diff --git a/snes/fast/smp/core/table.cpp b/snes/fast/smp/core/table.cpp deleted file mode 100755 index dc0f633a..00000000 --- a/snes/fast/smp/core/table.cpp +++ /dev/null @@ -1,264 +0,0 @@ -#ifdef SMPCORE_CPP - -void SMPcore::initialize_opcode_table() { - #define op opcode_table - op[0x00] = &SMPcore::op_nop; - op[0x01] = &SMPcore::op_tcall<0>; - op[0x02] = &SMPcore::op_setbit_dp<1, 0x01>; - op[0x03] = &SMPcore::op_bitbranch<0x01, true>; - op[0x04] = &SMPcore::op_read_reg_dp<&SMPcore::op_or, A>; - op[0x05] = &SMPcore::op_read_reg_addr<&SMPcore::op_or, A>; - op[0x06] = &SMPcore::op_read_a_ix<&SMPcore::op_or>; - op[0x07] = &SMPcore::op_read_a_idpx<&SMPcore::op_or>; - op[0x08] = &SMPcore::op_read_reg_const<&SMPcore::op_or, A>; - op[0x09] = &SMPcore::op_read_dp_dp<&SMPcore::op_or>; - op[0x0a] = &SMPcore::op_or1_bit<0>; - op[0x0b] = &SMPcore::op_adjust_dp<&SMPcore::op_asl>; - op[0x0c] = &SMPcore::op_adjust_addr<&SMPcore::op_asl>; - op[0x0d] = &SMPcore::op_push_p; - op[0x0e] = &SMPcore::op_adjust_addr_a<1>; - op[0x0f] = &SMPcore::op_brk; - op[0x10] = &SMPcore::op_branch<0x80, false>; - op[0x11] = &SMPcore::op_tcall<1>; - op[0x12] = &SMPcore::op_setbit_dp<0, 0x01>; - op[0x13] = &SMPcore::op_bitbranch<0x01, false>; - op[0x14] = &SMPcore::op_read_a_dpx<&SMPcore::op_or>; - op[0x15] = &SMPcore::op_read_a_addrr<&SMPcore::op_or, X>; - op[0x16] = &SMPcore::op_read_a_addrr<&SMPcore::op_or, Y>; - op[0x17] = &SMPcore::op_read_a_idpy<&SMPcore::op_or>; - op[0x18] = &SMPcore::op_read_dp_const<&SMPcore::op_or>; - op[0x19] = &SMPcore::op_read_ix_iy<&SMPcore::op_or>; - op[0x1a] = &SMPcore::op_adjustw_dp<-1>; - op[0x1b] = &SMPcore::op_adjust_dpx<&SMPcore::op_asl>; - op[0x1c] = &SMPcore::op_adjust_reg<&SMPcore::op_asl, A>; - op[0x1d] = &SMPcore::op_adjust_reg<&SMPcore::op_dec, X>; - op[0x1e] = &SMPcore::op_read_reg_addr<&SMPcore::op_cmp, X>; - op[0x1f] = &SMPcore::op_jmp_iaddrx; - op[0x20] = &SMPcore::op_setbit<0x20, 0x00>; - op[0x21] = &SMPcore::op_tcall<2>; - op[0x22] = &SMPcore::op_setbit_dp<1, 0x02>; - op[0x23] = &SMPcore::op_bitbranch<0x02, true>; - op[0x24] = &SMPcore::op_read_reg_dp<&SMPcore::op_and, A>; - op[0x25] = &SMPcore::op_read_reg_addr<&SMPcore::op_and, A>; - op[0x26] = &SMPcore::op_read_a_ix<&SMPcore::op_and>; - op[0x27] = &SMPcore::op_read_a_idpx<&SMPcore::op_and>; - op[0x28] = &SMPcore::op_read_reg_const<&SMPcore::op_and, A>; - op[0x29] = &SMPcore::op_read_dp_dp<&SMPcore::op_and>; - op[0x2a] = &SMPcore::op_or1_bit<1>; - op[0x2b] = &SMPcore::op_adjust_dp<&SMPcore::op_rol>; - op[0x2c] = &SMPcore::op_adjust_addr<&SMPcore::op_rol>; - op[0x2d] = &SMPcore::op_push_reg; - op[0x2e] = &SMPcore::op_cbne_dp; - op[0x2f] = &SMPcore::op_bra; - op[0x30] = &SMPcore::op_branch<0x80, true>; - op[0x31] = &SMPcore::op_tcall<3>; - op[0x32] = &SMPcore::op_setbit_dp<0, 0x02>; - op[0x33] = &SMPcore::op_bitbranch<0x02, false>; - op[0x34] = &SMPcore::op_read_a_dpx<&SMPcore::op_and>; - op[0x35] = &SMPcore::op_read_a_addrr<&SMPcore::op_and, X>; - op[0x36] = &SMPcore::op_read_a_addrr<&SMPcore::op_and, Y>; - op[0x37] = &SMPcore::op_read_a_idpy<&SMPcore::op_and>; - op[0x38] = &SMPcore::op_read_dp_const<&SMPcore::op_and>; - op[0x39] = &SMPcore::op_read_ix_iy<&SMPcore::op_and>; - op[0x3a] = &SMPcore::op_adjustw_dp<+1>; - op[0x3b] = &SMPcore::op_adjust_dpx<&SMPcore::op_rol>; - op[0x3c] = &SMPcore::op_adjust_reg<&SMPcore::op_rol, A>; - op[0x3d] = &SMPcore::op_adjust_reg<&SMPcore::op_inc, X>; - op[0x3e] = &SMPcore::op_read_reg_dp<&SMPcore::op_cmp, X>; - op[0x3f] = &SMPcore::op_call; - op[0x40] = &SMPcore::op_setbit<0x20, 0x20>; - op[0x41] = &SMPcore::op_tcall<4>; - op[0x42] = &SMPcore::op_setbit_dp<1, 0x04>; - op[0x43] = &SMPcore::op_bitbranch<0x04, true>; - op[0x44] = &SMPcore::op_read_reg_dp<&SMPcore::op_eor, A>; - op[0x45] = &SMPcore::op_read_reg_addr<&SMPcore::op_eor, A>; - op[0x46] = &SMPcore::op_read_a_ix<&SMPcore::op_eor>; - op[0x47] = &SMPcore::op_read_a_idpx<&SMPcore::op_eor>; - op[0x48] = &SMPcore::op_read_reg_const<&SMPcore::op_eor, A>; - op[0x49] = &SMPcore::op_read_dp_dp<&SMPcore::op_eor>; - op[0x4a] = &SMPcore::op_and1_bit<0>; - op[0x4b] = &SMPcore::op_adjust_dp<&SMPcore::op_lsr>; - op[0x4c] = &SMPcore::op_adjust_addr<&SMPcore::op_lsr>; - op[0x4d] = &SMPcore::op_push_reg; - op[0x4e] = &SMPcore::op_adjust_addr_a<0>; - op[0x4f] = &SMPcore::op_pcall; - op[0x50] = &SMPcore::op_branch<0x40, false>; - op[0x51] = &SMPcore::op_tcall<5>; - op[0x52] = &SMPcore::op_setbit_dp<0, 0x04>; - op[0x53] = &SMPcore::op_bitbranch<0x04, false>; - op[0x54] = &SMPcore::op_read_a_dpx<&SMPcore::op_eor>; - op[0x55] = &SMPcore::op_read_a_addrr<&SMPcore::op_eor, X>; - op[0x56] = &SMPcore::op_read_a_addrr<&SMPcore::op_eor, Y>; - op[0x57] = &SMPcore::op_read_a_idpy<&SMPcore::op_eor>; - op[0x58] = &SMPcore::op_read_dp_const<&SMPcore::op_eor>; - op[0x59] = &SMPcore::op_read_ix_iy<&SMPcore::op_eor>; - op[0x5a] = &SMPcore::op_cmpw_ya_dp; - op[0x5b] = &SMPcore::op_adjust_dpx<&SMPcore::op_lsr>; - op[0x5c] = &SMPcore::op_adjust_reg<&SMPcore::op_lsr, A>; - op[0x5d] = &SMPcore::op_mov_reg_reg; - op[0x5e] = &SMPcore::op_read_reg_addr<&SMPcore::op_cmp, Y>; - op[0x5f] = &SMPcore::op_jmp_addr; - op[0x60] = &SMPcore::op_setbit<0x01, 0x00>; - op[0x61] = &SMPcore::op_tcall<6>; - op[0x62] = &SMPcore::op_setbit_dp<1, 0x08>; - op[0x63] = &SMPcore::op_bitbranch<0x08, true>; - op[0x64] = &SMPcore::op_read_reg_dp<&SMPcore::op_cmp, A>; - op[0x65] = &SMPcore::op_read_reg_addr<&SMPcore::op_cmp, A>; - op[0x66] = &SMPcore::op_read_a_ix<&SMPcore::op_cmp>; - op[0x67] = &SMPcore::op_read_a_idpx<&SMPcore::op_cmp>; - op[0x68] = &SMPcore::op_read_reg_const<&SMPcore::op_cmp, A>; - op[0x69] = &SMPcore::op_read_dp_dp<&SMPcore::op_cmp>; - op[0x6a] = &SMPcore::op_and1_bit<1>; - op[0x6b] = &SMPcore::op_adjust_dp<&SMPcore::op_ror>; - op[0x6c] = &SMPcore::op_adjust_addr<&SMPcore::op_ror>; - op[0x6d] = &SMPcore::op_push_reg; - op[0x6e] = &SMPcore::op_dbnz_dp; - op[0x6f] = &SMPcore::op_ret; - op[0x70] = &SMPcore::op_branch<0x40, true>; - op[0x71] = &SMPcore::op_tcall<7>; - op[0x72] = &SMPcore::op_setbit_dp<0, 0x08>; - op[0x73] = &SMPcore::op_bitbranch<0x08, false>; - op[0x74] = &SMPcore::op_read_a_dpx<&SMPcore::op_cmp>; - op[0x75] = &SMPcore::op_read_a_addrr<&SMPcore::op_cmp, X>; - op[0x76] = &SMPcore::op_read_a_addrr<&SMPcore::op_cmp, Y>; - op[0x77] = &SMPcore::op_read_a_idpy<&SMPcore::op_cmp>; - op[0x78] = &SMPcore::op_read_dp_const<&SMPcore::op_cmp>; - op[0x79] = &SMPcore::op_read_ix_iy<&SMPcore::op_cmp>; - op[0x7a] = &SMPcore::op_read_ya_dp<&SMPcore::op_addw>; - op[0x7b] = &SMPcore::op_adjust_dpx<&SMPcore::op_ror>; - op[0x7c] = &SMPcore::op_adjust_reg<&SMPcore::op_ror, A>; - op[0x7d] = &SMPcore::op_mov_reg_reg; - op[0x7e] = &SMPcore::op_read_reg_dp<&SMPcore::op_cmp, Y>; - op[0x7f] = &SMPcore::op_reti; - op[0x80] = &SMPcore::op_setbit<0x01, 0x01>; - op[0x81] = &SMPcore::op_tcall<8>; - op[0x82] = &SMPcore::op_setbit_dp<1, 0x10>; - op[0x83] = &SMPcore::op_bitbranch<0x10, true>; - op[0x84] = &SMPcore::op_read_reg_dp<&SMPcore::op_adc, A>; - op[0x85] = &SMPcore::op_read_reg_addr<&SMPcore::op_adc, A>; - op[0x86] = &SMPcore::op_read_a_ix<&SMPcore::op_adc>; - op[0x87] = &SMPcore::op_read_a_idpx<&SMPcore::op_adc>; - op[0x88] = &SMPcore::op_read_reg_const<&SMPcore::op_adc, A>; - op[0x89] = &SMPcore::op_read_dp_dp<&SMPcore::op_adc>; - op[0x8a] = &SMPcore::op_eor1_bit; - op[0x8b] = &SMPcore::op_adjust_dp<&SMPcore::op_dec>; - op[0x8c] = &SMPcore::op_adjust_addr<&SMPcore::op_dec>; - op[0x8d] = &SMPcore::op_mov_reg_const; - op[0x8e] = &SMPcore::op_pop_p; - op[0x8f] = &SMPcore::op_mov_dp_const; - op[0x90] = &SMPcore::op_branch<0x01, false>; - op[0x91] = &SMPcore::op_tcall<9>; - op[0x92] = &SMPcore::op_setbit_dp<0, 0x10>; - op[0x93] = &SMPcore::op_bitbranch<0x10, false>; - op[0x94] = &SMPcore::op_read_a_dpx<&SMPcore::op_adc>; - op[0x95] = &SMPcore::op_read_a_addrr<&SMPcore::op_adc, X>; - op[0x96] = &SMPcore::op_read_a_addrr<&SMPcore::op_adc, Y>; - op[0x97] = &SMPcore::op_read_a_idpy<&SMPcore::op_adc>; - op[0x98] = &SMPcore::op_read_dp_const<&SMPcore::op_adc>; - op[0x99] = &SMPcore::op_read_ix_iy<&SMPcore::op_adc>; - op[0x9a] = &SMPcore::op_read_ya_dp<&SMPcore::op_subw>; - op[0x9b] = &SMPcore::op_adjust_dpx<&SMPcore::op_dec>; - op[0x9c] = &SMPcore::op_adjust_reg<&SMPcore::op_dec, A>; - op[0x9d] = &SMPcore::op_mov_reg_reg; - op[0x9e] = &SMPcore::op_div_ya_x; - op[0x9f] = &SMPcore::op_xcn; - op[0xa0] = &SMPcore::op_seti<1>; - op[0xa1] = &SMPcore::op_tcall<10>; - op[0xa2] = &SMPcore::op_setbit_dp<1, 0x20>; - op[0xa3] = &SMPcore::op_bitbranch<0x20, true>; - op[0xa4] = &SMPcore::op_read_reg_dp<&SMPcore::op_sbc, A>; - op[0xa5] = &SMPcore::op_read_reg_addr<&SMPcore::op_sbc, A>; - op[0xa6] = &SMPcore::op_read_a_ix<&SMPcore::op_sbc>; - op[0xa7] = &SMPcore::op_read_a_idpx<&SMPcore::op_sbc>; - op[0xa8] = &SMPcore::op_read_reg_const<&SMPcore::op_sbc, A>; - op[0xa9] = &SMPcore::op_read_dp_dp<&SMPcore::op_sbc>; - op[0xaa] = &SMPcore::op_mov1_c_bit; - op[0xab] = &SMPcore::op_adjust_dp<&SMPcore::op_inc>; - op[0xac] = &SMPcore::op_adjust_addr<&SMPcore::op_inc>; - op[0xad] = &SMPcore::op_read_reg_const<&SMPcore::op_cmp, Y>; - op[0xae] = &SMPcore::op_pop_reg; - op[0xaf] = &SMPcore::op_mov_ixinc_a; - op[0xb0] = &SMPcore::op_branch<0x01, true>; - op[0xb1] = &SMPcore::op_tcall<11>; - op[0xb2] = &SMPcore::op_setbit_dp<0, 0x20>; - op[0xb3] = &SMPcore::op_bitbranch<0x20, false>; - op[0xb4] = &SMPcore::op_read_a_dpx<&SMPcore::op_sbc>; - op[0xb5] = &SMPcore::op_read_a_addrr<&SMPcore::op_sbc, X>; - op[0xb6] = &SMPcore::op_read_a_addrr<&SMPcore::op_sbc, Y>; - op[0xb7] = &SMPcore::op_read_a_idpy<&SMPcore::op_sbc>; - op[0xb8] = &SMPcore::op_read_dp_const<&SMPcore::op_sbc>; - op[0xb9] = &SMPcore::op_read_ix_iy<&SMPcore::op_sbc>; - op[0xba] = &SMPcore::op_movw_ya_dp; - op[0xbb] = &SMPcore::op_adjust_dpx<&SMPcore::op_inc>; - op[0xbc] = &SMPcore::op_adjust_reg<&SMPcore::op_inc, A>; - op[0xbd] = &SMPcore::op_mov_sp_x; - op[0xbe] = &SMPcore::op_das; - op[0xbf] = &SMPcore::op_mov_a_ixinc; - op[0xc0] = &SMPcore::op_seti<0>; - op[0xc1] = &SMPcore::op_tcall<12>; - op[0xc2] = &SMPcore::op_setbit_dp<1, 0x40>; - op[0xc3] = &SMPcore::op_bitbranch<0x40, true>; - op[0xc4] = &SMPcore::op_mov_dp_reg; - op[0xc5] = &SMPcore::op_mov_addr_reg; - op[0xc6] = &SMPcore::op_mov_ix_a; - op[0xc7] = &SMPcore::op_mov_idpx_a; - op[0xc8] = &SMPcore::op_read_reg_const<&SMPcore::op_cmp, X>; - op[0xc9] = &SMPcore::op_mov_addr_reg; - op[0xca] = &SMPcore::op_mov1_bit_c; - op[0xcb] = &SMPcore::op_mov_dp_reg; - op[0xcc] = &SMPcore::op_mov_addr_reg; - op[0xcd] = &SMPcore::op_mov_reg_const; - op[0xce] = &SMPcore::op_pop_reg; - op[0xcf] = &SMPcore::op_mul_ya; - op[0xd0] = &SMPcore::op_branch<0x02, false>; - op[0xd1] = &SMPcore::op_tcall<13>; - op[0xd2] = &SMPcore::op_setbit_dp<0, 0x40>; - op[0xd3] = &SMPcore::op_bitbranch<0x40, false>; - op[0xd4] = &SMPcore::op_mov_dpr_reg; - op[0xd5] = &SMPcore::op_mov_addrr_a; - op[0xd6] = &SMPcore::op_mov_addrr_a; - op[0xd7] = &SMPcore::op_mov_idpy_a; - op[0xd8] = &SMPcore::op_mov_dp_reg; - op[0xd9] = &SMPcore::op_mov_dpr_reg; - op[0xda] = &SMPcore::op_movw_dp_ya; - op[0xdb] = &SMPcore::op_mov_dpr_reg; - op[0xdc] = &SMPcore::op_adjust_reg<&SMPcore::op_dec, Y>; - op[0xdd] = &SMPcore::op_mov_reg_reg; - op[0xde] = &SMPcore::op_cbne_dpx; - op[0xdf] = &SMPcore::op_daa; - op[0xe0] = &SMPcore::op_setbit<0x48, 0x00>; - op[0xe1] = &SMPcore::op_tcall<14>; - op[0xe2] = &SMPcore::op_setbit_dp<1, 0x80>; - op[0xe3] = &SMPcore::op_bitbranch<0x80, true>; - op[0xe4] = &SMPcore::op_mov_reg_dp; - op[0xe5] = &SMPcore::op_mov_reg_addr; - op[0xe6] = &SMPcore::op_mov_a_ix; - op[0xe7] = &SMPcore::op_mov_a_idpx; - op[0xe8] = &SMPcore::op_mov_reg_const; - op[0xe9] = &SMPcore::op_mov_reg_addr; - op[0xea] = &SMPcore::op_not1_bit; - op[0xeb] = &SMPcore::op_mov_reg_dp; - op[0xec] = &SMPcore::op_mov_reg_addr; - op[0xed] = &SMPcore::op_notc; - op[0xee] = &SMPcore::op_pop_reg; - op[0xef] = &SMPcore::op_wait; - op[0xf0] = &SMPcore::op_branch<0x02, true>; - op[0xf1] = &SMPcore::op_tcall<15>; - op[0xf2] = &SMPcore::op_setbit_dp<0, 0x80>; - op[0xf3] = &SMPcore::op_bitbranch<0x80, false>; - op[0xf4] = &SMPcore::op_mov_reg_dpr; - op[0xf5] = &SMPcore::op_mov_a_addrr; - op[0xf6] = &SMPcore::op_mov_a_addrr; - op[0xf7] = &SMPcore::op_mov_a_idpy; - op[0xf8] = &SMPcore::op_mov_reg_dp; - op[0xf9] = &SMPcore::op_mov_reg_dpr; - op[0xfa] = &SMPcore::op_mov_dp_dp; - op[0xfb] = &SMPcore::op_mov_reg_dpr; - op[0xfc] = &SMPcore::op_adjust_reg<&SMPcore::op_inc, Y>; - op[0xfd] = &SMPcore::op_mov_reg_reg; - op[0xfe] = &SMPcore::op_dbnz_y; - op[0xff] = &SMPcore::op_wait; - #undef op -} - -#endif diff --git a/snes/fast/smp/serialization.cpp b/snes/fast/smp/serialization.cpp index be2b992a..ea7c695d 100755 --- a/snes/fast/smp/serialization.cpp +++ b/snes/fast/smp/serialization.cpp @@ -1,6 +1,32 @@ #ifdef SMP_CPP +static void smp_state_save(unsigned char **out, void *in, size_t size) { + memcpy(*out, in, size); + *out += size; +} + +static void smp_state_load(unsigned char **in, void *out, size_t size) { + memcpy(out, *in, size); + *in += size; +} + void SMP::serialize(serializer &s) { + Processor::serialize(s); + s.integer(snes_spc_time); + s.array(samplebuffer); + + unsigned char state[SNES_SPC::state_size]; + unsigned char *p = state; + memset(&state, 0, SNES_SPC::state_size); + if(s.mode() == serializer::Save) { + snes_spc.copy_state(&p, smp_state_save); + s.array(state); + } else if(s.mode() == serializer::Load) { + s.array(state); + snes_spc.copy_state(&p, smp_state_load); + } else { + s.array(state); + } } #endif diff --git a/snes/fast/smp/smp.cpp b/snes/fast/smp/smp.cpp index 0798b75f..8124778b 100755 --- a/snes/fast/smp/smp.cpp +++ b/snes/fast/smp/smp.cpp @@ -21,9 +21,19 @@ void SMP::step(unsigned clocks) { } void SMP::synchronize_cpu() { + if(CPU::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + } else { + while(clock >= 0) cpu.enter(); + } } void SMP::synchronize_dsp() { + if(DSP::Threaded == true) { + if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); + } else { + while(dsp.clock < 0) dsp.enter(); + } } uint8 SMP::port_read(uint8 port) { @@ -34,7 +44,7 @@ void SMP::port_write(uint8 port, uint8 data) { snes_spc.write_port(snes_spc_time, port & 3, data); } -void SMP::run() { +void SMP::enter() { step(24); if(++snes_spc_time >= snes_spc.clock_rate / 60) { snes_spc.end_frame(snes_spc_time); diff --git a/snes/fast/smp/smp.hpp b/snes/fast/smp/smp.hpp index a7892265..cc37e072 100755 --- a/snes/fast/smp/smp.hpp +++ b/snes/fast/smp/smp.hpp @@ -2,6 +2,7 @@ class SMP : public Processor { public: + enum : bool { Threaded = false }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); alwaysinline void synchronize_dsp(); @@ -9,7 +10,7 @@ public: uint8 port_read(uint8 port); void port_write(uint8 port, uint8 data); - void run(); + void enter(); void power(); void reset(); diff --git a/snes/ppu/ppu.cpp b/snes/ppu/ppu.cpp index b57f28c7..d633b40f 100755 --- a/snes/ppu/ppu.cpp +++ b/snes/ppu/ppu.cpp @@ -22,7 +22,11 @@ void PPU::step(unsigned clocks) { } void PPU::synchronize_cpu() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + if(CPU::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + } else { + while(clock >= 0) cpu.enter(); + } } void PPU::Enter() { ppu.enter(); } diff --git a/snes/ppu/ppu.hpp b/snes/ppu/ppu.hpp index 69456f83..82b98ae6 100755 --- a/snes/ppu/ppu.hpp +++ b/snes/ppu/ppu.hpp @@ -1,5 +1,6 @@ class PPU : public Processor, public PPUcounter, public MMIO { public: + enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); @@ -8,6 +9,7 @@ public: bool overscan() const; bool hires() const; + void enter(); void power(); void reset(); @@ -42,7 +44,6 @@ private: } display; static void Enter(); - void enter(); void add_clocks(unsigned); void scanline(); diff --git a/snes/profile-asnes.hpp b/snes/profile-asnes.hpp deleted file mode 100755 index db8fb302..00000000 --- a/snes/profile-asnes.hpp +++ /dev/null @@ -1,10 +0,0 @@ -namespace Info { - static const char Name[] = "asnes"; - static const char Version[] = "067.20"; - static const unsigned SerializerVersion = 12; -} - -#include -#include -#include -#include diff --git a/snes/profile-baseline.hpp b/snes/profile-baseline.hpp new file mode 100755 index 00000000..1ee4d403 --- /dev/null +++ b/snes/profile-baseline.hpp @@ -0,0 +1,9 @@ +namespace Info { + static const char Profile[] = "Baseline"; + static const char ProfileName[] = "Supersedence"; +} + +#include +#include +#include +#include diff --git a/snes/profile-bsnes.hpp b/snes/profile-bsnes.hpp deleted file mode 100755 index b3fbc6ac..00000000 --- a/snes/profile-bsnes.hpp +++ /dev/null @@ -1,10 +0,0 @@ -namespace Info { - static const char Name[] = "bsnes"; - static const char Version[] = "067.20"; - static const unsigned SerializerVersion = 12; -} - -#include -#include -#include -#include diff --git a/snes/profile-csnes.hpp b/snes/profile-csnes.hpp deleted file mode 100755 index fd78b835..00000000 --- a/snes/profile-csnes.hpp +++ /dev/null @@ -1,10 +0,0 @@ -namespace Info { - static const char Name[] = "csnes"; - static const char Version[] = "067.20"; - static const unsigned SerializerVersion = 12; -} - -#include -#include -#include -#include diff --git a/snes/profile-performance.hpp b/snes/profile-performance.hpp new file mode 100755 index 00000000..a0040af0 --- /dev/null +++ b/snes/profile-performance.hpp @@ -0,0 +1,9 @@ +namespace Info { + static const char Profile[] = "Performance"; + static const char ProfileName[] = "Supersonic"; +} + +#include +#include +#include +#include diff --git a/snes/profile-research.hpp b/snes/profile-research.hpp new file mode 100755 index 00000000..ca1b8d75 --- /dev/null +++ b/snes/profile-research.hpp @@ -0,0 +1,9 @@ +namespace Info { + static const char Profile[] = "Research"; + static const char ProfileName[] = "Superfluous"; +} + +#include +#include +#include +#include diff --git a/snes/smp/smp.cpp b/snes/smp/smp.cpp index f35cfc42..6b7da28c 100755 --- a/snes/smp/smp.cpp +++ b/snes/smp/smp.cpp @@ -21,15 +21,19 @@ void SMP::step(unsigned clocks) { } void SMP::synchronize_cpu() { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + if(CPU::Threaded == true) { + if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + } else { + while(clock >= 0) cpu.enter(); + } } void SMP::synchronize_dsp() { - #if defined(PROFILE_ASNES) - if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); - #else - while(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) dsp.run(); - #endif + if(DSP::Threaded == true) { + if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); + } else { + while(dsp.clock < 0) dsp.enter(); + } } void SMP::Enter() { smp.enter(); } diff --git a/snes/smp/smp.hpp b/snes/smp/smp.hpp index b8d0bc6b..cb8211e4 100755 --- a/snes/smp/smp.hpp +++ b/snes/smp/smp.hpp @@ -1,5 +1,6 @@ class SMP : public Processor, public SMPcore { public: + enum : bool { Threaded = true }; alwaysinline void step(unsigned clocks); alwaysinline void synchronize_cpu(); alwaysinline void synchronize_dsp(); @@ -7,6 +8,7 @@ public: uint8 port_read(uint8 port); void port_write(uint8 port, uint8 data); + void enter(); void power(); void reset(); @@ -45,7 +47,6 @@ private: } status; static void Enter(); - void enter(); debugvirtual void op_step(); friend class SMPcore; diff --git a/snes/snes.hpp b/snes/snes.hpp index 32138e72..0ff0f13c 100755 --- a/snes/snes.hpp +++ b/snes/snes.hpp @@ -1,3 +1,11 @@ +namespace SNES { + namespace Info { + static const char Name[] = "bsnes"; + static const char Version[] = "067.21"; + static const unsigned SerializerVersion = 12; + } +} + //#define DEBUGGER #define CHEAT_SYSTEM @@ -14,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -67,12 +76,12 @@ namespace SNES { #include #include - #if defined(PROFILE_ASNES) - #include "profile-asnes.hpp" - #elif defined(PROFILE_BSNES) - #include "profile-bsnes.hpp" - #elif defined(PROFILE_CSNES) - #include "profile-csnes.hpp" + #if defined(PROFILE_RESEARCH) + #include "profile-research.hpp" + #elif defined(PROFILE_BASELINE) + #include "profile-baseline.hpp" + #elif defined(PROFILE_PERFORMANCE) + #include "profile-performance.hpp" #endif #include diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp index da72b4bb..bc1e52e7 100755 --- a/snes/system/serialization.cpp +++ b/snes/system/serialization.cpp @@ -6,6 +6,7 @@ serializer System::serialize() { unsigned signature = 0x31545342, version = Info::SerializerVersion, crc32 = cartridge.crc32(); char description[512]; memset(&description, 0, sizeof description); + strcpy(description, Info::Profile); s.integer(signature); s.integer(version); @@ -28,6 +29,7 @@ bool System::unserialize(serializer &s) { if(signature != 0x31545342) return false; if(version != Info::SerializerVersion) return false; //if(crc32 != cartridge.crc32()) return false; + if(strcmp(description, Info::Profile)) return false; reset(); serialize_all(s); diff --git a/snes/system/system.cpp b/snes/system/system.cpp index a2c8efc8..b6b3e97d 100755 --- a/snes/system/system.cpp +++ b/snes/system/system.cpp @@ -26,19 +26,25 @@ void System::run() { } void System::runtosave() { - scheduler.sync = Scheduler::SynchronizeMode::CPU; - runthreadtosave(); + if(CPU::Threaded == true) { + scheduler.sync = Scheduler::SynchronizeMode::CPU; + runthreadtosave(); + } - scheduler.thread = smp.thread; - runthreadtosave(); + if(SMP::Threaded == true) { + scheduler.thread = smp.thread; + runthreadtosave(); + } - scheduler.thread = ppu.thread; - runthreadtosave(); + if(PPU::Threaded == true) { + scheduler.thread = ppu.thread; + runthreadtosave(); + } - #if !defined(DSP_STATE_MACHINE) - scheduler.thread = dsp.thread; - runthreadtosave(); - #endif + if(DSP::Threaded == true) { + scheduler.thread = dsp.thread; + runthreadtosave(); + } for(unsigned i = 0; i < cpu.coprocessors.size(); i++) { Processor &chip = *cpu.coprocessors[i];