Question

I tried to simulate IF() .... ELIF .... ENDIF in assembly for PIC16F84, but it doesn't seem to work for more than one usage. I tried to use something like this in two places, but it gives some error that a label is duplicated. Shouldn't the parameter from the macro be replaced in the labels too? (name in true_name:)

_f macro name
  btfsc EQUAL,0
  goto true_name
  goto false_name
  true_name:
endm

_lse macro name
  goto next_name
  false_name:
endm

_ndif macro name
  goto next_name
  next_name:
endm

;; usage example
_f label1
  ...
_lse label1
  ...
_ndif 
Was it helpful?

Solution 3

I kinda solved this problem with MPLAB variables, here's an example for testing equality between a register and a literal:

_f_equal_literal macro register,literal,name
    movlw literal
    subwf register,0
    btfss STATUS,2 ;bit indicating result is zero
    goto _false#v(name)
    endm

_lse macro name
    goto _next#v(name)
_false#v(name):
    endm

_ndif macro name
_next#v(name):
    endm

Notice that I didn't use goto _true#v(name) and _true#v(name): label, you'll just have to figure if you need btfss or btfsc.

You can have a single _lse and _ndif macro, and have multiple macros for _f statements.

GJ's solution doesn't have a next label, so the true branch will execute the false branch.


You need to define a variable for each if-else-endif construct. It might even useful if the variable name describes what the if-else-endif is used for.

Example:

variable testing_something=123

_f_equal_literal some_register,some_value,testing_something
                ...       

_lse testing_something
                ...        

_ndif testing_something

OTHER TIPS

I think one can do a bit better. Here's some if-else-endif macros that can be nested five deep. Unfortunately, I was not able to make the definitions of if1, if2.. as nice as I would like since the assembler does not accept "#ifndef if#v(lvl)" so the macros as they stand limit the nesting level to five deep. These symbols count the number of Ifs at a given nesting level so unique labels can be attached. A nonsense example is included.

xIf macro L,R,A

#ifndef lvl
lvl=0
#endif
lvl=lvl+1

#ifndef if1
if1=0
if2=0
if3=0
if4=0
if5=0
#endif

if#v(lvl)=if#v(lvl)+1

    movf    R,A
    xorlw L
    bnz   _false_#v(lvl)_#v(if#v(lvl))
    endm 

xElse macro
    bra  _end_#v(lvl)_#v(if#v(lvl))
_false_#v(lvl)_#v(if#v(lvl)):
    endm

xEndIf macro
_end_#v(lvl)_#v(if#v(lvl)):
lvl=lvl-1
    endm

    xIf 123,STATUS,A
        clrf    TMR3H,A
        xIf 75,STATUS,A
            clrf    TMR3H,A
        xElse
            setf    TMR3L,A
        xEndIf
    xElse
        setf    TMR3H,A
    xEndIf

Do not use jumps from one macro to another, it is dangerous.

There is no need to use unique labels. Two ways haw to do this under MPLAB:

1)Case with LOCAL directive

_f macro name
 LOCAL true_name
      btfsc   EQUAL,0
      goto    true_name
      goto    name  
true_name:
endm

2)Case with $ as current memory address pointer.

_f macro name
      btfsc   EQUAL,0
      goto    $+1
      goto    name
endm
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top