Pulling Rdy Low (65C02/65816)
Pulling Rdy Low (65C02/65816)
I'm experimenting with some other ways for my Ruby 6502/816 to communicate with the ATmega host and am seeing some weird issues.
The scenario is that the 65C02/816 is running and I pull Rdy low. The CPU naturally stops running, but when I let Rdy go high (drive it high) it sometimes doesn't carry on from where it left off. This appears to be random. I don't currently have the tools to find out where or what it is doing, however if I send the 65C02 an NMI, it correctly executes the NMI code when it's in this tate. I can send it 1000's of NMIs once the main program has stalled (or gone awry) and it processes the NMIs correctly (or as correctly as I can tell from a bunch of LEDs)
Have I missed something crucial about pulling Rdy low? It's not being synchronised (by me) to any particular timing in relation to the clock (I'm not aware it has to be) and I'm not doing anything else other than pull Rdy low - wait a millisecond or 2, then take it high again.
Rdy works the other way just fine - execute a WAI instruction and Rdy goes low, the 65C02 halts and I can kick it back into life by sending it an IRQ.
Any thoughts are most welcome.
Cheers,
-Gordon
The scenario is that the 65C02/816 is running and I pull Rdy low. The CPU naturally stops running, but when I let Rdy go high (drive it high) it sometimes doesn't carry on from where it left off. This appears to be random. I don't currently have the tools to find out where or what it is doing, however if I send the 65C02 an NMI, it correctly executes the NMI code when it's in this tate. I can send it 1000's of NMIs once the main program has stalled (or gone awry) and it processes the NMIs correctly (or as correctly as I can tell from a bunch of LEDs)
Have I missed something crucial about pulling Rdy low? It's not being synchronised (by me) to any particular timing in relation to the clock (I'm not aware it has to be) and I'm not doing anything else other than pull Rdy low - wait a millisecond or 2, then take it high again.
Rdy works the other way just fine - execute a WAI instruction and Rdy goes low, the 65C02 halts and I can kick it back into life by sending it an IRQ.
Any thoughts are most welcome.
Cheers,
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Pulling Rdy Low (65C02/65816)
Pretty sure RDY is a synchronous input - unlike interrupts, you will need to sync it.
Re: Pulling Rdy Low (65C02/65816)
BigEd wrote:
Pretty sure RDY is a synchronous input - unlike interrupts, you will need to sync it.
Quote:
Sync
This line goes high during phase one of those cycles that are opcode fetches. When used with the RDY signal, this allows
hardware implementation of a single-step debugging capability.
This line goes high during phase one of those cycles that are opcode fetches. When used with the RDY signal, this allows
hardware implementation of a single-step debugging capability.
So maybe that's it. I think I have enough spare pins on a GAL, so I can AND the Rdy input (From the ATmega) to the 65C02 with Sync (Actually VPA & VDA) and I ought to be able to test this out over the weekend.
Cheers,
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Pulling Rdy Low (65C02/65816)
The important thing (I would think) is never to change RDY too close to the crucial end of phi2. Will conditioning it with SYNC achieve that?
Re: Pulling Rdy Low (65C02/65816)
Hmm, a WDC datasheet suggests we also do need to condition the interrupt and reset inputs...
See table 6-3 and figure 6-3 near page 40 of
http://datasheets.chipdb.org/Western%20 ... 65C02S.pdf
See table 6-3 and figure 6-3 near page 40 of
http://datasheets.chipdb.org/Western%20 ... 65C02S.pdf
Re: Pulling Rdy Low (65C02/65816)
BigEd wrote:
Hmm, a WDC datasheet suggests we also do need to condition the interrupt and reset inputs...
See table 6-3 and figure 6-3 near page 40 of
http://datasheets.chipdb.org/Western%20 ... 65C02S.pdf
See table 6-3 and figure 6-3 near page 40 of
http://datasheets.chipdb.org/Western%20 ... 65C02S.pdf
Cheers,
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Pulling Rdy Low (65C02/65816)
I checked an old Rockwell datasheet and it makes no sense to me: there's a hold time in the diagram, it's labelled as a setup time, and there's no other half to the story. (Even if setup time is zero I'd expect it to be labelled.)
Re: Pulling Rdy Low (65C02/65816)
I see you've just posted again while I was typing this, Ed. But your earlier post seems to be right on the money.
That makes sense, and indeed the tPCS spec says you need to allow at least 10 ns before the end of phi2 (assuming 5V operation).
One solution would be a flipflop, clocked by the rising edge of Phi2, to condition the incoming signal before it's applied to RDY.
BigEd wrote:
The important thing (I would think) is never to change RDY too close to the crucial end of phi2.
One solution would be a flipflop, clocked by the rising edge of Phi2, to condition the incoming signal before it's applied to RDY.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: Pulling Rdy Low (65C02/65816)
BigEd wrote:
unlike interrupts, you will need to sync it.
The CPU designers (quite reasonably) anticipated that interrupts may arrive from unsynchronized sources (such as a human typing on a keyboard) and they accordingly included synchronizing flipflops internally on-chip. Because synchronizers are provided the chance of a failure due to ignoring the restrictions is vanishingly small. Gordon's experience (and that of others) supports this assertion.
RDY, on the other hand, is typically driven by a memory decoder, not by some unknown and unsynchronized source outside the microcomputer. Because it'd be unnecessary -- indeed, counterproductive -- no internal synchronizer is provided for RDY. Thus in the RDY context violations of tPCS and tPCH are a far more serious concern.
Dr Jefyll wrote:
One solution would be a flipflop, clocked by the rising edge of Phi2, to condition the incoming signal before it's applied to RDY.
Quote:
When you violate the setup-and-hold times on a flip-flop, the output might erratically go high, stay low, or pop one way and then back again. EDN 3/16/2000
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: Pulling Rdy Low (65C02/65816)
So... After some time out for other stuff, health, etc. I've had a chance to get back to this.
If I qualify Rdy with the ph2 signal, so my Rdy out from the host is latched on the rising edge of ph2 then it works perfectly. It's one line of logic and 2 spare pins in the GAL and a couple of bodge wires. I'm now not using the Rdy output signal from the 65816 so I've no concerns there - unless it has a crash and mistakenly executes a WAI instruction..
My reason for changing the way I handle all this in my Ruby system is due to interrupt handling. I want the 6502/816 to be able to handle interrupts and using WAI to communicate with the host makes this more complex than I want it to be. Now the 6502/816 uses an otherwise unused bit in the VIA to signal the host when it wants stuff and can poll the shared memory to see if the host has anything urgent to send to the 6502/816.
Happy new year, everyone!
Cheers,
-Gordon
If I qualify Rdy with the ph2 signal, so my Rdy out from the host is latched on the rising edge of ph2 then it works perfectly. It's one line of logic and 2 spare pins in the GAL and a couple of bodge wires. I'm now not using the Rdy output signal from the 65816 so I've no concerns there - unless it has a crash and mistakenly executes a WAI instruction..
My reason for changing the way I handle all this in my Ruby system is due to interrupt handling. I want the 6502/816 to be able to handle interrupts and using WAI to communicate with the host makes this more complex than I want it to be. Now the 6502/816 uses an otherwise unused bit in the VIA to signal the host when it wants stuff and can poll the shared memory to see if the host has anything urgent to send to the 6502/816.
Happy new year, everyone!
Cheers,
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Pulling Rdy Low (65C02/65816)
Wrapping this up:
The above scheme of qualifying Rdy with ph2 wasn't a 100% success - the 6502/816 would still crash, seemingly at random, and lacking the tools (a fast logic analyser) I went for a plan B (although more like D by this stage!)
The issue appears to be an incoming IRQ when the 6502/816 executes the WAI instructions. This causes the CPU to re-start after the WAI instruction (by design - that's the fast IRQ mechanism)
This is not quite what I want, so as all incoming IRQs go through a GAL (just acting as a 3-input OR gate), then I added in another term to AND them with the Rdy signal which is now an output only signal from the CPU, I'm no longer driving it from the ATmega host. The idea being the when Rdy is low, then IRQs will be held off, so the host (ATmega) processor can do its thing then it sends an NMI to the 6502/816 which causes it to carry on (NMI just points to an RTI). At that point, any pending IRQ can get through and execute as normal, although with a slight delay. (Which is fine and I put up with lack of proper high speed interrupts as I'm using NMI here).
That worked - most of the time, but I was seeing the very occasional glitch - which I eventually worked out was manifesting itself as a missing packet of data from the CPU to the host.
I worked out what was happening was that an IRQ would come in (from the T1 timer in the VIA) at the exact point the SEI instruction (or possibly the start of the WAI instruction) was executing in the
sequence. This caused the WAI to essentially act as a NOP. Rdy didn't go low, so the ATmega never saw the signal. Probably for the best at this point as the next thing the ATmega would do is pull BE low which 100% crashes the 6502 when Rdy is high.
My solution was to check to see if the host communication had actually taken place via the shared RAM page and if-not then re-do it.
This has now been working with my stress test (passing data back and forth to the host as fast as it can), for over 12 hours now with T1 running 100x faster than normal and I'm happy. (and I've just realised the SEI/CLI is now superfluous too, so removed them and running the test again and so far, so good..)
-Gordon
The above scheme of qualifying Rdy with ph2 wasn't a 100% success - the 6502/816 would still crash, seemingly at random, and lacking the tools (a fast logic analyser) I went for a plan B (although more like D by this stage!)
The issue appears to be an incoming IRQ when the 6502/816 executes the WAI instructions. This causes the CPU to re-start after the WAI instruction (by design - that's the fast IRQ mechanism)
This is not quite what I want, so as all incoming IRQs go through a GAL (just acting as a 3-input OR gate), then I added in another term to AND them with the Rdy signal which is now an output only signal from the CPU, I'm no longer driving it from the ATmega host. The idea being the when Rdy is low, then IRQs will be held off, so the host (ATmega) processor can do its thing then it sends an NMI to the 6502/816 which causes it to carry on (NMI just points to an RTI). At that point, any pending IRQ can get through and execute as normal, although with a slight delay. (Which is fine and I put up with lack of proper high speed interrupts as I'm using NMI here).
That worked - most of the time, but I was seeing the very occasional glitch - which I eventually worked out was manifesting itself as a missing packet of data from the CPU to the host.
I worked out what was happening was that an IRQ would come in (from the T1 timer in the VIA) at the exact point the SEI instruction (or possibly the start of the WAI instruction) was executing in the
Code: Select all
SEI
WAI
CLIMy solution was to check to see if the host communication had actually taken place via the shared RAM page and if-not then re-do it.
Code: Select all
; hostCall:
; Initiate a data transfer with the host.
; Entry: A contains the code.
; Additional data passed in sBuf ($FF00-$FF7F), sBufCmd and sBufParam
;********************************************************************************
_hostCall:
sta sBufCmd
: sei ; Disable IRQs
wai ; All STOP until the host pokes us.
cli
lda sBufCmd ; Check to see if the host actually did something
bne :- ; ... if not
rts-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Pulling Rdy Low (65C02/65816)
drogon wrote:
Wrapping this up:
The above scheme of qualifying Rdy with ph2 wasn't a 100% success - the 6502/816 would still crash, seemingly at random, and lacking the tools (a fast logic analyser) I went for a plan B (although more like D by this stage!)
The above scheme of qualifying Rdy with ph2 wasn't a 100% success - the 6502/816 would still crash, seemingly at random, and lacking the tools (a fast logic analyser) I went for a plan B (although more like D by this stage!)
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Pulling Rdy Low (65C02/65816)
BigDumbDinosaur wrote:
drogon wrote:
Wrapping this up:
The above scheme of qualifying Rdy with ph2 wasn't a 100% success - the 6502/816 would still crash, seemingly at random, and lacking the tools (a fast logic analyser) I went for a plan B (although more like D by this stage!)
The above scheme of qualifying Rdy with ph2 wasn't a 100% success - the 6502/816 would still crash, seemingly at random, and lacking the tools (a fast logic analyser) I went for a plan B (although more like D by this stage!)
But no - I'd not thought to halt the clock as I felt I could do what I wanted to do with WAI and Rdy - and that all worked perfectly until I wanted to service external interrupts, however I have a solution now that allows it to all work and allow external IRQs to come in and be correctly serviced, so I'm happy.
Cheers,
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/