New Visual Boy Advance GX - with dynamic recompiler

  • Thread starter Thread starter Tantric
  • Start date Start date
  • Views Views 1,952
  • Replies Replies 17
  • Likes Likes 24

Tantric

Well-Known Member
Member
Joined
Feb 8, 2007
Messages
253
Reaction score
192
Trophies
1
XP
954
Country
Canada
I decided to give my VBA-M port some love - so I wrote a JIT thumb compiler for it. I didn't want to leave GameCube behind - so I've also written a whole new backend for handling paging (since GameCube only has 24MB of RAM). Note - I haven't put a ton of effort into tuning the JIT settings. They're not configurable from the front end but if anyone is interested they're not hard to find in the code. The main ones are - JIT_ARENA_SIZE, HASH_TABLE_SIZE, SMC_MAP_SIZE, JIT_TRACE_MAX_INSTRUCTIONS. I'd be interested to know if anyone finds better settings. With the settings I picked I've been able to get ~180fps out of the JIT headless (~25 MIPS vs ~5 MIPS in the C++ interpreter). There's a whole debug / profiling system I built to test with. This prompted me to stop tuning further since that already made 60fps (my target!) a lot easier.

With both of those in place I didn't want to leave things unpolished, so I rounded it out with cheat support, rewritten/reworked audio and new timing code. And before anyone tests and reports back that FPS jumps up and down slightly - my focus is on player experience not meeting some arbitrary benchmark. I notice more when audio skips than if a frame is skipped to keep the audio timing correct.

Enjoy!

Here's the full changelog:
  • Implemented a brand new Dynamic Recompilation (JIT) core for GBA games on both Wii and GameCube, built entirely from scratch. This is a from-the-ground-up addition, not a port - real GBA titles now run with plenty of headroom to
    run at full speed, well beyond what the interpreter core could sustain. Enable it from Settings > Emulation
  • Replaced GameCube's old ROM paging system with a new ARAM/SD hybrid virtual memory pager - ROM data now streams transparently from SD into ARAM and MEM1 on demand instead of needing to fit entirely in memory ahead of time, allowing the JIT to be possible (since it doesn't have to be aware of backing data location)
  • Rewritten memory management for both Wii/GameCube, freeing up 8MB+ for a JIT Cache, while still allowing 32MB ROMs
  • Added cheat code support for both GBA and GB/GBC games, using the Libretro .cht file format
  • GB/GBA audio is cleaner and truer to the original hardware, with one less resampling step - it is now generated natively at 48kHz - instead of upsampled from 44100Hz (GBA) and 22050Hz (GB)
  • Audio samples are now written directly into the output buffer with no intermediate mixing buffer in between, reducing audio latency
  • Smart dynamic audio rate control keeps playback speed correctly matched to real GBA hardware timing, with a stronger correction kicking in only when actually needed to avoid a dropout - this means fewer, less noticeable pitch adjustments during normal play
  • Buffer underruns (audio momentarily running dry) now fade smoothly to silence and back instead of producing a hard click, and startup/resume is primed to avoid an initial stutter
  • Reworked frameskip and frame pacing so video timing is smoother and more consistent, especially when the JIT core is running well above 60fps, and skipped frames are spaced more evenly instead of clumping
  • Added FPS display option
https://github.com/dborth/vbagx
 
I decided to give my VBA-M port some love - so I wrote a JIT thumb compiler for it. I didn't want to leave GameCube behind - so I've also written a whole new backend for handling paging (since GameCube only has 24MB of RAM). Note - I haven't put a ton of effort into tuning the JIT settings. They're not configurable from the front end but if anyone is interested they're not hard to find in the code. The main ones are - JIT_ARENA_SIZE, HASH_TABLE_SIZE, SMC_MAP_SIZE, JIT_TRACE_MAX_INSTRUCTIONS. I'd be interested to know if anyone finds better settings. With the settings I picked I've been able to get ~180fps out of the JIT headless (~25 MIPS vs ~5 MIPS in the C++ interpreter). There's a whole debug / profiling system I built to test with. This prompted me to stop tuning further since that already made 60fps (my target!) a lot easier.

With both of those in place I didn't want to leave things unpolished, so I rounded it out with cheat support, rewritten/reworked audio and new timing code. And before anyone tests and reports back that FPS jumps up and down slightly - my focus is on player experience not meeting some arbitrary benchmark. I notice more when audio skips than if a frame is skipped to keep the audio timing correct.

Enjoy!

Here's the full changelog:
  • Implemented a brand new Dynamic Recompilation (JIT) core for GBA games on both Wii and GameCube, built entirely from scratch. This is a from-the-ground-up addition, not a port - real GBA titles now run with plenty of headroom to
    run at full speed, well beyond what the interpreter core could sustain. Enable it from Settings > Emulation
  • Replaced GameCube's old ROM paging system with a new ARAM/SD hybrid virtual memory pager - ROM data now streams transparently from SD into ARAM and MEM1 on demand instead of needing to fit entirely in memory ahead of time, allowing the JIT to be possible (since it doesn't have to be aware of backing data location)
  • Rewritten memory management for both Wii/GameCube, freeing up 8MB+ for a JIT Cache, while still allowing 32MB ROMs
  • Added cheat code support for both GBA and GB/GBC games, using the Libretro .cht file format
  • GB/GBA audio is cleaner and truer to the original hardware, with one less resampling step - it is now generated natively at 48kHz - instead of upsampled from 44100Hz (GBA) and 22050Hz (GB)
  • Audio samples are now written directly into the output buffer with no intermediate mixing buffer in between, reducing audio latency
  • Smart dynamic audio rate control keeps playback speed correctly matched to real GBA hardware timing, with a stronger correction kicking in only when actually needed to avoid a dropout - this means fewer, less noticeable pitch adjustments during normal play
  • Buffer underruns (audio momentarily running dry) now fade smoothly to silence and back instead of producing a hard click, and startup/resume is primed to avoid an initial stutter
  • Reworked frameskip and frame pacing so video timing is smoother and more consistent, especially when the JIT core is running well above 60fps, and skipped frames are spaced more evenly instead of clumping
  • Added FPS display option
https://github.com/dborth/vbagx
Good 'ole VBA-GX is back too. :grog:
 
Wow, i wanna check this out, but i think i am sticking with GB/GBC with this one.
Post automatically merged:

I decided to give my VBA-M port some love - so I wrote a JIT thumb compiler for it. I didn't want to leave GameCube behind - so I've also written a whole new backend for handling paging (since GameCube only has 24MB of RAM). Note - I haven't put a ton of effort into tuning the JIT settings. They're not configurable from the front end but if anyone is interested they're not hard to find in the code. The main ones are - JIT_ARENA_SIZE, HASH_TABLE_SIZE, SMC_MAP_SIZE, JIT_TRACE_MAX_INSTRUCTIONS. I'd be interested to know if anyone finds better settings. With the settings I picked I've been able to get ~180fps out of the JIT headless (~25 MIPS vs ~5 MIPS in the C++ interpreter). There's a whole debug / profiling system I built to test with. This prompted me to stop tuning further since that already made 60fps (my target!) a lot easier.

With both of those in place I didn't want to leave things unpolished, so I rounded it out with cheat support, rewritten/reworked audio and new timing code. And before anyone tests and reports back that FPS jumps up and down slightly - my focus is on player experience not meeting some arbitrary benchmark. I notice more when audio skips than if a frame is skipped to keep the audio timing correct.

Enjoy!

Here's the full changelog:
  • Implemented a brand new Dynamic Recompilation (JIT) core for GBA games on both Wii and GameCube, built entirely from scratch. This is a from-the-ground-up addition, not a port - real GBA titles now run with plenty of headroom to
    run at full speed, well beyond what the interpreter core could sustain. Enable it from Settings > Emulation
  • Replaced GameCube's old ROM paging system with a new ARAM/SD hybrid virtual memory pager - ROM data now streams transparently from SD into ARAM and MEM1 on demand instead of needing to fit entirely in memory ahead of time, allowing the JIT to be possible (since it doesn't have to be aware of backing data location)
  • Rewritten memory management for both Wii/GameCube, freeing up 8MB+ for a JIT Cache, while still allowing 32MB ROMs
  • Added cheat code support for both GBA and GB/GBC games, using the Libretro .cht file format
  • GB/GBA audio is cleaner and truer to the original hardware, with one less resampling step - it is now generated natively at 48kHz - instead of upsampled from 44100Hz (GBA) and 22050Hz (GB)
  • Audio samples are now written directly into the output buffer with no intermediate mixing buffer in between, reducing audio latency
  • Smart dynamic audio rate control keeps playback speed correctly matched to real GBA hardware timing, with a stronger correction kicking in only when actually needed to avoid a dropout - this means fewer, less noticeable pitch adjustments during normal play
  • Buffer underruns (audio momentarily running dry) now fade smoothly to silence and back instead of producing a hard click, and startup/resume is primed to avoid an initial stutter
  • Reworked frameskip and frame pacing so video timing is smoother and more consistent, especially when the JIT core is running well above 60fps, and skipped frames are spaced more evenly instead of clumping
  • Added FPS display option
https://github.com/dborth/vbagx

Hey yo man, can i add some suggestions? is it possible you can fix the uneven blurryness that happens when you try to scale GB & GBC into SGB dimensions? specially when you are using borders, i am aware that long ago you guys switch the horizontal display to 720 as opposed to 640, and that causes pixels to look wider and sharper with no shimmering issues even without bilinear sharp, but i kinda dont like the way it looks too wide.
Post automatically merged:

Hey, when i set up Borders from SGB game only to play at SGB dimensions, i keep gettin stack dumps,.
 
Last edited by MeXen,
I've never even tried that feature, so it's no wonder it's not working. I took a look though - that code needed a lot of love. I've released a new version and tested the borders out (sized to 256x224)
 
  • Like
Reactions: MeXen
Nice work. I was a little surprised VBA GX didn't run fullspeed on the GameCube when I tried it, I figured that it was more than powerful enough. Lack of JIT certainly explains a lot.
 
Nice work. I was a little surprised VBA GX didn't run fullspeed on the GameCube when I tried it, I figured that it was more than powerful enough. Lack of JIT certainly explains a lot.
VBA-M is just poorly engineered. mGBA is still faster despite not having a JIT, and is more accurate to boot.
 
  • Like
Reactions: radicalten
Yup, there's no question that mGBA is a better core. And yup, VBA-M is poorly engineered. As far as the actual experience playing games, the challenge for me was just to improve what was already there.

This is all that i want for GB/GBC, as long as it does play these titles well, i noticed that old VBAgx had issues with simpler games like Roger Rabbit and MEGAMANs I and II, this one doesnt.
 
Excellent Work!

On the topic of ARM to PPC Dynamic Recompilers, do you have an opinion on whether your JIT could be adapted to work for NDS or would that be outside of the realm of feasibility?

I ask because I recently ported the NooDS emulator to Wii (NooDS-Wii), but without a working JIT interpreter performance is predictably low (I attempted to write my own JIT, but it does not reach 180fps!--27fps was the highest it reached). Likewise, NooDS-Wii currently loads everything into MEM2 on startup (which is slow), perhaps utilizing the on demand data streaming method you described things could fit into MEM1 instead.

Thank you
 
yay this is fantastic! I've been using the heck out of it. i've always loved VBA-GX and this is an amazing improvement.

I'm in the middle of enjoying a Fire Emblem 6 Hard Mode playthrough -- I'm trying to get the true ending for the first time ever (you gotta be very careful to meet all the conditions). Thanks for this great emulator that lets me do that!

The overhead on GBA games lets me speed up during enemy phase etc. It could never do that before! Just awesome stuff.
 
Hi Team,
Great work, as much as I would love to spend some time on this one (and I did) I noticed that on v248 my HDD is recognized and on v302 it is no longer recognized, what could be wrong here?
 
Excellent Work!

On the topic of ARM to PPC Dynamic Recompilers, do you have an opinion on whether your JIT could be adapted to work for NDS or would that be outside of the realm of feasibility?

I ask because I recently ported the NooDS emulator to Wii (NooDS-Wii), but without a working JIT interpreter performance is predictably low (I attempted to write my own JIT, but it does not reach 180fps!--27fps was the highest it reached). Likewise, NooDS-Wii currently loads everything into MEM2 on startup (which is slow), perhaps utilizing the on demand data streaming method you described things could fit into MEM1 instead.

Thank you
It should work, I mean it's still some effort for sure - but of course it would work for the GBA side of NooDS (or any GBA emulator for that matter), and the thumb instruction set for DS is pretty similar. All it's doing is compiling to PPC. And the design itself is pretty portable. The way I built it, unsupported instructions cause it to bail and then they're handled by the interpreter, so once it's wired in you'd just be extending it it with more instructions. Your challenge is for DS-mode you'll want an ARM compiler too - on GBA 80%+ of the time is spent in thumb mode - so I realized from benchmarking I didn't even need to bother building a second JIT for ARM-mode. On DS it's roughly flipped - up to 80% could be spent in ARM-mode.
 
  • Like
Reactions: radicalten
Ty so much for the awesome tool! Made some modifications to the code for my WiiU (3.0.2, since the latest files on github give me some visual artifacts on the menus) and thought of sharing them.

Turbo mode was made a toggle, so that ON makes the turbo always active, and hardcoded 2 more buttons for the turbo: ZR and ZL, or R and L. Shoulder buttons for the GBA are defaulted to the pair of buttons not acting as turbo. I only intend to use this on my WiiU gamepad and WiiU pro controller, and it is working, so I can't vouch for the other controllers.

Both dols are here.
 

Site & Scene News