This page relies on the Canvas element of HTML5.
[hide this message]

What is this?

The Digital Vector Generator (DVG) was a special-purpose CPU designed by Atari in the late 1970s to generate the vector graphics in coin-operated video games such as Asteroids and Lunar Lander. This page lets you program a virtual DVG and view the results on a simulated vector display.

Read below for more information, or open the program editor and start hacking.

Vectors Per Second: 200 ( Ctrl + [<] / [>] to change )
Phosphor Decay: -5%/ms ( Ctrl + [[] / []] to change )
Program ( Ctrl + Enter to assemble & run )
Quick Reference
Opcode  Operand        ...
     (value range)     ...  
LABS       X            Y       SCALE 
     (-511...512) (-511...512) (0...10)
VCTR       X            Y      DIVISOR  INTENSITY
     (-511...512) (-511...512) (0...10) (0...15)
SVEC       X             Y      SCALE   INTENSITY
       (-3...3)     (-3...3)   (0...3)  (0...15)
RTSL  (no operands)
HALT  (no operands)

Atari Digital Vector Generator Simulator

On this page, you can write programs for the DVG and see them run on the simulated vector display. To program the DVG, we use DVG assembly language. If you've never touched an assembly language before, don't worry — the DVG is a very simple processor, and the assembly language is correspondingly simple. There are only seven operations; they are:

  • LABS — Load Absolute
  • VCTR — Draw Long Vector
  • SVEC — Draw Short Vector
  • JMPL — Jump to Location
  • JSRL — Jump to SubRoutine Location
  • RTSL — Return From Subroutine
  • HALT — Halt

Additionally, there is one assembler directive:

  • LABEL — Used with the JMPL and JSRL operations.

To understand the finer points of all of these, you can read Philip Pemberton's Hitch-Hacker's Guide to The Atari Digital Vector Generator. To get you started though, I'll try to give a terse introduction here.

Programming the DVG

First, toggle open the Tools box if you haven't already. The easiest way to learn is probably by showing you some example code, so have a look in the text editing area, where you will see the program that's currently running in the simulator. The first line,

LABEL START ; This is the beginning of the program

Shows us the LABEL assembler directive, and a comment. LABEL is just what it sounds like: it's a label for a place in your program; in this case, the name of the label is "START". The semicolon and everything after it is a comment and is ignored by the assembler. Truth be told, the semicolon isn't necessary at all. The assembler looks at the beginning of each line for the LABEL directive or one of the opcode mnemonics (LABS, VCTR, SVEC, JMPL, JSRL, RTSL, HALT) and reads any operands that follow them, and ignores everything else on the line. So, the first line could just as well be written:

LABEL START This is the beginning of the program

Or even on multiple lines:

This is the beginning of the program.

It's pretty free-form.

On the next line, we see the LABS (Load Absolute) command, which takes three operands: X, Y, and SCALE.

LABS -512 0 2

What LABS does is tells the DVG to get ready to draw something, starting from the X and Y screen coordinates provided. One important thing to note is that the DVG coordinate system places 0,0 at the center of the screen. There are 1024x1024 addressable coordinate points, from -512,-512 at the upper-left, and 512,512 at the lower-right (however, the top top and bottom ~150 points are off-screen and won't be shown). In this example, our X and Y coordinates are -512 and 0, which will set the location to begin drawing from at the middle of the left screen edge.

The SCALE operand (in this example, scale is set to "2") sets the GLOBAL SCALE FACTOR for all vectors drawn after the LABS command. The GLOBAL SCALE FACTOR must be an integer between 0 and 15, and its value is interpreted as follows:

  • 0 — Multiply by 0
  • 1 — Multiply by 2
  • 2 — Multiply by 4
  • 3 — Multiply by 8
  • 4 — Multiply by 16
  • 5 — Multiply by 32
  • 6 — Multiply by 64
  • 7 — Multiply by 128
  • 8 — Divide by 256
  • 9 — Divide by 128
  • 10 — Divide by 64
  • 11 — Divide by 32
  • 12 — Divide by 16
  • 13 — Divide by 8
  • 14 — Divide by 4
  • 15 — Divide by 2

For that to make a bit more sense, let's take a look at the next program line:

VCTR 512 0 1 4

On this line is a VCTR (Draw Long Vector) command, which takes four operands: X, Y, DIVISOR, and INTENSITY. This tells the DVG to draw a vector on the screen from the coordinate specified in the previous instruction (-512,0) to the coordinate given in this one (512,0)with an INTENSITY (brightness) of 4 (from a range of 0 to 15) — though it's slightly more complicated than that.

The previous LABS command set the GLOBAL SCALE FACTOR to "2", which meant that the coordinates given in this VCTR instruction should be multiplied by 4. This VCTR command has a DIVISOR setting of "1", however, which means its value should be divided by 4! The DIVISOR values range from 0-7, and are interpreted as follows:

  • 0 — Divide by 1
  • 1 — Divide by 2
  • 2 — Divide by 4
  • 3 — Divide by 8
  • 4 — Divide by 16
  • 5 — Divide by 32
  • 6 — Divide by 64
  • 7 — Divide by 128

So, the real coordinates for any given VCTR operation are: VALUE * GLOBAL_SCALE_FACTOR / DIVISOR. In this case, the GLOBAL SCALE FACTOR and DIVISOR cancel each other out, and the coordinates in the program are interpreted exactly as given. The result? A line drawn across the center of the screen!

Monkey With It

Now's a good time to start fiddling with the program. Change some coordinates or the intensity or scale or divisor operands of a few lines and press Ctrl+ENTER to compile the program and see the changes on the simulated screen. This compiler is not helpful. If you put in an invalid operand value, you won't get an error or a warning; you'll just be ignored.

[ --- MORE TO COME --- ]


My understanding of the DVG's operation was gleaned entirely from Philip Pemberton's excellent Hitch-Hacker's Guide to The Atari Digital Vector Generator [PDF].

Further Resources