ASSEMBLY LANGUAGE PROGRAMMING PART SEVEN - MACROS AND OTHER DETAILS Frequently, when programming, the same short piece of code repeats itself, or, more commonly, code with exactly the same structure. Our project has such a drawback to it due to our method of subroutine calling. Macros can also assign more meaningful means to strings of code. In our case, we can provide somewhat (maybe) more memorable names for our complicated procedure calls and also make the calls easier to use. Instead of taking seven lines for some of the procedure calls, we can use only one line of code to create all the necessary contortions in the code. Now, in order to illustrate the concept, I will give an example. Suppose we had a routine to clear the screen which was called via SWI2 with the byte following the SWI2 instruction specifying the color to use to clear the screen, we might typically see a series of instructions such as: SWI2 FCB 4 to clear the screen to color 4. Clearly, this is difficult to remember. Instead, we might set up a macro as follows (EDTASM syntax): CLRSCR MACRO SWI2 FCB \0 ENDM which takes care of the complicated details. We would then call it as follows: CLRSCR 4 The last line is clearly the easiest to use. There are a couple of catches with macros. The macro must be defined before it can be used, and, every time the macro is called, the code is actually assembled into the final executable. For our purposes, these drawbacks are not real considerations compared to the advantages we obtain from them. Now for a discussion of the anatomy of a macro. Take the one used above. The first line tells the assembler that CLRSCR is a macro. The next two lines are the definition of the macro. The last line tells the assembler that we are finished defining the macro. You may have noticed the strange \0 on the FCB line. The \0 stands for the first argument on the line on which CLRSCR is invoked. In the case of the example, that is 4. There can be up to 36 parameters in a macro call, labelled \0 through \9 followed by \A through \Z. This mechanism allows us to formulate constant parameters into a useable form. Now, we need to decide what to use for names for our clever memory access subroutines. Using the same numbering of the routines as used last time, I propose the following names: 00 CLABO 01 CBOLA 02 CLMCLA LOWah,LOWal,HIGHah,HIGHal 03 CLMRLA 04 CLMCBO LOWblk,LOWoff,HIGHblk,HIGHoff 05 CLMRBO 06 SMCLAC LOWah,LOWal,HIGHah,HIGHal,Value 07 SMCLAR LOWah,LOWal,HIGHah,HIGHal 08 SMRLAC Value 09 SMRLAR 0A LDACLA ah,al 0B LDARLA 0C LDACBO blk,off 0D LDARBO 0E STACLA ah,al 0F STARLA 10 STACBO blk,off 11 STARBO 12 CPLABO 13 CPBOLA 14 SMCBOC LOWblk,LOWoff,HIGHblk,HIGHoff,Value 15 SMCBOR LOWblk,LOWoff,HIGHblk,HIGHoff 16 SMRBOC Value 17 SMRBOR In the above list, CLA stands for "constant linear address", meaning the address is specified as a constant in the instruction. RLA stands for "register linear address", meaning the address is stored in registers. CBO and RBO stand for "constant block/offset" and "register block/offset" respectively. Also, any of the instructions which need parameters have parameter lists specified. For instructions with ranges, LOW specifies the low address and HIGH specifies the high address. ah means the high order 3 bits of the address and al means the low order 16 bits of the address. blk stands for a block number while off stands for an offset within the block. Value is a byte value. You can see in the file MACROS.ASM how I implemented the various macros. In fact, that is the easiest way to explain how these macros work. I'll now deal with one more detail which may prove useful. As you noticed, last time I overran the buffer in EDTASM+ writing the code for that installment. I provided a piece of code to use for assembly purposes that looked somewhat like the following: INCLUDE PART6A.ASM INCLUDE PART6B.ASM The INCLUDE directive in EDTASM is used to literally insert the specified file into code at the point the INCLUDE statement occurs. As soon as the assembler encounters the INCLUDE directive, it assembles the entire file specified as though it were physically present within the file currently being assembled before proceeding to the next line. Not only does this allow for code that is too large to be assembled in one piece to be assembled into one executable, it allows for code to be reused. Or, for that matter, a library of code can be easily included. That should lead to an easy way to use the routines being developed in this series. In fact, I recommend the following code snipped for using these routines: INCLUDE MACROS.ASM get our useful macros ORG START LBSR SETUP call the setup routine for the * subroutines LBRA BEGIN jump around them INCLUDE PART6A.ASM include the code INCLUDE PART6B.ASM BEGIN include your code here . . . . END START end assembly, set start address * for START Until next time, keep programming.