Discussion forums

Put your questions, comments and suggestions here:

Current: RoboCommunity: Robopanda Hacks and mods

Old: Unofficial Robosapien Hacks and Mods Forum :: ROBOSAPIEN forum :: Future WowWee robotics :: RoboPanda :: Robopanda hacks

Additional information

Cartridges Contents

Dumped by Nocturnal:

Partially decoded cartridge contents available in emu_logs tarball


SPI Read Traces

Bytecode emulator

Cartridge MetaData

There are some essential values for decoding bytecodes:

Regions of cartridge:

cpu -> spi address conversion: spi_address = cpu_address * 2 + index

Known CPU Bytecodes

Programming model

CPU has stack, local registers and global memory.

Most opcodes work with values on stack (pop args, do op, push result)

Ops with local registers optimized for small values (0-15, 0-63) and mostly used for loops

Global mamory can be accessed as 16 and 32 bit values(pop/push @XXX and pop2/push2 @XXX)

There are read_spi bytecode for reading data from cartrigde

Codes by first byte

0 1 2 3 4 5 6 7 8 9 A B C D E F
0 push #XXXX                         cmp #XX  
2 push @XX push2 @XX     pop @XX pop2 @XX       misc commands       push/pop $XX misc commands  
7           sensors                    
9           cmp $X,#Y                    
A                 set $XX,#YY        
B spi_read
C call XXXX
E rjump XXXX rjump_e8 XXXX
F rjump_e0 XXXX rjump XXXX,#YYYY


Most bytecodes has lenght of 2 bytes, and some 4 or 6 bytes

Most 4 byte bytecodes get second word when arg is all-ones:

Call bytecodes has second or third word with number of args and locals. In traces this word gets readed twice - before and after call (first for args and locals push, second for locals pop).


For always up-to-date bytecode information see emu.py sources.

Bytecode decoding method

Decoding of CPU bytecodes done using cartridge emulator by writing small test images consisting of 3 sequences of code:

and by looking at addresses of spi_reads we can get stack and registers state after tested code.

pop @40 codes used for droping result of spi_read from stack (true drop opcode is not known now)

Example of such code can be seen in test.cfg in tools tarball.

Known Mover Bytecodes

Audio data encoding

Audio data chunk format:

All files coded with 07 codec, except for 2 songs in black cartridge

Audio player reads data chunk every 16ms for all codesc.

Different codecs was tried and next codecs worked:
codeinitial readnext readsbitrate

sound for codecs 4-7 and 8-9 is very different.

4-7 is white noise-like

8-9 is R2D2-like :))

traces of test cartridges with different codecs: test_codecs.tar.gz

Wav files corresponding to some audiochunks

There is a lot of activity with audio on RoboCommunity forum.

Test cartridge image

I have done hardware emulator for cartridge and tested it with standart cartridge images - it works.

So I tried to make some cartridge :)) For now it only contains one song, required metadata and 3 commands code for starting audioplay.

For testing assumptions about index position, this cartridge has index at 0x1000 instead of 0x2000 in standart cartridges.


For SPI sniffing I use FPGA based board ebayed 3 years ago :)) It has Xilinx XCV600E, config proms, RS232 level-shifter, dc-dc convertors and a lot of unsoldered pins connected to fpga :))

For physical emulation of cartridge I used chunk of old PCI card with termoglued connector housings :))

for fitting into socket PCB tickness must be trimmed in half

For this project it has been upgraded with

As development software used Xilinx ISE WebPack.

For SD Reader used core from OpenCores

For high level tasks small CPU was developed :)) It's not so optimized as existing cores, but it does exactly what i need :)) And having a relatively big FPGA (600k gates) greatly simplifies such a task :))

This was one of reasons for looking at traces from bytecode standpoint - it's really not so hard to develop and implement your own instruction set.

HDL sources available in hwemu tarball. In current state it uses 30% of Xilinx XCV600E.

Design contains:

32M of DRAM divided in 2 regions: sniffer memory (24M) and cartridge memory (8M)

Sniffer writes 64bit for each multibyte spi access, with spi usage of robopanda it gives ~20minutes of sniffing

traces and cartridge images read/written to SD card at fixed offsets (no filesystem)


Robopanda with brain probe attached. I'm not sure it's exactly brain... :))
Cartridge with sniffer attachment
Cartridge insides
"Development" board
emulator cartridge :))
PCB thickness adjusted
Yet another probe to little panda :))