Assorted demos for m4vgalib
C++ Python Ruby Assembly Shell
Switch branches/tags
Nothing to show
Clone or download
Failed to load latest commit information.
cobble @ 4378ef3
demo demo/tunnel: switch away from ARMv7M usat function. Jul 14, 2015
etl @ 845ad71 demo/tunnel: switch away from ARMv7M usat function. Jul 14, 2015
site_cobble demo/raycast: process textures during build. Jul 6, 2015
sys Initial Cobble support. May 11, 2014
vga @ 189e31e Rev m4vgalib for timing fixes. Jul 6, 2015
.gitignore Add Vagrantfile. Jul 7, 2016
.gitmodules Switch m4vgalib to public remote. May 11, 2014
BUILD.conf demo/raycast: process textures during build. Jul 6, 2015
Vagrantfile Bump Cobble version. May 12, 2014 scripts: tolerate being called from other dirs. Nov 30, 2014 scripts: tolerate being called from other dirs. Nov 30, 2014
m4vga-stm32f4xx.ld Update for revised Arena implementation. Nov 30, 2014
openocd.cfg Utility script for bumping ETL revision. Apr 4, 2014


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.

Using Vagrant

The easiest way to build and flash this code is by using Vagrant.

Clone the m4vgalib-demos git repository and cd into the clone:

$ git clone
$ cd m4vgalib-demos

Use Vagrant to set up a toolchain and build environment:

$ vagrant up

This will set up an isolated Ubuntu 14.04 environment with a tested version of the ARM GCC toolchain, along with OpenOCD for flashing and debugging. As its final action, it will run this codebase's to set up the build environment.

Enter the build environment and run the build:

$ vagrant ssh
$ cd /vagrant/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.

Building Natively

Using Vagrant is easy, but you might prefer to build on your real machine. There are good reasons for this: Ubuntu's packaged version of OpenOCD is really old, for example, and gets flaky after flashing sometimes.

You'll need to wrangle the prerequisites yourself. The biggest one is a recent ARM GCC toolchain (4.9 or later, ideally). If you're on Ubuntu, I suggest using the ARM GCC PPA. Otherwise, you can use my GCC build recipe, derived from Ubuntu's.

Once you have a toolchain, the process is identical to the one described for Vagrant above -- just without the vagrant commands, and you'll need to run in your fresh clone by hand.

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.