Background
In recent years 8-bit emulators enjoyed increased popularity. You can play your old 8-bit games of the eighties on Windows platforms, Linux, Mac, Android and even on a Rasberry PI. These emulators were even written in different languages such as c, c#, Java and even JavaScript.The source code of these emulators are even available for the curious that wants to know how they work. I myself had a peek at the source code of these projects. Looking at the complexity of the code for these projects just triggered another curiosity in the back of my head: How do you create such an emulator from scratch?
There are a couple of blog posts out there giving an overview and some pointers on how to write them, but no one actually goes into much detail on the steps they followed, problems they encountered and the steps they followed to solve them.
So, last year I wrote an Commodore 64 emulator from scratch in Java. This was lots of fun, but also on some days generated an equal amount of frustration!
This kept me busy for a couple of months. In the end I manage to write an emulator with support to load games from TAPE images (.tap files). I tried it on two .tap game images and gave sort of acceptable results. At that point duties called at work and I had to put this project on the back-burner and effectively forgot about until now...
How I ended up writing this Blog
Recently I got renewed interest in developing emulators. This time, not completing the outstanding TODO's of my Java emulator, but creating one in JavaScript!Why JavaScript, how will it keep up with emulation? In recent years with HTML 5 doing the rounds, a couple of browser vendors have a done a lot to try and jack up their JavaScript performance so that it is almost in par with programs compiled in CPU native code.
I am keen to see this for my own eyes. Previously I have seen emulators implemented in JavaScript and they were really SLOOOWWWW. So, an emulator is a good candidate to put the performance of the HTML5 claims to the test.
I also thought it would be nice to put my experience in a BLOG. I am sure there are people out there having the same curiosity I had. So I have will try and share as much of experience as possible during creation of this JavaScript Emulator. I will also post my source code as it evolves.
Planned Approach
In this series of block posts I am planning to follow an incremental approach. Starting out with a very simple emulator implementing only two machine language instructions of the 6510/6502 CPU (the CPU under the hood of the C64) and implementing the other instructions bit by bit. During this phase, I will also be writing very simple 6502 assembly language programs to test if I am implementing these instructions correctly.Once I have implemented the full 6502 instruction set for the emulator, I will be running some 6502 test harnesses to see if our emulator behaves more or less as expected as a whole. The is a couple of 6502 test harnesses on the web that we can use for this purpose.
After running the test harnesses, we will attempt to boot the C64 with its ROMS (e.g. KERNEL ROM and BASIC ROM). At this phase, we will not have any C64 screen display logic implemented yet, so the only way to check if the boot process is successfully, would be to inspect the contents of the screen memory (which is the 1000 byte memory block starting at memory location 1024) and see if it is populated with BASIC "welcome message".
After been convinced screen memory is populated with a welcome message, it would be time to start implementing emulation for the hardware. First a very basic implementation for a C64 screen in text mode (Black and white) and then the keyboard.
In the Background section I have mentioned that I tackled TAPE support. I will also be tackling tape support for the javascript emulator. Why Tape support, you might be asking? It was one of the slowest loading mechanisms in 8-bit machine history?
Well, TAPE loading actually always fascinated me on the Commodore 64. Firstly, because a Tape is analogue in nature, how did the C64 manage to extract digital information from it? Another thing that fascinated me about C64 game tapes, was that most of theme managed to high-jack the C64 and complete the loading process and fire up the game without the user typing RUN. As part of writing the emulator I wanted to found out how this "High-jacking" worked.
So, I will be focussing on TAPE instead of disk. I will choose a c64 game image on the WEB available in TAPE format and try to get it to run on our emulator, Implementing any missing functionality as we go along.
This whole approach will mean at times refining our code and doing some re-factoring.
About my Java emulator
For those that want to have a look at the of my Java emulator I wrote last year you can go to https://github.com/ovalcode/c64jjsTo run the project, add it as a project to eclipse. To kick it off use the main method in the class
ThreadAnimationExample.
Currently there is 4 important binary files missing from the project:
- The three C64 ROMS: Kernel, Basic and Characer ROM. These ROMS are readily available on the WEB. Download them to your local disk and adjust the paths in the Machine class constructor
- Any game image in .tap format. Remember to adjust the path accordingly in contructor on the Tape class
With the emulator started, to the load the game, type LOAD at the ready prompt an press enter. When prompted "Press Play On Tape" hit the backslah(\) key and loading will start.
In Summary
In this series of posts we will be developing a C64 emulator from scratch and will try try to document my experience in as much detail as possible.
Thats it! I hope you will enjoy my coming series of posts. Feel free to give comments and suggestions.
Hello Johan,
ReplyDeleteI would like to thank you very much for your blog. So you inspired me to start the journey myself and to write my own C64 emulator.
Your way of explaining the topics that were not known to me until then or only a little bit known helped me to get a better understanding of the subject matter.
I find the implementation of the addressing modes particularly elegant. That helped me a lot, since I first wrote an emulator (Space Invaders Arcade machine with the Intel 8080 CPU) on my first attempt to implement each statement multiple times without a test suite. The debugging was hell, but in the end I was able to run the attract mode, but the cpu had still some bugs that prevented me from playing the game. This is now 3 years ago and at the time I had very little experience of how a CPU works internally.
Today I ventured again to the topic and found your blog. Currently I have reached the point where the emulator boots and I can enter BASIC programs. With that I came further than I ever expected.
Again, many thanks. I will also describe my path in the blog, but in German, because it is easier for me. It should give others the opportunity to devote themselves to this exciting topic.
Greetings from Germany
Sven
P.S.: Since most ideas came from you, that made me understand the topic better, this note is also mentioned here: https://www.paass.net/c64-from-scratch-teil-1
I only wrote about the parts that I understood (that's why there is nothing about the vic yet).
Hi Sven
DeleteThanks for your comment.
Glad to hear my blog series helped you getting started with your own C64 emulator.
I have also read your blog post and tried out your html implementation on my Android phone and I am quite impressed with the speed.
Good luck with the serial implementation. Looking forward reading about it!