Some time ago a friend sent me a link to a YouTube short: an NES showing the planes flying over someone’s house. It was a challenge.
I have a Sega Genesis. So, challenge accepted.
This is Mega WiFi Radar: a live, ATC-style radar scope running on a stock Genesis. The traffic is real ADS-B data around whatever airport you pick. Range rings, a rotating sweep with phosphor afterglow, blips with history trails and data tags. Pick any aircraft and you can ride along in a cockpit view, drawn by the 68000 over the real terrain underneath it.


Videos: the radar, cockpit mode, and a ’90s-style commercial I made to sell it. I also posted it on Reddit and X. Everything is MIT or open hardware, and there’s an emulator build if you don’t have the cart.
First, the cartridge
A Genesis has no network. The way you get one is MegaWiFi, doragasu’s open hardware cartridge: 8 MiB of flat flash ROM, an ESP32-C3 for Wi-Fi, and a 16550-class UART that bridges the 68000 to the ESP32.
The problem was that the UART, an NXP SC16C550BIBS, was out of stock. Everywhere. JLCPCB had zero, and so did every distributor I checked.
So I respun the board. The TI TL16C550D is pin- and register-compatible, but it’s only rated to 20 MHz at 3.3 V, which meant a new crystal, a 1 MΩ bias resistor the TI oscillator needs and the NXP part didn’t, the RI pin tied high, and the cart-to-ESP32 link dropping from 1.5 Mbaud to 1.25 Mbaud. That last one breaks every existing MegaWiFi ROM and firmware. I was fine with that, because this board was for new ROMs anyway. That became Rev.C.
Changing the baud rate meant changing both ends of the wire. The ESP32 firmware got its own fork running at 1.25 Mbaud, and SGDK, the Genesis dev kit, got patched to match. My FlashKit MD tool learned to write 8 MiB flash chips and to identify a blank cart instead of reporting “Unknown / 0K.”
Ten assembled boards arrived from JLCPCB on October 27. Before writing a line of the radar, I wrote a standalone bring-up ROM that tests the UART, the crystal, the ESP32 link, the flash address lines and the full 8 MiB map. Board 1 passed all of it, including with a Mega-CD and 32X stacked on top.
Then, the radar
The console has 64 KiB of RAM and can’t do TLS, so it can’t talk to an ADS-B API directly. A small Go relay on my network does that part: it fetches the JSON over HTTPS from adsb.fi, boils it down to a 1-2 KB binary frame, and the cart polls it once per sweep.
The first bug was a good one. The cart would detect the ESP32 after a soft reset but not from a cold boot. The compiler’s link-time optimization had inlined the network loop into SGDK’s user task and hoisted the driver state out of the loop. The task starts before the driver is initialized, so on a cold boot it cached a NULL forever. A soft reset keeps RAM, which hid it. The fix was a memory barrier.
0.1.0 shipped on October 28, the day after the boards arrived.
Six days, seventeen releases
From there it turned into a sprint:
| Date | Release | What landed |
|---|---|---|
| Oct 28 | 0.1.0 to 0.1.2 | Radar scope, sweep, themes, setup screen; a boot splash where each radio call in a 787 departure is a real boot step |
| Oct 29 | 0.1.3 to 0.2.1 | Relay found over mDNS, a traffic list, a detail pop-up (registration, type, operator, squawk), printable label, box and manual |
| Oct 31 | 0.3.0 | Cockpit mode over real terrain |
| Nov 1 | 0.4.0 to 0.4.3 | Flyover notices from the MQTT feed of planes over my house, an emergency alert for squawk 7700/7600/7500, ambient mode, city lights at night |
| Nov 2 | 0.4.4 to 0.6.1 | NEXRAD weather as stippled cells like a real STARS scope, runway video maps, a spotter’s logbook of everything within 25 nm |
0.2.0 booted to a black screen on the real cart. The new pop-up’s static buffers left too little heap for SGDK’s own start-up allocations, so it hung before the splash. The emulator build has less static RAM, so it booted fine there. I patched SGDK’s unused DMA buffer from 8 KiB down to 2 KiB, and now the build fails if it leaves less than 8 KiB of heap at start-up. RAM is the budget everything else answers to.


Cockpit mode
Cockpit mode was the question I wasn’t sure the hardware could answer: can a 7.6 MHz 68000 draw terrain in real time? I built a throwaway spike ROM to find out, using Voxel Space (the Comanche technique) writing straight into VRAM:
| Step | FPS |
|---|---|
| 160 columns in C, RAM frame buffer, DMA | 1.8 |
| 80 columns, direct to VRAM | 5.4 |
| Assembly inner loop | 10.0 |
| Far-field column pairs, coarser depth steps | 14.5 |
Unrolled writes, assembly row table, HUD without sprintf | 20.0 |
One sprintf on the HUD could cost a whole frame. In the product, the relay serves terrain patches built from elevation tiles and then streams strips as the aircraft moves. It runs at 16-22 fps on the cart with no visible stutter. The sky follows the sun where the aircraft actually is, and towns show up as lights at night.


How it got built
You can just do things.
Electronics, PCB design, programming: these are all skills I’ve learned the hard way, one at a time, over years. What’s different now is that I can turn them into a working product in about a tenth of the time, because I’m not fighting the parts that used to eat it. I didn’t bootstrap a Genesis toolchain by hand or spend an evening hunting for a replacement chip. Claude did the heavy lifting, and I made decisions; 136 of the radar repo’s 137 commits are co-authored with it. I only prompted the board changes and never opened KiCad. When JLCPCB damaged components on the order, Claude found equivalent parts they had in stock. I stepped in once or twice for the critical calls.
Could I have done all of this myself? Yes. But I didn’t have to.
The real challenge was trusting it. I yoloed a PCB design without verifying anything, not upstream’s work and not Claude’s, and put money on the line. The boards worked the first time, which is largely a tribute to doragasu’s original design. I took the same leap with the software: sending screenshots of the TV, debugging in depth, setting up recorded-traffic replays so we could test against the same flights every time.
I use my technical skills to get close to a one-shot, and I design features so the thing is easy for me to live with, like relay discovery over mDNS and lookup tables in place of floating point. Claude takes the first pass, and I refine. The only limit is my imagination.
Why
Because it’s fun. I’m trying to discover what I can do without the drag and friction of integration.
The long game is to make an actual Genesis game. I flashed these cartridges and 3D printed their shells myself, so all this playing around is practice: learning the platform, and finding out whether I can make a real product.