What's new

Game Boy

Rüdiger

New member
Oh! to be honest I saw that article and also in every doc i´ve consulted they´ve splited the memory as a real gameboy hardware does it, but for the life of me I can´t figure how to manage the memory while decoding an opcode. I´ve been toying around with the idea of having a huge 64K array and assigning memory locations using if greater than, smaller than statements, but it feels like cheating... I guess i could rework my instructions template functions to include memory assignments on read and write

You won't get around some 'cheating' because not all locations in the address space behave the same. The MBCs for example are controlled by writing to addresses in the low 32K so you have to catch them and perform some actions instead of overwriting some of the ROM. Similarly, the region from 0xFF00 to 0xFF7F contains special hardware registers and for some of them you will want to trigger actions on access.
For example, writing to 0xFF46 will start a DMA transfer or 0xFF4D is used to switch between normal and double speed mode on the GBC.

I would suggest to put read/write in their own functions and do the special handling there, be it a cascade of if-statements or storing memory pointers and callback functions in a lookup table or whatever.
 
Last edited:

]-[ D X

New member
You won't get around some 'cheating' because not all locations in the address space behave the same. The MBCs for example are controlled by writing to addresses in the low 32K so you have to catch them and perform some actions instead of overwriting some of the ROM. Similarly, the region from 0xFF00 to 0xFF7F contains special hardware registers and for some of them you will want to trigger actions on access.
For example, writing to 0xFF46 will start a DMA transfer or 0xFF4D is used to switch between normal and double speed mode on the GBC.

I would suggest to put read/write in their own functions and do the special handling there, be it a cascade of if-statements or storing memory pointers and callback functions in a lookup table or whatever.

Thanks for the insight Rüdiger. As you both suggested now i have a working memory controller on it´s own function and so far is working great. Thanks for the support guys
 

mendus

New member
A question to the more experienced people on gameboy programming.

I started writing a GameBoy emulator around 2 years ago, but I left it at some point. I have just retaken the task and I'm refactoring the code trying to achieve the best interface possible in order to keep a clean and organized code.

Previously, I had implemented the opcodes by categories. For example, I had one function
Code:
_LD_r_s(int r, int s)
which handled all load instructions. The input variables worked as enums. This way, I avoided writing similar code many times.

This wasn't a problem while I was using a big switch in order to select the appropriate function to execute an operation, but when I tried to use pointers to functions I couldn't do it this way.

I would like to know your opinion on the cleanest way to implement the operations and make them run. I want the code to be as user friendly as possible. Not having to repeat code would be an extra, if this doesn't imply making the interface ugly. Have you experienced this problem while designing the interface?

I should probably mention that I have taken an object oriented approach (so I have MMU, CPU and GPU objects among others), and that not deviating from variables and methods would be best.
 

]-[ D X

New member
Sup! Finally started working on my Gameboy emulator, an upgrade from Chip8 (first emulation project) sadly i'm stuck on what it may seem... a really simple issue
I have a step debugger / dissembler to help me complete the CPU, but i'm now in that moment where i can't no longer sit there while i wait fro the step debuger to get stuck so i can capture the next instruction.. Why? Cause advancing one instruction at a time is painfully slow. So onto my question

How should i get around on implementing a real time execution timing? Should i just say... Each instruction takes this much time, add a bunch until i reach a given MHZ value?
The thing is... I'm using std::cout to get info for the debugger, so even if I mask the cycles under a for loop, it will trigger the same painfully slow process of waiting till the Opcode info has been shown (on each step) I know i should implement the whole CPU at once, but i'm so close to the fun stuff that is toying with the Vram, that i'm kinda looking for a workaround until i have to implement a more accurate Timer... Any ideas? I'm about to kill the debugger and try, sadly if i do that i won't know what opcode caused the crash... Any help will be appreciated :D

Self edit i could kill the debugger and log until two strings are the same... to last strings are the same...

2ennh1h.jpg
 
Last edited:

Shonumi

EmuTalk Member
but i'm now in that moment where i can't no longer sit there while i wait fro the step debuger to get stuck so i can capture the next instruction.. Why? Cause advancing one instruction at a time is painfully slow.
...
How should i get around on implementing a real time execution timing?

Breakpoints? In my debugger, I can set up breakpoints where program execution halts until the PC is a specified value. I have a "Continue" mode where normal emulation happens until the breakpoint is tripped (handy for actually playing a game until the breakpoint is tripped by certain actions). I also have a mode called "Print All" which displays each instruction and registers, but if "Print All" is disabled, only manually stepping through the debugger or breakpoints will display all that info.

I'd really recommend you implement breakpoints; then you can have your emu run until it hits a certain PC, and then you can inspect things. Also recommended (perhaps for later) is to have an option to launch the debugger at any time while the emulator is running, e.g. like BGB allows you to do. I have a hotkey that I press, and the emulator pauses and either a CLI or GUI debugger pops up. This is very helpful if you suspect your emulator is stuck in a loop, you can step through it on the spot.

I know i should implement the whole CPU at once, but i'm so close to the fun stuff that is toying with the Vram, that i'm kinda looking for a workaround until i have to implement a more accurate Timer...

Don't skimp on the CPU. Trust me, that's the one component you don't want to have in an incomplete state. Think of it this way, you wouldn't realistically try to drive a car without an engine. The CPU is at the heart of the Game Boy, and so it is with a Game Boy emulator. A lot of things don't work at all or as intended if the CPU isn't up to par. I know all about chasing after the "fun stuff" rather than getting all the nitty-gritty grunt work out of the way. Without that low-level CPU code, however, the "fun stuff" might end up a debugging headache.

Additionally, when you talk about "real time execution timing" you mean instruction timing? E.g. an instruction like DEC B takes 4 cycles. In that case, consider that part of working on the CPU. Game Boy CPU timings are pretty straightforward compared to other systems. Better to take care of it now rather than later.
 

]-[ D X

New member
Thanks man, really appreciate your answers and tips. AHahha it was so weird reading OLD me asking a dumb question on top of this same page... (Hopefully in a few years i will comeback and help someone and have a laugh again. This is my second attempt at a gameboy emulator. And I've matured a lot since then. Also! all those awesome and awful couts were destroying my performance. Implemented SDL, got rid of those couts and now it's crazy fast, plus I can shape the debugger as i see it fit.

I will tho', implement breakpoints as your idea sounds really handy
24pma2r.png

efrzp0.jpg

sadly i have to do most of the work on the go, so atm i'm just trying to accommodate to my small screen ahha so an SDL MessageBox will have to do for now. My approach for these debug message are pretty much alike than your BPs. I have every non linked instructions as a function that capture the next opcode and returns a text string describing that opcode. I have most of the CPU functions written already it just takes me a lot of time to link them :< Only 1 hour per day of a subway trip really early in the morning don't help much either haha


Btw I'll take care of timers right away then! Ty
 

MegaBoyEXE

New member
Hello, I've started my adventures in emulation a few days ago. I still didn't finished implementing all instructions and almost didn't touched PPU stuff yet.
The implemented instructions are enough to get blarggh's tests start running.

But it seems it entered a loop before even starting doing actual tests part. I'm grabbing the link port dbg prints as I don't have a LCD emulation yet, and it keeps looping forever printing the same test name over and over. I know this because I'm buffering the output before printing to console, and clearing right after.

My memory access has very basic stuff yet:
- does not write if address is < 0x8000
- link port dbg:
Code:
 if (aAddress == 0xFF02 && aValue == 0x81) { dbgStringBuilder.Append((char)Read8(0xFF01)); }

I tought it was related to register LY, so I added a scanline counter and resetting it when reaching 153 or if code tries to write to 0xFF44, but it seems to not have any effect. (Well, Tetris was looping before, and after LY counter it eventually broke out from the loop and reached some unimplemented instructions, so I know LY does works too)

So I got bored of not knowing if I was missing something and went reading from VRAM to learn how to draw tiles. The LCD does not work, I'm just reading the tileset and rendering tile by tile, completely unrelated to emu itself.

So, is there any other requirement to get blarggh's tests (the individual cpu_instrs ones) running besides instructions and simple memory? Because I don't know if there's actually an error in instructions or if it's just a part required that I'm not doing yet.
 
Last edited:

Danny

Programmer | Moderator
After completing another Chip8 Emulator to dust off the cobwebs.. I'm finally embarking on my GameBoy Emulation project :)

Hopefully there are others who are here working on them, otherwise it might be a lonely venture :/
 

dparrott

New member
*waves*

Not wanting to detract from the information that is presented here archived here, but another resource to use as well is the reddit /r/emudev slack, that has a pretty active #gmb channel among others.
 

Danny

Programmer | Moderator
*waves*

Not wanting to detract from the information that is presented here archived here, but another resource to use as well is the reddit /r/emudev slack, that has a pretty active #gmb channel among others.

Awesome!

How far along are you?

I currently have my skeleton code implemented, including the full opcode listing.

They're all just printing unimplemented opcode at the moment though.
 

dparrott

New member
Mine is running Rom only and MBC 1 games. Still fails many of mooneye-gb's tests though and has no sound emulated as yet.

Currently taking a break and looking at a master system emulator
 

Danny

Programmer | Moderator
Mine is running Rom only and MBC 1 games. Still fails many of mooneye-gb's tests though and has no sound emulated as yet.

Currently taking a break and looking at a master system emulator

Nice job! I'm in the early stages. Have about 170 opcodes implemented so far....

Have any screenshots for me, for inspiration? :)
 

Danny

Programmer | Moderator
Maybe you could write a how to?

You're still interested in making that emu Remote :D
I might just do that, once I get the system working in a more complete state (MBC1 (etc) support, controller support, sprites, sound etc).

Stay tuned :)
 

Remote

Active member
Moderator
You're still interested in making that emu Remote :D
I might just do that, once I get the system working in a more complete state (MBC1 (etc) support, controller support, sprites, sound etc).

Stay tuned :)

I'm learning C# atm. What language are you using?
 

Shonumi

EmuTalk Member
It's great to see this thread getting some more activity :) I'm still around here. Feel free to ask anything if anyone's curious.

I still work on a bunch of Game Boy emulation. This year in particular, been tackling a few GB things that have never been emulated by anyone. Currently working on a little something, atm. You'd be surprised how much of the Game Boy we haven't touched yet, even after all this time.

[MENTION=29773]Danny[/MENTION] - Keep up the good work! That debugging setup looks pretty sweet. Took me ages to get around to making a good GUI for mine.
 

Top