Gotchas: Works in Stella, Dies on Hardware#
This is the page worth bookmarking. The bugs here share a signature: the game is perfect in the emulator and wrong on the console. That signature is diagnostic — it means the fault is in an assumption the emulator papers over, not in your game logic.
RAM is not zero on real hardware#
Stella conveniently clears the 128 bytes of RAM at startup. A real 6507 powers on with RAM full of random garbage. If any of your code reads a variable before writing it — a counter, a flag, a sprite position — it works in Stella (where it read 0) and does something random on hardware.
The fix is the CLEAN_START macro at Reset, which every program in this book uses. If you removed it or rolled your own init, this is the first thing to suspect when a cart boots to chaos that Stella never showed.
Marginal frame timing#
Stella tolerates frames that are slightly the wrong length; a real TV — especially an old CRT — does not. If your visible kernel emits 191 or 193 scanlines instead of exactly 192, or your VSYNC/VBLANK counts are off, the emulator may still display a stable image while a real set rolls, tears, or loses vertical lock. Recount every region against The Frame Structure and check the total is 262 lines. Stella’s scanline counter and “jitter”/TV-emulation modes help flush these out before you burn.
NTSC vs. PAL#
Color values and frame timing are region-specific. A game written and tuned on an NTSC palette running on a PAL console (and TV) shows wrong colors and a 50 Hz frame — your 60-Hz-based timing and your COLU* values are both off. Decide your target region and test against it; “looks great in Stella’s default NTSC” tells you nothing about a PAL console.
Image / chip mistakes that mimic code bugs#
When the screen is black or garbage, before you debug 6502 logic, rule out the cartridge:
- Vectors not at the top of the chip → CPU jumps to garbage. (See Preparing the ROM Image.)
- 2K image not mirrored into a 4K chip → half the address space reads erased
$FF. - Wrong burn offset / load address in the programmer → a perfect image placed at the wrong spot.
- A failed/unverified bit → intermittent crashes. Always verify after burning.
- Floating high address lines on an oversized chip → reads a random bank.
Bus contention and analog reality#
- Enable polarity wrong (ROM driving the bus when A12 = 0) → erratic, temperature- and timing-dependent failures that come and go. (See Wiring the Cartridge.)
- Dirty edge connector / console slot → identical black-screen symptom to a logic fault. Clean the contacts before assuming the worst.
- Slow or marginal power → a console that’s fine with a stock cart may glitch with a hand-wired board that adds capacitance or draws more.
A bring-up checklist#
- Re-verify the exact
.binin Stella (after any padding/mirroring). - Confirm file size is exactly 2048 or 4096 bytes (or your banked size).
- Blank-check the chip, burn, then verify.
- Confirm the programmer’s load offset is 0.
- Seat the chip in a socket; double-check orientation (pin 1).
- Test in a console you know is good, with a TV you know is good.
- Change one thing at a time when it doesn’t work.
Your gotchas go here#
You mentioned you’ve hit plenty of these. This page is the natural home for them — the failures you actually ran into, with the symptom you saw and what it turned out to be, are far more valuable than a generic list. Add them as bullet points under the relevant section above (or as new sections), and they’ll become the part of this book you reach for most.