You have very interesting coding habits, my friend. The technique you used to re-adjust the digits of the initial sum's result after adding 0x66 to it is awesome and took me a while to understand. But it saves several lines of code and delivers the correct carry for the next iteration.Combining all our ideas, I wrote this today to sum to BCD numbers of arbitrary length.
Set FSR0 -> first operand (and result)
Set FSR1 -> second operand
Set WREG = number of bytes
call AddWBCD.
The last carry is returned for overflow information.
Should work, but not tested.
Code:;@JoeyD -- 20230507 #define SavedC SavedStatus,C+4 #define SavedDC SavedStatus,DC+4 ***************************************************** ;** AddWBCD ** ;** Add (FSR0) = (FSR0) + (FSR1) ** ;** wreg = number of BCD bytes (digits / 2) ** ;** return with final carry ** ;** second operand is preserved ** ;** requires registers "SavedStatus" and "bytecnt" ** ;**************************************************** AddWBCD movwf bytecnt ;save number of bytes clrf SavedStatus ;preclear first carry bcdloop movlw 0x66 ;prepare for BCD addition addwf indf0,f ;fsr0 -> first addend and result movfw indf1 ;get 2nd addend btfsc SavedC ;incoming carry? incf indf1,w ;yes, addend+1 addwf indf0,f ;add it in swapf status,w ;save resulting C and DC movwf SavedStatus clrw ; C and DC, adjustment = 0x00 btfss SavedDC ; C and NDC, adjustment = 0xFA addlw 0xFA btfss SavedC ;NC and DC, adjustment = 0xA0 addlw 0xA0 addwf indf0,f ;NC and NDC, adjustment = 0xFA + 0xA0 = 0x9A incf fsr0h,f ;update pointers incfsz fsr0l,f decf fsr0h,f incf fsr1h,f incfsz fsr1l,f decf fsr1h,f decfsz bytecnt,f ;do for all bytes goto bcdloop swapf SavedStatus,w movwf status ;return with last carry return
Your level of experience is light years ahead of mine ... but here's a couple of observations:
I never never ever use the movfw pseudo-instruction. Using it caused me several headaches in the past because (at least for me) it can very easily be visually confused with movwf . I always use the movf File, w complete form instead. Hasn't that ever been a problem for you too?
Also, you probably not remember the whole PIC16 instruction set, but:
Code:
incf fsr0h,f ;update pointers
incfsz fsr0l,f
decf fsr0h,f
incf fsr1h,f
incfsz fsr1l,f
decf fsr1h,f
can more easily be translated to
Code:
addfsr fsr0, d'1' ;update pointers
addfsr fsr1, d'1'
Last edited: