Today I looked into the bus activity during a WAI instruction on the WDC 65C02, and noticed that it is pulling RDY low during its second cycle, at the rising edge of phi2, if IRQB is high. Also, it seems to be a three cycle instruction - if you discount all the cycles where RDY was low at the end of phase two, there are three cycles left.
So I started to wonder - it's widely stated that it allows you to respond to an interrupt in only one clock cycle, but how can it possibly do that? It pauses itself during its second cycle, and surely needs to re-execute its second cycle with RDY high, and then execute its third cycle, before the next instruction can start. That's at least one and a half clock cycles, and maybe half a cycle more if the interrupt arrives soon after the falling edge of phi2.
I had already built a circuit to test WAI's bus behaviour so it was pretty easy to capture the timing on a scope. This system is running at 10MHz, and only consists of a CPU and some ROM.
In this scope trace the blue lower line shows the level on IRQB and the yellow upper line shows RWB. The CPU was executing WAI followed by STZ 0. I've aligned the scope trace so that the centre of the screen is at the start of phase 1 of the first cycle of the STZ instruction.
Attachment:
20230830_195547.jpg [ 4.14 MiB | Viewed 4253 times ]
I count two whole cycles (and change) after the IRQB transition before the centre of the screen where STZ starts. Note that at 10 MHz one clock cycle is two large grid squares wide.
My first capture was even worse, due I think to the point at which IRQB changed during the clock cycle:
Attachment:
20230830_195052.jpg [ 4.24 MiB | Viewed 4253 times ]
So I'm curious - has anyone here timed this before, and did your results match this? Is this timing what you'd expect? And is the "within one clock cycle" claim just a myth?
Edit - I thought it could be related to RDY having a slow rise rate due to the resistor pull-up that's required. Perhaps the one cycle response time only applies to the variants that have a separate pin for WAI, or the 65816.
I was using a 1k pull-up, which is already rather low - I think the datasheet suggests we should only draw 1.6mA to keep the voltage below 0.4V when the CPU is pulling it low. So my resistor is already about a third of the value it should be. I recaptured the test case with RDY and PHI2 measured as well, and it's pretty clear that RDY starts to rise at the beginning of phase 1 after IRQB goes low. It was quite slow but with a 10 MHz clock it got to about 4V before phase 2 and was pretty stable by the end of the cycle. So I think that cycle must then count as the second cycle of the WAI instruction, with the third following, just before the middle of my oscilloscope screen.
I also tried replacing the 1K pull-up with 330 ohms. This is probably pulling up with about 15mA, nearly ten times what the datasheet said. The voltage seemed pretty nice and low nonetheless, though I didn't measure it exactly. The rise time of RDY was now about a third of a cycle, as you'd expect compared to the 1k pull-up - it was comfortably high by the time the second cycle's phase 2 started. The overall cycle counts were unchanged by this, so I think this is not really due to the weak pull-up, it seems to be just the way the CPU works.