PS2 Linux Programming

 

A simple VU1 Micro Program (PATH 1)

 

 

Introduction

 

In this tutorial a sprite is rendered using pretty much the simplest VU micro-program that can be made. The point of the tutorial is to illustrate the basic techniques and steps that must be undertaken in order to get VU1 running in micro mode. In the tutorial, a GS packet is pre-build, upload into VU1 memory, then kick it off to the GS with a simple VU1 micro program. This is probably the simplest PATH1 render that is possible.

 

Background

 

Path 1 is illustrated in figure 1 below which shows the internal structure and pathways within the PS2.

 

 

Figure 1

 

 

Path 1 is from VU1 micro memory to the GIF. In order to use path 1, a micro program must be constructed and loaded into VU1 micro memory to control the transfer of data to the GIF every frame.

 

VU1 works chiefly as a pre-processor for the GS. It is designed to process three dimensional vector data and send the result directly to the GS via the GIF. VU1 executes micro programs using a fairly comprehensive instruction set - it has powerful 128bit multiply and divide units. In addition, VU1 has 16kB of instruction memory to store the micro program and 16kB of data memory to store program data. In order to start the execution of the micro instructions in VU1 a VIF code is sent to VU1 which specifies the execution start address (MSCAL).

 

 

The Example Program

 

Some new development tools and processes are introduced in this tutorial. It should be notes that the utility program (bin2as) and the section of the Makefile being used to generate the VU micro program are extracted from the samples that come with the SPS2 development libraries.

 

The VU code is contained within the file vu1code.vsm. This is compiled with the assembler ee-dvp-as which comes with the kit. The utility program bin2as turns the assembler output into a format that can be used. bin2as creates two external function pointers that are used within the main program, one that points to the start of the VU code in the binary, and one that points to the end. These function pointers are used in order to copy the VU code into VU1 micro memory. (Alternatively, the MPG VIF code, could be used to transfer micro programs into VU1 memory.)

 

In the previous tutorial the DIRECT VIF code was used to transfer data from the DMA packet sent to the VIF, directly to the GIF. In this example DIRECT is replaced with UNPACK. UNPACK transfers QWC of data from the DMA packet into VU data memory (note this is different to VU micro memory which is where the programs are stored). UNPACK takes 3 parameters, the first V4_32 says to unpack the data as-is. i.e. each quad word is an array of 4 32 bit items. The next parameter is the QWC to transfer. The final parameter is the address in VU memory where the data is to go (in this case data is being transferred to the start of memory, address 0).

 

After the data is unpacked, two more VIF codes are sent. The first is FLUSH, which basically says to wait until VU1 is idle and there is no transfer over PATH1 and/or PATH2 (i.e. there is no rendering going on). The reason for waiting until the current rendering has finished is that if data was being modifying in the VU micro program that the GS was busy rendering this could cause significant problems (remember that everything is running in parallel). The last VIF code  added is MSCALL(0) - This instruction says "Run the micro program code that is in VU micro memory starting at address 0".

 

The VU1 micro program is contained in the file vu1code.vsm and is repeated here for clarity.

 

.align 4

.vu

     

      NOP            iaddiu    VI01, VI00, 0

      NOP[E]        xgkick    VI01

      NOP            NOP

 

 

It can be seen that there are two streams of assembly language. The stream on the left is called the "upper instruction stream" and the stream on the right is called the "lower instruction stream". There are no upper instructions here so they are all NOPs. Notice that the second to last NOP has [E] at the end. The [E] tells the VU that this is the end of the program. There is a one instruction delay however, so the VU executes one row after the [E] bit and then ends the program so the final line of NOPs is necessary. There is a restriction that the xgkick instruction cannot be in the [E] delay slot. If this wasn't the case then it would be possible to removed the last line of NOPs and set the [E] bit in the first line.

 

The first VU1 instruction is "iaddiu" this instruction adds 0 to VI00 (which is hard coded to zero) and stores the result in VI01. This is the address of the start of the GS packet in VU memory. The second instruction is xgkick VI01, which tells the VU to send the GS packet at the address held in VI01 to the GS via PATH1. This micro program is executed every frame, so each frame the GS packet contained within the VU1 data memory is sent to the GIF over PATH 1.

 

A few additional features to note about the example program:

 

·        The VIF packet is pre-built in SPS2 memory with the function BuildVIFPacket();

·        The UNPACK instruction is placed at the start of the packet with the FLUSH and MSCAL instructions being placed at the end of the packet;

·        Notice (and be careful with) the alignment of the VIF codes and the qword pointers;

·        An extra method FirePacketToVIF() has been added to the SPS2 Manager class. This is similar to FirePacketToGS() except that the packet is send over DMAC channel 1 which is to the VIF. Also, within FirePacketToVIF(), the DIR bit in the channel control register is set to 1 to indicate that transfer is FROM main memory to the VIF;

·        In this example, within FirePacketToVIF(), the transfer tag enable (TTE) flag is set to 0. This means that the DMAC tag is not transferred with the data (remember it was in the previous tutorial). Notice that the VIF code is now in the first qword of the VIF packet – this can be seen at the start of the BuildVIFPacket() function.

 

Conclusions

 

In this tutorial probably the simplest PATH1 render using VU1 has been illustrated. Some additional tools and processes needed for programming the VUs have been introduced.

 

 

Dr Henry S Fortuna

University of Abertay Dundee

h.s.fortuna@abertay.ac.uk