Jump to content
43oh

# BCD Subtraction intrinsic?

## Recommended Posts

Hi guys. A couple questions, please?

(1) Anyone know if there's a reciprocal for the _bcd_add_short() intrinsic function that I can use to decrement packed BCD variables for a countdown timer routine?

(2) If there isn't a BCD subtract instrinsic, is there a good way to do decrement a packed BCD number in C, without resorting to in-line assembly code?

TIA! Regards, Mike

```   #define timer_running (hh|mm|ss)

```

```   /*
*  countdown timer, hh:mm:ss (1 second intervals)
*/
if(timer_running)                     //
{ if(ss != 0x00)                      // if seconds not 0x00
{ asm("  clrc              ");      // decrement seconds
asm("  dadd.b  #0x99,&ss ");      // (packed BCD)
} else                              // else, seconds == 0x00 so
{ ss = 0x59;                        // reset seconds to 0x59 and
if(mm != 0x00)                    // if minutes not 0x00
{ asm("  clrc              ");    // decrement minutes
asm("  dadd.b  #0x99,&mm ");    // (packed BCD)
} else                            // else, minutes == 0x00 so
{ mm = 0x59;                      // reset minutes to 0x59 and
asm("  clrc              ");    // decrment hours
asm("  dadd.b  #0x99,&hh ");    // (packed BCD)
}                                 //
}                                   //
if(!timer_running)                  // if timer has timed-out
P1OUT ^= relay_pin_mask;          // turn relay output off
}                                     //

```

##### Share on other sites

How about

`_bcd_add_short(-1)`

Never mind, that function takes unsigned

##### Share on other sites
How about

`_bcd_add_short(-1)`

Excellent! Thank you! I really should have thought of that (argh!)...

##### Share on other sites

Never mind, that function takes unsigned

How about overflowing your destination variable?

a = _bcd_add_short(a, 0x9999);

##### Share on other sites

I spoke too soon (grin). I'm trying some variations right now...

##### Share on other sites

`a = _bcd_add_short(a, 0x9999);`

Works as expected, 0x9999 is -1, 0x9998 is -2, etc.

##### Share on other sites

That should do it...

```   /*
*  countdown timer, hh:mm:ss (1 second intervals)
*/
if(timer_running)                     //
{ if(ss)                              // if seconds > 0x00
{ ss = _bcd_add_short(ss,0x99);     // decrement seconds
}
else                                // else, seconds == 0x00 so
{ ss = 0x59;                        // reset seconds to 0x59 and
if(mm)                            // if minutes > 0x00
{ mm = _bcd_add_short(mm,0x99);   // decrement minutes
}
else                              // else, minutes == 0x00 so
{ mm = 0x59;                      // reset minutes to 0x59 and
hh = _bcd_add_short(hh,0x99);   // decrement hours
}                                 //
}                                   //
if(!timer_running)                  // if timer has timed-out
P1OUT ^= relay_pin_mask;          // turn relay output off
}                                     //
```

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
• Blog

• #### Activity

×
• Create New...