1

This is a large program now so just a bit of the source code below.

       **DISASSEMBLED CODE:**
       0164 0739 ADDWF 0x39, W 531: addwf Trigger777,0 ;to get proper patch table
       0165 0733 ADDWF 0x33, W 532: addwf countUp,0 ;to get proper patch table
       0166 00BC MOVWF 0x3C 533: movwf EnvPointer
       0167 2109 CALL 0x109 534: Call read
       0168 210C CALL 0x10C 535: CALL TinyDelay;NEW
       0169 3008 MOVLW 0x8 536: movlw HIGH ATKDecayTable
       016A 008A MOVWF PCLATH 537: movwf PCLATH
       016B 083C MOVF 0x3C, W 538: MOVF EnvPointer,0
       016C 1003 BCF STATUS, 0x0 539: BCF STATUS,0 ;CLEAR CARRY FLAG
       540:
       # **016D 2000 CALL 0x0 541: call ATKDecayTable ;GET RegData FROM TABLE**
       542:
       016E 00B0 MOVWF 0x30 543: MOVWF RegData
       016F 0086 MOVWF PORTB 544: movwf PORTB

and later on

       2398: org 0x800
       2399:
       2400:
       2401: ATKDecayTable ;EnvTest PARAM CHANGE 24-39 DECIMAL INCLUSIVE
       2402:
       0800 0782 ADDWF PCL, F 2403: ADDWF PCL ,1
       2404: ;00h
       0801 3400 RETLW 0x0 2405: RETLW 0x00 ; ENV_FreqLow equ 0xB
       0802 3401 RETLW 0x1 2406: RETLW 0x01 ; ENV_FreqHgh equ 0xC

At this point, ANY CALL to address $800h will create the "CALL 0x0" code. I think that this is a compiler error and I'm tempted to change a byte using my EPROM BURNER.

I expected the assembler to do what I told it to do! Instead it created a endless loop by CALLing 0x0.

2
  • So how about the relevant C code? The assembler is not responsible for this. It is the compiler that produces the assembly code. This might be a copiler optimisation issue. Try with optimisation setting off. Commented Aug 6, 2024 at 6:26
  • 1
    Are you looking at the assembly before or after linking? Addresses could be wrong before linking but should be correct after linking. Commented Aug 6, 2024 at 6:28

1 Answer 1

2

The flash memory of a PIC16 is seperated in several pages, each 2048 words big. Depending on the total memory size, there are several pages in the controller.

The CALL instruction only works with eleven bits <10:0>. The upper bits of the destination are loaded from PCLATH<4:3>. The easiest way to call a function in another page is to use the pagesel directive. pagesel loaded the required values from the destination label into PCLATH register.

pagesel LABEL    ;write 0x10 into PCLATH<4:3>
CALL LABEL       ;new destination: PCLATH + address in CALL = 1000 0000 0000 = 0x800                 
...

0RG 0x0800
LABEL:
...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.