Hi!
John West wrote:
The obvious improvement is to set LASTKB = MILLIS + 100 instead. Then
Code:
lda MILLIS
cmp LASTKB
lda MILLIS+1
sbc LASTKB+1
bcc notyet
... as Martin said while I was typing. I will leave replacing "sec / sbc" with "cmp" as my contribution.
The above (and all the other code samples given) suffer from a data race: the ISR could fire just between the first LDA MILLIS and the second LDA MILLIS+1, and the roll-up will invalidate the count:
- Suppose MILLS = $0100
- LDA MILLS ; A = 0
- Now, the ISR fires and MILLS = $00FF
- LDA MILLS+1 : A = 0
So, instead of reading $0100 or $00FF, you are reading $0000, an invalid value.
To avoid this, you must read the value properly, the only way to do it in the presence of NMI is:
Code:
readTime:
LDX MILLS+1
LDA MILLS
CPX MILLS+1
BNE readTime
RTS
Now, if you have multiple tasks waiting for a given time to perform some action, it is better to have a priority queue with all the tasks, so you only check the earliest task available each loop.
Have Fun!