Welcome to Old Games, New Tech! This post should explain the name in addition to what I intend to put on this blog.
Old games – think games for the Nintendo Entertainment System (and its successor, the Super NES), Nintendo Game Boy, Sega Master System (and its successor, the Mega Drive, or Genesis), and arcade machines – had precious little ROM to hold their data and code. The consoles running the games also had processors with relatively low clock speeds, slow memory access, and no data cache. Most code was written directly in a given console's assembly language: the programmer was able to control every interaction between the processor and the slow main memory, which had an impact on both performance and code size. Code size was helped by the short instructions. However, it was hindered again when the programmer needed to perform calculations on values that were larger than 8 bits, as multiple instructions would be required.
Then, almost all at once, the performance of computers exploded:
- the clock speed of processors skyrocketed;
- memory became cheaper, so larger, more complex games could be made;
- data caches, and even instruction caches, became more and more common;
- wider data buses meant that more data could be read from main memory at once.
And one of the most contentious points of this explosion of performance was the extreme focus on having more bits. Having more bits was so important that many consoles were named after how many bits they had: the TurboGrafx-16, known as the PC Engine in Japan; the Sega 32X; the short-lived Amiga CD32; and the Nintendo 64. While some other consoles did escape this naming convention, the number of bits they had was important enough to mention in their marketing materials. The Super NES had 16 bits, for example, while the Atari Jaguar had 64 bits, and everyone knew that.
The number of bits referred to the width of the processor's registers – circuits which could store a value for later use and yield it in under one clock cycle for the next computation. Along with the increased number of bits, new architectures had more registers, too: ARM and its 16 registers, and MIPS and its 31 registers. In theory, a processor with that many registers would keep more data ready for immediate computations, and this would prevent some accesses to the main memory, increasing performance even more.
In practice, because of this explosion of performance, it no longer made sense to focus so much effort on making every clock cycle count, so developers stopped making games purely in assembly.
In the early 1990s, developers started making games with C compilers provided by the hardware makers, such as Sony's SDK for the PlayStation, and Nintendo and SGI's SDK for the Nintendo 64. Those C compilers were not like the optimizing compilers we know today. They often had very little RAM to themselves, so they could not keep holding on to the vast amounts of data required to optimize entire programs. They kept just the data that was needed in order to make sense of global variables, the functions of the C library, and everything defined in the function they were looking at right now. Everything else was already in flight to the assembler, forgotten to make way for the next function.
Someone reading the assembly generated by these early C compilers for these old games, knowing how well new tech can optimize C code (there's the name!) would be baffled. It's easy to think that some of the games of the early 32-bit and 64-bit eras were just compiled without optimizations, because they skipped frames so often while there were not even that many objects on the screen. The more likely explanation is that those optimizations were the best available at the time with the many constraints that contemporary computers had.
This blog will be about these code sequences. Some knowledge of computer internals as exposed by most instruction set architectures, i.e. registers and memory, addresses and pointers, as well as common bitwise operations like AND, OR, XOR and NOT, are required to understand these. Individual ISAs will have their own introduction.
This is a very interesting topic for me, as I am both a huge PS1 fan as well as an SGI fan. Would be interesting to also see comparisons of older versions of Borland/ Microsoft-C/Watcom 32-bit/etc
ReplyDelete