The answer is: very slowly YES!

I've recorded keyboard inputs that can be replayed to complete the first level. It finishes at in-game time 316, but wall-clock time is 32 minutes. Transitions and starting the second level adds another 15 minutes. 😀
Demo (speedup 50x):
https://github.com/nevesnunes/ghidra-plays-mario/assets/9061071/9b571a39-9672-4dc5-ada2-4a149f60a0dd
I took an existing minimal emulator, removed all CPU logic, and replaced it with a socket-based protocol for delegating CPU execution to Ghidra's PCode emulator (server). Everything else is still handled by the modified emulator (client), such as keyboard input and PPU logic.
Processor module validation! Sure, Ghidra has pcodetest for this purpose, but it's hard to tell how much coverage it provides. Apparently, not enough!
Just getting the Super Mario Bros title screen to render required fixing bugs in 3 instructions. Even more were fixed while appeasing nestest.nes.
Before (some tests fail, until a crash after jumping to an invalid instruction):

After (all tests pass):

Tested with Ghidra 10.3.2, on Debian GNU/Linux 12.
To reproduce the first level run:
Ghidra/Processors/6502/data/languages/*.slaspec from my fork to your Ghidra installation, then run ant -f build.xml under data/ to build the updated .sla files;ef27b8d);ea343f4e445a9050d4b4fbac2c77d0693b1d0922), and make sure it's focused in the listing (a.k.a. disassembly) window (in case you have other files open);./ghidra_scripts/NesEmu.java to your project's ghidra_scripts directory;./inputs/smb.w11full.inputs to /tmp/smb.inputs;NesEmu.java (starts the server);make && ./smolnes_emuclt $ROM, (starts the client, $ROM is the full path to the same ROM being disassembled in Ghidra);Of course, you can remove /tmp/smb.inputs and play yourself.
Some flamegraphs were captured with async-profiler: ./asprof -e itimer -d 30 -o flamegraph -f /tmp/out.html $GHIDRA_PID
Surprisingly, stepping through instructions only takes about 15% of CPU time. About 50% is socket I/O (even after some quick optimizations like reusing the same buffer for payloads and buffering socket writes):

deobfuscated.c from smolnes is under LICENSE.smolnes, and was modified into files smolnes_emuclt.c and smolnes_standalone.c;5 commits
HTML
86.3%
C
8.4%
Java
5.2%
The answer is: very slowly YES!

I've recorded keyboard inputs that can be replayed to complete the first level. It finishes at in-game time 316, but wall-clock time is 32 minutes. Transitions and starting the second level adds another 15 minutes. 😀
Demo (speedup 50x):
https://github.com/nevesnunes/ghidra-plays-mario/assets/9061071/9b571a39-9672-4dc5-ada2-4a149f60a0dd
I took an existing minimal emulator, removed all CPU logic, and replaced it with a socket-based protocol for delegating CPU execution to Ghidra's PCode emulator (server). Everything else is still handled by the modified emulator (client), such as keyboard input and PPU logic.
Processor module validation! Sure, Ghidra has pcodetest for this purpose, but it's hard to tell how much coverage it provides. Apparently, not enough!
Just getting the Super Mario Bros title screen to render required fixing bugs in 3 instructions. Even more were fixed while appeasing nestest.nes.
Before (some tests fail, until a crash after jumping to an invalid instruction):

After (all tests pass):

Tested with Ghidra 10.3.2, on Debian GNU/Linux 12.
To reproduce the first level run:
Ghidra/Processors/6502/data/languages/*.slaspec from my fork to your Ghidra installation, then run ant -f build.xml under data/ to build the updated .sla files;ef27b8d);ea343f4e445a9050d4b4fbac2c77d0693b1d0922), and make sure it's focused in the listing (a.k.a. disassembly) window (in case you have other files open);./ghidra_scripts/NesEmu.java to your project's ghidra_scripts directory;./inputs/smb.w11full.inputs to /tmp/smb.inputs;NesEmu.java (starts the server);make && ./smolnes_emuclt $ROM, (starts the client, $ROM is the full path to the same ROM being disassembled in Ghidra);Of course, you can remove /tmp/smb.inputs and play yourself.
Some flamegraphs were captured with async-profiler: ./asprof -e itimer -d 30 -o flamegraph -f /tmp/out.html $GHIDRA_PID
Surprisingly, stepping through instructions only takes about 15% of CPU time. About 50% is socket I/O (even after some quick optimizations like reusing the same buffer for payloads and buffering socket writes):

deobfuscated.c from smolnes is under LICENSE.smolnes, and was modified into files smolnes_emuclt.c and smolnes_standalone.c;5 commits
HTML
86.3%
C
8.4%
Java
5.2%