Shop OBEX P1 Docs P2 Docs Learn Events
SX/B Word Subtraction Carry Error — Parallax Forums

SX/B Word Subtraction Carry Error

pjvpjv Posts: 1,903
edited 2009-06-26 14:26 in General Discussion
Hello Terry;

I need to do some division with 32 bit Unix time, and have written a routine for that, using SX/B as much as I can (hence the earlier question regarding rotates vs shifts), employing the classical 'subtract, test addback and shift' method. However·I'm getting some errors, and find that the carry-out of a word subtraction will generate the wrong carry state for a certain range of numbers, specifically those where subtractor word is smaller than the subtrahend (while the upper byte of the subtractor is zero?). There may be other such situations... I have not studied it thoroughly.

The reason for the carry out error is that the word subtract instruction sequence·sort of "disconnects" the carry·between the first·and last instruction.

· ;__Wparam34 = __WParam34 - __WParam12

······ SUB __WPARAM34_LSB,__WPARAM12_LSB···················'carry OK here
······ SUBB __WPARAM34_MSB,/C····································· 'carry not affected
······ SUB __WPARAM34_MSB,__WPARAM12_MSB················· 'carry incorrect if result is negative

And so I can't use the SX/B word subtract operator in my division routine, or for that matter, anywhere I need to rely on the carry after a negative generating·subtraction.

So I'm wondering if you should replace the code generated by the SX/B assembler·for a word subtraction to be the same as you use for word subtraction in your division routine:

······· MOV W,__WPARAM12_LSB
······· SUB· __WPARAM34_LSB,W
······· MOV W,__WPARAM12_MSB
······· SC···························
······· MOV W,++__WPARAM12_MSB
······· SUB· __WPARAM34_MSB,W····································· 'carry stays "connected" with previous operation

As that is the same number of instructions, and does generate the correct carry-out.

Cheers,

Peter (pjv)

Comments

  • BeanBean Posts: 8,129
    edited 2009-06-19 17:28
    Peter,
    · I had to put a "SZ" in before the last "SUB" in case the value +1 value was zero.
    · Give this a try and let me know if it does what you need.

    [noparse][[/noparse]EDIT] Posted beta version in lower post...

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...



    Post Edited (Bean (Hitt Consulting)) : 6/19/2009 6:14:19 PM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-06-19 17:46
  • BeanBean Posts: 8,129
    edited 2009-06-19 17:50
    I guess I should change WORD addition as well...

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...



    Post Edited (Bean (Hitt Consulting)) : 6/19/2009 7:17:31 PM GMT
  • pjvpjv Posts: 1,903
    edited 2009-06-19 18:31
    @Terry;

    I have my code running correctly, but I can't use SX/B to do it.

    The word subtraction you are using in your own divide routine yields the correct result, and is an elegant answer.

    Also I'm now having trouble with the carry-out from some number sets when using the word add SX/B instruction, and the similar approach as suggested by Peter Verkaik referenced in the above post will also fix that:

    mov w,__Param1
    add __Param3,w
    mov w,__Param2
    snc
    mov w,++__Param2
    add __Param4,w 'carry out is correct here

    Is there a reason why the compiler could not be altered in the suggested manner to fix these? Seems pretty simple?

    @Peter;

    As I get older, I seem to forget more things.... heavens this was just discussed (but not fixed) only April of this year, and already I can't remember it !!!

    In your referenced addition example, what is the purpose of the movsz w,++Value verses just mov w,++Value ? I don't get the SZ part.

    Cheers,

    Peter (pjv)
  • pjvpjv Posts: 1,903
    edited 2009-06-19 18:48
    Hello Terry;

    Now THAT's some kind of service.... live sotware upgrades! You fixed it while I was still posting.

    Sorry to be such a whine, but there in a typo in the compiler in the word add instruction so it won't compile:

    MOV W,++__PARRAM2 2 R's in __Param2

    Also, I can't understand the purpose in the SZ instruction ?? What am I not seeing?


    Cheers,

    Peter (pjv)
  • BeanBean Posts: 8,129
    edited 2009-06-19 19:18
    Let's say you want to subtract $FF01 from $1000

    First you would subtract the 1 from zero, and that would cause a underflow (carry clear).

    Then W would get loaded with $FF +1 (zero), so the final SUB would NOT cause a underflow, but it should.

    But having the SZ we skip the SUB leaving the carry clear to indicate the underflow and still get the right result.


    I have fixed the typo. Try this version...

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-06-19 19:25
    pjv,

    The movsz w,++ does not affect flags, wheras mov w,++ does.
    If the·LSB add·gave overflow, C·gets set, and if ++MSB would be zero,·the following add
    must be skipped as that would clear C. I think that is also
    why Bean inserted an SZ before last addition.

    regards peter
  • pjvpjv Posts: 1,903
    edited 2009-06-19 19:59
    @Terry;

    WOW, compilers fixed-while-U-wait. This is phenomenal.

    Have downloaded, typo gone, will try in some detail.


    @Peter;

    Neither of the instructions affect the carry. I will try to wrap my head around Bean's explanation. Eventhough he does not use that SZ form in his own divide routine; just the MOV W,++VAR.

    Thanks all for your help... much appreciated.

    Cheers,

    Peter (pjv)
  • BeanBean Posts: 8,129
    edited 2009-06-20 01:24
    As long as the number you are subtracting is less than $FF01, it won't matter.
    I'll have to check the divide routine to see if it returns the currect results (0 or 1) when dividing by such large numbers.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...

    ·
  • BeanBean Posts: 8,129
    edited 2009-06-20 12:50
    I have confirmed that the divide routine requires the SZ instruction too.

    If you divide a small number by $FFxx you will get 1 instead of zero if xx is larger than the number you are dividing.

    For example 1 / $FF02 will return "1", but 1 / $FF01 will return zero.

    Bean

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...



    Post Edited (Bean (Hitt Consulting)) : 6/20/2009 7:07:59 PM GMT
  • BeanBean Posts: 8,129
    edited 2009-06-26 14:09
    I'm guessing that this works okay for you guys ???

    I'll post this version in the official thread.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Money is not that important....In the grand scheme of things.

    ·
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-06-26 14:26
    I think so. To resume, you updated word add, subtract and divide.
    Since add is changed, is mutiply affected?

    regards peter
Sign In or Register to comment.