HyperBrew

The Mattel HyperScan is a video game console made by Mattel, and designed by semilogic. Functional toolchains have been found and built, and a lot of information vital to the reverse engineering of the HyperScan has been found.
System
The Mattel Hyperscan was released by Mattel in 2006 and had a very short run before being discontinued and taken off store shelves. The system included some interesting hardware, most of which is actually part of the core chipset but not utilized in the HyperScan system itself. The utilized hardware (or at least openly included hardware) consists of a RFID reader-writer, a CD-ROM drive, USB 1.1, LEDs, a controller with analog joystick, 16 MB of RAM, and video and sound output to TV from a built-in composite cable. Some internal but not openly utilized things are stuff like UART, SD Card interface, and some others.
SoC (system on a chip)
The main processor in the HyperScan is an SPG290A, it is called a "system on a chip". What this means is that the chip itself actually holds some core hardware internally on the chip die, things like video, sound, UART, SD card, and others are internal to the chip and are accessed using MMIO (Memory Mapped Input/Output) registers. This makes some bus sniffing complicated.
Instruction set
While the main core is relatively obscure, it does in fact have a branch in the gcc/binutils suite under the name "score". This has allowed a cross-compiler toolchain for the system to be built and used for objdump in flat binary mode in order to reverse engineer the games that came out for it. The instruction set resembles MIPS somewhat in mnemonics, and generally the wording of the mnemonic and the usage becomes intuitive for the most part. Another thing in the instruction set is that it uses some "hybrid" instructions, where mnemonics denoted with a "!" signify 16-bit instructions, this is useful for code density for the most part, but if two 16-bit operands are not used back to back a 16-bit NOP will be inserted automatically by the compiler to stop address alignment problems. Aside from the 16-bit operands, all instructions without the 16-bit denoted are in fact 32-bit instructions. The ABI also differs from MIPS for the most part.
Games (and information in regards to their workings)
The games on the HyperScan are generally regarded as being poorly designed, and for the most part they consist of 2-D fighting and/or 2d "Beat-em-Up" games. Also, the loading times are notoriously long. The discs are packed with game data, and an executable called "HYPER.EXE". The way the games load is that the entire executable is loaded into memory at 0xa00901fc, where what looks to be a patched elf header is filled with Jumps to a location just before the actual code entry point and some NOPs that would make executing anything before the actual entry point fall on a branch loop. Compiler tools have been set up to automatically generate this header, and home-brew executables were produced. The actual entry point for HYPER.EXE executable is at 0xa0091000, and most of the games have a pretty generic way of setting up startup and branching to main where a global pointer is set to access global data, BSS cleared, interrupts set up, and finally the branch to main.
There seems to be a fixed MMU (Memory Management Unit) of sorts that adds 0x80000000 to the actual physical address for the most part, so things such as the MMIOs which look to start at 0x88000000 are actually starting at physical address 0x08000000. There also looks to be some functions exported to memory from the firmware that facilitate certain things in regards to the game development, and the games look to access these functions from the use of a GOT (Global Offset Table). An example of this is below.
Example
Game code:
Here is seen an address (0xa0092ae4) loaded into r4 (arg1), this address in particular contains a NULL-terminated string (/DAT/IWL.EXE) and then a jump and link takes place, let's see where that location goes to shall we.
Code:
a0092a40: 949ac012 ldis r4, 0xa009(-24567)
a0092a44: 8494d5c8 ori r4, 0x2ae4
a0092a48: 8812a161 jl 0xa0092160
Global offset table
Here you will see that the address goes to a Global Offset Table in which stores some stack frame information, and then loads the "real" function address from the data section relative to the global pointer, along with storing a return address. At this point the stack pointer is moved to accommodate a new stack frame and then the actual function is called. After the function returns, a jump and link is encountered to 0xa0092008 in order to reload the global pointer with the original value, since it is actually modified during this the call of the real function address, in order to accommodate the fixed value. Then return values are swapped and the saved values for the function return are pop'd off the stack and then the branched to so that execution can continue. This function in particular I believe loads a file handle for said file, and then returns accordingly.
Code:
a0092160: 8d80ffe4 sw r12, +
a0092164: c0bcc0cc lw r5,
a0092168: 8c60ffe4 sw r3, +
a009216c: 8403fff8 addi r0, -4
a0092170: 0f5c brl! r5
a0092172: 0c43 mv! r12, r4
a0092174: 8812a009 jl 0xa0092008
a0092178: 84008008 addi r0, 4
a009217c: 04c3 mv! r4, r12
a009217e: 230a pop! r3,
a0092180: 2c0a pop! r12,
a0092182: 0f34 br! r3
Interrupt handling
The actual interrupt handler is set up by the firmware in RAM at the start of memory (0xa0000000), and it is believed that the general vector is base+0x200. During interrupt processing all of the registers are saved to the stack and then the global pointer is again modified to accommodate, then a said "cause register" is moved into r4 (arg1) and then the function is then called to actually decode and handle and process these interrupts. Upon returning, all registers are then restored and then an "rte" instruction is executed at which point the instruction pointer begins resuming execution at the address that was stored in the "EPC" (Exception Program Counter) register, and some fields of the "PSR" (Process Status Register) and condition register are restored to the previously saved state and execution begins where it left off so normal processing can continue.
Real functions
As stated before, the firmware exports these "real functions" for game developers to use, think of it as a "shared library" (probably a more appropriate name) of sorts where these functions are already implemented and can be called to help assist in game development on the system. The Global Offset Table actually makes the calls to another table that looks to be exported starting at 0xa0000800, at which point the global pointer is again changed to accommodate, and the real function is called. They did this probably so they could easily change function addresses if they planned to add some, or modify existing ones in the future by just referencing the jump in the table to the new address so that it doesn't break the already implemented GOT function calls, and new one's could be added simply by adding GOT references.
Example
Code:
800: 979ac008 ldis gp, 0xa004(-24572)
804: 8795a280 ori gp, 0x5140
808: 8801c04c j 0xc04c
80c: 979ac008 ldis gp, 0xa004(-24572)
810: 8795a280 ori gp, 0x5140
814: 88039760 j 0x19760
818: 979ac008 ldis gp, 0xa004(-24572)
81c: 8795a280 ori gp, 0x5140
820: 8803a990 j 0x1a990
824: 979ac008 ldis gp, 0xa004(-24572)
828: 8795a280 ori gp, 0x5140
82c: 8803aa18 j 0x1aa18
830: 979ac008 ldis gp, 0xa004(-24572)
834: 8795a280 ori gp, 0x5140
838: 8803aa44 j 0x1aa44
83c: 979ac008 ldis gp, 0xa004(-24572)
840: 8795a280 ori gp, 0x5140
844: 8803aa90 j 0x1aa90
The Closing
There is a lot of other things that have figured out about the system. There are some small homebrew demo's circulating. A programming cable has been devised that hook's up to the system's controller port, and to a PC parallel port for PC->HyperScan communication, and a loader has been written that allows homebrewers to load compiled code on the fly to the system using this interface. An interface that hooks up to the HyperScan's LEDs has also been incorporated into that same PC parallel port connector, in order to provide HyperScan->PC communication to send memory dumps and debug information to PC. Basically the system can just use simple, regular CD-R's, and with a slight potentiometer modification, CD-RW's. A small library has been to help set up video and use a "framebuffer" mode where pixel data is stored in a linear array and the color's are represented in 16-bit RGB565 mode, at a resolution of 640x480 (NTSC). The library also has functions implemented for a few other things such as printing text, sending/receiving a byte over the programming cable, l.e.d fun, and a few other basic functions. As of now the controllers and sound working yet, mainly just video and a few other small things. Once the HyperScan->PC connection finished, The aforementioned "real functions", along with the rest of memory, and then the real fun can begin since everyone will then be able to figure out what each one of the "real functions" do, since they seem to be what's actually handling most of these things.
 
< Prev   Next >