Sega Dreamcast Visual Memory
Last changed: 2003-07-22

The protocol used in VM to VM communication

With this information it is possible to send and receive files from the VM. I myself have built a complex hardware using a AT90S8515 micro-controller from Atmel connected to a RS-232 port on a PC called SerialToVM. The only purpose of the micro-controller is to translate between the synchronous communication of the VM to the asynchronous communication on the PC side providing a reliable timing.

John Maushammer found a simple way to connect a VM directly to a PC parallel port, look at his VMU2PC page for more info.

Low-level byte transport

The basic protocol is synchronous serial, MSB first, triggered on the 0-1 edge. Timing is 64µs low and 64µs high on the clock line. A delay between bytes is not necessary. The VM does receive data on pins 3-5 and sends them on 10-12.

Handshaking

Before any communication can start the VM needs 3.5V Power on pin 1 to power the external IO. Since it delivers 3.5V at pin 14 this is not a problem. The power drawn is about 40µA. To be able to send data to a VM pin 6 has to be set to 1. As soon as the VM is switched into file mode and is displaying the file list it sets pin 11 to 0. The communication can now begin. The 1 on pin 6 has to be set until the communication is complete. If pin 6 goes to 0 while there is still a transfer in progress the VM crashes, sometimes the current mini game is started, but most of the time it has to be reset with the button on the backside.

Pin-out

All pins are in 3V logic, I don't know if the VM is 5V tolerant, so better use voltage converters on the VM inputs.

Pin 1 is the rightmost pin when holding the VM as if you are playing.

Pin Direction Port-bit Meaning
1InputNone1=activate external IO, 0=all pins are floating
2InputP7:0+5V Power from DC, switches into VM to DC mode: Maple-bus
3OutputP1:2CLK out
4InputP1:1delayed DATA in
5OutputP1:0DATA out
6InputP7:3Handshake, 1="waiting for data"
7OutputNoneGround
8OutputNoneGround
9InputNoneConnected to pin 1
10InputP1:4DATA in
11OutputP1:3delayed DATA out
12InputP1:5CLK in
13?P7:2The meaning of this pin in unknown, it is not used in VM to VM communication.
14OutputNone+3.5V Power output only

Additional comments on some pins

Pin 2

If feeding pin 2 with 3.5V there is only 2.8V on pin 14, so I think the VM needs 5V here, then there are 3.5V on pin 14, just like with batteries only. If the VM gets its power from pin 2 the display blanks and the keys don't show any reaction, so I think the DC takes full control over the VM, the normal communication does not work anymore.

Pins 4, 11

The delayed data is produced by the receiving end, perhaps to check if the data is correctly transmitted. This feature seems to be quite common in synchronous data communication, the Atmel AVR AT90S8515 does use it, too. In my experiments sending to the VM works even if pins 4 and 11 are not connected, but receiving fails if pin 4 is missing.

The file transfer protocol

The protocol is base on communication blocks. The format of the blocks is start_of_block type_of_block data ... data end_of_block. Start_of_block is a byte between 0x10 and 0x1f or 0x50. The number of data bytes is encoded into start_of_block.

Start_of_block Number of data bytes
0x10-0x1fStart_of_block-0x0f
0x50128

The data blocks have to be sent in the correct order or the VM will abort the communication. If a block contains more data than needed the additional data bytes will be ignored.

Type_of_block Length End_of_block Meaning
220xffbyte 1:file-type: 0x33=save, 0xcc=mini game, byte 2: size in 512 byte blocks
6120xfffilename on VM
41280x00file-contents
810xffwrite into flash, byte always 0?
3120xffdirectory data offset 0x10, time-stamp, length and start of header
810xffwrite into flash, byte always 0?

After receiving start_of_byte the VM answers with 0xe0. After receiving the end_of_block marker the VM answers with 0x0c to continue to communication or with 0x0a to abort the communication. The reason why the VM aborts the communication has to be guessed depending on the type_of_block, eg. if aborting after sending type 6 there is already a file with the same name. The file contents is sent in blocks of type 4 in 128 byte chunks always followed by a block type 8 containing 0.

Example communication sending a file to a VM

Pin6 -> 1, wait for Pin11 (DELAY OUT) = 0.
 
Send 0x11, wait for 0xe0.
Send 0x02.
Send file-type, 0xcc = mini-game, 0x33 = saved file, see directory entry 0x00.
Send size in 512 byte blocks.
Send 0xff, wait for 0x0c.
 
Send 0x1b, wait for 0xe0.
Send 0x06.
Send 12 chars ASCII filename on VM.
Send 0xff, wait for 0x0c.
 
While there are still bytes to send
Send 0x50, wait for 0xe0.
Send 0x04.
Send 128 byte of file contents.
Send 0x00, wait for 0x0c.
 
Send 0x10, wait for 0xe0.
Send 0x08.
Send 0x00, meaning unknown.
Send 0xff, wait for 0x0c.
End while.
 
Send 0x1b, wait for 0xe0.
Send 0x03.
Send 12 bytes directory entry at offset 0x10: time-stamp, file-size, header offset
Send 0xff, wait for 0x0c.
 
Send 0x10, wait for 0xe0.
Send 0x08.
Send 0x00, meaning unknown.
Send 0xff, wait for 0x0c.
 
Pin6 -> 0.

Using the SerialToVM

The SerialToVM just converts the bit formats from VM to 19200,8,n,1. It uses full RTS/CTS handshaking, but notice that there is no way to prevent the VM from sending, if the internal buffer overflows several bytes are lost. The SerialToVM additionally uses the DTR line to control pin 6 of the VM. On normal systems the DTR line is set as soon as the serial port is opened. The SerialToVM then sets pin 6 to 1 and waits until pin 11 is 0. After that it sends 0x55 to the PC. Now you can communicate with the VM. As soon as the serial port is closed, the DTR line is dropped to 0, which lets the Atmel set pin 6 to 0.

WARNING

It is very easy possible to produce inconsistencies in the internal VM structures. Make sure the file-size and header offset is correctly entered in the type 3 block. Only use the file-types 0x33 and 0xcc in the type 2 block, using 0x00 results in loss of free blocks, using 0x01 results in unusable VM. All these problems should be correctable by reinitialising the VM in the DC.