I’ve been away from the project for some time, but recently found opportunity to make some progress. As a respite from C64 bus timing issues, I decided to return to some final speed tests for the CPU ... and that’s been a lot of fun!
I had left off with stable operation at 20MHz, wondering if that could be bettered. My collection of half-can oscillators has grown over time, but I’ve yet to find the critical next one at 42MHz (21MHz after a div 2 flip flop). I did manage, though, to build the Variable Frequency Oscillator (VFO)
as Dr Jefyll and Garth suggested.Attachment:
B190C37F-1A2C-454A-BE00-2E77729150C6.jpeg [ 1.93 MiB | Viewed 2870 times ]
The VFO will allow a very gradual increase of the clock-rate, which is very handy. Unfortunately, it is also VERY sensitive to voltage changes, and that's been a problem. I was surprised to discover a significant voltage drop between my workbench PSU and the SBC, and the gap got wider with higher clock-rates. Worse yet, the SBC still lacks proper wait-stating, so booting from ROM requires starting with the half-speed SLOW clock, and switching to the full-speed FAST clock manually, once test code has been copied to RAM. That sudden "jump to hyperspeed" turns out to be a messy affair with the VFO, causing the voltage to drop, the frequency to wobble and the CPU’s Zero Delay Buffer to lose its lock on the clock-rate — certainly foibles enough to crash the CPU at critical speeds.
The first line of defence was to improve cabling. I got rid of the handy external power-switch I had installed between PSU and SBC, and it’s long skinny leads as well. Instead, at Dieter’s suggestion, I twisted together three lengths of wire for each lead, and ran “twisted-leads” to the Auxiliary Power inputs of the CPU. That helped narrow the voltage gap, so I felt the CPU was more easily able draw the additional power it requires at high clock-rates.
But it was also high-time I dispensed with the awkward “slow-clock” maneuver at boot up, and more properly addressed wait-states on the SBC. The simplest fix was to build an small wait-state adapter board to fit the empty 65C02 socket of the SBC. This socket goes unused when the TTL CPU is installed, and it conveniently has all the signals we need for wait-stating. I used the
wait-state circuit we discussed earlier in this thread to insert one or two wait-states when A15 goes high, as follows:
Attachment:
82B7DC76-DFB0-40D8-B097-66F3C77FE67B.jpeg [ 2.42 MiB | Viewed 2870 times ]
Recall that the challenge with wait-states on the TTL CPU is that tADDS (the time required for the CPU to generate an address) is very close to the half-cycle at 20MHz. That leaves precious little time for address decoding before the rise of PHI2, and any additional delay for clock-stretching or RDY logic will easily exceed the time available. To overcome this problem, the above circuit capitalizes on the fact that RDY need only go low before the FALL of PHI2 at the end of the cycle. That allows plenty of time, in fact, and this circuit requires only a single gate delay between address logic and RDY, which is about as crisp as you can get. (In this case, we use A15 as a proxy for ROM_CE since Chip-Enable signals are not available at the 65C02 socket). I tested the circuit with the 65C02 on a breadboard and it worked perfectly.
Unfortunately, that was not the case with TTL CPU. It turns out RDY took effect one cycle too late! The CPU’s RDY logic was extending Phase 1 of the next cycle for the wait-state, rather than Phase 2 of the current one. It was a bug, and one that had gone unnoticed to this point. A quick review of the WDC datasheet confirmed the correct RDY behaviour:
”A negative transition to the low state prior to the falling edge of PHI2 will halt the microprocessor with the output address lines reflecting the current address being fetched. This assumes the processor setup time is met. ... The microprocessor will be released when RDY is high and a falling edge of PHI2 occurs. This again assumes the processor control setup time is met.”After pondering it a bit, I concluded the simplest fix is a transparent latch on the RDY signal to gate the internal CPU clock. A 74LVC1G373 driven by PHI2 would work perfectly, but that would require a new PCB. As a temporary solution, I commandeered the flip-flop that the CPU uses for the 65C02 BCD wait-state, and pressed it into service to fix RDY, like this:
Attachment:
A0FD8AE6-A730-44EA-8652-0A73B32731B8.jpeg [ 3.08 MiB | Viewed 2870 times ]
With that, the CPU’s internal PHI11 clock now correctly handles RDY, with the “setup time” being the tpd of the NAND + flip-flop combination in the circuit. So, finally, here is the new test setup for the TTL CPU — the SBC stacked on top, the Wait-State adapter board mounted on the 65C02 socket, and the VFO installed:
Attachment:
A52F3637-ECD4-4BCC-AC99-3A70632FEC4B.jpeg [ 2.61 MiB | Viewed 2870 times ]
For the test itself, I rigged up a copy of the Klaus Dormann test suite to copy itself to RAM and then to write its progress to the 6510 port on the TTL CPU as it went. Having verified proper operation of the RDY circuit, and other preparations having been made, it was time for the big moment ... I inched the VFO along, hitting RESET each time ...
In the end, the CPU ran the full test suite comfortably at 21MHz, with a 5.5V supply! (current draw is 1A with the SBC LEDs off). Now that seems like a lot of work and trouble for just 1 MHz above the previous record, but so be it. I’m thrilled to get anywhere above the 20MHz threshold, even with the help of a little extra voltage.
So, with that, I’d like to officially declare 21MHz at 5.5V as the maximum clock-rate for the TTL CPU, and 20MHz as the “recommended” clock speed at 5V.
Ok, back to more testing with the C64!
Cheers for now,
Drass