COURS204.TXT

From Atari Wiki
Jump to navigation Jump to search

******************************************************************
*                                                                *
*             68000 ASSEMBLER COURSE ON ATARI ST                 *
*                                                                *
*                 by The Fierce Rabbit (from 44E)                *
*                                                                *
*                         Second series                          *
*                                                                *
*                         Lesson number 4                        *
******************************************************************

After seeing the principle of inclusions, we will now focus on the 
concept of MACROS. This path may seem strange to you since we are 
not tackling line_A, for example, right away. That’s simply because 
these concepts will be extensively revisited in the following 
chapters, which is why I’ve decided to approach them now.

To explain what a MACRO is, let’s start with a simple example: 
displaying HELLO on the screen. We've long known how to do this 
with Gemdos function number 9.

        MOVE.L  #MESSAGE,-(SP)
        MOVE.W  #9,-(SP)
        TRAP    #1
        ADDQ.L  #6,SP

MESSAGE DC.B    "HELLO",0

The problem (if one can call it a problem...) is that you have to type 
4 lines of instructions to perform the operation. We will therefore 
create one large instruction that will encompass all 4. Micro meaning 
small and macro meaning large, this 'large' instruction will be named 
macro-instruction or more commonly macro.

First, we need to define the macro. In this example, let’s call it…
PRINT (original, right?) It needs to take as a parameter the address
of our phrase to display. How do we define this macro? Here lies an
unsolvable problem: the method of defining a macro depends on the
assembler. Indeed, the signs and conventions used to define a macro
are specific to your assembler.

You immediately see the downside: macros defined with Profimat cannot
be used with DEVPACK, etc...

Let’s look at the definitions under DEVPACK, those who don't have
this assembler or who wish to define macros with another assembler
will need to refer to the user manual. The principle, however, remains
the same.

PRINT     MACRO    ADR_TXT
          MOVE.L   1,-(SP)
          MOVE.W   #9,-(SP)
          TRAP     #1
          ADDQ.L   #6,SP
          ENDM

There’s our macro defined: First, its name is placed on the far left.
Then we list the parameters that it needs to receive, after the word
MACRO. In this case, I named it ADR_TXT. For the macro, the fact that
this name is the first one after the word MACRO means that it is number 1.
It will be referred to as \1. Then comes the body of my program which
uses \1 as if it was the address of my phrase. The macro definition
is concluded by ENDM (END MACRO).

The macro definition is placed at the beginning of the program. Because
this definition contains MACRO and ENDM, the assembler knows very well
not to assemble it. However, when it encounters PRINT #MESSAGE, it will
know that it is a macro and will go to copy it in place of PRINT.

Here is an example:

(   copy here the definition of the print macro   )
VOID_INP2 MACRO
          MOVE.W   #7,-(SP)
          TRAP     #1
          ADDQ.L   #2,SP
          ENDM

END_PRG   MACRO
          MOVE.W   #0,-(SP)
          TRAP     #1
          ENDM

          PRINT    #MESSAGE
          VOID_INP2
          PRINT    #MESSAGE2
          VOID_INP2
          END_PRG

          SECTION DATA
MESSAGE   DC.B     "FIRST PHRASE",0
MESSAGE2  DC.B     13,10,"AND THE SECOND!!!",0

Type this program, then assemble it and launch it. Afterwards,
debug it and you will see that the macro calls have been
replaced by the texts of these macros. For now, we have
seen only one macro with 1 parameter passage. The number of
these 'passable' parameters to a macro is variable and depends
on the assembler. Thus, in DEVPACK it is possible to pass
up to 36 parameters which will be identified by numbers (0-9)
and then by letters (A-Z or a-z). It is also possible
to call a macro from another macro.

That being said, there are very many disadvantages to using
macros. Some programmers love them, I must admit it’s not
my case. Indeed, the huge advantage of assembler lies in
the small number of instructions and hence the small number
of terms to remember. As soon as you start to proliferate
macros, you find yourself stuck between two fires: either
give them simple names and get mixed up between them, or give
them long names and often make mistakes in their spelling.

Some even go as far as to create macros for calls to GEMDOS,
BIOS or XBIOS, calling the macros by the function names or by
number. I do not find this solution particularly viable because
the names of the operating system functions are not very
'talkative'. (a macro named setprt or cprnos.....)
Moreover, it must be acknowledged that calls to BIOS, XBIOS,
GEMDOS are all made in the same manner and that it’s not
difficult to remember. However, we will see that the use of
macros in the case of line_A or GEM is an excellent solution.

On this topic, the MAD_MAC assembler is known for its huge
library of macros. Unfortunately, there is some doubt about
its availability. The STATION Computing club asserts that
it’s a Public Domain while Atari provides it with the
development pack. In any case, the Station club used to supply
it without its macro library, which considerably reduced its
interest.

To conclude with macros, know that it is of course possible
to define a library of macros and then include it with INCLUDE
at the beginning of your program. That’s what we’ll do with
GEM, among other things.

Example exercise: create a macro which you will name, for
example, PRINT_AT and that you’ll call this way:
         PRINT_AT #12,#14,#MESSAGE

The 2 numbers indicating the location where you want the text
to be displayed.

A note: it would be entirely possible not to put the #,
but at that time, it would be necessary to put it in the macro.
For example

print     macro    1
          move.w   #\1
          move.w   #2
          trap     #1
          addq.l   #4,sp
          endm

To display the character A of ASCII code 65 one would then have to
do PRINT 65

Back to ASM_Tutorial