Arduboy 'Classic'!

Introducing, a prototype of what I am tentatively calling the ‘Arduboy Classic’ (with Kevin’s blessing?). Using an Arduino Leonardo (same ATmega32U4 microcontroller as the Arduboy), but with the screen, the buttons, the speaker, and the LED indicator all being provided by the front half of a classic Nintendo GameBoy!

Here’s a video of the prototype running some adapted Arduboy demos:

There are a few other components in the mix as well, an Arduino Nano (ATmega328) working as a sort of co-processor / LCD controller, and two other chips – a 2K dual-port RAM chip plus an 8-bit flip-flop which act together as a memory buffer between the Leonardo and the Nano. (And for the moment I’m also still using the GameBoy’s little power PCB to get the negative 20V required by the LCD.)

I had a breakout board made for the 21-pin connector which allows the ribbon cable from the GameBoy’s front daughterboard to connect straight into a breadboard for prototyping. And then started out with just the Nano and the daughterboard, working on hooking up all of the LCD’s control signals and getting something (anything!) to show up on the LCD – the awesome research into this by mARC at robotdialogs.com was a great foundation to be able to start from!

Once the Nano and the LCD were cooperating, I added in the Leonardo and started adapting the Arduboy libraries with the goal of feeding the Nano with some actual data to display on the LCD. Using the dual-port 2K FIFO (first-in, first-out) RAM as a middle-man means that there is no need for strict synchronisation between the Leonardo and the Nano – they can both be independently reading from / writing to the same memory without any conflicts, and once the Leonardo writes a frame into memory the Nano can keep reading that same frame until a new one is ready.

The second part of the memory buffer is a SN74HC374 8-bit flip-flop. Because each byte is only on the FIFO’s output pins for a brief moment, I added in this flip-flop to keep the data latched for longer so that the Nano can read in each byte straight off the pins without having to store anything in its own RAM. Another advantage of the flip-flop is that it has enough drive to defeat the RX / TX resistors on pins 0 and 1 of the Nano, which the FIFO alone cannot do and had me scratching my head for a while over unexpected vertical lines on the LCD!

The GameBoy speaker is driven directly from a single pin on the Leonardo, with a 220 Ohm resistor in series, and the GameBoy’s battery LED is connected to a PWM pin on the Leonardo to allow for nice controlled fades. The buttons on the GameBoy are arranged in a matrix with diode arrays like so:

…and so the Leonardo reads the button values in a two-stage process, which looks like:

pinMode(A0, INPUT_PULLUP); // Down & Start
pinMode(A1, INPUT_PULLUP); // Up & Select
pinMode(A2, INPUT_PULLUP); // Left & B Button
pinMode(A3, INPUT_PULLUP); // Right & A Button
pinMode(A4, INPUT); // pin 5, button diode arrays
pinMode(A5, INPUT); // pin 9, button diode arrays

DDRF &= ~B00000010; // set A4 to INPUT, LOW
  
DDRF |=  B00000001; // set A5 to OUTPUT, LOW

button_state = ((~PINF) & B11110000); // Down, Up, Left, Right

DDRF &= ~B00000001; // set A5 to INPUT, LOW

DDRF |=  B00000010; // set A4 to OUTPUT, LOW

button_state |= ((~PINF) & B11110000) >> 4; // Start, Select, B, A
I hooked the LCD's VSYNC pin up to a scope, and it is firing at around 80Hz – which means around 80 frames per second! Although a big part of the reason for this speed is that the Arduboy code on the Leonardo is only putting out 128x64 sized frames, so for each 160x144 frame drawn by the Nano, all of the pixels outside of that 128x64 'active area' do not require any decision-making, and so I just set the data lines to zero and clock those pixels straight out at top speed.

The next step would be to move up to a bigger FIFO, and a microcontroller with more RAM, so that we can start working with the full 160x144 frame – for this purpose I have an 8K FIFO and a choice of the Mighty-1284P (which has 16K of RAM) or the Teensy++ (which has 8K of RAM) ready and waiting:

Of course, this will also mean more work on the Arduboy libraries to adapt to the bigger frame size. And while we’re at it, changing from the vertical byte orientation of the Arduboy’s display to a horizontal byte orientation would also be a handy optimisation – because at the moment assembling the value for one horizontal byte means accessing the values for eight different vertical bytes:

The end goal of all of this would be to produce a drop-in replacement for the GameBoy motherboard – I have already sourced components for the power switch, power jack, and volume dial. And there is ample space in the motherboard’s footprint for the two microcontrollers:

So, if you have read this far and you are still interested, I have setup a MailChimp list for sending out updates on the project, and would certainly be open to collaborating with others moving forward! (Kevin? :grinning: )

11 Likes

Holy fucking shit! This is incredible! You guys are amazing!!!

Whoah, I had this crazy idea actually to build a replacement PCB for the gameboy but you are like half way there already!!!

Nice work @uXe!!

5 Likes

Ha! Thanks @bateske! :smile:

As I said, would be happy to put our heads together working the rest of the way towards a replacement PCB!

Ditched the little GameBoy voltage board today, and have a nice elegant solution to generate the -20V for LCD using only two components: an RO-0524S 5V to 24V isolated DC / DC converter and a L7920CV fixed negative voltage regulator.

By reversing the + and - pins on the 24V side of the DC / DC converter you end up with -24V, which the regulator then turns into -20V. Voilà! :grinning:

Works well, much neater, and the contrast on the LCD is noticeably better.

1 Like

Hey @uXe! Your hack is up on hackaday!! :smiley:

2 Likes

Awesome!! :smiley: :grin:

Had some time on my hands today so I managed to put some work in and come up with what I think is pretty close to a first prototype attempt at least!

2 Likes

And here it is! :grinning:




Works great - and with the GameBoy’s 160x144 LCD there’d be room for both horizontally (Arduboy) and vertically (Tetris MicroCard) oriented games with just a tweak to the code on the Nano!

The thumbwheel potentiometer is wired as a voltage divider sending 0-5V signals to the spare A6 and A7 analog inputs on the Nano.

The one hitch is that the Nano is only just marginally too tall for the case, so I’ll need to source slightly shorter female headers… or just make a little cut-out in the case!

3 Likes

Holy crap, that is amazing, you should sell these boards!

1 Like

If you don’t mind doing a little cutting and trimming with a sharp utility knife, you could use a 40 pin IC socket. You would want the side-wipe type, not round pin machined. An open frame one would be easier to cut shorter. Or you could leave it the full length and just cut the pins at either end.
E.g.:
http://www.digikey.com/product-detail/en/ED40DT/ED3048-5-ND/4147604
Or 32 pin but not as common or easy to source, and would be too short for the Micro:
http://www.digikey.com/product-detail/en/ED32DT/ED3053-5-ND/4147603

Clever thinking @MLXXXp! Found these though, should allow that few extra millimetres:

http://gct.co/connector/?series=BG095

Nice work! You could also just solder the arduinos directly to the board as well and save like 4-6 mm :wink:

This is awesome! When things slow down after kickstarter we would love to help you produce and sell these in our store!

2 Likes

[quote=“bateske, post:11, topic:293”]
Nice work! You could also just solder the arduinos directly to the board as well and save like 4-6 mm :wink:[/quote]

Yes :stuck_out_tongue: Only problem is that they need to be raised up off the board a little so that the USB ports on the two Arduinos can be easily accessed through the cartridge-slot opening in the GameBoy case.

That would be amazing, thanks! :smiley:

And am happy to wait until there’s a little less on your plate, since there are a few revisions to be made in the meantime anyway…

For one, the L7920CV negative voltage regulator is a discontinued part, so might be better off replacing it with an LM337 and a couple of resistors. Would also be good to add in a power switch, and think about running it from a battery pack or just 4 AA’s like the original GameBoy?

1 Like

the 4 AA would be 6v nominal so should work just fine!! :smile:

Might be cool to source a lithium pack that will fit inside the battery compartment too.

This is a cool project. I’ve heard there are some factories that still make copies of the old gameboy mold, I wonder what the legality on having those produced would be. Hmmm…

1 Like

There is a healthy GameBoy modding community in the 8-bit chipmusic scene, with retailers selling newly molded GameBoy cases, like these by ASMretro:


or kitsch’s custom case:

as well as backlighting kits for the LCD, custom coloured buttons, and even backlighting kits for the buttons:

There was even talk of producing brand-new LCD front boards, so it is not inconceivable that an Arduboy Classic could be made using all-new parts!

That being said, I do have a mountain of old GameBoys here waiting to donate their parts! :grin:

Also, I noticed that arduino.cc are now having their ‘Genuino’ branded boards made in China by Seeed Studio - so you should definitely be in the right place at the right time to source the necessary Arduinos! :grinning:

1 Like

Wow!! Thats so cool! I had no idea it was so easy to find these cases.

And you are right about Seeed being the producer for Genuino which was one of the factors for selecting them as our manufacturer.

Finally found the time to try the shorter headers today, and all systems are GO! :grinning:

What a great feeling to go from thinking “wouldn’t that be cool” - to making it happen and holding it in your hands! :grin:



6 Likes

With that many pixels the CPU starts to become an issue for some applications. Just do some simple math. You have 16 or 20 million cycles per second… but now you also have 160x144x80(fps), which is around 1.8 million pixels you have to push every second (assuming full screen scrolling, etc). Obviously having a dedicated chip for just graphics is going to go a long ways, but you’re starting to get to some pretty big numbers here.

Would love to see something like a megaman demo running on this at full 160x144 and see what FPS is achievable.

Once we go fullscreen, things will start running slower than 80 FPS just because there will be extra instructions needed on the Arduino Nano for decision making on pixels outside of the current 128x64 ‘active area’.

I would love to see a fullscreen demo running too - have just been too snowed under with work and the holidays to sit down and code!

I do have the 8K FIFO in place now though, so if you wanted to get something up and running for the Arduino Micro that could directly render out some kind of animation or something from PROGMEM in 2,880 byte frames (144 lines of 20 horizontally oriented bytes) then I’d be happy to run it!

How is this rendering happening? The Micro grabs data off the FIFO, but how is it putting it onto the Gameboy screen? What does that API and timing look like? That itself might be the limiting factor if it’s too slow.

And what is the interface/timing on getting into the FIFO? Looks like FIFO is 9 bit parallel access (in and out), but what is the timing on that? I assume you have to toggle a pin to advance the read/write pointer? I see it says 12ns… ok, that’s actually crazy fast… faster than we could push/pull. So the FIFO isn’t the limiting factor.

Sorry if I’m causing some confusion here - the Arduino Nano is the LCD controller, the Arduino Micro is where the Arduboy sketches are running.

What I meant by directly rendering from PROGMEM is that the Micro does not have enough RAM for a 2,880 byte frame buffer, so we would need to bypass using that frame buffer and render directly (like the Squario sketch does). Retrieving the pixel data from PROGMEM instead, or even just generating it on the fly?

As long as there is a loop included that will iterate through those 2,880 bytes one at a time in the correct order then I’ll be able to make it work with the FIFO and the Arduino-Nano-LCD-controller…