• Updated 2023-07-12: Hello, Guest! Welcome back, and be sure to check out this follow-up post about our outage a week or so ago.

gb6: game boy emulator for System 6

Tekk

Active member
This is a very unfinished project I started a long time ago but recently picked back up - a Game Boy emulator targeting System 6 with the (impractical?) goal of running at a playable speed on an unmodified Mac Plus. Today I managed to get to a milestone: it displays something on the screen.

Screen Shot 2022-07-20 at 7.14.13 PM.png

I also created a OpenGL/ImGui-based UI to use on my modern laptop for enhanced iteration speed and less crashiness:

Screen Shot 2022-07-20 at 1.04.06 PM.png

It is SLOW. I haven't tried it on my real Mac Plus yet, but on Mini vMac set to 1x speed, it takes around 90 seconds to get to the Tetris title screen, with rendering turned off and not even calling WaitNextEvent - i.e. basically just:

C:
while (1) {
    step emulation;
    if (at title screen) {
        render output once;
        break;
    }
}

With Mini vMac set to "all out" speed and rendering/event handling turned on, it gets there in a few seconds. I knew it would be slow, but I didn't expect it to be this slow. There is still a lot of optimization I can do - for example, rendering directly into a 1bpp bitmap instead of using a one-byte-per-pixel array and copying everything down to 1bpp. My CPU code also has a lot of layers of function calls and I imagine the call/return overhead is actually significant on a machine this slow. I need to figure out how to do real profiling to see where the machine is spending all of its time. I think if I move the rendering into a vblank interrupt handler it might help.

The code is over on github if anyone is interested. I have been working on this pretty consistently recently and want to get it to a point where a few games are playable. I don't care too much about emulation accuracy, I just think this would be a neat program to have on 68k Mac. Even if it turns out to be impractical on a Plus, maybe it would be playable on a 68030?

I think once I implement the memory mapper chips for more complicated games and implement the LCD scroll registers and sprites, it will actually be useful. I will post any significant updates here!
 

Byrd

Well-known member
A gameboy emulator for System 6 in 2022? Yes please, I wouldn't say no. Can you focus on the 16Mhz '030 for playable speeds as found in a SE/30 and Classic II? Most people that tend to own a compact Mac in their collection have an SE/30 lying around and having the army of GG games to play would be amazing.
 

sfiera

Well-known member
This is cool, but do keep in mind what you’re up against! The Game Boy executes instructions at 1 MHz and the Plus at 8 MHz, so full speed would mean executing cpu_step() in well under 8 cycles (to leave room for the PPU and sound). It would be nice to see it running playable games, whatever the target machine.
 

Tekk

Active member
This is cool, but do keep in mind what you’re up against! The Game Boy executes instructions at 1 MHz and the Plus at 8 MHz, so full speed would mean executing cpu_step() in well under 8 cycles (to leave room for the PPU and sound). It would be nice to see it running playable games, whatever the target machine.
Yeah, not sure if that would be possible unless I do some crazy JIT thing where I recompile the game to 68k code and only use software emulation where instructions don’t match up. Just updating the emulated flags uses well over 8 cycles.
 

rjkucia

Well-known member
This looks great! Looking forward to seeing it progress & trying it out. I agree that targeting an '030 would have a good chance of being playable.
 

retrac

New member
This is cool, but do keep in mind what you’re up against! The Game Boy executes instructions at 1 MHz and the Plus at 8 MHz, so full speed would mean executing cpu_step() in well under 8 cycles (to leave room for the PPU and sound). It would be nice to see it running playable games, whatever the target machine.

The timing isn't quite that tight, but it is tight. I believe a full-speed emulator would be possible on the 68000 Macs, but the graphics couldn't be updated in real time and it would have to be some assembly.

Technically the GB CPU runs at 4 MHz but every instruction takes at least 4 cycles, and is timed in multiples of four, so some think of it as a 1 MHz processor. With a straight sequence of NOPs the GB CPU runs at 1 million instructions per second. But there are 2 and 3 byte instructions, and complex slow instructions. The 68000 is much more efficient per cycle.

Instruction decode can be very fast with such a simple CPU to emulate. Use the instruction byte and CB prefix flag, as a 9 bit pointer into a 64 KB jump table of 512 routines for each GB CPU opcode. I think that dispatch can be done in about 20 cycles on the 68000? Load masked into address register, then jump indirect. Many GB CPU instructions will have one or two instruction equivalents, leaving most of the table sparse (128 bytes per instruction available, you could jump out if you need more but I can't think any would).
 
Last edited:

Corgi

Well-known member
The Game Boy emulator I wrote with my friends a few years ago is only playable on a 600MHz G3, but then it's straight C with no asm. That in itself is an accomplishment, since it is also cycle-accurate. There are a number of hacks if you don't care about "pure" accuracy that should make it go much faster, but I've forgotten most of them in the intervening years 😅
 

rjkucia

Well-known member
I’ve tried GB68k on my SE/30, and it’s a very unpleasant experience. Games are really more slideshows than games.
 
Top