Tag Archives: Arduino


Play retro color 8 bit games on your TV from an Arduino.

Arduinocade features old school color 8 bit graphics (tiles, sprites, smooth scrolling, simple 3D) and sound (4 voice wavetable synthesis). All video and audio signals are generated with three resistors, an upgraded crystal and a little software. By overclocking the Arduino to 28.6363Mhz we can directly manipulate NTSC to generate 27 simultaneous colors. An IR receiver supports a wide variety of keyboards, joysticks and remote controls.

Video of Arduinocade in action at https://www.youtube.com/watch?v=nGIujZiEu_o

Code, tools, schematics and more detail at https://github.com/rossumur/Arduinocade


These games are sketches of what is possible on the Arduinocade hardware and a far from the polished pieces that inspired them.


A one-on-one sports style game inspired by the brilliant 1984 game Ballblazer. This uses a simple physics model and a 2D/3D rendering pipeline to produce 60fps animation. Try and grab the ball and shoot it into your opponent’s goal.


What can I say? pakku pakku pakku.


Fly around on ostrich thingys. Poke each other with sticks. Nice example of using the sprite engine to generate lots of large multicolor sprites.

Caverns of Titan

Homage to the Atari classic “Caverns of Mars”. Smooth scrolling, sprites and animation.

Building the Hardware

Lots of different ways to build this beastie. The design is simple enough to build on a breadboard with a DIP Atmega328, alternatively you might want to add a 28.6363Mhz crystal to a $2 Arduino Pro Mini or even build on a custom PCB.

You will need

  • Arduino Pro Mini, Atmega328p or equivalent
  • 28.6363Mhz Crystal (from Adafruit, eBay etc)
  • RCA Audio/Video Cable (eBay)
  • 470ohm, 1k and 100k resistors
  • IR receiver TSOP38238,TSOP4838 or equivalent (Adafruit, Mouser etc)
  • IR Input device (see below)
        |    arduino     |
        |    uno/pro     |
        |     28Mhz      |       5v <--+-+   IR Receiver
        |                |      GND <--|  )  TSOP4838
        |              8 |-------------+-+
        |                |
        |              6 |----[ 100k ]--------> AUDIO
        |                |
        |              9 |----[  1k  ]----+---> VIDEO
        |                |                |
        |              1 |----[ 470  ]----+
        |                |
        |              3 |
        |              2 |
        |                |

Mini Pro

We will be upgrading the crystal/resonator on these boards from 16Mhz to 28.6363Mhz. The easiest ones to modify have the big silver cans on them. Others use a ceramic resonator which require a bit of SMD fiddling.

Custom PCB

If you want to get silly and build a custom board you can get a video console down to about the size of a quarter. Board and schematics can be found in sim/docs/eagle.

Input Devices

Retcon IR Controller, Atari Flashback 4 joysticks, Apple TV remote

A number of IR input devices are supported. The IR Wireless Controllers from Atari Flashback 4 work well and have that classic joystick feel, as do the Retron IR controllers. These can be readily found on eBay for a few bucks. The Apple TV remote is also supported by you might feel a little silly. Edit config.h to select your input of choice.

Upgrading the bootloader

If you want to use the Arduino IDE you should upgrade the bootloader to be able to work at 115200 baud with the faster crystal installed. The optiboot_atmega32_28.hex image has been rebuilt with F_CPU=28636363 and a slower watchdog reset so baud rate calculations will be correct for our overclocked device. Install the image with avrdude and your favorite ISP.

avrdude -c usbtiny -p atmega328p -e -u -U lock:w:0x3f:m -U efuse:w:0x05:m -U hfuse:w:0xDE:m -U lfuse:w:0xFF:m
avrdude -c usbtiny -p atmega328p -U flash:w:optiboot_atmega328_28Mhz.hex -U lock:w:0x0f:m

Once the modified optiboot is installed the device will behave like an Uno, so remember to select that from the boards menu in the Arduino IDE.

Using the Arduino IDE

The current code does not work correctly with Arduino IDEs later than 1.5.6. Compiler optimizations in later versions interfere with hand timed loops in the video kernels. I will fix soon.

Copy the `Arduinocade` folder into the IDE libraries folder and relaunch IDE. You should be able to open the example games from File->Examples->Arduinocade. Edit the config.h file to enable or disable the custom `BALLBLASTER_GAME` kernel.

How it works


Upgrading the crystal to 28.6363Mhz allows us to run at a multiple (8x CPU clock, 4x SPI output) of the NTSC subcarrier frequency. By spitting out bits in the right pattern at the right time we can generate NTSC colorburst and different colors based on the relative phase of the pattern.

Black (0000), White (1111), gray_5 (0101) and gray_10 (1010) don’t have a chroma component; the other 12 colors do. By inserting or skipping an extra nop in rendering kernel we can select between two different phases at the start of a line yielding 12+12+(black,white,gray) = 27 simultaneous colors on screen simultaneously. You can then add more by dithering etc.

The Art of Artifacts

Left – Pixels being emitted from the TX port, Right – Colors as they appear on NTSC

Every HSYNC interrupt the cpu emits a 3.57Mhz colorburst signal then sends pixel data from carefully timed tile or RLE video kernels. These are tricky to maintain in C, as helpful compiler optimizations often alter timing in unexpected ways. They probably all need to move to asm at some point. See note above.

The higher layer code uses a RLE format (BallBlaster) or tiles to represent game content. Because we don’t have enough memory for a full frame buffer individual lines of tiles and sprites are composed in a loop that is in lock step with the HSYNC interrupt.

TileGrind is a primitive html/javascript tool for generating color tiles and sprites. It can load and save C structs and understands the nature of NTSC color phase / artifacting. Its limitations vividly recreate the frustration of early graphics editing tools.


The Audio driver has two parts. The low level kernel runs every HSYNC, stepping each of the 4 voices though it’s wavetable, mixing the sampled voices together based on their current volume and emitting a sample to the PWM/resistor single bit DAC. This corresponds to a sample rate of 15734Hz.

The high level task runs every frame at 60Hz and adjusts envelope, modulates frequency of the underlying channels etc. It is responsible for parsing data structures containing music tracks and sound effects, adjusting volume envelopes and frequencies, swapping wavetables for different instruments etc.

AudioGrind is a primitive html/javascript audio editing tool is used to convert midi files to C struct data. It can also be used to reverse engineer classic gaming sound effects using a graphical spectrogram, without which it is nearly impossible to figure out how the effects are constructed – I’m talking to you Joust.

IR input Joysticks, Keyboards etc

The GPIO attached to the IR sensor is sampled at HSYNC and fed to one of a number of IR decoders. The 15734Hz sample rate is enough to accurately parse nearly all IR protocols. For performance reasons only one is enabled at a time; check the #ifdefs in ir_input.cpp.

So enjoy

Let me know if you have some fun with it.




Play Zork on your TV with an Arduino.

Who doesn’t love Zork?. Who doesn’t love Arduinos? Why not grab a few cheap components and build an Arduino gadget capable of playing all the classic Infocom games on your TV from the comfort of your couch.

A few years ago I ported a Z-Machine player to a little arduino-like device. Ever since I have been meaning to get around to a project that would work on a TV with a real keyboard and once again rekindle fond memories of long nights playing Zork on my Atari 800.

You will need:

  • Arduino UNO, Pro, Pro Mini or equivalent.
  • SD card or micro SD card + breakout board (from Adafruit, eBay etc).
  • RCA A/V Cable (eBay).
  • 470ohm, 1k and 100k resistors.
  • Breadboard, wires etc.
  • WebTV or MsnTV IR Keyboard or PS2 a nasty old PS2 keyboard (eBay).
  • IR receiver TSOP38238,TSOP4838 or equivalent (Adafruit, Mouser etc).

Building it

The schematic is very simple:

        +----------------+           +-----------------+
        |                |           |                 |
        |             13 |-----------| SCK    micro\SD |
        |             12 |-----------| MISO   card     |
        |             11 |-----------| MOSI   module   |
        |             10 |-----------| CS              |
        |                |      5v <-|                 |
        |                |     GND <-|                 |
        |    arduino     |           +-----------------+
        |    uno/pro     |
        |                |       5v <--+-+   IR Receiver
        |                |      GND <--|  )  TSOP4838 etc.
        |              8 |-------------+-+
        |                |
        |              6 |----[ 100k ]--------> AUDIO
        |                |
        |              9 |----[  1k  ]----+---> VIDEO
        |                |                |
        |              1 |----[ 470  ]----+
        |                |
        |              3 |----------------> *PS2 CLOCK
        |              2 |----------------> *PS2 DATA
        |                |

Layout on an Arduino Uno…

…and on a Mini Pro.

Just about any SD card or microsd card breakout will do. Some of the very cheap ones (<$1) don’t have 5v to 3v3 level converters and may fry your SD card so caveat emptor. As always, Adafruit has nice ones.

WebTV keyboards come in various guises: WebTV, MsnTV, Displayer, UltimateTV etc. They all should work just fine. A few places have the nice Philips variant new for $11.95 w/ free shipping (search for ‘SWK-8630’). This one comes with a nice PS2 IR receiver; more on it later.

IR receivers come in a number of different forms. You are looking for a 38khz version with a known pinout: Some have the center pin as GND, some as V+. Make sure you know what kind you have. When in doubt, Adafruit.

I like using iPhone/iPod video cables for TV projects. Because they no longer work (their MFI chips long since revoked) they are inexpensive, are labeled internally and have a strain relief grommet.

If you have an IR keyboard then good for you. If not, connect your nasty old PS2 clock and data lines to pins 3 and 2 then order an IR keyboard.

On the disk

The microsdfiles folder contains a zd.mem pagefile along with several sample games:

tutorial.z3 Introduction to interactive fiction and a little bit of Zork I

Samples of Planetfall, Infidel, and The Witness.

Samples of Zork I, Leather Goddesses of Phobos, and Trinity

A nice big chunk of Zork I that was given away with the British Commodore users’ magazine “Zzap! 64” no. 67. in 1990.

Copy these files to a freshly formatted sd or microsd card. You can find lots of other Zorkduino compatible games at the Interactive Fiction Archive. Insert the card and run the zorkduino.ino sketch from the zorkduino folder. When it is all up and running, it should look like this (depending on how many games you found):


How it works

Squeezing Zork into the limited footprint of an Arduino proved to be a bit of a challenge. The code uses a port of Mark Howell and John Holder’s JZIP, a Z-machine interpreter. The Z-machine was created in 1979 to play large (100k!) adventure games on small (8K!) personal computers. Long before Java the implementors at Infocom built a virtual machine capable of paging, loading and saving complete runtime state that ran on a wide variety of CPUs. Clever stuff.

The trouble is the Arduino only has 2k of ram. The Z-machine interpreter uses 2k for its stack alone, leaving no room for dynamic memory, disk buffers, video frame buffers, avr stack and other program state. The solution is to virtualize all stack and memory accesses from the interpreter down to a 160 byte cache and a 512 byte disk buffer. Thats where the zd.mem file comes in – a megabyte or so of virtual stack, memory and save-game slots.

Virtualizing everything slows things down a bit but serendipitously makes the Arduino perform at roughly the same speed as my old Atari 800. Video needs 912 bytes for the frame buffer, leaving ~464 bytes for the avr stack and all application and interpreter state.


The video is generated with a simple state machine on the Timer1 ISR. HSYNC interrupts occur at 15.73kHz and trigger state changes for video, audio and keyboard state machines.

Active video is 308×192 pixels, 38×24 8×8 charaters. Getting this resolution requires use of the UART in SPI mode running at top (8Mhz) speed to shift out pixels from either a character font (the Atari 800 default font) or a graphics font (an extravagant waste of 2k logo). Because the video is being emitted from the TX pin it is fun to open the serial monitor to watch what ntsc video looks like as text: almost at bit Matrixy.


No homage to 70’s and 80’s computing would be complete without keyboard beeps and disk thweeps. Keystrokes generate a 1000hz feedback beep, sd card writes make a 3600hz mechanical click. These sounds are generated in the video isr by toggling pin 6 after a certain number of HSYNCs.


WebTV IR is an unusual UART-like asych serial protocol. It runs at ~660 baud with 3.25 start bits, a 10 bit class code, 8 bit key code, parity and stop bit. Class codes are things like keyup, keydown etc. and key codes map physical keyboard layout. The video ISR counts HSYNCs between transitions on the IR data line and passes state change events to the keyboard code.

The PS2 code is pretty conventional. A good explanation is here.

Extra Credit

If you get the Philips $11.95 keyboard variant you get a PS2 IR receiver as well. The receiver can be…

  • used as-is as a PS2 keyboard connected to pins 2 and 3.
  • gutted and turned into a nice case.

I prefer the latter. The case has a nice slot in the back with a sliding door that is perfect for a microSD card. It has a nice IR window at the front and a TSOP31238 (5V center pin) IR receiver that can be harvested from the PCB. Get a cheap Pro/Mini + microsd breakout, add that iPod video cable and it looks like this:

Drop me a line at rossumur@gmail.com if you have any trouble.



p.s. The maze in minizork is not the same layout as in Zork I. I have it if you need it.