The Dan64: A Minimal Hardware AVR Microcomputer

[Juan] sent us his writeup of a microcomputer he built using an Arduino UNO (AVR ATmega328p) and some off-board SRAM. This one’s truly minimalistic.

Have a look at the schematics (PDF). There’s an Arduino, the SPI SRAM, some transistors for TV video output, and a PS/2 connector for the keyboard. That’s it, really. It’s easily built on a breadboard in a few minutes if you have the parts on hand. Flash the Dan64 operating system and virtual machine into the AVR and you’re good to go.

Now we’ve seen a few 6502-based retro computers around here lately that use a 6502 paired with a microcontroller for the interfacing, but they’ve all been bulky three-chip affairs. [Juan] wins the minimalism prize by using a 6502 virtual machine implemented in the AVR to reduce the parts count down to two chips for the whole shooting match.

Using a 6502 virtual machine was a crucial choice in the design, because there are 6502 cross compilers that will let you compile and debug code for the microcomputer on your macrocomputer and then load it into the micro to run. This makes developing for the micro less painful.

How does it load programs you ask? The old-fashioned way of course, using audio files. Although rather than using the Kansas City Standard as in days of yore, he encodes the data in short and long pulses of square waves. This might be less reliable, but it sure saves on external hardware.

What else does the Dan64’s OS do? It’s got a limited shell that includes a 6502 assembler and disassembler, so you can program the microcontroller on the fly in its native assembly language if you want. And of course, no microcontroller is complete without raw memory access through peek and poke.

Have a look through the videos, well-written instruction manual, and the code. Build yourself a microcomputer and write some software like it’s 1982. We can think of worse ways to waste a weekend.

26 thoughts on “The Dan64: A Minimal Hardware AVR Microcomputer

  1. The screen going funny is no problem. The Commodore 64’s screen would go blank during cassette loading because the video circuitry was used for a “modem” to read cassette audio data. Since nothing intelligible would happen on the screen anyways they blanked it out during this process.

      1. You’re right. That video in the post is old, current version of DAN64 disables the video output when loading/saving programs.

        Why disabling the screen? Basically the Arduino can’t do both things at the same time. The composite video generation relies on an interrupt every 28 microseconds and, for example in the loading operation, the pin change interrupt plus the decoding algorithm is interfering with that interrupt.

        Besides I used the same SRAM for both video memory and storing the programs and that means you can’t write into SRAM if it is busy bit-banging the video output.

        So, yes. One single MCU can’t compete with the Comodore 64 dedicated hardware, even if you run it at 16MHz ;)

      2. Is that because it CAN’T be blanked? Or because for this game they CHOSE not to blank it, giving the user some reassurance that something is actually happening during the long multi-part loading process?

        1. Just to jump in; back in the say I wrote this C64 loader
          https://www.youtube.com/watch?v=M3NkuS6pOfA
          which was used on dozens (possibly hundreds) of games. The C64 (unusually) had a hardware timer+interrupt connected to the tape input so you could do all sorts of things while loading (like playing Space Invaders and music). All other computers of the era (AFAIK) used software timing loops to measure the tape pulses. Blanking the display was generally done in order to disable screen DMA (and sprite DMA etc) and get consistent CPU timing. Because of the CIA (IRQ+timers) It actually wasn’t necessary on the C64 at all. Other systems like the ZX Spectrum etc just put up with small errors in the software timing loops, it didn’t cause serious issues.

    1. The actual reason is timing – the video chip is not actually involved in the tape loading, the modem implementation is actually completely on the CPU. This requires, obviously, reasonably precise timing to measure the pulses. HOWEVER. when the screen is on, the video chip shuts down the CPU for 40 cycles every 8 scanlines (these are called “badlines”). In order to avoid dealing with this, the standard implementation blanks the screen.

      Many turbo tape implementations (i.e. non-rom implementations of the modem part) use other syncronisation methods, usually based on the NMI signal, and can have the screen on to show a picture or whatever, or play music and shit.

  2. The image lead me to believe somebody had managed to port Dwarf Fortress or Nethack to the Arduino platform. Now that I think about it, it’s actually pretty likely that somebody already has.

    1. Unfortunately Dwarf Fortress is closed source so it wouldn’t be portable. Also running something with that gigantic code base on an Arduino would be quite a feat, since DF’s single thread really hammers a modern CPU core running at >3GHz!

      Dungeon Crawl would be a good candidate, I run it on my Beaglebone as a game server. It’s open source, which is why I can compile it for ARM.

  3. Looks to me like your audio input library is using some interrupts which messes up the timing for the screen output…
    you have to change it so when you go into loading mode that the cpu does pio during the time between raster draws and return to origin…like the aruduino retrocomputer that amigojapan made a while back…or just blank the screen when loading…
    might not be many mips left over after drawing the screen….I ported AVGA to the arduino with an overclocked arduino…at ~29MHz, but still had over 6 MIPS left over for running game code between generating video time….

    1. Current version disables the screen (looks blank then), but I couldn’t find a way the audio input (detects pin change with an interrupt) didn’t affect the video generation.

      I’ll look at the project you mention, sounds interesting!

  4. Is this legit?
    While watching the “Loading programs into Arduino Uno using audio” video from the playlist, if you look close at the bottom of the monitor for the Dan64 output, there appears to be what looks like video player controls. IE play, pause, FF, REW, etc. implying this is actually a mock up video being played back and not live output.

    1. Well spotted, that’s VLC!

      The microcomputer generates composite video (PAL), so you can use a TV or (like in the video) a video capturer card.

      The video capturer is really picky and it was easier to get the video generation working with the TV. Then I tweaked the video generation until it was “good enough” for the capturer (I generate de-interlaced video and the capturer won’t accept it if it deviates too much from the standard!).

      It was extra work but is handy to have the video output in a VLC window (and the capturer is cheap: Easycap USB).

      I assure you it is totally legit :)

        1. No worries!

          At first debugging was basically a led blinking when the code reached a certain point (the project was done with AVR C, not Arduino IDE so I didn’t bother with serial terminal or anything fancy like that).

          As you can imagine it was a great achievement to get the video output in a window in my desktop screen :)

  5. Why emulate a 6502? Why not just have an AVR-based microcomputer? You still can do cross-compiling and debugging on your PC using Atmel’s tools. I could understand it if you were emulating a Commodore 64 and wanted to run C-64 software on this, but if you’re writing code from scratch, why “dumb-down” the AVR to the level of a 6502?

    1. It is explained in the page.

      TL;DR: The ATmega328p implements a Harvard architecture and it has different buses for data and code. If you want to load external programs without reflashing the AVR… well, I decided to implement a virtual machine. The 6502 was simple and fun to implement (and the footprint is over 1.5KB IIRC).

  6. Very nicely done. Having lived through the era that retrocomputing seeks to recapture, I can honestly say that doing this myself does not interest me in the least. However, I have great respect for anyone who manages to pull it off.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.