xpectrum for the SPMP8000
The A3300 is... different.
Not so fast!
As it turned out, this system is a very, very different beast, but in many ways every bit as crappy as the good old SPMP8000/eCos platform.
The Actions Semiconductor OS
Running our own code
The neat thing here is that dlopen() automatically runs the code in the .init section of the binary, so I wrote a little program ("installer") that resides entirely in the .init section, and if you put a file called new_libp1.so on the external flash, it will copy that file over the internal PS1 emulator, before any version numbers are being checked. Now all we need is a MIPS ELF binary that conforms to a few simple standards, and we can run your own code on this "closed" platform by choosing any file that is configured to be run by the PS1 emulator in the file browser.
Doing something useful
WARNING: This is alpha-quality code, use it at your own risk. It is unlikely to cause any serious damage to your system, but I am not making any promises. It may also work on devices like the JXD 3000, 5000, and M1000, but it has only been tested on my JXD A3300.
- Download installer.elf and put it on the internal flash drive as "libp1.so".
- Download launcher.elf and put it on the internal flash drive as "new_libp1.so".
- Choose the game icon in the main menu to bring up the file browser; this will trigger the installation process.
- Connect the console to your computer. What you should see is that the file new_libp1.so has been deleted, and the file backup_libp1.so (and possibly backup_libp1+.so) have been created.
- Download real_libps1.so and put it on the internal flash drive. This is the PS1 emulator that will be used from now on. (You could use the backup files created previously instead, but the emulator has to be a specific version (R1.06), so it' s better to use the downloaded one.)
- Put xpectrum in the GAME directory.
Now you should be able to launch xpectrum from the file browser.
The following components are available for your enjoyment from the actsemi github repository:
- libactsemi: A support library that provides access to the system call interface, which includes most standard C library functions and a lot of other things, from everyday stuff like semaphores and threads to a complete GUI interface, property lists, and text encoding functions, although many of them still lack prototypes and data type definitions.
- Baselibc: A customized version of the small C library Baselibc that provides the stuff that the operating system doesn't, such as string functions. I chose it over newlib because the Actions Semi OS already provides a rather high-level interface through system calls, and it's not easy to make newlib cooperate with another C library.
- installer: The binary injection program that replaces the PS1 emulator with our own code.
- launcher: A replacement for the PS1 emulator to be installed by launcher that is able to launch both native ELF binaries and a PS1 game images.
- demo: A simple moving-bar demo that also emits a lot of random debug output. I use it to test OS features.
The xpectrum code can be found in the actsemi branch of the SPMP8000 git repo.
To build all this goodness, you need a MIPS32 cross-toolchain. I built mine using crosstool-ng and this configuration file. Unfortunately, crosstool-ng doesn't pass the target CFLAGS that you set in the config file correctly when building newlib. While we don't use the newlib libc.a, this will still cause us grief when linking with the newlib math library. I worked around this by building newlib manually with CFLAGS_FOR_TARGET="-march=mips32r2 -G0 -Os".