#include  <msp430x14x.h>

;------------------------------------------------------------------------------
            ORG     01100h                  ; Progam Start
;------------------------------------------------------------------------------
RESET       mov.w   #0x0A00,SP               ; Initialize stackpointer
StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT

CODE

 PUBLIC _bcdadd ;

_bcdadd
 
  MOV.W @R15+, R4  ; A LSB
  MOV.W @R15,  R5  ; A MSB
  MOV.W @R14+, R6  ; B LSB
  MOV.W @R14,  R7  ; B MSB

  MOV #0050h,R4
  MOV #8900h,R5
  MOV #0022h,R6
  MOV #8900h,R7
;check signs by applying mask #0x8000h

  MOV #0x8000, R10
  AND R5, R10    
  CMP #0x8000, R10 ; 
  JNE A_POSITIVE    ;if A is positive the comparision should yield a non equality and jump to the appropiate instruction
 
  MOV #0x8000, R10
  AND R7, R10
  CMP #0x8000, R10
  JNE minus_plus      ; A is negative, B is positive => go to subtraction
                   
  JMP ADD2NEGATIVES          ;A is negative, B is negative => go to add2negatives


A_POSITIVE:

  MOV #0x8000, R10
  AND R7, R10
  CMP #0x8000, R10
  JNE ADD         ; A is positive , B is positive  => go to add
 
  JMP plus_minus    ; A is positive, B is negative => go to subtraction


 
plus_minus:    ; case + -
;remove the negative sign from the second argument
 MOV #0x7FFF, R10 ;mask to clear the sign bit
 MOV R7, R8       
 AND R10,R8       ;clear the sign bit

 CMP R5,R8        ;compare MSB
 JEQ compare_lower  ;if they are equal compare LSB
 CMP R5,R8      
 JGE first_part    ; compare upper registers if they are not the same
 JMP second_part  ;and branch appropiately

compare_lower:    ;compare lower registers and branch appropiately
 CMP R4,R6  
 JGE first_part
 JMP second_part

first_part:   ; 2nd number is larger in magnitude than the first one
 CLRC
 ;compute a subtraction by calculating the complement of the number to be
 ;subtracted , then performing an addition

 DADD #6666h,R4 
 DADD #6666h,R8
 MOV R8,R5
 INV R4
 INV R5

 ADD #0001h,R4

 CLRC
 DADD R4,R6
 DADD R5,R7


 JMP endend

second_part:   ; 1st number is larger in magnitude than the 2nd one

 CLRC
 ;compute a subtraction by calculating the complement of the number to be
 ;subtracted , then performing an addition

 DADD #6666h,R6
 DADD #6666h,R8
 MOV R8,R7
 INV R6
 INV R7

 ADD #0001h,R6

 CLRC
 DADD R4,R6
 DADD R5,R7
 
 JMP endend

 

minus_plus:   ; case + - 
;remove the negative sign from 1st argument
 MOV #0x7FFF, R10 ;mask to clear the sign bit
 MOV R5, R8
 AND R10,R8       ;clear the sign bit

 CMP R7,R8        ;compare MSB
 JEQ compare_lower2 ;if they are equal compare LSB
 CMP R7,R8        ; compare upper registers if they are not the same
 JGE second_part2 ;and branch appropiately
 JMP first_part2

compare_lower2:    ;compare lower registers and branch appropiately
 CMP R4,R6
 JGE first_part2
 JMP second_part2

 JMP endend
first_part2:       ; 2nd number is larger in magnitude than the first one
 CLRC
;compute a subtraction by calculating the complement of the number to be
 ;subtracted , then performing an addition
 DADD #6666h,R4
 DADD #6666h,R8
 MOV R8,R5
 INV R4
 INV R5

 ADD #0001h,R4

 CLRC
 DADD R4,R6
 DADD R5,R7

 JMP endend

second_part2:   ; 1st number is larger in magnitude than the 2nd one

 CLRC
 ;compute a subtraction by calculating the complement of the number to be
 ;subtracted , then performing an addition
 DADD #6666h,R6
 DADD #6666h,R7

 INV R6
 INV R7

 ADD #0001h,R6

 CLRC
 DADD R4,R6
 DADD R5,R7


 JMP endend


ADD2NEGATIVES: ;add 2 negatives
 
 MOV #7FFFh,R8
 AND R8,R7
 
 CLRC
 DADD R4,R6
 DADD R5,R7
 




 JMP endend;
ADD:     ;add 2 positives
 CLRC
 DADD R4,R6
 DADD R5,R7
 
 JMP endend
; if an overflow was detected, add one to the most significant register
; and continue with the loop through the 2nd register

 


SUBTRACT12:
;reverse registers
  MOV R4,R8
  MOV R5,R9
  MOV R6,R4
  MOV R7,R5
  MOV R8,R6
  MOV R9,R7
  JMP SUBTRACT
SUBTRACT:


endend:
 ; RET ; Return to caller (in this case the C program)                                            ;

                                            ;
;------------------------------------------------------------------------------
;           Interrupt Vectors
;------------------------------------------------------------------------------
            ORG     0FFFEh                  ; MSP430 RESET Vector
            DW      RESET                   ;
            END
