• Steam recently changed the default privacy settings for all users. This may impact tracking. Ensure your profile has the correct settings by following the guide on our forums.

PSX problem plz help

dragon_boi

New Member
Well I upgraded my psp to version 3.71 M33-2 and now psx games don't work. It will show that screen saying read the manual and stuff then it will just go to a black screen and nothing happens it just stays a black screen. I can press home and the normal menu shows up.
 

dragon_boi

New Member
Oh well its a phat and i got the 1.50 kernel addon version 2. Well I tried someone elses eboot for a game and it worked so it must be my conversions. Mine were working before and i tried 3 different programs to convert them but they still don't work. Can someone tell me which program i should use? or link me to a guide to one.
 

x3sphere

Administrator
Staff member
Enforcer Team
Game Info Editor
Oh well its a phat and i got the 1.50 kernel addon version 2. Well I tried someone elses eboot for a game and it worked so it must be my conversions. Mine were working before and i tried 3 different programs to convert them but they still don't work. Can someone tell me which program i should use? or link me to a guide to one.

Try using PSX2PSP:

http://exophase.com/files/download.php?id=91
 

dragon_boi

New Member
Thanx I found the problem it was my isos. I tried ripping them with a different program and they work fine now.
 

Cheezeball99

But I was committed after that birthday party...
I rip mine in linux using a combo of READCD and CDRDAO.

Well that's because you're hardcore, CW. You're the most hardcore person on this board. +Rep for hardcore!

Oh, and sidenote, I suppose I'll pitch in, I use the free version of Isobuster, works like a charm for me every time.
 

MenaceInc

Staff Member
Well that's because you're hardcore, CW. You're the most hardcore person on this board. +Rep for hardcore!

Oh, and sidenote, I suppose I'll pitch in, I use the free version of Isobuster, works like a charm for me every time.

yea,i always used a combo of Isobuster and PSX2PSP when i was on windows....

havent tried on ubuntu linux though.. :\
 

Chilly Willy

Contributor
Well that's because you're hardcore, CW. You're the most hardcore person on this board. +Rep for hardcore!

Oh, and sidenote, I suppose I'll pitch in, I use the free version of Isobuster, works like a charm for me every time.

Can I get another +Rep for writing the python script I use to rip the disks and make the EBOOT files? :biggrin: 8)

popsx.py
Code:
#!/usr/bin/env python

#***************************************************************************
#*                                                                         *
#*         PopSX - convert a PSX CD to a POPStation EBOOT.PBP              *
#*                                                                         *
#*   by Chilly Willy, based on code by Dark_AleX, Tinnus, and Rck          *
#*                                                                         *
#***************************************************************************

#***************************************************************************
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU General Public License as published by  *
#*   the Free Software Foundation; either version 2 of the License, or     *
#*   (at your option) any later version.                                   *
#*                                                                         *
#***************************************************************************


import sys
import os
import string
import array
import struct
import zlib


# binary helper functions

def get_byte(buffer, offset):
    "get the byte at offset in the buffer"
    return struct.unpack("B", buffer[offset])[0]

def get_word_le(buffer, offset):
    "get the word at offset in the buffer"
    return struct.unpack("<H", buffer[offset:offset+2])[0]

def get_long_le(buffer, offset):
    "get the longword at offset in the buffer"
    return struct.unpack("<I", buffer[offset:offset+4])[0]

def put_byte(val):
    "return a string with the byte passed in"
    return struct.pack("B", val)

def put_word_le(val):
    "return a string with the word passed in"
    return struct.pack("<H", val)

def put_long_le(val):
    "return a string with the longword passed in"
    return struct.pack("<I", val)


# format helper functions

def maybebcd(n):
    "return the BCD equivalent of the hex number passed in if < 0xA0"
    if n < 0xA0:
        return ((n / 10) << 4) | (n % 10)
    else:
        return n

def hex2bcd(n):
    "return the BCD equivalent of the hex number passed in"
    return ((n / 10) << 4) | (n % 10)


# convert toc.dat from readcd into PSX format

def get_toc():
    "read TOC via readcd, return string with PSX TOC"
    # try to run readcd
    print 'Attempting to read TOC from CDROM -'
    print
    try:
        os.spawnlp(os.P_WAIT, 'readcd', 'readcd', 'dev=/dev/cdrom', '-fulltoc')
    except:
        print 'Could not run readcd'

    print
    # try to read toc.dat
    try:
        toc_file = open('toc.dat', 'rb')
    except:
        print 'Could not open toc.dat'
        return ''
    toc_data = toc_file.read()
    toc_file.close()
    toc_size = len(toc_data)

    # find the start of the first session
    toc_start = 0
    while toc_start < len(toc_data):
        if get_byte(toc_data, toc_start) == 0xA0:
            break
        else:
            toc_start += 1
    if toc_start == len(toc_data):
        print 'toc.dat has invalid data'
        return ''
    toc_start -= 3
    print 'Found TOC start at offset', toc_start

    toc_entries = (len(toc_data) - toc_start) / 11
    print 'This disc has', toc_entries, 'entries'
    toc_list = []   # PSX TOC list starts empty
    # convert from normal TOC format to PSX TOC format
    for entry in range(toc_entries):
        # ctrl:adr field
        toc_list.append((get_byte(toc_data, toc_start+entry*11) & 15) | ((get_byte(toc_data, toc_start+entry*11+1) & 15) << 4))
        #reserved
        toc_list.append(get_byte(toc_data, toc_start+entry*11+2))
        # point
        toc_list.append(maybebcd(get_byte(toc_data, toc_start+entry*11+3)))
        # amin, asec, afrm
        if entry < 3:
            toc_list.append(hex2bcd(get_byte(toc_data, toc_start+entry*11+4)))
            toc_list.append(hex2bcd(get_byte(toc_data, toc_start+entry*11+5)))
            toc_list.append(hex2bcd(get_byte(toc_data, toc_start+entry*11+6)))
        else:
            amin = get_byte(toc_data, toc_start+entry*11+8)
            asec = get_byte(toc_data, toc_start+entry*11+9)
            afrm = get_byte(toc_data, toc_start+entry*11+10)
            if entry == 3:
                afrm += 1
            else:
                asec -= 2
                if asec < 0:
                    amin -= 1
                    asec += 60
            toc_list.append(hex2bcd(amin))
            toc_list.append(hex2bcd(asec))
            toc_list.append(hex2bcd(afrm))
        # reserved
        toc_list.append(get_byte(toc_data, toc_start+entry*11+7))
        # pmin, psec, pfrm
        pmin = get_byte(toc_data, toc_start+entry*11+8)
        psec = get_byte(toc_data, toc_start+entry*11+9)
        pfrm = get_byte(toc_data, toc_start+entry*11+10)
        if entry == 0:
            toc_list.append(hex2bcd(pmin))
            toc_list.append(psec)
            toc_list.append(hex2bcd(pfrm))
        elif entry < 4:
            toc_list.append(hex2bcd(pmin))
            toc_list.append(hex2bcd(psec))
            toc_list.append(hex2bcd(pfrm))
        else:
            psec -= 2
            if psec < 0:
                pmin -= 1
                psec += 60
            toc_list.append(hex2bcd(pmin))
            toc_list.append(hex2bcd(psec))
            toc_list.append(hex2bcd(pfrm))

    return struct.pack(repr(toc_entries * 10) + 'B', *toc_list)


# get file size

def get_file_size(infile):
    infile.seek(0, 2)   # seek to the end
    size = infile.tell()
    infile.seek(0)      # seek to the beginning
    return size


# check game code

def check_code(code):
    "check if the code passed in is valid, if not pass a replacement"
    codes = set(['SCUS','SLUS','SLES','SCES','SCED','SLPS','SLPM','SCPS','SLED','SIPS','ESPM','PBPX'])
    if code[0 : 4] in codes:
        return code[0 : 9]
    return 'PBPX12345'


# get extra data files from the current directory or from BASE.PBP

def get_sfo(base_data):
    "get SFO from BASE.PBP"
    sfo = base_data[get_long_le(base_data, 0x08) : get_long_le(base_data, 0x0C)]
    # set TITLE and DISC_ID in SFO
    title = sys.argv[1]
    if len(title) > 127:
        title = title[0 : 127]  # trim title to 127 characters
    disc_id = check_code(sys.argv[2])
    fields_table_offs = get_long_le(sfo, 0x08)
    values_table_offs = get_long_le(sfo, 0x0C)
    num_items = get_long_le(sfo, 0x10)
    for i in range(num_items):
        item_type = get_byte(sfo, i * 0x10 + 0x17)
        if item_type != 2:
            continue    # not a string, skip
        field_offs = get_word_le(sfo, i * 0x10 + 0x14)
        item = ''
        while get_byte(sfo, fields_table_offs + field_offs) != 0:
            item += sfo[ fields_table_offs + field_offs ]
            field_offs += 1
        if item == 'TITLE':
            length = get_long_le(sfo, i * 0x10 + 0x18)
            size = get_long_le(sfo, i * 0x10 + 0x1C)
            val_offs = get_word_le(sfo, i * 0x10 + 0x20)
            val_start = values_table_offs + val_offs
            val_end = val_start + len(title) + 1
            sfo = sfo[: i * 0x10 + 0x18] + \
                put_long_le(len(title) + 1) + \
                sfo[i * 0x10 + 0x1C : val_start] + \
                title + put_byte(0) + \
                sfo[val_end :]
        if item == 'DISC_ID':
            length = get_long_le(sfo, i * 0x10 + 0x18)
            size = get_long_le(sfo, i * 0x10 + 0x1C)
            val_offs = get_word_le(sfo, i * 0x10 + 0x20)
            val_start = values_table_offs + val_offs
            val_end = val_start + len(disc_id) + 1
            sfo = sfo[: i * 0x10 + 0x18] + \
                put_long_le(len(disc_id) + 1) + \
                sfo[i * 0x10 + 0x1C : val_start] + \
                disc_id + put_byte(0) + \
                sfo[val_end :]
    return sfo


def get_icon0(base_data):
    "get ICON0.PNG from file, or BASE.PBP if no file"
    try:
        icon0_file = open('ICON0.PNG', 'rb')
        icon0_data = icon0_file.read()
        icon0_file.close()
        return icon0_data
    except:
        return base_data[get_long_le(base_data, 0x0C) : get_long_le(base_data, 0x10)]


def get_icon1(base_data):
    "get ICON1.PMF from file, or BASE.PBP if no file"
    try:
        icon1_file = open('ICON1.PMF', 'rb')
        icon1_data = icon1_file.read()
        icon1_file.close()
        return icon1_data
    except:
        return base_data[get_long_le(base_data, 0x10) : get_long_le(base_data, 0x14)]


def get_pic0(base_data):
    "get PIC0.PNG from file, or BASE.PBP if no file"
    try:
        pic0_file = open('PIC0.PNG', 'rb')
        pic0_data = pic0_file.read()
        pic0_file.close()
        return pic0_data
    except:
        return base_data[get_long_le(base_data, 0x14) : get_long_le(base_data, 0x18)]


def get_pic1(base_data):
    "get PIC1.PNG from file, or BASE.PBP if no file"
    try:
        pic1_file = open('PIC1.PNG', 'rb')
        pic1_data = pic1_file.read()
        pic1_file.close()
        return pic1_data
    except:
        return base_data[get_long_le(base_data, 0x18) : get_long_le(base_data, 0x1C)]


def get_snd0(base_data):
    "get SND0.AT3 from file, or BASE.PBP if no file"
    try:
        snd0_file = open('SND0.AT3', 'rb')
        snd0_data = snd0_file.read()
        snd0_file.close()
        return snd0_data
    except:
        return base_data[get_long_le(base_data, 0x1C) : get_long_le(base_data, 0x20)]


def get_boot():
    "get BOOT.PNG from file"
    try:
        boot_file = open('BOOT.PNG', 'rb')
        boot_data = boot_file.read()
        boot_file.close()
        return boot_data
    except:
        return ''


# M:S:F helper function

def get_msf(loc):
    "return tuple of minutes : seconds : frames given location on CD"
    frames = int(loc / 2352)        # 2353 bytes per frame (sector) in raw/XA mode
    seconds = int(frames / 75)      # 75 frames per second
    minutes = int(seconds / 60)     # 60 seconds in a minute
    seconds -= (minutes * 60)
    frames -= ((minutes * 60 + seconds) * 75)
    return minutes, seconds, frames


#**** main entry point ****

print 'popsx v1.0'
print

# try to run cdrdao
print 'Attempting to read CDROM data -'
print
# 0 = skip dump, 1 = dump CD (debug thingy)
if 1:
    try:
        os.spawnlp(os.P_WAIT, 'cdrdao', 'cdrdao', 'read-cd', '--read-raw', '--datafile', 'temp.bin', \
            '--device', '/dev/cdrom', '--driver', 'generic-mmc:0x00020000', 'temp.toc')
    except:
        print 'Could not run cdrdao'
else:
    print 'Skipped CD dumping'
print


in_file = open('temp.bin', 'rb')
isosize = isorealsize = get_file_size(in_file)
# 1 block = 16 sectors (16 * 2352 = 0x9300), round ISO size to block boundary
if (isosize % 0x9300) != 0:
    isosize += (0x9300 - (isosize % 0x9300))
#print isorealsize, isosize
print


# try to get the TOC
psx_toc = get_toc()
#psx_toc = ''    # test fake TOC
if len(psx_toc) == 0:
    # whoops! no TOC... better make a fake one
    print 'Making fake TOC...'
    pmin, psec, pfrm = get_msf(isorealsize + 2 * 75 * 2352)
    pmin = hex2bcd(pmin)
    psec = hex2bcd(psec)
    pfrm = hex2bcd(pfrm)
    psx_toc = struct.pack("BBBBBBBBBB", 0x41,0,0xA0,0,0,0,0,1,0x20,0)   # 1st track = 1, XA
    psx_toc += struct.pack("BBBBBBBBBB", 0x41,0,0xA1,0,0,0,0,1,0,0)     # last track = 1
    psx_toc += struct.pack("BBBBBBBBBB", 0x01,0,0xA2,0,0,0,0,pmin,psec,pfrm)    # lead-out
    psx_toc += struct.pack("BBBBBBBBBB", 0x41,0,1,0,2,1,0,0,2,0)        # 1st track start
else:
    print 'Actual TOC being used'

for i in range(len(psx_toc)):
    if i % 10 == 0:
        print
    if get_byte(psx_toc, i) < 16:
        print '0%X ' % get_byte(psx_toc, i),
    else:
        print '%X ' % get_byte(psx_toc, i),
print
print

# try to read BASE.PBP
try:
    base_file = open('BASE.PBP', 'rb')
except:
    print 'Could not open BASE.PBP'
    sys.exit()
base_data = base_file.read()
base_file.close()
base_size = len(base_data)

# get SFO data
sfo = get_sfo(base_data)
# get ICON0.PNG data
icon0 = get_icon0(base_data)
# get ICON1.PMF data
icon1 = get_icon1(base_data)
# get PIC0.PNG data
pic0 = get_pic0(base_data)
# get PIC1.PNG data
pic1 = get_pic1(base_data)
# get SND0.AT3 data
snd0 = get_snd0(base_data)


# construct the header
header = put_long_le(0x50425000)
header += put_long_le(0x00010000)
curroffs = 0x28
header += put_long_le(curroffs)     # offset to sfo
curroffs += len(sfo)
header += put_long_le(curroffs)     # offset to ICON0.PNG
curroffs += len(icon0)
header += put_long_le(curroffs)     # offset to ICON1.PMF
curroffs += len(icon1)
header += put_long_le(curroffs)     # offset to PIC0.PNG
curroffs += len(pic0)
header += put_long_le(curroffs)     # offset to PIC1.PNG
curroffs += len(pic1)
header += put_long_le(curroffs)     # offset to SND0.AT3
curroffs += len(snd0)
header += put_long_le(curroffs)     # offset to PSP header

psp_hdr_offs = get_long_le(base_data, 0x20)
prx_size = get_long_le(base_data, psp_hdr_offs + 0x2C)

xoffs = curroffs + prx_size
if (xoffs % 0x00010000) != 0:
    xoffs += (0x00010000 - (xoffs % 0x00010000))    # round xoffs to next 0x00010000 boundary

header += put_long_le(xoffs)        # offset to ISO header


# open output file and write header
out_file = open('EBOOT.PBP', 'wb')
print 'Writing header...'
out_file.write(header)


# now write the SFO
print 'Writing SFO...'
out_file.write(sfo)


# now write ICON0.PNG
print 'Writing ICON0.PNG...'
out_file.write(icon0)


# now write ICON1.PMF
print 'Writing ICON1.PMF...'
out_file.write(icon1)


# now write PIC0.PNG
print 'Writing PIC0.PNG...'
out_file.write(pic0)


# now write PIC1.PNG
print 'Writing PIC1.PNG...'
out_file.write(pic1)


# now write SND0.AT3
print 'Writing SND0.AT3...'
out_file.write(snd0)


# now write DATA.PSP
data_psp = base_data[psp_hdr_offs : psp_hdr_offs + prx_size]
print 'Writing DATA.PSP...'
out_file.write(data_psp)

# now pad to next 0x00010000 boundary
#print 'Padding to next 0x00010000 boundary...'
for i in range(xoffs - curroffs - prx_size):
    out_file.write(put_byte(0))

iso_offs = out_file.tell()      # remember where this is


# now write the ISO header
print 'Writing ISO header...'
out_file.write('PSISOIMG0000')

p1offs = out_file.tell()        # pointer to special data at end of ISO

out_file.write(put_long_le(isosize + 0x00100000))
# pad to 0x100 longs
for i in range(0xFC):
    out_file.write(put_long_le(0))


# now write the game code
disc_id = check_code(sys.argv[2])
game_code = '_' + disc_id[: 4] + '_' + disc_id[4 :]
out_file.write(game_code)

# pad out to TOC
for i in range(0x3F5):
    out_file.write(put_byte(0))


# now write the TOC
print 'Writing TOC...'
out_file.write(psx_toc)


# misc until reach title
cnt = iso_offs + 0x0BFE - out_file.tell()
# pad to next data
for i in range(cnt):
    out_file.write(put_byte(0))
out_file.write(put_byte(0x10))

cnt = iso_offs + 0x1220 - out_file.tell()
# pad to next data
for i in range(cnt):
    out_file.write(put_byte(0))

p2offs = out_file.tell()

out_file.write(put_long_le(isosize + 0x00100000 + 0x2D31))
out_file.write(put_long_le(0))
out_file.write(put_long_le(0x7FF))


# now write the title
title = sys.argv[1]
if len(title) > 127:
    title = title[0 : 127]  # trim title to 127 characters
out_file.write(title)
out_file.write(put_byte(0))

cnt = iso_offs + 0x12AC - out_file.tell()
# pad to next data
for i in range(cnt):
    out_file.write(put_byte(0))

out_file.write(put_long_le(3))

cnt = (iso_offs + 0x4000 - out_file.tell()) / 4
# pad to next data
for i in range(cnt):
    out_file.write(put_long_le(0))


# now write dummy index table
index_offset = out_file.tell()
print 'Writing dummy indexes...'
for i in range(isosize / 0x9300):
    # write an IsoIndex for each block in the ISO
    out_file.write(put_long_le(0))  # offset
    out_file.write(put_long_le(0))  # length
    out_file.write(put_long_le(0))  # dummy[6]
    out_file.write(put_long_le(0))
    out_file.write(put_long_le(0))
    out_file.write(put_long_le(0))
    out_file.write(put_long_le(0))
    out_file.write(put_long_le(0))


# pad to next 1M boundary from ISO header
cnt = iso_offs + 0x00100000 - out_file.tell()
for i in range(cnt):
    out_file.write(put_byte(0))


# now write ISO data, building index table as go
comp_lvl = int(sys.argv[3])
if comp_lvl > 9:
    comp_lvl = 9
print 'Compression level =', comp_lvl
offset = 0
indicies = []
print 'Writing ISO...'
for i in range(isosize / 0x9300):
    # do a block of 16 sectors at a time
    iso_block = in_file.read(0x9300)
    # check if last block needs padding
    if len(iso_block) < 0x9300:
        # last block, pad to 0x9300
        cnt = 0x9300 - len(iso_block)
        for j in range(cnt):
            iso_block += put_byte(0)
    # check if we are compressing
    if comp_lvl != 0:
        # compress the block
        try:
            comp_block = zlib.compress(iso_block, comp_lvl)
        except:
            # if an error occurs, just use the uncompressed data
            comp_block = iso_block
        if len(comp_block) < len(iso_block):
            iso_block = comp_block  # only use compressed data if smaller
    indicies.append(offset)
    indicies.append(len(iso_block))
    indicies.append(0)
    indicies.append(0)
    indicies.append(0)
    indicies.append(0)
    indicies.append(0)
    indicies.append(0)
    #print 'Block', i, 'is', len(iso_block), 'long'
    out_file.write(iso_block)
    offset += len(iso_block)


# pad to next 16 byte boundary
offset = out_file.tell()
if offset % 0x10 != 0:
    cnt = 0x10 - (offset % 0x10)
    for i in range(cnt):
        out_file.write(put_byte(0))

end_offset = out_file.tell()


# now write the index table
print 'Writing actual indexes...'
out_file.seek(index_offset, 0)
out_file.write(struct.pack('<' + repr(isosize / 0x9300 * 8) + 'I', *indicies))

out_file.seek(p1offs, 0)
out_file.write(put_long_le(end_offset - iso_offs))
end_offset += 0x2D31
out_file.seek(p2offs, 0)
out_file.write(put_long_le(end_offset - iso_offs))


# now write the special data
offset = get_long_le(base_data, 0x24) + 12
offset = get_long_le(base_data, offset) + 0x50000
data_buf = base_data[offset : offset + 8]
if data_buf != 'STARTDAT':
    print 'Cannot find STARTDAT in BASE.PBP'
    print 'Not a valid PSX eboot.pbp'
    sys.exit()
out_file.seek(0, 2)     # go to end of file
# get BOOT.PNG
boot_pic = get_boot()
if len(boot_pic) == 0:
    # no BOOT.PNG found
    print 'Writing special data...'
    out_file.write(base_data[offset :])
else:
    # offset + 0x10 has size of header data = offset to boot png
    # offset + 0x14 has size of boot png = offset to rest of data
    seg1_offs = offset                                           # has header data
    seg2_offs = seg1_offs + get_long_le(base_data, offset + 0x10) # has boot.png data
    seg3_offs = seg2_offs + get_long_le(base_data, offset + 0x14) # has all the rest
    # write segment 1 (header data)
    out_file.write(base_data[seg1_offs : seg1_offs + 0x14])
    out_file.write(put_long_le(len(boot_pic)))
    out_file.write(base_data[seg1_offs + 0x18 : seg2_offs])
    # write segment 2 (boot.png)
    print 'Writing BOOT.PNG...'
    out_file.write(boot_pic)
    # write segment 3 (everything else)
    print 'Writing special data...'
    out_file.write(base_data[seg3_offs :])


in_file.close()
out_file.close()
print
print 'All done! EBOOT.PBP has your PSX game ready for POPStation.'
print
 

icedman204

New Member
wow thats one big script...

Anyways, it's good to hear that PSx games work on a PSP Phat with the 1.5v2 add on for the 3.71 M33-2. I guess the people that didn't have it working had pretty bad PSx iso Rip's that worked on the previous versions....
 
Top