PIC Arithmetic 16-bit

Posted in June 27th, 2007

Target:

; 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

Follow-up responses to this entry through the RSS feed, Leave a Reply or Trackback from your own site.

Leave a Reply

 Username (*required)

 Email Address (*private)

 Website (*optional)