It's occurred to me recently that I got myself a bit backwards in having created a Gameboy emulator without ever having done some Gameboy programming myself. Now that I've lost interest in the emulator I figure I might as well see how quickly I can correct the discrepancy of never having written some software that could run on it. So, here's a record of my trials and tribulations in making something interesting. It's 6:24 on a Tuesday and if I'm not done by Friday evening I'll be dropping the whole affair.

7:35 - I finally have an ancient c toolchain set up and working. No float support should make my chosen project, a Mandelbrot set generator, a whole lot more interesting.
8:17 - Direct manipulation of the background layer now works with some not required sprite support.
2/06 - 5:39 - Too sick yesterday so it was a write off. Now it seems like my virtual box has somehow screwed itself up in the last 48 hours. Could be annoying.
5:48 - Never mind, just took forever to boot. First order of business is a layer for an emulated bitmap mode. Slower than writing tile by tile but much more convenient. Of course, the GB can only support 256 tiles which means I'll be able to bitmap a 16x16 block tile area of the screen.
6:22 - I'm using libraries for accessing VRAM because I assume it's faster. The problem is that the library function to read background tile data appears to be unavailable to the compiler and no definition is provided in the header file. It's pretty easy to find the implementation in other library files and the assembly looks reasonable to me so I can add in the declaration and we're compiling again.
7:36 - Bitmap mode is now finished. Works like a dream and faster than I thought.
7:38 - So, the c compiler I'm using apparently doesn't have any support for float, or so compiler documentation from 2001 would have you believe. Maybe the switch to using SDCC as the compiler changed that. Let's find out.
7:57 - Yep, floats are broken. That's alright. If you've never hacked together fixed point on an extremely limited CPU then have you really ever lived?
9:21 - Well, more virtualbox annoyances. Getting negatives working in the fixed point routines is hard because you can't shift when it means you'll just destroy the 2s complement representation. Actually, it wasn't that it was hard. I was just an idiot and the Gameboy isn't the best system for easy debugging. Still, circle, drawn with fixed point arithmetic.
fixed point circle
9:53 - There was probably a less screwy method than making the fractional part of a number have it's own sign. Leads to some... interesting conventions. Not difficult to write, you just need to realise that if the whole part of a number is 2 then it's possible fractional range is [1.5,2.5).
11:26 - I really should have sat down and properly done the maths for these fixed point routines first. I think I've ironed out all the bugs now. You might notice that the circle is now a lot circlier.
circlier
3/06 - 6:09 - Bitchin, it's super slow but I don't care. now I just need to get scaling and moving the origin working.
first mandelbrot
7:04 - Well, now I understand the need for processor instructions for floating point operations. Hell, I'd settle for integer multiplication instructions. This program really chugs.
7:13 - Time for the hacks to get those beautiful shots I want. #noshame.
7:25 - Well, I'm done. See the obligatory Mandelbrot set at different scales at high resolutions.
high res mandelbrothigh res zoom

Ultimately, I think the fixed point bit depth wasn't enough but the emulation of multiplication already killed the speed of the program. A faster implementation would use native 8 bit types and use a series of flags or structured statements during mathematical operations. As it is, it's much simpler to overflow the allowed range in a larger datatype and then fix it. Of course, it's also slower. Ultimately, this has been an interesting project and a potent argument for powerful ALUs.

If you want to download the ROM then it's in the repo. I'd recommend you run on an emulator which can fast forward.