September 15th, 2020 posted by Jabo

I spent a large part of my emulation life building a NES emulator and playing games, however the original Gameboy has always been a favorite handheld for me. Through the years I've been asked if I would build emulators for other consoles, but the time and dedication to building a polished emulator makes it difficult to do more. Recently I decided to go through some of my old projects and remembered that I had written a relatively functional Gameboy emulator, come with me on a journey to rediscover this project.

Original Gameboy DMG-01 1989

Technical Details

On the surface it has a tiny 160x144 screen, a limited palette of green colors, and lacks that thunderous triangle audio channel that NES enjoys. However as I looked past the crude graphics I found many interesting features coming from the NES:

Sharp LR35902 CPU

 

A very accessible instruction set, inspired by the Z80, where source and destination registers are available with many opcodes, not to mention 16-bit registers for memory addressing. While you might be impressed with the 4 MHz clock rating, most of the opcodes are double the clock cycles of related processors such as the 6502. Here is an example snippet of code:

ld b, a

add a, a ; *2

add a, b ; *3

add a, a ; *6

Allows you to multiply the accumulator by 6 since the Gameboy had no multiply instruction.

PPU Windowing

 

Coming from the NES this was a really cool feature I came to appreciate. On the NES it's relatively annoying to provide a sub-menu or status menu area due to the fact that these are often stored separately from your main window, which is scrolling. Windowing provides the ability to overlay these layers natively so the game does not have to manipulate registers with pixel-precision in order to snap in a status area, or update the screen to paint a quick sub-menu.

Megaman II uses windowing in order to provide a status area on the bottom with player health.

This technique is more modern and far easier to program.

4-bit Waveform Audio

 

Having the ability to stream 4-bit PCM is quite an improvement from the NES. Waves are commonly used for digitized speech or to recreate the sound of real instruments, every retrogamer remembers the first time they heard something like this.

While there aren't any games I felt necessary to single out here, there is a great YouTube video with examples, and an article that tracked more games if you are interested in exploring.

Easier Memory Map

 

I definitely preferred dealing with the memory map in the Gameboy compared to the NES. It's nice to see a smaller screen reduced the entire memory map to fit into a 16-bit space, nicely done gentlemen. Here is a simplistic view of the address space:

0150-7FFF Cartridge ROM
8000-9FFF Video RAM

A000-BFFF Cartridge RAM

C000-DFFF Internal RAM

FE00-FE9F Sprite (OAM)

FF00-FF7F I/O Registers

The Gameboy included 8Kb RAM, where the NES had a smaller 2Kb RAM.

Scanline IRQ via LCDY

 

Being able to trigger an IRQ on a specific scanline allowed games to create special effects. While most consoles had this feature, it was a native feature to the Gameboy not implemented in cartridge hardware like the NES.

World Heroes 2 Jet triggers an IRQ to produce a drip effect for it's logo rendering.

Techniques like this were a common way of animating images to save storage.

Also worth a mention is the Timer IRQ capabilities in the Gameboy, which I can only assume was used to update music in some games, or for more advanced graphical effects.

Stereo Audio Mixer

 

While I did not have the opportunity to emulate audio on the Gameboy platform, I found it compelling that there is a register NR51 that allows the programmer to specify how each audio channel is mixed as stereo audio. Unfortunately the Gameboy included a single speaker, I can only assume there was not much motivation for developers to take advantage of this.

Emulation

Somewhere along my emulation adventures, around 2003, I got interested in Gameboy emulation. The platform has striking similarities to the NES in terms audio and graphics, so I can only assume I wanted to learn more about it. I never set out to create a fully featured emulator, there were plenty of those. Looking back on it almost 20 years later I was surprised by a few things about this project. First like many programmers I was slightly shaken by the code I wrote so long ago, but more importantly with a few hours of updating the DirectX code I was actually able to get some games running. From a technical perspective it uses an interpreter for the CPU and a scan-line renderer for the PPU, a pretty classical emulation setup.

I thought it would be fun to dig up the past a little bit and walk through some of my favorite games and see if the old code still works before I put it back in the closet for another lengthy amount of time.

Game Library

Perhaps the best part of the Gameboy was that the platform had longevity and enjoyed a vast library of games. In addition to offering games that appeared on the NES, the Gameboy often bridged a gap between the NES and SNES with more modern console ports such as Street Fighter 2, Mortal Kombat 2, King of the Fighters, and World Heroes Jet.

This combined with incredible exclusive titles such as Donkey Kong Land, Metroid 2, and Legend of Zelda Link's Awakening made the platform a viable alternative to playing games on a television.

As with any library of games, not every game was great, especially since anyone creating Gameboy titles started off with serious visual challenges, and a tighter budget for development. As a gamer the novelty of it being handheld often made it easier to overlook some serious flaws in games.

Final Thoughts

It's been a long time since I looked at not only the Gameboy platform, but also an emulator that I created so long ago. I'm not going to lie, this was a huge trip back in time for nostalgia, I really enjoyed getting back into this. I don't think I will be picking this project up any time soon, it's a very raw basic emulator that lacks polish and audio emulation. Not to mention that the games have not held up well over time.

I probably have other projects laying around I should go through.

June 19th, 2019 posted by Jabo

When I made the decision to introduce Jnes back to the Google Play store in early 2017, I knew that making it free to download and missing two years of Android platform changes would make it an uphill battle to provide a stable build of Jnes, but I didn't quite anticipate how much. The first decision to make was deprecating support finally for Gingerbread 2.3 and supporting Jelly Bean 4.1 and higher. Gingerbread was old, often single-core, and OpenGL never worked well there.

Removing this code simplified the platforms to test, but it didn't make up for the the amount of time spent with the Storage Access Framework. The SAF as it is called, was introduced in Android 4.4 KitKat as an alternative way to access storage compared to the standard Java File class. The idea being that by introducing another abstraction to files and folders based on a Uri, Android could provide better security and extend storage beyond the local file system to any provider. To me at least this didn't become usable for general purpose storage browsing until Android 5.0 Lollipop with the introduction of the ACTION_OPEN_DOCUMENT_TREE flag which allowed developers to make entire directories available to applications, like Jnes.

While I successfully ignored this for many years! It became obvious in 2018, when Google Play required developers to target newer versions of their SDK, that most newer phones were preventing access to the file system outside of the Storage Access Framework, which of course broke Jnes for Android. Over the course of more than two months, and a lot of frustrated users, I was able to switch over to the new storage framework. The rewrite was definitely worth it as the new storage framework, combined with new user experience on startup in Jnes made things much easier.

I'm happy to say that the Jnes release from April 2019 marked a stable chapter for Jnes on Android. If you gave Jnes a try previously and ran into problems I would suggest trying it out again, it may work better. Overall developing anything of significant quality for a mobile platform is a lot of work, I will be avoiding it for any projects I work on for personal enjoyment.

Lessons Learned

  • I didn't really ever think about how much storage access was there until I had to rewrite it all
  • If you need to support older phones you need two sets of storage code
  • The helper class for DocumentFile is generally not as easy to use as Java's traditional File class

  • SingleDocumentTree is missing functionality that you may need
  • Every storage provider may decide to just not implement some functionality
  • You can't rely on being able to parse the storage Uri, although most people rightfully try to

September 13th, 2011 posted by Jabo

I've decided to release a patch to 1.6 that includes the majority of the plugin fixes from Project64 1.7 beta, and take a step away from the project.

I began actively working on Project64 again earlier this year, and was disappointed at the state of things. After going over 5 years, with no end in sight, the beta project became a bit silly to many. Most of the original team has left for different reasons over the years, and the community on the site has faded.

At the same time, I felt it would be irresponsible to the legacy of the project to keep important bug fixes in the beta permanently; the donations seem to go into a black hole now anyway.

Looking back it's been longer than I would care to admit, so many great memories and new friends. First, I want to thank the people who donated over the years, this emulator was a decade of ambitious work, knowing that people appreciated it and showed it really did matter to the team. There are too many people to thank individually, but special thanks to Gent, RadeonUser, Witten, and Smiff - you guys pushed the project forward in too many ways to mention, and truly defined my experience working on the project with zilmar.

There was a forum thread at emutalk.net which may help answer any questions you might have, however it is now locked. There will not be any additional releases or source code so please do not ask. I am doing this independently of the project, it is not an official release.

Download

Project64 is a N64 emulator for Windows, originally released in 2005, that I worked on for many years following. For more information about this wonderful project visit the website.

Project64 1.6 package

Project64 1.6.1 update patch

What's New

Jabo's Plugins for Project64

DirectSound Audio Plugin:

  • Disney's Tarzan and Hydro Thunder (Midway) have audio now due to buffering changes

 

DirectInput Plugin

  • configuration dialog gamepad polling stops at first hit now properly

  • ported the polling order from 1.7 which should be more reliable

  • uses system keyboard names now

  • updated layout to be more like 1.7 changes

 

Direct3D8 Graphics Plugin:

  • bugfix: fixed a problem where the plugin could crash if it ran out of video memory

  • bugfix: fixed microcodes for Blast Corps, Body Harvest, O.D.T. (Or Die Trying), and Asteroids

  • 1080 Snowboarding: fixed europe region effects

  • 40 Winks: fixed strange texturing issue

  • Bakuretsu Muteki Bangaioh: sprite edges should look correct

  • Banjo-Tooie: fixed puzzle rendering and other regions

  • Cruisin USA: brake lights work

  • Dragon Sword: menu text drawing and scaling fixed

  • Dr. Mario: fixed background in versus mode

  • F-Zero X: fixed potential triangle overflow issue

  • GoldenEye 007: fixed calculations of sky triangles

  • Lego Racers: fixed players going out of sight

  • Mario Kart: fixed whomps in bowser castle

  • Mario Kart: racetrack frame buffer support

  • Legend of Zelda Ocarina of Time: end of game subscreen issues

  • Paperboy: fixed map drawing in game

  • Perfect Dark: fixed scanners

  • Disney's Tarzan: fixed butterfly and health meter

  • Vigilante 8: fixed some textures

  • Legend of Zelda Majora's Mask: fixed day transition borders and lens of truth in snow areas