Mini-challenge: detecting activity on a port
Re: Mini-challenge: detecting activity on a port
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.
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.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Mini-challenge: detecting activity on a port
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?????)
(just randomly brain-storming now ...)
... (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
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)
Mike B. (about me) (learning how to github)
Re: Mini-challenge: detecting activity on a port
Hi!
Using this approach and again using a state machine, this works (NMOS instructions):
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!
leepivonka wrote:
Code: Select all
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
Have Fun!
Re: Mini-challenge: detecting activity on a port
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.
Re: Mini-challenge: detecting activity on a port
(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.)
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Mini-challenge: detecting activity on a port
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".
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)
Mike B. (about me) (learning how to github)
Re: Mini-challenge: detecting activity on a port
Code: Select all
ldy PORT
eor PORT ; check for PORT activity
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Mini-challenge: detecting activity on a port
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)
Mike B. (about me) (learning how to github)
Re: Mini-challenge: detecting activity on a port
Chromatix wrote:
My solutions read it only once per pass, so they're guaranteed to see any transition after the initialisation phase.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Mini-challenge: detecting activity on a port
mvk wrote:
What happens when PORT has more than one state change within your polling interval?
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)
Mike B. (about me) (learning how to github)
Re: Mini-challenge: detecting activity on a port
barrym95838 wrote:
mvk wrote:
What happens when PORT has more than one state change within your polling interval?
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.
Re: Mini-challenge: detecting activity on a port
> 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.
Yes, that's about right.
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: Mini-challenge: detecting activity on a port
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.
Regards, KM
https://github.com/floobydust
https://github.com/floobydust
Re: Mini-challenge: detecting activity on a port
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: This reads the port once while both comparing it to the previous value, and storing it for later.
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
- floobydust
- Posts: 1394
- Joined: 05 Mar 2013
Re: Mini-challenge: detecting activity on a port
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).
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).
Regards, KM
https://github.com/floobydust
https://github.com/floobydust