## 10-bit overflow in Z prob?

16 posts / 0 new
Author
Message

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?

RES

Last Edited: Wed. Nov 4, 2009 - 07:22 PM

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).

Regards,
Steve A.

The Board helps those that help themselves.

```        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.

Megger wrote:

```        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:
....
```

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.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

ossi wrote:
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.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

Scale up to 12 bits, and use the half-carry?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

glitch wrote:

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.

Right. I have corrected this just before you replied as you can see in your quote :D

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.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

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

Quote:

Scale up to 12 bits, and use the half-carry?

Just remember that ADIW don't set the half bit !!!

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	noOvf

noOvf:

```

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.

RES

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.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

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.

RES

Last Edited: Wed. Nov 4, 2009 - 07:21 PM

What about having Z go from 1023-0 and using a BREQ instead?

Cheers,

Joey