Now I’ve mastered Metal (ha ha), I think it’s time to build an emulation that’s a little more complex. It’s time for the Commodore 64. Yay!
Had some thoughts about how to do this. The extra challenges that I see are:
- the banked memory. I will need to be able to swap the RAM/ROM banks in and out without too much overhead in terms of the processor.
- the graphics chips. I wasn’t sure I could emulate the hardware graphics fast enough using standard Cocoa techniques. It should certainly be possible with Metal. In fact, I’m wondering if I can emulate most of the VIC chip in Metal.
- sound. Actually, getting the sound right on the PET would have been very difficult, which is why I didn’t bother. The way sound was done on the PET was to emit a square wave at the frequency you want using the VIA shift register. That, in turn implied that the VIA had to run at actual speed, which is next to impossible to achieve on standard PC type hardware. The SID, on the other hand, generated its own frequencies and you just set a register to tell it what frequency to use. It should be relatively easy to use the register values to program the Mac’s own sound device., although perfect fidelity won’t be easy since that would require emulating manufacturing defects in the SID.
The 6510
I’m going to start with the 6510. The main difference between the 6510 and 6502 is the IO port. The IO port data register is accessed by reading/writing address $01
and the direction of the IO port bits is controlled by writing address $00
. In the Commodore 64, this port is used to control the tape drive (which I don’t care about) and the RAM banks. The problem I have here is that the RAM is currently internal to the CPU for performance reasons. I’m going to have to externalise it and add some bank switching capability.
So task number one is going to be to put together some performance tests to monitor the degradation and make sure I don’t drop too low.
Update
Had some thoughts about the above. I’m going to clone the PET2 target as a Commodore64 target and strip out everything except the screen. Then I’m going to load up the coverage tests and run those as a performance test. I’ve created a 6510 branch in the repository and will publish the changes I make to that.
Update 2
So I did the above. The coverage tests achieve a speed of 76MHz. Code is posted to the repository.