Mini-challenge: detecting activity on a port

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: Mini-challenge: detecting activity on a port

Post by Chromatix »

The point is that the question didn't say anything about the timing relationships of the transitions, so any window in which a transition could be missed is potentially a problem - one that could prove hard to debug, especially if the signals are asynchronous to the CPU clock. It does no good to reduce the window to 4 cycles, if transitions on different bits can be seen 1 cycle apart, regardless of any specification about the time between transitions of the same bit.

So you need to load the current port value, save it somewhere, and use the same value to compare against the previous value. I think that requires three memory locations, one of which is used to remember the previous value, and the other two are used to count transitions.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Mini-challenge: detecting activity on a port

Post by barrym95838 »

I'm pretty sure I understand your point. Thanks for explaining it clearly enough that even this old dog can get it!

... (maybe if I can figure out an economical way to wedge the LDY between the TYA and the EOR?????)

Code: Select all

attempt3:
    ldy  PORT
    lda  #0        ; initialize bit trackers
    sta  once
cont:
    sta  twice     ; track bits that flipped >= twice
    beq  first
    txa
    ora  once      ; 1s for bits that flipped >= once
    sta  once      ; track bits that flipped >= once
    tya
    ldy  PORT
    eor  PORT      ; check for PORT activity
first:
    tax            ; 1s for bits that flipped this time
    and  once
    ora  twice     ; 1s for bits that flipped >= twice
    cmp  #$ff      ; have all 8 bits flipped >= twice?
    bne  cont
    rts
(just randomly brain-storming now ...)
Last edited by barrym95838 on Tue Mar 31, 2020 4:09 pm, edited 1 time in total.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
dmsc
Posts: 154
Joined: 17 Sep 2018

Re: Mini-challenge: detecting activity on a port

Post by dmsc »

Hi!
leepivonka wrote:
Using this approach and again using a state machine, this works (NMOS instructions):

Code: Select all

wait:
   ; Init old input var
   lda INPUT
   sta OLD_IN
   lda #255
   ldx  #0
loop:
   sta S_X
   txa
   eor #$FF
   and S_X
   sta S_Y    ; Y' = X * ~(I * X) = X * (~I + ~X) = X*~I + X*~X = X * ~I
   ; Check toggled bits without updating old value
   lda INPUT
   eor OLD_IN
   ; Filter out already detected
   and S_X
   tax
   ora S_Y     ; X' = I * X + Y

   ; Compare X with 0 (al bits reset
   bne loop
   ; Ok!
   rts
I also changed S_X so that it is all bits 0 to simplify the comparison. It's 29 bytes, a little shorter than before. I suspect that changing the meaning of S_X and S_Y it could be shorter...

Have Fun!
kakemoms
Posts: 349
Joined: 02 Mar 2016

Re: Mini-challenge: detecting activity on a port

Post by kakemoms »

Alternately you can use two flip-flops (2-bit shift register) and a XOR per bit, then OR all the outputs and put them on the NMI/IRQ. That way you get an interrupt when one of the bits change.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Mini-challenge: detecting activity on a port

Post by BigEd »

(Don't worry about missing things as you go around the loop! If it helps, suppose the port changes pretty slowly compared to the 6502. As stated, the idea is not to miss any transitions that you do see.)
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Mini-challenge: detecting activity on a port

Post by barrym95838 »

Even so, my second and smallest attempt is still unacceptable to me, because it spends about 10% of its time "blinking its eyes", which is too much.

If I'm not horribly mistaken, my first attempt "stares" and closes its "eyes" only to digest a transition, and my third attempt never closes its "eyes".
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: Mini-challenge: detecting activity on a port

Post by Chromatix »

Code: Select all

    ldy  PORT
    eor  PORT      ; check for PORT activity
This is still theoretically problematic, because it reads the port twice, 4 cycles apart. My solutions read it only once per pass, so they're guaranteed to see any transition after the initialisation phase.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Mini-challenge: detecting activity on a port

Post by barrym95838 »

I would never presume or intentionally imply that my solution was better or even equal to yours. I was simply jamming on an independent groove over here ... please try not to get too offended by any sour notes I've been hitting, and I'll get tired of trying soon enough ... :)
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
mvk
Posts: 81
Joined: 21 Mar 2017

Re: Mini-challenge: detecting activity on a port

Post by mvk »

Chromatix wrote:
My solutions read it only once per pass, so they're guaranteed to see any transition after the initialisation phase.
What happens when PORT has more than one state change within your polling interval?
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: Mini-challenge: detecting activity on a port

Post by barrym95838 »

mvk wrote:
What happens when PORT has more than one state change within your polling interval?
I think that violates Ed's revised spec, Marcel. My interpretation is that transitions occur asynchronously, but don't bunch up too tightly for a reasonable 65xx loop to process.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
mvk
Posts: 81
Joined: 21 Mar 2017

Re: Mini-challenge: detecting activity on a port

Post by mvk »

barrym95838 wrote:
mvk wrote:
What happens when PORT has more than one state change within your polling interval?
I think that violates Ed's revised spec, Marcel. My interpretation is that transitions occur asynchronously, but don't bunch up too tightly for a reasonable 65xx loop to process.
Ok fair, I missed that.

But then isn't there indeed a race condition if you don't anticipate a transition between two consecutive read instructions? After all, transitions must occur. And without synchronisation they can occur anywhere.
Last edited by mvk on Tue Mar 31, 2020 6:54 pm, edited 1 time in total.
User avatar
BigEd
Posts: 11464
Joined: 11 Dec 2008
Location: England
Contact:

Re: Mini-challenge: detecting activity on a port

Post by BigEd »

> My interpretation is that transitions occur asynchronously, but don't bunch up too tightly for a reasonable 65xx loop to process.

Yes, that's about right.
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: Mini-challenge: detecting activity on a port

Post by floobydust »

So perhaps it would be a suitable to make this part of an interrupt service routine which occurs every xx milliseconds and sets a page zero location when the detection meets the criteria.
Chromatix
Posts: 1462
Joined: 21 May 2018

Re: Mini-challenge: detecting activity on a port

Post by Chromatix »

That would be a reasonable design if the ISR is serviced more frequently than the minimum high/low times for each individual bit. I think my code can easily be adapted to that, as it keeps all its critical state in RAM, not in registers, between iterations. But as a tight loop it can correctly handle signals up to tens of kilohertz if needed; eg. a 100kHz signal would have high and low times of 40 clock cycles at 8MHz, which would be reliably seen by even my slowest 37-cycle loop.

The discussion about race conditions has more to do with skew between transitions on multiple bits. If the port state being compared against was sampled separately from the port state used for the previous comparison, then a transition on a second bit could be lost while servicing the transition of a first bit, even if both bits are individually low-frequency. You can even imagine slow signals transitioning at the same time, but triggering their respective Schmitt triggers during different CPU cycles. My routines don't mind skew; if a transition happens too late for one loop, it'll be seen by the next. The key code is the following:

Code: Select all

: LDA port
  TAX
  EOR prev
  STX prev
This reads the port once while both comparing it to the previous value, and storing it for later.
User avatar
floobydust
Posts: 1394
Joined: 05 Mar 2013

Re: Mini-challenge: detecting activity on a port

Post by floobydust »

I agree with what you're saying. However, from my view, the real problem is that we don't have sufficient detail on the port being monitored to create a reliable solution. As an example, let's say you have a 6502 running at 1MHz. Lets also say that the routine to poll the port takes 25 clock cycles. That's 25 microseconds... if the port changes at a rate of less than 25 microseconds, the routine doesn't work. In fact, even at rate change of 25 microseconds, you could end up losing samples as the port updates are not synchronous with the 6502 clock and executing code.

So... I would go back to the spec (create by BigEd) and ask for the minimum time for bit changes at the port. If you don't know this critical parameter, you can't claim to provide a reliable solution. As has been noted, one can create a routine that handle a range of port changes up to a certain rate, but until the absolute rate is known, it's still a best guess scenario.

Having a hardware port that generates an interrupt whenever a bit changes would greatly simplify this, but you would still need to the absolute rate of change of the port data to design a working solution, i.e., you might need a faster CPU clock (than 1MHz).
Post Reply