COURS204.TXT

From Atari Wiki
Revision as of 00:11, 17 December 2023 by Olivier.jan (talk | contribs) (Replacing content of with translated version)
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