I had disassembled and rebuilt the Commodore CP/M cartridge some time ago. Thereby I had the idea not only to rebuild this adapter 1:1, but to create a new version.
A version that is not only much smaller, but also more compatible. And at the opportunity you could maybe make the whole thing a little faster.
The old cartridge was clocked with just under 4MHz. So why not go to 8MHz, where the C64 provides exactly this frequency at the expansion port with the DOT clock.
A lot has already been said about the Commodore CP/M Cartirdge. What you always read is that the VIC is to blame that this cartridge would not work in newer C64 models.
After my many measurements and tests I can at least claim that it is not the VIC as such that is the problem. I have even been able to get the original cartridge to work on any VIC with a few tricks.
The VIC does play into this problem, but only in terms of clock generation. Not because of any missing features in the newer versions.
Also on the VIC-II you get the cartridge running, if of course not in the original version. By cleverly replacing various TTL components in this cartridge with S/LS/ALS/HCT variants, you can actually get the cartridge to run on any system, with the exception of the Ultimate64 board.
Since all these variants have a slightly different timing, you can put together the cartridge accordingly. Which of course can not be the point of the thing.
By the way, what can also make a difference is the PLA used. Especially when it comes to replicas, the Commodore cartridge does not work stably. Most of the time the whole thing hangs in the boot process.
However, I have not analyzed this further. I could only make this observation during my tests, that depending on the PLA used, the behavior of the cartridge also changed.
The first CPLD version
The first version I built with enamelled copper wire and breadboard:
And the back:
The two boards were simply plugged together.
First I had translated the Commodore version into VHDL code. But without great success.
The CPLD is much faster than the TTL components. Then I started to build the whole thing as cycle-exact as possible. I also added an external oscillator for the CPLD to synchronize the whole thing.
With this I managed to reproduce the 4MHz version (which effectively runs slower). However, also with all the disadvantages that the original cartridge had again. Actually witless, as I found.
Speaking of frequencies. Of course, only the Z80 is operated with 4MHz, or later the said 8MHz. The C64 still works with its 1MHz. This does not change either. Since only the 6510 CPU is switched off, but not the VIC, the bus cannot be accessed faster.
So as far as memory accesses are concerned, the Z80 CPU is always slowed down by waitstates.
This also makes working with CP/M so slow, because in the end this is a disk operating system. And everything you do runs over the C64 bus with one megahertz.
Twice as fast is not twice as fast
I still had some 8MHz NMOS types of the Z80 in my fundus. So it was obvious to speed up the whole thing at least a little bit.
I can’t change the CP/M and also the C64 memory bus can’t be bored. Therefore external memory is not possible. And more than 64k would not be possible, because the old CP/M 2.2 could not address more than this 64k. At least not by default.
To clock the CPU with 8MHz would mean to build in more waitstates. Therefore this version, even if clocked twice as fast, would not work twice as fast.
However, you notice the 8MHz when compiling or calculating. Or everything else, where you don’t have to access the memory bus.
Adrenaline for the Z80
I had to discard the concept for the 8MHz version several times. What became clear quite quickly was that you can’t just drill the old version up to 8MHz.
I had first worked with a counter for the waitstates. The counter was then fed by the DOT clock and Phi2.
But this turned out to be not very clean. Measurements have then shown that the counter counts itself again and again. Although Phi2 is derived from Phi0 and this in turn is generated by the DOT clock, they do not run absolutely synchronously in the long run.
Already the problem that the duty cycle and the period of the square wave signals are not exactly the same produces “inaccurate” edges. So it happens from time to time that the counter is evaluated too early or too late, and thus the result is not correct.
First I thought of an error by the CPLD. Then I rebuilt the whole thing with a 74LS197. And there this also happens, if you take the signals from the C64.
By the way, the longer the C64 runs, and the warmer its components are, the stronger this effect is.
Unfortunately, this is not noticed at first glance. If you record a few seconds with the Logicanalyser, you already have so much data due to the 8MHz that this is hard to find.
The whole thing does not happen constantly, but every few seconds. I had found this rather by chance.
Therefore I then went to determine the cycles exactly with the help of the /MREG signal of the Z80. So whether the Z80 is just at T1, T2, T3, etc..
And then to react exactly to these cycles, and to generate the waitstates depending on BA, R/W, I/O1 of the C64.
Furthermore I used the BA signal for the /BUSREQ signal to the Z80. The resulting BUSACK signal I then took into the control for direction switching of the address and data bus.
Just to use the BA signal in more places increased the stability enormously.
The first PCB
But since I had problems with my prototype again and again, I decided to put the whole thing on a board for testing. This is how the second prototype came into being:
The components for switching the data bus were still on it. Because in the beginning I had problems to find the right timing here. But in the course of time these became superfluous.
I also discarded the first timing model. By the complete redesign of the control I could do without an external oscillator.
However, it soon turned out that I had unfortunately not thought of having to take further measurements. Without an expansion port extender, I could no longer access important signals.
So I had to create a new board again, which I had designed a bit more far-sighted.
Here I had provided additionally a small breadboard, anyway some free I/Os of the CPLDs rausgeführt around easier signals abgreifen to be able. But I didn’t use most of it any more.
At the same time I had already developed a new board, which would be the final version.
Since I always wanted to design a more unusual board, I decided to use this “designer version”.
I was initially concerned that the slash would be too unstable. But after the boards were delivered, I was able to calmly dispel this fear. At 1.6mm thickness, this fine line is very stable after all.
In the meantime, I have also pushed the firmware with version 0.5 so far that I have published the whole thing on GitHub.
I tried to do some tests in advance, as far as they were possible for me. Unfortunately, not all possible boards are available to me. I have tested in the following constellations:
- ASSY-NO.250407 / ARTWORK-NO.251137 / REV.B
- ASSY-NO.250407 / ARTWORK-NO.251137 / REV.C
- ASSY-NO.250469 / PCB-NO.252311 / REV.4
- ASSY-NO.250469 / PCB-NO.252311 / REV.B
- SX-64 (I would have to unscrew it to check the revision)
- Ultimate 64 Elite V1.3, Firmware 1.37, DolphinDOS Kernal
Furthermore I had tested different VIC versions and revisions on these boards.
I would see the stability personally already quite high. Crashes during operation were quite rare. Now and then there was a hang during the first boot.
I tested with the original kernel, SpeedDOS Plus+ and JiffyDOS. I would definitely recommend a floppy speeder. Without it CP/M is no fun.
On the internet I found a small Pascal program which calculates a Mandelbrot set. I used this as a kind of benchmark.
The times are as follows:
- Commodore CP/M Cartridge: 7:16 (min:sec)
- 8MHz Z80 Cartirdge for C64: 3:50 (min:sec)
For CPU-only work, my card is really almost twice as fast.
If you always wanted to try CP/M on the C64, you will get an easy start with my card. The number of components is manageable and also the price of the individual components is far below what used Commodore cartridges achieve.
I would estimate the stability to be about the same as the Commodore version. I’m not even sure if some of the problems are not caused by the software, i.e. CP/M 2.2.
I had also considered integrating an IEEE-488 interface in the meantime.
However, I doubt in the meantime whether this brings any advantage. Because the CP/M 2.2 from Commodore only supports drives which are compatible to the 1541 from the disk format. Like the 2031 for example.
And if you use JiffyDOS or SpeedDOS, the speed advantage of the IEEE-488 drives would not exist anymore.
As mentioned above, I put all the relevant information and files on my GitHub account: https://github.com/DL2DW/Z80-Card_for_Commodore_C64
I would be very interested in feedback regarding compatibility with other boards. Only then I could develop the firmware accordingly.