What's new

Game Boy

Shonumi

EmuTalk Member
Probably nothing to do with LCDC status interrupts. I'm not detecting Aladdin or Tomb Raider setting up the flags in the LCDC register (Aladdin does set LY == LYC interrupts which I know I've done correctly with homebrew tests of my own). However, both games seem to forgo using the interrupts and constantly read the LCDC status register themselves. Looks to me like it is something to do with setting Bits 0-1 correctly at the right times. I'll investigate later.
 

RossIain

New member
Since implementing double speed I've have been having problems with Aladdin gameplay. The game starts correctly with the level music playing and all the backgrounds/sprites/etc. visible except Aladdin himself and the
game essentially softlocks as moving left or right, or attempting to pause the game does nothing (music still continues to play fine though).

ynrygEI.png


Weirdly enough modifying the cpu speed to x3 instead of x2 for double speed mode actually renders the gameplay correctly and eveything plays fine except for being too fast due to the speed
increase. So I'm wondering if my double speed implementation still possibly has a flaw somewhere.
GBGvDsF.png


Some games I'm also getting some weird horizontal bars. Noteably in the pink background in Rayman (top middle of screen). On the green floor below Lara and in green column in the middle of the screen in Tomb Raider.
On Link's Horse in the intro to Oracle Of Seasons.

joJ6C0o.png
mbEzUUt.png
OzxJogR.png


Pokemon Pinball also behaves strangely, the black and white credit screen and the title screen are completely black, and the selection screen for the red/blue stage is completely
pink with the stage selection outline appearing in black. The gameplay seems fine though. This game doesn't seem to use and hdma/gdma transfers, and runs in entirely in "single speed" mode.
Manually fixing the bg/sprite palettes to the values shown in the bgb vram viewer for the title screen gives the correct graphics on my emulator so it's definitely a palette issue. For some reason
the palettes in my emulator are all set to 0x00 in the intro and title, so I'm going to look into why they're being set like that.
G2GWB7r.png
jLsX7IS.png


edit: Managed to fix Pokemon Pinball, turns out that writing to the Sprite/Background palette index registers should also update the respective palette data register with the value of the index in palette memory. The menus in this game rely on this to set the palettes when ran on a Gameboy Color.

g5Eq56u.png
Ei0hIxE.png
 
Last edited:

Flerovium

Member
I've been working really hard the past three days to get proper audio and color support up and I'm almost finished!
EDIT: I currently have the Coincidence Interrupt disabled, because my implementation somehow creates bugs in Pokemon Gold / Silver
 
Last edited:

Shonumi

EmuTalk Member
Sounds like you're missing a few notes (bad recording?) but it's great that you've made so much progress. Keep it up! :)
 

Flerovium

Member
No, unfortunaly this is not the bad recording :( Notes get eaten randomly and I haven't exactly figured out, from where this problem arises. Either the emulators timing is off, or the audio library (in my case NAudio) is lagging, when running beside the emulator. But fortunaly I abstracted the audio code from the beginning. Therefore it shouldn't be too hard to exchange the library.

EDIT: The bug was in the audio library. I changed my code so that NAudio uses DirectSound and now it isn't lagging anymore! :)

EDIT2:
 
Last edited:

Shonumi

EmuTalk Member
Congratulations! For me, sound programming is always a challenge because I know very little about dealing with digital audio. I managed to do the GB/GBC just fine, and I've gotten the GBA mostly correct (more correct than wrong). It sounds like your audio is still a bit too slow. It plays all of the notes, but you'll notice audio-video desyncing during Pokemon Gold/Silver's intro (around the time Pikachu attacks Jigglypuff). I'm sure you know what to do, and it's really great to see someone working on their emulator again. Good luck!
 

Flerovium

Member
Thanks, good luck to you too! For myself I already was interested in audio (programming) for some time. And my big brother is a physics students which explained some of the elementary rules to me. The rest I did with the help of the internet and my own thoughts :p You're right it is a bit desynced sometimes but most time it's not noticeable therefore it doesn't annoy me too much.
 
Last edited:

Shonumi

EmuTalk Member
Have a look at these links ->
http://belogic.com/gba/channel4.shtml
http://gbdev.gg8.se/wiki/articles/Sound_Controller#Sound_Channel_4_-_Noise

The GBA's noise channel is the same as the GB/GBC's, just so you know. Essentially, the output frequency of the noise channel is

Code:
(524288.0 / DIVIDING_RATIO) / SHIFT_CLOCK

The dividing ratio is 0.5 for a 0, and 1.0, 2.0, 3.0 and so on for values of 1, 2, 3... The shift clock is basically 2 << (top 4 bits of NR42). This is the frequency you run the LSFR (i.e. times per second). The LSFR is basically a series XORing the first two values of a number (the 7 or 15 stages, that is to say, a variable holding a 7-bit or 15-bit value), shifting that number once to the right, then replacing the most significant bit of that number with the results of the XOR. The output of the noise channel itself is either ON or OFF, high or low. The ON state is determined if the least significant bit of 7-bit or 15-bit variable is 1. Otherwise, if the least significant bit is 0, the state is OFF.
 

Shonumi

EmuTalk Member
  Spoiler:
I've implemented double speed by halving the cycles passed to the sound and lcd which essentially makes the cpu and timers run twice as fast.

This has fixed a lot of graphical errors in games which use double speed. Rayman now manages to boot and play correctly.
2dJi3sD.png


However still having the same problem with Aladdin as well as multiple other games which give me the same distorted background effect.

Aladdin:
zLZ7Cfc.png
GJ3bCiz.png
wSKScjh.png
K2efe3Y.png


Tomb Raider Curse Of The Sword:
knsO91G.png
lCtYLCl.png


The New Addams Family Series:
YU3Yn0B.png
iGEgYX4.png


I'm having a hard time trying to figure out what's exactly causing this effect.

So I finally fixed this issue myself. I pinpointed down the cause specifically. Some undocumented crap with LCD timing -> https://github.com/shonumi/gbe-plus/commit/c878372d271439e093ce0347fc92a39050090680

One of these days I'm going to compile a list of all the things no one ever writes down about GB emulation (except maybe in source code). IMO, source code is only ever half of properly documenting something. You have to formally explain what's happening in the hardware.
 

Rüdiger

New member
During my holidays last october I picked up my emulator project again (hardware and software) and have since worked on it on and off during my free time.
The emulator still runs on the STM32F429 discovery board with a 180MHz ARM Cortex-M4 with 192+64KB RAM and 2MB flash, a 320x240 LCD and 8MB external RAM.
I added a carrier board with a STM32F103 that can read gb cartridges and SNES and Sega gamepads and optimized the emulator to run at reasonable speeds.
The board also has a MicroSD slot, audio amplifier, speaker, headphone jack, voltage regulators and a battery holder.
And the STM32F1 has a clock crystal and a coin cell for the RTC which I want to use for MBC3 emulation.

I replaced the horribly slow pixel-by-pixel renderer and got a nice ~3x speed up. Moving as much as possible into the internal RAM gave another ~3x speed up.
Only the cartridge ROM and the framebuffers remain in the external memory, as they are simply too large.

Some improvements to the CPU template code, some tweaks to the blitter and caching sprite lookups probably increased the frame rate by another 40-50%, which is enough to run (almost?) all gb games above 60fps, some even close to 100fps.
Color games are a different issue. Even with the fast dmg/sgb renderer, they don't reach more than 40-50fps. I guess the renderer is now so fast, that the additional CPU cycles in double speed mode have a noticeable impact. And adding back the gbc specifics to the renderer will likely make it even slower :down:

The graphic controller hardware has some useful features, including two independent layers with blending. The background layer is set to 144x160 and displays the game, while the foreground layer has 320x240 pixels and displays the SGB border and everything else. This also allows the border to overlap the game without special handling or additional overhead. It also does vsync with double buffering.

The STM32F1 has enough free pins to connect to a gb cartridge and still have some pins left for the gamepad and the SPI bus from the STM32F4.

The STM32F4 has a 12bit DAC that I use for sound. It has two channels, but unfortunalety one of the outputs is occupied by the LCD interface and so I'm limited to mono. It is connected to a TDA 7052A amplifier which drives a small speaker, similar to the one in the gameboy, and a headphone jack. I still have to write my own gb sound emulation, but the hardware side is fully operational and playback of raw data from the SD card works.

The board is either powered over USB or from 2x1.5V AA batteries with a 3V and a 5V step-up regulator. I had a 3.3V regulator module from China with abysmal efficiency, but even my self-build module only manages 60%-80% efficiency depending on the battery voltage. Measuring the exact currents and power consumption is not easy, but it seems that for low battery voltages I'm close to the maximum output current, where the efficiency drops significantly. I lowered the output voltage from 3.3V to 3V, which helped with the overall consumption but not too much in regard of efficiency.
 

Attachments

  • CIMG8697_s.JPG
    CIMG8697_s.JPG
    345.1 KB · Views: 563
  • CIMG8731_s.JPG
    CIMG8731_s.JPG
    485.8 KB · Views: 127

Shonumi

EmuTalk Member
I don't suppose anyone else is working on GB emulation at the moment are they? Currently I've been working on Serial I/O emulation. Finally got it to work, at least on the same host (same machine). Haven't tried it over a network, but it's cool to finally have this feature working :D
 

dparrott

New member
Hi all,

I'm hoping someone can give me a steer on implementing the HALT bug?

I have had a few attempts in my emulator at implementing this but based on the results of a halt_bug.gb test rom I found at https://github.com/retrio/gb-test-roms I cannot get it passing.

The closest I have got has the results reversed from those that appear to be expected in the test rom when I run it with BGB, I don't understand why I would have them the other way round and believe I must be missing a condition that triggers the bug.

I have the simplest implementation based on the IME flag, is this all that should trigger the bug or is it also based on interrupts being enabled in IE?

My current attempt just has a haltBug flag that is set to !IME when HALT is called, and in my step proc if haltBug is set then it reads and executes the opcode without incrementing PC.

The test output also raised another question, when reading the value of IE/IF are the unused bits returned as 1 or 0? The test in BGB appears to suggest that they return as 1 where as I have been storing IF ANDed with 0x1F and returning that so zero in the upper 3 bits. Should I be ORing with 0xE0 before reading?

Thanks
 

dparrott

New member
Forgive the self post but I thought I'd follow up.

I wonder is this another of those GameBoy issues where a few people have worked it out but it's not documented anywhere?

I have consulted some other emulators and the behaviour seems to be that if interrupts are disabled and there is a pending interrupt when the HALT instruction executes then the bug is triggered. From what I could find the docs only mention interrupts being disabled.

Implementing the above behaviour passes the halt_bug.gb and still passes the individual instructions tests from Blargg.

Hopefully this helps if others are trying to implement the same issue.

Cheers
 

]-[ D X

New member
Guys I already finished a chip8 emulator and thought about making the jump to GB
After reading a lot and learning a lot i think i have a pretty good footing to start shaping up the emulator. As i was writing the CPU i came across a weird opcode
At first i thought i understood what to do, but as i try to debug with lunar.gb i'm finding some weird stuff going on.

The problem

As i'm not concerned yet with memory banks I just loaded the whole rom in a 32K array of unsigned char type called tmemory[0x8000]
well overall this works, but then I encounter 0x32 LD (HL), A... All hell breaks loose... Allow me to explain at this point the value HL is 0xDFFF and this is correct as proven by BGB debugger, but if my understanding of the opcode is correct it means tMemory[HL] = register[A]... this however is actually weird.. as I'm modifyng address 57K, but my array is only 32K in lenght.

Am I misreading the way the opcode has to be implemented? Is there a problem on my variable lenght perhaps... my registers are 8 bit, combined registers are 16bit variables. I think i've exhausted my programming skills on this particular issue. I was trying to only use the pandocs and the gb opcode summary and not asking for help, but I'm really stumped on this one. Any help would be greatly appreciated.
 

mendus

New member
The ROM is only 0x8000 bytes but the gameboy's whole memory is larger. The virtual address 0xDFFF falls into Working RAM. The opcode LD (HL), A is loading the value of register A to the value at position 0x1FFF of the WRAM.

See this article for a clearer insight. http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Memory

I would also suggest splitting the memory in different arrays as specified in the article, so you can handle memory banking easier in the future, without the need of refactoring part of the code.

Hope this helps.
 

]-[ D X

New member
The ROM is only 0x8000 bytes but the gameboy's whole memory is larger. The virtual address 0xDFFF falls into Working RAM. The opcode LD (HL), A is loading the value of register A to the value at position 0x1FFF of the WRAM.

See this article for a clearer insight. http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Memory

I would also suggest splitting the memory in different arrays as specified in the article, so you can handle memory banking easier in the future, without the need of refactoring part of the code.

Hope this helps.

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

Thank you for your tips mendus :D
 
Last edited:

Top