Dodo: 6502 Game System

Handheld Game System featuring the 6502

Similar projects worth following
Dodo is a 6502 portable game system. What started as a simple homebrew computer has evolved into a retro gaming platform. Dodo uses an authentic 65C02 processor running at 1mhz without any emulation. Game development is easy with built in system functions for sprites, sound and input. Development is done in a web app that hosts an IDE, simulator, documentation and flashing utility all in one place. A completed game can easily be shown to your friends just by sending them a link, and then flashed to a game cartridge for playing on the actual device.

Check out to see some games

Dodo is comprised of two stacked boards with all through hole components for easy soldering and all parts are still in production. Nearly all Dodo technology is retro with a handful of modern parts. The screen is a beautiful 128x64 OLED and the games are stored on FRAM chips, but the heart of the machine is all 8-b

There are many 6502 projects out there in the wild that I used to get up to speed with a basic design for this game system. I mostly followed the guidance found here. The address layout sacrifices some address space from RAM, but allows for up to 8 I/O chips to be very easily addressed. It also uses a single NAND IC for chip select logic which should limit propagation delays which should raise the potential top end speed of the circuit. However, this doesn't really matter since I am clocking it at 1mhz for now.

The display used is a pre-assembled component from Adafruit that has a SSD1305 driver chip and a 128x64 pixel OLED. The SSD1305 has a 6800 compatible bus mode which made it fairly straight-forward to interface with. I added bus tranceivers to go from 5v down to 3.3v. I also had to add a bit more complexity with the chip select logic because the SSD1305 only has a select line. The 65XX chips all have 2 chip select lines.

Dodo supports a single voice of sound. Unfortunately, there are no longer any sound generator ICs in current production like the SID from the C64. Basic sound is created through a trick with the 6522 VIA. The shift register can be set to "free run" and can be used to output a square wave.

Dodo also supports game cartridges so that the game code is separate from the system. The system software is stored on the EEPROM, it has the boot screens, the code to read and flash the game cartridges, and a game API. The API supports sprite drawing, sound playing, button interfacing, and so on. Games on Dodo target 20FPS. An interrupt fires every 50ms to coordinate a consistent game loop.

There is also a simulator for Dodo that works in both the console and through a web interface. Game development is done in C using cc65. The system API calls are all written in assembly.

  • 1 × WDC 65C02S Modern version of the 6502 that can be clocked higher, has low power mode, and is all static design
  • 1 × WDC 65C22S I/O chip, has 2x 8 bit ports as well as 2 internal timers
  • 1 × WDC 65C51N Connectors and Accessories / Miscellaneous Connectors
  • 1 × AT28C256 32k EEPROM
  • 1 × AS6C62256A 32k SRAM

View all 15 components

  • Updated Playground!

    Peter Noyes04/13/2021 at 00:23 0 comments

    It's been a minute but there is an exciting new update on Dodo! The original Dodo Playground is a bit long in the tooth and sadly Chrome Applications had been deprecated so there was no longer a good way to flash Dodo games directly from the browser. 

    However, with Chrome 89 that recently came out WebSerial is now generally available to all users of Chrome. This means that there is now a much better solution for communicating with serial devices without even needing a Chrome App! 

    For this and other reasons, I decided it was time to give the Playground a facelift so I ported the app to VueJS and introduced support for WebSerial. I am hosting it on a separate URL while I iron out the last details, however it is ready for others to give it a whirl. Another fun technology advancement is that now the simulator part uses WebAssembly, feel free to check out the source below! 

    Try out a game here:

    The source code for the new playground is available on github

  • Live on Tindie

    Peter Noyes05/25/2017 at 20:14 0 comments

    Dodo is now available on Tindie!

    If you want to check out how to program games for Dodo, check out the Playground where you can write and simulate games all in the browser. Space Invaders is the latest game to be ported.

    Also, the Documentation is now complete and live and is a great resource for anyone looking into how a single board computer (or in this case double board!) is put together.

    Updates are regularly posted on Twitter

    Thanks for following!

  • Final Stretch

    Peter Noyes04/16/2017 at 21:47 1 comment

    The past few months have been spent getting Dodo ready to be available as a kit. Its a lot of work to get a kit together of this complexity! The hardware is final, the firmware final, parts have arrived, and most importably the documentation is complete!

    Check out the documentation at I have provided both assembly instructions and information pages on the sub-systems of Dodo.

    The last change to the firmware was to support versioning and improved flashing. There is now a version number built in that can be queried over the serial connection. Games record what version of the firmware they were built to target. Semantic versioning has been adopted and there is a version check when games load to avoid unexpected behaviors and allow for continued development.

    There is no longer a flash button on the splash screen. The flash button has been replaced with an Info button that will show the firmware version. Dodo listens for a flash command as it sits on the splash screen indefinitely. The user experience is now much improved.

    Be sure to check out, follow on twitter, and sign up for the e-mail list to stay updated on the latest Dodo news! The Tindie page will go live soon!

  • Happy Holidays

    Peter Noyes12/23/2016 at 04:24 0 comments

    For fun I hacked together a Christmas demo for Dodo. I found an animated GIF of a retro graphics style Santa which I then manually converted to monochrome. I use the program Pixen for laying out sprites. From there I took the 7 frames and dumped them as byte arrays and wrote a quick little program to cycle through the frames. The resulting sprite size was 42x48 so there were room to show 3 of them. The finishing touch was to get Jingle Bells playing in the background. Unfortunately 256 bytes are not enough to hold the complete song. I will go back and update the firmware to support longer music.

    See it in the playground here:

    Here is the original GIF:

  • Assembly Language and More

    Peter Noyes12/20/2016 at 02:56 0 comments

    The Dodo Playground now supports writing games in 6502 assembly. Some of the initial feedback I received for Dodo is that C is great and all, but a big part of the nostalgia for a 6502 retro system is to be able to write in 6502 assembly. I totally get it, I have had a lot of fun writing the system firmware in assembly. Now in the Playground, it is easy to make a language choice using the dropdown in the top navigation bar.

    Here is a working example in Assembly

    Making the change wasn't all that difficult, the back end compilation still uses cc65. Basically I just needed to author a thin set of assembly routines for calling each API, and update the backend with two different make files. The thin wrappers each hardcode an index into the API's jump table. The calling convention for C is pretty friendly for making assembly calls so that is left in place. Basically each parameter needs to be pushed onto a stack and I incorporated helper functions to do so. Here is a simple API call example:

            lda #<message
            ldx #>message
            jsr pushax
            jsr draw_string

    To support this new functionality involved making changes across the board so it was a good opportunity to finally make the last changes to fully take advantage of the updated address space in Dodo 1.2 and above. Video memory and user code space are now moved around to now give a game 22KB of available RAM.

    Another reason for supporting assembly in the playground is to make it much easier to iterate while implementing my 1KB challenge submission, which is to implement image compression for Dodo.

    The challenge for 1KB is to compress a single image such that the image data and algorithm all fit under the 1KB limit. As an extension to this I also want to challenge myself to fit 20 compressed images into 8KB. With 20 images, the new 22KB of avilable RAM and the fact that Dodo operates at 20FPS, it should be possible to store 1s of looping video in memory and be able to play it back! I just need to find the perfect idea for a 1s monochrome video loop. Any ideas?

  • Batteries

    Peter Noyes12/16/2016 at 05:42 0 comments

    Dodo has nearly reached its final form by now having integrated batteries! The Hackaday Superconference badge gave me the inspiration I needed to finally figure out a way to mount the batteries. By mounting the battery holders sideways on either side of the board, they are unobtrusive yet still accessible. To fit, I needed to downside to AAA batteries, but I think the tradeoff is worth it.

    I also now have a working boost regulator circuit on board. The previous revision (Rev 2) had the MAX756 but it didn't work. For Rev 3 I switched to the LT1303 and very carefully laid out the PCB after researching the best practices for laying out such a circuit. I also experimented with different capacitors. I am happy to report that it is running at 85% efficiency, which is as good as expected for this part.

    Unfortunately, Dodo does not run for long on typical alkaline batteries. However, with Ni-MH rechargeable batteries, or with lithium batteries the life is much better. My rechargeable batteries yield a life of around 3 hours and the lithium batteries from Energizer last nearly 5 hours.

    Dodo uses around 100mA at 5V. Below is the formula for the current draw from the batteries based upon the 85% efficiency. At 3v, the current draw is around 200mA. Once the batteries are nearly depleted at 2V, the current draw is nearly 300mA.

    200-300mA is quite high for an alkaline battery and significantly degrades the capacity. For instance, a 750mAh alkaline battery might instead only provide 500mAh when the current is large. The voltage also falls quickly with the alkaline batteries. On the other hand, a lithium battery holds a voltage closer to 1.5V for much longer. Also, the lithium battery is able to provide a high current without losing capacity. The rechargeable batteries seem to behave similar to the lithium batteries. I therefore recommend that rechargeable batteries be used with Dodo.

    The battery indicator is also working spot on. I have it tweaked to go off when the voltage reaches 2V. The LT1303 has an internal voltage comparator and the LBO pin goes low when that threshold is reached. The trip voltage is 1.24v which is too low for a pair of AAA batteries. I use a voltage divider to scale that threshold. I am using values of 255k and 412k resistors for the divider. For my rechargeable batteries, the battery indicator goes off when there is right around 10 minutes of life remaining.

    Unfortunately, version 1.3 is still not right :( There is a problem with the wiring of the low battery indicator on the top board. I was able to fix it with patch wires but a new PCB will be needed. I guess the 4th try will be a charm.

  • EEPROM Flashing

    Peter Noyes11/16/2016 at 06:06 3 comments

    One of the big remaining tasks before Dodo is ready to be available as a kit is to support in-circuit flashing of the 32kb EEPROM that holds the system firmware. I want to continue to add functionality and it would be a major bummer to require everyone to pull a chip out and use a separate EEPROM burner. As of this week, Dodo now officially supports EEPROM flashing over the serial cable!

    Version 1.2 of the hardware hooked up the control signals such that in theory the flashing could work, but it took software changes to make it a reality. The trickiest part is that the system code basically needs to overwrite itself which is not straightforward. I ended up creating a small standalone routine that reads from the serial port and writes to the ROM and it is embedded as a resource in the system firmware. This routine is copied into a reserved area in RAM and then executed from there so that no code is read from the ROM while its being written to.

    I am pretty happy for my own sake that this now works. I have pulled the chip and reprogrammed it over 100 times during development. I can now iterate much faster when making firmware changes.

    In other news, I ported a simple version of Tetris to Dodo. Here is a playable version in the playground.

  • See Dodo at SuperCon

    Peter Noyes11/05/2016 at 07:27 5 comments

    I will be at SuperCon tomorrow with version 1.2 of the Dodo hardware!

    This new revision was a bit painful to get up and running. There were two mistakes made on the PCB, the MAX756 battery regulator doesn't have enough oomph for Dodo, and there is a mechanical clearance problem. The wires coming out the top of Dodo in the picture above are a patch to fix one of the PCB issues.

    The good news is that I have found a replacement regulator that works (I have a breadboard of it), the new memory decoding scheme works and gives close to the full 32KB of RAM. And, I got to buy a logic analyzer to help troubleshooting!

    With hopefully all the issues now resolved I plan to start offering kits soon on Tindie. If anyone is interested hop on over to to get on a mailing list for updates. Also, I ported the old QBASIC classic Nibbles over to Dodo and there is a link to play it on the same page.

  • Hardware v1.2

    Peter Noyes10/12/2016 at 03:29 0 comments

    At this point, there is only one working Dodo in existence, so not quite extinct ;-), but this needs to change! The next step in getting more Dodos out there is a new hardware revision.

    For a bit of history, the version 1.0 boards had several known problems, so it never seemed worth it to make any more prototypes. There was a version 1.1 that was designed to correct the most glaring issues, but no boards were ever fabricated because a more extensive update is really what was needed. Well, the time is now! Version 1.2 boards are off for fabrication.

    Here are the highlights:

    • RAM Upgrade. Now all 32KB is accessible
    • In place firmware updates
    • Faster game flashing
    • Thinner, no longer uses IDC cables between boards
    • Battery powered. Will run off of 2 AA Batteries.

    Above is a mockup of the new PCBs that I printed out. I have learned my lesson and will now always print these out and do some test placements of components.

    The RAM upgrade opens up the possibility of adding a BASIC interpreter to Dodo. The plan is to allow 6502 Assembly, C, and BASIC as different options for game development, but all using the same API.

    Dodo 1.0 supported flashing game cartridges over serial, but updating the firmware stored in the EEPROM required extracting the chip and using a dedicated programmer. The new Dodo will be able to program the EEPROM over the serial port.

    The new Dodo will also have RS232 control lines connected which will enable more efficient communication that will ultimately result in faster game flashing.

    Now the boards will be able to be mounted closer together, which means that the overall thickness of the device will be substantially less.

    Finally the new Dodo is battery powered. Two AA batteries should last around 10 hours. There will even be a low battery indicator!

    The battery circuit uses the Max756CPA+ which is able to boost the voltage of 2 AA batteries up to the 5V that Dodo needs. In the video above I am showing the test circuit I breadboarded to help fine tune the resistor values needed for the low battery indicator. The Max756 chip has an open drain low battery output pin that is driven low when a reference voltage falls below a 1.25v threshold. I wanted to show the low battery indicator when the voltage is 2v, so a voltage divider is needed to drop it down to around the threshold. In the video you see the second LED turn on as soon as the voltage falls to 2v, which is exactly what I want! The 2v is chosen based upon looking at the discharge curve of AA batteries and that is around the inflection point where the voltage really starts to tailspin.

    Once I have the new boards in my hands and have assembled a few prototypes, the next step will be to make some software updates to take advantage of the new hardware features. At that point the project is basically complete. If there is interest I will make a kit available on Tindie.

  • Playground Flashing

    Peter Noyes10/01/2016 at 04:00 0 comments

    Last update introduced the Playground, where games can be written in simulated all from within the web browser. Now, users of Chrome will be able to flash games right from within the browser, with the help of a Chrome App. Chrome Apps have the capability of interfacing directly with hardware, such as USB, Serial, and Bluetooth. Additionally, web pages can send and receive messages with Chrome Apps if they are white-listed by the App. With those two pieces web flashing is possible!

    When the playground website loads, it checks for the existence of the App and if found it reveals a flash button. The website queries the App for a list of COM ports, and then when flashing commences, it sends the App the compiled game binary that was built in the cloud and then the App sends the bytes over Serial to the real Dodo hardware. As the bytes are transmitted, progress messages are sent back so that a progress bar can be updated. Check out the video to see how it all works.

    Additionally, this means that a Chromebook can be used as a complete development environment for Dodo. The only feature missing from the Playground at this point is a way to more easily save games as they are being developed. Right now, a user would have to save a unique hyperlink every time they want to 'save' to get back to where they were. The problem is that for persistent storage I probably need to introduce the concept of a logged in user as an option to the playground. Perhaps I will use Github for single sign on using OAuth2.

View all 36 project logs

Enjoy this project?



teraz wrote 09/19/2021 at 15:00 point

what You think about

  Are you sure? yes | no

Martin Cejp wrote 04/11/2018 at 08:13 point

This is fantastic, gotta build my own!

  Are you sure? yes | no

Brett wrote 08/14/2017 at 04:40 point

I ordered one of the Dodo's last week and we assembled it this weekend. I was pretty fun to assemble. I couldn't believe it turned on and worked the first time. I have to credit that to the great online documentation you have. The family has been quite a bit of green Tetris on it this evening. The only thing I can recommend, and I can probably do this in 3 seconds in C if Tetris is in C, is button combination which pauses the game. Oh and the other thing, I will probably do this on mine. This is sort of personal preference probably. But If the plastic cover did not have an opening for the OLED screen, that would bring peace of mind, that something would not damage it. It isn't too much work to just glue a cover over it. It's a great project. It's nice to be able to run native 6502 code on a portable.

I have a question too. Can the cartridges be larger than 8kb, given a larger memory chip?

Thanks for making such a cool system.

  Are you sure? yes | no

Peter Noyes wrote 08/17/2017 at 01:53 point

Thanks for the kind words! I am glad you got it up and running without needing to troubleshoot anything!

Thanks for the suggestion on the front screen protector. Next time I order a batch I will consider making that change. 

It should be possible to build pause into tetris. The only difficulty is that the code is pushing up against the 8kb limit, so it will take a bit of creativity to make room for that functionality. Here is the source code for the game:

As for a larger than 8kb cartridge, there might be something possible but it wouldn't be straightforward. The system code in Dodo has reserved 8kb of RAM to hold the game binary, the 8kb contents on the FRAM are blindly copied into that RAM segment and then the code is executed from there.  One possibility to use a larger chip is to still use the 8kb for pure code,  but use the rest of the chip to store sounds, strings, and graphics, and then bring those resources in while the game is running. 

Sorry for the delayed response!

  Are you sure? yes | no

Jasmine Brackett wrote 05/08/2017 at 17:59 point

Awesome work Peter. Dodo was featured on the Tindie Blog today!

  Are you sure? yes | no

Jim wrote 04/14/2017 at 19:00 point

I have played with the assembler in the play ground. I'm having issues with drawing a line with the set_pixel subroutine. If I run a counter from 0 to 19 (just picking a random end point), I can do an "lda counter" (loading from a memory address) and push to the stack for both x and y. That draws a line where x=y just like it should. But when I try to draw a vertical line with "lda #10" for x and "lda counter" for y, it just hangs.

I've also noticed that when I load an existing assembly language program, I have to select "c" and then select "assembly" before I can run it. Other wise it loads with the same type it was saved as ("assembly"), but tries to initially run as "C".

Hoping you kit some up soon and I can melt some solder... :-)

  Are you sure? yes | no

Yvan256 wrote 11/15/2016 at 20:00 point

"Unfortunately, there are no longer any sound generator ICs in current production like the SID from the C64."

Unless you are planning on manufacturing thousands of units, this shouldn't be a problem. There's still dozens of vendors on eBay selling the SN76489AN in various quantities from 1 to 50 units. I just bought five of them for only 2.82$CAD total, shipping included. At that price you could even use two of them to have stereo audio. A lot of work has already been done for this IC, see the wikipedia page for it. In my opinion this a low-cost, simple solution which fits perfectly with your project.

edit:  granted, the SN76489AN is no SID, but unlike the SID it's easily available.

  Are you sure? yes | no

Rosmianto Aji Saputro wrote 09/15/2016 at 05:57 point

Love reading the documentations here...

  Are you sure? yes | no

Jasmine Brackett wrote 04/02/2016 at 02:38 point

Great to see Dodo yesterday. Thanks for coming and bringing it!

Some photos are up:

  Are you sure? yes | no

Peter Noyes wrote 02/03/2016 at 21:08 point

Thanks man! Your bread project looks great too. My dad is really into baking sourdough bread and he doesn't have a proofing box. I can't wait to see how it turns out. I might need to build one someday!

  Are you sure? yes | no

Jan wrote 02/03/2016 at 20:22 point

Nice project there, mate! I always envy people who do things totally bare bone. I´m more like "a bit c++ here, a few libraries there" :)
Your board looks fantastic. I´m doing my first board in KiCAD. Hope it´ll turn out as nice!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates