VU emu

versión española


 
   
Introduction
Using the emulator
VU emu Source Coce
To Do
Downloads

 

Introduction

VU emu is an emulator for the PS2 VU1 vectorial unit developed in C++. The aim of the project is to be able to test small micro code routines and, once the code is safe, use it on the PS2.

If you have a PS2 Linux Kit you should forget this program and use Sauce's Visual VU Debugger. Sauces debugger is a powerful tool which perform a lot more functionality than VU emu. But for the rest of the people who does not have a Linux Kit this tool can be usefull. In fact I get involved in this project be cause I was tired of see how all the Linux Kit development tools (VCL, Sauces, etc..) are not distributed under open source.

This version is a very early beta of the product and it should contain dozens of bugs, I promise to debug it as soon as I can. I started this project as an 2 hours entertainment and, finally, I need more than three weeks to do this beta. I am a little feed up of this application so I do not test it deeply. Please, report any error found to m3ntol@yahoo.es in order to be fixed.

 

Using the emulator

In order to be able to run the emulator we need to provide it with separate code and memory files. The code file should not contain any preprocesor instruction, only microcode and labels. Emulator will run the program till a NOP[E] UPPER instructions will be found

I have included a lot of examples so you can make a clear idea of how the files should be prepared.

Emulator interface looks as follows. Make click on the links to get descriptions of each item:

Load Program
This option will open a 'Open File' dialog where you can select the program code file; remember, only microcode no memory, no preprocesor. If any error is found a 'Sintax Error' message will appear. If this happen, please, send me the file to m3ntol@yahoo.es  so I can test if there is any bug in the program.

Load Memory
This option will open a 'Open File' dialog where we can select the memory file. By the moment this options do not do anything. Next version will incorporate mem load.

Save Program
This option is also disabled, next version will incorporate save code.

RESET
This option will RESET the VU chip, mem and registers.

RESTART
This option Restat the program. By clicking this button is like reset and load the same code.

Step
Execute curren instruction.

Run to BreakPoint
Just run to next break point.

Settings
By the moment this option do not do anything.

Help
Open this window.

Exit
Close aplication.

Instruction pointer.
You can see in this column which instruction will be the next in be executed. This instruction is  marked with a '>'.

Break Points
This column see where BreakPoints are located. Each instruction with breakpoint have a 'O' mark. You can toogle breakpoints by right clicking over the line you whish (click over code). REMARK!! if you put a break point at a a label, errors may occurs.

Memory address
This is the memory addres of the instruction (address x 16)

Cycles
Display the number of clock cycles  spent by the instruction in its last execution. Due to internal VU architecture stalls may occurs.

UPPER instruction
UPPER microcode.

LOWER instruction
LOWER microcode.

In the right side there is a panel with register information, you can see a description of each item by click on it:

Register Selector
This combo box allow us to select the register we wish to see/edit. There are 16 VI registers, 32 VF registers and ACC, P, Q R and  special registers.

Register values
This edit boxes display the values of the registers and allow us to modify them.

STALL
When you try to access a register whose value is not still fixed the procesor stalls. This edit box see how many clock cycles the register needs to be fixed. If you try to read the registers when this value is different than 0 stall states will occur.

Last read
Address of last instruction in read the register.

Last write
Address of last instruction in write the register values.

View as
VF registers can be stored in different formats. By selecting differents options you can see values in several formats.

Instr. Status and flags windows are self explanatories. First one display bulk information about the instruction to be executed and the other one display flags values. REMARK!! flags values can not be edited.

Finally, memory window display the content of the VU 16 Kb memory. The values can be edited and displayed in several formats.


 

VU emu source code

If you are interested in the source code of VU Emu you can download in this link: here, Application has several C++ clases to emulate VU1 unit and an user front progammed in C++ Builder 4. Front can be easily changed (by programing) to add new functionality or migrate to other platforms.

The most interesting part of the code is the VU1 emulation classes. There is a main class 'VU' which contains all the VU Unit elements (registers, flags, ...) and all the functionality to runs programs. Code is documented (not too much in fact...) and you are allowed to change wathever you want.

For sure, there should be a lot of bugs, I will try to debug all but if you find and fix one, please, send em a copy to m3ntol@yahoo.es or if you find one and do not wish to fix it, please, send it to me and I try to fix.

You can take a general idea of the clases looking at this code:

//===============
// type definitions
//===============

typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long uint64;
typedef char int8;
typedef short int16;
typedef int int32;
typedef long int64;

typedef struct int128 {
int64 lo,hi;
}int128;

typedef struct fvec {
float x,y,z,w;
}fvec;

typedef struct ivec {
int32 x,y,z,w;
}ivec;

typedef struct ivec16 {
int16 x,y,z,w;
}ivec16;

typedef union vec {
int128 value;
fvec vf;
ivec mi;
int16 vi;
}vec;

 

//============================
// Generic register classes VF y VI
//============================

class VUReg {
private:
int vstall;
int lRead;
int lWrite;
protected:
vec data;
public:
int stall(); //stall states before can accessed
int lastRead(); //last instruction in read value
int lastWrite(); //last instruction in write value
void stall(int v); //set previously defined values
void decstall(); //decrease stall, this occurs when a cycli is completed
void lastRead(int v); //set las instrcución read
void lastWrite(int v); //set last instruction write
};

class VFReg:public VUReg {
public:
float x();  //GET values
float y();
float z();
float w();
void set(float v); //SET values
void x(float v);
void y(float v);
void z(float v);
void w(float v);
void xtoi(float v, int a); //Used to cast between types
void ytoi(float v, int a);
void ztoi(float v, int a);
void wtoi(float v, int a);
void xtof(int v, int a);
void ytof(int v, int a);
void ztof(int v, int a);
void wtof(int v, int a);
void mcopy(int *dest, int reg); //Used to get memory data
void mwrite(int *org, int reg); //Used to set memory data

};

class VIReg:public VUReg {
public:
int16 value(); //read values from register
void value(int16 v); //sets values on register
};

 

//============================
// PARSER clases
//============================
//TYPES of flavors
//0 - normal
//1 - i register
//2-5 - bc broadcast 2-x 3-y 4-z 5-w
//6 - q register
//7 - a acumulator
//8 - ai acumulator and i register
//9 - aq acumulator and q register
//10-13 - abc acumulator broadcast 10-x 11-y 12-z 13-w
//=======================================
// Types of params
// VI, VF, VIDEST, VFDEST, ACC, IMM24, IMM15, IMM12, IMM11, IMM5,
// I, IMM11(VI), IMM11(VI)DEST, (VI)DEST, (--VI), (VI++),
// P, Q, R, VI01


class VUInstructionDef {
public:
int mode; //uppder-lower-macromode
int sufix; //diferent flavors. See above
char nemot[15]; //instruction
int operands; //number of operands
char types[4][50]; //type of operands (by order)
int throughput; //see VU manual
int latency; //
int lastthr[15]; //one for each flavor
friend class VUInstruction;
};

class MicroCode
{
public:
VUInstructionDef Instr[200]; //only encapsulates de parser set-up
int nInstructionDef;
void DecThroughput(); //decreases instruction throughput counter
};

 

//=================================
// Instructionn, symbol and parameter classes
//=================================
//=======================================
// Types of params
// VI, VF, VIDEST, VFDEST, ACC, IMM24, IMM15, IMM12, IMM11, IMM5,
// I, IMM11(VI), IMM11(VI)DEST, (VI)DEST, (--VI), (VI++),
// P, Q, R, VI01

class VUParam {
public:
void Reset(); //used when reset
int type; //kind of parameter vf, vi, value, other
int index; //if vf-vi-other index i.e. VI3 VF8 VF31
char sufix[5]; //x-y-z-w-combination
unsigned long udata; //data value
long data; //data value
char label[50]; //if parameter is a symbol, this indicates the label
int stalling; //used for calculate stallings
int memdir; //address of instruction
};

class VUInstruction {
public:
void Reset(); //used when reset
char flg; //has the instruction a [E] flag or similar?
int addr; //memory address
int tics; //tics counter
int breakpoint; //user breackpoint?
int SymbolIndex; //Symbol index, only for easy drawing
int InstIndex[2]; //pointer to instruction class
int flavor[2]; //flavor of instruction
char dest[2][50]; //XYZW and combinations
VUParam Params[2][4]; //parámeters
};

class Symbol {
public:
char symb[50]; //if line is a symbol this containts the address of label
int Line;
};

 

class VU {
public:
VFReg RegFloat[32]; //32 float registers
VIReg RegInt [16]; //16 integer registers
VFReg ACC, I, Q, P, R; //special registers
//P & Q are only 1 float so I use only the x value
uint16 PC; //program counter
int64 clock; //clock ticks
ivec dataMem[1000]; //data memory 16 Kb
VUInstruction program[1000]; //program to be executed
int NInstructions; //number of instructions to be executed
Symbol Labels[500]; //as much as 500 labels
int NSymbols;
Symbol MemDir[500]; //as much as 500 labels
int NMemDir;
//FLAGS
uint16 ClipFlag[4];
int StatusFlag;
char MacZ,MacS,MacU,MacO;

VU();
void Tic(void); //do all the tastk when running
int DoUpper(); //perform upper part of instruction
int DoLower(); //perform lower part of instruction
void Reset(); //used when reset
void DecStall(); //decrease stall on all registers
int Stalling(VUParam &a); //calculate if a rgister is stalling
void (*CallBack) (int mode, int error); //callback function to draw all properly

void MemVal2(uint16 v2,int16 *v3); //get/set memory values in diferents formats
void MemVal16(uint16 v2,char pos, int16 *v3);
void MemSetVal16(uint16 v2,char pos, int16 v3);

//all the rest are instructions definitios.

//UPPER instructions
int VU_ABS(VUInstruction &a);
int VU_ADD(VUInstruction &a);
int VU_CLIPW(VUInstruction &a);
int VU_FTOI(VUInstruction &a, int mode);
int VU_ITOF(VUInstruction &a, int mode);
int VU_MADD(VUInstruction &a);
int VU_MAX(VUInstruction &a);
int VU_MIN(VUInstruction &a);
int VU_MSUB(VUInstruction &a);
int VU_MUL(VUInstruction &a);
int VU_NOP(VUInstruction &a);
int VU_OPMULA(VUInstruction &a);
int VU_OPMSUB(VUInstruction &a);
int VU_SUB(VUInstruction &a);

//LOWER instructions
int VU_B(VUInstruction &a);
int VU_BAL(VUInstruction &a);
int VU_DIV(VUInstruction &a);
int VU_EATAN(VUInstruction &A);
int VU_EATANXY(VUInstruction &A);
int VU_EATANXZ(VUInstruction &A);
int VU_EEXP(VUInstruction &A);
int VU_ELENG(VUInstruction &A);
int VU_ERCPR(VUInstruction &A);
int VU_ERLENG(VUInstruction &A);
int VU_ERSADD(VUInstruction &A);
int VU_ERSQRT(VUInstruction &A);
int VU_ESADD(VUInstruction &A);
int VU_ESIN(VUInstruction &A);
int VU_ESQRT(VUInstruction &A);
int VU_ESUM(VUInstruction &A);
int VU_FCAND(VUInstruction &A);
int VU_FCEQ(VUInstruction &A);
int VU_FCGET(VUInstruction &A);
int VU_FCOR(VUInstruction &A);
int VU_FCSET(VUInstruction &A);
int VU_FMAND(VUInstruction &A);
int VU_FMEQ(VUInstruction &A);
int VU_FMOR(VUInstruction &A);
int VU_FSAND(VUInstruction &A);
int VU_FSEQ(VUInstruction &A);
int VU_FSOR(VUInstruction &A);
int VU_FSSET(VUInstruction &A);
int VU_IADD(VUInstruction &A);
int VU_IADDI(VUInstruction &A);
int VU_IADDIU(VUInstruction &A);
int VU_IAND(VUInstruction &A);
int VU_IBEQ(VUInstruction &A);
int VU_IBGEZ(VUInstruction &A);
int VU_IBGTZ(VUInstruction &A);
int VU_IBLEZ(VUInstruction &A);
int VU_IBLTZ(VUInstruction &A);
int VU_IBNE(VUInstruction &A);
int VU_ILW(VUInstruction &A);
int VU_ILWR(VUInstruction &A);
int VU_IOR(VUInstruction &A);
int VU_ISUB(VUInstruction &A);
int VU_ISUBIU(VUInstruction &A);
int VU_ISW(VUInstruction &A);
int VU_ISWR(VUInstruction &A);
int VU_JARL(VUInstruction &A);
int VU_JR(VUInstruction &A);
int VU_LQ(VUInstruction &A);
int VU_LQD(VUInstruction &A);
int VU_LQI(VUInstruction &A);
int VU_MFIR(VUInstruction &A);
int VU_MFP(VUInstruction &A);
int VU_MOVE(VUInstruction &A);
int VU_MR32(VUInstruction &A);
int VU_MTIR(VUInstruction &A);
int VU_RGET(VUInstruction &A);
int VU_RINIT(VUInstruction &A);
int VU_RNEXT(VUInstruction &A);
int VU_RSQRT(VUInstruction &A);
int VU_RXOR(VUInstruction &A);
int VU_SQ(VUInstruction &A);
int VU_SQD(VUInstruction &A);
int VU_SQI(VUInstruction &A);
int VU_SQRT(VUInstruction &A);
int VU_WAITP(VUInstruction &A);
int VU_WAITQ(VUInstruction &A);
int VU_XGKICK(VUInstruction &A);
int VU_XITOP(VUInstruction &A);
int VU_XTOP(VUInstruction &A);
};


Todo

There are tons of things to do. I have divided the taks in differents parts and I will program it as soon as I wish (not by the moment)

PARSER
Parser module is responsible for reading and parsing the code and memory files and load it into the VU1 structures and clases. There are several improvements like:

 

FRONT
Well, front is not emulation at all. It only make classes accesibles to the user but there are also a lot of improvements to do:

 

EMULATOR
Emulator are the classes which emulates VU1. There are also tons of improvements:


Downloads

Windows exe
Source Code