Friday, December 21, 2012

Ewww, MIPS! (Spectrum emulator)

xpectrum for the SPMP8000


A week or so ago I have ported xpectrum (also known as gp2xpectrum, iXpectrum, Xpectroid, and Aunt Irma [citation needed]) to the SPMP8000 platform. There is no support for ZIP files (if built with zlib all files, even non-compressed ones, fail to load), and the scaling in full-screen mode is done in software, and not very well. Other than that, it works quite nicely, sound and virtual keyboard included. You can download it here, source code is at the usual place.

The A3300 is... different.


I actually wanted to fix the two issues with xpectrum before announcing it here, but I didn't find the time because I've been had. My JXD A3300 has arrived at about the same time I finished the xpectrum port, and when I tried to run the emulator on it, it didn't work! Apparently, the A3300 is not an SPMP8000 device at all, but based on some obscure MIPS controller by "Actions Semiconductor". A little online research indicated that nobody has done any homebrewing on this platform yet. Bummer.

Not so fast!


I was unwilling to write off this purchase, though, so I went ahead and extracted the data from the encrypted firmware update image for the A3300. (Load it into the firmware update tool, attach OllyDbg, find the largest data segment, dump it, remove some superfluous bytes, and you've got yourself an SQLite3 database file.)
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


The Actions Semi OS appears to be based on uC/OS-II. It features a dynamic loader and virtual memory, but nonetheless almost all interfaces are implemented using system calls, even the GUI and libraries like SQLite. There even is a memcpy() syscall, although most applications have the good sense not to use it. On top of that they put something that seems to borrow many conventions and architectural features from Unix/Linux, such as devices as files, the POSIX threads API, or file name endings (".so" for dynamically loaded object and ".ko" for kernel modules), but it is clearly not derived from Linux. It's probably a custom job, either grown in-house at Actions Semi, or contracted from a third party. The latter seems more likely to me because the strings found in the binary files are almost entirely void of Chinglish, very much unlike the SPMP8000 OS.

Running our own code


From what I could tell there is no mechanism similar to the "native game" loading on the SPMP8000 that would allow you to run third-party native applications. There is, however, an update mechanism that checks if there are new emulators on the externally accessible flash partition. To check for updates, the OS tries to load certain files (libp1.so, libg1.so, etc.) with dlopen() and inspects an exported symbol to get a version number. If the number is higher than the one of the installed emulator (or there is no emulator of that type installed yet), it will copy the new file over the existing one on an internal flash partition and use it as an emulator for the corresponding types of files from now on.
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.

Getting comfortable


Of course this is not very convenient: You don't want to copy files around and run the installer every time you want to use a different program. So I wrote another program ("launcher") tailored to the Actions Semi emulator interface that pretends to be an emulator up until the point where the emulator framework tells it what "ROM" it is supposed to play. At that point it opens that file and checks if it is an ELF binary. If it is, it dlopen()s the file and relays all information it has previously received from the emulator framework. At this point, the new binary has hooked itself into the emulator framework and takes over. If the file to be played is not an ELF binary, the same thing happens, with the exception that it's the PlayStation emulator that is loaded. Now we can simply copy our homebrew code to the console and run it from the file browser, provided we give it a PlayStation-ey file extension; .bin seems like the obvious choice.

Doing something useful


What we need now is a substantial demo. Since I had played around with xpectrum anyway, I just went ahead and ported that as the first homebrew program for the Actions Semiconductors platform. It works every bit as well as the SPMP8000 port, except that it's even faster if you disable throttling. Here's how to try it:

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.
  1. Download installer.elf and put it on the internal flash drive as "libp1.so".
  2. Download launcher.elf and put it on the internal flash drive as "new_libp1.so".
  3. Choose the game icon in the main menu to bring up the file browser; this will trigger the installation process.
  4. 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.
  5. 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.)
  6. Put xpectrum in the GAME directory.
Now you should be able to launch xpectrum from the file browser.

The Code


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".

Have fun!

14 comments:

  1. very unexpected and delightful news! I just bought a EGP1000 which is a rebranded jxd 3000. i'm going to see if this works on it.

    ReplyDelete
    Replies
    1. i put those files into the root of my EGP1000 internal memory but it didn't read them. The os on my device looks like the one in dingoo. It looks like the EGP1000 has an entirely different firmware

      Delete
    2. Quite possible. I have something that closely resembles a Kulala K-802 here. It doesn't have the Kulala branding, but other than that it's completely identical, down to to the fake PSP logo. It clearly also runs on the Actions Semi platform (a string in a playlist file told me so), and the UI looks a lot like the JXD 3000, but it doesn't seem to have the same update mechanism.
      (It's also a load of crap, seems the battery is already dead after a couple of days...)

      Delete
    3. Any help to run in a EGP 1000?

      Delete
    4. i tried to install a firmware from another handheld which has the same chip inside(Ko Technology W6000). It didn't work so well, sounds and buttons worked but the screen was black. So i tried another firmware, this time from the w5000. Now nothing works not even the usb. the led still works when i put it on but nothing else. It's now a brick. If you have any idea how I could fix it somehow, please let me know. If I can't sort this out I think i'll buy a GCW zero or a proper jxd handheld next time.

      Delete
    5. How do you install a firmware?

      Anyway without original firmware is not possible restore it.

      Do you contact with eachgame to get original firmware?

      Delete
    6. There is a program named productool specifically made to update mp3 , mp4 and handhelds that use an actions chip. I used a custom made version of it from the ko technology site.

      I cannot connect my EGP1000 to any computer and install old firmware because it's bricked.

      I contacted eachgame a week ago but they haven't responded yet.

      Delete
    7. But the console needs boot into ADFU mode.

      How you put your console in ADFU mode?

      Delete
  2. Hi, Uli! Many thanks for your Spectrum emulator! It's wonderful! I am very happy, my dream has come true! I have two questions. 1. Are you continuing to improve Spectrum emulator? For best compatibility with games. 2. With the purchase of a new A3300 will you do emulators for old SPMP8k? Thank you for being with us there! (I do not know how flawed my English, I hope you understand my point).

    ReplyDelete
    Replies
    1. I will not do anything about the Spectrum emulation itself, that's not my area of interest. I do, however, plan to fix issues related to the ports, such as the display scaling and ZIP file stuff I mentioned before.

      When I port something new I will probably do it for both platforms. But for now, there's some catching up to do on the MIPS front. :) ScummVM with touchscreen still seems like a worthwhile endeavor to me. I don't have all that much spare time, though, so don't hold your breath.

      Delete
  3. Uli, a few questions. 1.) I have the Defender MultiMixMagic (Clone MiShark64 \ LetCool) and has a shifts L and R. But in your programs do not work! And so in the Spectrum emulator I do not have buttons. 2.) For fast scrolling games selection screen games go green artifacts. 3.) Would be very grateful if you add a supported format games Spectrum TRD. It is often spread. This is my firmware (This is my firmware http://www.defender.ru/userfile/drivers/SXB1G-ZI6mmm-firmware-v3.zip). Help your fans, please.

    ReplyDelete
    Replies
    1. Привет!
      У меня тоже МММ, и вот какая проблема:
      эмуль похоже не умеет делать правильно Save state. Создает только файл .tmp 0 кб.
      Прошивка у меня не дефендеровская
      http://emulate-su.livejournal.com/726862.html

      Delete
  4. This post, along with a friend's JXD3000, has afforded me a weekend of pleasant and interesting hacking, so thankyou :-).

    ReplyDelete