6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat May 11, 2024 2:48 am

All times are UTC




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Fri Dec 06, 2019 7:38 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1411
Location: Scotland
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

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 7:53 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
Pretty sure RDY is a synchronous input - unlike interrupts, you will need to sync it.


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 8:48 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1411
Location: Scotland
BigEd wrote:
Pretty sure RDY is a synchronous input - unlike interrupts, you will need to sync it.


Hmmm... Reading the data sheet for the 65816 doesn't suggest anything special, however, the Assembly language programming manual says (page 7)

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.


Although this is in the 6502 section, not the 65C02 section, however it doesn't add to that.

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/


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 9:02 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
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?


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 9:05 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
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


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 9:09 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1411
Location: Scotland
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


I think the timing there refers to when they get sampled (the input pins). Maybe one day we'll get definitive documentations!

Cheers,

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 9:37 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10800
Location: England
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.)


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 9:42 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
I see you've just posted again while I was typing this, Ed. But your earlier post seems to be right on the money. :)

BigEd wrote:
The important thing (I would think) is never to change RDY too close to the crucial end of phi2.
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.

Attachment:
Figure 6-3.png
Figure 6-3.png [ 70.41 KiB | Viewed 1674 times ]

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 06, 2019 10:47 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3354
Location: Ontario, Canada
BigEd wrote:
unlike interrupts, you will need to sync it.
Unlike interrupts, yes -- and that's where the doc seems excessively cautious (in that it applies the tPCS and tPCH restrictions not just to the RDY input but also to the interrupt inputs). Arguably that caution is warranted in a critical setting such as life-support, but for anything less demanding I think it's reasonable for the interrupt inputs to be exempted from the tPCS and tPCH restrictions.

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.
I think you'll find this solution effective. But it's not rigorous -- there's a great deal more that can be said. Briefly, the technology for a 100% reliable synchronizer doesn't exist. See these documents pertaining to metastability.

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


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 31, 2019 8:43 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1411
Location: Scotland
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

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 27, 2020 9:11 am 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1411
Location: Scotland
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

Code:
    SEI
    WAI
    CLI


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.

Code:
; 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


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

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 27, 2020 3:16 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8178
Location: Midwestern USA
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!)

Have you given any thought to halting Ø2 instead of using RDY to generate wait-states?

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 27, 2020 3:40 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1411
Location: Scotland
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!)

Have you given any thought to halting Ø2 instead of using RDY to generate wait-states?


I'm not generating wait states although the net effect is similar. It's part of a 2-processor communication system via a small section of 'shared' RAM which only one processor can access it at any time.

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/


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: