Pastrami+Tina: a SNES to PlayStation porting project
Players: depends on the game that we'll decide to port
Memory Card: 1+ Blocks (again, depends on the game; 1 block per save slot should to it, though)
Genre: depends
Controller: Standard Analog, Dual Shock is also supported (vibration not supported)
Time to Complete: still being developed
Languages: unknown yet, probably multi language
SDK: PSY-Q
This project is meant as a conversion procedure used to port SNES games to the PlayStation (or other systems more similar to the SNES, i.e. the Nintendo DS). It is composed of two main programs: Tina, the SNES to C converter (which is basically supposed to disassemble a full ROM and port all the code to C-style code), and Pastrami, the actual code base used to interpret all the SNES part of the software so that it can run in a similar manner to the original game.
The basic idea behind this project is to create a decent conversion of the 65c816 code so that it can be recompiled to newer systems using a set of macros to translate SNES opcodes and low-level procedures into more user friendly C instructions. So far it doesn't do much more than rendering VRAM chunks and interpret a few instructions manually disassembled and converted to C code, but in a near (?) future it will be able to do most of this stuff automatically and only ask the user to correct particular parts of the code that simply cannot be converted automatically (i.e. WRAM code, particular jump tables, indirect addressing).
Here's an example of the translated code:
Code: Select all
void GetPlayTime()
{
LDAram(0x21E); //LDA byte_7E021E ; Load frame count
if(a.seg.l==60) goto carry_sec; //CMP.B #060 :: BEQ loc_3143C | If 60, branch to below "carry out" into seconds
goto __overflow; //BRA __overflow | Otherwise, branch directly to overflow checks
carry_sec:
STZ(0x21E); //STZ byte_7E021E
LDAram(0x21D); //LDA byte_7E021D
if(a.seg.l==59) goto carry_min; //CMP.B #059 :: BEQ loc_3144B | If 59, branch to below "carry out" into minutes
INC(0x21D,1); //INC byte_7E021D
goto __overflow; //BRA __overflow
carry_min:
STZ(0x21D); //STZ byte_7E021D | Set seconds to 0
LDAram(0x21C); //LDA byte_7E021C
if(a.seg.l==59) goto carry_hr; //CMP.B #059 :: BEQ loc_3145A | If 59, branch to below "carry out" into hours
INC(0x21C,1); //INC byte_7E021C | Increment minutes
goto __overflow; //BRA __overflow
carry_hr:
STZ(0x21C); //STZ byte_7E021C | Set minutes to 0
LDAram(0x21B); //LDA byte_7E021B
if(a.seg.l==99) goto __overflow; //CMP.B #099 :: BEQ __overflow
INC(0x21B,1); //INC byte_7E021B
__overflow:
LDAram(0x21B); //LDA byte_7E021B
if(a.seg.l!=99) goto frame_inc; //CMP.B #099 :: BNE loc_31478 | If not 99, branch to frame increment; hours haven't overflowed
LDAram(0x21C); //LDA byte_7E021C
if(a.seg.l!=99) goto frame_inc; //CMP.B #059 :: BNE loc_31478 | If not 99, branch to frame increment; minutes haven't overflowed
STZ(0x21D); //STZ byte_7E021D | Set seconds to 0
frame_inc:
INC(0x21E,1); //INC byte_7E021E | Increment frames
TDC; //TDC
//RTL
}

A test of VRAM emulation with the rename screen from Star Ocean. Right is the SNES original, left is the PSX improved version using the same VRAM chunk as a base for rendering.

Testing a field scene from Star Ocean. The debugging information are there just for optimization purpose, since the PlayStation hardware isn't very good for rendering tiled graphics and the whole screen reprocessing can take a long time causing frame skipping in some cases.


A couple newer test screens made with the latest build of Pastrami. The second screen also shows the canvas procedures used to print text on screen, so that it can be impressed to a buffer once and will not need any additional drawing routines, just like it used to be on the SNES.