The example embodiment is a device to play games. It consists of a strong PowerPC-based CPU with some proprietary extensions, a proprietary GPU/Peripheral core (called "Flipper"), including a powerful 3D processor, 24MB of 1T-SRAM, a mini-DVD disc drive, several external interfaces.

The example is meant to be only used with original games, and thus has a protection that boot is only possible from copy protected discs. However, a game called "Phantasy Star Online" contained a possibility to exploit the games' connect to the internet, thus allowing code to be injected and executed (www.gdev.com) - the homebrew scene had started!

The problem is that the boot process with PSO takes very long each time you want to try something, about 1-2 minutes - really not perfect for a nice development cycle. To overcome this, I developed a bios (or bootrom, as or9 would say) replacement, which i want to present here.

DISCLAIMER

The information presented here are based on my opinion that they no not break any laws, rules or whatever. If they do, please contact me at gc@_n0spam_debugmo.de (remove the n0spam) and I will remove the stuff IMMEDIATELY.

DISCLAIMER 2

Any information here are provided "as-it". I take no warranties for anything here, especially if you break you device you're on your own. Please do not mail me about broken connectors, broken pins or simply "not-working devices". In doubt, don't modify your device if you don't have another one to play with.

DISCLAIMER 3

About piracy - PLEASE don't. This isn't about piracy. It won't help you if you want to read non-original game discs, and i'm quiet happy about the fact that the actual copy protection seems to be done in the dvdrom's firmware. This project is about HOMEBREW development, demos and stuff. Not about playing copied games. Piracy will kill the whole scene on the day you can boot warez without having a BBA or having to boot PSO each time. If this will happen, the commercial interest in warez will grow, and nintendo will have to take legal wars against everybody who is circumventing the ordinary boot process. Please DON'T LET THIS HAPPEN. DON'T SUPPORT WAREZ, otherwise we soon have to search for another console to hack.

As I explained in this dextrose forum post i managed it to program a CPLD to replace the contents of the IPL, or BIOS, or bootrom. The hardware part consists of:

When the IPL is read from the IPL chip, the CPLD inject a small block of code. The code will be read to 0x81300000, the entry point of the normal IPL. When the code is executed, it loads the first sector from the memory card in slot b to 0x81000000 and jumps there. The code looks as the following:
  .long 0x52000000         # although being code, it's nearly a no-op.
                           # this is the sector address sent to memory card
  lis r27, 0xcc00          # load base of hardware registers.
                           # as the bat are already initialized by BS, we
                           # add 0xC0000000 to the base 0x0C000000.
  li r28, 0x0880           # chip select on for memcard slot, low speed
  mflr r29                 # lr still contains the address of this code - i.e. 0x81300000
  li r30, 128              # transfer 128 bytes
  li r31, 7                # EXI DMA write
  bl do_dma                # do dma, and wait for end
  lis r29, 0x8100          # now read to 0x81000000, again 128 bytes
  li r31, 3                # EXI DMA read
  mtlr r29                 # set address to be jumped to
do_dma:
  stmw r28, 0x6814(r27)    # initiate DMA
write_wait:
  lmz r5, 0x6820(r27)      # read status byte
  rlwinm. 0, 5, 31, 31     # extract "in transfer" bit
  bne write_wait           # wait until cleared
  blr                      # branch back / to code
This code may look a bit confusing at first, but it had to be as small as this, otherwise it wouldn't have fit into the CPLD.

The code sends itself out to the EXI. thus the bytes sent are "52 00 00 00 3f .. .. ..", 128 bytes in total. The memory card expects one command byte, which is 0x52 in this case. after that, it expects the address, 00 00 00 3f in this case, which is the first sector, offset 0x3F. then it expects 4 dummy bytes, and starts sending out the data bytes after that. after it reaches the end of the sector (128 bytes + 6 special bytes for ECC, but we can use them as well), it starts repeating the sector. So after writing out 128 bytes we can read 128 bytes of payload into memory. A special program will shuffle the data around so that after 128 bytes of data the first data of our beloved payload comes out, and gets read into memory. After we finished the exi read dma, we jump there.

This was the first stage bootloader. Now the first sector of the memory card contains 128+6 bytes of a second stage bootloader, which reads the remaining sectors of the card into mem and jumps there. We couldn't do this from the beginning because of the lack of space in the CPLD. the 2nd stage bootloader i wrote fits exactly into 128bytes, but probably can be optimized a bit further. i don't care, since it fits.

Now we can load up to (nearly) 512k of user code into memory, thus writing our own IPL replacement. I have started to do that, but it still misses important functions, but can be used to upload DOLs (using network) and execute them (allowing to boot homebrew in a matter of seconds), and start games (using a small apploader).

The mc.c tool:

This tool will prepare an action replay card for our bootloader. The program is made for linux on a PC, thus needing an interface to the memory card. I made the following connection to the printerport:
Pin
 3    D1  - SERIAL IN (to card)
 4    D2  - CHIP SELECT (to card)
 5    D3  - CLK (to card)
 10   ACK - SERIAL OUT (from card)
 25   GND - GROUND
 
3.3v      - Card VCC
For the pinout of the memory card, take a look at http://members.shaw.ca/cheezWhizzer/GCNCard.htm.
You could port the memory card writer to be run on the example embodiment, but i strongly recommend to use a PC, because you can reprogram it much faster. Note that you should not attempt to get the 3.3v from the parallel port - it won't work. Be careful, if you have an old PC, the levels at the parallel port might be still 5v. Use buffers or a newer PC (with 3.3v levels) then.

You have to call ./mc with a binary file as argument. It must be a file linked to 0x81000080, with entry point at start. My makefile will produce a file called "main_boot.bin", which is suitable for this. Take care that the number of used pages does not exceed the number of pages read into memory by the second stage bootloader. You can increse them as you like.

The IPL replacement

My IPL replacement is still far away from being perfect. However, it already supports: Note that you have to adjust the IP addresses directly in the code. Take a look into "network.c". Thus it is almost anything you need for a rapid development cycle.

DOWNLOADS

The IPL replacement, including the memory card writer tool mc.c.
The CPLD code, usable for Xilinx ISE (WebPack will do it).

Pictures

(detailed soldering information will follow)
The ROM/RTC/...
The SERIAL_OUT-pad
The action replay memory card connection
The action replay memory card with pc connector
The CPLD in front of the example embodiment
First screenshot of my IPL replacement - yes, very ugly.