-
Dual-core architecture & multi-target build
6 days ago • 0 commentsDual-Core Architecture
Cross-core communication uses volatile flags — no mutex overhead needed for this use case.
- Core 0 — Game logic & display
- XOR sprite rendering
- DMA double buffering
- Deferred flush (union bounding box)
- Clock / alarm state machine
- Input handling
- Core 1 — Audio engine
- Square wave generation on GP8
- Drift-free timing
- Melody + SFX queue
- All code runs from RAM
Software Versions
Three build targets share the same game logic core:
- Pico (Pico SDK )
- MS-DOS (Watcom C 10.6)
- Linux/Windows (GCC, SDL 1.2)
- Core 0 — Game logic & display
-
Reverse engineering the SM511 game logic
6 days ago • 0 comments- Game Logic
I reversed engineered the game logic and reimplemented the full game state machine in C:
- Player movement
- Enemy spawning patterns (Game A and Game B)
- Score and miss counter
- Game over logic
- Built-in clock and alarm- Graphics Pipeline
The original CJ-71 uses a color filter overlay on a monochrome LCD. Each sprite is a fixed
segment. To reproduce this on a TFT:- Sprites extracted from MAME artwork assets, converted to **RGB332** (1 byte/pixel) stored in flash
- Transparent pixels use `0x00` as sentinel
- Scenery background (471×238) centered on 480×320 display
- XOR blitting over scenery, deferred flush with union bounding box
- DMA double buffering for tear-free renderingA Python asset pipeline (`gen_sprites.py`) handles extraction, color conversion, and C header generation.
- Audio
The SM511 melody ROM (256 bytes) was extracted from MAME. Rather than emulating the SM511
audio engine at runtime, I decoded the melody ROM offline into a table of `(freq_hz, duration_ms)`
note pairs — full audio fidelity with no runtime SM511 dependency.On the Pico, **Core1** is dedicated to audio, generating square waves on GP8 via
`busy_wait_until()` for drift-free timing. All audio code runs from RAM to avoid flash latency.The original CJ-71 audio circuit uses a PNP transistor (C458) in a negative-supply design to
drive the piezo. On the Pico, a direct GPIO connection proved sufficient — the piezo pressed
against the original plastic shell acts as a natural resonator and amplifier. -
Hardware overview & power design
6 days ago • 0 comments- Hardware
- MCU : Raspberry Pi Pico (RP2040)
- Display : ILI9488 480×320 SPI TFT (3.5")
- Audio : Original CJ-71 piezo buzzer, GPIO driven
- Power : 2× LR14 → XL6019 boost converter → 5V → Pico VBUS
- SPI : SPI0 at 40MHz, 18-bit color
- Consumption : ~55mA at 5V · ~70h estimated battery life
The ILI9488 fits almost perfectly behind the original CJ-71 screen bezel.
- Power
- The original CJ-71 ran on 2× LR14 C-cell batteries (~3V). An XL6019 boost converter steps this up to stable 5V for the Pico VBUS.
- Hardware
Kalice