Tag: stm32

26 posts tagged with "stm32".

Reading a Real Cartridge Through a Fake CH340

The console's USB host port met a GBFlash cartridge reader that pretends to be a CH340 serial chip. Three wrong theories, one packet-size discovery, and by the end of the day the firmware read a physical Game Boy cartridge's header and validated it.

Running Ahead of the Sound Chip

The SNES core was losing four million cycles a frame waiting for a sound chip on another board to answer a one-byte question. Teaching the H7 to predict the answer and execute speculatively lifted dense Super Mario World from 35 to 49-52 fps. Then the fastest exact build ever measured painted garbage on the top of the screen while every checksum said it was perfect.

A flight recorder for firmware

Timing-sensitive failures on this console keep beating my telemetry: the screen goes wrong while every counter reads clean. This is the build log of a recorder that captures a working run and a failing run of the same workload, so a tool can find the earliest difference that matters.

The Receiver Was Innocent

I spent days optimising the HDMI coprocessor because every symptom said it was holding the SNES back. The optimisations worked, the frame rate climbed, and then the measurements turned around and convicted a different part entirely: the wire. This is the story of proving a bottleneck before building its replacement.

Every Millisecond Now Has a Name

The from-scratch SNES core matched the reference emulator to the cycle across a 750-frame run of Super Mario World. Then the hardware priced five optimisations: two worked, two did nothing, and a profiler said the real problem is memory, not arithmetic.

363960 Free Memory

One evening after the 68000 passed its cycle budget, the emulated Amiga boots a real Workbench 1.3 floppy to the desktop. The chipset, the floppy, and the three bugs that stood between a spinning motor and the blue screen.

Kickstart 1.3 Meets the Cycle Counter

First hardware numbers for the Amiga 500 programme: a real Kickstart 1.3 ROM executing deterministically on the STM32H753, with a p99 of 2.51M cycles per PAL frame against a 3.35M gate.

The drive is not a USB stick

Planning USB floppy support for the console: four transport dialects from 1998, a FAT12 layer nobody ships, and why the first firmware milestone is nothing but reading descriptors.

The shell, the stack and the secret palette

Two days building the console's v2 shell: a SPLORE-souled library, a crash hunt that ended eight kilobytes from a stack floor, and PICO-8's hidden palette arriving over an 8-bit wire.

Nine FPS under the clouds

Cattle Crisis opened its first level at 9 FPS on the H753. One day of hardware A/Bs later it holds 58, Dank Tomb stopped dying of OOM, and the biggest single win was a compiler flag I should have set weeks ago.

The wire learns a second shape: Game Boy first light

Two days from a feasibility study to DMG code rendering pixel-perfect on the TV: picking an emulator core, passing Blargg and dmg-acid2 on the host, and teaching the console's SPI video wire to carry two frame geometries at once.

The Console That Files Its Own Bug Reports

Giving a bare-metal fantasy console a crash reporter: capture the fault, survive the reset, journal it to flash, upload it, and email me. Plus three ways an STM32H7 loses your data across a warm reset that I had to learn the hard way.

Seventeen demos in forty-nine pixels

The launcher header's blinking sparkle became a 9x9 demoscene square: a breakout ball with real physics, copper bars, fire, the Boing ball, and thirteen friends, dealt from a shuffled deck.

The Cartridge That Killed Its Own Soundtrack

The morning after deleting the old Lua core: 32,000 lines gone, everything played - and then the speakers started clicking. Two wrong fixes, one command trace, and the crossfade every PICO-8 reimplementation eventually learns it needs.

The Default Flips

Stage 9: the fixed-point core becomes THE runtime. Getting there took an executor split, a clock experiment, two optimisations executed for measuring zero, a one-byte regression that cost 19 carts, and a PLL trick that ended the night at 59fps on jumper wires.

The Ghost, the Ladder, and the Cartridge

One evening, three fronts: a haunted iterator that cloned the player, a link clock ladder re-measured rung by rung, and a physical cartridge that finally keeps its saves.

The Swap, Measured

z8lua lands behind a flag: a bug class from a C port, an allocator caught red-handed on the pad, a licensed PICO-8 pressed into service as an oracle, and a compatibility matrix instead of a feeling.

Measure First: the Runtime Baseline

Before any z8lua code lands, Stage 1 of the runtime migration: a permanent benchmark instrument, input tapes recorded from real play, and the numbers the new VM has to beat.

Reading the framebuffer out of RAM

I wanted to redesign Rusty Nail's boot splash, but the standalone build sends nothing back to a host - the panel is the only display. So before I could change the splash, I had to work out how to screenshot a screen my Mac can't see.

16 megabytes for a 32-kilobyte game

I want to dock a physical cartridge into the fantasy console, so I picked the flash chip, mapped the firmware, and found most of the work was already done. None of it is built yet - this is the plan.

The HDMI board I bought before reading the datasheet

I bought a 50-pin RGB888-to-HDMI board for the fantasy console, then counted the pins. Two of them are Ethernet, three are the audio bus, and the Nucleo never had 24 to give. The fix might be a second microcontroller whose whole job is HDMI.

A divide per pixel

Once the SPI panel was off the critical path, the frame became the cart's own Lua and the slow part moved inside it. A missing string builtin, then the real prize: a stretched-sprite blit doing an integer divide per pixel on a chip with no fast divide. The profiler found it; the obvious guess was wrong. About 41fps to about 58fps.

Getting the panel off the critical path

The SPI blit was a blocking, row-by-row write that stalled the whole console for about 13ms every frame. DMA fixed that, the data cache nearly broke it, and a frame I was packing for nobody was the last easy win. About 14fps to about 41fps.

I keep choosing hard mode (the SPI panel and me)

I had a working HDMI path at 12:48 in the morning. Then at 10am, well rested and full of hope, I picked up the tiny SPI screen instead and spent nine hours reinventing flicker. A note on patience, and on why hardware scanout is the thing I should have just waited for.

The SPI panel saga: from a blank screen to 25 MHz

Getting the desktop off the USB stream and onto a real LCD. A dead-end controller that latches on the wrong clock edge, a switch to the ST7735, and climbing from 1 MHz to 25 MHz without losing the audio.

Getting sound out of it

An I2S DAC, SAI plus DMA, and three gotchas that each ate a session: a mute pin nobody pulls high, a data cache fighting the DMA, and an async executor that starved the audio to silence.