Sega dreamcast VMU development tools
 

loading a neat-o picture here...
 

C O N T E N T S
. . . . . . . . . . . . . .

Introduction
Resources
Disassembler Release 1.02
Assembler
Simulator
CPU Documentation
Potato Chip Hardware (new memory map!)
Hardware protocols
Sample Code
Future stuff

rest of my homepage

. . . . . . . . . . . . . .










Introduction

Why?? Where else can you get a small processor, a decent screen, lots of memory, a serial port, a buzzer in a case for only $25 (including the batteries!)? It's a great little platform for writing mini games and for little hardware projects. And, these games are easy to share with friends over the internet or in person.
 

Resources

Marcus Comstedt has provided the bulk of the tools to the community and has a very useful website. He wrote the assembler and the emulator, and has an excellent description of the VMU assembly language. He also has described some of the software entrypoints as well, and documented how the game files are saved in memory. He also wrote the first game with publicly available source code- tetris. On this page I've got a Windows port of his assembler and instructions on how to get his emulator running under Linux.

The best message boards are at booyaka.com-- that's where most people interested in developing applications for the VMU appear to be gathering. Loren Peace, who reverse-engineered the unit and wrote an animator program, runs the site with others.

Richard Munn has information on his RAMtronics website (cool icons!) with some Amiga ports, insides pictures, and an unoffical VMU FAQ. You'll see his name mentioned here a bunch.

The VirtuaMUnstaz are a good resource (they put my name in their scrolling demo!). Leo there started another discussion group; this one is more technical than the pages at Booyaka and has less whining. Visit it at http://www.egroups.com/list/vmu-dev.

Soeren Gust has been working on connecting a VMU to a PC. Check out his website.

Alessandro Sanasi has an excellent well-documented "hello-world" type program that can serve as a skeleton for future code. He also has a bunch of utilities for dealing different file formats: A .VMS->.DCI/.VMU creator, a .DCI->.VMS converter, a .VMS checksum calculator, and .LCD to textfile (for use in a source code listing), and an .LCD->.VMS converter (similar to Loren's DC Animator website, but not as fancy and doesn't require use of a website. Also generates animated .GIF's). Check it out on Alessandro's web page.

Lastly, and importantly, Sega engineer Alexander Villagran is working on getting the official VMU development tools released to hobbyists. In the meantime, he's been dropping clues and helping us figure out the internals. He hasn't been too active on booyaka in a long time; he's busy working on dreamcast.com. Check out his interview on segadreamcast.net, where he says that he's planning on releasing his tools on booyaka.com soon! (it's been a while, so I guess we have to be patient while Alexander works it through the legal bowels of Sega)
 

Disassembler
My contribution so far is the first (and still only!) publicly released disassembler. This program takes machine-readable code and turns it into a human-readable format. It's useful for dissecting and analyzing programs that have been released without source code, such as officially released games.

Features:
 - Sanyo LC86104C/108C disassembler, plus extra instructions used by the VMU
 - Automatic determination of code/data space.
 - Automatic determination of RAM banks accessed (mostly)
 - Special function registers and BIOS entry points are annotated.
 - Some instructions are automatically commented (i.e. branch if 'A' button pressed)
 - Disassembly output has been tested and found accurate.
 - Either easier-to-read or ready-to-assemble code can be generated.
 - User specification of graphic and font areas (which are commented graphically).
 - Portable GPL C code. (with C++ style comments).

The current release [version 1.02] is in three parts:  The source code, two sample output listings (plus bonus hand-annotated boom.lst), and a windows console ap executable. This program has been successfully tested against Marcus's assembler with boom, football, and Chao -- his assembler generates the exact same .vms file that lcdis took as an input, so if there is an error, it is in both of our programs. This long-delayed first release incorporates a few new features over the beta 0.8 version. Most notably, it has a special BIOS dissassembly mode that alters some of the program flow assumptions, new instruction support, and automatic RAM bank determination.

The sample listings contain output from lcdis (with additional command-line parameters specific to each program; the effects of these are visible in the memory mapping section at the top of the listing). Boom is a DC Animator program -- It has Loren's DC Animator code and graphics provided by Mike Munn. I've done a pretty complete job of hand annotating this program, with the exception of some misaligned data in the frame section which I can't explain. This program doesn't run well on the simulator, so my .vms file may have been messed up to begin with. Hopefully my annotation will be a good learning resource. Also included in the listings.zip is the football program (with no extra annotation).

Richard Munn has an Amiga port of this as part of his complete Amiga development system. And, yes, he is the big brother of Mike Munn whose graphics I stole -- what a coincidence!  His RAMTronics site is at http://go.to/rvmu or  http://www.munnfamily.demon.co.uk/rvmu.

Assembler
Marcus has a great VMU assembler. I have a windows port of version 1.8: vmuasm windows console ap; check with Richard for the Amiga version.

It's relatively straightforward; its usage is

vmuasm {-I<include_directory>} {inputfilename...}

I've also compiled a version 1.5 as a linux command line ap. It's a little old, so you might do best building your own version:  the only conversion required is to add "#include <getopt.h>" to the beginning of file main.c (and then ignore a bunch of harmless looking warnings). This is invoked in a similar fashion:

vmuasm {-I <include_directory>} {inputfilename...}

The main difference between the windows version and the linux version is that the linux version requires a space between the -I and the include directory, whereas the windows version requires that there be no space. For help, type "vmuasm -h". Email me if you want my modified source code; otherwise his is a bit easier to read.

Once you get it, the first thing you'll probably want to do is assemble Marcus's tetris code. It's a good framework for development, and is fun to play, too (I feel crazy playing it on a laptop that plays doom well!). Anyway, get tetris.s and sfr.i from Marcus's site and put them in the same directory as the assembler. Use the command

vmuasm tetris.s

and you should end up with a file called tetris.vms. This is the output file, suitable for use with the emulator, or if you build an appropriate .VMI file and put it on a properly configured website (I'm not too sure about what kind of MIME type to make it), you can get it into an actual VMU.

The assembler doesn't have much documentation, but that's why I suggest you follow the tetris code as an example. One thing that isn't obvious from this file is how local labels work: Local labels are ones that start with a period. Unlike global labels, a local label can be defined more than once in a program. Their scope is bounded by global labels, i.e., you cannot access a local label if a global label stands in the way.

Maybe an example is best:

    global1: ld #$10
    .delay   dbnz acc,.delay
             ret

    global2: ld #$20
    .delay   dbnz acc,.delay
             ret

The local label "delay" can be used twice because it is separated by global label "global2". Each of the two dbnz instructions decrement the accumulator and branches back to themselves.

Simulator
Marcus also has a great VMU simulator. It simulates most of VMU hardware -- enough to run all known Sega binaries -- but since every aspect has not been discovered yet, it is limited by our knowledge.

This program was originally written for X Windows (see below for Linux), but thanks to the nice job Marcus did in making it portable, the simulator is available for many platforms.

David Steinberg made a windows port, and Marcus tweaked it for inclusion in his regular distribution (it'll be in version 1.7). My only (minor) complaint with this program is that the window is too small-- I've started a windows version that will hopefully support an in-real-time resizable window, but development on it has taken a backseat to my hardware debugging.

Colm Cox has a really nice DOS port that runs full-screen or in a dos box under windows. His web page can be found at http://www.fortunecity.com/skyscraper/wav/1190/

Richard Munn has an Amiga port and also a complete Amiga development system. He also has some useful scripts for generating asm code out of graphics. His RAMTronics site is at  http://go.to/rvmu or  http://www.munnfamily.demon.co.uk/rvmu.

Richard Bannister is working on a MacOS port; sorry, but I don't have any more info on this handy as I type this.

I used to host the Linux binaries because at first I had trouble getting it to compile (I'm not much of a linux guru). Then I discovered the ridiculously easy way to install it that Marcus provided - it's probably easier to follow these instructions than to install my binary.

Installation instructions (tested with Red Hat 6.1, but pretty generic):
1. Download the file. I downloaded it in windows, booted linux and accessed it with a mounted dos partition. Or you could just download directly into linux. Anyway, my file name was "softvm~1.gz"
1. Un g-zip it: gzip -d softvm~1.gz
2. Untar it: tar -x -f softvm~1
3. Go to the directory it created: cd vms
4. Run the configuration script: ./configure
5. Make it: make


The simulator has only three options, only one of which is really useful:
-h    Displays a help message: Usage: vms [-h] [-V] [-2] game.vms ...
-V   Displays the version number: softvms v1.0 by Marcus Comstedt <marcus@idonex.se>
-2    Runs with 2x size pixels. The screen is small, even at this double size.

A typical usage is: vms -2 tetris.vms
 

CPU Documentation
The VMU uses Sega's own custom Sanyo LC8670 processor, nicknamed "the potato". It uses the same instruction set and some of the same registers as some non-custom parts, such as the LC86104C/108C processors, but also adds some custom (non-documented) stuff.  You can access Sanyo's datasheets through their clunky interface at http://www.elisnet.or.jp/login-sanyo.htm, or you use my LC86104C documentation mirror. The mnemonics are at the end of the document.

The VMU's processor instruction set is pretty close to the the LC86104C, but with four differences (that have been found, so far).  Most notably, the operation of the MUL and DIV instructions are different, although their encoding is the same.

The two other undocumented opcodes are $50 and $51, and I'm going to tenatively name them LDF and STF (email me if you have a better name). According to Marcus, the $50 reads the flash memory and works like an LDC except that it doesn't add ACC to the address. The 17th address bit is taken from SFR $154. Opcode $51 writes the flash, but it has a safeguard which makes it a bit more difficult to use. [he didn't elaborate on the safeguard].

Marcus has also found out that instructions $48-4F and $58-5F map to "BPC d9,b3,r8", which is a "if bit set, clear it and branch". It's on his page.

Check out Richard Munn's page for his VMS-ectomty to see the innards and find out why people call it the potato!

Potato Chip Hardware
It's really the hardware that differentiates a computer and not just the instruction set. The disassembler allows us to watch a real life program interact with the hardware registers, and hopefully we can determine what register does what.  This is maybe halfway done - useful enough to construct serious programs, but not enough to do fancy things, like communicate to another VMU or play music through the speaker.

I've started to document all the registers in this document (updated 3/22/00); this data is mostly from Alexander (SFR names), the databook, from disassembling programs, and Marcus's experimentation. Suggestions in this department would be really welcome!

Here are some other general facts to start off with:
    The computer has 128KB of flash, but only 64KB is visible at a time.
    There are 768 bytes of RAM. One section of "working ram" is available by accessing registers. The processor can directly access 256 bytes of ram, and a bit in the PSW register controls which of two banks this is-- either a user or a system bank (containing the stack).
    The system software can be used to read or write most of the FLASH memory.

We haven't figured out where the built-in code resides or been able to get a listing of it. There is a section of the Flash that isn't allocated in the FAT (see Marcus's page), but he's been unable to read this. Another mystery is that it seems that the VMU code references low memory (the $100 page), but it seems that this portion is usable for data storage.
 

Hardware Protocols (sortof new!)
update 3/7: I haven't done much with this for about 2 months now. Soeren Gust has built a PC-VMU interface using an Atmel microprocessor. He also gives a better interpretation of the meaning of the bytes. Check it out at Soeren Gust's website.

This is the latest portion that I've been working on.  I took a soldering iron to one of my VMUs and instrumented up the connector. I've finally gotten around to renting a dreamcast [Sidebar: Ok, call me a hardcore VMU fan. I don't have enough time to own a TV and I get my fill of games on my laptop, so I don't own a dreamcast. Unfortunately, the rental did not include the modem; I guess the people at the video store weren't quite prepared to walk people though dial-up connections, which is unfortunate because the modem is really neat] and have hooked it up to my company's logic analyzer (It's capable of 32 channels at 1 GHz and 96 more at 250 MHz, but somehow I don't think we'll need all that capability).

I have a lot of effort to go yet, but here's what I've learned so far:

There are 14 pins on the VMU. They are actually labeled on its internal PC board, so I'll keep the same convention. Looking from the back of the unit with the connector at the top, the pins are numbered (from left to right) 1 through 14. Pins 1 through 7 are on one half of the connector and pins 8 through 14 are on the other half. The connector is designed so that some of the pins engage before the others; these are marked with an asterisk below. The signal levels seem TTL-compatible, but I haven't measured them carefully.
 
pin
mates to
play default
(w/ dc)
direction

*=connects first

 vmu-vmu usage
DC-VMU usage
1
14
1
*
power in?  I think this is used by the dreamcast to power a VMU with a dead battery. I haven't looked at the schematic yet, so something else might be needed to build a battery eliminator (like a current regulating resistor perhaps?). I measured 3.28 volts.
2
13
1
*
low=dreamcast not connected  high=dreamcast connected
3
12
0
out
sync clock (rising edge active) goes high during mem xfers
4
11
1
out
sync data (delayed by 8 bits) used for periodic data (async?)
5
10
1
out
sync data mem xfer data (idles high)
6
9
0
 
handshaking? ?
7
8
-
*-
ground
8
7
-
*-
ground
9
6
1
 
handshaking? ?
10
5
1
in
sync data used for periodic data (async?)
11
4
1
in
sync data (delayed by 8 bits) mem xfer data (idles low)
12
3
0
in
sync clock (rising edge active) goes high during mem xfers
13
2
0
*
 ? ?
14
1
1
*out
power out of VMU (on all the time), measured 3.52 volts

The data lines for VMU-VMU communication seem to contain the same data, but one data line is an 8-bits delayed version of the other. I'm not sure why this is. Data is transferred most-signifcant-bit first.  The two clocks (one for each pair of data lines) are about 7812.5 Hz -- 64uS low and 64 uS high -- and don't run continuously.

Here's a VMU-VMU transfer sequence I've analyzed: (The file being sent is named "SONICADV_INT", the description is "MAIN_SAVE_FILE", the size is 10 blocks, and the date is 11/27/98)
 
out in purpose
$11    hello
  $e0  hi there
$02    i want to send you something
$03    [unknown usage]
$0A    guess: size 10 blocks [unknown usage]
  $0c  yeah, go ahead
$1b    ok, I'll go ahead
  $e0  I said go ahead
$06    ok. Here's the file name:
12 chars   ‘SONICADV_INT’
$ff    that's it
  $0e
<or>
$0a
I don't have that file. you can continue.
<or>
I already have filename (abort)
$04   here's the first data chunk
128 bytes   file data
$00    
  $c0 ok I got it 
$10    
  $e0  continue
$08    
$00    
$ff    
  $0c  
$50    
  $e0 continue
$04   here's another data chunk
128 bytes   file data
 <unfinished>    

When connected, the dreamcast continuously talks with each vmu even if it isn't displaying graphics. This periodic communication is weird- it doesn't look clocked (as in vmu-vmu comms) and it doesn't look to asynchronous. It is hard to believe it is asynchronous because typically asynchronous data is sampled with an 8x or 16x clock, and I'm not sure if there is a clock this fast in the VMU. The data bits are at about 200kHz; the VMU has one 32kHz and one 600 kHz crystal. Alexander said that the VMU could run at 5 MHz when connected to the dreamcast (which is fast enough to sample the data), but I don't see how this clock is generated (originally I had assumed the clock came over the connector, but I didn't see it).  This data may be a modulation scheme that includes the clock in the data, like manchester encoding or the dot-dash of morse code.

When the dreamcast reads or writes to the VMU another format is used(!) Pins 3 and 12 go high and data is transfer on pins 5 and 11 (as opposed to pins 4 and 10 for the periodic communications).

Things to do still-- see how the VMU-VMU conversation continues and how it ends up. (despite skull-numbing speed, my trace buffer is a bit small so I have to do a lot of triggers)  Also, I want to see how game code is downloaded into the VMS so that I can build an PC parallel-port downloader.
 

Sample Code
What fun is this all if you don't write neat programs? I thought I'd cut my teeth on a version of pong. It's still in major development, but here's pong beta [version 0.2, now with better "ball feel"]  I've improved it enough that I've got the source code to share. It seems pretty slow on Colm's emulator, but fast on Marcus's linux port, so I'm not sure what it will be on a real VMU. Currently it has a lot of delays built into it, so it can be tweaked to run much faster.

This demo shows a partially done title screen (with just my name so far)-- press 'a' to continue to the game. The game screen appears; press "A" to serve the first ball. The paddle is moved using the left and right buttons. If you miss, you'll lose a ball, and of course, when you're out of balls the game restarts. You can put english on the ball depending on what part of your paddle is hit -- this feels better than what I had before which required you to be moving the paddle to spin the ball.

You may also notice that the ball goes right through the bricks. Let's just say it's a really heavy ball and that the bricks are actually dust bunnies. That's the major thing missing right now- the bricks are inert.

The code so far is just for the emulator. I don't have a .VMI file for the DC, and (WARNING!) I haven't tested it on an actual VMU.

Alessandro Sanasi has an excellent well-documented "hello-world" type program that can serve as a skeleton for future code. Check it out on his web page.

Future Stuff to Figure out
Some things that would be nice to find out:

VMU<->VMU and/or VMU<->dreamcast communication protocol (both electrical and logical) [some progress here]
Built-in source code listing (aprox. 28K) [have object, working on source!]
FLASH programming specifications [marcus figured out how to make the built-in firmware do this]
how to build a PC simulator/emulator [done already!]
how to program a VMU from a PC [soeren has done this, but with extra hardware]
how to enable the 3D holographic display (maybe that's just a vicious rumor)


my homepage

last update: 3/28/00 [LCDIS release 1.02, added memory map, vmuasm v1.8, flash info in potato.htm, welcome Alessandro]

legal: this page is not affiliated with Sega. Use this information at your own risk. "Sega" and "Dreamcast" are trademarks of Sega Enterprises, Ltd. Also, this notice was written without legal counsel and may be totally ineffective at warding off lawsuits. The theory here is that you'll email me and I'll fix whatever-it-is before you sue me. One really interesting court case concerning reverse engineering of software is Sega v. Accolade 977 F2d 1510 (9th Cir. 1992).