1

I'm new to assembly language and I wrote a simple program to learn. I run into a problem of program counter (I believe) with a "goto" instruction. I use a PIC 10f202 and I use MPLAB v.6.15 in simulator mode to debug my code. Here my code:

PROCESSOR 10f202

#include <xc.inc>

; CONFIG
  CONFIG  WDTE = OFF            ; Watchdog Timer (WDT disabled)
  CONFIG  CP = OFF              ; Code Protect (Code protection off)
  CONFIG  MCLRE = OFF           ; Master Clear Enable (GP3/MCLR pin fuction is digital I/O, MCLR internally tied to VDD)

PSECT resetVect, class=CODE, delta=2
resetVect:
    PAGESEL main
    goto main
    
PSECT code, delta=2
main:
    clrf GPIO           ; clrf GPIO, F
    movlw   0b0001000       ; configure GP1 (only) as an output
    tris    GPIO
    
loop:
    bcf GPIO,0
    bsf GPIO,0
    movlw 256
    movwf 0x10
    nop
    goto loop
    
END resetVect

The program start at program memory 1F6 (line 503) with the instruction "goto main". It executes all code lines but when it reaches the instruction "goto loop", the program memory line 1FF does not show the instruction "goto loop" and then the program goes to program memory line 0c7 where there is no instruction. It does not go back to instruction "bcf GPIO,0" has expected.

Program memory

At first I was using a "call" instruction to call the subroutine "loop" with a return instruction but I was getting the error message that the instruction return was an illegal instruction for this PIC 10F202. I had an old assembly code that work before with "goto" instruction but this code was compiled with the old compiler from MPLAB: MPASM. In this code (using the same PIC 10f202) I used goto and call instructions and it compiled fine. Thanks for helping! Dominique

1 Answer 1

1

The controller you are using (PIC10F202) is a VERY resource restricted device.

There is only one opcode that returns from a call, RETLW 0x00 to 0xFF

This always sets a literal value in the W register.

There are several other "features" in this controller that makes it a challenge to create code for it. Such as:

  • call stack is two levels deep
  • no interrupts
  • called function must begin at an address between 0x000 and 0x0FF

There are a lot of others and I suspect that learning to write assembly code with the pic-as tool chain will be very frustrating.

For an MPLABX project I created just for you see:

https://github.com/dsoze1138/MPLABXv5xx_pic-as_examples/blob/master/10F202_Example_v615.X/start.S

In your question you said:

I had an old assembly code that work before with "goto" instruction but this code was compiled with the old compiler from MPLAB: MPASM. In this code (using the same PIC 10f202) I used goto and call instructions and it compiled fine.

The reason this fails when building your code with the pic-as tool is kind of complicated, I'll try to be brief. It involves how this specific family of controllers keeps track of the factory calibration value for the internal oscillator.

Microchip writes the calibration value as a MOVLW n opcode as the last instruction word in the program memory space. When an application locates an instruction in this location too it will be overwritten by the device programming tool with the factory calibration value.

What this means for you is that your application should not use this location. As you have seen the last instruction of your application is a GOTO that got overwritten because it was located at address 0x1FF of the PIC10F202 controller.

Edited to expand this answer base on comment of 2023-JAN-16.

The PIC10F2xx family of controllers are implemented based on the way the first 12-bit instruction word controller (PIC16C54).

There is no internal oscillator in the controller, it must be connected to an external crystal, resonator, or RC circuit.

This controller has 512 instruction words, 2-level call stack, no interrupts, one timer and 25 bytes of RAM.

Microchip, in their infinite and God like wisdom assigned the power-on-reset address to be the last instruction word in memory because called function must begin at an address of 0x000 to 0x0FF. What is called page zero in the data sheet.

When an internal oscillator is implemented a few years later the clever clogs at Microchip thought is would be a spiffy idea to store the oscillator calibration constant in the last instruction word instead of a GOTO to the POR entry of the application. Now address 0x000 is the "default" POR reset after executing one `MOVLW' to load the oscillator factory calibration value.

I have a long rant about the stupid way factory calibration values are stored in some of the 14-bit instruction word controllers. Not needed here.

My project is implemented this way to remind me of just how nutty this specific controller is that the device programming tools will overwrite the last instruction word of an application when it is the last word in the code space, and the actual POR address is not 0x000.

All of this is mostly hidden when us the XC8 compiler with this controller.

Keep in mind that Microchip really does not like developers that create applications in assembly language.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for your detailed response. I'll work with your exemple to better understand. Thanks!
Thanks you for your code. It is greatly appreciated. From the datasheet of PIC10f202, the effective reset vector is at 0000h and the location 01FFh contains the internal clock oscillator calibration value. This value should never be overwritten. In the code example you provided, why do you put your reset vector at location 01FFh (-presetvector=01FFh)? Can you put the reset vector at location 0000h?. I believe there is a fundamental difference between your reset vector and the effective reset vector mentioned in the picf10202 datasheet that is illustrated at figure 4-2 p.12 Thanks!!!
@Dominique Tremblay see edited answer for reply.
I do now understand every bits of your code you shared except for one thing... Why did you declared "global Start", "global ResetVector" and "global Temp". I'm not sure why declaring these as global routines is needed.
@DominiqueTremblay, The global assembly language directive will force the symbol to be placed in the symbolic debug name space. These symbols should be visible in a debug session.

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.