Coding · Tutorial

Tutorial #1 – An introduction

This is the first of what I hope will turn into a series of posts that will help the newcomer to programming the Voltmace Database, Interton VC4000 and related TV video game consoles. I will cover both the microprocessor and the video chip. I will assume some basic knowledge of assembler programming but will try to provide links to other websites to explain some fundamentals that I don’t want to get bogged down in here. Please leave comments or use the contact page if you have any questions.

I will be using examples of real code as much as possible, taken from my Leapfrog program, details of which you can find via the Links page of this site. On that page you can also find links to data sheets for both the 2650 microprocessor and the 2636 programmable video interface, or PVI.

  lodi,r3   H'AA'	;blank the score digits
  stra,r3   score12
  stra,r3   score34

  lodi,r3   H'C8'	;clear all other PVI registers
  stra,r0  object1SHAPE,r3,-
  brnr,r3  loop0015

All mnemonics in the 2650 instruction set are 3 or 4 characters long. In most cases the first three characters tell us what the instruction is going to do, and the fourth one tells us what addressing mode it will use. In the example above there are three types of instruction:

  • lod – Load a register with data.
  • str – Store the contents of a register.
  • brn – Branch to another location in the program.

The three types of addressing mode used in this example are:

So lets look as the example line by line and explain these in a little more detail.

lodi,r3 H’AA’ – this tells the processor to load register r3 with the data byte immediately specified in the instruction itself which in this case is the Hexadecimal value AA.

stra,r3 score12, and stra,r3 score34 both tell the processor to store the contents of register r3 in the absolute memory addresses labelled score12 and score34. These have been defined elsewhere in the program as memory addresses 1FC8 and 1FC9 which in our circuit are two registers in the PVI that define the four characters that can be displayed as score values at the top or bottom of the screen. Each nibble represents one character, 0-9. Hexadecimal values A-F cause the digit to be blank.

The effect then of these first three instructions is to blank the score digits.

lodi,r3 H’C8′ you should now be able to figure this out for yourself.

stra,r0 object1SHAPE,r3,- is a more complicated instruction, but very powerful. The first part is straightforward. The contents of register r0 are going to be stored somewhere. That ‘somewhere’ is defined by object1SHAPE,r3,- . What happens here is the final address is calculated by subtracting 1 from the value if r3 and adding that to the address defined by object1SHAPE , then saving r0 in the resulting address.

This is what is called indexed addressing. In this case the index register is r3.

The sign at the end of the line indicates that the index register will be automatically decremented before the store operation. This is known as pre-indexing. Some other microprocessors use post-indexing where the decrement is performed after the data is stored, but the 2650 always does the decrement first.

The 2650 can also do an auto-increment. This would be shown by a + sign at the end of the line: stra,r0 object1SHAPE,r3,+ Again, the increment would be done before the data is stored.

A final option would be to use the index register without changing it: stra,r0 object1SHAPE,r3

brnr,r3 loop0015 – this causes the program execution to branch to program location loop0015, but only if r3 does not equal 0. The mnemonic brn stands for Branch on Register Non-zero. It uses relative addressing as indicated by the r at the end of the mnemonic. This addressing mode uses one less byte of code than absolute addressing, but can only jump to a location within about 128 bytes of the current instruction.

These two lines therefore execute repeatedly until r3 is decremented to zero. The value of object1SHAPE is 1F00. The first time around the loop, the data in r0 is stored in 1F00+C8-1, or 1FC7. The last time around it is stored in 1F00. Register r3 is now 0 so the branch back to loop0015 is not taken and the processor moves on to the next instruction.

We will use code like this wherever we want to work with a block of data.

Video circuits · Voltmace Database


The Voltmace Database, along with many other UK video game consoles and home computers of that era, sent their PAL-I output to an analog TV set. To do that, the output had to be modulated on an RF signal. This was done inside a little tin box. The Database used an ASTEC UM-1233 tuned to channel 36.

While I don’t care too much about the analog wizardy that goes on inside this box, I thought I should research it a little for the sake of completeness, and for help in adjusting voltage levels if I ever hope to get a useable TV signal. There doesn’t seem to be a whole lot of detail about it anywhere, but this article (translated by Google, I think from Hungarian), seems to describe the circuitry in depth.

Perhaps more useful are these snippets of information from Motorola application note ” AN4921D A video display board for CD-i development” :

The MC13077’s composite video output (COMP V) connects to both of 1C45’s non-inverting inputs. This means that both of the MCi4576A’s amplifiers output composite video. One amplifier drives to CENELEC
/RS-343 levels, while the other provides an input to an RF-modulator (1C46). As the UM1233 RF-modulator requires a 0.64V peak-to-peak input around a 2.83V black level, the associated amplifier output signal
requires some level conversion. Resistors R27, 28 reduce the peak-to-peak voltage and a 470μF capacitor (ClO) provides AC-coupling. The LM317LZ regulator (1C43) and associated circuitry provides a DC-bias for the AC-coupled signal.

Voltmace Database

First look inside my Voltmace Database

I finally got around to opening up one of my Voltmace Database consoles today. It wasn’t as easy as I thought, but I was able to take lots of photos of the hardware. My main motive was to see what condition it was in, and decide whether to replace any electrolytic capacitors before attempting to power it up. At some point I also want to create a circuit diagram of it, but this is going to be a bigger job than I imagined.

The first thing I noticed was that the console seems to have originally been designed to have an internal loudspeaker. The console case has a hidden grille, with a circular mounting ring and screw holes. The circuit board has space for missing components, I’m guessing to make an audio amplifier, and the bottom of the console has a cutout that might have taken a switch, probably to turn the speaker on or off.

The circuit board is double sided, but not plated through. Where a through connection is required, a pin is inserted and soldered on both sides.

I was also interested in the exact vintage of the machine. The retail box had a sticker with the Voltmace name and their Park Drive address. The console itself had the earlier Videomaster brand on the front, but the back had a Voltmace label with their earlier Church Street address. The latest date code I could find was 8134 on one of the voltage regulators.


Indirect relative addressing

0BC0 : 0D 1F 94    loda,r1 X1F94
0BC3 : 51               rrr,r1
0BC4 : C9 FB         strr,r1 *X0BC1

In this example, r1 is saved back to its original location (1F94) using indirect relative addressing. This saves one byte of code. The disassembler doesn’t resolve the full address of the save operation, which makes it a little hard to follow. I shall fix this with comments eventually, unless anyone can suggest a better way.

DASMx · Disassembly · Leapfrog · WinArcadia

The puzzle of a lifetime

Way back in November 1982 I finished writing Leapfrog, a game for the Voltmace Database console, and based on the arcade game Frogger. In 2003 I came across a mention of Voltmace on a and did a short interview for them, but it wasn’t until 2017 that I got interested in retro programming, and discovered the WinArcadia emulator. The binary of Leapfrog doesn’t run on the emulator, so I made a start at disassembling it to try and figure out where things are going wrong and maybe helping to improve the emulator. (Somewhere along the line I had tracked down my boss at Voltmace, but unfortunately he had recently thrown out all the stuff he had from the long defunct Voltmace.)

I used the disassembler DASMx which made a pretty good stab at the job right out of the box, and I made a start at trying to document a paper copy, with limited success. However, life got in the way as it so often does, and I’m only now getting back to the task. This time around I read the instructions that came with DASMx (!) and understand the need for the symbol file and how to make best use of it. After multiple loops of disassembling, checking the results and slowly figuring out what is data and what is code, I am getting close to having something useful. I’m now at the stage of trying to assign somewhat meaningful labels to all of the RAM locations and some of the code branch locations and the few subroutines that I used (more on that later). I’m still a long way off fully understanding why I test certain bits, increment certain counters, or did things the way I did. It is turning into a huge cryptic puzzle, but one I’m enjoying immensely.

It would have been nice to have had the original source file though!