From d691ec6d76b58df15238e1bae49a7d57bfc7742e Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 1 Feb 2022 18:08:19 -0500 Subject: [PATCH] add a chip playground in debug menu --- src/engine/dispatch.h | 13 +++++++ src/engine/engine.cpp | 14 ++++++++ src/engine/engine.h | 6 ++++ src/engine/platform/abstract.cpp | 8 +++++ src/engine/platform/arcade.cpp | 8 +++++ src/engine/platform/arcade.h | 2 ++ src/engine/platform/ay.cpp | 8 +++++ src/engine/platform/ay.h | 2 ++ src/engine/platform/ay8930.cpp | 8 +++++ src/engine/platform/ay8930.h | 2 ++ src/engine/platform/c64.cpp | 8 +++++ src/engine/platform/c64.h | 2 ++ src/engine/platform/gb.cpp | 8 +++++ src/engine/platform/gb.h | 2 ++ src/engine/platform/genesis.cpp | 8 +++++ src/engine/platform/genesis.h | 2 ++ src/engine/platform/nes.cpp | 8 +++++ src/engine/platform/nes.h | 2 ++ src/engine/platform/pce.cpp | 8 +++++ src/engine/platform/pce.h | 2 ++ src/engine/platform/saa.cpp | 8 +++++ src/engine/platform/saa.h | 2 ++ src/engine/platform/sms.cpp | 8 +++++ src/engine/platform/sms.h | 2 ++ src/engine/platform/tia.cpp | 8 +++++ src/engine/platform/tia.h | 2 ++ src/engine/platform/ym2610.cpp | 8 +++++ src/engine/platform/ym2610.h | 2 ++ src/gui/gui.cpp | 62 ++++++++++++++++++++++++++++++++ src/gui/gui.h | 3 ++ 30 files changed, 226 insertions(+) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 39a483659..0ddc6cd30 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -277,6 +277,19 @@ class DivDispatch { */ std::vector& getRegisterWrites(); + /** + * poke a register. + * @param addr address. + * @param val value. + */ + virtual void poke(unsigned int addr, unsigned short val); + + /** + * poke a register. + * @param wlist a vector containing DivRegWrites. + */ + virtual void poke(std::vector& wlist); + /** * initialize this DivDispatch. * @param parent the parent DivEngine. diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 1aef41fee..247af1b77 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3927,6 +3927,20 @@ bool DivEngine::removeSystem(int index) { return true; } +void DivEngine::poke(int sys, unsigned int addr, unsigned short val) { + if (sys<0 || sys>=song.systemLen) return; + isBusy.lock(); + disCont[sys].dispatch->poke(addr,val); + isBusy.unlock(); +} + +void DivEngine::poke(int sys, std::vector& wlist) { + if (sys<0 || sys>=song.systemLen) return; + isBusy.lock(); + disCont[sys].dispatch->poke(wlist); + isBusy.unlock(); +} + String DivEngine::getLastError() { return lastError; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 9a619795e..32542c540 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -493,6 +493,12 @@ class DivEngine { // remove system bool removeSystem(int index); + + // write to register on system + void poke(int sys, unsigned int addr, unsigned short val); + + // write to register on system + void poke(int sys, std::vector& wlist); // get last error String getLastError(); diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index fa7419502..abfb843c5 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -78,6 +78,14 @@ std::vector& DivDispatch::getRegisterWrites() { return regWrites; } +void DivDispatch::poke(unsigned int addr, unsigned short val) { + +} + +void DivDispatch::poke(std::vector& wlist) { + +} + int DivDispatch::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { return 0; } diff --git a/src/engine/platform/arcade.cpp b/src/engine/platform/arcade.cpp index 5c100490d..b25535fd5 100644 --- a/src/engine/platform/arcade.cpp +++ b/src/engine/platform/arcade.cpp @@ -728,6 +728,14 @@ void* DivPlatformArcade::getChanState(int ch) { return &chan[ch]; } +void DivPlatformArcade::poke(unsigned int addr, unsigned short val) { + immWrite(addr,val); +} + +void DivPlatformArcade::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); +} + void DivPlatformArcade::reset() { while (!writes.empty()) writes.pop(); if (useYMFM) { diff --git a/src/engine/platform/arcade.h b/src/engine/platform/arcade.h index 4cc1e3640..ca6027d46 100644 --- a/src/engine/platform/arcade.h +++ b/src/engine/platform/arcade.h @@ -79,6 +79,8 @@ class DivPlatformArcade: public DivDispatch { void setFlags(unsigned int flags); bool isStereo(); void setYMFM(bool use); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformArcade(); diff --git a/src/engine/platform/ay.cpp b/src/engine/platform/ay.cpp index f348c3923..4ba59e2a8 100644 --- a/src/engine/platform/ay.cpp +++ b/src/engine/platform/ay.cpp @@ -368,6 +368,14 @@ void DivPlatformAY8910::notifyInsDeletion(void* ins) { } } +void DivPlatformAY8910::poke(unsigned int addr, unsigned short val) { + immWrite(addr,val); +} + +void DivPlatformAY8910::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); +} + void DivPlatformAY8910::setFlags(unsigned int flags) { switch (flags&15) { case 1: diff --git a/src/engine/platform/ay.h b/src/engine/platform/ay.h index 822aa5faa..12029f828 100644 --- a/src/engine/platform/ay.h +++ b/src/engine/platform/ay.h @@ -65,6 +65,8 @@ class DivPlatformAY8910: public DivDispatch { bool isStereo(); bool keyOffAffectsArp(int ch); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index e3f39988f..cf8269f64 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -408,6 +408,14 @@ void DivPlatformAY8930::notifyInsDeletion(void* ins) { } } +void DivPlatformAY8930::poke(unsigned int addr, unsigned short val) { + immWrite(addr,val); +} + +void DivPlatformAY8930::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); +} + void DivPlatformAY8930::setFlags(unsigned int flags) { switch (flags&15) { case 1: diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 36405bde8..cea171d32 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -58,6 +58,8 @@ class DivPlatformAY8930: public DivDispatch { bool isStereo(); bool keyOffAffectsArp(int ch); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 5b5ebc4ba..6b5789f29 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -349,6 +349,14 @@ void DivPlatformC64::reset() { vol=15; } +void DivPlatformC64::poke(unsigned int addr, unsigned short val) { + rWrite(addr,val); +} + +void DivPlatformC64::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) rWrite(i.addr,i.val); +} + void DivPlatformC64::setChipModel(bool is6581) { if (is6581) { sid.set_chip_model(MOS6581); diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index 5526e312b..f61001648 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -66,6 +66,8 @@ class DivPlatformC64: public DivDispatch { void setFlags(unsigned int flags); void notifyInsChange(int ins); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void setChipModel(bool is6581); void quit(); diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index ac62167b2..cb02bc4d1 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -349,6 +349,14 @@ void DivPlatformGB::notifyInsDeletion(void* ins) { } } +void DivPlatformGB::poke(unsigned int addr, unsigned short val) { + immWrite(addr,val); +} + +void DivPlatformGB::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); +} + int DivPlatformGB::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { for (int i=0; i<4; i++) { isMuted[i]=false; diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index 40da7e317..5ee98eae0 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -51,6 +51,8 @@ class DivPlatformGB: public DivDispatch { void notifyInsChange(int ins); void notifyWaveChange(int wave); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformGB(); diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 33fef29d6..c735c1bba 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -643,6 +643,14 @@ void DivPlatformGenesis::notifyInsDeletion(void* ins) { psg.notifyInsDeletion(ins); } +void DivPlatformGenesis::poke(unsigned int addr, unsigned short val) { + immWrite(addr,val); +} + +void DivPlatformGenesis::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); +} + int DivPlatformGenesis::getPortaFloor(int ch) { return (ch>5)?12:0; } diff --git a/src/engine/platform/genesis.h b/src/engine/platform/genesis.h index 4b4404639..933bff605 100644 --- a/src/engine/platform/genesis.h +++ b/src/engine/platform/genesis.h @@ -86,6 +86,8 @@ class DivPlatformGenesis: public DivDispatch { void notifyInsChange(int ins); void notifyInsDeletion(void* ins); int getPortaFloor(int ch); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformGenesis(); diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 796c4f9e3..5527418a2 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -397,6 +397,14 @@ void DivPlatformNES::notifyInsDeletion(void* ins) { } } +void DivPlatformNES::poke(unsigned int addr, unsigned short val) { + rWrite(addr,val); +} + +void DivPlatformNES::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) rWrite(i.addr,i.val); +} + int DivPlatformNES::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { parent=p; apuType=flags; diff --git a/src/engine/platform/nes.h b/src/engine/platform/nes.h index ac6c9bc1f..bb8b5adc8 100644 --- a/src/engine/platform/nes.h +++ b/src/engine/platform/nes.h @@ -54,6 +54,8 @@ class DivPlatformNES: public DivDispatch { bool keyOffAffectsArp(int ch); void setFlags(unsigned int flags); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformNES(); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index db523c1bd..719cedcaa 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -405,6 +405,14 @@ void DivPlatformPCE::setFlags(unsigned int flags) { rate=chipClock/12; } +void DivPlatformPCE::poke(unsigned int addr, unsigned short val) { + rWrite(addr,val); +} + +void DivPlatformPCE::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) rWrite(i.addr,i.val); +} + int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { parent=p; dumpWrites=false; diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 7f5e08c27..3463abd7d 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -70,6 +70,8 @@ class DivPlatformPCE: public DivDispatch { void setFlags(unsigned int flags); void notifyWaveChange(int wave); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformPCE(); diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index d59c27929..f5871d578 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -322,6 +322,14 @@ void DivPlatformSAA1099::setFlags(unsigned int flags) { rate=chipClock/32; } +void DivPlatformSAA1099::poke(unsigned int addr, unsigned short val) { + rWrite(addr,val); +} + +void DivPlatformSAA1099::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) rWrite(i.addr,i.val); +} + int DivPlatformSAA1099::init(DivEngine* p, int channels, int sugRate, unsigned int flags) { parent=p; dumpWrites=false; diff --git a/src/engine/platform/saa.h b/src/engine/platform/saa.h index b4800efbf..98e0fe56c 100644 --- a/src/engine/platform/saa.h +++ b/src/engine/platform/saa.h @@ -62,6 +62,8 @@ class DivPlatformSAA1099: public DivDispatch { int getPortaFloor(int ch); bool keyOffAffectsArp(int ch); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 7905c8c6e..74a78f9b2 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -230,6 +230,14 @@ void DivPlatformSMS::notifyInsDeletion(void* ins) { } } +void DivPlatformSMS::poke(unsigned int addr, unsigned short val) { + rWrite(val); +} + +void DivPlatformSMS::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) rWrite(i.val); +} + void DivPlatformSMS::setFlags(unsigned int flags) { if ((flags&3)==2) { chipClock=4000000; diff --git a/src/engine/platform/sms.h b/src/engine/platform/sms.h index d0de5f2fd..aa8725e70 100644 --- a/src/engine/platform/sms.h +++ b/src/engine/platform/sms.h @@ -48,6 +48,8 @@ class DivPlatformSMS: public DivDispatch { int getPortaFloor(int ch); void setFlags(unsigned int flags); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformSMS(); diff --git a/src/engine/platform/tia.cpp b/src/engine/platform/tia.cpp index ece5577fc..b9b0527f5 100644 --- a/src/engine/platform/tia.cpp +++ b/src/engine/platform/tia.cpp @@ -254,6 +254,14 @@ void DivPlatformTIA::notifyInsDeletion(void* ins) { } } +void DivPlatformTIA::poke(unsigned int addr, unsigned short val) { + rWrite(addr,val); +} + +void DivPlatformTIA::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) rWrite(i.addr,i.val); +} + void DivPlatformTIA::setFlags(unsigned int flags) { if (flags&1) { rate=31250; diff --git a/src/engine/platform/tia.h b/src/engine/platform/tia.h index e22866238..a0a9bf21f 100644 --- a/src/engine/platform/tia.h +++ b/src/engine/platform/tia.h @@ -35,6 +35,8 @@ class DivPlatformTIA: public DivDispatch { bool isStereo(); bool keyOffAffectsArp(int ch); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); }; diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index d52229cbf..e6018bb0f 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -721,6 +721,14 @@ void* DivPlatformYM2610::getChanState(int ch) { return &chan[ch]; } +void DivPlatformYM2610::poke(unsigned int addr, unsigned short val) { + immWrite(addr,val); +} + +void DivPlatformYM2610::poke(std::vector& wlist) { + for (DivRegWrite& i: wlist) immWrite(i.addr,i.val); +} + void DivPlatformYM2610::reset() { while (!writes.empty()) writes.pop(); if (dumpWrites) { diff --git a/src/engine/platform/ym2610.h b/src/engine/platform/ym2610.h index 5e0b5055c..9cd510160 100644 --- a/src/engine/platform/ym2610.h +++ b/src/engine/platform/ym2610.h @@ -77,6 +77,8 @@ class DivPlatformYM2610: public DivDispatch { bool keyOffAffectsArp(int ch); void notifyInsChange(int ins); void notifyInsDeletion(void* ins); + void poke(unsigned int addr, unsigned short val); + void poke(std::vector& wlist); int init(DivEngine* parent, int channels, int sugRate, unsigned int flags); void quit(); ~DivPlatformYM2610(); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index c6973b16e..4d2ac858b 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3246,6 +3246,68 @@ void FurnaceGUI::drawDebug() { ImGui::Columns(); ImGui::TreePop(); } + if (ImGui::TreeNode("Playground")) { + if (pgSys<0 || pgSys>=e->song.systemLen) pgSys=0; + if (ImGui::BeginCombo("System",fmt::sprintf("%d. %s",pgSys+1,e->getSystemName(e->song.system[pgSys])).c_str())) { + for (int i=0; isong.systemLen; i++) { + if (ImGui::Selectable(fmt::sprintf("%d. %s",i+1,e->getSystemName(e->song.system[i])).c_str())) { + pgSys=i; + break; + } + } + ImGui::EndCombo(); + } + ImGui::Text("Program"); + if (pgProgram.empty()) { + ImGui::Text("-nothing here-"); + } else { + char id[32]; + for (size_t index=0; indexpoke(pgSys,pgProgram); + } + ImGui::SameLine(); + if (ImGui::Button("Clear")) { + pgProgram.clear(); + } + + ImGui::Text("Address"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100.0f*dpiScale); + ImGui::InputInt("##PAddress",&pgAddr,0,0,ImGuiInputTextFlags_CharsHexadecimal); + ImGui::SameLine(); + ImGui::Text("Value"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(100.0f*dpiScale); + ImGui::InputInt("##PValue",&pgVal,0,0,ImGuiInputTextFlags_CharsHexadecimal); + ImGui::SameLine(); + if (ImGui::Button("Write")) { + e->poke(pgSys,pgAddr,pgVal); + } + ImGui::SameLine(); + if (ImGui::Button("Add")) { + pgProgram.push_back(DivRegWrite(pgAddr,pgVal)); + } + ImGui::TreePop(); + } if (ImGui::TreeNode("Settings")) { if (ImGui::Button("Sync")) syncSettings(); ImGui::SameLine(); diff --git a/src/gui/gui.h b/src/gui/gui.h index 4e2c4aa98..a03568e00 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -256,6 +256,9 @@ class FurnaceGUI { FurnaceGUIWindows curWindow; float peak[2]; + std::vector pgProgram; + int pgSys, pgAddr, pgVal; + struct ActiveNote { int chan; int note;