Page 1 of 2

Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 8:39 am
by drogon
I'm wondering if anyone is successfully using Rdy to halt a 65C02?

I tried it some time back on my Ruby boards and had mixed results - in that it worked very well - I was pulling Rdy low, then BE low, then fiddling with the RAM from another processor (an ATmega), then releasing BE then taking Rdy high ... At that point, sometimes the 65C02 would crash - it's as if it was reading a random instruction at that point.

I've read & re-read the WDC data sheet and I'm wondering if it's actually correct, given that it's known to be "interesting" in places.... Part of me is wondering if it waits until the end of the instruction cycle before the halt actually happens (but even when I did delay pulling BE low for some microseconds it didn't help - similarly pulling BE high, waiting a few microseconds then taking Rdy high didn't help)

I tried qualifying the Rdy signal with the clock (both falling and rising edges - I could not do much more with the hardware I had on that board, just one GAL) and it didn't help.

I moved to another way of controlling the system which is working well, but i'm keen to revisit this way of controlling the 65C02, so really keen to know if anyone is doing this successfully.

Thanks,

-Gordon

[edit to add the link below where I originally posted about it]

viewtopic.php?f=4&t=5861

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 10:13 am
by BigDumbDinosaur
drogon wrote:
I'm wondering if anyone is successfully using Rdy to halt a 65C02?

I tried it some time back on my Ruby boards and had mixed results - in that it worked very well - I was pulling Rdy low, then BE low, then fiddling with the RAM from another processor (an ATmega), then releasing BE then taking Rdy high ... At that point, sometimes the 65C02 would crash - it's as if it was reading a random instruction at that point.

Timing is tricky with RDY. It needs to be driven low during Ø2 high, since the MPU won't stop until the next high-to-low transition of Ø2. Needless to say, BE can't be driven low until the MPU stops, which also means waiting for the next high-to-low transition of Ø2.

There are several problems with use of RDY with the 65C816, mostly related to the bank bits. There's a topic I posted about that. Stopping the clock rather than relying on RDY may be the safer route.

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 2:28 pm
by fachat
With the 6502 I for example used RDY to coordinate two 6502 on the same bus. http://www.6502.org/users/andre/csa/auxcpu/index.html

On the MicroPET that uses a 65816 I tried RDY, but found that not to be working well, so I used clock stretching instead.

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 5:20 pm
by Dr Jefyll
drogon wrote:
I was pulling Rdy low, then BE low, then fiddling with the RAM from another processor (an ATmega), then releasing BE then taking Rdy high ...
Yes, that part sound fine.
Quote:
At that point, sometimes the 65C02 would crash - it's as if it was reading a random instruction at that point.

I tried qualifying the Rdy signal with the clock (both falling and rising edges
Qualifying the Rdy signal... l can you clarify? If you mean combinatorial logic, that's not the answer. In the scenario you describe (ie, accepting an asynchronous cue from the ATmega), what's required is a flipflop (clocked by the rising edge of Phi2) to condition the signal from the ATmega. This will ensure that tPCS and tPHC are satisfied (see below). Nothing tricky about it, really (for 'C02, at least). You simply need RDY to be stable -- either high or low, but not in flux -- immediately before, during, and after the fall of Phi2.

And, because the flipflop will introduce a certain delay, the ATmega mustn't be too hasty in adjusting BE. To be on the safe side, you'd wanna allow one entire 65xx clock cycle before concluding that the RDY cue has been accepted.

HTH!

-- Jeff

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 5:28 pm
by drogon
Dr Jefyll wrote:
drogon wrote:
I was pulling Rdy low, then BE low, then fiddling with the RAM from another processor (an ATmega), then releasing BE then taking Rdy high ...
Yes, that part sound fine.
Quote:
At that point, sometimes the 65C02 would crash - it's as if it was reading a random instruction at that point.

I tried qualifying the Rdy signal with the clock (both falling and rising edges
Qualifying the Rdy signal... l can you clarify? If you mean combinatorial logic, that's not the answer. In the scenario you describe (ie, accepting an asynchronous cue from the ATmega), what's required is a flipflop (clocked by the rising edge of Phi2) to ensure that tPCS and tPHC are satisfied (see below). Nothing tricky about it, really (for 'C02, at least). You simply need RDY to be stable -- either high or low, but not in flux -- immediately before and after the fall of Phi2.

And, because the flipflop will introduce a certain delay, the ATmega mustn't be too hasty in adjusting BE. To be on the safe side, you'd wanna allow one entire 65xx clock cycle before concluding that the RDY cue has been accepted.

HTH!

-- Jeff
Based on some suggestions a while back, I was ANDing it inside a GAL with either the rising edge of the clock or the falling edge. No real difference. But based on what you're saying that's not going to cut it. I'm not at this stage going to add more logic to the board so it looks like I'll stick to plan B for the next one.

And BE (being on a separate output pin on the ATmega) would be pulled high a good few µS after I took Rdy high - purely by the code execution time of the ATmega - both at 16Mhz but the 6502 would have had a good half dozen cycles before the ATmega even thought about raising BE (and in any case I did add explicit delays when testing it too).

Thanks,

-Gordon

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 5:56 pm
by Dr Jefyll
drogon wrote:
I'm not at this stage going to add more logic to the board
Well, there might be other alternatives. Really what's required is any means (not necessarily a flipflop) of preventing transitions on RDY around the time that Phi2 falls.

If the ATmega is fast enough, perhaps it could repeatedly read Phi2; then, upon detecting a high-to-low transition, it would alter the state of RDY before the critical tPCS and tPCH interval at the end of the cycle.

Or, if there's a bit too much latency in the ATmega's response, it could detect a low-to-high transition instead, with the goal of issuing a cue that takes effect on the following 'C02 cycle. I think if you're sufficiently devious and stubborn the flipflop can probably be avoided. :P

Edit: oops, I just noticed we have both CPUs at 16Mhz. I was hoping the AT was running a lot faster. :|

Another alternative is to forget RDY, and use clock stretching (as BDD suggested).

-- Jeff

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 6:19 pm
by BigEd
(Have you got your rising and falling edges swapped around there??)

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 6:33 pm
by fachat
drogon wrote:
Dr Jefyll wrote:
drogon wrote:
I was pulling Rdy low, then BE low, then fiddling with the RAM from another processor (an ATmega), then releasing BE then taking Rdy high ...
Yes, that part sound fine.
Quote:
At that point, sometimes the 65C02 would crash - it's as if it was reading a random instruction at that point.

I tried qualifying the Rdy signal with the clock (both falling and rising edges
Qualifying the Rdy signal... l can you clarify? If you mean combinatorial logic, that's not the answer. In the scenario you describe (ie, accepting an asynchronous cue from the ATmega), what's required is a flipflop (clocked by the rising edge of Phi2) to ensure that tPCS and tPHC are satisfied (see below). Nothing tricky about it, really (for 'C02, at least). You simply need RDY to be stable -- either high or low, but not in flux -- immediately before and after the fall of Phi2.

And, because the flipflop will introduce a certain delay, the ATmega mustn't be too hasty in adjusting BE. To be on the safe side, you'd wanna allow one entire 65xx clock cycle before concluding that the RDY cue has been accepted.

HTH!

-- Jeff
Based on some suggestions a while back, I was ANDing it inside a GAL with either the rising edge of the clock or the falling edge. No real difference
Not sure I understand. ANDing does not work on edges. Can you give more details?

Where do you detect the RDY condition? On the CPU side or the bus side? If you assert BE the bus side becomes invalid....

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 6:48 pm
by Dr Jefyll
BigEd wrote:
(Have you got your rising and falling edges swapped around there??)
The swapping is intentional. But perhaps I need to be more clear.

The idea is to have the ATmega in a (possibly unrolled) loop that waits for a transition on the 'C02's Phi2. Upon detecting said transition it'll respond by raising or lowering the output pin that directly feeds the 'C02's RDY input. In arranging this scheme, we need to know what range of delays can be expected from the Phi2 transition to the change on RDY. (The delay will vary because the two CPU's use independent clocks.)

Let's say the ATmega is very fast -- fast enough that, even accounting for jitter, we know the delay from transition to response will always be comfortably less than one 'C02 clock cycle. In this case the ATmega could detect a Phi2 hi-to-low transition and issue a response that takes effect later in the same cycle that's just beginning.

But all is not lost if the transition to response delay is slower. Let's say it's in the range of (roughly) .5 to 1.4 clock cycles. In this case the ATmega could detect a Phi2 low-to-high transition (partway through one cycle) and issue a response that takes effect later in the following cycle.

-- Jeff

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 6:53 pm
by Dr Jefyll
( PS to André. Some confusion here, perhaps. I think in that sentence Gordon is describing a previously attempted scheme which indeed turned out not to work. )

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 8:12 pm
by drogon
fachat wrote:
drogon wrote:
Dr Jefyll wrote:
drogon wrote:
I was pulling Rdy low, then BE low, then fiddling with the RAM from another processor (an ATmega), then releasing BE then taking Rdy high ...
Yes, that part sound fine.
Quote:
At that point, sometimes the 65C02 would crash - it's as if it was reading a random instruction at that point.

I tried qualifying the Rdy signal with the clock (both falling and rising edges
Qualifying the Rdy signal... l can you clarify? If you mean combinatorial logic, that's not the answer. In the scenario you describe (ie, accepting an asynchronous cue from the ATmega), what's required is a flipflop (clocked by the rising edge of Phi2) to ensure that tPCS and tPHC are satisfied (see below). Nothing tricky about it, really (for 'C02, at least). You simply need RDY to be stable -- either high or low, but not in flux -- immediately before and after the fall of Phi2.

And, because the flipflop will introduce a certain delay, the ATmega mustn't be too hasty in adjusting BE. To be on the safe side, you'd wanna allow one entire 65xx clock cycle before concluding that the RDY cue has been accepted.

HTH!

-- Jeff
Based on some suggestions a while back, I was ANDing it inside a GAL with either the rising edge of the clock or the falling edge. No real difference
Not sure I understand. ANDing does not work on edges. Can you give more details?

Where do you detect the RDY condition? On the CPU side or the bus side? If you assert BE the bus side becomes invalid....
I'm not detecting it - at least in this scenario, I'm not - in my current system, I am. This may be confusing.

I have a system with an ATmega and a 65C02. The ATmega can "see" 256 bytes of RAM from $FF00 through $FFFF, but only when the 65C02 is tristated (ie. BE low).

I wanted to poke data into the memory window while the 65C02 was running, so thought initially that if I simply pulled Rdy low, then pulled BE low, then did the Atmega stuff to latch onto the RAM, store the data then do the reverse, the 6502 would not notice anything but "magically" would see new data.

I now know this doesn't work, so I have another solution that does work - it's driven from the 65C02 which executes a WAI instruction, which stops the 65C02 and sets Rdy low which the Atmega detects and does what it needs to do (bring BE low, etc. ) and finished off by sending an NMI to the 65C02 to wake it from WAI.

What I was looking to do was re-investigate the issue I had back then (2 years ago, thread linked in my first post), and see if anyone knew why so I might again look at it on my next board.

Anyway, thanks for all the input so-far. I think I might just leave this to rest for a while and file my current solution in the "if it aint broke, don't fix it" drawer...

Cheers,

-Gordon

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sat Aug 21, 2021 8:34 pm
by gfoot
drogon wrote:
I now know this doesn't work, so I have another solution that does work - it's driven from the 65C02 which executes a WAI instruction, which stops the 65C02 and sets Rdy low which the Atmega detects and does what it needs to do (bring BE low, etc. ) and finished off by sending an NMI to the 65C02 to wake it from WAI.
I think you need to be careful with relying on the WAI here - I believe any interrupt from any source will cause it to continue, and with BE low it's not going to be very happy. Perhaps if you tie RDY to BE through a resistor - instead of to +5V with the resistor as normal - it will then guarantee that RDY is held low until BE goes high again, even if an interrupt occurs. Or maybe you're already making the Arduino drive RDY after it has detected the initial low-going pulse.

I'm not sure how the 6502 responds to BE being low with RDY high and clock pulses happening. I guess it just tries to execute random instructions, which is not going to end well. :)

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sun Aug 22, 2021 2:29 am
by BillG
Dr Jefyll wrote:
( PS to André. Some confusion here, perhaps. I think in that sentence Gordon is describing a previously attempted scheme which indeed turned out not to work. )
What is the fetish with parentheses on this forum? I have not seen it anywhere else.

Is it a 6502 thing? Indirect reference?

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sun Aug 22, 2021 4:14 am
by BigDumbDinosaur
I had a thought, although it may not be applicable to this case.

If the intention of stopping the MPU and floating its outputs is so another processor can become the bus master, I think you'd have to stop the MPU when SYNC is high (or in the case of the 65C816, when VDA && VPA is true), which indicates an opcode fetch is occurring. Stopping the MPU during an opcode fetch should always be safe. Stopping the MPU during an operand fetch or any other step in the current instruction may cause trouble.

The other thing that might be worth considering is biasing the address and data buses down or up so during that brief period between when the 65C02 gets off the buses and the other processor gets on them you don't have floating signals.

Re: Anyone using Rdy to halt a 65C02 ? (or '816)

Posted: Sun Aug 22, 2021 4:19 am
by BigDumbDinosaur
gfoot wrote:
Perhaps if you tie RDY to BE through a resistor - instead of to +5V with the resistor as normal - it will then guarantee that RDY is held low until BE goes high again, even if an interrupt occurs.

You might want to think about that a little more. :D When the 65C02 executes WAI it also drives RDY low. If you tie RDY to BE the 65C02 will float the buses while WAIting.

Quote:
I'm not sure how the 6502 responds to BE being low with RDY high and clock pulses happening. I guess it just tries to execute random instructions, which is not going to end well. :)

BE and RDY have no relationship to each other. Driving BE low will not stop the MPU, which will continue to run, with undefined results.