What's new

Game Boy

pradipna

New member
Write function does need to have some overhead, you need to check if it wants to write to ROM bank registers, RAM bank registers, LY, STAT, P1, DIV, Echo etc etc.
 
Last edited:

MelvoPR

New member
If you read my post again, you will notice I'm refering to intercepting every write that the cpu performs.

Example:
Opcode 0x77: Write contents of A to location in memory[(H << 8 )+ L]:
Now, you don't need an intermediary function for writing to a location in memory:
Code:
void WriteToMem(ushort location)
{
	// let's check where it wants to write:
	if(location == 0xFF44) // it wants to write to LY
	{
		// do stuff to handle a LY write
	} else if(location == 0xFF41) // it wants to write to STAT
	{
		// do stuff to handle a STAT write
	}
	// and so on, you get the idea....
}
This would create unnecesary overhead to each write and/or read performed.
You could simply write directly to a location, and then have a function that updates all necessary registers after a set number of cycles...

Hope you understand now. :)

Now, this doesn't really matter that much (Also, you'll not gain a lot of speed), I mean, most GB emu's are done as a learning experience, and don't care or focus about speed, so, this is just something to have in mind for future projects, since I've seen this on some emulators.
 

pradipna

New member
Yeah I understand what you say. :) But like you said, it won't have much performance impact. Also some register like, let's say LY register, needs to be reset as soon as it is written to, so waiting for some cycles and then checking won't be an option. Same goes for ROM and RAM bank registers, and most others.

Are you making an emulator too? Or have you already made one? I am doing lot's of debugging right now to increase the compatibility of my emu.
 

MelvoPR

New member
As far as emulators are concerned, I've only done CHIP8 and Space Invaders interpreter(similar CPU).
Then moved on to implementing a dynarec, since I've too, made them for the sole purpose of learning.

When you finish your GB emu, you can take the challenge of doing a dynarec too :)
I mean, moving from GB to NES/Master System, you will probably find you'll not learn much from what you already did with GB.
Heck, some people think Master System is easier than GB.


BTW, you can check my x86 Space Invaders dynarec in this thread:
http://www.emutalk.net/threads/52849-Space-Invaders-Recompiler

Exophase gave me nice info for further improvements, and I plan to implement some of them on my next dynarec (dead flag elimination is a must!)

I've made some improvements quickly after I released it, but didn't get to implement the complex features due to being useless effort on doing so on a core which an interpreter can emulate full speed even on very old systems...


Check the thread for further info :)

BTW, Good job getting that far already!

Hope to hear some sound from your emu soon :p
 

pradipna

New member
Oh yeah the sound. :p I haven't started it yet but I will start after I implement the CGB functions.

And thank you for the dynarec implementation. Exophase knows what he is talking about, his GBA emulator for PSP was the best. I will definitely learn dynarec after I complete this project.
You should start a GB emu with dynamic recompilation. :p That should be fun. :)
 

MelvoPR

New member
Yup, I agree. Exophase is a pretty good coder, even though, he sometimes do some strange things (Ex: abuse of #define), but what programmer doesn't do some erratic things anyway?

While a dynarec for GB wouldn't be bad, it would be more of the same...
So, I think I'm moving to something different than x86, would like to experiment with other architectures, maybe MIPS.
 

MelvoPR

New member
As far as I know, JPCSP is the most compatible one, and can run a lot of commercial games.
It lacks in speed, obviously.

I don't think it's possible to make a full speed emulator with decent compatibility with

today's computers. Even with the most optimized code, it's just too expensive.

How about PSP emulator then? :p

Nice joke lol, I don't posess enough skills for such a project, not to mention you can't do

it on your own, there are a lot of things on PSP. And even if I could start such a project,

I'm not really interested on it at the moment, given that it's very time consuming...
Yeah, PSP is definitely out of question.

Now, for a real project, it could be a GP32 :)
 

pradipna

New member
Haha.. Yeah, PSP would be very difficult. I've never heard of GP32 before.

Anyway, small update on my GB emu. I have made some progress and now most of the games (non color) work well. I still haven't implemented CGB feature since I am too busy increasing compatibility of my emu which is fairly good at this moment - more than 90%. :)

Here's what I've already done:

1. All CPU opcodes are implemented.
2. Non CGB graphics completed, except some priority issues which I haven't given much focus on.
3. All interrupts except Serial Interrupt has been implemented.
4. All I/O registers except sound registers and serial registers are taken care of.
5. MBC1, MBC2, MBC3 (no RTC yet) and MBC5 has been implemented.
6. Battery feature has been implemented which now means you can save game progress.


Here's a todo list:

1. CGB feature.
2. Real Time Clock (RTC) for MBC3
3. Sound registers
4. SGB feature (not sure if I will bother adding this feature though)


Here are some latest screenshots:

Legend of Zelda: Link's Awakening:

http://i2.photobucket.com/albums/y6/pradipna/OhBoy-Zelda1.jpg
http://i2.photobucket.com/albums/y6/pradipna/OhBoy-Zelda2.jpg

Pokemon Red: :p

http://i2.photobucket.com/albums/y6/pradipna/OhBoy-PokeRed2.jpg
http://i2.photobucket.com/albums/y6/pradipna/OhBoy-PokeRed1.jpg
 

pradipna

New member
Some games are just plain weird. They try to access memory bank that doesn't even exist. For example Final Fantasy Legends 2, when PC is $491A (I guess in ROM bank $E), it tries to write $8e to rom bank register at $4195. But it only has 16 banks...

Finished debugging my emu for today. Every game that I have with me in my computer are now playable in my emu. YAY!!! Now I can focus on CGB feature...
 

pradipna

New member
Finally got the CGB feature implemented. There are some glitches and I am sure my graphics code isn't 100% accurate. I haven't tested a whole lot of color games but out of those I have tested, some don't load at all. I have to check them tomorrow, it's almost 2:30am so I should get some sleep. Here are some latest picture from Legend of Zelda: Link's Awakening DX:

http://i2.photobucket.com/albums/y6/pradipna/OhBoy-Link1.jpg
http://i2.photobucket.com/albums/y6/pradipna/OhBoy-Link2.jpg
http://i2.photobucket.com/albums/y6/pradipna/OhBoy-Link3.jpg
http://i2.photobucket.com/albums/y6/pradipna/OhBoy-Link4.jpg
 

WingsORC

New member
hey guys just wanted to say that i started my GB emulator a few days ago.
Got nearly all CPU instructions by now and im trying to implement the interrupts now.
(its entierly written in java)
 

pradipna

New member
Good luck with your emulator.
I am doing sound emulation right now. Channel 2 is done and it works quite well but has some bugs and channel 1 is almost completed.
 

MelvoPR

New member
Just wanted to say that I have released my emulator as a beta version: http://www.pradsprojects.com/dinoboy.html
There is no sound emulation yet but I will emulate sound in next version...

Hi, nice to see you are still working on your emu!

I've took a quick glance over your code and this is what I've found you could very easily improve:

You should #define special memory locations. (Ex: #define MEM_LY 0x1F44)
So, it looks more readable.

Some sanity check on input.dat won't hurt.

Also, you can extract instruction registers from the opcode itself, so, your code doesn't look so bloated like on main.cpp

that is, to reduce redundancy:
Instead of this:
Code:
case 0x34: 
SWAP(H);
case 0x35:
SWAP(L);
Write this:
Code:
case 0x34: case 0x35: /* etc... */
SWAP(opcode >> offset); // you get the idea...

Also, it is good practice to use ++x instead of x++ when the temporary value is not needed. While this doesn't really matter for default data types, it does for custom data types (ex: objects).

There are other optimizations skipped that have been discussed earlier, but other than that, it looks good!

Keep up the good work :D
 

pradipna

New member
You should #define special memory locations. (Ex: #define MEM_LY 0x1F44)
So, it looks more readable.

Oh yeah, that should definitely be done. I was just being lazy before I guess.

Also, you can extract instruction registers from the opcode itself, so, your code doesn't look so bloated like on main.cpp

that is, to reduce redundancy:
Instead of this:
Code:
case 0x34: 
SWAP(H);
case 0x35:
SWAP(L);
Write this:
Code:
case 0x34: case 0x35: /* etc... */
SWAP(opcode >> offset); // you get the idea...

Ok but wouldn't extracting the register from the opcode have some performance issue. I mean, if I want to extract the registers from opcode of LD r, r', I would have extract the register r by "r = (opcode & 0x38) >> 3;" and then extract register r' by "r' = opcode & 7".
Then I would have point it to register something like this for both:

Code:
switch (r) {
case 0:
R = &B;
break;
case 1:
R = &C;

and so on...

}

Or I could put all registers in array instead of using switch case but still I think it will have some performance issue...

Also, it is good practice to use ++x instead of x++ when the temporary value is not needed. While this doesn't really matter for default data types, it does for custom data types (ex: objects).

Since I started programming I have always been using x++ so it kinda of hard to break that habit. *lame excuse :p* But I will try to use ++x more. haha

Thank you for your advice. :)
 
Last edited:

MelvoPR

New member
Yes, you could put registers on an array.
Performance impact would be very minimal (extracting the registers). However, code will be reduced significantly and look cleaner.
(Also, the primary aim of your emu isn't speed, as far as I know.)

Good luck on sound!
 

pradipna

New member
Sound is going well, I have finished emulating channel 1 and 2 and in some games it sounds almost perfect while in others it is very buggy. I am going to emulate channel 3 today...
 

WingsORC

New member
Hello guys, got a question:

i checked out a few gb emulators and saw that writing 0x03 to the LCD control register(FF40) seems to reset LY (Scanline thingy). Didnt find anything in the docs with which i could explaint that.

edit: its in the tetris ROM at PC 239 to 23B
 

pradipna

New member
Yes, writing 0x03 should indeed reset the value of LY register and it should also reset the value of Mode Flag in STAT register too. Actually writing any value with bit 7 turned off should do that since LCD stops working after that until it is restarted again by writing any value equal to or greater than 0x80 to LCDC Register...
 

Top