Help with routine inc / dec in ASM 16 bit PIC16f877

Thread Starter

massanetabr

Joined Jun 3, 2019
44
Guys, I made this code in asm for a PIC 16F877 that decreases Value (high and low) to 0x00 and increases to 0x64. Does anyone see something wrong with this code, or do you think it could be improved?

Code:
DEC
MOVF VALUE_HIGH,W

SUBLW B'00000000'

BTFSS STATUS,C

GOTO DC_DEC

MOVF VALUE_LOW,W

SUBLW B'00000000'

BTFSC STATUS,C

GOTO EXIT


DC_DEC

DECF VALUE_LOW,F

MOVLW .255

XORWF VALUE_LOW,W

BTFSC STATUS,Z

DECF VALUE_HIGH,F

GOTO EXIT

INC
MOVLW B'00000011'

SUBWF VALUE_HIGH,W

BTFSS STATUS,C

GOTO DC_INC

MOVLW B'11101000'

SUBWF VALUE_LOW,W

BTFSC STATUS,C

GOTO EXIT


DC_INC

INCF VALUE_LOW,F

BTFSC STATUS,Z

INCF VALUE_HIGH,F

GOTO EXIT
 
Last edited by a moderator:

JohnInTX

Joined Jun 26, 2012
4,787
I would do it something like this:
Code:
    ; math877.asm
    ; INCREMENT/DECREMENT/COMPARE 16 bits
    ; This program increments ACCB to TestValue then decrements it to 0000 and repeats
    ; Increment, decrement and compare are subroutines.
    ; Accumulators ACCB and ACCA contain the values to operate on 

        cblock 20h
        ACCB:    2               ; accumulators, 16 bits, big endian  
        ACCA:   2               
        endc

TestValue   equ .64             ; value to count up to

        ORG     0

MAIN_loop:
        clrf    ACCB            ; clear the result register
        clrf    ACCB+1

        movlw   high TestValue  ; set test value for compares
        movwf   ACCA
        movlw   low  TestValue
        movwf   ACCA+1   
        nop                         ; nops to set breakpoints

INC_loop:
        nop

        call    incACCB             ; increment ACCB
        call    compareACCB_ACCA    ; look for terminal value
                                    ; skpz (skip on zero) is the same as btfss STATUS,Z
        skpz                        ; iff ==, proceed to decrement
        goto    INC_loop            ; else, keep incrementing   


        nop                         ; ACCB reached terminal count
DEC_loop:
        call    decACCB             ; decrement ACCB..
        movf    ACCB,W              ; down to 0000
        iorwf   ACCB+1,W            ; test by ORing all bits
        skpz                        ; skip if zero..
        goto    DEC_loop            ; else, loop

        goto    MAIN_loop
       
        ;**************** INCREMENT ACCB  ***************************
        ; Increment ACCB by 1.  Rolls over FFFF->0000       
incACCB:
        incf    ACCB+1,F        ; increment low byte
        skpnz                   ; and if it rolled over to 00..
        incf    ACCB,F          ; increment high byte
        retlw    0

        ;***************** DECREMENT ACCB  ***************************
        ; Decrement ACCB by 1.  Rolls over 0000->FFFF       
decACCB:
        movf    ACCB+1,F        ; look ahead: if low byte is 00 now..
        skpnz                   ;   it will need a borrow from upper byte
        decf    ACCB,F          ;   decrement upper byte
        decf    ACCB+1,F        ; always decrement lower byte           
        retlw    0

        ;******************** 16 BIT COMPARE  ***************************
        ;compareACCB_ACCA
 
        ; Compares 16 bit ACCB with ACCA. Result is in Z and C flags:             
        ; RET:  Z  --     ACCB = ACCA 
        ;       NZ NC     ACCB < ACCA
        ;       NZ  C     ACCB > ACCA
        ;       --  C     ACCB >= ACCA 

compareACCB_ACCA:                                
        movf    ACCA,W          ; compare high to low starting with high bytes      
        subwf   ACCB,W
        skpz                    ; if ==, need to compare low bytes
        retlw   0               ; else, high bytes not equal, return with flags
       
        movf    ACCA+1,W
        subwf   ACCB+1,W
        retlw   0               ; return with flags

        END
 

BobaMosfet

Joined Jul 1, 2009
2,113
@massanetabr
Not the way to do it. 2 things- Don't work in binary, work in hex. Hex is just as easy, but easier to read. Second, whenever possible in assembly, ONLY count down. The only value a processor knows about is zero. Anything else it views as 'not zero'. So count down and use a single instruction to 'branch equal' elsewhere when done. Learn to work _with_ your machine, not against it.
 
Last edited:
Top