Hi
Will this code work if Z is a 10-bit counter and thus overflow at 1023 while Z is 16-bit?
lsr ZH ;Z / 2 ror ZL brcc noOvf noOvf:
If this not work how can I get a 10-bit overflow in Z?
Hi
Will this code work if Z is a 10-bit counter and thus overflow at 1023 while Z is 16-bit?
lsr ZH ;Z / 2 ror ZL brcc noOvf noOvf:
If this not work how can I get a 10-bit overflow in Z?
Z is 16 bit, so it can not overflow at 10 bits. You will have to test the bit manually. But if the value in Z is less than 1024, shifting right will not make it overflow since the new value is necessarily less that the old value. What your code will do, however, is put the LSB of Z into the carry, which will affect the branch (but not do what you want it to do).
adiw ZL,1 ; Increment a counter (for example) sbrc ZH,2 ; Bit ZH.2 means bit Z.10, i.e. carry from bit 9 rjmp overf noov: .... overf: ....
You could also use the upper 10 bits.
Then you add 64 in order to increment.
Then at overflow the usual flags will work.
adiw ZL,1 ; Increment a counter (for example) sbrc ZH,2 ; Bit ZH.2 means bit Z.10, i.e. carry from bit 9 rjmp overf noov: .... overf: ....
You could also use the upper 10 bits.
Then you add 64 in order to increment.
Then at overflow the usual flags will work.
That'll work, provided the rest of your code can work with a value that is 64x in magnitude. Likely to be a problem if the value is being used to access a table of data. Note that a similar effect can be achieved by fixing the upper bits to 1's, this will add an offset to the result, but it can easily be subtracted or masked back out.
@RES: Is overflow detection really needed, or is it fine if the value simply rolls over? If the roll-over is fine, you can simply mask the upper bits to 0 after each increment/decrement.
Scale up to 12 bits, and use the half-carry?
That should be sbrc, not sbrs, as you want to call "overf" when there is an overflow. Bit 10 will be set on an overflow, and clear otherwise. Just be sure it is clear before your calculation.
hahaha, yeah, I had to go back and add the quotation because of ossi's post popping up between my reply to yours. Didn't notice that you corrected it.
Is the counter being incremented by 1 or some other increment each time? If not 1 then just testing bit 11 of the 16 for being set may not be enough. Instead you need to test for a 1 anywhere in the top 6 bits. As the 16 bits are split ZH,ZL this would mean ANDing ZH with 0xFC and testing for Z
Scale up to 12 bits, and use the half-carry?
I would do it (as glitch) set all the unused bit's to one so a overflow on 10th bit make a overlow on 16th aswell, and just AND those bit's away if you need the the real value.
It looks like I have to do this?
lsr ZH ;Z / 2 ror ZL ori ZH, 0xfc ;set upper bits for ovf brcc noOvfnoOvf:
In the next rounds I need to know if 10-bit_Z was overflowed, then I have to wait for 0 and reset the flag.
But there is no overflow in the operation you are performing! You are dividing by two. The carry bit is only going to indicate the value of the bit that was shifted out. Setting the high bits in this case is not adding any value. In fact it is going to work against you in the next round.
you really need to explain more of what it is exactly you are trying to achieve. Like many of your other posts, you seem to focus too much on the minute detail, instead of looking at the overall operation.
Does this piece of code give exactly the same result ..
ldi temp, low(1022) cp ZL, temp ldi temp, high(1022) cpc ZH, temp brlo noOvf cli stop: rjmp stop noOvf:
.. as this piece of code? It seems like it does. Or does the second code always stop? (forced set c?)
subi ZH, -0xfc brcc noOvf cli stop: rjmp stop noOvf:
Z going round from 0 - 1023.
What about having Z go from 1023-0 and using a BREQ instead?
Z going round from 0 - 1023.