7. Macros 7.1 Defininfg a Macro A macro definition begins with: NAME MAC (no operand) NAME is in the label field. The macro's definition is terminated by the pseudo op EOM or <<<. The label NAME cannot be referenced by anything other than PMC NAME or >>> NAME. You can define a macro the first time you wish to use it the program. However, it is preferable (and required if the macro uses variables) to define all macros at the beginning of the program with the assembly condition;n OFF. The macro(s) then can be called where needed. Forward referencing to a macro definition is not possible and will result in a "NOT MACRO" message. That is, the macro must be defined prior to the first call via PMC. The conditionals DO, ELSE and FIN may be used inside a macro definition. Labels inside macros, such as LOOP and OUT in the example in section 7.4, are updated each time PMC is encountered. Error messages generated by errors in macros usually abort assembly, because of possible harmful effects. Such messages will generally indicate the line number of a PMC rather the line inside the macro where the error occurs. 7.2 Nested Macros Macros may be nested to a depth of 15. For nesting, macros must be defined with the DO condition OFF. Here is example of a nested macro in which the definition itself is nested. (This can only be done when both definitions end at the same place.) TRDB MAC >>> TR.]1+1;]2+1 TR MAC LDA ]1 STA ]2 <<< In this example >>> TR.LOC,DEST will assemble as: LDA LOC STA DEST PMC TRDB.LOC;DEST will assemble as: LDA LOC+1 STA DEST+1 LDA LOC STA DEST A more common form of nesting is illustrated by these two macro definitions (where CH = $24): POKE MAC LDA #]2 STA ]1 <<< HTAB MAC >>> POKE.CH;]1 <<< 7.3 Special Variables Eight variables, named ]1 through ]8 are pre-defined and are designed for use in macros. They receive there values from the variables supplied on the actual call of the macro. For example: >>> NAME.expr1;expr2;expr3;... will assign the value expr1 to the variable ]1, expr2 to ]2, and so on. An example of this concept is: TEMP EQU $10 DO 0 SWAP MAC LDA ]1 STA ]3 LDA ]2 STA ]1 LDA ]3 STA ]2 <<< FIN The call of >>> SWAP $6;$7;TEMP will result in the following code being generated. LDA ]1 becomes LDA $6 STA ]3 STA TEMP LDA ]2 LDA $7 STA ]1 STA $6 LDA ]3 LDA TEMP STA ]2 STA $7 If, as above, some of the special variables are used in the macro definition, then values for them must be provided in the PMC (or >>>) statement. In the assembly listing the special variables will not be printed. Rather, they will be replaced by the variables and/or constants from the macro call. On the macro call itself, the number of parameters input must match the number of variables in the macro definition. A BAD OPERAND error will be generated if the number of parameters is less than the number of variables. However, no error message will be printed if there are more parameters than variables. The assembler will accept some other characters on place of the space between the macro name and the expression in the PMC statement. For example, you may use any of these characters: . / , - ( The semicolons between parameters are required and no extra spaces are allowed. Macros will accept literal data. Thus the assembler will accept the following type of macro call: DO 0 MUV MAC LDA ]1 STA ]2 <<< FIN PMC MUV (PNTR),Y;DEST >>> MUV.#3;FLAG,X It will also accept: DO 0 PRINT MAC JSR SENDMSG ASC ]1 BRK <<< FIN PMC PRINT.!"quote"! PMC PRINT.'This is an example' >>> PRINT."So's this, understand?" LIMITATION: If such strings contain spaces or semicolons, they must be delimited by quotes (single or double. See ASC for single and double quote rules.). Also, literals must have the final delimiter. (This is only true in macro calls or VAR statements, but it is goods practice in all cases.) A previous version of this assembler, that did not have the capabilities just described, used commas rather than semicolons in >>> statements. For people that have source files that used that version, a program called CONVERT has been provided which changes those commas to semicolons in a second or two. In order to use CONVERT follow the following procedure: 1. Boot the MERLIN disk. 2. Load the source file that has the offending commas. 3. Type C(catalog) at the EXEC mode's menu. 4. When the catalog has completed and the word "Command?" appears, type BRUN CONVERT. 5. Save your source file when CONVERT has completed and return is made to the EXEC menu. 7.4 Sample Program Here is a sample program intended to illustrate the usage of macros with non standard variables. It would be simpler and more pleasing if it used ]1 instead of ]MSG since the variable equates would be eliminated and the values for ]1 provided in the >>> lines. HOME EQU $FC58 COUT EQU $FDFD KEY EQU $C000 STROBE EQU $CO10 DOS EQU $3D3 DO 0 ;ASSEMBLY OFF SENDMSG MAC ;START DEFINITION OF THE ;MACRO SENDMSG LDY #0 LOOP LDA ]MSG,Y ;GET A CHARACTER BEQ OUT ;END OF MESSAGE JSR COUT ;SEND IT INY BNE LOOP ;BACK FOR MORE OUT <<< ;END OF MACRO DEFINITION AND ;EXIT FROM ROUTINE FIN JSR HOME ;CLEAR SCREN ]MSG EQU HITMSG >>> SENDMSG INVRS CMP #"I" BNE NORM ]MSG EQU IMSG >>> SENDMSG NORM CMP #"N" BNE STP ;SEE IF HE WANTS TO STOP ]MSG EQU NMSG PMC SENDMSG ;>>> AND PMC ARE EQUIVALENT STP CMP #"S" BNE GETKEY ;NO, GET NEXT KEY INPUT JMP DOS ;ALL DONE. EXIT GRACEFULLY HITMSG ASC !HIT ;A KEY "F","I","N", OR "S"! HEX 8D8D00 FMSG FLS "THIS IS A FLASHING MESSAGE" HEX 8D8D00 IMSG INV "THIS IS A MESSAGE IN INVERSE" HEX 8D8D00 NMSG ASC "THIS IS NORMAL MESSAGE" HEX 8D8D00 7.5 The Macro Library A macro library with the example programs is included in source file form on this diskette. The purpose of the library is to provide some guidance to the newcomer as to the utility of macros. Once macro writing is mastered, one wonders why others consider macros difficult and "not worth the effort." NOTE" All macros are defined at the beginning of the source file, then each example program places macros where they are needed. Conditionals are used to determine which example program is to be assembled. The KBD opcode allows the user to make this selection from the keyboard during assembly.