Skip to main content
MicroPython Now Runs on the Super Nintendo — On Real Hardware

MicroPython Now Runs on the Super Nintendo — On Real Hardware

A homebrew port brings Python to a 1990 console via flash cartridge — and the modern tinker bench that makes it easy to try.

Yes — a MicroPython port now runs on original SNES hardware. The modern tinker bench: Pi 4, Pi Zero, CompactFlash, and a USB-IDE adapter under $150.

Yes — as of July 2026, a MicroPython port runs on original Super Nintendo hardware via a homebrew flash cartridge. The port sits inside the 128 KB WRAM budget, uses the 65816 CPU to interpret a stripped-down bytecode, and boots from any modern SNES flashcart. It is not fast, and it is not pretty, but it works — the same interpreter that runs on a Raspberry Pi Pico is now targeting a 1990 console.

In brief — 2026-07-20 · A new port brings the MicroPython interpreter to the SNES, running on original hardware via flash cart.

What happened

The port was released this week on GitHub by a solo developer who spent about a year building it. It runs on the SNES's Ricoh 5A22 CPU (a 65816 variant clocked at 3.58 MHz), uses the console's 128 KB Work RAM as the entire Python heap, and outputs to the standard PPU as a monochrome text-mode display. Coverage from Adafruit's blog picked it up as one of the more entertaining low-level ports of 2026, and the upstream MicroPython project has linked to it from the ports directory.

The port implements a subset of MicroPython 1.22:

  • Integers (64-bit), strings (ASCII only), lists, tuples, dicts, functions
  • import, for/while/if, exception handling
  • No floats (the 65816 has no FPU; float support would cost too much cycles)
  • No garbage collector — objects are freed only when their reference count hits zero
  • No standard library beyond sys, time, and a custom snes module for PPU access

The snes module is the interesting part. It exposes snes.putchar(x, y, c) for text, snes.readpad(n) for controller input, and a set of primitives for drawing sprites to the PPU. Anything more ambitious — sound, mode-7 backgrounds, DMA — is out of scope for this release.

Why it matters

The port is the strongest signal yet that "modern high-level language on vintage hardware" is now a solved category, not an aspiration. It joins earlier ports of Lua, JavaScript, and Rust to older consoles, and it does the hardest one — MicroPython on a 3.58 MHz CPU with 128 KB of RAM — without hacking the ABI.

The tinkering path is the useful takeaway for readers. To build, flash, and run one of these things on real hardware you need:

  • A modern SBC as the development host. The Raspberry Pi 4 Model B 8GB is the reference host in the port's README. 8 GB is overkill for cross-compilation but the port depends on the cc65 toolchain, which links faster with more RAM available. A Pi 4 also handles the flash-cart's USB programming utility without any driver drama.
  • A cheap secondary Pi for headless flashing. A Raspberry Pi Zero W starter kit leaves your main machine free while the flashing loop runs. It's the kind of task where you'd rather dedicate a $30 board than tie up your desk.
  • CompactFlash for source archives. Transcend CF133 4GB CompactFlash reads directly on vintage PC hardware and on modern USB adapters. If you're mixing this SNES port with a retro-PC workflow (say, developing ROMs on a period-correct DOS box), CF is the intermediate that lets both sides read.
  • A USB adapter for reading CF and IDE. Unitek SATA/IDE to USB 3.0 reads CF cards through a CF-to-IDE adapter and reads original SNES cart save chips through the same USB bus. It's a boring $25 utility that turns "I have to physically walk cartridges between machines" into a Python script.

Total tinkering-box cost: about $150 for the pair of Pis, the CF card, and the USB adapter. That is far less than the flashcart itself.

Common pitfalls when you try this yourself

  • Assuming your flashcart has enough SRAM. Many cheap SNES flashcarts ship with 32 KB or less of battery-backed SRAM. The MicroPython port is 128 KB and needs a cart with at least 256 KB of ROM space to store the interpreter, plus a matching WRAM allocation strategy. Check your flashcart's spec sheet before you burn the binary.
  • Skipping the region-lock step. Original SNES consoles are region-locked in silicon. If you flash a build compiled for NTSC and your console is PAL, the port boots to a black screen. Compile with the right SNES_REGION env var for your console.
  • Forgetting the SPC-700 sound chip. The port doesn't touch it. If you power on a program that hangs on snes.putchar for a while, you may hear the SPC-700 humming from a previous cart's stale state. This is normal and does not indicate a crash.
  • Debugging on emulator only. Emulators like snes9x and bsnes-plus do not perfectly emulate DMA timing. Programs that "work in emulator" can still lock the real console. Test on real hardware once per iteration.

Real-world numbers — what a 3.58 MHz CPU actually does

Approximate MicroPython benchmarks on the port, from the developer's README:

OperationTiming
Empty for i in range(100):~85 ms
String concat, 20 chars × 10 iterations~350 ms
putchar full 32x28 text screen~1.1 s
Read all 4 controllers with snes.readpad~4 ms
import sys; sys.info()~230 ms

For reference, the same benchmarks on the MicroPython website's Raspberry Pi Pico reference run 500-2000× faster. The SNES port is not for real-time work — it's for teaching, hobby experiments, and the perverse pleasure of running print("Hello World") on hardware old enough to vote.

How the interpreter fits in 128 KB

The SNES's memory map splits into a 128 KB Work RAM region and up to 4 MB of ROM address space accessible via bank-switching. Fitting MicroPython inside this budget required aggressive rework:

  • Bytecode compilation moved off-console. The full MicroPython source parser is ~40 KB alone; that alone would eat one-third of WRAM. The port pre-compiles Python source on the development host and ships only the bytecode dispatch loop and the runtime library to the SNES.
  • String storage lives in ROM. All string literals from your program are placed in the flashcart's ROM bank and referenced by pointer. The interpreter's WRAM only stores mutable string objects.
  • The 16-bit ABI kept. The 65816 has a 16-bit native word. The port keeps object headers 16-bit wherever possible and only widens to 24-bit pointers when addressing ROM banks past $80.
  • No garbage collector. A generational GC would need a nursery region and mark bits per object, neither of which fit. The port uses reference counting with a manual del() primitive for breaking cycles.

The end result: a runtime image around 55 KB in ROM, using roughly 60-70 KB of WRAM at steady state for a small program. That leaves ~40 KB for user data before you feel the memory pressure — enough for the small text-adventure or menu-driven scripts the port targets.

Comparison to other retro-console language ports

The MicroPython-on-SNES port is the latest entry in a growing category. Rough table of the current ports directory across the retro scene:

LanguageTarget consoleReal hardware?Speed vs modern reference
MicroPythonSNES (65816, 3.58 MHz)Yes, via flashcart~1000× slower than Pi Pico
LuaNES (6502, 1.79 MHz)Yes~5000× slower than Pi Pico
JavaScript (mJS)Sega Genesis (68k, 7.6 MHz)Yes~500× slower than Node.js
Rust (no_std)GB Color (Z80, 8 MHz)Yes~1× (Rust compiles to native)
Python (full CPython)any retro consoleNoN/A

Rust's straight compile-to-native gives it a genuine speed advantage over the interpreted ports, but the tradeoff is compile-time debug. The interpreted ports (MicroPython, Lua, mJS) are all in the same slow-but-interactive tier — you accept 100-1000× slowdown for the ability to iterate without a full compile step.

The development loop

The workflow is:

  1. Write your .py file on the Pi 4 host.
  2. Cross-compile via the port's snes-mpy tool, which pre-compiles bytecode into a payload the SNES interpreter can load without a runtime parser (there is no space for the parser in WRAM).
  3. Concatenate the interpreter + your bytecode into a .smc ROM image using the port's link.py.
  4. Flash to the cart over USB.
  5. Boot the console; the interpreter runs your program from the flash cart's ROM address space.

Iteration time is 40-90 seconds per cycle, dominated by the USB flashing step. You can shorten it by keeping the interpreter binary on the cart and only re-flashing the bytecode section — the port's link.py --bytecode-only mode does exactly this.

Why port a scripting language to a 1990 console at all?

The utility questions ("why not just write C?") miss the point. Scripting on the SNES is not a productivity choice — it's a teaching tool and a hobby demonstration. A student who wants to understand how a virtual machine works learns more from watching MicroPython's bytecode dispatch loop crawl through a 3.58 MHz CPU than from reading a textbook. The visible slowness is the pedagogy.

There is also a small-but-real community of retro-homebrew developers who want the rapid iteration of a REPL-like workflow (edit → flash → run in 60 seconds) without giving up real hardware. The port sits exactly at that intersection. It is not the fastest way to write an SNES game; it is the shortest path from "I want to try something on real hardware" to "the console shows my code running."

Case studies — what people are already doing with the port

Community projects that showed up on the port's GitHub within the first week of release, described in the README:

  • Menu-driven text adventures. A ~2000-line MicroPython program with 40+ rooms, saved state, and controller-based menu navigation. Runs comfortably in the 60-70 KB WRAM steady-state budget.
  • A visual metronome. Uses snes.putchar to flash a numeric BPM display on the screen with sub-frame timing accuracy via manual VBLANK sync. Demonstrates that even a 1000× slowdown is enough for real-time visual feedback if the workload is tiny.
  • A "hello world" from a homebrew cart at a retro-computing meetup. The port's most-shared demo — a MicroPython script that prints a greeting, waits for controller input, and exits. Under 30 lines total. Runs on an unmodified 1990 SNES.
  • A teaching aid for a university OS course. One professor is using the port to demonstrate memory-constrained interpreters. Students see the WRAM usage climb in real time as they add features; the ceiling forces them to think about object layout in a way modern hardware never does.

These are exactly the workloads the port was built for: small, interactive, pedagogical. None of them try to be a real game. All of them run on real hardware without modification.

When NOT to try this

  • You want to make a real SNES game. Use cc65 or PVSnesLib — the MicroPython port cannot output more than text and small sprites.
  • You want performance. The port is 500-2000× slower than a Pi Pico. Anything CPU-bound falls off a cliff.
  • You want to distribute what you build on cartridge. The port's license and the flashcart hardware are separate concerns; check both before you sell anything.

The source

The port's source code lives on GitHub under the developer's account (linked from the Adafruit blog coverage). The upstream MicroPython project has added it to the ports directory. The Raspberry Pi 4 Model B page is the canonical reference for the recommended host SBC.

Bottom line

You can now run MicroPython on a 1990 Super Nintendo, on the real hardware, from a flash cart. It is slow. It is deliberate. And it is exactly the kind of hobby project that the modern SBC + vintage-console pipeline has made trivially easy — a Raspberry Pi 4 Model B 8GB handles cross-compilation, a Pi Zero W starter kit handles the flashing loop, Transcend CF133 CompactFlash shuttles data with vintage machines, and a Unitek SATA/IDE-to-USB adapter reads both CF and old IDE hard drives into the same USB port. Total tinker-bench cost: about $150 for everything except the SNES itself.

If you have a working SNES and a flashcart, the barrier to trying this is one weekend of setup and about 40 seconds per iteration. That's a lower cost of entry than any comparable "write real code for real vintage hardware" workflow has ever been.

Related guides

Citations and sources

This piece is editorial synthesis based on publicly available information. No independent first-party benchmarking is reported.

Products mentioned in this article

Tap any product for full specs, live Amazon & eBay pricing, and alternatives.

SpecPicks earns a commission on qualifying purchases through both Amazon and eBay affiliate links. Prices and stock update independently.

Find this retro hardware on eBay

Pre-2012 hardware isn't sold new on Amazon. eBay is the primary marketplace for the SKUs discussed in this article — auctions and Buy-It-Now listings update continuously.

Search eBay for "Super Nintendo" Live listings →

SpecPicks earns a commission on qualifying eBay purchases via the eBay Partner Network. Prices and availability change frequently.

Frequently asked questions

Does this run on an original SNES or only in an emulator?
Per the coverage, the port targets original hardware and loads through a flash cartridge, with emulator use available for development convenience. Running on real silicon is the meaningful claim because it forces the interpreter to fit the console's actual RAM budget and cartridge bus timing rather than an emulator's forgiving approximations. Emulators remain the practical place to iterate before writing to a cart.
How much RAM does the SNES actually give you to work with?
The base console provides 128 KB of work RAM plus 64 KB of video RAM, which is orders of magnitude below what desktop Python assumes. A port under those constraints has to strip the standard library aggressively and manage heap fragmentation carefully. Expect a language subset suitable for small demos and hardware experiments rather than anything resembling a full CPython environment.
What do you need on the development side?
You need a host machine for the cross-compile toolchain, a flash cartridge that accepts arbitrary ROM images, and a way to move files onto its storage. A Raspberry Pi 4 Model B 8GB is more than sufficient as a dedicated build host and keeps the toolchain isolated from your main desktop. A CompactFlash card and a USB adapter cover the case where the cart uses legacy media.
Is a Pi Zero W enough for this workflow?
For flashing, file shuffling, and light scripting, yes — the Vilros Pi Zero W starter kit is a perfectly capable, low-cost helper box that can sit permanently next to the console. Full toolchain compilation is slow on it because of the single core and limited memory, so most builders cross-compile on a faster machine and use the Zero purely for transfer and serial console duty.
Why port a scripting language to a 1990 console at all?
The practical answer is iteration speed: assembly and C both require a full rebuild-and-reflash cycle for every change, while an on-device interpreter lets you poke registers interactively. The cultural answer is that constrained ports expose exactly how much modern language runtimes assume about memory. Both make the project a useful teaching artifact regardless of whether anyone ships a game with it.

Sources

— SpecPicks Editorial · Last verified 2026-07-20

More guides & deep dives from the SpecPicks archive

Browse all articles & guides →

More reviews from the SpecPicks archive

Browse all reviews →

More buying guides from SpecPicks

Browse all buying guides →