!pr2
!np
!lm12
!rm75
Star-tling Stunts.....................Bill Morgan & Mike Laumer

In most assemblers, including the S-C Macro Assembler, you can use the character "*" in the operand of an instruction to mean the current value of the location counter.  (The location counter is a variable used by the assembler to keep track of where the next byte of object code goes.)  Here are a couple of simple examples of using the *, from page 6-2 of the Macro Assembler manual:

!lm+10
0800- 03       1000 QT     .DA #QTSZ
0801- 41 42 43 1010        .AS /ABC/
0003-          1020 QTSZ   .EQ *-QT-1
               1030  
0804- 00 00    1040 VAR    .DA *-*
               1050  
0806-          1060 FILLER .BS $900-*
0900-          1070 END    .EQ *
!lm-10

The QT, QTSZ example uses the * to help calculate the length of a string of characters.  The VAR line uses "*-*" to define a variable as having a value of zero.

The expression labelled FILLER causes the assembler to skip ahead to $900.  This has much the same effect as .OR $900, but it won't cause the assembler to close a target file, the way .OR would.

One thing Bill wanted was an expression to have the assembly skip up to the beginning of the next page, no matter what that page might be.  Here's what we came up with:

!lm+10
0800- 34 12    1000 START  .DA $1234
0802-          1010 FILL   .BS *+255/256*256-*
0900- 45 23    1020 END    .DA $2345
!lm-10

If you change the origin to $C00, END will move to $D00.  With this coding, END will always be $100 above START.  Note that there is no precedence when the assembler is evaluating an expression.  Terms are taken strictly left-to-right.  But notice how smart the expression cracker in the assembler is!  It knows that a "*" between numbers or labels means "multiply", and a "*" between arithmetic operators means "location counter".

In the American Heart Association CPR project Mike uses lots of overlays, and has to make sure that modules don't grow above a certain address.  He does it by putting lines like these at the end of a module:

!lm+10
1000        .DO *>LIMIT
1010   !!! PROGRAM TOO BIG !!!
1020        .FIN
!lm-10
!np
Here's an example, to keep a program below the Hi-res pages:

!lm+10
1000        .OR $1FFE
1010        .DA $4321
1020        .DO *>$2000
1030   !!! PROGRAM TOO BIG !!!
1040        .FIN
!lm-10

That will assemble just fine:

!lm+10
               1000        .OR $1FFE
1FFE- 21 43    1010        .DA $4321
               1020        .DO *>$2000
               1040        .FIN

0000 ERRORS IN ASSEMBLY
!lm-10

But, try inserting another line:

!lm+10
1015        .DA $1234
!lm-10

Here's what happens:

!lm+10
*** BAD OPCODE ERROR
 1030   !!! PROGRAM TOO BIG !!!

0001 ERRORS IN ASSEMBLY
!lm-10

The key to this technique is putting a couple of blanks at the beginning of line 1030.  That way, the assembler tries to parse "!!!" as an opcode, and reports an error during pass one, before any code has been generated.

You should be very careful about using "*", and experiment on a test disk when trying something new.  For example, take another look at line 1060 in the first listing.  If you put "*-$900" for the operand, that would be negative.  The result would be $FF07, which would try to write 65,287 zero bytes onto your target file.  The next thing you see is probably DISK FULL!

That's about all the tricky things we have room for right now.  We hope these hints will help you to navigate "by the stars" in your programming.  Just remember to experiment carefully with the * operand before using it in vital programs.  There are also many pitfalls on this road!
