Single stepping with RDY, re-implementing Woz's circuit

For discussing the 65xx hardware itself or electronics projects.
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

Hi!

Woz's 6502 single stepping circuit (attached below) has been covered already in this forum. The goal of this circuit is to generate a low-going pulse of RDY that lasts only a single clock cycle. This allows an external process to pause the CPU during execution, and examine the contents of the busses.
sy4xmw3y8po41.gif
To make use of such a circuit, the rest of the glue logic needs to be adapted. /RD and /WR pulses going to memory need to stay active while RDY is low. Additionally, if using a 65C816, the bank address latch needs to stay closed, and the data bus buffer needs to stay on. Finally, I/O devices such as the 65C21, 65C22 and 65C51 use a direct clock input, and this also needs to stay high while RDY is low. This is to prevent reads and writes to be repeated in a loop between stepping pulses, and for the data bus to remain valid. Of course this messes with the VIA's timers. I think a solution to that can be found by isolating the VIA but I'll talk about that later.

We also need to make sure that RDY does not change when the clock is low, to avoid generating spurious reads and writes with the logic below:

Code: Select all

!RD = (CLK || !RDY) && RWB
!WR = (CLK || !RDY) && !RWB

# For I/O chips (not if using VIA's timers)
IOCLK = CLK || !RDY

# For 65C816
573_LE = !(CLK || !RDY)
!245_OE = CLK || !RDY
In any case, I needed to implement Woz's circuit in modern logic, and most importantly, I wanted an external circuit (such as an Arduino) to drive the inputs rather than mechanical switches. I also wanted to take care to properly synchronize the inputs to the clock (double-flopping), to avoid glitches in the output.

So, here is my version of the circuit. I was able to squeeze it in 3 chips, by removing the instruction single stepping I don't need (with SYNC).
I hope this is useful to someone else! I'm also attaching a Digital simulation to try it out. Feedback is welcome!
Screenshot 2023-06-30 at 15.33.52.png
Attachments
stepping_digital.zip
(1.65 KiB) Downloaded 110 times
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by BigDumbDinosaur »

Every requirement you’ve described for use of RDY is why I use clock stretching for wait-states. As for single-stepping, all that is needed is to stop the clock in either phase.

Incidentally, RDY should not be directly driven by any device’s output. Either an isolation diode (Schottky) or resistor should be inserted into the circuit to protect the 816 in the event it drives RDY low while the other device is driving it high. The diode method is preferable, in my opinion.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

Sure, and that's a fine option too. Conceptually, this is also kind of clock stretching, only I do it by replacing the clock with (CLK || !RDY) everywhere except the CPU.
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by cjs »

BigDumbDinosaur wrote:
As for single-stepping, all that is needed is to stop the clock in either phase.
Well, so long you don't mind the contents of your registers vanishing.

Or you're one of those kids using only the modern remakes of the real 6502, such as the 65C02. :-)

BTW, I always find it interesting to compare these kinds of things to the original suggested static test control logic that MOS gave us, back in the day.
Attachments
6502-sstcl.jpg
Curt J. Sampson - github.com/0cjs
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

cjs wrote:
BigDumbDinosaur wrote:
As for single-stepping, all that is needed is to stop the clock in either phase.
Well, so long you don't mind the contents of your registers vanishing.

Or you're one of those kids using only the modern remakes of the real 6502, such as the 65C02. :-)

BTW, I always find it interesting to compare these kinds of things to the original suggested static test control logic that MOS gave us, back in the day.
Really enjoyed looking at this circuit, thanks for sharing!
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

For fun, here is a new version that re-introduces the option to step through instructions as the original did, and uses a spare OR gate to generate the stretched clock signal, in only four chips! (two if you don't care about synchronising inputs to the clock). Feedback welcome!
6502_single_stepping_revB.png
Attachments
6502_single_stepping_revB.zip
Digital simulation
(2.29 KiB) Downloaded 107 times
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

I've been working on how to integrate the VIA into this circuit. My primary concern is to keep its clock input connected to PHI2, in order for internal timers to work as expected, while keeping the data bus valid as long as RDY is low.

I also want to avoid reads from and writes to the VIA being repeated every cycle that RDY is low, because it could mess with interrupts. For example if we happen to read the status register, and with counters if we happen to write them.

At the moment, I have only considered reads. The idea is to use the VIA's chip select input to select it only once during a RDY cycle. Additionally, we need to latch the data bus at that moment to keep the data available for the rest of the cycle.

So, here is the logic I came up with (please note that it is missing writes handling):
via-rdy-RevB.png
The inputs to this circuit are:
- CLK is the clock, CLK+ is the clock delayed 10ns to satisfy the CPU read hold times
- /IOCS is the chip select for the VIA's address
- /RDY is the inverted RDY signal we get from the output flip flop in the circuit above

The outputs are:
- IOCLK is the clock stretched with RDY
- VIA_LE is the latch enable signal for the VIA's data outputs
- /VIA_CS is /IOCS active for a single cycle
- /VIA_LOE is the output enable for the latch

Here is the timing diagram I came up with, that shows RDY going low for two cycles, and the data being latched. This is at around 8MHz and uses a 22V10 for /IOCS. I think it would be more practical to implement everything in a single CPLD but for now this speed makes the diagram more readable.
via-rdy-timing-RevA.png
As you can see, there is a period of 42ns of uncertainty / potential contention between the VIA's CS going high, and the latch's OE going low, but since they'll both be outputting the same bits, I'm not too worried, especially if I speed this up in a CPLD.

Next up is adding writes to this circuit. One issue I'm having is I want writes to happen at the end of IOCLK, just like they would if it was the actual slowed clock. However, it's not obvious to me how to detect the end of RDY low and do a write in the remaining time. It would probably mean that this circuit has to request an additional RDY low cycle for the write to happen, which might complicate the logic. We'll see what I can figure out next!
Last edited by akohlbecker on Fri Jul 21, 2023 8:26 am, edited 3 times in total.
gfoot
Posts: 871
Joined: 09 Jul 2021

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by gfoot »

akohlbecker wrote:
Here is the timing diagram I came up with
Nice detailed diagram! Is that hand-drawn or do you have a tool to help generate these?
Quote:
As you can see, there is a period of 42ns of uncertainty / potential contention between the VIA's CS going high, and the latch's OE going low, but since they'll both be outputting the same bits, I'm not too worried, especially if I speed this up in a CPLD.
I didn't understand what you mean by contention here - the latch's outputs don't seem to be connected to the same bus as the VIA's data pins, so it's fine for them to overlap. Or did I miss something?
Quote:
Next up is adding writes to this circuit. One issue I'm having is I want writes to happen at the end of IOCLK, just like they would if it was the actual slowed clock. However, it's not obvious to me how to detect the end of RDY low and do a write in the remaining time. It would probably mean that this circuit has to request an additional RDY low cycle for the write to happen, which might complicate the logic. We'll see what I can figure out next!
As I'm sure you're aware, the VIA's chip select and other control inputs have to be valid before its PHI2 goes high, so if RDY is lowered after PHI2 goes high, you're already committed to this particular PHI2 cycle being the one with the VIA active - as it has already begun. This is as shown in your diagram for the read cycle, but I think you have no choice but to also do it this way for the write cycle.

My understanding is that the CPU will complete its phase 2 processing in the usual time, in spite of RDY being low, but then wait for RDY to be high again, and a falling edge of PHI2, before it continues to the next cycle. So the data to be written should still be available the at usual time dellay after the initial rising edge of PHI2, and your VIA should accept the write at that point without problems.
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

gfoot wrote:
Nice detailed diagram! Is that hand-drawn or do you have a tool to help generate these?
The rendering engine for the diagram is Wavedrom https://wavedrom.com/, with a few patches by me (most importantly a narrower theme for more horizontal space) as seen on my GitHub here https://github.com/wavedrom/wavedrom/co ... drom:trunk

Now, this tool generates cool looking diagrams but its syntax is obnoxiously arcane. I have a library I haven't published yet that helps me with writing it in a sane way.
gfoot wrote:
I didn't understand what you mean by contention here - the latch's outputs don't seem to be connected to the same bus as the VIA's data pins, so it's fine for them to overlap. Or did I miss something?
Apologies, I was rushing to publish this before leaving for the week-end and I made a mistake in the schematic. In this scheme the VIA is connected to the data bus, and the latch outputs are connected to its inputs and to the data bus. I will fix it now
gfoot wrote:
As I'm sure you're aware, the VIA's chip select and other control inputs have to be valid before its PHI2 goes high, so if RDY is lowered after PHI2 goes high, you're already committed to this particular PHI2 cycle being the one with the VIA active - as it has already begun. This is as shown in your diagram for the read cycle, but I think you have no choice but to also do it this way for the write cycle.

My understanding is that the CPU will complete its phase 2 processing in the usual time, in spite of RDY being low, but then wait for RDY to be high again, and a falling edge of PHI2, before it continues to the next cycle. So the data to be written should still be available the at usual time dellay after the initial rising edge of PHI2, and your VIA should accept the write at that point without problems.
I haven't fully thought it through yet, but in the write case, I would like the VIA's CS pulse to be delayed until the last cycle where RDY is low, to mimic the behavior where the clock itself is stretched.

Say if you're manually single stepping, RDY goes low, you see that this cycle is a write to the via of some data, and when you push the button to go the next cycle, this is when the VIA updates its outputs.

So, when you push the button, RDY pulses high for one cycle, but that is clocked by PHI2! Since the VIA needed its CS pulse to start earlier, it doesn't work. So I have more thinking to do about that :idea:
gfoot
Posts: 871
Joined: 09 Jul 2021

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by gfoot »

Perhaps you can clock your RDY circuit at some point while PHI2 is still low. I presume you still need SYNC to be valid but you may be able to time something far enough after PHI2 falls for SYNC/A0-15/RWB to be valid but early enough to still have time to conditionally suppress the clock from reaching the VIA. You might also, or instead, be able to give the VIA a shorter, later clock pulse in general perhaps?

Regarding the latch, you can also consider using some form of bus-holding circuit like this:
busholder.png
See also https://www.ti.com/lit/an/scla015b/scla ... 9895489474 for better advice on that!
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

gfoot wrote:
Perhaps you can clock your RDY circuit at some point while PHI2 is still low. I presume you still need SYNC to be valid but you may be able to time something far enough after PHI2 falls for SYNC/A0-15/RWB to be valid but early enough to still have time to conditionally suppress the clock from reaching the VIA. You might also, or instead, be able to give the VIA a shorter, later clock pulse in general perhaps?

Regarding the latch, you can also consider using some form of bus-holding circuit like this:
busholder.png
See also https://www.ti.com/lit/an/scla015b/scla ... 9895489474 for better advice on that!
Good suggestions, and very informative app note, thanks
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

I think your first idea was the most practical! I do not really need instruction stepping / SYNC.

Replacing U1B in the top-most post with an AC112 triggered by the fall of CLK+ (ie the clock delayed by 10ns - so that the signal still satisfies tPCH), I can get RDY generated right at the beginning of PHI2 low, giving me ample time to react to it. Computing the stretched clock can't happen with just an OR gate in this scheme, so more changes are needed. I'll get to work on exploring that :mrgreen:

I also looked into a shorter pulse for the VIA, but if I'm thinking about reaching 14MHz+ it is less ideal.
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

Actually, now that I think about it, if the circuit is in instruction stepping mode, it will not pause a VIA cycle in regular conditions (outside of executing code from the VIA's registers :mrgreen: ). And in cycle stepping mode, SYNC is ignored. Maybe I can keep this functionality by changing on which edge I generate RDY depending on the mode. Not sure if worth it
User avatar
akohlbecker
Posts: 282
Joined: 24 Jul 2021
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by akohlbecker »

I have made some more progress on the reading side. With the bus holding circuit suggested by gfoot, I was able to save two pins from my CPLD. So, the added cost of handling the VIA reads in this scheme are one CPLD flip-flop per VIA, one buffer IC and one resistor network (but it removes the resistor network needed for data bus pull down I use for BE low).

One simplification I got was also from better understanding the VIA's timings. I thought I needed CS to be valid during the PHI2 high, and held 10ns after that, but the datasheet actually mentions that it only needs to be valid around PHI2's rising edge. Which means I don't actually need my 10ns shifted clock signal.

I'm still going back and forth on what to do with writes. On one hand, I would like this to be agnostic to what RDY is used for and only rely on it being valid around the falling edge of the clock, on the other hand, I don't want to add an extra cycle for writes. I don't see other compromises to make so I'll have to pick one :mrgreen:
Screenshot 2023-07-24 at 12.52.07.png
wavedrom(6).png
fachat
Posts: 1124
Joined: 05 Jul 2005
Location: near Heidelberg, Germany
Contact:

Re: Single stepping with RDY, re-implementing Woz's circuit

Post by fachat »

I am not sure I understand your schematics. Why is the output of the '541 always connected to the data bus?

But anyway, what tool are you using to draw these timing diagrams?
Author of the GeckOS multitasking operating system, the usb65 stack, designer of the Micro-PET and many more 6502 content: http://6502.org/users/andre/
Post Reply