assemblypicprogram-counter

Reset of PCH when adding a value to PCL using addwf pic18f2x


I'm trying to use simple lookup tables in assembly by adding a certain index to the program counter. It appears to be working in a range of the PCL (so until 0xff) but afterwards, when the PCH comes in to play the PCH just resets after the addwf instruction.

How do I prevent the PCH from resetting after addition? Do I need to manipulate the PCLATH and PCLATU in some way so PCH will keep its value.

I'm using a pic18f25k50 with the mpasm assembler.

So this lookup table works fine:

TABLE_GET_VALUE
    movf    index, 0 ; memory location = 0x9E 
    mullw   4
    movf    PRODL, 0
    addwf   PC
    movf    0x20, 0
    return
    movf    0x21, 0
    return
    movf    0x22, 0
    return
    movf    0x23, 0
    return
    movf    0x24, 0
    return
    movf    0x25, 0
    return
    movf    0x26, 0
    return
    movf    0x27, 0
    return
    movf    0x28, 0
    return      ; memory location = 0xC8

while this one resets the program back to the first instructions:

TABLE_GET_COEFFICIENT
    movf    index, 0    ; memory location 0x108
    mullw   4
    movf    PRODL, 0
    addwf   PC
    movf    0x30, 0
    return
    movf    0x31, 0
    return
    movf    0x32, 0
    return
    movf    0x33, 0
    return
    movf    0x34, 0
    return
    movf    0x35, 0
    return
    movf    0x36, 0
    return
    movf    0x37, 0
    return
    movf    0x38, 0
    return      ; memory location 0x132

Solution

  • This is one example of a complete way to code the table look up for a PIC18F controller.

    ;------------------------------------------------------------------------------ 
    ; MAIN PROGRAM 
    ;------------------------------------------------------------------------------ 
    MAIN_CODE CODE              ; let linker place main program 
    
    Main: 
        movlw   8
        call    TableOneLookup
        bra     Main
    
    ;------------------------------------------------------------------------------ 
    ;
    ; TableOneLookup
    ;
    ; Description: Look up data in table placed in code space
    ;
    ; Input:  WREG = byte offset in table
    ;
    ; Output: WREG = byte from table
    ;
    ;------------------------------------------------------------------------------ 
    TABLE_ONE_CODE  code
    TableOneLookup:
        push
        clrf    TOSU
        clrf    TOSH
        movwf   TOSL                ; Save offset in to TableOne
        addwf   TOSL,F              ; Double offset in to TableOne
        rlcf    TOSH,F              ; Propagate carry
        movlw   LOW(TabelOne)       ; Add TableOne address low byte
        addwf   TOSL,F
        movlw   HIGH(TabelOne)      ; Add TableOne address high byte
        addwfc  TOSH,F
        movlw   UPPER(TabelOne)     ; Add TableOne address upper byte
        addwfc  TOSU,F
        return                      ; Branch in to TableOne
    TabelOne:
        DT      0x30
        DT      0x31
        DT      0x32
        DT      0x33
        DT      0x34
        DT      0x35
        DT      0x36
        DT      0x37
        DT      0x38
        end
    

    There are better ways to do this using the assembly language opcodes specifically designed for program memory read operations.