[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.
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.
oh really ?
https://www.youtube.com/watch?v=zKcM9gk5qMA
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 ;)
Oh, make that 64 microseconds instead of 28 (PAL line period).
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?
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.
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.
Absolutely a cool small hack with a retro-feeling even if an Arduino is involved. I like :-)
Man don’t start the arduino shit
++;
Don’t start with the hating shit
which arduino shit? llc or srl?
Please flag things that are hacks so I know to just ignore them.
;-)
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.
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.
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….
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!
Now he just has to put it in one of those repoped retro C=64 cases.
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.
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 :)
Ahh, OK. That makes sense. I didn’t think this was faked, but I had to ask about that as it really jumped out at me when I noticed it.
Thanks for the explanation!
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 :)
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?
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).
Off-topic, I saw this on Slashdot, but I don’t recall seeing this on Hackaday, an Apple ][ emulator on an Arduino Uno.
http://dpeckett.com/turning-the-arduino-uno-into-an-apple
Overall, not that much different from [Juan]’s project, except they use the ATmega8U2 to generate monochrome VGA video.
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.