What's new

Game Boy

ShizZy

Emulator Developer
Nice job on getting what you have gotten done so far. Try Asteroids, it doesn't use MBC and it runs fairly easily. You can also try Amida, Boxxle,Boulder Dash, Castelian, Motorcross Maniacs, and Missile Command. All are commercial games, and none of which use MBC.
 

truth2

New member
Oh.. Ok.. Thanks.

By the way I fixed a silly mistake in which I was accessing rom bank 0 even if trying to access rom bank 1 and now both tetris and othello work flawlessly*!
now i guess i need to either focus on mbc or on correct timing...

*no sound, of course. also probably incorrect timing, also all serial registers are completely unimplemented, which probably what makes tetris 2player crash when selected.
 
Last edited:

aprentice

Moderator
all i could get sound wise is pop and clicks in different frequencies, is the 16 samples in channel 3 per second? I'm using directsound, does anyone have any experiences in it? I know the buffer is circular, and i took that into account when writing to it.. I have my buffer size set to ~2kb, bits per sample to 8, and samples per second to 22050. Then i have it set to loop playback and every frame i mix the sound and write to the sound buffer. Am i not writing enough samples per second thus resulting in pops and clicks? I'm still confused about some aspects of sound but i understand more than what i started out with..
 

Dark Stalker

New member
aprentice said:
all i could get sound wise is pop and clicks in different frequencies, is the 16 samples in channel 3 per second? I'm using directsound, does anyone have any experiences in it? I know the buffer is circular, and i took that into account when writing to it.. I have my buffer size set to ~2kb, bits per sample to 8, and samples per second to 22050. Then i have it set to loop playback and every frame i mix the sound and write to the sound buffer. Am i not writing enough samples per second thus resulting in pops and clicks? I'm still confused about some aspects of sound but i understand more than what i started out with..
The 32 4-bit samples in ch3 are played back at a frequency between 1024 and 2097152 Hz (counting each sample), depending on the value of NR33 and NR34.

I think you should focus on ch2 first. You only need to emulate the frequency to get the melodies going, just keep the high samples at something like a value of 32, and the low ones at -32. The value of the frequency registers can be implemented as a down-counter, which increments a wave duty counter upon reaching 0/being reloaded. The wave duty counter in turn determines whether the sample should be high or low. You could simply dictate this to be 50% high/low for now, you'll be able to recognise melodies anyway. You'll also probably want to stick to mono sound for now, or you'll have to generate pairs of stereo samples.

What do you mean by "every frame"? The buffer will need more data at a rate of samplerate/(buffer_size*sample_size), but you'll have to generate samples at least as often as the values of the sound registers are changed if you want accuracy. Generating samples only when the sound buffer needs more data should still be enough to get "proof of concept" sound output however.

AFAIK DirectSound has a "play cursor" and a "write cursor" that move in parallel. You'll need to write to the area beyond the "write cursor"/before the "play cursor". I suppose you could always poll positions to determine how much has been played back, but I think it should be possible to set a callback-function that fills the buffer when needed (in a seperate thread), that's what I'm using in sdl. I hope someone that knows directsound can give some input here.


A mostly unrelated side note: Remeber that the sample rate needs to be at least twice as high as the frequency of the wave it's representing, which is why 44100 Hz is a popular rate (hearing has it's limit at around 22kHz waves).
 

ShizZy

Emulator Developer
Been working on mine like crazy over the weekend. I got a half assed sprite system implemented (no priorities, no limiting, crude flipping, slight glitching) but they work pretty well for now. I also reimplemented input similiar to how I did in the previous write up my emulator, but changed some things and now it works properly. It's much simpler than I expected it to be. Fixed a bunch of other bugs, and now Tetris, Amida, Space Command, and Asteroids are fully playable - and pretty much glitch-free. Also added support for the boot rom.

Still a lot doesn't work though. I havn't had any luck with mbc. I tried a sloppy mbc1 implementation, and I think had it setup right. But no games worked (tried Metroid, Super Mario Land, and Zelda). Maybe there are still too many bugs in my core? If anyone knows of any easy to emulate mbc1 games, or just some ones to try, please let me know. I'm pretty satisfied with my progress though, so I think I'll upload a build of my emu tonight and post it.

Regards
 

truth2

New member
Well I implemented MBC1 (and 2, 3 and 5, but never actually got the guts to test them) and here are my experiences: (I wonder if any of you had the same/similar problems before and could help me out or at least guess what part of the code the problem lies at:

Super mario land (it's a hack where you cannot die, but it works fine on VBA/bgb as far as I know) - game randomly crashes or resets. very odd..

metroid 2 - the menu works fine, the game seems to work fine, samus, enemies, screen scrolling and all (only advanced through 3 screens, through, was too scared to go on :p), but i decided to check out the ship at the beginning, and when jumping high from the ship, i noticed some weird graphic glitches (a 'line' from the ship was in the air above).

zelda - well i was only brave enough to go through the intro, the menu, and the first two screens of the game, but it seemed to work fine so far :). EDIT: well i just checked the map screen and the image on the bottom right that tells you what is in the location the cursor is pointing to, is showing garbage. Damn.

edit :

great greed - it doesn't boot up at all, stuck in a glorious loop of ff's

another edit, to shizzie :
my suggestion to you is to double check the mbc code and everything affected by it (memory access, etc.).
but then again, that's just what usually helps me due to my sloppy coding, dunno how you code :).
 
Last edited:

ShizZy

Emulator Developer
Wow... disabled P1 and Metroid 2 goes to the title screen! Strange, but I'm not complaining I guess. Must be buggers :p
 

aprentice

Moderator
Dark Stalker said:
The 32 4-bit samples in ch3 are played back at a frequency between 1024 and 2097152 Hz (counting each sample), depending on the value of NR33 and NR34.

I think you should focus on ch2 first. You only need to emulate the frequency to get the melodies going, just keep the high samples at something like a value of 32, and the low ones at -32. The value of the frequency registers can be implemented as a down-counter, which increments a wave duty counter upon reaching 0/being reloaded. The wave duty counter in turn determines whether the sample should be high or low. You could simply dictate this to be 50% high/low for now, you'll be able to recognise melodies anyway. You'll also probably want to stick to mono sound for now, or you'll have to generate pairs of stereo samples.

What do you mean by "every frame"? The buffer will need more data at a rate of samplerate/(buffer_size*sample_size), but you'll have to generate samples at least as often as the values of the sound registers are changed if you want accuracy. Generating samples only when the sound buffer needs more data should still be enough to get "proof of concept" sound output however.

AFAIK DirectSound has a "play cursor" and a "write cursor" that move in parallel. You'll need to write to the area beyond the "write cursor"/before the "play cursor". I suppose you could always poll positions to determine how much has been played back, but I think it should be possible to set a callback-function that fills the buffer when needed (in a seperate thread), that's what I'm using in sdl. I hope someone that knows directsound can give some input here.


A mostly unrelated side note: Remeber that the sample rate needs to be at least twice as high as the frequency of the wave it's representing, which is why 44100 Hz is a popular rate (hearing has it's limit at around 22kHz waves).

i already give samples for right and left speakers, i have a 64 byte buffer set up, 32 for left and 32 for right, i know it has a play cursor and theres a write cursor that you have created yourself to keep track of where you are in the buffer. What confuses me is how many samples do i need to generate to play a full second of audio, and how do i generate that many if channel 3 is only 16 bytes in lenght, do i just keep checking the gameboy sound buffer when i need more sound? and to detect if i need to fill the buffer again do i need to do if playpos < writepos?
 

ShizZy

Emulator Developer
MBC1 works great with Tetris 2

tetris2.jpg


(Having fun with the pallette, almost looks GBC :p)

EDIT:
Here is the latest build: NhesGMB0.20.1.exe.

Tetris 1 & 2, Asteroids, Space Command, Boulder Dash, and Amida all emulate perfectly, that I've tested. Not quite sure what else, MBC1 is somewhat working. Please try it and let me know what you think :)
 
Last edited:

Sagon

New member
Good work ShizZie! Here what i noticed while testing your emu:
1) Input doesn't work in Asteroids, and there are some glitches with sprites in demo mode.
2) In Bomb Jack only logo working, looks like some bugs still in your cpu.
3) Heiankyo Alien, Shangai, Sprite Demo, Space Demo doesn't work.
4) Tetris, Missle Command works fine.
In summary there are still many bugs in cpu, if you debug Space Demo, Sprite Demo, Heiankyo Alien and Bomb Jack you'll find most of the them (that's how i've killed my bugs =)) ), and when these games will work, it will be wise to debug Motocross Maniacs, this game uses almost full potential of gb cpu. Anyway keep it up!

BTW: How did you implement VSync, i still obscured with frameskip techniques.
 

ShizZy

Emulator Developer
Hey Sagon, thanks for giving it a try :) Sprite Demo and Space Demo both work when the boot rom is disabled. Same goes for other emulators, the boot rom sets the true values, and I'm assuming these demos weren't meant to be played on the actual hardware. Huge thanks for the tips, I'll work on the those today.

As for vsync... in DirectX it's really easy. In your Flip Buffer function, you add:
lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);

I believe you are using SDL, correct? In my SDL version, I added a hack for it. I know it's not the proper way to do it, but it works, so maybe it'll help you.

Code:
    // Count framerate & slow down emu, I call this every time the
    // screen is rendered
    void VIDEO::CountFrameRate()
    {
	/* fps counter */
        static int Last;
        const int Past = SDL_GetTicks() - Last;

        if(Past == 0)
            mFps = 1000;
        else
            mFps = (1000 / Past);
       
        Last = SDL_GetTicks();

	// Slow Down the Framerate if it is greater than 60
	// these values I just played with so it worked at the right speed in my emu,
	// they may need to be adjusted (the 60 and the 15).  
	if(mFps>60) SDL_Delay(mFps/15);
    }
 

Dark Stalker

New member
Good to see things loosening up a bit ShizZie, I'll give your emu a try the next time I'm on windows.

aprentice said:
i already give samples for right and left speakers, i have a 64 byte buffer set up, 32 for left and 32 for right, i know it has a play cursor and theres a write cursor that you have created yourself to keep track of where you are in the buffer. What confuses me is how many samples do i need to generate to play a full second of audio, and how do i generate that many if channel 3 is only 16 bytes in lenght, do i just keep checking the gameboy sound buffer when i need more sound? and to detect if i need to fill the buffer again do i need to do if playpos < writepos?
I was of the impression that the write cursor moves with the play cursor, always staying a little bit ahead of the play cursor, to signal from which point on it's safe to write new data to the buffer.

I guess you know this, but sample rate is given in samples pr second, so <sample rate> number of samples are needed for one second of audio (or twice that for stereo cycles depending on how you look at it).

Ch3's wave pattern is repeated over and over again on playback. It is usually used for making simple tones rather than sample based playback, which would require constantly writing new data to the wave pattern memory. The wave pattern memory may change whenever ch3 is not being played back. The number of samples you are supposed to generate pr ch3 sample, depends on the ratio between your sample rate and ch3's frequency.

The game boy can sort of be seen as having a sample rate of 2097152 Hz, you'll have to resample this to your output sample rate. A crude way to do this, is to generate one sample every 44100 Hz (or every 4194304/44100=~95.11 cpu cycle), based on the channels' current output state, assuming a sample rate of 44100 Hz. A better way is to accumulate all of the samples produced by the game boy over a period of 4194304/samplerate cpu cycles, and use the average as your generated sample (a simple box filter). Of course this is easily optimised by only generating samples when either the output buffer needs more data, or the value of a sound register is changed. To know what a channel is outputting, you'll need to keep counters for frequency, sweep, envelope, length counters etc, based on number of cpu cycles passed.
 

ShizZy

Emulator Developer
Went through each opcode by hand, didn't really find much (a couple of issues with the rotates where I was setting some bits wrong, but it didn't fix any games that I can see). I think the bugs are elsewhere... not memory handling, because you can disable most of that and many roms which should still work don't. Which basically leaves... STAT/LY/LYC/LCDC, DIV/Timers, and Interrupts. All of that is simple though, can't see where I could go wrong. I must be missing something :p
 

bcrew1375

New member
If you want some help, you can post your code. I can look through it for you and try and find some problems. Or, if you don't like other people fixing your problems, I could just give you some hints :p.
 

ShizZy

Emulator Developer
Big thanks, it's kind of stressing me out. I'll post my code when I get home today. You don't need to go crazy, but any help you can give me would be great.

Regards,
 

ShizZy

Emulator Developer
bcrew: check your PM's. I sent you the source, wasn't quite ready to post it publically here yet.
 

truth2

New member
what are those emulator test roms someone talked about before? what do they contain, and where can one get them (zophar's domain's dead, i think)
 

Top