...|....|....|....|....|....|...|....|....|....|....|....|....|.....

                   ALPHANSO'S ASSEMBLER ASSYLUM
                              by SDH


                       More Fun with MACROs


   Hey gang! Last month we explored the practicality and readability
of user defined MACROs. This months session will take another look at
MACRO definitions, exploring some quick tricks with MACROs that make
some programming problems a snap.

Quick Review

   Remember, a user defined MACRO is a small piece of source code
that aids in generating very similar or like bodies of more SOURCE
CODE. To produce slight modifications within a body of repeating
source code, the assembler allows variables to be "passed" to the
MACRO. When the assembler reaches a MACRO call from within the
main body of the code, it will scan the source code file for the
defined MACRO, substitute the variables passed to the MACRO source
code block before assembling, and finally assemble the block of
code accordingly. If you are unfamiliar with the above discussion -
see AAA, July '86.

Creating More MACROs

   Most screen control fuctions handled from within BASIC are taken
care of with the PRINT TAB (#,#) instruction. For example, from
within BASIC, PRINT TAB (-1,0) will clear the screen. PRINT TAB (4,5)
will move the cursor to row 4, column 5. Most of you are familiar
with these calls - called "TCRT calls". Alpha Micro has reserved many
PRINT TAB (#,#) functions for special screen control purposes. See
your AMOS/L Monitor Calls manual - Chapter 7 - for the complete
listing.

   For one to execute a TCRT call from within assembler, the
following rules need to be followed: using D1 as the dedicated
register, place a word value in D1 that represents (#,#). The most
significant byte, or MSB (the left hand byte of the word), should
contain the left hand number, and the least significant byte, the LSB
(the right hand byte of the word), should contain the right hand
number. After D1 is set up according to the above rule, the monitor
call TCRT will take the word in D1 and execute a "PRINT TAB (#,#).
Graphically:

                MSB       LSB
           +---------------------+
           | 00000100 | 00000101 |   <-----  Register D1 (word)
           +---------------------+
                 \           \       "Cursor to row 4, column 5"
               binary 4   binary 5

   Simple enough, no? Let's see how we can use the pattern of always
placing a word value into register D1 and calling TCRT to create a
few new MACROs. By using last months JOBRUN program, we will add some
simple tricks to this file and create a "dynamic" modem STAT program
that will report everything that JOBRUN did, but will continue to
update you on any changes in programs being run by any one JOB.
Here's a new version of JOBRUN:

; ed: JOBRUN is in a listing JOBRUN.M68 in 300,7... "mac" it or no???

Line-by-Line, Byte-by-Byte

   Again I am going to bypass all repeated lines previosly covered
in AAA. If you do not have your back issues or are unsure of any
previous coverage, you may either order back issues via AMUS or
obtain previous articles in the assembler SIG PPN on the Network -
[100,133].

OBJNAM
| |
| |
ENDM (TYPEIT)
   This portion of the code should be "old hat", so it will not be
covered in this months session.

DEFINE PRTTAB AA,BB
   This statement is informing the assembler that what is to follow
will be a MACRO definition that contains two variables within the
MACRO. If PRTTAB is used within the main body of the program, the
code directly below this definition will replace PRTTAB, and the
variables AA and BB will also be swapped out accordingly.

MOVB     #AA,D1
   This instruction will take the first of the two values PASSED to
PRTTAB from within the main body of the program and place this byte
value  into the lower 8 bits of register D1. If for example the main
program contained PRTTAB 4,5 , D1 would contain at this time a "4" in
the lower 8 bits of the 32 bit register.

LSLW  D1,#10
   Logically Shift Left the Word contained in D1 by 8 decimal bits.
What this will do is take the WORD in D1 and shift the 16 bits that
make up the word to the left. ZEROS are shifted in from the right.
Graphically:

            D1 before LSLW                 D1 after LSLW #10
   -----+---------------------+    -----+---------------------+
   ..xx | 00000000 | 00000100 |    ..xx | 00000100 | 00000000 |
      --+---------------------+       --+---------------------+

                 <----- movement of shift -------

MOVB #BB,D1
   This will take the value of BB and place this byte in the lowest
8 bits of D1. Notice that since we use the MOVB, the bits 8-15 remain
untouched from the MOVe.

TCRT
   The actual TCRT call. This call will examine what word is in the
register D1 and perform the special screen function accordingly,
i.e., something like "clear the screen" or perhaps a simple cursor
movement to a given row/column location.

ENDM
   End of the Macro definition.

DEFINE TABDWN AA,BB
 |   |
 |   |
ENDM
   See if you can figure out exactly what this MACRO does. It is
very similar to the previous MACRO but with a slight twist.
Basically, this MACRO will move the cursor to a particular row/column
location on the screen, and at the same time, increment the row
number for the next usage of the MACRO call. This is a useful MACRO
when printing out columns of information.

PHDR -1,0,PH$REE!PH$REU
GETIMP IMPSIZ,A5
   These two lines should look extremely familiar. PHDR will define
a program header that AMOS will examine if this file is to be loaded
into system memory. GETIMP will assign the address register A5 with
the value inside your particular memory location that points to the
first (and only) variable used in this program.

PRTTAB  -1,29.
   The first call to the PRTTAB MACRO. Since a MACRO is just a
source code generation routine, PRTTAB -1,29. is replaced with the
instructions contained within the PRTTAB MACRO definition, and, "AA"
is replaced with "-1", "BB" is replaced with "29" decimal (note the
"." to indicate decimal). This simulates a PRINT TAB (-1,29), which
is the reserved TCRT call to turn the cursor off.

PRTTAB   -1,0
   Similar to the above PRTTAB, but this one will clear the screen
of your terminal.

MOV #3,D4
   The MACRO TABDWN requires a "dedicated" data register that will
dynamically keep track of the correct row number when printing
columns. I have chosen the register D4 because I have learned from
experience that this particular data register is not "blown out" by
some other monitor call or special library call. Therefore, D4 will
actually contain the correct row number for column printing, starting
with an initial value of three.

TABDWN  D4,40
   This will generate assembly language instructions listed within
the TABDWN MACRO definition, replacing AA with D4, and BB with 40.
For the first TABDWN call, the cursor will be moved to row #3/column
#40 (octal). After the cursor movement, D4 will be incremented to
contain a #4. See if you can follow the sequence by examining the
TABDWN MACRO definition.

TYPE    < Job      Program>
TABDWN  D4,40
TYPE    <-------+--------->
   These three lines will create the header information for JOBRUN.
Notice that no CRLF (carriage-return-line-feed) is needed after each
TYPE monitor call due to the TABDWN MACRO call. It is this call that
takes care of the necessary cursor movements.

LOOP:  CTRLC  EXIT
   Here is the first introduction to error trapping! It is useful to
understand what happens within a program when a user hits a ^C. Upon
a ^C, a flag is set in the JCB (Job Control Block) status word
located at the JOBSTS offset in the JCB. CTRLC will check this status
word and see if there is a ^C waiting to be processed. If there IS,
then the program will JMP to the label following the CTRLC monitor
call; in this case, the label EXIT. Note: the only time the program
will JMP to the label EXIT is when this particular instruction line
is executed. The program will NOT JMP to the label EXIT until this
line is executed, so placement of CTRLC monitor calls must be
properly located to insure that the ^C will be "seen" by the program.

MOV JOBTBL,A0
|   |   |
|   |   |
EXIT
END
   I'm assuming that the rest of the program is faily self
explanatory since it resembles JOBRUN 1.0(100) in last month's
session fairly close, with all "new" instruction lines covered above.
See if you can follow the logic of the lines not presented in full,
reading the comment lines of the source file if you need help.
   Remember, if you use FIX to examine the workings of the program,
all of the MACRO calls will be replaced by the actual body of the
MACRO including substitutions. The program within FIX will seem a bit
"longer" that what your origionally wrote, but that's part of the
whole idea behind MACROs anyway. Also, I promised to show you how to
create a user library of frequently used MACROs etc. Well, maybe next
month since I have been out of town quite a bit this month (Excuses,
excuses!). See you next month, experiment, and call if you have Q's.