maandag 8 mei 2017

Pandora's box 4S game list entries

Now that we know where the game list is, we can try to deduce some things.
Facts:
1. Libnsxsa.so does not contain any driver for 80's game "zerotime".
2. Galaga3 is in the list. as 'xxxxx' for some reason, but who cares.
3. There has to be an emu capable of running "galaga3".
4. There are config files for this game. They appear to be for MAME, in xml format.
5. Candidates for this are libnsxnsa and libnsxnx (nsa is an unknown.. nx=xmame)
6. $GAME can be 3 for libnsxnsa, 4 for libnsxnsap or 5 for libnsxnx
7. There must be some identifying mark(s) in the list, to ensure proper launches of games.
8. The game name and/or coins could somehow be preserved between the switching of emulators.
It is likely that the current running instance of libnsx* writes its emu/game type(s) into /tmp/configfile. Coin data perhaps in /tmp/config/data.so.
We need value 5 for xmame launching.

00601EE8 9B 17 00 00 │ 67 61 6C 61 │ 67 61 33 00 │ 00 00 00 00  ›↨..galaga3.....
00601EF8 00 00 00 00 │ 00 00 00 00 │ 78 78 78 78 │ 78 78 78 78  ........xxxxxxxx
00601F08 78 78 78 78 │ 78 78 00 00 │ 00 00 00 00 │ 00 00 00 00  xxxxxx..........
00601F18 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00  ................
00601F28 78 78 78 78 │ 78 78 78 78 │ 78 78 78 78 │ 78 78 78 78  xxxxxxxxxxxxxxxx
00601F38 78 78 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00  xx..............
00601F48 00 00 00 00 │ 00 00 00 00 │ 00 01 00 00 │ 01 02 03 04  .........☺..☺☻♥♦
00601F58 00 00 00 00 │ 00 00 00 00 │ 58 02 00 00 │ 01 00 00 00  ........X☻..☺...
00601F68 0F 00 00 00 │ 05 00 00 00 │ 9C 17 00 00 │ 71 69 78 00  ☼...♣...œ↨..qix.

Looking at it in an hex editor:
Kind of difficult to see, but there is a numbering scheme: "9B 17"for Galaga3 and 9C 17" for Qix followed by xxxx's for the Chinese and English names of the game. There is an unmistakeable 05 at 0x601F6C.

Let's look at a neo geo game. 601EE8-601F6C = +0x84 hex offset could have some number..

005EE578 EA 03 00 00 │ 6B 6F 66 39 │ 37 00 00 00 │ 00 00 00 00  ê♥..kof97.......
005EE588 00 00 00 00 │ 00 00 00 00 │ E6 8B B3 E7 │ 8E 8B 39 37  ........拳王97
005EE598 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00  ................
005EE5A8 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00  ................
005EE5B8 4B 6F 66 39 │ 37 00 00 00 │ 00 00 00 00 │ 00 00 00 00  Kof97...........
005EE5C8 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00 │ 00 00 00 00  ................
005EE5D8 00 00 00 00 │ 00 00 00 00 │ 00 01 00 00 │ 01 00 00 00  .........☺..☺...
005EE5E8 00 00 00 00 │ 04 00 00 00 │ 68 01 00 00 │ 01 00 00 00  ....♦...h☺..☺...
005EE5F8 00 00 00 00 │ 00 01 00 00 │ EB 03 00 00 │ 6B 6F 66 39  .....☺..ë♥..kof9

Hmm. Could be a '00' value there.

I need to test more when i get the box.
For now, if people want, they can change some roms as well. The Galaga/Galaxian games could be switched with say, Psychic 5, Toki.. and so on. You'll need some roms, use sets for Mame 0.106 as this is the one they use in the box.

zondag 7 mei 2017

So what about libnsxs.so..

Let's dig a bit deeper into libnsxs.so

Without having the box, it's difficult to see what it actually does, and where the symlink in /tmp/libnsxs.so actually points to. But we can deduct it.

Step 1, a look at /usr/emu/runGame
rm -f /tmp/libnsxs.so
cp /tmp/configfile /usr/sd1/configfile.last.$GAME; sync
EMU0=`od -t d -N 1 -j 538 /tmp/configfile |  head -n 1 | awk '{print $2}`
EMU=$(( $EMU0 & 15 ))
In case of pb4s configfile i have on the dump, the value is '0'. which means
if [ $EMU -eq  0 ]; then
ln -sf /lib/$GAME/libnsxas.so    /tmp/libnsxs.so
So we need to look a libnsxas.so.

This is a copy of Final Burn with a menu tacked in front of it. Could be a heavily modded FBA since most ports have some sort of menu, like for example the Xbox 360 version(s).

Game list

Look at 0x005EE4F0 in a hex editor. Or search for "END_OF_THE_LIST"..
It should be possible to inject a new gamelist or at least edit existing entries, once we figure out the format. Perhaps it is similar to the older list.dat from PB3.

How the emu is switched is unclear, it would need to write configfile and exit out to a new instance.
It has to switch. libnsxas.so does not contain drivers for say, galaga or galaxian.

More soon :)

A closer look at Pandora's box 4S

A closer look at these chinese boxes.
For this example i will use a public dump called pb4sfix.img. This one appears to be unencrypted.

The SD card.

Disk pb4sfix.img: 7,2 GiB, 7744782336 bytes, 15126528 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x14e65c89

Device Boot Start End Sectors Size Id Type
pb4sfix.img1 2048 609929 607882 296,8M 83 Linux
pb4sfix.img2 609930 15126527 14516598 6,9G 83 Linux

Quick and dirty mounter script:
mount -o rw,loop,offset=1048576 pb4sfix.img ./test
mount -o rw,loop,offset=312284160 pb4sfix.img ./test2
You can calculate the offset by doing start * 512. (2048*512=1048576 for example.)

Kernel Boot

The first partition holds kernels, configfiles and script.bin. The last one is a parameter file for the A13 platform that the Pandora's run on. Sectors 0-2048 of this SD card are reserved for u-boot. (I have seen a few different Pandora SD cards where the first partition starts later on, but that is beyond the scope of this post.)

At boot, the script inside U-boot you can see here reads the GAME parameter and boots the kernel accordingly. This parameter is possible to change at boot by holding 1p start & 1p shot 1 at boot until a board selection screen appears.
There are several other parameter files
bi = 4 bytes, function unknown
forcevga = 4 bytes, 1 or 0.
game = 4 bytes, pb4s, kzbw, or mame
lang =
xmame.game = may contain a romname for launching. 
For now, let's assume we're booting pb4s

Init

After kernel is loaded, and booting, the second partition will be mounted as root filesystem (/dev/mmcblk02). It is a basic Busybox system. Then /etc/init.d/rcS is parsed.
mount -t vfat /dev/mmcblk0p1 /usr/sd1
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
export QWS_DISPLAY=LinuxFb:/dev/fb0
export QTDIR=/root/real210/qt3
/usr/emu/runGame &
Nothing special. Let's see about runGame. this is a big beast of a file. So i only include the parts relevant for $GAME=pb4s at this point.
  # main loop
  while true;
  do
          rm -f /tmp/libnsxs.so
      cp /tmp/configfile /usr/sd1/configfile.last.$GAME; sync
        EMU0=`od -t d -N 1 -j 538 /tmp/configfile |  head -n 1 | awk '{print $2}`
        EMU=$(( $EMU0 & 15 ))
        #switch game emulator
        if [ $EMU -eq  0 ]; then
                ln -sf /lib/$GAME/libnsxas.so    /tmp/libnsxs.so
        elif [ $EMU -eq  1 ]; then
          ln -sf /lib/$GAME/libnsxcs.so    /tmp/libnsxs.so
        elif [ $EMU -eq  2 ]; then
          ln -sf /lib/$GAME/libnsxns.so    /tmp/libnsxs.so
        elif [ $EMU -eq  3 ]; then
          ln -sf /lib/$GAME/libnsxnsa.so   /tmp/libnsxs.so
        elif [ $EMU -eq  4 ]; then
          ln -sf /lib/$GAME/libnsxnsap.so  /tmp/libnsxs.so
        elif [ $EMU -eq  5 ]; then
          ln -sf /lib/$GAME/libnsxnx.so  /tmp/libnsxs.so
        else
                ln -sf /lib/$GAME/libnsxas.so    /tmp/libnsxs.so
        fi
      if [ "`cat /lib/pb4s/home `" -eq "1" ]; then
        if [ $EMU -eq  5 ]; then
          (cd /tmp && ./libnsxs.so btime )
        else
              if [ $MODE -eq 0 ];  then
          ( cd /tmp  && ./libnsxs.so -qws 52 800 600 )
              else
          ( cd /tmp  && ./libnsxs.so -qws 52 384 224)
              fi
        fi
      else
        if [ $EMU -eq  5 ]; then
          (cd /tmp && ./libnsxs.so tankfrce )
        else
              if [ $MODE -eq 0 ];  then
          ( cd /tmp  && ./libnsxs.so -qws 54 800 600 )
              else
          ( cd /tmp  && ./libnsxs.so -qws 54 384 224)
              fi
        fi
     fi
  done
}
There are some interresting things before we get to this point that i skipped over. The binary /usr/emu/gameselectmenu is called, (with -m $MODE), and also the binary /usr/emu/testHD.
The gameselectmenu allows switching between pandora/xmame/pb4s mode. The testHD binary is likely for HDMI implementation. A HDMI version of PB4S exists, built into a control panel for direct use on a HDTV

Of more interest is the file '/usr/emu/getkey3m' which runs as part of the init.
Earlier versions of Pandora used a 'jamma.ko' loadable kernel object, and getkey seems to use gpio to get input keys, or perhaps transfer coins or something. It reads/writes to /usr/sd1/bi , /dev/mem, /dev/i2c-0 and /dev/ttyS1. The exact use of this is unclear, as i don't have the box yet :)

With all that out of the way, we are on our way to /tmp/libnsxs.so.. Or whatever is linked symbolically at that point. See you next post!


vrijdag 10 juli 2009

Here we go

Thttpd + php5 on mips

My sourcery install went into /opt/Sourcery_G++ Lite/
I'm using /usr/local/mips as target dir for my bins/libs/whatever.

Needed: zlib-1.2.3, thttpd-2.21b, php5 (read below..)

Zlib:

I started with zlib-1.2.3, which was fairly easy. It throws an error in the end that you'll need to add to the ' maker.sh' in order to create the final product :)

I prefer a per-program sh script i call 'maker.sh' that contains all exports and commands needed to compile the final thing. Below is maker.sh for zlib:
export CFLAGS="-EL "
export CC="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-gcc"
export CXX="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-g++"
export PATH=/opt/Sourcery_G++_Lite/bin:$PATH
export RANLIB="/opt/Sourcery_G++_Lite//bin/mips-linux-gnu-ranlib"
export AR="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ar"
export AS="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-as"
export LD="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ld"
export STRIP=/opt/Sourcery_G++_Lite/mips-linux-gnu/bin/strip
CFLAGS="-EL " ./configure --prefix=/usr/local/mips
Make will spit out some errors:
/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ar libz.a adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ar: illegal option -- z
..
..
..
make: *** [libz.a] Error 1

Lucky for us, the entire command is on the screen with the missing part plainly (in)visible... We'll just ar that manually thank you:

/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ar rc libz.a adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o

Then make install, and zlib goes into /usr/local/mips.

thttpd:

At first i thought: We need to configure it first, then configure php5 --with-thttpd so that it modifies the makefile/makefile.in for us.. But that's not how it works.. read on..

Php5

This was a pain in the ass. I took the latest php (5.3.0 at time of writing) and struggled with it to get it to a stage where it fails with :
main/php_ini.o: In function `php_load_php_extension_cb':
php_ini.c:(.text+0x1154): undefined reference to `php_load_extension'
php_ini.c:(.text+0x1158): undefined reference to `php_load_extension'

And it's also spitting out lots of "cc1: warning: include location "/usr/include" is unsafe for cross-compilation" warnings..

After a while i went back to version 5.2.10 and that compiles fine. Here's maker.sh:
export CFLAGS="-EL "
export CC="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-gcc"
export CXX="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-g++"
export PATH=/opt/Sourcery_G++_Lite/bin:$PATH
export RANLIB="/opt/Sourcery_G++_Lite//bin/mips-linux-gnu-ranlib"
export AR="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ar"
export AS="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-as"
export LD="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-ld"
export STRIP=/opt/Sourcery_G++_Lite/mips-linux-gnu/bin/strip
./configure --disable-shared --prefix=/usr/local/mips --target=mips-linux-gnu --with-ssl=/usr/local/mips --with-z
lib=/usr/local/mips --with-libxml-dir=/usr/local/mips --with-openssl=/usr/local/mips --with-thttpd=../thttpd-2.21
b --without-pear
make
make install
It still gives me those warnings about unsafe for cross-compilation, but seems to work.. You need to make install for it to patch thttpd makefile. Still didn't like the warnings though.. read on..

Back to thttpd..

With our makefile patched, we can now build it. But.. failure!
libhttpd.c:655:40: error: ext/standard/php_smart_str.h: No such file or directory

So, i copied the whole ext folder into the thttpd-2.21b folder and tried again. This time it went a bit further.
libhttpd.o: In function `httpd_complete_request':
libhttpd.c:(.text+0x58a0): undefined reference to `thttpd_closed_conn'
libhttpd.c:(.text+0x58a4): undefined reference to `thttpd_closed_conn'

Make clean and make also did not work. Configuring again also not.. I ran out of options, but google told me the order was supposed to be:

1. Extract thttpd
2. Configure, make, and make-install php
3. Compile thttpd..

Which in turn gave me another bunch of errors i've never seen before :)
/tmp/cckR8fMf.s: Assembler messages:
/tmp/cckR8fMf.s:681: Error: unrecognized opcode `rorw $8,$20'
/tmp/cckR8fMf.s:681: Error: unrecognized opcode `rorl $16,$20'
/tmp/cckR8fMf.s:681: Error: unrecognized opcode `rorw $8,$20'
make: *** [libhttpd.o] Error 1

I then googled some more, modified my little maker script after seeing better examples of --host and --target options, and started fresh with a clean thttp and php5 source..
export CFLAGS="-EL "
export CC="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-gcc"
export CXX="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-g++"
./configure --host=i386-linux-gnu --target=mips --prefix=/usr/local/mips --disable-short-tags --without-mysql --without-pear --disable-all --disable-short-tags --with-thttpd=../thttpd-2.21b

And i modifed maker.sh for thttpd as well:
export CFLAGS="-EL "
export CC="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-gcc -EL"
export CXX="/opt/Sourcery_G++_Lite/bin/mips-linux-gnu-g++"
CFLAGS="-EL" ./configure --host=i386-linux-gnu --target=mips --prefix=/usr/local/mips --with-zlib=/usr/local/mips
make

And that works as expected! No errors, just a warning about tmpnam:
htpasswd.o: In function `main':
htpasswd.c:(.text+0x4a0): warning: the use of `tmpnam' is dangerous, better use `mkstemp'
make[1]: Leaving directory `/home/target/build/thttpd-2.21b/extras'
Now i had my very own thttpd+php5 to run on my mips board!
Offcourse, it's time to revisit php 5.3.0 now and check how that goes..
And, --disable-all is a bit crude for php.. we'll probably need some extra stuff later on, but at least we've got a working compiled thttpd :)
(update: 5.3.1 is still a no-go :( it compiles error-less untill the end, and gives the same error as before..)

Enabling more stuff in php

since we have them, we might as well use them. Add the following to the php configure-command, (after extracting a nice clean thttpd again):
--with-libxml-dir=/usr/local/mips --with-openssl-dir=/usr/local/mips --with-zlib-dir=/usr/local/mips

Thttpd again
Seems make-install somehow stops working if you use the php stuff.
After configuring you can just edit ./Makefile and change the prefix to whatever you need, and run make-install..

# Top level hierarchy.
prefix = /usr/local/mips
exec_prefix = ${prefix}
# Pathname of directory to install the binary.
BINDIR = ${exec_prefix}/sbin
# Pathname of directory to install the man page.
MANDIR = ${prefix}/man
# Pathname of directory to install the CGI programs.
WEBDIR = $(prefix)/www
Voila! Thttpd+php5 cross-compiled :) Hope it's of use to someone!

Labels: , , ,

Adventures in cross compiling

Finally got my cross environment set up. I'm using VMware, ubuntu and Sourcery G++ Lite 4.3-51 for MIPS GNU/Linux to get some mips stuff running on a dev board..

Labels: ,