A Showcase of the Internal Construction of the Game Boy Advance Cartridge

X

Recently, after completing The Legend of Zelda: A Link to the Past, I was struggling to think of what game to play next. A session of gaming with some of my friends pointed me towards the Pokémon games, which I had not played in quite a while. Instead of jumping straight into the newest game in the series that I own, Pokémon Diamond, I decided that I’d play through the Game Boy Advance games first. Taking Pokémon Sapphire out of storage revealed that the internal battery had died, and that I would have to open up the case of the cartridge in order to replace it. Having opened the cartridge case and identified the battery type that I’ll need to purchase, I got to thinking what the internal structure of other Game Boy Advance cartridges that I own was like.

My (admittedly small) collection of Game Boy Advance games includes games with about five different internal patterns, ranging from simple patterns with a ROM chip and a few surface-mount capacitors to the complicated pattern found in the Pokémon Ruby and Sapphire cartridges, which contains a ROM chip, a large Flash memory chip, a real-time clock and a large set of surface-mount components.

The simplest internal structure was found in my copy of MotoGP among others.

The most substantial component in this pattern is the large Mask ROM chip that dominates the centre of the cartridge. The circuit board is marked with the lettering, “U1 32M MROM”, suggesting that this chip has a capacity of 32 megabits, or 4 megabytes. This connects to the Game Boy Advance using the traces coming from the chip which lead to the bottom of the cartridge, where several copper-coated traces lead to the cartridge connector of the Game Boy Advance. To the left of the ROM chip, we can see three surface-mount capacitors, marked “C1”, “C2” and “C3”. Aside from these components, there is little to talk about in the remainder of the cartridge case. The construction of this cartridge is very simple, and it’s easy to see how this might work. One thing which is non-existent on this design which we’ll see on other cartridges is a memory chip – this game uses the rather archaic technique of providing passwords to the player in lieu of saving progress.

A more advanced pattern can be seen inside of the cartridge for Doom. Doom on the Game Boy Advance was a port of the version found on the Atari Jaguar console, a low-resolution version which was missing the Cyberdemon and Spider Mastermind enemies, along with the Spectres (invisible variants of the mêlée-based Demon enemies). Nevertheless, despite the limitations of the port, it proved to be one of the more accomplished first-person shooters of the Game Boy Advance.

The Mask ROM chip in this cartridge has been offset to the right to make room for the memory chip, taking the form of an EEPROM chip, presumably of the larger 64-kilobit capacity. This EEPROM chip provides non-volatile memory which is an improvement over the battery-backed RAM found in games for the Game Boy and Game Boy Color. The life span of a Game Boy Advance save state is effectively limited to the life of the EEPROM or Flash chip, a far greater time than the life of the CR2025 or CR2032 batteries of the Game Boy cartridges.

Unlike the PC version of Doom, where saving can be done on any part of a level, the Game Boy Advance version only allows you to save at the end of a level, and needs only to store the current level along the health, armour and ammunition state of the player. Save games are also limited to four, rather than the eight found in the PC version. Aside from the additional EEPROM chip, there is another surface-mount capacitor on this board which was not found on the MotoGP cartridge.

Despite the addition of save states to this game, it does not have a particularly complex pattern by the standards of other Game Boy Advance games. A design more typical of Nintendo first- and second-party cartridges can be seen in the cartridge for Golden Sun.

Golden Sun plays very much to the sensibilities of the SNES era of Japanese RPGs, despite being released about five years after the likes of Chrono Trigger and Final Fantasy VI. Yet it was this playing to those sensibilities that made it one of my favourite games on the Game Boy Advance, and an avid follower of the series up to the recent Golden Sun: Dark Dawn for the Nintendo DS. The Mask ROM chip on this circuit board has been moved to the left-hand side, with the memory chip, a 512 kilobit Flash memory chip used to store up to three save files, containing such details as the geometric position of the player on the game environment, the health status of the characters, how the Djinn are set on each character, and so on and so forth. The other surface-mount components are four capacitors, as found on the Doom cartridge, only found in a different arrangement to suit the left-mounted position of the Mask ROM chip.

A similar pattern can be found on the cartridge for Golden Sun‘s sequel, Golden Sun: The Lost Age, along with the cartridge for Pokémon FireRed as can be seen below.

The general layout of this cartridge is similar to that of the cartridge for Golden Sun, and while both games are RPGs, a layout precisely like the cartridge layout for Golden Sun can also be found in Mario Kart: Super Circuit. The FireRed cartridge differs from the Golden Sun cartridge in some subtle ways, using a different Flash memory chip, and with a few more surface-mount components, this time including resistors as well as capacitors. The Flash memory chip still does not extend across the entire space allocated to it, which could suggest that it is a 512 kilobit chip rather than a 1 megabit chip.

The final type of cartridge pattern that I have found is also the most complex one, belonging to Pokémon Sapphire. Unlike any other Game Boy Advance game that I have found, Pokémon Sapphire possesses a type of time-linked game mechanic, which despite not being as advanced as the similar features in the Game Boy Color predecessors in the series, does still necessitate the use of a real-time clock.

The real-time clock is found above the Flash memory chip, which is found on the left-hand side of this cartridge. To the right, above the Mask ROM chip, is a CR1616 button cell which powers the real-time clock. This is the component that will have to be replaced in order for all of the features of this game to work correctly, as certain events are linked to the time of day and the progression of time. None of them are critical to the completion of the game, but it still annoys me to have an incomplete game for the sake of a cheap button cell.

The Flash memory chip on this circuit board is substantially larger than that on the other cartridges with Flash memory, which suggests that this is of the 1 megabit capacity rather than the smaller 512 kilobits found in the other cartridges. As well as that, there are more surface-mount components on this wafer than on others, with a larger set of resistors and plenty of capacitors. Another component, marked “X1”, is prominent on the left-hand top corner, beside the RTC chip, although its use is a mystery to me. It may be some sort of transducer, based on the decoding of the reference symbol, but aside from this, I have no real idea what the component could be used for.

UPDATE: I must be some sort of electronics dunce for only realising this now, but the component marked “X1” on the last picture is probably a crystal diode for the real-time clock IC.

Fundamentals of String Manipulation in C: Part 1

We’ve already seen arrays, which are chains of contiguous pointers to variables, and we’ve seen how we use them. There are arrays available of all data types, including integers of all lengths, floats, doubles and chars. A char array could be used to hold a series of characters corresponding to a word or sentence, as such:

#include <stdio.h>

int main(void)
{
    char word[] = {'f', 'o', 'o', 'b', 'a', 'r'};
    int i;
    for (i = 0; i < 6; i++)
	printf("%c", word[i]);
    printf("\n");
    return 0; /* Recall that main() returns this as an error code */
}

The array is defined with a series of characters, six in total, and the for loop goes through each character in sequence and prints it to the screen. This is, however, a cumbersome procedure and requires knowledge of the length of each individual character array. Because the manipulation of text in C is so common, there is a simpler, less cumbersome way of declaring and using arrays of characters, as illustrated below:

#include <stdio.h>

int main(void)
{
    /* Note that there are no curly brackets, and quotation marks are
    * used. */
    char word[] = "foobar";
    int i;
    for (i = 0; i < 6; i++)
	printf("%c", word[i]);
    printf("\n");
    return 0;
}

The format of the character array in this example is known as a string. Indeed, we’ve seen them before many times without explicitly referring to them as such; the printf() function takes arguments which are strings. Indeed, we can change the printf() arguments in this example to make it easier and less cumbersome:

#include <stdio.h>

int main(void)
{
    char word[] = "foobar";
    printf("%s\n", word);
    return 0;
}

This is much simpler to read, less dependent on knowing the length of the string and less error-prone. The question is, however, “How does printf() know when to stop printing?” The answer is that the word[] string isn’t just declared with the six characters in “foobar”, but also with a so-called null character, which is denoted using “”. Internally, printf() goes through the characters in the string until it reaches the null character, whereby the function terminates and returns.

There is another function in <stdio.h> which acts like printf() with a %s format specifier, and which is easier to remember and use. puts() takes a single argument, a character array, and prints it to the screen with a newline character at the end. This is illustrated below:

#include <stdio.h>

int main(void)
{
    char word[] = "foobar";
    puts(foobar);
    return 0;
}

As you can see, this is a cleaner way of printing strings to the screen than printf(), albeit without the flexibility. String printing is commonplace in text-based systems with C programming, and so puts() is often useful.

Now that we have a string, we might want to add it to another string. This can be done by declaring a larger character array which is large enough to accommodate all of the characters of both strings, and then copying the contents of both strings together. This can be illustrated with the following example:

#include <stdio.h>

int main(void)
{
    char word_1[] = "foobar";
    char word_2[] = "baz";
    char combined[10];
    int i = 0; j = 0;

    /* Continue going through the string until '' is reached */
    while (word_1[i] != '')
    {
	combined[i] = word_1[i];
	i++; /* Incrementing i goes to the next slot in memory for
	* both arrays */
    }
    /* i is now equal to the first empty element in combined */

    /* Starting again with a new counter variable */
    while (word_2[i] != '')
    {
	combined[i+j] = word_2[j];
	j++;
    }
    combined[i+j] = ''; 
    printf("%s\n", combined);
    return 0;
}

This will print out a string with the contents “foobarbaz”. The problem here, though, is that as above, with the definition of the character array using individual characters, is that this is complicated, cumbersome and error-prone. For this reason, several functions have been defined in the C standard library under the header file, <string.h>, which more cleanly deal with the manipulation of strings. The following program demonstrates some of them:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char word_1[] = "foobar";
    char word_2[] = "baz";
    char combined[10];

    strcpy(combined, word_1);
    strcat(combined, word_2);
    puts(combined);
    return 0;
}

As you can see, this is a far cleaner way of defining these operations, without any need for explicit counters or anything else which would make the program more error-prone. Both strcpy() and strcat()take their arguments in the following form:
strcpy(destination, source);
strcat(destination, source);

strcpy() (standing for string copy) is used to copy the contents of one string to another, including the ” null character. strcat() (standing for string concatenate) is used to append the contents of one string onto the end of another; the word “concatenate” is merely a fancy way of saying “link

together”, in this case referring to joining two pieces of text together.

There are a number of other useful functions defined in <string.h> which are of note. strcmp() takes two strings and compares the characters in them. If the characters are exactly the same, the function returns 0; otherwise, it returns a positive or negative value depending on the difference in ASCII values between the first character that disagrees in both strings. strlen() returns the length of a string. Both functions are illustrated below:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char word_1[]="hello";
    char word_2[]="world";
    char word_3[]="concatenate";

    /* Note the different values returned each time. */
    printf("The difference between word_1 and word_2 is %d\n",
    strcmp(word_1, word_2));

    printf("The difference between word_2 and word_1 is %d\n",
    strcmp(word_2, word_1));

    printf("The length of word_3 is %d\n", strlen(word_3));

    return 0;
}

This program returns the following results:

The difference between word_1 and word_2 is -15
The difference between word_2 and word_1 is 15
The length of word_3 is 11

This is consistent with the difference between ‘h’ and ‘w’ in the ASCII table; this is also consistent with the length of the word “concatenate”. These functions can therefore be used usefully when comparing text, which is a common task in the C programming language.

Using scanf(), we can write our own text into a character array as a string; however, this does not have any security against the characters overflowing the string and causing a segmentation fault. The use of scanf() to write into a string is illustrated below:

#include <stdio.h>

int main(void)
{
    char string[21]; /* 20 characters plus the null character. */

    /* Note that we don't use the & dereference operator here. */
    scanf("%s", string);
    printf("%s", string);
    return 0;
}

This will work successfully unless the characters entered are greater than 20; this will cause a segmentation fault and cause the program to halt unexpectedly. As with printf() and puts(), there is a function defined for entering characters specifically into a string called gets(). gets() is, however, considered dangerous and replacements are available in many extended C standard libraries; however, gets() is defined in ISO C90 and C99 and is available on all implementations of Standard C. It is illustrated below:

#include <stdio.h>

int main(void)
{
    char string[21];
    gets(string);
    puts(string);
    return 0;
}

Another thing to note is that strings, unlike character arrays defined with discrete characters, are not modifiable. Assignment statements cannot be used on a string or its elements. A function must therefore be used on the string in order to modify it.

Finally, there are a number of functions which are defined in <stdlib.h> which can be used to convert a string of characters with numerical values (i.e. ‘0’ to ‘9’) into integers, floats or doubles. atoi(), for example, (standing for ASCII to integer) converts a string consisting of such values, e.g. “1234” into an integer value. Other similar functions are also contained in <stdlib.h> and would be described in a reference of the C standard library (such as Appendix B of The C Programming Language (Kernighan & Ritchie, 2nd Edition, 1988)).