Raph Levien's JIT trick renders bitmap text on microcontrollers at 6 cycles per pixel

JIT bitmap text rendering for microcontrollers

Raph Levien's JIT trick renders bitmap text on microcontrollers at 6 cycles per pixel

Raph Levien needed text rendering for his RP2350 home computer project, vic-2350, but with only 520kB of SRAM and a 6-cycle-per-pixel budget, he races the beam instead of using a framebuffer. His solution: a JIT compiler that generates optimized ARM assembly on the fly for each string, packing glyphs into a shared bitmap with overlap detection that shrinks the font from 1140 to 960 bytes. The result is crisp proportional text at video rate.

Any glyph contained within another glyph doesn't need to be packed separately. There are a few examples, some surprising. For example, `l` is the left side of `U`, and `0` is identical to `()` with the space between them removed.
  1. drfuchs

    For prior related work, check out patent US-6377261-B1 "Compiling glyphs into instructions for imaging for execution on a general purpose computer" filed 1996. The basic idea is each character turns into a sequence of "Load Immediate" / "Shift" / "OR to Memory" instructions; so there's no more fetching from a stored bitmap of the font, as the pixels are implicit in the Immediate data in the generated machine code. Then you can get fancy when one row of pixels is the same as the previous row in the character, so you don't even need to do the Load Immediate. Etc. This scheme was used in FrameMaker for Macintosh back in the day, as implemented by Gus Fernandez (who went hog wild on additional optimizations).

  2. karmakaze

    This is a really great project. So many retro computers are OP that they can use large frame buffers and programming to them doesn't feel like being close to the metal back like back in the day which was more intimate.

    This implementation reminds me of two of my early experiences: programming display lists on Atari 8-bit and an HP PCL 5e interpreter (with short raster band buffer). I didn't really get into VCS/2600 128-byte beam racing but did do a fair amount of display-list-interrupt on-the-fly coding for homemade games and demos. I really thought the Atari Antic display list system was terrific--thanks to Jay Miner who also did the Amiga--and didn't see much like it again until OS/2 Presentation Manager or Java FX.

    The PCL interpreter probably had the closest shape using a few hundred line cyclic buffer. It 'rendered' into y-sorted objects that needed to be later rendered/rasterized. Each object was cut to be at most 255 pixels (0.85") tall and used reverse max-y ordering since it couldn't be drawn until after the beam passed the wraparound scan line still rendering Y - buffer_height.

  3. codazoda

    I've been building BASIC32, a retro BASIC interpreter for microcontrollers so I can flash it once and easily create lots of new projects.

    What you give up with the authors approach is "read". The screen becomes write-only. There are only a few functions that require reads: getting a pixels current color and doing operations like flood fills or paints.

    Because I was going for the retro feel of BASIC, I wanted to support these, so I opted for a frame buffer. It isn't as technically cool. On the RP2350, it does require low resolution and low bit rates because they often have RAM limited to KB.

    If you step-up to the ESP32-S3 variants with 4MB or 8MB of RAM the frame buffer gets much easier.

More from this day

2026-11-08