
Writing a Game Boy emulator - tosh
https://cturt.github.io/cinoop.html
======
anyfoo
I mentioned this already in another thread, but if you are interested in
emulating hardware or just how CPUs and hardware work in general, writing a
Game Boy emulator is about the most fun and educational project you can take.

The Game Boy hardware is, on its surface, extremely simple (as an example,
there is no “operating system”, only a 256 byte (!) boot ROM that pretty much
only serves to display and validate the Nintendo logo shown at start), and it
has a vast library of games available for it that make use of that hardware to
varying degrees.

This means that you can get really good results really fast. Especially the
earlier games, like Tetris, don’t rely on fine grained implementation details
too much, so even a sloppy, quickly put together emulation can run them well.

But if you then strive for accuracy or just being able to run more complex
games, you can take things to almost arbitrarily detailed levels of this
somewhat “fractal” complexity, uncovering and implementing all sorts of
interesting hardware intricacies.

Contrast this with even slightly more recent game consoles, where you will
have a lot of busywork ahead of you to even get the system past any reasonable
definition of “booting”, without any gratifying visual feedback. With the Game
Boy on the other hand, getting to a game’s title screen, with working buttons
and all, is actually pretty simple.

~~~
Legogris
I actually started C programming on Game Boy back in the days, but for me the
Game Boy Advance really hit the sweet spot. ARM (nicer instruction set) and
all of the close-to-the-metal characteristics you name above.

If you want to write a complete emulator, I can imagine that the Game Boy
Advance can be a bit more of an undertaking with the different alternative
graphics modes.

~~~
Graziano_M
I haven't written a GBA emulator, but GBA got me into ARM. Tonc's old guide to
ARM[1] I'll still send to people who want to learn ARM.

[1]
[https://www.coranac.com/tonc/text/asm.htm](https://www.coranac.com/tonc/text/asm.htm)

------
lloeki
> I also had plans to port to Mac OS X, but like with PS2, this proved too
> difficult since I was unable to install a working C compiler and development
> environment on Mac OS X.

I am surprised by this statement, as it's generally as easy as _xcode-select
--install_ to install the CLT (or failing that, installing full-blown Xcode).
Slightly up in the article there is mention of Lion, so maybe this is related.

~~~
roblabla
While this is true, I have a few major gripes with the toolchain that comes
with XCode. For instance, I was recently working on a project using C++17
features. It works correctly on linux and windows, but making it compile on
macOS was nigh impossible. The clang compiler that comes bundled with macOS
has a "special" version that makes it very hard to know where exactly it
stands compared to the normal LLVM repository.

Then there's the problem of libraries. You have to use homebrew or whatever to
install libraries in /usr/local. Some libraries would conflict with the system
though, so you have to fiddle with env variables to make the build system find
it.

Overall, building on MacOS/Xcode is a frustrating experience. I ended up
installing nixos and using its toolchain for my work...

~~~
twodayslate
The documentation for the macOS version of clang seems to be non-existent as
well (sans the man/info page - but even that seems incorrect as some flags
simply don't work).

------
the_spacebyte
I've been developing a Game Boy emulator with a friend as well, and struggling
a lot with the poor documentation. There's a very thorough PDF with lots of
information online but when it comes to Opcodes (and cpu flags) it's quite
inaccurate. Most often than not I have to skim through several github projects
to check that the implementations match. (which sometimes don't)

Perhaps we'll start doing a Nintendo64 emulator instead which is more complex
but from what I've heard/read has much better documentation.

~~~
zerr
While playing with the result (working emulator) can be exciting, the process
of developing itself sounds quite mundane.

~~~
anyfoo
What makes you say that? Writing a Game Boy emulator is essentially
implementing _a whole computer system_ , in the case of the Game Boy one that
can quickly give you gratifying results, but allows you to dive almost
arbitrarily deep.

I’d state the opposite and claim that it’s actually one of the most fun and
interesting things I’ve ever undertaken. In fact, I am more interested in the
process than the actual product. There are tons of well working Game Boy
emulators already.

~~~
zerr
But you're not creating a new computer system, you're not designing it. You
have to exactly follow the specs, and the things mentioned by parent. Seems
more like mundane and housekeeping stuff rather than creative.

~~~
jdietrich
Implementing a well-documented spec is fairly mundane, but figuring out that
spec on your own is a fascinating puzzle. Emulators are full of curious little
edge cases that can drive people to the point of obsession.

[https://mgba.io/2017/05/29/holy-grail-bugs/](https://mgba.io/2017/05/29/holy-
grail-bugs/)

------
ArtWomb
This would make a great undergraduate computer science class. I particularly
like where author is somewhat forced by circumstances to fashion their own
bespoke tooling. Rapid prototyping of minimal tools is a very real-world
developer skillset.

------
bandwitch
If you are interested in this post, you might want to have a look at an older
post on hackernews that gained some traction back then (see
[https://news.ycombinator.com/item?id=17134668](https://news.ycombinator.com/item?id=17134668)).
In contrast to this post, the aforementioned emulator was written in Java
instead of C.

------
userbinator
_This is one of the more unique aspects of my emulator; since most other Game
Boy emulators were written in an older C standard, (or an undesirable
alternative like C++), they didn 't have access to anonymous structs or
unions_

...unless you use MSVC, which has had that as an extension for a _very_ long
time (since MSVC6 at least.) I wonder if MS was the one who got that into C11.

~~~
xmkfkg
You got to be kidding! The MSVC impl is a incompatible incomplete joke and
everyone knows it. Even MS is investing more and more in llvm tooling because
of this.

~~~
int0x80
you can have anon structs an unions on gcc:

[https://gcc.gnu.org/onlinedocs/gcc/Unnamed-
Fields.html](https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html)

------
tnecniv
Honestly, writing a Game Boy emulator was the most instructive project I ever
did on how computers work. Probably learned more on that project than from my
OS and embedded systems classes combined.

------
samfriedman
>The Game Boy has eight 8 bit registers: A, B, C, D, E, F, H, and L

Why these letters? I'm assuming I, J and K are reserved for specific uses...
is G likewise?

~~~
mhink
It's less that other letters are reserved, and more that there are only eight
general-purpose registers, and four of them already have special meanings.

A is the accumulator, F is flags, and as the sibling comment mentioned, H and
L represent the high and low bytes of HL, which is the only 16-bit register
you can use for indirect memory access in most instructions. It's also used in
some control-flow instructions.

That leaves four remaining registers, which just so happen to fit perfectly
into the remaining space: B, C, D, and E. (They can also be accessed as BC and
DE with 16-bit instructions.)

------
sk1pper
> I used C11's anonymous structs and unions so that I could access individual
> registers, or grouped registers straight from the root structure:
> registers.a or registers.af for example.

That's excellent, when I wrote mine I wasn't aware of this feature and used a
kludge of macros to handle it instead.

------
bmurray7jhu
A usefull shortcut not highlighted in the article: Instead of implenting an
emulator for the LCD display hardware, the author simply peaked at the
frambuffer and dumped the contents.

For most target hardware, this shortcut provides a reasonable approximation of
the intended output image. However, some older hardware relied upon specific
characteristics of CRT displays to enhance the graphics. For example, some
clever developers found that they could create extra colors by swapping the
palate during the vertical blanking interval on interlaced NTSC video.

Of course, some of the earliest video game consoles don’t have a framebuffer
since RAM was to expensive. For these consoles, you will be stuck writing a
video display emulator.

------
earenndil
> The GameCube emulator I used for testing, gcube, doesn't support reading
> files from the memory card

Just curious, why use anything except dolphin for emulating gamecube?

