- All
- Freescale DSP56F8xx
- Microchip PIC16
Arithmetic Operations
UDATA
HIBYTE RES 1
LOBYTE RES 1
COUNTX RES 1
MULCND RES 1
MULPLR RES 1
BCD RES 2
ACCaLO res 1
ACCaHI res 1
ACCbLO res 1
ACCbHI res 1
ACCcLO res 1
ACCcHI res 1
ACCdLO res 1
ACCdHI res 1
R2 res 1
R1 res 1
R0 res 1
TEMPX res 1
L_temp res 1
H_temp res 1
w_save res 1
RandHi res 1
RandLo res 1
parity res 1
;*************************************************************************
; Multiplication MULPLR(8 bit) x MULCND(8 bit) -->HIBYTE(msb),LOBYTE(lsb)*
; a) Load the multiplier in the location MULPLR *
; b) Load the multiplicant in the location MULCND *
; c) Call Mpy8x8 *
; d) Msb is in the location HIBYTE *
; e) Lsb is in the location LOBYTE *
;*************************************************************************
Mpy8x8
clrf HIBYTE
clrf LOBYTE
clrf COUNTX
bsf COUNTX, 3
movf MULCND, W
LoopX
bcf STATUS, C
btfsc MULPLR, 0
addwf HIBYTE, f
rrf HIBYTE, f
rrf LOBYTE, f
bcf STATUS, C
rrf MULPLR, f
decfsz COUNTX, f
goto LoopX
return
;*******************************************************************
;Multiplication: ACCb(16 bits)*ACCa(16 bits) -> ACCb,ACCc (32 bits)*
;(a) Load the 1st operand in location ACCaLO & ACCaHI (16 bits) *
;(b) Load the 2nd operand in location ACCbLO & ACCbHI (16 bits) *
;(c) CALL Mpy_16bit *
;(d) The 32 bit result is in location (ACCbHI,ACCbLO,ACCcHI,ACCcLO)*
;*******************************************************************
Mpy_16bit
movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI,W ; move ACCb to ACCd
movwf ACCdHI
movf ACCbLO,W
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
Mloop
rrf ACCdHI, F ;rotate d right
rrf ACCdLO, F
btfsc STATUS,C ;need to add?
call Add_16bit
rrf ACCbHI, F
rrf ACCbLO, F
rrf ACCcHI, F
rrf ACCcLO, F
decfsz temp, F ;loop until all bits checked
goto Mloop
return
;******************************************************************
;This routine convert the hex value present in the WREG to decimal*
;and store the results in the reg: BCD and BCD+1 *
;******************************************************************
BinBCD
clrf BCD
clrf BCD+1
Again1
addlw 0x9C ;subtract 100 and check for borrow
btfss STATUS, C
goto add100
incf BCD+1, f
goto Again1
add100
addlw 0x64
Again
addlw 0xF6 ;subtract 10 and check for borrow
btfss STATUS, C
goto SwapBCD
incf BCD, f
goto Again
SwapBCD
addlw 0x0A
swapf BCD, f
iorwf BCD, f
return
;***************************************************************
;This routine find the square of the number present in the WREG*
;The hex result is stored in WREG and the decimal result is *
;stored in GPRs BCD and BCD+1 *
;***************************************************************
square
movwf COUNTX
movlw 0x01
movwf TEMPX
clrw
r_square
addwf TEMPX,W
incf TEMPX,F
incf TEMPX,F
decfsz COUNTX,F
goto r_square
movwf w_save
call BinBCD
movf w_save,W
return
;*******************************************************************
;This routine find the square root of a number which is stored in *
;WREG.The result is stored in WREG.If the number hasn't a finite *
;square root this function returns an error value EE in WREG *
;*******************************************************************
square_root
movwf w_save
movlw 0x01
movwf TEMPX
movwf COUNTX
loop
movf TEMPX,W
subwf w_save,f
btfsc STATUS,Z
goto zero
btfss STATUS,C
goto no_root
incf COUNTX,F
incf TEMPX,F
incf TEMPX,F
goto loop
zero
movf COUNTX,W
return
no_root
movlw 0XEE
return
;********************************************************************
; Binary To BCD Conversion Routine *
; This routine converts a 16 Bit binary Number to a 5 Digit *
; BCD Number. *
; The 16 bit binary number is input in locations ACCaHI and *
; ACCaLO with the high byte in ACCaHI. *
; The 5 digit BCD number is returned in R0, R1 and R2 with R0 *
; containing the MSD in its right most nibble. *
;********************************************************************
Hex_to_Dec
bcf STATUS, C
clrf COUNTX
bsf COUNTX, 4 ;set count to 16
clrf R0
clrf R1
clrf R2
Loop16a
rlf ACCaLO, f
rlf ACCaHI, f
rlf R2, f
rlf R1, f
rlf R0, f
decfsz COUNTX, f
goto Adjdec
return
Adjdec
movlw R2 ;load as indirect address pointer
movwf FSR
call AdjBCD
incf FSR, f
call AdjBCD
incf FSR, f
call AdjBCD
goto Loop16a
AdjBCD
movf INDF, w
addlw 0x03
movwf TEMPX
btfsc TEMPX,3;test if result > 7
movwf INDF
movf INDF, w
addlw 0x30
movwf TEMPX
btfsc TEMPX, 7 ;test if result > 7
movwf INDF ;save as MSD
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Division : ACCb(16 bits) / ACCa(16 bits) -> ACCd(16 bits) with ;
; Remainder in ACCc (16 bits) ;
; (a) Load the Denominator in location ACCaHI & ACCaLO ( 16 bits );
; (b) Load the Numerator in location ACCbHI & ACCbLO ( 16 bits ) ;
; (c) CALL Division ;
; (d) The 16 bit result is in location ACCdHI & ACCdLO ;
; (e) The 16 bit Remainder is in locations ACCcHI & ACCcLO ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Division
clrf COUNTX
bsf COUNTX,4 ; set count = 16
clrf ACCcHI
clrf ACCcLO
clrf ACCdLO
clrf ACCdHI
divLoop
bcf STATUS,C
rlf ACCbLO,F
rlf ACCbHI,F
rlf ACCcLO,F
rlf ACCcHI,F
movf ACCaHI,W
subwf ACCcHI,W ; check if a>c
btfss STATUS,Z
goto notz
movf ACCaLO,W
subwf ACCcLO,W ; if msb equal then check lsb
notz
btfss STATUS,C ; carry set if c>a
goto nosub ; if c < a
subca
movf ACCaLO,W ; c-a into c
subwf ACCcLO, F
movf ACCaHI,W
subwf ACCcHI, F
bsf STATUS,C ; shift a 1 into d (result)
nosub
rlf ACCdLO,F
rlf ACCdHI,F
decfsz COUNTX,F
goto divLoop
return
;*******************************************************************
; Random Number Generator *
; This routine generates a 16 Bit Pseudo Sequence Random Generator *
; It is based on Linear shift register feedback. The sequence *
; is generated by (Q15 xorwf Q14 xorwf Q12 xorwf Q3 ) *
; The 16 bit random number is in location RandHi(high byte) *
; & RandLo (low byte) *
; Before calling this routine, make sure the initial values *
; of RandHi & RandLo are NOT ZERO *
; A good chiose of initial random number is 0x3045 *
;*******************************************************************
Random16
rlf RandHi,W
xorwf RandHi,W
movwf w_save
rlf w_save, F ; carry bit = xorwf(Q15,14)
swapf RandHi, F
swapf RandLo,W
movwf w_save
rlf w_save, F
xorwf RandHi,W ; LSB = xorwf(Q12,Q3)
swapf RandHi, F
andlw 0x01
rlf RandLo, F
xorwf RandLo, F
rlf RandHi, F
return
;**********************************************************************
; BCD To Binary Conversion *
; This routine converts a 5 digit BCD number to a 16 bit binary *
; number. *
; The input 5 digit BCD numbers are asumed to be in locations *
; R0, R1 & R2 with R0 containing the MSD in its right most nibble. *
; The 16 bit binary number is output in registers ACCaHI & ACCaLO *
; ( high byte & low byte repectively ). *
; The method used for conversion is : *
; input number X = abcde ( the 5 digit BCD number ) *
; X = abcde = 10[10[10[10a+b]+c]+d]+e *
;**********************************************************************
Dec_to_Hex
clrf ACCaHI
movf R0,W
andlw 0x0F
movwf ACCaLO
call mpy10a ; result = 10a+b
swapf R1,W
call mpy10b ; result = 10[10a+b]
movf R1,W
call mpy10b ; result = 10[10[10a+b]+c]
swapf R2,W
call mpy10b ; result = 10[10[10[10a+b]+c]+d]
movf R2,W
andlw 0x0F
addwf ACCaLO, F
btfsc STATUS,C
incf ACCaHI, F ; result = 10[10[10[10a+b]+c]+d]+e
return ; BCD to binary conversion done
mpy10b
andlw 0x0F
addwf ACCaLO, F
btfsc STATUS,C
incf ACCaHI, F
mpy10a
bcf STATUS,C ; multiply by 2
rlf ACCaLO,W
movwf L_temp
rlf ACCaHI,W ; (H_temp,L_temp) = 2*N
movwf H_temp
bcf STATUS,C ; multiply by 2
rlf ACCaLO, F
rlf ACCaHI, F
bcf STATUS,C ; multiply by 2
rlf ACCaLO, F
rlf ACCaHI, F
bcf STATUS,C ; multiply by 2
rlf ACCaLO, F
rlf ACCaHI, F ; (H_byte,L_byte) = 8*N
movf L_temp,W
addwf ACCaLO, F
btfsc STATUS,C
incf ACCaHI, F
movf H_temp,W
addwf ACCaHI, F
return ; (H_byte,L_byte) = 10*N
;*********************************************************************************************
;This routine is used to find the parity bit(ODD or EVEN)an 8 bit no:stored in the WREG. *
;The parity bit is stored in the LSB of parity reg.To find EVEN parity make the EVEN_PARITY *
;definition TRUE.To find ODD parity make the EVEN_PARITY definition FALSE. *
;*********************************************************************************************
find_parity
movwf TEMPX
swapf TEMPX,W
xorwf TEMPX,W
movwf parity
rrf parity, F
rrf parity, F
xorwf parity,W
andlw 0x03
addlw 0x01
movwf TEMPX
rrf TEMPX,F
rrf TEMPX,W
movwf parity
#if EVEN_PARITY
xorlw 0x01
movwf parity
#endif
return
;************************************************************************
; Subtraction : ACCb(16 bits) - ACCa(16 bits) -> ACCb(16 bits) *
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) *
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) *
; (c) CALL Sub_16bit *
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) *
;************************************************************************
Sub_16bit
call Neg_16bit
call Add_16bit
return
;************************************************************************
; Addition : ACCb(16 bits) + ACCa(16 bits) -> ACCb(16 bits) *
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) *
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) *
; (c) CALL Add_16bit *
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) *
;************************************************************************
Add_16bit
movf ACCaLO,W
addwf ACCbLO, F ; add lsb
btfsc STATUS,C ; add in carry
incf ACCbHI, F
movf ACCaHI,W
addwf ACCbHI, F ; add msb
return
;************************************************************************
; 2's Compliment: negate ACCa ( -ACCa -> ACCa ) *
; (a) Load the operand in location ACCaLO & ACCaHI ( 16 bits ) *
; (b) CALL Neg_16bit *
; (c) The result is in location ACCaLO & ACCaHI ( 16 bits ) *
;************************************************************************
Neg_16bit
comf ACCaLO, F ;
incf ACCaLO, F
btfsc STATUS,Z
decf ACCaHI, F
comf ACCaHI, F
return
Software SPI
#include<p16f877a.inc>
#define s_data_o PORTC,5 ;serial data out
#define s_data_i PORTC,4 ;serial data in
#define s_clock PORTC,3 ;clock out
udata_shr
tx_reg res 1
rx_reg res 1
code
;************************
;Configure I/O Ports
;Load data in WREG
;Call soft_spi_write
;************************
soft_spi_write
global soft_spi_write
banksel tx_reg
movwf tx_reg ;store W = tx_reg
banksel PORTC ;Bank 0
bsf STATUS,C ;Set Carry Flag=1
send_next_bit
rlf tx_reg,F ;rotate left
movf tx_reg,F ;Check wheter 8 bit transmitted or not
btfsc STATUS,Z ;If no ,send next bit
return ;if yes,return
bcf s_data_o ;data line low
btfsc STATUS,C ;check the bit in carry,
bsf s_data_o ;if high,s_data_o =1
fill (nop),3
bsf s_clock ;s_clock=1 | _
fill (nop),5 ; |clock high to low _| |_
bcf STATUS,C ;clear carry |
bcf s_clock ;S_clock=0 |
fill (nop),3
goto send_next_bit ; looping process...........
;**************************************************
;Configure I/O Ports
;Call soft_spi_read
;This fuction returns the received data is in WREG
;**************************************************
soft_spi_read ;subroutine for receive
global soft_spi_read
movlw 0x01 ;eight bit reception
movwf rx_reg
read_next_bit
rlf rx_reg,f ;rotating the rx_reg register to store the received bit
bsf s_clock
fill (nop),5
btfsc s_data_i
bsf rx_reg,0 ;receiving the data
bcf s_clock
fill (nop),3
btfss STATUS,C ;testing whether the reception is compleate or not
goto read_next_bit ;if not compleated do the process again
movf rx_reg,W ;restore data in WREG
return
end
- All
- Freescale DSP56F8xx
- Microchip PIC16
Software SPI
#include<p16f877a.inc>
#define s_data_o PORTC,5 ;serial data out
#define s_data_i PORTC,4 ;serial data in
#define s_clock PORTC,3 ;clock out
udata_shr
tx_reg res 1
rx_reg res 1
code
;************************
;Configure I/O Ports
;Load data in WREG
;Call soft_spi_write
;************************
soft_spi_write
global soft_spi_write
banksel tx_reg
movwf tx_reg ;store W = tx_reg
banksel PORTC ;Bank 0
bsf STATUS,C ;Set Carry Flag=1
send_next_bit
rlf tx_reg,F ;rotate left
movf tx_reg,F ;Check wheter 8 bit transmitted or not
btfsc STATUS,Z ;If no ,send next bit
return ;if yes,return
bcf s_data_o ;data line low
btfsc STATUS,C ;check the bit in carry,
bsf s_data_o ;if high,s_data_o =1
fill (nop),3
bsf s_clock ;s_clock=1 | _
fill (nop),5 ; |clock high to low _| |_
bcf STATUS,C ;clear carry |
bcf s_clock ;S_clock=0 |
fill (nop),3
goto send_next_bit ; looping process...........
;**************************************************
;Configure I/O Ports
;Call soft_spi_read
;This fuction returns the received data is in WREG
;**************************************************
soft_spi_read ;subroutine for receive
global soft_spi_read
movlw 0x01 ;eight bit reception
movwf rx_reg
read_next_bit
rlf rx_reg,f ;rotating the rx_reg register to store the received bit
bsf s_clock
fill (nop),5
btfsc s_data_i
bsf rx_reg,0 ;receiving the data
bcf s_clock
fill (nop),3
btfss STATUS,C ;testing whether the reception is compleate or not
goto read_next_bit ;if not compleated do the process again
movf rx_reg,W ;restore data in WREG
return
end
Arithmetic Operations
UDATA
HIBYTE RES 1
LOBYTE RES 1
COUNTX RES 1
MULCND RES 1
MULPLR RES 1
BCD RES 2
ACCaLO res 1
ACCaHI res 1
ACCbLO res 1
ACCbHI res 1
ACCcLO res 1
ACCcHI res 1
ACCdLO res 1
ACCdHI res 1
R2 res 1
R1 res 1
R0 res 1
TEMPX res 1
L_temp res 1
H_temp res 1
w_save res 1
RandHi res 1
RandLo res 1
parity res 1
;*************************************************************************
; Multiplication MULPLR(8 bit) x MULCND(8 bit) -->HIBYTE(msb),LOBYTE(lsb)*
; a) Load the multiplier in the location MULPLR *
; b) Load the multiplicant in the location MULCND *
; c) Call Mpy8x8 *
; d) Msb is in the location HIBYTE *
; e) Lsb is in the location LOBYTE *
;*************************************************************************
Mpy8x8
clrf HIBYTE
clrf LOBYTE
clrf COUNTX
bsf COUNTX, 3
movf MULCND, W
LoopX
bcf STATUS, C
btfsc MULPLR, 0
addwf HIBYTE, f
rrf HIBYTE, f
rrf LOBYTE, f
bcf STATUS, C
rrf MULPLR, f
decfsz COUNTX, f
goto LoopX
return
;*******************************************************************
;Multiplication: ACCb(16 bits)*ACCa(16 bits) -> ACCb,ACCc (32 bits)*
;(a) Load the 1st operand in location ACCaLO & ACCaHI (16 bits) *
;(b) Load the 2nd operand in location ACCbLO & ACCbHI (16 bits) *
;(c) CALL Mpy_16bit *
;(d) The 32 bit result is in location (ACCbHI,ACCbLO,ACCcHI,ACCcLO)*
;*******************************************************************
Mpy_16bit
movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI,W ; move ACCb to ACCd
movwf ACCdHI
movf ACCbLO,W
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO
Mloop
rrf ACCdHI, F ;rotate d right
rrf ACCdLO, F
btfsc STATUS,C ;need to add?
call Add_16bit
rrf ACCbHI, F
rrf ACCbLO, F
rrf ACCcHI, F
rrf ACCcLO, F
decfsz temp, F ;loop until all bits checked
goto Mloop
return
;******************************************************************
;This routine convert the hex value present in the WREG to decimal*
;and store the results in the reg: BCD and BCD+1 *
;******************************************************************
BinBCD
clrf BCD
clrf BCD+1
Again1
addlw 0x9C ;subtract 100 and check for borrow
btfss STATUS, C
goto add100
incf BCD+1, f
goto Again1
add100
addlw 0x64
Again
addlw 0xF6 ;subtract 10 and check for borrow
btfss STATUS, C
goto SwapBCD
incf BCD, f
goto Again
SwapBCD
addlw 0x0A
swapf BCD, f
iorwf BCD, f
return
;***************************************************************
;This routine find the square of the number present in the WREG*
;The hex result is stored in WREG and the decimal result is *
;stored in GPRs BCD and BCD+1 *
;***************************************************************
square
movwf COUNTX
movlw 0x01
movwf TEMPX
clrw
r_square
addwf TEMPX,W
incf TEMPX,F
incf TEMPX,F
decfsz COUNTX,F
goto r_square
movwf w_save
call BinBCD
movf w_save,W
return
;*******************************************************************
;This routine find the square root of a number which is stored in *
;WREG.The result is stored in WREG.If the number hasn't a finite *
;square root this function returns an error value EE in WREG *
;*******************************************************************
square_root
movwf w_save
movlw 0x01
movwf TEMPX
movwf COUNTX
loop
movf TEMPX,W
subwf w_save,f
btfsc STATUS,Z
goto zero
btfss STATUS,C
goto no_root
incf COUNTX,F
incf TEMPX,F
incf TEMPX,F
goto loop
zero
movf COUNTX,W
return
no_root
movlw 0XEE
return
;********************************************************************
; Binary To BCD Conversion Routine *
; This routine converts a 16 Bit binary Number to a 5 Digit *
; BCD Number. *
; The 16 bit binary number is input in locations ACCaHI and *
; ACCaLO with the high byte in ACCaHI. *
; The 5 digit BCD number is returned in R0, R1 and R2 with R0 *
; containing the MSD in its right most nibble. *
;********************************************************************
Hex_to_Dec
bcf STATUS, C
clrf COUNTX
bsf COUNTX, 4 ;set count to 16
clrf R0
clrf R1
clrf R2
Loop16a
rlf ACCaLO, f
rlf ACCaHI, f
rlf R2, f
rlf R1, f
rlf R0, f
decfsz COUNTX, f
goto Adjdec
return
Adjdec
movlw R2 ;load as indirect address pointer
movwf FSR
call AdjBCD
incf FSR, f
call AdjBCD
incf FSR, f
call AdjBCD
goto Loop16a
AdjBCD
movf INDF, w
addlw 0x03
movwf TEMPX
btfsc TEMPX,3;test if result > 7
movwf INDF
movf INDF, w
addlw 0x30
movwf TEMPX
btfsc TEMPX, 7 ;test if result > 7
movwf INDF ;save as MSD
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Division : ACCb(16 bits) / ACCa(16 bits) -> ACCd(16 bits) with ;
; Remainder in ACCc (16 bits) ;
; (a) Load the Denominator in location ACCaHI & ACCaLO ( 16 bits );
; (b) Load the Numerator in location ACCbHI & ACCbLO ( 16 bits ) ;
; (c) CALL Division ;
; (d) The 16 bit result is in location ACCdHI & ACCdLO ;
; (e) The 16 bit Remainder is in locations ACCcHI & ACCcLO ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Division
clrf COUNTX
bsf COUNTX,4 ; set count = 16
clrf ACCcHI
clrf ACCcLO
clrf ACCdLO
clrf ACCdHI
divLoop
bcf STATUS,C
rlf ACCbLO,F
rlf ACCbHI,F
rlf ACCcLO,F
rlf ACCcHI,F
movf ACCaHI,W
subwf ACCcHI,W ; check if a>c
btfss STATUS,Z
goto notz
movf ACCaLO,W
subwf ACCcLO,W ; if msb equal then check lsb
notz
btfss STATUS,C ; carry set if c>a
goto nosub ; if c < a
subca
movf ACCaLO,W ; c-a into c
subwf ACCcLO, F
movf ACCaHI,W
subwf ACCcHI, F
bsf STATUS,C ; shift a 1 into d (result)
nosub
rlf ACCdLO,F
rlf ACCdHI,F
decfsz COUNTX,F
goto divLoop
return
;*******************************************************************
; Random Number Generator *
; This routine generates a 16 Bit Pseudo Sequence Random Generator *
; It is based on Linear shift register feedback. The sequence *
; is generated by (Q15 xorwf Q14 xorwf Q12 xorwf Q3 ) *
; The 16 bit random number is in location RandHi(high byte) *
; & RandLo (low byte) *
; Before calling this routine, make sure the initial values *
; of RandHi & RandLo are NOT ZERO *
; A good chiose of initial random number is 0x3045 *
;*******************************************************************
Random16
rlf RandHi,W
xorwf RandHi,W
movwf w_save
rlf w_save, F ; carry bit = xorwf(Q15,14)
swapf RandHi, F
swapf RandLo,W
movwf w_save
rlf w_save, F
xorwf RandHi,W ; LSB = xorwf(Q12,Q3)
swapf RandHi, F
andlw 0x01
rlf RandLo, F
xorwf RandLo, F
rlf RandHi, F
return
;**********************************************************************
; BCD To Binary Conversion *
; This routine converts a 5 digit BCD number to a 16 bit binary *
; number. *
; The input 5 digit BCD numbers are asumed to be in locations *
; R0, R1 & R2 with R0 containing the MSD in its right most nibble. *
; The 16 bit binary number is output in registers ACCaHI & ACCaLO *
; ( high byte & low byte repectively ). *
; The method used for conversion is : *
; input number X = abcde ( the 5 digit BCD number ) *
; X = abcde = 10[10[10[10a+b]+c]+d]+e *
;**********************************************************************
Dec_to_Hex
clrf ACCaHI
movf R0,W
andlw 0x0F
movwf ACCaLO
call mpy10a ; result = 10a+b
swapf R1,W
call mpy10b ; result = 10[10a+b]
movf R1,W
call mpy10b ; result = 10[10[10a+b]+c]
swapf R2,W
call mpy10b ; result = 10[10[10[10a+b]+c]+d]
movf R2,W
andlw 0x0F
addwf ACCaLO, F
btfsc STATUS,C
incf ACCaHI, F ; result = 10[10[10[10a+b]+c]+d]+e
return ; BCD to binary conversion done
mpy10b
andlw 0x0F
addwf ACCaLO, F
btfsc STATUS,C
incf ACCaHI, F
mpy10a
bcf STATUS,C ; multiply by 2
rlf ACCaLO,W
movwf L_temp
rlf ACCaHI,W ; (H_temp,L_temp) = 2*N
movwf H_temp
bcf STATUS,C ; multiply by 2
rlf ACCaLO, F
rlf ACCaHI, F
bcf STATUS,C ; multiply by 2
rlf ACCaLO, F
rlf ACCaHI, F
bcf STATUS,C ; multiply by 2
rlf ACCaLO, F
rlf ACCaHI, F ; (H_byte,L_byte) = 8*N
movf L_temp,W
addwf ACCaLO, F
btfsc STATUS,C
incf ACCaHI, F
movf H_temp,W
addwf ACCaHI, F
return ; (H_byte,L_byte) = 10*N
;*********************************************************************************************
;This routine is used to find the parity bit(ODD or EVEN)an 8 bit no:stored in the WREG. *
;The parity bit is stored in the LSB of parity reg.To find EVEN parity make the EVEN_PARITY *
;definition TRUE.To find ODD parity make the EVEN_PARITY definition FALSE. *
;*********************************************************************************************
find_parity
movwf TEMPX
swapf TEMPX,W
xorwf TEMPX,W
movwf parity
rrf parity, F
rrf parity, F
xorwf parity,W
andlw 0x03
addlw 0x01
movwf TEMPX
rrf TEMPX,F
rrf TEMPX,W
movwf parity
#if EVEN_PARITY
xorlw 0x01
movwf parity
#endif
return
;************************************************************************
; Subtraction : ACCb(16 bits) - ACCa(16 bits) -> ACCb(16 bits) *
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) *
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) *
; (c) CALL Sub_16bit *
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) *
;************************************************************************
Sub_16bit
call Neg_16bit
call Add_16bit
return
;************************************************************************
; Addition : ACCb(16 bits) + ACCa(16 bits) -> ACCb(16 bits) *
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) *
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) *
; (c) CALL Add_16bit *
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) *
;************************************************************************
Add_16bit
movf ACCaLO,W
addwf ACCbLO, F ; add lsb
btfsc STATUS,C ; add in carry
incf ACCbHI, F
movf ACCaHI,W
addwf ACCbHI, F ; add msb
return
;************************************************************************
; 2's Compliment: negate ACCa ( -ACCa -> ACCa ) *
; (a) Load the operand in location ACCaLO & ACCaHI ( 16 bits ) *
; (b) CALL Neg_16bit *
; (c) The result is in location ACCaLO & ACCaHI ( 16 bits ) *
;************************************************************************
Neg_16bit
comf ACCaLO, F ;
incf ACCaLO, F
btfsc STATUS,Z
decf ACCaHI, F
comf ACCaHI, F
return