What's new

Game Boy

ShizZy

Emulator Developer
pradipna: Nice work!
I hope you (and WingsORC) keep your projects up, its nice to see people working on new emulation projects & keeping the programming community active. Looking at this thread brings me back..
 

Drenn

New member
Hi, I've been slowly plugging away on a gameboy emulator since june. I've made a lot of progress but sound emulation is a very new thing to me. I've emulated the first 2 channels and they sound something like a piano player who always hits the adjacent key... I used SDL_audiospec while following codeslinger's master system sound code and I ended up with this:
Code:
	updateBufferCount += cycles;
	if (updateBufferCount >= updateBufferLimit)
	{
		if (bufferPosition < BUFFERSIZE)
			playbackBuffer[bufferPosition] = tone*3000;

		bufferPosition++;
		updateBufferCount = updateBufferLimit - updateBufferCount ;		
	}
where playbackBuffer is copied into the audio buffer in my SDL_audiospec's callback routine, and updateBufferLimit is the interval measured in clock cycles between the times that the tone is stored into playbackBuffer. The value calculated for updateBufferLimit should make playbackBuffer completely filled by the time SDL requests its audio buffer to be refilled, but it tends to vary. When bufferPosition < BUFFERSIZE equals false, the tone doesn't get put into the playbackBuffer since the array has been filled already, and this seems to happen too often, which I believe is what makes the music sound sloppy.
If there is any better way to program this, I'd love to know, since I've never done anything like this before. Maybe something other than SDL would work better, or I could just be doing it wrong...
 

pradipna

New member
I don't have any experience with SDL so I can't really help you on that. I am using xAudio2. The way I am emulating channel 1 and 2 is like this, I have created 4 buffers with different wave duty (12.5%, 25%, 50% and 75%). When game wants to play sound from channel 1 or 2, I just copy the required wave duty buffer to xAudio source buffer and loop it infinitely at given frequency. And stop it according to sound length register, or sweep frequency overflows etc etc...
 

ShizZy

Emulator Developer
Drenn,

Have you checked out:

http://slack.net/~ant/libs/audio.html#Blip_Buffer

Blip_Buffer implements an efficient band-limited sound buffer for high-quality emulation of sound chips. After setting the source clock rate and output sample rate, sound waves are made by specifying the time points where amplitude changes occur.

It's written using SDL, and really helpful for audio emulation of older systems. Blargg also has a really simple example of the Game Boy PAPU sound chip emulator, written in C/SDL (if you're feeling less adventurous).
 

Drenn

New member
Thanks for replying :)
As it turns out,
Code:
updateBufferCount = updateBufferLimit - updateBufferCount ;
should have been
Code:
 updateBufferCount = updateBufferCount - updateBufferLimit;
An honest mistake :)
It sounds loads better now, just a little... how to say... unclean? Not as crisp as it should be. Blip Buffer sounds perfect for an emulator, I'll probably use that when I'm feeling less lazy. For now I'm happy with the result, I just need to emulate sweep and noise. I may be back to ask about the details of sweep, since my previous attempt at emulating that ended badly.

Edit - gah, now the frequency for channel 3 sounds too low in some cases, like the intro in mario deluxe. Screw it, I'll use blip_buffer!
 
Last edited:

Drenn

New member
I am SO close... it sounds nearly perfect, like a real gameboy... except that channel 3 has an annoying tendancy to be a little bit off-tune sometimes. It completely wrecks a few songs :(

Weirdly, for channel 3 the pandocs say:
Code:
Frequency = 65536/(2048-x) Hz

but the value that works for me is

Code:
frequency = (65536/(2048-x)*32) Hz

Does anyone else have this? Could this be screwing up the frequency just slightly? It's driving me crazy!

Edit - Ohh, the 32 is for the 32 samples. Still, the off-tune channel 3 remains at large... here's my code:
Code:
	// Channel 3
	if (chanOn[2])
	{
		static double polarity[] = { -1, -0.8667, -0.7334, -0.6, -0.4668, -0.3335, -0.2, -0.067, 0.0664, 0.2, 0.333, 0.4668, 0.6, 0.7334, 0.8667, 1  } ;
		if (chanVol[2] != 0)
		{
			// Read the sample from ram
			int wavTone = ioRam[0x30+(chan3WavPos/2)];
			wavTone = chan3WavPos%2? wavTone&0xF : wavTone>>4;

			// Add the sample to the output
			if (chanToOut1[2])
				toneSO1 += (polarity[wavTone])*(0xF >> (chanVol[2]-1));
			if (chanToOut2[2])
				toneSO2 += (polarity[wavTone])*(0xF >> (chanVol[2]-1));
		}
		chanPolarityCounter[2] -= cycles;
		// Update polarity
		if (chanPolarityCounter[2] <= 0)
		{
			chanPolarityCounter[2] = clockSpeed/(65536/(2048-chanFreq[2])*32);

			chan3WavPos++;
			if (chan3WavPos >= 32)
				chan3WavPos = 0;
		}


		// Check that it hasn't timed out
		if (chanUseLen[2])
		{
			chanLenCounter[2] -= cycles;
			if (chanLenCounter[2] <= 0)
			{
				chanOn[2] = 0;
				chanPolarityCounter[2] = 0;
				clearChan3();
			}
		}
	}

Sorry for the mess. It's possible the error's not in there, but unlikely. It's the only channel giving me problems.
 
Last edited:

pradipna

New member
Ok, I have finally decided to release the new version of my emulator. Here's a feature list:

Features:
---------------------
-> Can emulate GameBoy and GameBoy Color hardware.
-> Sound Emulation (excluding Vin output)
-> Keyboard and JoyPad input support.
-> MBC1, MBC2, MBC3 and MBC5 support.
-> Real Time Clock emulated.
-> Battery Pack support. Save format is compatible with VBA-M.
-> Save State
-> VisualBoy inspired Turbo Button. Press Space to speed up the game.

I have increased the compatibility too. I am going to keep this project aside for now and work on a new one.
If anyone's interested, download it from here: http://www.pradsprojects.com/dinoboy.html
 

HyperHacker

Raving Lunatic
I've been working on a GB emu recently. I've got Tetris and Super Mario Land working great. Now I'm trying out Blargg's tests... It's telling me my "ADD SP,n" and "LD HL,SP+n" are broken somehow, but it doesn't say what the problem is, and I can't find it. Does adding to SP affect flags differently or something?

I tried copying what VBA does, but it doesn't seem to have helped. (I didn't even check if VBA passes that test either... >.>) bgb passes all the tests, but its source doesn't seem to be available.
 

WingsORC

New member
Hi guys just wanted to drop by to tell you that im still working /programming emulators. Several months ago i started off with a chip-8 emulator then i moved on to a gb emu. Meanwhile I also worked a lil bit on a NES emulator and now I am back again :). I learned a lot about emulation (escpecially about sound emulation and dsp), considering i didnt konw anything about it when i started off. Recently i looked at my (unfinished) gb emu source code and I noted that it sucks. Well hereby i shall start again with a complete rewrite of my gb emu! I hope there are still some guys here working on emulators, because its rly fun and gives u a great insight into those fascinating machines.
 

ShizZy

Emulator Developer
Hi WingsORC,

I know the feeling :) You learn so much writing emulators that you quickly deprecate your own code. The same thing happened to me when I started by GB emu, and it still happens with more advanced projects. Moral of the story: If you've learned enough to realize how you could have done a simple thing better, you've probably grown enough to move on to a more advanced emu project. I'd recommend just diving into a more complex system, you'll learn more that way then by rewriting your other projects.
 

WingsORC

New member
ok, well i in the last few days i wanted to give my gb emu a finishing touch before i would follow your advice to move on to a more difficult project (any recommandations?). But i before that i have to resolve one more problem.
Games which scroll a lot have a sometimes a weird scanline drawing but. Some scanlines seems to shift by one pixel right, left, up or down (depending on scrolling direction) while drawing the screen. And this scanlineshift goes like a wave through the screen. Happens with super mario land 1 2 3 , metroid II etc.

ht tp://img6.image shack.us/img6/5994/gbirqtiming.png //remove spaces, how to post pictures properly?
This picture is extremly outdated but the vblank timing is still the same
Vblank seems to be off even though i verified the frequency of my timer (and it is correct) and the number of cpu cycles a screen refresh takes (70224). Any ideas?¨

EDIT:
Ok guys i could fix the scanline glitch. It was simple vertical tearing... so i just synched the screen refresh with the gb vblank interrupt. But the problem with the timer still remains.
 
Last edited:

ShizZy

Emulator Developer
Well, people say the next logical step from gb is nes... because its more involved but very doable. But imo nes isn't more of a challenge than gb, but just more frusterating/time consuming :D. Getting a nes emu to boot will be very easy for you, but so many games are very sensitive to timing/accuracy that most people start them to learn then give up because they aren't learning much new. I'd say do a system that's more interesting to you/newer...
 

WingsORC

New member
but just more frusterating/time consuming
:D well i can approve of that because i already wrote a nes emu :p. Cpu is quite accurate (luckily NES community has a lot of testroms) but well graphic is glitchy as hell. It runs a few games but to get more games running withought extensive hacks oh my... Like battletoads, your off by one 1 cycle and the screen starts shacking weird etc... So id rather not go back to the nes
 
Last edited:

Helius

Capsule Corp.
It's been a long time since I last posted here... 6 years methinks :)

That time I was struggling with my Gameboy emulator written in C# and finally abandoned it.

And for the sake of completeness I just wanted to say that I'm now finishing it! :blush:

Some weeks ago I decided to give it another try, this time in C++ in order to run it on Windows, Linux, Mac and iOS...

Well, this is the result, it needs more work and lacks sound, but is compatible whith most roms.

You can see all the progress and source code in my github repository: https://github.com/drhelius/Gearboy

Cheers!
 

roig

New member
Hello! Fast noob question... Which is the correct implementation?

I have SP = 0xFFFE

If I push a value to the stack it will
A) first decrement SP and then save the value to 0xFFFD
or
B) Save the value to 0xFFFE and decrement SP

??

Thanks :D
 

Helius

Capsule Corp.
A is correct.

Code:
void Processor::StackPush(SixteenBitRegister* reg)
{
    SP.Decrement();
    m_pMemory->Write(SP.GetValue(), reg->GetHigh());
    SP.Decrement();
    m_pMemory->Write(SP.GetValue(), reg->GetLow());
}
 

djh

New member
Not sure if this post is still active but I'm working on a GB emulator too. I'm aiming to get a gameboy color emulator going but I've not implemented any GBC features as of yet.

Anyway just wanted to say that after much toil I've managed to get the boot rom working, which is quite an achievement for me as I never thought I would get this far!

boot.png


Next step is to get some games working (the hard part :))
 

Top