What's new

-

Cyberman

Moderator
Moderator
Hello
I thought it would be useful to open a thread for information exchange about programme gameboy advance emulators.
And there I go with my first question :D

I'm currently writing the function that decodes thumb instructions. Currently I have to approaches for executing and decoding those instructions:
1. Decode opcode information to an struct at corresponding decode stage of the pipeline and execute it with the information from the struct at execution stage.
This approach would strictly follow the rules of pipelining. Also this is my current approach
2. Do nothing at instruction corresponding decode stage and do both decoding and execution at the execution stage.

What do you think would be better for my emulator?

This is my current code:

Greetz Flerovium


  1. Its your emulator
  2. What are you trying to acomplish?

You can use this data in a number of ways.
For example you can run it through an interpretor for step by step execution
You could have a dynamic recompilor generate pointers to function calls.
You could have a quasi static recompilor generate intermediate data that can be used to generate code to run in the emulator with self modifying code detection.
Not sure how much memory you plan on using and each approach has different requirements.

Anyhow you should expiriment see what works best for what you want to do.

Cyb
 

Shonumi

EmuTalk Member
I think Flerovium was asking if it's strictly necessary to emulate the decoding stage as a separate stage (true to a real ARM processor) or if the decoding and execution stage can be lumped together.

In the end though, I don't think it matters. I emulate the pipeline stage-by-stage, but this is actually a matter of preference. It might be easier in your codebase to put the decoding and execution stages together, or you might want them separate to be explicit about how the emulator works. I have not delved too deeply into the GBA's ARM CPU, but ordinarily I would not expect the two approaches you listed to cause two different results.

Also, looks like you beat me to making this thread. :D In the spirit of the other emulator programming threads, I'll post some helpful links:

http://problemkaputt.de/gbatek.htm - GBATEK, the king of GBA and DS documentation
http://simplemachines.it/doc/arm_inst.pdf - Generic ARM instruction overview
http://www.gbadev.org/ - Demos, homebrew, tutorials and more
http://exophase.devzero.co.uk/armwrestler.zip - ARMWrestler, a test ROM for verifying the accuracy of ARM and THUMB instructions (like blargg's GB CPU tests).

Guess I should get back to work. I haven't touched my GBA emulator in a bit. Implementing ARM and THUMB instructions myself as a learning experience, but it's not exactly a fast learning experience you know.
 

Cyberman

Moderator
Moderator
I suppose I may have too stick this, (LOL).
The irony of the discussion regarding ARM emulation is it can be difficult to emulate an ARM on an ARM, as all instructions sets are not the same on the ARM.
For the GBA programmers often had 2 sets of code. A tight library that executed from the internal RAM that was almost purely tradional ARM code (mostly sound processing and things like JPEG DCT things)
and a set in Thumb mode which was executed from the ROM space. Slow stuff was kept in ROM space along with data. I was always facinated by how good a job they had done for what space they had.

Erstwhile some 'stuff' may be added too this thread by me if I get some time.

Cyb
 

Shonumi

EmuTalk Member
Spent a lot of time today working on ARM emulation (more so today than in days before). For the most part I have ARM.3 through ARM.5 done (Branches + Data Processing basically), and THUMB.1 and THUMB.2 done. I thought I'd tackle ARM first given how complex it is, but I seem to be shifting back to THUMB. THUMB really is reduced in scope, just like they say (not complaining, that makes it easy to implement :D) I think the bulk of the work one has to do with emulating the ARM instructions is with Data Processing and coming up with an efficient design for that. Everything else doesn't seem so bad after that. Big step up from a modified Z80 though.

Still some little nagging TODO stuff (like flushing the pipeline whenever an instruction manually changes the PC) but I'm really enjoying this, now that I've got a feel for how the GBA's CPU works. No timing implemented just yet (no need to, no code worth running can run). Long ways to go. We'll see where I am next weekend :)
 

Shonumi

EmuTalk Member
So, is any one working on anything? Been quite busy myself. I have made two small test ROMs with a focus on LCD emulation at the most basic level. Currently I have most of the THUMB instructions finished (just two more to implement) and I've got LCD emulation too. I'm aiming to make this emulator as cycle-accurate as I can, and everything runs on a per-pixel basis at the moment. I figured I'd share the test ROMs for anyone else interested in writing a GBA emulator for themselves. When I was making GB Enhanced, Imran Nazar gave a lot of little ROMs that demonstrated key concepts in action and was a good way to measure how well progress on one's own emulator was coming along. Hopefully I can do the same.

Stripes Demo #1 - Displays alternating black and white vertical bars on the screen. The file is called checkerboard, but I was too lazy to make a checkerboard pattern :p Later versions will actually have the checkerboard pattern by manipulating BG scrolling.

i9njdL7RLtWJX.png

checker_board_final.gba
Source Code

TV Test #1 - Displays colored stripes, similar to some of the old test patterns found on TVs. This is the first version, more will come to test even more aspects of the GBA LCD. For now, something simple.

ibkltFKaoJPDDw.png

tv_test_final.gba
Source Code

Hope this helps someone. Please note that this was all written by hand with a hex editor so the "source code" isn't something you can run through a compiler. They're more like super-detailed notes. They only detail the THUMB instructions. Each Test ROM runs in ARM mode for a few instructions just to switch to THUMB mode.

At any rate, I'm still a bit too far from being able to test commercial games, and I still need to get a Flash Cart to verify my own homebrew tests (these work in VBA-M and naturally my own WIP emulator though). Next up, more tests, more ARM7 emulation, and more tests :D
 

Shonumi

EmuTalk Member
Well, unless that assembler will attach a GBA ROM header and make sure the bytes are little-endian, there's still a lot to do to produce a functioning GBA ROM. An assembler dedicated for the GBA sounds better to me.

I have a little JavaScript that builds the code I need for several instructions. I just copy and paste the hex output into a hex editor. That's as close to an assembler as I get. You know me though, I do things with the bare minimum tools :p

I think I'll tackle interrupts next, at least the VBlank interrupt. We'll see how it goes.
 
Last edited:

Shonumi

EmuTalk Member
Code:
ldr r0, =0x080000E1

Oh, this is a problem for me when it comes to assemblers. To my knowledge, LDR (ARM.9) can either only use a 12-bit immediate value or a shifted register as the offset. The default value of R0 on the GBA (after exiting BIOS) is zero. So the assembler has to be doing something other than LDR to get a value of 0x080000E1 into R0; there's no way to get that value by just using the LDR instruction (as defined in ARM.9), especially since all other registers at this time are 0 except R14 and R15. I would guess that the assembler actually adds other instructions (MOVS and such) to the binary output so that the value of 0x080000E1 can be placed into R0 when LDR is called.

This is great for programming demos from the perspective that you do not really care what goes on, so long as in the end R0 holds the value of 0x080000E1, but when you are trying to develop a cycle-accurate emulator or you want to test specific behavior, it will be a major pain. Sure, it is convenient on one hand, but when you are trying to recreate a system as accurately as possible, assemblers obfuscate certain things like what I pointed out. Ideally, I need to know every input (yes, on a binary level) I'm feeding into my program to measure the output. It's not just a matter of printing or drawing things to the screen like the demos I posted above; it's important for verifying accurate CPU emulation.

Assemblers are good for "quick and dirty" work. I have no issues with that, but I'm very strict about details :p
 

Shonumi

EmuTalk Member
My bad, I completely forgot about loading from an address. I have not extensively gone over ARM.9, so ignore the above post.

But how does the assembler grab the word in .offset? When writing assembly by hand, you would first set a register as Rn (the base address) after loading 0x80000E1 into it. Now this is something that gets obfuscated.
 

ikeboy

New member
I'm trying to port some GBA emulator to rockbox. The target I have for testing is the Fuze+, which has a stmp3780 processor and a 454 MHz clock speed, which seemed enough for GBA.

I'd like a recommendation for which open-source GBA compilers it would be easiest to port. I know Gpsp was ported to Ipodlinux, which implies it might be easier to port in general.

Preferably, something written in C, so I don't have to re-write everything. I've found the Gpsp source code, although there seems to be several forks of it which aren't easy to find source code for. (Gpsp-J and others.)

I know how to code in C. I've never done any emulator work before, though. How long can I realistically expect it to take, and can anyone give me tips? What do I need to know about emulation for porting?
 

Shonumi

EmuTalk Member
So, any one else been working on their stuff? Flerovium? Well, there's been a flurry of work on my end recently. Super Dodge Ball Advance is basically the only thing that boots and displays something, only because I've focused on that exclusively for the time being:

iwDwHO2saJxNv.png
izaxUsWChy3QC.png


Sprites are not yet implemented (weekend project :)) and neither are timers or input. Hopefully the game will be mostly playable once that's added. Then I'll try to get other games running.
 

Shonumi

EmuTalk Member
Hey, that's great that you were able to work on it! If you have anything specific you want, I could make some more tests.

Currently I'm dealing with bugs, bugs, and more bugs. I have Super Dodge Ball Advance, Kirby: Nightmare in Dreamland, and Mega Man Battle Network 4: Blue Moon working to some extent. I can play around in all of them, but eventually errors prevent further gameplay. Bomberman Tournament boots, but it freezes for some reason, fixing this will be key since it seems to be the same kind of freeze I recently introduced as a regression (I bet it's when I changed the code that calculates the Overflow flag...) I really want to get Mega Man Zero to boot, that game's one of my favorites and a classic :)

Good luck with things on FakeBoyAdvance, nice name btw :D

EDIT: Hmm.. yeah, my new method of calculating the V flag sucks. The old implementation boots Bomberman Tournament just fine. The new one fails pretty hard and breaks other games. Back to the drawing board. But at least Bomberman Tournament goes in game (with bad graphics however...) but progress is progress. I've been trying to get this game to work for a week now, so I'm glad something is showing up now.

ibrwj4C0KWUBOV.png
ibgikML4YZ3WG3.png
ibtBNWuBWX3sUd.png


Goes in-game, but it draws a lot of nothing once the intro (pictured above) is finished. Maybe the data is there in VRAM but my LCD emulation isn't complete enough? It seems to work (pressing A goes through text, and I can start a new game if I just keep tapping Start). I'll have to investigate later. I have my eyes set on booting Final Fantasy Tactics Advance next. Looks this is one of the few games I've encountered so far that use DMA0 and DMA3. I only implemented DMA3, since that's what commonly used in most games.
 
Last edited:

Shonumi

EmuTalk Member
I figured it out. I was flipping some bits incorrectly. I read a portion of an ARM assembly book that had rules for the V Flag and basically described them as such

Addition

* Are MSBs of the Input and Operand different?
* Clear V Flag​

* Are the MSBs of the Input and Operand the same?
* Is the MSB of the Result the same as the MSBs of the Input and Operand?​
* Clear V Flag​
* Is the MSB of the Result different from the MSBs of the Input and Operand?​
* Set V Flag​

Subtration

* Are MSBs of the Input and Operand the same?
* Clear V Flag​

* Are the MSBs of the Input and Operand different?
* Is the MSB of the Result the same as the MSB of the Operand?​
* Set V Flag​
* Is the MSB of the Result different from the MSB of the Operand?​
* Clear V Flag​

I was reversing when to set or clear the V flag during addition. No more freezes :)
 

Shonumi

EmuTalk Member
Haven't tried to run any Pokemon game just yet. I'm pretty sure those games (like many Nintendo games on the GBA) use EEPROM. I found this out the hard way. Super Mario Advance won't boot without some form of EEPROM emulation. GBATEK isn't very clear on how this operates (at least it makes little sense when I last looked at it) but I'll handle that eventually.

I've been very busy these past few weeks (see my GitHub activity log :D) I want to have a lot of things done by the end of this year. This time next year, I want a lot of games to boot and play without issue. I'm definitely going faster than I was programming a GB/GBC emulator. Gotta go fast.

As for speed, most games (without limits) can run 110~130 FPS with my i5-2500K @ 3.8GHz. That's not really good, but for the time being, speed isn't a priority. Once things start working and games can play normally, I'll get back to optimizations.
 

Shonumi

EmuTalk Member
That's a pretty cool demo you made. I can run it without issues, so that's good. Perhaps we should both start making a collection of test ROMs for others. I've been focusing on getting commercial games to work, which is basically some of the most challenging forms of testing (that is to say, real-world code). I think I would like to make more test ROMs though since 1) it's fun :) and 2) it would be nice to have a comprehensive array of tests. I know there is ARMWrestler and another CPU test suite (google "cpu test by deadbody") but it would be great to have specific tests that work on all of the GBA's major features (DMAs, lots of LCD rendering features, input, memory read/writes).

I see your test ROM actually does some interesting things: you use the BG Palette #0, Color #0 (0x5000000-0x5000001) as the backdrop color to quickly fill the screen (smart move). You also have misaligned halfword writes during the draw function (the misaligned bits are ignored by the hardware, so it's no problem, but it's a neat trick) and you use your own "timer" as a delay. Rather than a sprite, you just write values to the BG map for animation. Good stuff all-around :D

Here's a list of what I have running. Apparently I boosted compatibility over the last couple of days.

Super Mario Advance: Displays something now (was a black screen). Complains about corrupted saves; EEPROM emulation necessary.
Advance Wars: Displays 1st frame of the game, freezes, then quits, which is an improvement (was a black screen).
Bomberman Tournament: Works fairly well, goes in-game, except a lot of sprites are invisible for some reason. Technically playable.
Kirby - Nightmare in Dreamland: Works very well. Few graphical glitches, most everything works except advanced LCD stuff, saving. Technically playable from start to finish (probably, if it didn't randomly crash, like most games).
Mega Man Battle Network 4 - Blue Moon: Works fairly well, goes in game. Prone to crashing when switching scenes, but otherwise seems playable. Text is weird, but that seems to be the only graphical glitch.
Super Dodgeball Advance - Works well. Plays just fine until a dodgeball match actually starts. Player sprites are completely glitched. Needs BIOS math functions (arctan2 and sqrt) to work properly.
Kingdom Hearts - Chain of Memories - Boots (to my surprise) and tries to start a new game, but instead goes into the game's Debug Mode (which you usually need cheats to do). Heavy graphical glitches and the main game won't start (stuck in debug mode). Better than a black screen
Riviera - The Promised Land - Works very well, until I try to start a new game. Keeps writing to unused memory and hangs after that. Before that, the intro works wonderfully with no issues.
Pokemon Fire Red - This game doesn't actually boot yet, but it looks like it needs timers (specifically, Timer 3), so if you want to play this game, implement Timer 3!
 

Shonumi

EmuTalk Member
Some ARMTDMI variants implement ARMv5, however, the GBA CPU is not one of them. One the other hand, the Nintendo DS does have an ARMv5 CPU (but it also has an ARM7TDMI as well). If you're like me and plan to go onto DS emulation after the GBA, then that's when you'll need to worry about ARMv5 (ARM9 support), but not immediately. So on the GBA, there is no such thing as BLX (since it's an ARM9 thing). Technically, the GBA is ARMv4T, for reference.

I think I'll work on a V-Blank test/demo that manipulates BG scrolling. I already made a simple test ROM that changes the BG color every V-Blank (which I'll share with you later) but I want something a bit more fancy. Hopefully it will go well. This should be fun though. :D
 

Shonumi

EmuTalk Member
I really haven't stopped working on my emulator (not once, not for a single day). I guess Github keeps me motivated to make at least 1 useful commit every day. As for my progress, most games boot and run with the only problem being graphical glitches (due to unimplemented LCD features, such a sprite scaling/rotation). Recently I got the Pokemon games (Ruby, Sapphire, Emerald, Fire Red, Leaf Green) to run. Just implemented FLASH ROM saving and loading as well, so I can fully play my version of Sapphire now :) The saves are also compatible with VBA-M. Basically, I just need to finish up more LCD emulation, then work on sound, and I should have a fully functional emulator on my hands. After that, I just need to increase the speed and accuracy.

Good luck with your work btw. I'll be watching your progress. It's alright to use the test ROMs. They're essentially Public Domain, so do whatever you want with them.

EDIT: For reference, I'll just cross-post the images I've already shared elsewhere of my current progress:

  Spoiler:

ibzOuB68Ehi5TD.png
i6eDt7VA9pOdy.png
i6CSHuxfxBCL5.png

ibpoYmtIWGmGcm.png
ibh7a4mWeM2IAf.png
iV5ChKn66J84p.png

iuz2MZnAuaGso.png
iPCj1Pum8Eptc.png
ibmzeObn386pvf.png

ib2DGKZR1dQos1.png
iIUvthf2w44Yb.png
ibtcEvdkLOTLkd.png

iVNAFphqaX1Ay.png
ibgaxXR6uXYvLz.png
ibgHEhUmurNBmu.png

ibkioR0GSGgXLx.png
isU2GtudGTiLF.png
ibdnMQ1loGG5Oy.png

inzfdrk5qj0Hg.png
igSCrkAGKEyZf.png
ihfOY3ajkJUr0.png

iQcPQBpseWvMZ.png
i43P2kxUDdsCv.png
i27BTyiMvPLeG.png

irEY1E3qHNyAP.png
iukWfZdTKoQVS.png
i0sXTZRhfFVIZ.png

ikwO94VtcgCvn.png
i8seuKxhCBlON.png
ivo27Yxk5jwzL.png



That's all the stuff I've done since mid-November. Didn't think I'd get this far this early. I took forever to get original Gameboy games working in my first attempt at an emulator, so I assumed I wouldn't get things running this well until May or something. By the way, the Pokemon Fire Red picture is from a randomized version where everything gets flipped around (based on TwitchPlaysFireRed from last year). That's why I'm fighting a lvl 2 Gengar :D
 
Last edited:

Shonumi

EmuTalk Member
What a coincidence, I was about to implement a decoding cache some time next week myself. I had already made a prototype months ago, but I never merged the code to my master branch. However, I only did it for instruction fetching in ROM, not RAM. Currently I'm looking for little design decisions to make CPU emulation faster, e.g. using switch statements when possible, using less branching C++, high-level stuff that the compiler really can't optimize.

My goal is to make it so that every game can at least run at 120 FPS on my computer. It's a 3.8 GHz i5-2500K, so if I can run the GBA @ 200%, any comparable computer (Sandy Bridge @ 1.9GHz). I'd like to think that my emulator is just being demanding like bsnes, but the truth is I need to optimize it a lot more ;)
 

Danny

Programmer | Moderator
Nice work guys. Nice to see emulation progress threads like these.
Keep it up.

PS: Gotta finish my Chip8 emulator... (just started), then I plan on stepping through the list in order: Chip8 > Space Invaders (emu) > GameBoy > NES > ?
We will see how the Chip8 and space invaders emu's go first however lol
 

Shonumi

EmuTalk Member
So, it's barely been a year since I started working on GBA emulation, but already I'm at the final steps of getting a fully functional emulator up and running. By functional, I mean just that, it'll run without exploding. The last major area to tackle is sound. The GBA basically copies the original GB sound very closely, so I'm reusing previous code I wrote for GB/GBC emulation. The real fun starts when I tackle the two digital FIFO audio channels. Hopefully by April, things will be more or less complete.
 

Top