1

Hi all, first time on this great Atari forum. Unfortunatelly I don't know Polish so I often figure out by the content what is talked about here. I started using MADS and it is really great assembly language cross-compiler with all those great features. One question thou. I can't make it work when using .IF statement. Funny but true. I could go using ASM branches but why not using this feature. The problem I found is when I declare a variable like this: 

.var j .word

Then I declare the value for it like  mwa #10 j

But if I use something like that:

.if j > 10
  jsr printf
  dta c'*** j > 10 ***',$9b,0
.else
  jsr printf
  dta c'*** j = 10 ***',$9b,0
.endif

the program flow jumps to the first part of .IF statement, which should in fact go the second one. Please help me out and tell me what I am doing wrong.

Thank you for any help, greetings
Gury

2 Ostatnio edytowany przez laoo/ng (2007-09-16 19:13:39)

You've became a victim of misconception :)
Directive .var declares placeholder for data in atari memory at the end of code, where it's used. "mwa" does not declare any value, because it is a kind of 6502 code macro So when you write "mwa #10 j" it generates sequence of "lda #10 sta j" . It does not change value of j. ".if j > 10" always holds because you assemble your code to memory address greater than 10 :)

3 Ostatnio edytowany przez Gury (2007-09-16 20:07:36)

Ok, thank for explanation. I am aware of MADS abbreviations for long ordinary instructions. But I am really confused now :) So lda #10 sta j does not change the contents (literal value) of variable j? So please tell me what it really does? I am using MADS variables this way and I have no problems with them in any other operation, except in the example with .IF statement right now. Sorry for my newbie question :)

4

"sta j" changes value in atari memory at address held in label "j". So "j" is not really a variable, but a label of (or a "pointer to") some place in memory. There is obvious difference between assigning value to label (virtually by MADS during assembling) and storing value in memory (physically by 6502 during execution of resulting program). Here you have a listing from simple example:

     1                     org $2000
     2
     3 = 0000            .var j .word
     4
     5 FFFF> 2000-2008> A9 0A        lda #10
     6 2002 8D 07 20            sta j
     7
     8                 .if j > 10
     9 2005 69 66            dta c'if'
    10                 .else
    11                     dta c'else'
    12                 .endif
    12 = 2007 00 00        J

MADS assigned to "J" value of $2007 (at the end of code) and "sta j" stores content of acumulator to memory at addres $2007. '.if' does not know anything about contents of this memory location. It checks value of label "j" which is $2007, therefore "j > 10" evaluates to true. Try to assemble it from addres 0 (org $0000) then address of "j" would be $0008 and "j > 10" would be evaluated to false and "else" path of condition would be used.

You have to distinct "metaprogramming" in assembler from "programming" on machine.

5

as far as I understand it, it changes the memory at adress 'j'. However, 'j' is still the same address.
It's similar to modifying a pointer or a value that the pointer points to in C/C++.

: 404. Stopka not found

6 Ostatnio edytowany przez Gury (2007-09-16 21:07:50)

Thank you laoo/ng, it tells me a lot more about internal functioning of MADS. What i missed was clarifying some things like the problem above. It will help me to understand more and differentiate labels and variables at specific memory addresses.

7 Ostatnio edytowany przez Gury (2007-09-16 22:39:39)

This discussion helped me a lot to understand it more. The problem was solved with declaring extra variables such as

TEMP1 equ $3000
TEMP2 equ $3001

and then after copying the contents of variables such as j (from previous problem) to TEMP1 (specific memory address location) and set TEMP2 to some value to compare, it worked perfectly.

.if TEMP1 > TEMP2
...

8 Ostatnio edytowany przez eru (2007-09-16 21:53:41)

The above 'if' will always evaluate false. TEMP1 and TEMP2 are still "pointers", not the data.
One thing that confuses you clearly, is that .IF (or IFT) is actually evaluated during COMPILATION not EXECUTION. It's a preprocessor directive, and not some macro.
It's useful for things like conditional compilation, e.g.:

  ldx array,y
  .if DEBUG_ON
  stx $20  ; so we can check in a debugger what 'routine' was called with
  .endif
  jsr routine

If DEBUG_ON is on, the STX will be included in the compiled program, if not, not.

: 404. Stopka not found

9 Ostatnio edytowany przez Gury (2007-09-16 22:41:56)

That's right. I tried several conditions and it always resulted in False. Thanks, this clarify things. Branching instructions are the only way in my case. Tell me, is WHILE statement behaving differently? I had no problem using this feature. As I see it emulates high language WHILE, comparing literal values (.word variables).

10 Ostatnio edytowany przez tebe (2007-09-17 00:39:12)

Gury use directive .TEST , .ENDT (.ELSE, .ELSEIF not exist)

.test .word j>#10 (value = 10)

.test .word j>10   (value from addres 10..11)

.test .byte     - ok
.test .word    - ok

.test .long       - not working
.test .dword    - not working


org $2000

.var j .word

mwa #10 j

.test .word j > #10
  jsr printf
  dta c'*** j > 10 ***',$9b,0
 
  jmp skip
.endt

  jsr printf
  dta c'*** j = 10 ***',$9b,0

skip

jmp *

.link 'stdio\printf.obx'

run $2000

*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

11

Thank you 100x times Tebe, that is what I need. Super!