Shop OBEX P1 Docs P2 Docs Learn Events
IFDEF not working, or is it me? — Parallax Forums

IFDEF not working, or is it me?

WoFWoF Posts: 10
edited 2009-03-30 08:03 in General Discussion
Hello, assembler gurus,

what I wanted to achieve is a default clock frequency of 50MHz, being defined in the common include file.
But I wanted the possibility to override the setting in individual source files.
I want to put a statement like MHZ EQU 20, or MHZ EQU 4 in a source file.
In the include I put:
 IFDEF MHZ
    IF MHZ = 20
       FREQ 20_000_000
    ENDIF
 ELSE
    FREQ 50_000_000
 ENDIF

The assembler will not assemble if I don't have MHZ defined in the source.
But this is the·reason why I used the IFDEF statement. In case I didn't define MHZ I want FREQ 50_000_000 to be executed.
In case I defined MHZ, I want FREQ to be set according to the value of MHZ.
This would be fine.
But the assembler complains about the missing symbol MHZ in the IF MHZ = 20 line.
Why? The assembler is not supposed to assemble the lines between IFDEF MHZ and ELSE?
Bug? Or silly me?

Comments

  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-28 18:29
    The error must be prior to the line the error is listed.
    Please post the entire program.

    Besides that, it is not wise to redefine FREQ.
    Instead, demand·that device and freq are set in the application file·
    rather than an include file. Then also let define a symbol that represents
    the freq so you can have several code sections based on frequency
    in your include files. That way you control everything from the application
    file.

    regards peter
  • WoFWoF Posts: 10
    edited 2009-03-28 23:43
    Yes, Peter, thank you for your suggestions. I went and took the FREQ directive out of the include file which makes more sense, since the targetted clock frequency will always be related to the program you are writing.
    I dropped the idea by now.

    But still the strange behaviour of the Assembler persists.
    Here is a complete sample. Put it in a.src file and try:
     org $100
    IFNDEF  mySym
     inc $09
    ELSE
     IF mySym<10
      REPT mySym
      inc $08
      ENDR
     ENDIF
     IF mySym=10
      call Anything
     ENDIF
    ENDIF
    
    

    mySym is not defined. The assembler should assemble inc $09, no?
    Instead it complains about the line IF mySym<10 in the ELSE clause, which should not be assembled at all, when mySym is not defined.
    Also, mySym must be defined BEFORE the IFDEF statement. (That's ok, as long if you know it). But it is NOT alright, that any expression in a conditionally excluded part of the code is evaluated somehow and cause an error which stops the assembly.
  • WoFWoF Posts: 10
    edited 2009-03-28 23:59
    Ok, there was some more testing and I found:
    This one is ok. No error. If storage is not defined, ds 2 is assembled. The else clause is not evaluated and there is no complaining about storage not being defined.
     org $8
    ifndef storage
     ds 2
    else
     ds storage
    endif
    

    This one is not ok:
     org $8
    ifndef storage
     ds 2
    else
     if storage = 0
      ds 1
     else
      ds storage
     endif
    endif
    


    The IF storage = 0 statement will be evaluated somehow and cause the assembly to fail.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-29 00:39
    There is indeed something wrong when using if{n}def .. else .. endif

    But this works
    org $100
    ;mysym equ 4
    ifndef mySym
      mysym = -1
    endif
    if mysym < 0
      inc $09
    else
      if mySym < 10
        rept mySym
          inc $08
        endr
      endif
      if mySym = 10
        call Anything
      endif
    endif
    
    

    The if .. else .. endif works for sure. I use that frequently.

    regards peter
  • WoFWoF Posts: 10
    edited 2009-03-29 22:43
    Hm... yes. Your IFNDEF never leaves the symbol undefined, avoiding the problem situation. Well... clever. I'd adapt that one.

    Nevertheless, somebody who is responsible for SASM should read that and take in account that there is a leeettle bug in the assembler. smile.gif

    Thanks, Peter, for caring for my problem.
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-03-30 08:03
    I remembered pjv once needed to autocreate a jumptable
    but we couldn't make it work. I used the above trick but with
    a compiler variable. And I think that works.
    Load the attached program and view list.
    It should generate:

         1                  ;autocreate indirect jumptable
         2  0FF8  0BFF      device sx18,oschs1
         3  =01312D00       freq 20_000_000
         4  07FF  0B02      reset reset_entry
         5  =00000000       irc_cal irc_slow
         6                  
         7                  ;------------------------------------
         8                  farcall macro
         9                  curorg = $
        10                  ifndef __??\1
        11                  __??\1 = jmpentry
        12                  endif
        13                  if jmpentry >= $FE
        14                  error "Too many jumpentries"
        15                  endif
        16                  if jmpentry = __??\1
        17                          org     __??\1
        18                  __??\1
        19                          jmp     @\1
        20                  jmpentry = $
        21                  endif
        22                          org     curorg
        23                          call    @__??\1
        24                  endm
        25                  ;------------------------------------
        26                  
        27  =00000000               org     $000
        28  0000  0010              jmp     @interrupt
            0001  0B00
        29  =00000002       jmpentry = $
        30                  ;here we want entries
        31                  ;__farname
        32                  ;       jmp     @farname
        33                  
        34  =00000100               org     $100
        35  =00000100       interrupt
        36  0100  0C27              mov     w,#39
        37  0101  000F              retiw
        38  =00000102       reset_entry
        39  =00000102       main
        40                  farcall target          ;this should setup entry __target and call __target
        41  =00000102    m  curorg = $
        42               m  ifndef __target
        43               m  __target = jmpentry
        44               m  endif
        45               m  if jmpentry >= $FE
        46               m  error "Too many jumpentries"
        47               m  endif
        48               m  if jmpentry = __target
        49  =00000002    m          org     __target
        50  =00000002    m  __target
        51  0002  0010   m          jmp     @target
            0003  0B0D
        52  =00000004    m  jmpentry = $
        53               m  endif
        54  =00000102    m          org     curorg
        55  0102  0010   m          call    @__target
            0103  0902
        57                  farcall target2         ;this should setup entry __target2 and call __target2
        58  =00000104    m  curorg = $
        59               m  ifndef __target2
        60               m  __target2 = jmpentry
        61               m  endif
        62               m  if jmpentry >= $FE
        63               m  error "Too many jumpentries"
        64               m  endif
        65               m  if jmpentry = __target2
        66  =00000004    m          org     __target2
        67  =00000004    m  __target2
        68  0004  0010   m          jmp     @target2
            0005  0B0E
        69  =00000006    m  jmpentry = $
        70               m  endif
        71  =00000104    m          org     curorg
        72  0104  0010   m          call    @__target2
            0105  0904
        74                  farcall target          ;this should just call __target
        75  =00000106    m  curorg = $
        76               m  ifndef __target
        77               m  __target = jmpentry
        78               m  endif
        79               m  if jmpentry >= $FE
        80               m  error "Too many jumpentries"
        81               m  endif
        82               m  if jmpentry = __target
        83               m          org     __target
        84               m  __target
        85               m          jmp     @target
        86               m  jmpentry = $
        87               m  endif
        88  =00000106    m          org     curorg
        89  0106  0010   m          call    @__target
            0107  0902
        91                  farcall target2         ;this should just call __target2
        92  =00000108    m  curorg = $
        93               m  ifndef __target2
        94               m  __target2 = jmpentry
        95               m  endif
        96               m  if jmpentry >= $FE
        97               m  error "Too many jumpentries"
        98               m  endif
        99               m  if jmpentry = __target2
       100               m          org     __target2
       101               m  __target2
       102               m          jmp     @target2
       103               m  jmpentry = $
       104               m  endif
       105  =00000108    m          org     curorg
       106  0108  0010   m          call    @__target2
            0109  0904
       108                  farcall target          ;this should just call __target
       109  =0000010A    m  curorg = $
       110               m  ifndef __target
       111               m  __target = jmpentry
       112               m  endif
       113               m  if jmpentry >= $FE
       114               m  error "Too many jumpentries"
       115               m  endif
       116               m  if jmpentry = __target
       117               m          org     __target
       118               m  __target
       119               m          jmp     @target
       120               m  jmpentry = $
       121               m  endif
       122  =0000010A    m          org     curorg
       123  010A  0010   m          call    @__target
            010B  0902
       125  010C  0B02              jmp     main
       126                  
       127  =0000010D       target
       128  010D  000D              retp
       129                  
       130  =0000010E       target2
       131  010E  000D              retp
    

    @pjv,
    This is what you were after, right?
    I have set aside a fixed area for the jumptable so it does require two compilations
    if you want to trim that area so no codespace is wasted. The first compilation
    will give you the address to be used instead of org $100 (= jmpentry value).


    regards peter
    SRC
    914B
Sign In or Register to comment.