Sega Virtua Processor Research
Posted: Sat Feb 04, 2017 1:25 am
For the past few months, I've been digging through Virtua Racing to see how the Sega Virtua Processor works and how I could implement it into other ROMs. Reading this document: http://notaz.gp2x.de/docs/svpdoc.txt helped me understand how the DSP that the SVP runs on works. Reading that should help you understand some of the terms I'm about the use.
I have gathered the following info:
* You can set an address in DRAM that the generated tile data will be written to. You do this by taking the low word of the address in DRAM (let's say for example, $306000, we then get $6000), and then dividing by 2, because of how the DSP handles data and what not. (Going back to our example, $6000 then becomes $3000). This allows you to have multiple buffers that tile data can be dumped to.
* The way that the SVP runs is that it take commands sent from the 68000. So far, I've gotten to know commands 2, 5, and 6's functionality. Commands 5 and 6 are both commands that generate and dump tile data, but they have major differences.
* Command 5 seems to be made specifically for the SEGA screen in Virtua Racing. You can load models, but they can only really be rotated on 1 axis and you write to a variable that basically makes the models do the rest of the movement found in the SEGA screen. You basically have very limited movement of the models, and there is no camera object, either.
* Command 6 allows for models to be loaded and have more free movement. You can set its position and angle, and you also have a camera and have a world model be loaded, too. It also seems you can input sprites and allow them to be rotated and moved in a 3D space, but I haven't gotten to making that work yet.
* There are these 2 variables, in which I believe that their purpose is for timing. I do know that it's used by commands 2, 5, and 6. One of those variables is to be set to a nonzero value by the 68000 before issuing a command. Once the command has run, this value is checked to be nonzero and if it is, then it sets another variable to be a nonzero value, in which the 68000 can check and reset. So basically, you can set the 1st variable and then issue a command to generate and dump tile data. The 68000 can then constantly wait for the 2nd variable to be set, and once it has been set to indicate the command is finished, then the 68000 can then transfer the dumped data to VRAM, without timing issues.
EDIT: Pretty much every command uses these variables and is required for the commands to run.
* Command 2 only seems to do the timing thing. It only checks for the first variable mentioned earlier to be set and then sets the second variable. Nothing else.
* The model format is very simple. The first value in a model is the triangle/polygon count. Then, for each polygon, there's 2 values that set up how that polygon will be shown. If you have noticed in Virtua Racing, some models have this checkerboard pattern with 2 colors on them. This is the value that defines how the checkerboard pattern will be rendered. It defines the 2 colors (the colors being palette entry IDs) and the width and the height of each rectangle in the pattern. After that, the X, Y, and Z positions of the 3 points in the polygon are defined. The checkerboard rendering info and point positions are used for each polygon.
* Each model has $40 bytes of variables in DRAM, which each variable being a word or longword in size. When using command 6 to draw the tiles, the first model is the camera object, which also can draw the world model.
So far, I have found that the first value seems to be a visibility flag. If it's set to 0, then the model is invisible, and if it's 1, it's visible. The only exception is that the camera object for command 6 drawing doesn't seem to utilize this variable.
The next variables are the X, Y, and Z positions, which are only used by command 6 drawing.
Then, the X, Y, and Z angles are next. X and Y angles are not used by command 5 drawing, only the Z angle can be used in command 5 drawing. All 3 can be used in command 6 drawing.
The only other variable I know of now is the model address, but it's in a specific format made for the DSP. Basically, it's the address of the model in 68k space, but divided by 2 so that the DSP can use it, but it also has "auto increment by 1" set, which is used for accessing data and whatnot in the DSP. The only exception I know of for this is that in command 6 drawing, the camera object, which holds the address of the world model, doesn't use auto increment. I am still looking into that.
With the info I've gathered, I have done the following:
I've a couple of my own basic models.
And I've implemented the SVP in a Sonic 1 ROM and did a basic rotation test for a model I stole from Virtua Racing.
https://youtu.be/Hr-QmrLipEM
I hope that this has contained some valuable info on the SVP. I will be continuing to research more to fully understand how it all works! Any help is appreciated as well.
I have gathered the following info:
* You can set an address in DRAM that the generated tile data will be written to. You do this by taking the low word of the address in DRAM (let's say for example, $306000, we then get $6000), and then dividing by 2, because of how the DSP handles data and what not. (Going back to our example, $6000 then becomes $3000). This allows you to have multiple buffers that tile data can be dumped to.
* The way that the SVP runs is that it take commands sent from the 68000. So far, I've gotten to know commands 2, 5, and 6's functionality. Commands 5 and 6 are both commands that generate and dump tile data, but they have major differences.
* Command 5 seems to be made specifically for the SEGA screen in Virtua Racing. You can load models, but they can only really be rotated on 1 axis and you write to a variable that basically makes the models do the rest of the movement found in the SEGA screen. You basically have very limited movement of the models, and there is no camera object, either.
* Command 6 allows for models to be loaded and have more free movement. You can set its position and angle, and you also have a camera and have a world model be loaded, too. It also seems you can input sprites and allow them to be rotated and moved in a 3D space, but I haven't gotten to making that work yet.
* There are these 2 variables, in which I believe that their purpose is for timing. I do know that it's used by commands 2, 5, and 6. One of those variables is to be set to a nonzero value by the 68000 before issuing a command. Once the command has run, this value is checked to be nonzero and if it is, then it sets another variable to be a nonzero value, in which the 68000 can check and reset. So basically, you can set the 1st variable and then issue a command to generate and dump tile data. The 68000 can then constantly wait for the 2nd variable to be set, and once it has been set to indicate the command is finished, then the 68000 can then transfer the dumped data to VRAM, without timing issues.
EDIT: Pretty much every command uses these variables and is required for the commands to run.
* Command 2 only seems to do the timing thing. It only checks for the first variable mentioned earlier to be set and then sets the second variable. Nothing else.
* The model format is very simple. The first value in a model is the triangle/polygon count. Then, for each polygon, there's 2 values that set up how that polygon will be shown. If you have noticed in Virtua Racing, some models have this checkerboard pattern with 2 colors on them. This is the value that defines how the checkerboard pattern will be rendered. It defines the 2 colors (the colors being palette entry IDs) and the width and the height of each rectangle in the pattern. After that, the X, Y, and Z positions of the 3 points in the polygon are defined. The checkerboard rendering info and point positions are used for each polygon.
* Each model has $40 bytes of variables in DRAM, which each variable being a word or longword in size. When using command 6 to draw the tiles, the first model is the camera object, which also can draw the world model.
So far, I have found that the first value seems to be a visibility flag. If it's set to 0, then the model is invisible, and if it's 1, it's visible. The only exception is that the camera object for command 6 drawing doesn't seem to utilize this variable.
The next variables are the X, Y, and Z positions, which are only used by command 6 drawing.
Then, the X, Y, and Z angles are next. X and Y angles are not used by command 5 drawing, only the Z angle can be used in command 5 drawing. All 3 can be used in command 6 drawing.
The only other variable I know of now is the model address, but it's in a specific format made for the DSP. Basically, it's the address of the model in 68k space, but divided by 2 so that the DSP can use it, but it also has "auto increment by 1" set, which is used for accessing data and whatnot in the DSP. The only exception I know of for this is that in command 6 drawing, the camera object, which holds the address of the world model, doesn't use auto increment. I am still looking into that.
With the info I've gathered, I have done the following:
I've a couple of my own basic models.
And I've implemented the SVP in a Sonic 1 ROM and did a basic rotation test for a model I stole from Virtua Racing.
https://youtu.be/Hr-QmrLipEM
I hope that this has contained some valuable info on the SVP. I will be continuing to research more to fully understand how it all works! Any help is appreciated as well.