Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

This is a collection of demos which, together, show how to use m4vgalib to produce high-quality graphics on an STM32F4 with few external components.

For more information about the approach used, see m4vgalib.

Building Natively

I used to recommend using Vagrant, but it turns out that the image sources I was using don't keep old images forever -- so you can't reproduce my historical build.

So instead, here are my non-Vagrant instructions.

These instructions are for Arch Linux. Arch ships recent, unmolested versions of the toolchain, so you don't need to build your own -- yay! If you're running a different distro, you'll have to adapt them.

  1. Install (through pacman) arm-none-eabi-{gcc,newlib,gdb} (tested with GCC 8.2.0).
  2. Install (through pacman) ninja and ruby.
  3. Install (through AUR) openocd (tested with 0.10).

To build:

$ git clone
$ cd m4vgalib-demos
$ ./
$ cd build
$ ./cobble build

This will compile binaries for all of the demos individually, plus a "demo reel." (See the tour below for details.) On a recent Intel machine this takes less than 10 seconds.

Connect an STM32F4Discovery board. Still within the build environment, run:

$ ../ latest/demo/conway/demo

This flashes the Conway's Life demo, which should take about five seconds.

Congratulations! Your STM32F4Discovery board is now producing VGA output. To actually see it, you'll want to wire the board up as described below.

Tour of the Demos

Each demo has its own README file. To learn more about a demo and which parts of m4vgalib it exercises, see demo/*/README.mkdn. Here's a brief overview of each.

All of the demos are stable at 60fps unless otherwise noted.

  • conway: cellular automata demonstration, achieving almost 29 million cell updates per second while generating 800x600 video.
  • hires_mix: mixed character and pixel graphics at 800x600.
  • hires_text: 80x37 high-res attributed character mode.
  • horiz_tp: alternating white/black vertical stripes, which is sometimes useful for getting an ornery monitor to sync properly.
  • midres_graphics: simple pixel graphics at 640x480. This exercises m4vgalib's 640x480 mode support, but it's not very interesting because I'm way more excited about the hires modes.
  • rook: realtime wireframe rendering of a piece from my chess set. Perspective projection, rotation, etc.
  • serial: a basic "glass teletype." Accepts input on a UART, prints it on the display.
  • tunnel: old-school demoscene animation, rendered using chunky pixel graphics inside an 800x600 mode.
  • xor_pattern: full-screen procedural texture generation.


The demos assume an 8MHz oscillator, which happens to be the type used on the STM32F4DISCOVERY board.

m4vgalib assumes the following connections:

Pin(s) Signal Description
B6 HSYNC governs monitor's horizontal timing
B7 VSYNC governs monitor's vertical timing
C8 sig B used for benchmarking
C9 sig A used for benchmarking
E15:8 video feed to video DAC

The demos further assume that only the bottom six pins of video are connected, and that they have the following roles:

Pin(s) Signal Description
E9:8 R1:0 red channel
E11:10 G1:0 green channel
E13:12 B1:0 blue channel

So while m4vgalib can do 256-color modes, these demos assume 64-color mode, largely to allow use of a trivial six-resistor R2R ladder DAC on a breadboard.

The interactive demos assume a five-way switch joystick and an action button, all of which are normally open and pull to ground when pressed.

Pin Signal Description
A4 Left Joystick Left
A6 Up Joystick Up
B15 Down Joystick Down
B14 Right Joystick Right
B13 Center Joystick Press
A0 User User (Action) Button

The Joystick pins are identical to those used on the WaveShare Open407V-D board, with the exception of Right, which must be jumpered.

The User Button is the blue button on the STM32F4DISCOVERY board.


Assorted demos for m4vgalib







No releases published


No packages published