PIC Arithmetic 16-bit
Target: PIC16C71
; Bit definitions
#define _c status,0
#define _z status,2
#define _dc status,1
#define _gie intcon, 7
; Macro definitions
Bank1 macro
bsf status, 5
endm
Bank0 macro
bcf status, 5
endm
; Mov pointer Work register with Literal
MovWL macro Literal
movwf fsr
movlw low(Literal)
movwf indf
incf fsr
movlw high(Literal)
movwf indf
endm
; Mov File register from Literal
MovFL macro File, Literal
movlw low(Literal)
movwf File
movlw high(Literal)
movwf File + 1
endm
; Compare Literal with File register
CmpLF macro Literal, File
movf File + 1, w
sublw high(Literal)
btfss _z
goto $ + 3
movf File, w
sublw low(Literal)
endm
; Compare File register with Literal
CmpFL macro File, Literal
movlw high(Literal)
subwf File + 1, w
btfss _z
goto $ + 3
movlw low(Literal)
subwf File, w
endm
; Compare File register Destination with File register Source
CmpFF macro FileD, FileS
movf FileS + 1, w
subwf FileD + 1, w
skpz
goto $ + 3
movf FileS, w
subwf FileD, w
endm
; Add File register Source to File register Destination
AddFF macro FileD, FileS
movf FileS, w
addwf FileD,F
skpnc
incf FileD + 1
movf FileS + 1, w
addwf FileD + 1
endm
; Data declarations
cblock 0ch
AccA :2
AccB :2
W1
Flags :1
endc
; Routines
; Mov accumulator A from pointer Work register
MovAW
movwf fsr
movf indf, w
movwf AccA
incf fsr
movf indf, w
movwf AccA + 1
return
; Mov pointer Work register from accumulator A
MovWA
movwf fsr
movf AccA, w
movwf indf
incf fsr
movf AccA + 1, w
movwf indf
return
; Increment pointer Work register
IncW
movwf fsr
incfsz indf
return
incf fsr
incf indf
return
; Decrement pointer Work register
DecW
movwf fsr
movlw 0ffh
addwf indf
btfsc _c
return
incf fsr
decf indf
return
; Compare accumulator A with pointer Work register
CmpAW
movwf fsr
incf fsr
movf indf, w
subwf AccA + 1, w
btfss _z
return
decf fsr
movf indf, w
subwf AccA, w
return
; Compare pointer Work register with accumulator A
CmpWA
movwf fsr
incf fsr
movf AccA + 1, w
subwf indf, w
btfss _z
return
decf fsr
movf AccA, w
subwf indf, w
return
; Add pointer Work register to accumulator A
AddAW
movwf fsr
movf indf, w
addwf AccA
btfsc _c
incf AccA + 1
incf fsr
movf indf, w
addwf AccA + 1
return
; Subtract pointer Work register from accumulator A
SubAW
movwf fsr
movf indf, w
subwf AccA
btfss _c
decf AccA + 1
incf fsr
movf indf, w
subwf AccA + 1
return
; Subtract accumulator A from pointer Work register
SubWA
movwf fsr
movf AccA, w
subwf indf
incf fsr
btfss _c
decf indf
movf AccA + 1, w
subwf indf
return
IncBCD
; Input: AccB Base address
; AccB + 1 Index
; Output: None
movf fsr, w ; Store FSR
movwf w1
bcf _c
rrf AccB + 1, w ; Get address
addwf AccB, w
movwf fsr
btfsc AccB + 1, 0
swapf indf
movlw 9
subwf indf
movlw 10
btfss _dc
addwf indf
btfsc AccB + 1, 0
swapf indf
movf w1, w ; Restore FSR
movwf fsr
return
Mul_8
; Input: AccA Multiplicand
; AccB Multiplicator
; Output: AccA+1:AccA Result
clrf W1
bsf W1, 3
clrf AccA + 1
movf AccB, w
rrf AccA
Mul_SL0001
btfsc _c
addwf AccA + 1
rrf AccA + 1
rrf AccA
decfsz W1
goto Mul_SL0001
return
Div_8
; Input: AccA Dividend
; AccB Divisor
; Output: AccA Result
; AccA+1 Remainder
movlw 8
FDiv_Byte
movwf W1
clrf AccA + 1
Div_SL0001
rlf AccA
rlf AccA + 1
movf AccB, w
subwf AccA + 1, w
btfsc _c
movwf AccA + 1
decfsz W1
goto Div_SL0001
rlf AccA
return
FDiv_8
movlw 16
goto FDiv_Byte
Div_16_8
; Input: AccA+1:AccA Dividend
; AccB Divisor
; Output: AccA+1:AccA Result
; AccB+1 Remainder
clrf W1
bsf W1, 4
clrf AccB + 1
Div_SL0002
rlf AccA
rlf AccA + 1
rlf AccB + 1
movf AccB, w
subwf AccB + 1, w
btfsc _c
movwf AccB + 1
decfsz W1
goto Div_SL0002
rlf AccA
rlf AccA + 1
return