NOTE: I DO NOT RECOMMEND THAT YOU PERFORM THIS UPGRADE! If you do, there is a good chance that you will permanently
damage your GP32. While you are welcome to use this description as a guide to performing the upgrade, I will
not accept any responsibility for the consequences. It's all at your own risk.
I did the upgrade in 4 stages:
Find the right RAM
Modify the BIOS
Replace the RAM chip
Add MMU code to applications
My conclusions from the exercise are:
- the 32MB works perfectly.
- Battery life will be shortened, probably by about 5%.
- An upgraded GP32 will not overclock any better than an un-upgraded one.
Find the right RAM
If you click the "Submit" button, you will send your input to a new page called form_action.asp.
The 8MB RAM in the stock GP32 is 133MHz SDRAM. It is arranged as 1M x 16 bits x 4 banks, and is addressed with 8
column and 12 row address signals. It uses 4096 refresh cycles per 64ms.
I got a PC133, 128MB, 4 chip DIMM module from the local PC store. It is vital that the module had 4 chips, because
PC DIMM modules have 64 data bits so in a 4-chip module each chip has 16 data bits. The module I got has "V-Data"
chips, which are made by A-Data Corporation. Each chip is arranged as 4M x 16 bits x 4 banks, and is addressed
with 9 column and 13 row address signals. They use 8192 refresh cycles per 64ms.
This is why the bios needs to be updated: the normal BIOS programs the CPU's memory controller to use only 8 column
address lines, and also the refresh rate is not fast enough.
I did a pretty thorough comparison between the data sheets for the two RAM chips, and they seem compatible. However,
the data sheet for the 32MB chip is a horrible mess of obviously wrong information (for example, the pinout diagram
is for a completely different chip) so I can't be too confident about any of it!
Modify the BIOS
I'm not going to explain the changes in complete detail, if you want more detail then look at the BIOS disassembly
on Mr. Spiv's site and figure it out for yourself :-)
The changes that I made were:
Address 0x0002B0 00890543 -> 008906A2
Address 0x0028A0 00002710 -> 00004E20
These change the refresh rate to 8192 cycles/64ms
Address 0x0001A8 E3A0B016 -> E3A0B010
Changes BANKSIZE to have 32M/32M banks 6 & 7, instead of 8M/8M
Address 0x00019C E3A08906 -> E3A09906
Address 0x0001A0 E3A09906 -> E2898001
Changes BANKCON6 to use 9-bit column addressing instead of 8-bit. Note: it is possible to piggy-back two 32MB RAM
chips to give 64MB total, but this requires BANKCON7 to be set to use 9-bit column addressing for bank 7. I have
not bothered to do it.
Address 0x001B78 000004FF -> 000007FF
Sets the CPU pins GPA8/A23 and GPA9/A24 to be address pins rather than port pins.
Mr. Spiv and I have made a modified copy of the multifw2 BIOS available
for download. Many thanks to Mr. Spiv for his improvement to this, which makes the extra memory a LOT easier to use!
This bios can be used to flash a GP32, but it must not be done until just before the RAM chip is changed
because it does not work with the 8MB chip.
Replace the RAM chip
Because the RAM chip has an extra row address signal, a wire must be added to connect this signal to the CPU. Also,
the RAM bank select signals BA0 and BA1 are connected to the CPU pins A22 and A21 for the 8MB chip, these signals
must be connected to CPU pins A24 and A23 for the 32MB chip.
So, the connections to be made are:
CPU pin 178 (ADDR13) to RAM pin 36 (A12)
CPU pin 188 (GPA8/A23) to RAM pin 20 (BA0)
CPU pin 191 (GPA9/A24) to RAM pin 21 (BA1)
Pins 20 and 21 on the RAM must be separated from the PCB traces that they normally contact to, as these traces are
connected to CPU pins A22 and A21.
Here's the GP32 and RAM module before I started the job:

Removing the back of the GP32 exposes the RAM chip. I decided to completely remove the PCB and disconnect it from the
LCD, because this removed the LCD from the heat involved in soldering the RAM chip.
The RAM chip was pretty easy to remove with a hot-air desoldering tool. It would be more difficult with a soldering
iron. One good strategy for removing ICs is to use fine-tipped cutters to cut the legs along one side of the device,
and then wiggle the body of the IC up and down until you break the legs on the other side of the device. Then a
soldering iron can be used to remove the remaining pieces of the legs.
Before putting the 32MB RAM in the GP32, I gently bent pins 20 and 21 up so that they would not contact the PCB when
the RAM was soldered in. Here's the RAM ready to go into the GP32:
Next, I soldered the RAM onto the GP32, and added the three wires. I ran the wires through one of the holes in the
PCB where plastic case clips go through. Although you can't see it too well in the photos below, I also added blobs
of silicone compound to the ends of the wires, to stop them breaking due to vibration.
This was definitely the hardest part of the job. The pins on the CPU are 0.5mm apart, and so soldering a wire to one
pin without connecting to any other pins took a LOT of care!
Next, I put it all together again and it worked! Well, it didn't work first time because I'd connected one of the
wires to the wrong place. But after I pulled it apart, moved the wire, and closed it up again, it was all good :-)
Add MMU code to applications
With the memory controller changes in the BIOS, and the RAM chip installed, the GP32 has 32MB of working RAM. This
RAM is at addresses 0x0C000000 to 0x0DFFFFFF. The BIOS system memory is from 0x0C796000 to 0x0C7FFFFF, so from
0x0C000000 to 0x0C795FFF and from 0x0C800000 to 0x0DFFFFFF is available to programs.
The final issue is how to get programs using all of that extra space. Probably the best solution is put the heap in
the extended memory, which means changing the way the malloc function works. I don't know how to do this for
the gamepark SDK, but Mr. Spiv is looking into it.
If you are an emulator coder, all you really have to do is put your emulator's ROM image into the extended memory. For
example, if you're currently allowing 4MB for ROMs, and you use gm_malloc, you can change
unsigned char *pROM;
unsigned int nRomSize;
nRomSize = 4 * 1024 * 1024;
pROM = (unsigned char *)gm_malloc( nRomSize );
to
#define GP32_BANKSIZE (*((unsigned int *)0x14000028))
unsigned char *pROM;
unsigned int nRomSize;
if ( ( GP32_BANKSIZE & 7) == 0)
{
nRomSize = 24 * 1024 * 1024;
pROM = (unsigned char *)0x0c800000;
}
else
{
nRomSize = 4 * 1024 * 1024;
pROM = (unsigned char *)gm_malloc( nRomSize );
}
What this does, is it checks the CPU's BANKSIZE register to see if the RAM memory bank is 32MB in size. If it is, then
24MB is allocated for ROMs. Otherwise, the standard amount of memory (4MB in the example) is allocated.
By doing this, you will make an emulator that will work on either 8MB or 32MB GP32s, and will automatically take
advantage of the extra size when it is available!
Personally, I don't use the gamepark SDK. Instead, I use newlib
which is well documented and the modification to put the heap in the extended memory area was very simple. I won't
put details about that here (yet), but I'm working on a library to replace the gamepark sdk (well, the low-level
stuff like file and memory management anyway) and that will appear on this site sometime in the future...
Update:
I have now upgraded my GP32 to 64MB! That is the maximum that the GP32's CPU can handle, and is done by connecting another
32MB RAM chip into the unit. The new RAM chip shares all of its connections except for one with the existing RAM chip,
so the upgrade was done by simply sandwiching another chip on top of the one that was already there. I don't imagine
that anyone else will seriously consider doing this, so I won't give too many details (e-mail me if you're interested).
However, here's a photo of the sandwiched RAM chips: