Programming for the Playstation on Linux : Blade + libspu

This article is an updated translation of the following guide : by Bemipefe

Original material publication date : 07/01/2009 Update date : 10/05/2020

The SDK used in this tutorial is ANCIENT. For a more modern and easy-to-use PSX SDK, check Lameguy64's PSn00bSDK. It is also easily installed on GNU/Linux.

Programming the Playstation with Linux

Preface

Despite the release of the new PlayStation 3 4, and upcoming PS5, the previous models are still found on the second-hand market. The PSX (or PS1)'s production stopped in 2006, that is, after about 12 years after its release.

This guide is oriented toward those who want to venture into the programming of the PSX console on a GNU/Linux system, an experience that teaches us to understand the differences between an advanced machine like a x86/x86_64 PC and a low power machine but with big optimizations like the MIPS architecture.

A bit of terminology

As you know the most important component of a Calculator is the CPU or the Central Process Unit which is often commonly called "Processor". Our PCs or laptops that are equipped with processors that have different brands and characteristics in particular are called Intel and AMD. However, all the processors built by these two manufacturers still belong to the same family, the Intel x86 family. So both Intel and AMD processors are built according to the specifications of the Intel x86 architecture, where the 'x' indicates the identification number of a processor, for example this architecture was introduced in 1978 with the 8086 processor.

After that, as some will certainly remember, the 286 and then 386 were born leading to the birth of the "Pentium" family. At the same time AMD built the Am386, the K5, the first Athlons and so on.

What do these processors have in common ?

Simple... the machine language they use to be commanded. You can speak the same language to a Pentium 3 and an Athlon.

As complex as a computer may seem, it can be compared to a mega calculator. In fact the basic operations that it manages to perform are sums, subtractions, divisions, multiplications and obviously operations to move the data in the memory or send it to some device. These operations are called 'instructions'.

When programming a computer, you do not need to use these basic operations (though you can if you want).Instead, you write in a 'programming language'. This language will then be translated into instructions by a program called a compiler. In our case we will program in C language. Here is an example:

   void main ( ){

  s = a + b 
  printf ("Result =% dn", s); 
  } 

With this we say that we want to add two numbers and we want to print the result on the screen.

The compiler translates a file from the programming language to the machine language, that is, a series of basic operations that, performed together, do exactly what we command. This machine language program should then be able to run on both Intel or AMD processors.

On GNU/Linux, You can get informations about your processor with the command:

 cat /proc/cpuinfo 

What processors equip the Ps1 and Ps2 ?

I guess you are already wondering if the machine language used by the PSX and PS2 processors is the same as that of your PC. The answer is no.

For one simple reason, the processors of these two computers, which you like to call consoles, are part of another family of processors. Or rather, they are built according to the MIPS architecture. This family was born when Bill Gates and Steves Jobs (the owners of Microsoft and Apple respectively) were still novice. In particular, the first MIPS processor was created in 1981 in America, at Stanford University.

The PSX is equipped with a R3000 and the PS2 with a R5900 processor. The former is 32-bit whereas the latter is 64-bit. For the record, MIPS processors are mainly used in integrated devices. You may find that your ADSL router-modem is equipped with a MIPS processor, as well as pre-ARM mobile phones, DVD players, satellite navigators, washing machines, etc.

What do we need to program for the PSX's MIPS?

We are going to need to 'translate' the higher level C code into a machine language that even your x86/x64 equipped workstation can't understand, that is to say MIPS instructions.

This kind of operation is called 'cross-compiling'.

The GNU GCC compiler is a free (as in freedom) compiler. With the sources available, many versions exists for different architectures, and fortunately for us, MIPS is one of these.

You can download a MIPS pre-built version here : ftp://ftp.denx.de/pub/eldk/4.1/mips-linux-x86/iso/mips-2007-01-21.iso

Mirror

Credits go to Wolfgang Denk, for creating this crossdevelopment tools. If you want more information about his work you can visit this page: http://www.denx.de/wiki/DULG/ELDK

You'll have to mount the downloaded iso file in order to access the files it contains.

Open a terminal in the folder where you put the iso file and :

 sudo mount -t auto -o loop mips-2007-01-21.iso /mnt/cdrom/ 

Alternatively, modern GNU/Linux distibutions allow you to mount a disk image with a right-click.

Then, we have to create the folder structure for the installation :

 mkdir -p $HOME/Programs/MIPS 
 /mnt/cdrom/install -d $HOME/Programs/MIPS 

Be sure to replace '/mnt/cdrom/' with the path you used to mount the iso.

In order to avoid problems with the system compiler, the tool will be installed in you home folder.

Once this first step is taken, you have to setup a few more tools to be able to create executable PSX files.

You'll have to download and execute the following script :

Corrected version : http://psx.arthus.net/sdk/Blade/psxtool-install.sh

Original version : http://digilander.libero.it/Bemipefe/Psone/psxtool-install.sh

Once you downloaded and read it, execute the script in a terminal :

sh psxtool-install.sh 

Additionally, you have to install ePSXe on your system and add it to your $PATH. If you'd rather use another PSX emulator, you'll have to edit $EMULATOR in $HOME/bin/psx-compiler to reflect that.

Once launched, the script will download psxtool.tar.gz - Mirror.

This archive contains the sources of a few tools needed to program the PSX.

You can find a description of these tools below :

__mips_4KCle-objcopy__ : Convert executable files from ELF format to ECOFF which is the old standard Linux format.

eco2exe : It converts the ECOFF files (previously obtained with mips_4KCle-objcopy) to the PS-X EXE specific format.

exefixup : It is used to change the size of the files in PS-X EXE format so as to make their size a multiple of 2048 bytes. This is due to the PlayStation CD player being a bit rudimentary ; it can only read in blocks of 2048 bytes. If a file does not have a size that is a multiple of this value, the PSX won't be able to read the file.

vagpack & depack : The first tool converts .wav audio files into .vag audio files which are interpretable by PSX. The second does the opposite, converts the .vag to .wav .

bladeps.a : Library a bit old but still functional, it allows you to manage video prints, renderings, and something about audio, and was developed by a certain Blade . A console.o file was added to this library by Bemipefe, providing it with a sort of console mode print.

libspu.a : It is a part of the Net Yaroze SDK 'libps.a' library, of which was only taken the audio part. It will be used to make the console play sounds.

syscall.o and _start.o : These two files are the basis of the programming, in fact the first contains the list of syscall and bioscall of the PSX, the second deals with the initialization of the programs. They will be mixed with your program to make it work.

elf32psx.x : Not everyone knows that you can change the formatting of ELF files (Linux executable files) simply by editing or rewriting a custom ldscript . The ldscript is used by the linker to understand how to arrange data in an ELF. The linker is the program that takes care of establishing links between the files translated into the machine language to obtain an executable. For the compiler of our PC the linker is simply called 'ld' while for MIPS the linker will be 'mips_4KCle-ld'.

'elf32psx.x' is a script for this linker, which arranges the data in order to make it readable by the psx.

psx-compiler : This is the script that takes care of compiling and converting the PSX exe from the .c file, then creates a CD image that you can burn and put in your console or open in an emulator.

The script executes the various tools in succession in order to obtain an executable and recognizable file for the PSX:

Basically, just create a folder, put your .c files in it, and run psx-compiler in it from terminal.

Configuring ePSXe

In order to obtain the most faithful emulation, you should avoid enabling any fancy option in ePSXe.

Make sure you enable FPS limit with a setting of 30fps for NTSC and 25fps for PAL. Disable overscan and vsync. In the 'Options' menu > GTE Hacks, uncheck 'subpixel precision'.

ePSXe won't read ISO files, only BIN/CUE raw images. If you need to convert an ISO to BIN/CUE, use the provided iso2raw utility :

 iso2raw nobootinfo file.iso 

Where "file.iso" is the name of the ISO you want to convert.

To convert from RAW to ISO there is a program called ccd2iso and it can be downloaded from the package manager.

You might have to install the base build-environment of your Gnu/Linux distro.

For a debian derivative (Ubuntu, Mint...) : sudo apt-get install build-essential For Arch derivatives : sudo pacman -Su base-devel

You might also need additional 32bit libraries from your package manager:

Not sure about these three. The original script did install them but I suspect it's for ePSXe.

Our first PSX program

We can now begin to test everything, by compiling a simple program, which as in any programming language is done as the first approach to language.

I'm talking about the classic "Hello World" or the video printing of this writing. This time you will not see it on the Linux console but on the PSX. If you don't have one, well ... you'll see it from the emulator.

hello_psone - Mirror

Create a folder on the home or wherever you want, copy the hello_psone.c file inside, then press F4 or reach the location of the file from the shell, and type:

 psx-compiler 

If all goes well you should be able to see the ePSXe emulator window that opens and shows you the word "Hello World". By moving the keyboard arrows you should be able to move the writing.

Mastering a CD that the PSX can read

The only way you can burn a CD-ROM for PSONE is Mode 2, which differs from Classic Mode (Mode 1) by the space occupied in each block. In both modes, the blocks are 2352 bytes, but in Mode 1 the free space per block is 2048 bytes, compared to 2336 in Mode 2, which does not use error correction codes and therefore has more free space per block.

The remaining space of a block is occupied in both modes by metadata or formatting information such as block number, space used, sector to which it belongs, etc. This explains why it's not possible to occupy all the 2352 bytes of a block.

When burning an ISO image, remember to set it. In our case it is not necessary since you just have to click on the .CUE file generated after the compilation or after launching psx-compiler. The .CUE file is used to burn the RAW image with the extension .BIN, and it is already inserted the burning mode of this image.

Does the PSX have an operating system ?

Of course, albeit a pretty small one ! Just think that the OS of the PSX occupies in RAM just 64 KB whereas Linux/Windows set you in the hundreds of megs.

Interested in a full explanation of how an OS works ? ++++ Click here | Not sure how technically accurate this information is. Take with a grain of salt... An OS is a set of fundamental programs that make a computer usable for the user activities. In reality the thing is a little more complex, in the sense that an operating system is built in a hierarchical way, that is, you need "foundation" programs that communicate with the hardware. These foundation will provide an interface for higher level user-space applications like a music player that needs access to the soundcard, or a videoplayer, office suite, etc.

However, each machine natively has a micro OS called the BIOS, this is what sets up the machine at startup, and is the one that provides the functionality to communicate with the hardware and manage the routing on the BUS of the data. In addition, this is what interfaces with the OS that you then install on the machine. On most PCs, you can access it by pressing a key upon startup.

A fundamental part of the OS, the one that deals with communicating with the Hardware is the kernel . This provides a series of basic functions relating to display, sending data to and from devices, file management, etc.

Above the kernel are all user programs, which use all the previous levels to carry out activities that we command. Let's try to retrace the various levels with an example ... if you fire up an audio player, what happens?

This occurs more or less:

The audio player will use the functionality of the OS on which it is run (in this case Linux) to ask about the existence of a certain file. Then it will try to OPEN this file and read it. At this point the OPEN which is a SYSCALL (or system call) will perform all the steps to find this file, but in this context the BIOS functions for the management of Interrupts will also intervene. These interrupt the normal execution flow to switch to functions that vary by the type of interrupt. For example, interrupt 9 is launched from the keyboard when a key is pressed and the CPU takes care of transferring the data to the RAM from which they will be read by the various programs concerned.

The BIOS functions will in turn be called by OPEN. The requests will be of the type: on disk X read Y bytes, (where X and Y are values) and copy them into memory (the RAM).

At this point you will go up in the hierarchy going back to the application. The data will be loaded, the OPEN will know where it is in RAM, and depending on the information contained in these it will tell if the file is present or not and where it is located on the disk. The audio player will start reading and playing the file or issue an error message saying that the file does not exist.

For the PSX at this point, is the hierarchy the same?

More or less. However the OS is integrated in the BIOS ROM, contrary to a PC OS which resides on a disk drive. At boot time, the BIOS is loaded, performs the preliminary initialisations and loads up the kernel, on which the interface relies to start. This is what you see by turning on the PSX without a CD.

Now all the applications or programs, which in our case are videogames use this mini OS or BIOS to work. Be it playing animations, sounds, loading images, writing drawings, drawing polygons (3D environment), etc.

The PSX BIOS provides many interesting features. The kernel supports standard Linux syscalls, which are open, read, write, lseek, and many others. In addition, it supports some of the standard functions of the C library (the glibc library) on strings such as atoi, strcpm, strcat, etc. So programming in C you can use them as you do on your x86 PC.

The complete list of PSONE syscalls and system functions and many more information can be found on this PDF - Mirror.

PSX cd boot

The boot system of CD-ROMs on PSX is fairly simple. This can happen in two ways. In the first case we have a file on the CD called PSX.EXE and it starts it directly. This is what happens for programs compiled with the tool provided in this guide.

In the second case there is no psx.exe file on the CD but we have the SYSTEM.CNF file which contains the boot information, the typical content can be:

 BOOT = cdrom:PROGRAM.EXE;1   TCB = 4   EVENT = 10   STACK = 801FFF00 

where the line 'BOOT' specifies which program will start at boot.

Using the PSX's gpu primitives

The GPU (Graphic Process Unit) of our PSX is the processor of all the graphic instructions. This processor supports commands that can be sent by the main CPU through the 'GPU_cwb' system call which looks something like:

 GPU_cwb (void * to_print, int size); 

As first parameter it accepts structures of the type:

struct triangle {

  unsigned char R,G,B,code; 
  short x0, y0; 
  short x1, y1; 
  short x2, y2; 

};

for 3-point monochrome polygon (a triangle), or

struct rectangle {

  unsigned char R,G,B,code; 
  short x0, y0; 
  short x1, y1; 
  short x2, y2; 
  short x3, y3; 

};

for a 4-point monochrome polygon (rectangle).

To better understand how it works (as long as you know the C language) you can try reading and compiling these two sources:

polygons - Mirror

snake - Mirror

As usual, put them each in a folder and run the command psx-compiler.

As you may have guessed, R, G and B are the variables that memorize the color of the polygon. x0, y0, x1, y1... are the coordinates of the 3 or 4 points which jointly give the geometric shape we want to display.

An important variable is queue (??) which is appropriately set according to the action to be performed. In particular, the values ​​it can assume are shown in this list : GPU Command - Mirror

PSX's Memory and Pathname

The PSX's memory is made up of the RAM of 2048 KB (about 2 MB), the ROM where the BIOS and OS resides, and of course the CD-ROM.

In particular, for the latter it is useful to know how to reach a file through the syscall open.

The routes are of the type:

 "Cdrom: PATHNAME; 1" 

where PATHNAME indicates the path through the folders, to reach a certain file. For example, if we have folder A in the cdrom with folder B in it that contains the FOO file, our pathname to reach FOO will be:

 "Cdrom: ABFOO;1" 

Playing with the PSX's Sound Process Unit

The PSX SPU, or the Sound Process Unit, the apparatus that reproduces sounds, supports playback with sampling at 44.100 kHz (typical of Audio CD-ROMs). The playable formats are the PCM (Pulse Code Modulation) standard of Audio CD-ROMs and the VAG format which should be based on the PSF (Portable Sound Format).

The PSX does not have software or utilities for decoding newer formats such as MP3 or WMA.

Now a simple example with which to play a .vag file obtained by converting a .wav file through the vagpack tool to convert a .wav file just reach the file and then give it as a shell:

 vagpack filename.wav 

where filename.wav indicates the file to be converted.

spudemo - Mirror

Unfortunately, the sound quality is bad since the author (Bemipefe) was unable to optimize the program or maybe something wrong with the conversion or reproduction. However, it is useful as an example.

Other useful material

To better understand the functioning of the PSX and the bladeps.a library, Here are the demos that were contained in the development kit PsoneDevStudio for Windows :

Other Demos - Mirror

In addition, you can find the sources of the bladeps and libspu libraries that can be compiled with make from Linux :

bladeps sources - Mirror libpsu_sources - Mirror

Links

Original article ( Italian ) : http://www.mandrakeitalia.org/guide/guide/programmare-la-playstation-con-linux

ENGLISH VERSION of THIS GUIDE http://digilander.libero.it/Bemipefe/Psone/psxtool.html Link is dead

Hardware PSONE http://digilander.libero.it/Bemipefe/Psone/psone_hardware.pdf

Wikipedia Page http://en.wikipedia.org/wiki/Psone#PS_one

PSONE Programming in Windows http://digilander.libero.it/Bemipefe/psone_windev.html

PSONE resource and help http://hitmen.c02.at/

Not Yaroze http://www.geocities.co.jp/Playtown/2004/pSX/ Archived version