4 * Copyright (C) 2010-2021 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 * The module asmcro.c includes the macro processor.
31 * asmcro.c contains the following functions:
32 * char *fgetm() get a macro text line
33 * VOID getdarg() get a macro definition argument
34 * VOID getxarg() get a macro expansion argument
35 * VOID getxstr() get a macro expansion string
36 * int macro() run a macro
37 * VOID macroscn() scan macro text line for symbols
38 * int macrosub() substitute macro expansion arguments
39 * VOID mcrinit() initialize macro processing variables
40 * int mcrprc() macro processing control
41 * char *mstring() store a macro string
42 * char *mstruct() allocate macro space
43 * mcrdef *newdef() initialize a macro definition
44 * mcrdef *nlookup() lookup a macro
47 /*)Function int mcrprc(code))
49 * int code function code
51 * The function of mcrprc() is to evaluate the
52 * following assembler directives:
54 * .macro define a general macro
55 * .irp define an inline indefinite repeat macro by arguments
56 * .irpc define an inline indefinite repeat macro by characters
57 * .rept define an inline repeating macro
58 * .mexit exit to end of macro
60 * .nchr assign number of characters in a string to a symbol
61 * .narg assign number of expansion arguments to a symbol
62 * .ntyp assign 0/1 if absolute/relocatable symbol
63 * .nval assign value of argument to an absolute symbol
64 * .mdelete delete a macro definition
66 * And to control the building and exiting of a macro
67 * by the use of the internal assembler directives:
69 * O_BUILD building a macro processing
70 * O_EXIT exit a macro processing
73 * int d character string delimiter
74 * expr e1 expression structure
76 * mne *mp pointer to an assembler mnemonic structure
77 * macrofp *nfp macro pseudo FILE Handle
78 * mcrdef *nq pointer to a macro definition structure
79 * mcrdef *np pointer to a macro definition structure
80 * int rptcnt repeat count evaluation
81 * sym *sp pointer to a symbol structure
82 * strlst *str string list structure
85 * asmf * asmc current asmf structure
86 * sym dot current program counter value structure
87 * a_uint laddr equate value
88 * int lmode assembler list mode
89 * mcrdef mcrlst pointer the macro definition linked list
90 * mcrdef mcrp pointer to macro definition being built
93 * a_uint absexpr() asexpr.c
94 * VOID clrexpr() asexpr.c
97 * VOID getdarg() asmcro.c
99 * int getdlm() aslex.c
100 * int getmap() aslex.c
101 * int getnb() aslex.c
102 * VOID getxarg() asmcro.c
103 * sym * lookup() assym.c
104 * VOID macro() asmcro.c
105 * mne * mlookup() assym.c
107 * char * mstring() asmcro.c
108 * VOID * mstruct() asmcro.c
109 * mcrdef *newdef() asmcro.c
110 * VOID qerr() assubr.c
111 * VOID unget() aslex.c
112 * VOID xerr() assubr.c
115 * Macro directives processed and
116 * macro structures created.
122 struct mcrdef
*np
,*nq
;
134 * Valid .macro definition forms:
137 * .macro mne(,) arg1(,) arg2(,) ((,) arg3(,) ...(,) argn)
139 * where 'mne' is a string beginning with a
140 * LETTER followed by LETTERs or DIGITs.
142 * If the 'arg' is immediately preceeded by a '?'
143 * (ie ?arg) then the argument is a dummy argument.
144 * Dummy arguments left blank become local symbols
145 * when the macro is expanded.
153 xerr('q', ".macro requires at least one argument.");
155 np
= newdef(code
, id
);
157 * Get macro definition arguments
166 * Valid .irp definition forms:
169 * .irp sym(,) arg1(,) arg2 ((,) arg3(,) ...(,) argn)
171 * where 'sym' is a string beginning with
172 * a LETTER followed by LETTERs or DIGITs.
174 * The complete .irp definition is processed once
175 * for each argument in the .irp definition.
178 * An inline definition
180 np
= newdef(code
, NULL
);
182 * Get macro definition argument
186 * Get expansion arguments
191 np
->rptcnt
= np
->xarg
;
196 * Valid .irpc definition forms:
199 * .irpc sym(,) character_string
201 * where 'sym' is a string beginning with
202 * a LETTER followed by LETTERs or DIGITs.
204 * The complete .irpc definition is processed once
205 * for each character in the character_string.
207 * If the character_string contains white space
208 * or commas then the character string must be
209 * delimited as ^/character_string/ where the
210 * delimiting character ('/') must not be in
214 * An inline definition
216 np
= newdef(code
, NULL
);
218 * Get macro definition argument
222 * Get expansion argument
225 np
->rptcnt
= (np
->bgnxrg
!= NULL
) ? strlen(np
->bgnxrg
->text
) : 0;
230 * Valid .rept definition forms:
234 * where 'sym' is a symbol or expression which
235 * is evalauated to an absolute value.
237 * The complete .rept definition is processed
241 * An inline definition
243 np
= newdef(code
, NULL
);
249 rptcnt
= (int) absexpr();
254 xerr('o', ".rept requires a repeat count.");
261 if (asmc
->objtyp
!= T_MACRO
) {
262 xerr('n', ".endm found without matching .macro.");
269 if (asmc
->objtyp
== T_MACRO
) {
270 nfp
= (struct macrofp
*) asmc
->fp
;
272 nfp
->lstptr
= nfp
->np
->endlst
;
274 xerr('n', ".mexit found outside of a macro.");
290 while (getmap(d
) >= 0) {
294 laddr
= sp
->s_addr
= rptcnt
;
298 nfp
= (struct macrofp
*) asmc
->fp
;
300 if (asmc
->objtyp
!= T_MACRO
) {
301 xerr('n', ".narg found outside of a macro.");
304 if (np
->type
!= O_MACRO
) {
317 laddr
= sp
->s_addr
= np
->xarg
;
330 laddr
= sp
->s_addr
= (e1
.e_flag
|| e1
.e_base
.e_ap
) ? 1 : 0;
347 laddr
= sp
->s_addr
= e1
.e_addr
;
360 if (np
== nq
->next
) {
368 if (more() && comma(0) && !more()) {
369 xerr('q', "Expecting argument after ','.");
376 if (asmc
->objtyp
== T_MACRO
) {
377 nfp
= (struct macrofp
*) asmc
->fp
;
387 if (((mp
= mlookup(id
)) != NULL
) &&
388 (mp
->m_type
== S_MACRO
)) {
389 switch (mp
->m_valu
) {
406 * Append to MACRO Definition
408 str
= (struct strlst
*) mstruct (sizeof (struct strlst
));
410 str
->text
= mstring(ib
);
411 if (mcrp
->bgnlst
== NULL
) {
414 mcrp
->endlst
->next
= str
;
420 if (mcrp
->nest
== 0) {
421 switch (mcrp
->type
) {
429 if (mcrp
->rptcnt
!= 0) {
438 if ((lnlist
& LIST_MD
) == 0) {
449 /*)Function VOID getdarg(np)
451 * struct mcrdef *np pointer to macro definition structure
453 * The function getdarg() gets the next macro definition
454 * argument from the assembler input text. The definiton
455 * may be any valid label or symbol (excluding temporary
459 * strlst *str text line structure
460 * char id[] text string
464 * char ctype[] charcter type array
465 * mcrdef mcrp link to macro definition being built
468 * int comma() aslex.c
469 * int getid() aslex.c
470 * int getnb() aslex.c
471 * char * mstring() asmcro.c
472 * VOID * mstruct() asmcro.c
473 * VOID qerr() assubr.c
476 * Macro definition argument is added to macro definition
477 * structure and the number of arguments is incremented.
478 * Failure to allocate space for the argument string will
479 * terminate the assembler.
483 getdarg(struct mcrdef
*np
)
494 if (((c
=getnb()) == '?') && (ctype
[c
=get()] & LETTER
)) {
498 if (ctype
[c
] & LETTER
) {
507 str
= (struct strlst
*) mstruct (sizeof (struct strlst
));
509 str
->text
= mstring(id
);
510 if (np
->bgnarg
== NULL
) {
513 np
->endarg
->next
= str
;
519 /*)Function VOID getxarg(np)
521 * struct mcrdef *np pointer to macro definition structure
523 * The function getxarg() gets the next macro expansion
524 * argument from the assembler input text. The expansion
525 * may contain any ASCII character including the space and
526 * tab characters. If the argument contains a comma then
527 * the argument string must be delimited using the form
529 * ^/ ... / where the character '/' may be any
530 * printing character not in the delimited string.
532 * If the undelimited string is of the form \arg then
533 * the argument is evaluated and represented by an
534 * unsigned integer in the current radix.
537 * char id[] text string
538 * char * frmt format string pointer
539 * char * sip save ip pointer
540 * strlst *str text line structure
543 * char * ip source text line pointer
546 * a_uint absexpr() asexpr.c
547 * VOID getxstr() asmcro.c
548 * char * mstring() asmcro.c
549 * VOID * mstruct() asmcro.c
550 * int sprintf() c_library
553 * Macro expansion argument is added to macro definition
554 * structure and the number of arguments is incremented.
555 * Failure to allocate space for the argument string will
556 * terminate the assembler.
560 getxarg(struct mcrdef
*np
)
568 * Get the argument string
572 str
= (struct strlst
*) mstruct (sizeof (struct strlst
));
580 case 10: frmt
= "%lu"; break;
581 case 8: frmt
= "%lo"; break;
582 case 16: frmt
= "%lX"; break;
587 case 10: frmt
= "%u"; break;
588 case 8: frmt
= "%o"; break;
589 case 16: frmt
= "%X"; break;
592 sprintf(id
, frmt
, absexpr());
595 str
->text
= mstring(id
);
596 if (np
->bgnxrg
== NULL
) {
599 np
->endxrg
->next
= str
;
605 /*)Function VOID getxstr(id)
607 * char * id pointer to string
609 * The function getxstr() processes the next macro expansion
610 * argument from the assembler input text. The expansion
611 * may contain any ASCII character including the space and
612 * tab characters. If the argument contains a comma then
613 * the argument string must be delimited using the form
615 * ^/ ... / where the character '/' may be any
616 * printing character not in the delimited string.
620 * int dc delimiting character
621 * char * p character string pointer
624 * char ctype[] charcter type array
627 * int comma() aslex.c
629 * int getnb() aslex.c
630 * VOID qerr() assubr.c
631 * VOID unget() assym.c
634 * Macro expansion argument is returned in id[].
644 * The argument delimiters are SPACE, TAB, and ','.
645 * If the argument contains a SPACE, TAB, or ',' then
646 * the argument must be enclosed within a delimiter of
647 * the form ^/ ... / where the character '/' may
648 * be any character not in the delimited string.
656 case '^': dc
= get(); break;
657 default: dc
= ','; break;
661 while ((c
=get()) != '\0') {
667 if (ctype
[c
] & ILL
) {
673 while ((c
=get()) != '\0') {
688 /*)Function VOID macro(np)
690 * mcrdef *np macro definition structure
692 * macro() prepares the macro described by
693 * np for insertion into the code stream.
696 * macrofp *nfp pseudo FILE Handle
697 * strlst *str missing argument expansion string
698 * strlst *arg macro definition argument string
699 * strlst *xrg macro expansion argument string
700 * char xrgstr[] dumby argument evaluation string
703 * asmf asmq queued macro structure
704 * int srcline current assembler line number
705 * int flevel current IF-ELSE-ENDIF level
706 * int tlevel current IF-ELSE-ENDIF level index
707 * int maxmcr maximum macro nesting level encountered
708 * int mcrfil macro nesting counter
709 * int lnlist current LIST-NLIST flags
712 * VOID getxarg() asmcro.c
713 * char * mstring() asmcro.c
714 * VOID * mstruct() asmcro.c
715 * char * strcpy() c_library
716 * int sprintf() c_library
717 * int strlen() c_library
718 * VOID qerr() assubr.c
721 * Macro is inserted into assembler stream
734 if (++mcrfil
> MAXMCR
) {
739 if (mcrfil
> maxmcr
) {
743 * Create an asmf structure for nxtline()
745 asmq
= (struct asmf
*) mstruct (sizeof (struct asmf
));
747 asmq
->objtyp
= T_MACRO
;
748 asmq
->line
= srcline
;
750 asmq
->flevel
= ftflevel
- 1;
753 asmq
->flevel
= flevel
;
755 asmq
->tlevel
= tlevel
;
756 asmq
->lnlist
= lnlist
;
758 strcpy(asmq
->afn
,np
->name
);
760 * Create a macrofp structure for fgetm()
762 nfp
= (struct macrofp
*) mstruct (sizeof (struct macrofp
));
764 nfp
->lstptr
= np
->bgnlst
;
765 nfp
->rptcnt
= np
->rptcnt
;
767 nfp
->flevel
= asmq
->flevel
;
768 nfp
->tlevel
= asmq
->tlevel
;
769 nfp
->lnlist
= asmq
->lnlist
;
770 nfp
->npexit
= nfp
->rptcnt
? 0 : 1;
772 * Check if arguments are required
774 if (np
->type
== O_MACRO
) {
781 if (np
->xarg
> np
->narg
) {
785 * Fill in missing arguments and
786 * check for dummy arguments.
790 while (arg
!= NULL
) {
792 str
= (struct strlst
*) mstruct (sizeof (struct strlst
));
794 str
->text
= mstring("");
795 if (np
->bgnxrg
== NULL
) {
798 np
->endxrg
->next
= str
;
803 if ((*arg
->text
== '?') && (strlen(xrg
->text
) == 0)) {
805 sprintf(xrgstr
, "%lu$", mls
.s_addr
++);
807 sprintf(xrgstr
, "%u$", mls
.s_addr
++);
809 xrg
->text
= mstring(xrgstr
);
816 * Cast nfp as a FILE HANDLE
818 asmq
->fp
= (FILE *) nfp
;
823 /*)Function mcrdef *newdef(code, id)
825 * int code macro type code
826 * char * id macro name string
828 * The function mcrdef() creates a new macro
829 * definition structure and initializes it.
832 * mne * mp pointer to a mnemonic structure
835 * mcrdef *mcrp pointer to the new macro definition structure
838 * mne * mlookup() assym.c
839 * char * mstring() asmcro.c
840 * VOID * mstruct() asmcro.c
841 * mne * nlookup() asmcro.c
844 * Macro definiton structure created
856 * New MACRO Definition
858 mcrp
= (struct mcrdef
*) mstruct (sizeof (struct mcrdef
));
861 * Check for Assembler Directive Conflicts
864 if (nlookup(id
) != NULL
) {
867 mcrp
->name
= mstring(id
);
870 if (mp
->m_type
< S_DIREOL
) {
875 mcrp
->name
= mstring("");
891 /*)Function mcrdef *nlookup(id)
893 * char * id macro name string
895 * The function nlookup() searches the macro list
896 * for a match returning a pointer to the macro
897 * definition structure else it returns a NULL.
900 * mcrdef *np pointer to macro structure
920 if (symeq(id
, np
->name
, 1)) {
928 /*)Function char *fgetm(ptr, len, fp)
930 * char * ptr pointer string address
931 * int len maximum number of characters to return
932 * FILE * fp pseudo FILE Handle
934 * The function fgetm() reads characters from the pseudo
935 * stream fp into the string pointed to by ptr. The integer
936 * argument len indicates the maximum number of characters
937 * that the buffer ptr can store. Reading stops when an end
938 * of string or len-1 characters were read. The string read
939 * is terminated with a 0.
941 * Macro types O_MACRO, O_IRP, and O_IRPC will have
942 * the macro definition strings replaced by their
943 * respective macro expression strings.
945 * When no more macro lines are available then
946 * the macro terminates by restoring the assembler
947 * conditional and listing state at the time the
948 * macro was invoked and a NULL is returned.
951 * macrofp *nfp pointer to the pseudo FILE Handle
952 * mcrdef *np pointer to macro structure
955 * char ib[] string buffer containing
956 * assembler-source text line for processing
957 * char * ip pointer into the assembler-source
959 * int flevel current IF-ELSE-ENDIF level
960 * int tlevel current IF-ELSE-ENDIF level index
961 * int lnlist current LIST-NLIST flags
962 * int mcrline current macro line number
966 * fprintf() c_library
967 * macroscn() asmcro.c
968 * strncpy() c_library
971 * mcrline, the current macro line number
976 fgetm(char *ptr
, int len
, FILE *fp
)
982 * macroscn() and macrosub()
983 * require that ptr == ib !!!
986 fprintf(stderr
, "?ASxxxx-Internal-fgetm(ptr)-Error.\n\n");
992 fprintf(stderr
, "?ASxxxx-Internal-fgetm(fp)-Error srcline %d.\n\n", srcline
);
996 nfp
= (struct macrofp
*) fp
;
999 if (nfp
->lstptr
== NULL
) {
1000 if (nfp
->npexit
== 0) {
1001 if ((flevel
!= nfp
->flevel
) ||
1002 (tlevel
!= nfp
->tlevel
)) {
1007 * Repeat macro until repeat count is zero or an
1008 * .mexit has been processed then exit with NULL
1010 if ((--nfp
->rptcnt
<= 0) || (nfp
->npexit
!= 0)) {
1013 nfp
->lstptr
= np
->bgnlst
;
1018 * Reset IF-ELSE-ENDIF and LIST-NLIST levels
1020 flevel
= nfp
->flevel
;
1021 tlevel
= nfp
->tlevel
;
1022 lnlist
= nfp
->lnlist
;
1024 strncpy(ptr
, nfp
->lstptr
->text
, len
);
1026 nfp
->lstptr
= nfp
->lstptr
->next
;
1028 * Macro String Processing
1043 * Return Macro String
1048 /*)Function VOID macroscn(nfp)
1050 * struct macrofp * nfp a Macro 'FILE Handle'
1052 * The function mcroscn() scans the macro text line
1053 * for a valid substitutable string. The only valid targets
1054 * for substitution strings are strings beginning with a
1055 * LETTER and containing any combination of DIGITS and LETTERS.
1056 * If a valid target is found then the function macrosub() is
1057 * called to search the macro definition argument list.
1060 * int c temporary character value
1061 * char id[] a string of maximum length NINPUT
1064 * char ctype[] a character array which defines the
1065 * type of character being processed.
1066 * The index is the character
1070 * int endline() aslex.c
1071 * int getid() aslex.c
1072 * int macrosub() asmcro.c
1073 * int unget() aslex.c
1076 * The assembler-source text line may be updated
1077 * and a substitution made for the string id[].
1082 struct macrofp
*nfp
;
1087 while ((c
= endline()) != 0) {
1088 if (ctype
[c
] & DIGIT
) {
1089 while (ctype
[c
] & (LETTER
|DIGIT
)) c
= get();
1092 if (ctype
[c
] & LETTER
) {
1094 if (macrosub(id
, nfp
)) {
1103 /*)Function int macrosub(id, nfp)
1105 * char * id a pointer to the search string
1106 * of maximum length NINPUT
1107 * macrofp *nfp a Macro 'FILE Handle'
1109 * The function macrosub() scans the current macro's argument
1110 * definition list for a match to the string id[]. If a match
1111 * is found then a substitution is made with the corresponding
1112 * expansion argument.
1115 * int arglen definition argument string length
1116 * int indx repeat argument index
1117 * char * p pointer to definition argument string
1118 * struct strlst *arg pointer to macro definition arguments
1119 * struct strlst *xrg pointer to macro expansion arguments
1120 * int xrglen length of xarg
1121 * char xrgstr[] temporary argument string
1124 * char ib[] source text line
1125 * char * ip pointer into the source text line
1126 * int zflag case sensitivity flag
1129 * char * strcat() c_library
1130 * char * strcpy() c_library
1131 * int strlen() c_library
1132 * int symeq() assym.c
1135 * The source text line may be updated with
1136 * a substitution made for the string id[].
1137 * If there is insufficient space to make
1138 * the substitution then macrosub returns
1145 struct macrofp
*nfp
;
1148 char xrgstr
[NINPUT
*2];
1156 * Check for a macro substitution
1158 arg
= nfp
->np
->bgnarg
;
1159 xrg
= nfp
->np
->bgnxrg
;
1160 while (arg
!= NULL
) {
1163 if (nfp
->np
->type
== O_MACRO
) {
1164 if (*p
== '?') { ++p
; }
1166 if (symeq(id
, p
, zflag
)) {
1169 * Substitution string
1171 switch (nfp
->np
->type
) {
1173 while ((--indx
>= 0) && (xrg
!= NULL
)) {
1176 /* Continue into O_MACRO */
1179 strcpy(xrgstr
, xrg
->text
);
1184 xrgstr
[0] = xrg
->text
[indx
];
1194 arglen
= strlen(id
);
1195 xrglen
= strlen(xrgstr
);
1197 * Verify string space is available
1199 if ((strlen(ib
) - arglen
+ xrglen
) > (NINPUT
*2 - 1)) {
1203 * Beginning of Substitutable string
1207 * Remove a leading '.
1210 p
-= *(p
- 1) == '\'' ? 1 : 0;
1214 * Remove a trailing '.
1216 ip
+= *ip
== '\'' ? 1 : 0;
1218 * Append the tail of the original
1219 * string to the new argument string
1220 * and then replace the dummy argument
1221 * and tail with this string.
1226 * Set pointer to first character
1227 * after argument replacement.
1238 /*)Function VOID * mhunk()
1241 * Return a pointer to the allocated space.
1243 * This function based on code by
1245 * jhartman at compuserve dot com
1248 * memlnk *lnk memory link pointer
1251 * int bytes bytes remaining in buffer area
1252 * char * pnext next location in buffer area
1255 * memlnk mcrmem pointer to 1K Byte block being allocated
1256 * int mcrblk 1K Byte block allocations
1257 * memlnk pmcrmem pointer to first 1K Byte block allocated
1260 * VOID * new() assym.c
1263 * Space allocated for object.
1264 * Out of Space terminates assembler.
1268 * To avoid wasting memory headers on small allocations
1269 * allocate a big chunk and parcel it out as required.
1271 * Hunks are linked to allow reuse during each pass
1275 #define MCR_SPC 1024
1278 * MCR_MSK = 1 for a 2 byte boundary
1279 * MCR_MSK = 3 for a 4 byte boundary
1280 * MCR_MSK = 7 for a 8 byte boundary
1285 static char * pnext
;
1294 * 1st Call Initializes Linked Hunks
1296 if (pmcrmem
== NULL
) {
1297 lnk
= (struct memlnk
*) new (sizeof(struct memlnk
));
1298 lnk
->ptr
= (VOID
*) new (MCR_SPC
);
1300 pmcrmem
= mcrmem
= lnk
;
1304 * Start Reuse of Linked Hunks
1306 if (mcrmem
== NULL
) {
1310 * Allocate a New Hunk
1312 if (mcrmem
->next
== NULL
) {
1313 lnk
= (struct memlnk
*) new (sizeof(struct memlnk
));
1314 lnk
->ptr
= (VOID
*) new (MCR_SPC
);
1323 mcrmem
= mcrmem
->next
;
1325 pnext
= (char *) mcrmem
->ptr
;
1331 /*)Function char * mstring(str)
1333 * char * str pointer to string to save
1335 * Allocate space for "str", copy str into new space.
1336 * Return a pointer to the allocated string.
1338 * This function based on code by
1340 * jhartman at compuserve dot com
1343 * int len string length + 1
1344 * int bytes bytes remaining in buffer area
1347 * char * p pointer to head of copied string
1348 * char * pnext next location in buffer area
1354 * VOID * mhunk() asmcro.c
1355 * char * strcpy() c_library
1356 * int strlen() c_library
1359 * Space allocated for string, string copied
1360 * to space. Out of Space terminates assembler.
1371 * What we need, including a null.
1373 len
= strlen(str
) + 1;
1384 * Copy the name and terminating null.
1391 /*)Function char * mstruct(n)
1393 * int n size required
1395 * Allocate n bytes of space.
1396 * Return a pointer to the allocated space.
1397 * Structure boundary is defined by MCR_MSK.
1400 * int bofst calculated boundary offset
1401 * int bytes bytes remaining in buffer area
1404 * char * p pointer to head of copied string
1405 * char * pnext next location in buffer area
1411 * VOID * mhunk() asmcro.c
1415 * Out of Space terminates assembler.
1426 * Memory Boundary Fixup
1428 bofst
= bytes
& MCR_MSK
;
1444 /*)Function VOID mcrinit()
1446 * Initialize Macro Processor Variables
1449 * int bytes bytes remaining in buffer area
1450 * char * pnext next location in buffer area
1453 * struct sym mls Macro local symbol
1454 * int mcrfil macro nesting counter
1455 * int maxmcr maximum macro nesting emcountered
1456 * int mcrline current macro line number
1458 * struct mcrdef *mcrlst link to list of defined macros
1459 * struct mcrdef *mcrp macro being defined
1460 * struct memlnk *mcrmem Macro Memory Allocation Structure
1466 * Prepares values for next assembler pass.