Table of Contents
The MISOSYS Relocating Macro Assembler product is published by: MISOSYS,
Inc., P. O. Box 239, Sterling, Virginia 22170-0239 [703-450-4181]
FIXUP/CMD - Copyright 1985 MISOSYS, Inc., All rights reserved.
MLIB/CMD - Copyright 1983/85 Richard N. Deglin, All rights reserved.
MLINK/CMD - Copyright 1985 MISOSYS, Inc., All rights reserved.
MRAS/CMD - Copyright 1985 MISOSYS, Inc., All rights reserved.
SAID/CMD - Copyright 1984 Karl A. Hessinger, All rights reserved.
SAIDINS/CMD - Copyright 1984 Karl A. Hessinger, All rights reserved.
XREF/CMD - Copyright 1983/84 MISOSYS, Inc., All rights reserved.
LDOS is a trademark of Logical Systems, Inc.
MICROSOFT is a trademark of the Microsoft Corp.
TRSDOS is a trademark of Tandy Corp.
MRAS was designed to provide the maximum in assembly power. As such, it is an
advanced tool which is not recommended for the novice Z-80 assembly language
programmer. This user manual is not a "learning" manual -- it details the use
of MRAS and its companion utilities -- and in no way attempts to teach you how
to program in the Z-80 assembly language. You should have available a standard
reference handbook on the Z-80 code. Many texts are available.
The MISOSYS Relocatable Macro Assembler Development System includes:
Source files commonly used with other assemblers take one of three forms; a
pure ASCII text file, a line-numbered text file, or a line numbered file which
includes a header. MRAS will automatically accept any of the three types for
its input provided all files included in one source stream use the same
convention. On the other hand, headered and numbered source files would be
found unworkable with the SAID text editor. Thus, a utility called FIXUP has
been provided. FIXUP allows you to change from one form to any of the other
forms. FIXUP requires a properly terminated file. Its syntax is:
The Model I/III MRAS Development system works on both the Model I and Model
III under LDOS 5.x, DOSPLUS 3.5, TRSDOS 2.3, and TRSDOS 1.3. It is released on
a 35-track single density data diskette. TRSDOS 1.3 users must use the CONVERT
utility and a two-drive system to transfer the files from the master disk to a
working system disk. Model I TRSDOS 2.3 users need to first modify their
TRSDOS system via a one-byte patch prior to transferring the files from the
master disk to a working system disk (see below). The master disk is readable
by LDOS and DOSPLUS. Model I or III use under a DOS other than LDOS may
require patches to one or more of the supplied programs.
Method (1) directly modifies the system diskette with a patch. To prepare for
this patch, obtain a fresh BACKUP of your TRSDOS 2.3 to use for this
operation. Then enter the following BASIC program and RUN it. After you RUN
the program, re-BOOT your TRSDOS diskette to correct the byte in memory.
If you are using other than 11" form paper, use the LINES parameter to alter
the paging parameters to suit the specifications of your printer. Note that
MRAS does not count characters per line!
The "+" indicator denoting a macro expansion will appear after the stream line
number. The address will be suffixed with a mode indicator which indicates the
current mode of the assembly source. The 16-bit operand will be suffixed with
a mode indicator which indicates the mode of the operand. The symbol table
will include a mode indicator following the value of each symbol. The
indicators are as follows:
The statement line is considered to be freely formatted. That means that there
are no columnar restrictions. Fields are separated by one or more tabs or
spaces. If a tab is used, it makes for neater listings. Tabs are also retained
as tabs and thus will keep source files smaller than using multiple spaces. A
statement line must not exceed 128 characters in length; thus, if a carriage
return is not detected by the 129th character, a "Load file format error" will
be generated.
A label may contain, within character positions 2-15, letters (A-Z), decimal
digits (0-9), or certain special characters: the at sign, "@"; the underline,
"_"; the question mark, "?"; or the dollar sign, "$". The dollar sign "$",
appearing by itself, is reserved for the value of the reference counter of the
current instruction. It cannot be used as a single character symbol.
A symbol appearing by itself in the LABEL field of a line, will be interpreted
as being equated to the current value of the program counter. Thus, the
following two LABEL examples are completely equivalent:
A value in parentheses "()" specifies indirect addressing when used with
registers, or "contents of" otherwise.
Constants are data declarations of fixed value. They are constructed as a
sequence of one or more digits and an optional radix specification character.
The digits must be valid for the radix used. The following table denotes
acceptable constant composition:
Operands may also be constructed as complicated expressions using the
mathematical and logical operators. These are described in the section on
"Expressions".
The pseudo-OPs DM, DEFB, and DEFM can be used in lieu of "DB" and are
completely equivalent.
"DB" string arguments permit two connected single-quotes to indicate a
single-quote value PROVIDED that two or more characters precede the 2-quote
appearance in the string. For example:
The following are valid declaration statements:
The "quantity" must range from 1 to 65535 (a zero value will result in 65536).
The "value" must be less than 256. With this pseudo-OP, you can generate
repetitions of a single constant. For example, say you want to set 100 storage
locations to a zero value during the assembly. Insert the statement,
The expansions of the constant will appear in listings just as they do in the
DB expansion. The expansions may be suppressed from your listings by using the
assembler switch, -NE.
The quantity, "nn", can be a data value or an expression. Note that "DS" does
not define data values. "DS" adds the quantity of storage locations reserved
to the current program counter (PC) to calculate a new PC value. When
generating a CMD object code file, this action will cause the next assembled
byte to create a new load record. When generating a REL object code file, this
action will generate a Set Location Counter special link item.
The statement,
If your source code is being assembled with the "-CI" switch, MRAS
automatically converts all "DS" declarations into equivalent "DC" declarations
using a value equal to zero. The previous two examples would therefore be
translated to the following:
In the expansion of the data word, its least significant byte is located at
the current program reference counter while the most significant byte is
located at the reference counter plus one. The data word can be a numeric
constant, an expression that evaluates to a 16-bit value, or a character
constant of one or two characters. The following examples illustrate various
forms of "DW" data declarations.
It would be unusual for an ORG to follow a COMMON. An ORG cannot follow a
named common. A COMMON will set the specified common relative program counter
to the beginning of the common segment (i.e. to zero relative).
The assembler defaults to CSEG if no other segment pseudo-OP is specified;
however, if MRAS is invoked with the -GC switch, it will default to ASEG.
Labels defined as "DEFL" will be carried as "DEFL" in the EQUate file
generation of the Cross-Reference utility. They will also be notated in the
cross-reference listing by a plus sign, "+", prefix to the label name.
A symbol can also be implicitly declared PUBLIC by appending two colons to
the "name" where the symbol is defined. Thus, the following two methods both
declare the symbol, TRUST, as PUBLIC:
An "EQU" can occur only once for any label. A multiple "EQU" with different
values will result in the MULTIPLY DEFINED SYMBOL error.
If you want to switch off the offsetting operation of LORG, add the statement:
LORG is usable only when generating CMD files directly from the assembler via
the -GC switch. LORG cannot be used when generating REL output.
A program can have more than one "ORG" statement. If multiple "ORGs" are
used, and one or more inadvertantly will cause the overwrite of a previously
assembled module of code, no warning message of any kind will be issued. It is
left up to the programmer, to protect against such events by use of
conditional tests (using conditional pseudo-OPs) and the "ERR" pseudo-OP.
An ORG can follow an ASEG, CSEG, DSEG, or COMMON //; but not a named common.
When ORG follows a relative segment specification, the program counter will be
set relative to the beginning of the segment, an amount equal to the operand
of the ORG. The operand of the ORG must evaluate to an absolute value.
The conditional construct of IF-ELSE-ENDIF may be used. It is coded as:
As mentioned earlier, the IF argument can take one of three forms. The
conditional structures of these are as follows:
If, for instance, you want to ensure that a program does not assemble code
past a particular address, then the ERR pseudo-op could be used in conjunction
with IFGT to force an assembly error as follows:
The "IFEXT name" pseudo-OP will evaluate TRUE if "name" has been declared
EXTRN. "IFNEXT name" will evaluate TRUE if "name" is not declared extern.
"IFABS name" will evaluate TRUE if "name" is defined in an absolute segment
whereas "IFREL name" will evaluate TRUE if "name" is defined in one of the
relative segment types (code, data, common).
The Type III constructs will find greater use when working with source
libraries of code. For instance, if a clause is a routine that is surrounded
with an IFREF-ENDIF conditional, the routine will only be assembled if prior
to the clause, the "name" has been referenced but not yet defined. If "name"
is the entry point symbol to the routine, then the routine will be assembled
if it is needed. Similarly, you may have a library routine that is always to
be placed in your program unless its "name" has already been defined in some
alternate routine. Surrounding it with the IFDEF-ENDIF conditional will
inhibit its assembly if your program has defined that "name".
The COM pseudo-OP will generate a comment block in the object file of the
format X'1F' followed by the string length, followed by the string itself. A
typical use would be to place a non-loading copyright statement in an
executable object code file. For example:
The OPTION pseudo-OP is only processed during the first pass; therefore, you
cannot use it to dynamically switch options ON and OFF during an assembly. It
is used to conveniently set options specific to a source stream to eliminate
the need for their entry on the assembler command line.
"SPACE n" performs line spacing whenever the "SPACE" pseudo-OP is used. When
assembled, "n" is the number of lines to space and is interpreted as modulo
256. The line containing the SPACE pseudo-op is not displayed. This pseudo-op
also will be ignored if it appears between *LIST OFF and *LIST ON.
A sub-title to a heading is permitted with the "SUBTTL" pseudo-OP. The
subtitle string length can be from zero (0) to 80 characters in length. A zero
length indicates that sub-titling is disengaged. The SUBTTL string does not
need to be enclosed in angle brackets; they are optional. SUBTTL also
automatically invokes a PAGE.
Lower case strings can be maintained by the use of single quotes which
surround the angle brackets. You may change the subtitle by using additional
SUBTTL pseudo-OPs throughout the text. Subtitles will appear on the first page
following the SUBTTL pseudo-op. If the SUBTTL text string is null (of zero
length), then subtitling will cease on the subsequent page. A line will also
be skipped between the subtitle and first printed text line on the page. Where
many *GETs are being used, you may want to establish a sub-title for each to
provide a visual indication on the listing.
The TITLE pseudo-OP automatically invokes a page heading and adds the title to
the headings of assembler listings. The title string is limited to 28
characters and only one TITLE is accepted. The angle brackets must be entered
but are not output in the listing - they serve only to delimit your title
string. The title line will include the MRAS version, the date and time
retrieved from the system, your title string, and a page number [page number
is limited to the range <1-255> and will wrap around to zero if more
than 255 pages are printed]. For this reason, if you use a title, it is
advisable to set DATE and TIME prior to executing the assembler. A line will
be skipped between the title and start of printed text (or subtitle if used).
Lower case titles will be maintained by surrounding the angle brackets with
single quotes as in:
"*GETs" can be nested to four (4) levels. That is, a statement can GET a file
which GETs a file which GETs a file file which GETs a file. This assembler
directive is extremely powerful. It can be used to provide the capability of
assembling large programs which are stored on disk in a series of source files
as one assembly stream.
Labels such as $?001 will have the "?" replaced with the current MOD string
value. Thus, a *MOD directive preceding each module will force $?001 labels in
each module to be distinctly named by having the question mark replaced with
the substitution string. The MOD string value cycles from A-Z, then from
AA-AZ, BA-BZ, ..., ZA-ZZ, then from AAA-AAZ, BAA-BAZ, ..., ZZZ.
This will allow for a simulation of "local" labels. Remember, the "?"
substitutions will only be made if *MOD was specified.
MRAS will search the PaDS library and locate a member name that matches up
with a symbol table entry. If that symbol is currently undefined, the member
will be accessed and read just as if it were the target of a *GET. MRAS will
verify that the member just accessed did in fact define the symbol invoking
its access. If a member is accessed and there exists no defined symbol in the
member that has the same name as the member name, MRAS will abort the assembly
and advise of a library error by displaying the message:
Where more than one routine is in a member, each should be surrounded by
IFREF/ENDIF and each should have an entry in the member directory (you must
use the MAP option of PaDS to provide multiple entries to a member). This will
benefit by not having needless routines appear in your object code output. For
example, the following depicts two routines stored as one member.
There are a few ways to deal with routines that are repeated in a program. You
could block copy it from the first appearance to wherever you needed the
routine. Or you could establish the routine as a macro. The first method could
take up more source storage than is desirable. Also, if you decide to change
the routine's algorithm, having many copies in a program can be cumbersome to
update.
The second method mentioned is the use of macros. Consider the following
commonplace sequence of code:
We invoke the statements defined in the macro by specifying the macro name AS
IF IT WERE AN OPCODE. Using the macro invocation method, we can save storage
space and introduce structured techniques to our coding. Notice that we have
used some fictitious names when the STOR macro was defined. These names are
called "dummy" parameters. They serve to provide a means to pass actual
parameters when the macro is invoked. Through the dummy parameters, the real
power of the macro is utilized. During the macro invocation, the model
statements are expanded with substitutions for the dummy parameters that are
provided in the macro call.
When a macro is defined, it is not assembled into your program. The macro
prototype is parsed and analyzed. The macro definition is then stored in a
compressed format within the macro storage area. Comments appearing with the
macro definition are not stored if the comment starts with a double semi-colon
in lieu of a single one. Comments with a single semi-colon are thus carried
through a macro expansion to the listing.
Macro definitions may be nested. The inner macro will not become defined until
the outer macro is expanded during an invocation. However, since macros cannot
be redefined, the outer macro should be invoked only once!
The MACRO pseudo-OP is used to define the prototype of a macro model. Its
syntax is:
Default strings can contain any character except the comma, ",". The comma is
used as a field delimiter. There is no limit to the length of a default string
other than the limiting factor of the statement length.
Macros must be defined prior to use but can be defined in a separate disk file
accessed via a "*GET filespec".
MACRO parameters are acceptable within a quoted string if prefixed by an
ampersand. i.e. TEST DB 'NAME'. See the following example.
Macro definitions also may be nested. The inner macro will not be
defined until the outer macro is expanded. For instance:
If macro A "calls" another macro, say B, any dummy parameter in the macro call
of B that matches a dummy in macro A, will be considered part of macro A and
the parameter substitution will be invoked by the parameter passed when the
user calls macro A.
During the expansion, the "actual" parameters passed in the call statement are
substituted for the "dummy" parameters which appear in the macro model and
which are designated in the prototype of the macro. Note that the actual
parameter values are character strings and can be labels, expressions, or data
constants. An actual parameter can even be a quoted string data declaration if
its use is designed into the macro model.
The entire expanded macro model is listed during the listing pass (phase two).
Macro expansions in the listing will be so noted by the appendage of a plus
sign immediately following the line number displayed. You may find that you
don't really want to see these expansions since the macro definition contains
the entire illustration of the macro. An assembler switch, "-NM" is provided
to suppress listing of macro expansions. In the case of nested macro calls
(i.e. a macro is defined which calls another macro which was separately
defined), only the primary macro call will be listed if the "suppress" switch
is invoked.
The substitution of the actual character string parameters for the dummys
occurs during the macro expansion when the macro is called. Since a macro can
have more than one parameter, it is necessary to have a procedure that
specifies which actual parameter corresponds to each dummy parameter. There
are two methods supported in MRAS. Parameters can be passed to the macro
expansion when calling by either position or keyword.
If you wish to omit an actual parameter in a macro call, then you must supply
the comma to denote its place. For instance:
Note that the parameter list contains five parameters. Thus if you were to use
the "%%" operator which returns the number of parameters passed in a macro
caImportant Note
Certain documentation pertaining to this package may be available after the
user manual has gone to press. Consult the file entitled README/TXT for
details on additional support material and errata. General Information
The MISOSYS Relocating Macro Assembler (MRAS) is a disk assembler which
generates a relocatable (REL) module from one or more source files. The REL
module generated by MRAS is a bit-stream compatible with Microsoft (TM) M-80
generated files. Multiple REL modules are then linked via the MISOSYS linker
(MLINK) to produce an executable object code file (CMD). The assembler is also
capable of directly generating a CMD file when the source file(s) contain no
references to relocatable segments. Source files may be created and edited
with the full screen text editor (SAID) provided. Libraries of relocatable
modules are organized with the librarian (MLIB).
FIXUP/CMD - a utility to convert from/to line-numbered source files
MLIB/CMD - a relocatable module librarian
MLINK/CMD - a relocatable module linker
MRAS/CMD - a macro assembler generating relocatable modules
OVERLAY/REL - a module which supports overlay handling
README/TXT - a LISTable text file containing errata
SAID/CMD - a full-screen text editor for source code preparation
SAIDINS/CMD - SAID installation program
XREF/CMD - a symbol cross-reference listing generator
All source text to MRAS must have a Control-Z (1AH) as the last character of
the text. This byte must immediately follow a CARRIAGE RETURN (0DH). If you
are using an editor other than SAID to prepare your source text, and that
editor does not terminate the text file with a CONTROL-Z, you may have
difficulty in using the file with the assembler. If such is the case, load the
file into SAID using the ASM parameter and resave it (after ensuring that the
last character in the file is a carriage return).
FIXUP filespec {(*/strip/header/number}
where the parameter "strip" is used to eliminate headers and line numbers,
"number" is used to add line numbers, and header is used to add both a header
and line numbers. The '*' is used to rewrite the file left in the FIXUP
buffer. FIXUP defaults to "strip"; reads its input from and writes its output
to the file identified as "filespec". Distribution Disks
The TRSDOS 6.x MRAS Development System is distributed on a 40-track double
density data diskette. Model I TRSDOS 2.3 Patch
Model I TRSDOS users will find difficulty in reading the distribution disk due
to the data address mark used for the directory. Therefore, before making a
BACKUP or copying MRAS files from the diskette, you will need to change one
byte of the TRSDOS 2.3 disk driver using either of the following two methods.
This change should not affect the operation of your TRSDOS.
10 OPEN"R",1,"SYS0/SYS.WKIA:0"
20 FIELD 1,171 AS R1$, 1 AS RS$, 84 AS R2$
30 GET 1,3: LSET RS$="<": PUT 1,3: CLOSE: END
Method (2) uses a POKE from BASIC to change the value directly in memory. This
procedure is as follows:
1. Enter BASIC (files = 0, protect no memory)
2. Type POKE &H46B0,60 followed by <ENTER> .
3. Type CMD"S followed by <ENTER> .
Now, after using either method noted above, COPY the MRAS files from the
master diskette to your TRSDOS system diskette. Invoking MRAS
MRAS is a macro assembler used to assemble a source disk file(s) into a
relocatable object code module. MRAS provides a command line rich in features.
The syntax:
________________________________________________________________
| |
| MRAS source/ASM {+L=listing/PRN +O=object/CMD +X=reference/REF |
| +S=symbol/SYM +I=include/ASM } {assembler switches} |
| {(p1=value1,p2=value2,p3=value3,p4=value4,LINES=n)} |
| |
| +L=listing/PRN - send listing to spec in lieu of *DO. |
| +L=:d Use -LP for printer (or +L=*PR if DOS |
| supported). Will inhibit -NL and -LP. |
| |
| +O=object/REL - send object to spec in lieu of "source/REL".|
| +O=:d Will inhibit -NO. |
| |
| +X=reference/REF - send cross reference data to spec in lieu |
| +X=:d of "source/REF" if -XR switch invoked. |
| Will invoke -XR. |
| |
| +S=symbol/SYM - send symbol table to spec in lieu of *DO or |
| +S=:d *PR depending on setting of -WS and -LP |
| switches. Will invoke -WS. |
| |
| +I=include/ASM - use spec for "*INCLUDE" assembler directive |
| which is similar to "*GET". |
| |
| Switches: -CI -FE -GC -LP -MF -NC -NE -NH |
| -NL -NM -NO -SL -WE -WS -XR (see text) |
| |
| Parms: |
| Pn - Set internal symbols (see text) |
| Lines=n - set printed lines per page to n (abbrev=L). |
| |
| Note: Default file extensions are shown capitalized in the |
| file option filespecs. |
|________________________________________________________________|
File options
File options are denoted with a plus sign prefix and are used to redirect one
or more output streams of the assembler. They can accept a syntax of
"+s=filename:d" or "+s=:d". The "s" refers to any of the file switches: O, I,
L, S, X. The latter will re-use the source filename for the file being
switched and the extension appropriate for the switch. File switches must
precede the assembler switches. Assembler switches
These switches control various aspects of the assembler. They are always
prefixed with a minus sign.
Switch -CI
The "-CI" switch is used to generate a "core-image" object code file.
Executable command files in the DOS are constructed with address information
that the system loader uses when loading and executing your command file.
Also, a header record is usually found in a load module object code file. When
the "-CI" switch is specified, a number of changes take place in MRAS. First,
the object code file default extension is changed to "/CIM". Next, the header
record and the transfer address record are suppressed. Any COM pseudo-OP
statement is, likewise, suppressed. A core-image file needs to contain
contiguous address sequential code. Since MRAS reserves only storage locations
when assembling the DS/DEFS pseudo-OPs, DS instructions will automatically be
converted to their corresponding "DC" statements with a zero value for
operand2. The "-GC" switch will also be turned on.
Switch -FE
The normal operation of MRAS will suppress the output of linkage data for
symbols declared EXTRN but never referenced within the source code stream.
This switch forces chain external linkage data to be generated for external
symbols declared via EXTRN where no reference is made in the module. This can
be used to force a loading of the extrn'd module from a library even though no
other reference is made in the module with the EXTRN. Its use is generally
associated with the inclusion of desired library modules into the ROOT segment
of an overlayed program. If -FE is not specified, any symbol listed in the
argument of the EXTRN statement which has no other reference in the module
will not generate a "chain external" and will not be searched for in a library
search.
Switch -GC
This switch tells the assembler to directly output a CMD file. The normal
object file output is a relocatable module (/REL). Do not specify this switch
if your source contains any CSEGs, DSEGs, or COMMONs. The -GC switch is
automatically turned on by switch -CI. The assembler will default to ASEG if
this switch is specified.
Switch -LP
The -LP switch is used to send the assembler listing, error messages occurring
during the assembly of your source code, and the symbol table listing (if
specified by means of the "-WS" switch) to a line printer. MRAS assembler
listings print 56 lines per page and send a form feed at the conclusion of the
56 lines. If you are generating a listing output and a
properly paged display is desired, it is suggested that you set your paper to
begin printing at the sixth line from the top of the page (which assumes
paging parameters set at 56 print lines and 66 lines page length -- the
default). This will provide five blank lines for a top margin, and five blank
lines for a bottom margin. Switch -MF
The assembler normally searches the OP code table prior to the macro table. If
you want to redefine the code generation of Z-80 OP code mnemonics, you can
specify the -MF switch. It causes the assembler to search the macro table
before the OP code table. Switch -NC
Conditional assembly (see the section on ASSEMBLER PSEUDO-OPS) can greatly
ease the maintenance of programs designed to work with multiple configurations
of hardware. However, it is unnecessary to "see" the source statements within
conditional clauses that are logically "false". This -NC switch is provided to
have no "false" conditionals appear in your listings. If a conditional is
suppressed, neither the "IF" statement nor the "ENDIF" statement of the
"false" clause will be listed.
Switch -NE
Various data declaration pseudo-OPs create a structured format for the listing
of code generated after the first byte of the statement. These are the
DB/DEFB, DM/DEFM, DW/DEFW, and the DC pseudo-OP statements. If you want to
inhibit the expansion from the listing only (the code will still be expanded
for assembly of object code), then specify the "no expansion", -NE, switch.
Switch -NH
Object code files usually start off with a header record of X'05 06 xx xx xx
xx xx xx'. The x's would be replaced with the first six characters of the
object code filename (buffered with spaces). MRAS automatically generates this
record when writing an object code CMD file. The DOS loader has no problem
with this record. If you would like your object code files to contain this
record, then do absolutely nothing. If you do not want to have this header
record generated, then specify the "no header", -NH, switch.
Switch -NL
The second phase of the assembly process generates the assembler listing. If
you do not want to see a listing, then you may enter the "no listing", -NL,
switch. This will completely suppress phase two and shift the assembler to
phase three. If you are interested in listing statements containing errors,
then you must not suppress the second phase. Note that the lines containing
only assembly errors can be listed by specifying the "*LIST OFF" assembler
directive. See the section on "ASSEMBLER DIRECTIVES" for further details.
The cross-reference data file is written during phase two. In order to
guarantee that the second phase is available, a cross-reference specification
will automatically override any entry of the -NL switch.
Switch -NM
The macro model code is repeated whenever you invoke the macro. Once you
become familiar with what the macro does, you really don't need to see its
expansion in your listings every time the macro is invoked. Switch -NM has
been provided to inhibit the listing of such expansions. If you specify no
macro expansions, only the statements invoking the macros will be listed --
the listing of the expansions will be inhibited. In the case of a nested macro
invocation, only the highest level macro call will be listed.
Switch -NO
MRAS will generate an object code output file unless you tell it to suppress
this generation via the -NO switch.
Switch -SL
If you specify -SL, then any label starting with a dollar sign, "$", will be
suppressed from the symbol table listing and from any cross-reference data
file. Therefore, by using a "$" as the first character of local labels and
specifying -SL will result in keeping your symbol table listings uncluttered
with local labels.
Switch -WE
In a long assembly, you may want the assembler to pause the listing if it
detects an assembly error (you're bound to get some of them). The "wait on
error" switch, -WE, is available for that purpose. If specified, each time the
assembler comes to an error during phase two, it will pause the listing. Any
character entered from the keyboard will continue the assembly and listing. If
you choose to enter the character "C" or "c", then the phase two process will
continue without further interruption - even though additional errors may be
detected. The listing may also be paused at any time by depressing the
<SHIFT-@> key, momentarily.
Switch -WS
A complete symbol table cross-reference listing of a single assembly stream
is available via the -XR switch and subsequent processing by the XREF/CMD
program. An abbreviated printout that contains only a sorted listing of
symbols and their value is available at assembly time by invoking the -WS
switch. The symbol table listing would normally be displayed on the video
display. If the -LP switch was specified, the listing would be directed to the
Line Printer. The symbol table can also be invoked via the "+S=filespec" file
option.
Switch -XR
This is the switch option to use if you want to generate a complete symbolic
cross reference listing of the assembly stream. Switch -XR will invoke the
generation of a reference data file used by the XREF/CMD utility (see the
chapter on CROSS REFERENCE UTILITY). The reference data file is generated
during the listing pass (phase two). If the XREF filespec is entered via
"+X=filespec", this switch is assumed to have been entered. If the XREF
filespec is not entered via "+X=", the filespec of the reference file will be
generated from the source filename.
Parameters: Pn=val
This parameter provides the power of entering symbol table equates directly
from the MRAS command line. "Pn" is actually four parameters as "n" can range
from <1-4>. Thus, you specify the parameter as either P1, P2, P3, or
P4. These parameters are entered in MRAS as absolute DEFL values added to the
symbol table. By passing parameter values with these on the MRAS command line,
you can alter four symbol table entries. Thus, you can use these to control
EQUate options, pass values to symbols, etc. The format usable is dependent on
that supported by your DOS and may include:
_____________________________________________________________
| |
| Pn sets @@n to TRUE. |
| |
| Pn=ddd sets @@n to decimal value ddd. |
| |
| Pn=X'hhhh' sets @@n to hexadecimal value hhhh. |
|_____________________________________________________________|
The actual labels added to the symbol table as DEFLs are "@@n", where "n" is
the same as the "n" of "Pn". This is depicted as follows:
_____________________________________________________________
| |
| P1 == @@1 P2 == @@2 P3 == @@3 P4 == @@4 |
|_____________________________________________________________|
The four symbols initially have a value of zero (logical FALSE). You can use
these to externally set flags for use in conditional assembly. For example,
say you have a program that uses two conditional symbols, MOD1 and MOD3. If
your program has the statements:
MOD1 EQU @@1
MOD3 EQU @@3
then an MRAS command line including (P1) will set "@@1" to
TRUE, "@@3" was defaulted to FALSE, and thus "MOD1" would be TRUE and "MOD3"
would be FALSE since the two conditional symbols you are using are equated to
the "@@n" parameters.
Assembler listing
During the first pass, the name of each file included or searched will be
displayed as an informative message. During the listing pass, MRAS keeps track
of each statement's logical line number within its source file and the logical
line number of the assembly output stream. Stream line numbers are output in a
sequential order incremented by one for each line of logical output. Lines
suppressed from display use up one line number for each line omitted [i.e.
from *LIST OFF to *LIST ON; -NC statements; -NM statements]. Lines containing
errors will be prefixed with the name of the file containing the line, the
line number within the file, and the error message. The statement itself will
display the stream line number.
blank - absolute
' - code relative
" - data relative
! - common relative
C - named common
* - extern symbol
At the conclusion of the listing pass, the free space remaining in the buffer
pool will be displayed as, "ddddd Free space". This can be used as an
indicator of how dangerously huge your program is getting.
Error totals
At the conclusion of pass three, the total number of errors will be listed. An
"Unclosed conditional" error is also included in the ERROR TOTALS count. This
error total will be displayed after the conclusion of phase two if object code
is not generated. If you place a "*LIST OFF" pseudo-OP at the beginning of
your code, lines containing errors will be listed.
Syntax
The basic format of an assembly language statement consists of up to four
fields of information. These fields, in order, are:
_____________________________________________________________
| |
| {LABEL} {OPCODE} {OPERAND{S}} {;COMMENT} |
| |
| LABEL is a symbolic name assigned the address value |
| of the first byte of the object instruction. |
| |
| OPCODE is the mnemonic of a specific Z-80 assembler |
| instruction or pseudo-OPeration code. |
| |
| OPERANDS are arguments of the OPCODE. |
| |
| ;COMMENT is an informative notation that is ignored by |
| the assembler but aids in documenting the |
| source code. |
| |
| Note: Fields are separated by a tab or spaces. |
|_____________________________________________________________|
As can be noted from the format box, none of the fields are required; however,
each line should contain at least one field. If you want the comment field to
occupy the entire line, start the line with a semi-colon in the first
character position of the line - then, no other field is needed. A symbolic
label can exist by itself on a line. There are some Z-80 operation codes that
have no arguments; thus, an OPCODE could exist by itself on a line (in field
2). You will never have an argument by itself as an argument relates to an
OPCODE. Symbolic names
A label is a symbolic name of a line of code. Labels are always optional. A
label is a string of characters of any length; however, only the first 15
characters will be significant. A symbol is defined as:
name{{:}:} Defines "name"
A terminating single colon is optional. A double colon defines "name" as
PUBLIC. If "name" is used as a reference suffixed with "##", then "name" is
declared extern. Labels designated as PUBLIC or EXTRN which exceed seven
characters in length will be automatically truncated to seven during the
generation of the /REL file without warning. If two or more labels with
identical first seven characters are so truncated, the linker will flag a
multiple definition error. The first character must be a letter (A-Z) or one
of the special characters: the underline, "_"; the dollar sign, "$"; or the at
sign, "@". It is recommended that you reserve use of "$" as the first
character of "local" labels since they can be suppressed from a symbol table
output via the "-SL" assemble switch
ALLALONE
ALLALONE EQU $
Certain labels are reserved by the assembler for use in referring to
registers. Others are reserved for branching conditions (condition codes) and
may not be used for labels. (these conditions apply to status flags). The
following labels are reserved and may not be used for other purposes:
_____________________________________________________________
| Reserved Labels |
| |
| A, B, C, D, E, H, L, I, R, |
| IX, IY, SP, AF, BC, DE, HL, ON |
| C, NC, Z, NZ, M, P, PE, PO, OFF |
|_____________________________________________________________|
Examples of labels:
ENTRY @OPEN BUFFER$ BYTE_POINTER WHAT?
SELECT_CODE $$CORE @ CARRIAGE_RETURN @EXIT
A special symbol is "$MEMRY". If this symbol name is declared PUBLIC, the
linker will store the address of the first available memory location which
follows your program into the word defined as "$MEMRY". Thus, if you choose to
use this capability, $MEMRY must be defined via a DW statement. or equivalent.
Opcodes
The OPCODES for the MRAS assembler correspond to those in the "Z-80-Assembly
Language Programming Manual", 3.0 D.S., REL 2.1, FEB 1977.
Operands
Operands are always one or two values separated by commas. Some instructions
may have no operands at all.
_____________________________________________________________
| |
| Data Type Radix Char Digits Examples |
| ----------- --------- -------- -------------------- |
| hexadecimal H <0-9,A-F> 1AH, 0ABH, 0FFH |
| |
| decimal D <0-9> 107D, 107, 15384 |
| |
| octal O or Q <0-7> 166Q, 166O |
| |
| binary B <0-1> 01101110B |
| |
| Note: Decimal is assumed if the radix character is omitted |
| unless *RADIX is used to change the default radix. |
|_____________________________________________________________|
A constant not followed by one of the radix characters is assumed to be
decimal. This assumption can be changed via the *RADIX assembler directive. A
constant must begin with a decimal digit. Thus "FFH" is not permitted, while
"0FFH" is valid. Comments
All comments must begin with a semicolon ";". If a source statement line
starts with a semicolon in the first character position of the line, the
entire line is a comment.
Expressions
A value of an operand may be an expression consisting of multiple terms
(labels and data constants) connected with mathematical operators. These
expressions are evaluated in strictly LEFT to RIGHT order. No parentheses are
allowed. MRAS does not support operator precedence. Most operators are binary,
which means that they require two arguments. Both "+" and "-" have unary uses
also. The following operators are supported:
_____________________________________________________________
| |
| Operator Function Example |
| |
| + Addition value1 + value2 |
| - Subtraction value1 - value2 |
| * Multiplication value1 * value2 |
| / Division value1 / value2 |
| .MOD. Modulo Division value1 .MOD. value2 |
| < Shift Left or Right value1 < -value2 |
| .AND. or & Logical Bitwise AND value1 .AND. value2 |
| .OR. or ! Logical Bitwise OR value1 .OR. value2 |
| .XOR. Logical Exclusive OR value1 .XOR. value2 |
| .NOT. Logical 1's Complement FALSE EQU .NOT. TRUE |
| .NE. Logical Binary Not Equal value1 .NE. value2 |
| .EQ. Logical Binary Equal value1 .EQ. value2 |
| .GE. greater than or equal to value1.GE.value2 |
| .GT. greater than value1.GT.value2 |
| .LE. less than or equal to value1.LE.value2 |
| .LT. less than value1.LT.value2 |
| .SHL. shift value1 left value1.SHL.value2 |
| .SHR. shift value1 right value1.SHR.value2 |
| .HIGH. obtain high order byte .HIGH.value |
| .LOW. obtain low order byte .LOW.value |
| % Length of MACRO %#LABEL or %% |
| %& MACRO label concatenation #NAME%&L |
|_____________________________________________________________|
Addition (+)
The addition operator will add two constants and/or symbolic values. When used
as a unary operator, it simply echoes the value.
001E CON30 EQU 30
0010 CON16 EQU +10H
0003 CON3 EQU 3
002E A2 EQU CON30+CON16
Subtraction (-)
The minus operator will subtract two constants and/or symbolic values. Unary
minus produces a 2's complement.
000E A2 EQU CON30-CON16
FFF2 A4 EQU -A2
Multiplication (*)
The multiplication operator will perform an integer multiplication of a 16-bit
multiplicand by a 16-bit multiplier. Overflow of the resulting 16-bit value is
not flagged as an error.
01E0 A5 EQU CON30*CON16
BF20 A6 EQU 60000*3 ;this overflows
Division (/)
The division operator will perform an integer division of a 16-bit dividend by
a 16-bit divisor.
0002 A7 EQU 5/2
1B4D A8 EQU 48928/7
Modulo (.MOD.)
The modulo operator calculates the remainder of the above integer division.
0001 A9 EQU 5.MOD.2
0005 A10 EQU 48928.MOD.7
Shift (<)
This operator can be used to shift a value left or right. The form is:
____________________________________________________________
| |
| VALUE < {-}AMOUNT |
|____________________________________________________________|
If AMOUNT is positive, VALUE is shifted left. If AMOUNT is negative, VALUE is
shifted right. The magnitude of the shift is determined from the numeric value
of AMOUNT.
0057 HIORD EQU 5739H<-8
C000 A1 EQU 3C00H<4
03C0 A2 EQU 3C00H<-4
BBFF A3 EQU 3CBBH<8+255
03C0 A3 EQU 15+3C00H<-4
Logical AND (.AND. or &)
The logical AND operator bitwise ANDS two constants and/or symbolic values.
Each bit position of the 16-bit resultant value is a "1" only if both
arguments have a "1" in the corresponding position, or a "0" if either
argument has a "0".
3C00 A1 EQU 3C00H&0FFH
0000 A2 EQU 0&15
0000 A3 EQU 0AAAAH.AND.5555H
Logical OR (.OR. or !)
The logical OR operator bitwise "ORS" two constants and/or symbolic values.
Each bit position of the 16-bit resultant value is a "1" if either argument
has a "1" in the corresponding position, or a "0" if neither argument has a
"1".
3CFF A1 EQU 3C00H!0FFH
000F A2 EQU 0.OR.15
FFFF A3 EQU 0AAAAH.OR.5555H
Logical XOR (.XOR.)
The logical XOR operator performs a bitwise exclusive OR on two constants
and/or symbolic values. Each bit position of the 16-bit resultant value is a
"1" only if both arguments have reversed bits in the corresponding position
(i.e. one must have a "1" while the other must have a "0"). The XOR operation
is considered a modulo two addition.
3CF8 A1 EQU 3C07H.XOR.0FFH
0007 A2 EQU 8.XOR.15
FFFF A3 EQU 0AAAAH.XOR.5555H
Logical NOT (.NOT.)
This is a unary operator. It performs a one's complement on the term it
precedes. Observe the following examples:
FFFE T1 EQU .NOT.1
FFFF T2 EQU .NOT.0
0000 T3 EQU .NOT.-1
Logical NOT-EQUAL (.NE.)
This operator is a binary operator that compares two adjacent terms. The
resultant value is TRUE if the terms are not equal. A FALSE result is returned
if the two terms are equal. Observe the following examples:
0000 T1 EQU 1000.NE.1000
FFFF T2 EQU 1000.NE.10
FFFF T3 EQU 1.NE.-1
0000 T4 EQU .NOT.0.NE.-1
Logical EQUAL (.EQ.)
This operator is a binary operator that compares two adjacent terms. The
resultant value is TRUE if the terms are equal. A FALSE result is returned if
the two terms are not equal. Observe the following examples:
FFFF T1 EQU 1000.EQ.1000
0000 T2 EQU 1000.EQ.10
0000 T3 EQU 1.EQ.-1
FFFF T4 EQU .NOT.0.EQ.-1
Logical GREATER-THAN-OR-EQUAL-TO (.GE.)
This is a binary operator that compares two adjacent terms. The resultant
value is TRUE if the left term is equal to or larger then the right term.
0000 T1 EQU 1.GE.2
FFFF T2 EQU 2.GE.2
Logical GREATER-THAN (.GT.)
This is a binary operator that compares two adjacent terms. The resultant
value is TRUE if the left term is larger than the right term.
0000 T1 EQU 1.GT.2
0000 T2 EQU 2.GT.2
Logical LESS-THAN-OR-EQUAL-TO (.LE.)
This is a binary operator that compares two adjacent terms. The resultant
value is TRUE if the left term is smaller than or equal to the right term.
FFFF T1 EQU 1.LE.2
FFFF T2 EQU 2.LE.2
Logical LESS-THAN (.LT.)
This is a binary operator that compares two adjacent terms. The resultant
value is TRUE if the left term is smaller than the right term.
FFFF T1 EQU 1.LT.2
0000 T2 EQU 2.LT.2
Logical SHIFT LEFT (.SHL.)
This is a binary operator that shifts the left term a number of bits left
according to the right term. It is the same as "value1<value2".
2340 T1 EQU 1234H.SHL.4
Logical SHIFT RIGHT (.SHR.)
This is a binary operator that shifts the left term a number of bits right
according to the right term. It is the same as "value1<-value2".
0123 T1 EQU 1234H.SHR.4
Obtain HIGH-ORDER byte (.HIGH.)
This is a unary operator that provides a low-order result which is equal to
the high order value. It is the same as "value.SHR.8".
0012 T1 EQU .HIGH.1234H
Obtain LOW-ORDER byte (.LOW.)
This is a unary operator that provides a low-order result which is equal to
the low order value. It is the same as "value.AND.0FFH".
0034 T1 EQU .LOW.1234H
Macro Length Operator (%)
The length operator is applicable only with MACRO usage. Therefore, its use
will be discussed in the section on MACRO PROCESSING.
Evaluation of expressions - limitations of mode/class
Symbols have both a mode and a class. The modes are absolute, code relative,
data relative, and common relative (which is common specific, i.e. coupled to
common relative is the specific common which the symbol is a part of). The
class is either extern or not extern. The following rules apply to all
expressions:
A. Addition:
1. One term must be absolute.
2. The resulting mode is: absolute + <mode> = <mode>
3. Either term may be extern but not both.
4. If one term is of class extern, the other must be absolute.
B. Subtraction:
1. <mode> - absolute = <mode>
2. <mode> - <mode> = absolute; both modes must be the same.
3. <extern> - absolute = extern; the result is extern
4. The second term cannot be of class extern.
C. All other binary operators require absolute terms. All unary
operators except unary minus require an absolute term. Unary
minus follows the rules of subtraction with the left term assumed
to be absolute.
Additionally, all expressions which resolve to a byte value (in contrast to
16-bit word value) must resolve to absolute mode, class not-extern. Pseudo-OPs
There are many pseudo-OPs which MRAS will recognize. These assembler
operations, although written much like processor instructions, interface to
the assembler instead of the Z-80 processor. They direct the assembler to
perform specific tasks during the assembly process but have no meaning to the
Z-80 processor. Some of these pseudo-OPs generate data values used by your
program and are called "data declaration" pseudo-OPs. Others control paging
operations and may be best termed, "listing" pseudo-OPs. A broad range of
operations to invoke the assembly of code clauses based on conditional
evaluations are supported through many "conditional" pseudo-OPs. These
assembler pseudo-OPs are:
________________________________________________________________
| Constant Declarations |
| |
| DATE Assembles system date as 8-character string, MM/DD/YY. |
| |
| DB Specifies a data byte or string of bytes. Also |
| equivalent to DEFB, DEFM, and DM. |
| |
| DC Specifies a multiple of byte constants. |
| |
| DS Reserves a region of storage for program use. |
| Equivalent to DEFS. |
| |
| DSYM Assembles "label" as an n-character string. (Similar |
| to the construct, DB 'label', in a macro. |
| |
| DW Specifies a word (16-bit data value) or a sequence of |
| words. Also equivalent to DEFW. |
| |
| DX Assembles "expression" as a 4-hexadecimal digit string.|
| |
| TIME Assembles system time as 8-character string, HH:MM:SS. |
|________________________________________________________________|
________________________________________________________________
| Origins and Values |
| |
| ASEG Sets the program counter to the absolute segment |
| |
| COMMON Sets the program counter to a common relative segment. |
| |
| CSEG Sets the program counter to the code relative segment. |
| This is the default mode of the assembler. |
| |
| DEFL Establishes a value for a label which can be altered |
| during the assembly. |
| |
| DSEG Sets the program counter to the data relative segment. |
| |
| END Signifies the end of a *GET, *INCLUDE, or *SEARCH |
| member. Supplies the execution transfer address. |
| |
| ENTRY Synonomous with GLOBAL. |
| |
| EQU Estalishes a constant value for a label. |
| |
| EXT Synonomous with EXTRN. |
| |
| EXTRN Specifies the symbols in the name list as external. |
| |
| GLOBAL Specifies the symbols in the name list as entries. |
| |
| LORG Establishes a load origin for executable object code |
| files. LORG is unusable for /REL output. |
| |
| NAME Specifies the module's name for the /REL file. This |
| defaults to the object code filename. |
| |
| ORG Establishes an origin for executable object code files |
| or relative code segments. |
| |
| PUBLIC Synonomous with GLOBAL. |
| |
| Note: An ORG can follow ASEG, CSEG, DSEG, or COMMON //; but |
| not a named common. A maximum of seven named commons |
| are permitted in one module. The "name" of a common |
| cannot be the same as any symbol. |
|________________________________________________________________|
________________________________________________________________
| Conditionals |
| |
| ELSE Alternate clause to be assembled if the prior clause |
| has evaluated FALSE. |
| |
| ENDIF Signifies the end of a conditional block. |
| |
| IF Conditional evaluation of expression. |
| |
| IF1 Logically TRUE if the assembler is on the first pass. |
| |
| IF2 Logically TRUE if the assembler is on the second pass. |
| |
| IF3 Logically TRUE if the assembler is on the third pass. |
| |
| IFABS Logically TRUE if "name" is absolute. |
| |
| IFDEF Logically TRUE if "name" has been defined prior to |
| this statement or if "name" is extern, else FALSE. |
| |
| IFEQ Logically TRUE if expression1 = expression2. |
| |
| IFEQ$ Logically TRUE if string1 = string2. |
| |
| IFEXT Logically TRUE if "name" is extern. |
| |
| IFLT Logically TRUE if expression1 < expression2. |
| |
| IFLT$ Logically TRUE if string1 < string2. |
| |
| IFGT Logically TRUE if expression1 > expression2. |
| |
| IFGT$ Logically TRUE if string1 > string2. |
| |
| IFNDEF Logically TRUE if "name" has not been defined prior to |
| the statement or if "name" is not extern, else FALSE. |
| |
| IFNEXT Logically TRUE if "name" is not extern. |
| |
| IFNE Logically TRUE if expression1 <> expression2. |
| |
| IFNE$ Logically TRUE if string1 <> string2. |
| |
| IFREF Logically TRUE if "label" has been referenced but not |
| defined prior to the statement, else FALSE. |
| |
| IFREL Logically TRUE if "name" is relative. |
| |
| Note: "IFxx$" denotes alternate macro string comparison. |
|________________________________________________________________|
________________________________________________________________
| Miscellaneous |
| |
| COM Generates a CMD object code file comment record. |
| |
| ENDM Designates the end of a MACRO model. [**] |
| |
| ERR Forces an assembly error. |
| |
| EXITM Can be used to prematurely exit from a MACRO expansion.|
| This is normally used within a conditional. [**] |
| |
| IRP The statements within IRP-ENDM are repeated for as |
| many items are in the argument list with "dummy" being |
| replaced by each argument in turn. [**] |
| |
| IRPC The statements within IRPC-ENDM are repeated for each |
| character in the character-list while the "identifier" |
| is replaced, in turn, from the identifier list. [**] |
| |
| MACRO Designates the prototype of a MACRO model. [**] |
| |
| OPTION This permits the altering of any of the permissable |
| assembler switches from within the source code during |
| the first pass of the assembler. |
| |
| PAGE Outputs a form feed during a listing. |
| |
| REF Forces a reference to the symbols identified in the |
| argument list. |
| |
| REPT The statements within REPT-ENDM are repeated according |
| to the result of "expression". [**] |
| |
| SPACE Generates extra line feeds during a listing. |
| |
| SUBTTL Invokes a heading sub-title for listings. |
| |
| TITLE Invokes a heading title for listings. |
| |
| [**] Details are in the section on USING MACROS |
|________________________________________________________________|
Pseudo-OP DB
The "DB" pseudo-OP is used to define a data byte or series of bytes. Its
syntax is:
_____________________________________________________________
| |
| DB n{,n}{,'c'}{,s}{,expression} |
| |
| n defines the contents of a byte at the current |
| reference counter to be "n". |
| |
| 'c' defines the content of one byte of memory to |
| be the ASCII representation of character "c". |
| |
| 's' defines the contents of n bytes of memory to |
| be the ASCII representation of string "s", |
| where "n" is the length of "s". |
| |
| expression is a mathematical expression which evaluates |
| to a number in the range <0-255>. |
|_____________________________________________________________|
The constant declaration "DB" permits the concatenation of its data arguments
using the comma "," as an argument separator. Data values are denoted
according to the specifications in the section on ASSEMBLY LANGUAGE
INFORMATION.
DB 'AB''C'
will produce the character string: 41 42 27 43. This may have been coded as a
complex declaration such as, "'AB',27H,'C'", but the extensive declaration
support in MRAS provides the easier specification.
DB 1,2,'buckle your shoe',3,4,'close the door'
DB 'This is a tes','t'!80H,CR
The hexadecimal expansions of the constant will appear in listings as rows of
eight bytes per row. The expansions may be suppressed from your listings by
using the assembler switch, -NE.
Pseudo-OP DC
This pseudo-OP defines a repetitive constant. Its syntax is:
_____________________________________________________________
| |
| DC quantity,value |
| |
| quantity specifies how many times that "value" is to be |
| repeated as a data byte. It can be defined as |
| any other data definition: n, expression, 'c'. |
| |
| value is the constant to be repeated. As in a "DB" |
| data declaration, the value can be specified |
| as a character, 'c', a numeric value, n, or an |
| expression evaluated to a number in the |
| range <0-255>. |
|_____________________________________________________________|
The pseudo-OP, "DC", will define a repetitive constant and eliminate the
necessity of defining a series of identical data values by long DB
specifications. For example, the following two statements are equivalent:
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DC 16,0
The latter is much shorter, easier to enter as text, more readable, and takes
up less space in its source form.
DC 100,0
and it will be done. A character constant can also be used for "value" as
illustrated in the following example:
DC 256,'A'
which will set the next 256 storage locations to the letter, "A". Pseudo-OP DS
This pseudo-OP is used to reserve a quantity of storage locations for use by
your program. Its syntax is:
_____________________________________________________________
| |
| DS nn |
| |
| nn reserves "nn" bytes of memory starting at the |
| current value of the reference counter. |
|_____________________________________________________________|
The DS pseudo-OP can also be entered as "DEFS".
FCB DS 32
will define a 32-byte region for later use as a File Control Block. Its origin
can then be referenced as "FCB". The statement,
TABLE DS TABLE_LENGTH * TABLE_WIDTH
will reserve a quantity of storage locations equal to the result of
multiplying the two terms, TABLE_LENGTH and TABLE_WIDTH.
FCB DC 32,0
TABLE DC TABLE_LENGTH * TABLE_WIDTH,0
Pseudo-OP DW
This declaration specifies a 16-bit data value. Its syntax is:
_____________________________________________________________
| |
| DW nn{,'cc'}{,nn} |
| |
| nn defines the contents of a 2-byte word to be |
| the value, "nn". |
| |
| 'cc' defines the contents of a 2-byte word to be |
| the characters, 'cc' |
|_____________________________________________________________|
The DW pseudo-OP can also be entered as "DEFW".
DW 10000,1000,100,10,1
DW 'ab'
DW 'R','o','y'
Note that if a single character is defined as a character constant word, the
low-order byte of the word will contain the character value and the high-order
byte of the word will be set to zero.
Pseudo-OP DATE
The DATE pseudo-OP is used to assemble the system date as an 8-character
string, MM/DD/YY. It's syntax is:
_____________________________________________________________
| |
| DATE |
|_____________________________________________________________|
This actual date is established when you power up your computer and respond to
the DOS's date entry query or by using the DOS's DATE library command. The
date string can be useful to place an ASCII date stamp in your object program
for the purpose of identification as to when it was assembled. See example 1
for an illustration of DATE.
Pseudo-OP DSYM
DSYM is usually used within a macro to assemble the "symbol" argument as if it
were a DB character string. It's syntax is:
_____________________________________________________________
| |
| label DSYM symbol |
| |
| label An optional statement label. |
| |
| symbol A defined symbolic label. |
|_____________________________________________________________|
When used in a macro environment, "symbol" will have the "#" indicator
prefixed to designate the symbol as a macro dummy argument name. An
alternative method is to use the ampersand escape function within a standard
quoted character string such as "DB 'symbol'" which also assembles to the
same thing in a macro. See example 1 for an illustration of DSYM.
Pseudo-OP DX expression
DX assembles "expression" as a 4-hexadecimal digit character string. Its
syntax is:
_____________________________________________________________
| |
| label DX expression |
| |
| label An optional statement label. |
| |
| expression An expression operand. |
|_____________________________________________________________|
The expression can be a simple symbol or a complicated collection of terms.
The expression is evaluated to a 16-bit value and output as four hexadecimal
digits. See example 1 for an illustration of DX.
Pseudo-OP TIME
The TIME pseudo is used to assemble the system time as an 8-character string,
HH:MM:SS. It's syntax is:
_____________________________________________________________
| |
| TIME |
|_____________________________________________________________|
This actual time is established when you power up your computer and respond to
the DOS's time entry query or by using the DOS's TIME library command. The
TIME string can be useful to place an ASCII TIME stamp in your
object program for the purpose of identification as to when it was assembled.
See Example 1 for an illustration of TIME.
Example 1
3000 00001 ORG 3000H
3000 00002 NAME MACRO #SYM
3000 00003 DSYM #SYM
3000 00004 DX #SYM
3000 00005 ENDM
3000 00006 ENTRY BEGIN
3000 210730 00007 BEGIN LD HL,MSG$
3003 3E0A 00008 LD A,10
3005 EF 00009 RST 40
3006 C9 00010 RET
3007 00011 MSG$ NAME BEGIN
3007+42 00012 DSYM BEGIN
45 47 49 4E
300C+33 00013 DX BEGIN
30 30 30
3010 0D 00014 DB 13
3011 31 00015 DATE
32 2F 33 31 2F 38 34
3019 30 00016 TIME
39 3A 31 31 3A 33 36
0000 00017 END
Pseudo-OP ASEG
This pseudo-OP is used to set the program counter to the absolute segment. The
syntax of "ASEG" is:
_____________________________________________________________
| |
| ASEG |
| ORG expression (optional) |
| |
| expression When evaluated, "expression" will be the |
| origin of the segment. Expression must |
| evaluate to an absolute value. |
|_____________________________________________________________|
It is not necessary for an ORG to follow an ASEG. An ASEG will set the
absolute program counter to the last encountered ASEG value, or to zero if no
previous ASEG had been specified.
Pseudo-OP COMMON
This pseudo-OP is used to set the program counter to a common relative
segment. The syntax of "COMMON" is:
_____________________________________________________________
| |
| COMMON /{name}/ |
| |
| name An optional name which specifies a name |
| for the common segment. |
|_____________________________________________________________|
This pseudo-OP sets the PC to a common relative segment: the slashes are
required. If "name" is omitted, blank common is assumed. A maximum of seven
named commons are permitted in any one module. The "name" of a common cannot
be the same as any symbol. Pseudo-OP CSEG
This pseudo-OP is used to set the program counter to the code relative
segment. The syntax of "CSEG" is:
_____________________________________________________________
| |
| CSEG |
| ORG expression (optional) |
| |
| expression When evaluated, "expression" will be the |
| origin of the segment. Expression must |
| evaluate to an absolute value. |
|_____________________________________________________________|
It is not necessary for an ORG to follow a CSEG. A CSEG will set the code
relative program counter to the last encountered CSEG value, or to zero if no
previous CSEG had been specified. Pseudo-OP DEFL
The "DEFL" pseudo-OP assigns a value to a label. The value is permitted to be
changed during the assembly. The "DEFL" syntax is:
_____________________________________________________________
| |
| label DEFL nn |
| label DEFL expression |
| |
| nn sets the value of "label" to the quantity "nn" |
| |
| expression sets the value of "label" to the evaluated |
| result of "expression". |
|_____________________________________________________________|
This declaration is similar to the "EQU" declaration except that the label
value is permitted to change during the course of the assembly without
producing phase errors (which are generally observed as numerous MULTIPLY
DEFINED SYMBOL errors). If the value of "label" is declared by a "DEFL", the
declaration can be repeated in the program with different values for the same
label. Pseudo-OP DSEG
This pseudo-OP is used to set the program counter to the data relative
segment. The syntax of "DSEG" is:
_____________________________________________________________
| |
| DSEG |
| ORG expression (optional) |
| |
| expression When evaluated, "expression" will be the |
| origin of the segment. Expression must |
| evaluate to an absolute value. |
|_____________________________________________________________|
It is not necessary for an ORG to follow a DSEG. A DSEG will set the
code relative program counter to the last encountered DSEG value, or to zero
if no previous DSEG had been specified.
Pseudo-OP END
The "END" pseudo is used to denote the exit of a *GET, *INCLUDE, or *SEARCH
process. If the END statement of the source file has a non-zero operand, it
will denote the transfer address of the module. Its syntax is:
_____________________________________________________________
| |
| END {nn} |
| END {label} |
| |
| nn Specifies an execution transfer address branch |
| that will be used by the system loader. |
| |
| label Specifies an execution transfer address branch |
| to be the value of "label". |
|_____________________________________________________________|
The "END" statement is used to indicate to the assembler, when the last source
code statement is reached so that any following statements are ignored. If no
"END" statement is found, processing stops when the end of the file is
reached. The END statement can specify a transfer address (i.e. END LABEL or
END 6000H). Only one transfer address should be specified per assembly stream;
however, if more than one non-absolute-zero END operand is detected, only the
first one will be retained. The transfer address is used by the DOS program
execution to transfer control to the address specified in the END statement.
Note that the END statement cannot have a label in the label field of the
statement).
Pseudo-OPs ENTRY, GLOBAL, and PUBLIC
Any one of these may be used to specify that the names of the symbols in the
name list are symbols global to linkage when REL modules are linked by the
linker (MLINK). The syntax is:
_____________________________________________________________
| |
| ENTRY name{,name}... |
| GLOBAL name{,name}... |
| PUBLIC name{,name}... |
| |
| name A symbol to be defined global. |
|_____________________________________________________________|
MRAS treats GLOBAL, ENTRY, and PUBLIC totally equivalent in order to provide
compatibility with other relocating assemblers. A symbol classified as such is
known to other separately assembled modules which specify "name" as EXTRN. All
symbols not specified as GLOBAL, PUBLIC, or ENTRY are known only to the module
currently being assembled.
--------method 1------- --------method 2-------
PUBLIC TRUST
TRUST LD HL,VALUE TRUST:: LD HL,VALUE
Symbols declared PUBLIC in one module that need to be referenced by another
module must be declared EXTRN in all modules other than the module where the
symbol is defined.
Pseudo-OP EQU
This pseudo-OP assigns a constant value to a label. Its syntax is:
_____________________________________________________________
| |
| label EQU nn |
| label EQU expression |
| |
| nn Sets the value of label to nn. |
| |
| expression Sets the value of label to the calculated |
| value of "expression" |
|_____________________________________________________________|
The "EQU" (equate) pseudo-OP is the generally accepted way to define constant
values for use in your program. This declaration serves a different purpose
than the data declarations such as DB, DC, and DW. Data declarations specify
storage locations that contain the values declared. The "EQU" assigns
the value to the label; thus, anywhere the label is used, the assigned value
is utilized. Your programs will be more readable, and easier to maintain if
the values need to be altered in a program revision. Pseudo-OP EXTRN
The EXTRN pseudo-OP is used to declare a PUBLIC symbol which is defined in
some other module. EXT is synonomous with EXTRN. The syntax of "EXTRN" is:
_____________________________________________________________
| |
| EXTRN name{,name}... |
| EXT name{,name}... |
| |
| name A symbol defined external to the current |
| module. |
|_____________________________________________________________|
When your program is made up of more than one REL module linked together by
the linker, symbols which are referenced in a module but defined in another
must be declared EXTRN in all modules which reference the symbol other than
the module which defines it.
Pseudo-OP LORG
The "LORG" pseudo-OP is used to establish a CMD object code file (or part of
one) that loads at an address different from where it will execute. The syntax
of "LORG" is:
_____________________________________________________________
| |
| LORG nn Turn on LORG |
| LORG expression Turn on LORG |
| LORG $ Turn off LORG |
| |
| nn Is the address to start loading the object |
| file (or part of the file). |
| |
| expression When evaluated, "expression" will be treated |
| the same as "nn". |
|_____________________________________________________________|
A load-origin assembler directive, "LORG", is provided to cause the load
addresses of the object file to be based on the LORG operand while the
execution code address references will still be based on the "ORG" operand.
This is useful to construct a module (or part of a module) that will load at
an address different from its execution address. Such is the case when using
MRAS to generate a PROMable module to be used on an external processor
origined at zero. For example:
ASEG
ORG 0000H
LORG 7000H
will assemble code so that absolute address references and the execution
addresses are referenced from X'0000'; however, the object code file will
start loading at X'7000'. Any subsequent "ORG" will maintain the offset
difference established at the previous "ORG" until another "LORG" is detected.
LORG $
to follow the last statement of the offset block of code. The assembler will
specifically test for the case, LORG $, so that it forces a new load block
where one is required. Pseudo-OP NAME
This is used to specify the module name of the generated REL file. The syntax
of "NAME" is:
_____________________________________________________________
| |
| NAME modname |
| NAME ('modname') (equivalent) |
| |
| modname Specifies the module name for the REL file. |
| |
|_____________________________________________________________|
If NAME is not specified in the source stream of an assembly which generates a
REL object code file, a special link item module name record will be generated
using as a default, the first seven non-blank characters of the REL file's
name. The second format is supported for compatability with M-80.
Pseudo-OP ORG
The "ORG" pseudo-OP is used to establish an address for the program counter so
that the address references within a program are designated to origin from
other than address 0000H. The syntax of "ORG" is:
_____________________________________________________________
| |
| ORG nn |
| ORG expression |
| |
| nn sets the address reference counter to the |
| value "nn". |
| |
| expression when evaluated, "expression" will be treated |
| the same as "nn". Terms of "expression" must |
| be defined prior to the "ORG" statement. |
|_____________________________________________________________|
The "ORG" statement is used to tell the assembler at what address to begin
generating the object code for statements which follow. The assembler will
generate object code starting at the address specified by "nn" or
"expression", automatically advancing the program counter by the length of
each instruction or data declaration assembled. The "DS" data declaration
advances the program counter by the amount of storage locations reserved.
Conditional Pseudo-OPs
The "conditional" pseudo-OPs provide a powerful way to maintain a program that
is slightly different when assembled to run on different machine
configurations. Instead of having to maintain multiple copies of a program,
with each having some routines and modifications to make a "custom" version of
the program, by using the conditional pseudo-OPs, you can maintain one set of
source code that has conditional clauses that perform the "customization". It
is very easy to specify which clauses are to be assembled during a particular
assembly. The structure of a conditional clause is as follows:
_____________________________________________________________
| |
| IFxx operand_of_IF |
| . |
| clause |
| . |
| ENDIF |
| |
| THE OPERAND OF THE CONDITIONAL MUST BE DEFINED |
| PRIOR TO THE EVALUATION OF THE "IF" STATEMENT! |
|_____________________________________________________________|
The operand of the "IF" takes on different formats depending on the particular
"IF" pseudo-OP. It can be an expression, a label, or two expressions separated
by commas. If the operand evaluates to a non-zero value, it is interpreted as
a logical TRUE condition. If the argument evaluates to a zero value, it is
interpreted as a logical FALSE condition. When the condition is TRUE, the
conditional clause between the "IF" and the "ENDIF" is assembled. If the
evaluation is to a zero value then the conditional clause is not assembled,
For the sake of uniformity, use the value of "-1" for a logical TRUE and "0"
for a logical FALSE so that, "FALSE EQU .NOT.TRUE" is a valid statment. The
values can be set in program as follows:
TRUE EQU -1
FALSE EQU 0
MOD1 EQU TRUE
MOD2 EQU FALSE
MOD3 EQU FALSE
Conditional clauses can also be nested, in case complicated logical constructs
are needed or in case a conditional clause itself has a conditional
sub-clause. For example:
IF expression1
IF expression2
ENDIF
ENDIF
is a two-level conditional. Conditional clauses can be nested to sixteen (16)
levels although you will rarely find a need for more than three.
IF expression
clause_1.
ELSE
clause_2.
ENDIF
which implies that if expression is TRUE, clause_1 assembles. If expression is
FALSE, then clause_2 will be assembled. The ELSE construct is not required in
a conditional but may be used where you have alternative clauses that can be
based on one switch.
_____________________________________________________________
| |
| ---Type I--- -----Type II------ --Type III-- |
| IF[x] exp IFxx[$] exp1,exp2 IFyy name |
| . . . |
| clause clause clause |
| . . . |
| ENDIF ENDIF ENDIF |
| |
| [x] Optional entry of 1, 2, or 3 to evaluate based |
| on the assembler phase during the assembly |
| |
| xx Can be "LT", "EQ", "GT", or "NE" meaning less |
| than, equal to, greater than, or not equal to |
| respectively when comparing "exp1" to "exp2". |
| |
| [$] The "$" is specified in macro comparisons with |
| the expressions treated as strings (see the |
| section on USING MACROS). |
| |
| yy Can be "DEF", "NDEF", or "REF" representing |
| whether <name> has been defined, undefined, |
| or referenced but undefined; or ABS, REL, EXT, |
| or NEXT representing a test of the mode or |
| class of the symbol. |
|_____________________________________________________________|
Pseudo-OPs IFx - Type I
The IF1, IF2, and IF3 conditional pseudo-OPs evaluate TRUE when the assembler
is on pass 1, 2, and 3 respectively. Pass 1 is the first pass used to evaluate
the value of all symbols. Pass 2 generates the listing and cross reference
data file. Pass 2 will be omitted if -NL is TRUE and -XR is FALSE. Pass 3
generates the object code. Macros must be read in on each pass. EQUates must
be read in on each pass if they are the object of an IFDEF pseudo-OP,
otherwise, they can be read in on the first pass only. In the latter case,
surround the *GET which gets the equate file with an IF1-ENDIF.
Pseudo-OPs IFxx - Type II
Among the Type II constructs, using "IFLT", if the value of expression_1 is
less than the value of expression_2, then the conditional clause will be
assembled. Using "IFEQ", the conditional clause will be assembled only if
expression_1 and expression_2 have equal values. The "IFGT" pseudo-OP will
assemble the conditional clause (i.e. result in a TRUE condition) only if
expression_1 has a value exceeding that of expression_2. The last possibility
is "IFNE", which will cause the assembly of the conditional clause if the
expressions are not of equal value.
IFGT $,MAXADDRESS
ERR Program is too long!
ENDIF
which compares the current value of the program counter (PC) to some
previously specified maximum address. Once the PC exceeds this maximum value,
the condition evaluates TRUE resulting in an assembly of the segment. The
"ERR" pseudo-OP is used to force an assembly error.
Pseudo-OPs IFyy - Type III
Among the Type III constructs, "IFDEF name" will evaluate TRUE if "name" has
been defined prior to the evaluation of the IFDEF on each assembler pass or if
name has been declared EXTRN. "IFNDEF name" will evaluate TRUE if "name" has
NOT been defined prior to the evaluation of the IFNDEF on each assembler pass
nor has it been declared EXTRN. "IFREF name" will evaluate TRUE if "name" has
been referenced but NOT defined prior to the evaluation of the IFREF on each
assembler pass. Suppressing FALSE Conditionals
If during the listing pass, you want to suppress the listing of certain
conditional clauses that are not assembled (i.e. they are evaluated as FALSE),
use the following sequence of operators:
*LIST OFF
IF expression
*LIST ON
clause
*LIST OFF
ENDIF
*LIST ON
With this sequence, the "IF" and "ENDIF" lines will always be suppressed. The
conditional clause will only be listed if the condition being evaluated is
logically TRUE. If no FALSE conditional segment is to be listed, then you may
use the assembler -NC switch which inhibits the listing of all FALSE
conditionals -- including the IF-ENDIF statements.
Pseudo-OP ENDIF
Each IF statement must be matched up with a corresponding ENDIF. The ENDIF is
needed to define the scope of the conditional clause.
Pseudo-OP COM
This pseudo-OP is used to generate a comment record in the object code file of
a directly generated CMD file. Its syntax is:
_____________________________________________________________
| |
| COM <string> |
| |
|
An object deck comment block can be generated within the executable object
code file directly by using the COM pseudo-OP. The comment string must have a
length less than 128 characters. As can be noted, the comment string must be
enclosed in angle brackets. The closing bracket may be omitted. If lower case
characters are desired, then single quotes must surround the angle brackets.
Neither the quotes nor the angle brackets will be a part of the comment
record.
COM '
will produce the comment record which would be viewed if the file were listed.
The generation of the COM object code record will be inhibited if the assembly
is performed using the -CI switch. A binary core-image file can not have a
non-loadable record.
Pseudo-OP ERR
The ERR pseudo-OP is used to force an assembly error. Its syntax is:
_____________________________________________________________
| |
| ERR {message} |
| |
| message is an optional message to inform what is wrong. |
|_____________________________________________________________|
This pseudo-OP forces an immediate warning error and displays the optional
message. It is commonly used in a conditional clause for error trapping.
Pseudo-OP OPTION
This pseudo-OP is used to alter the state of any of the assembler switches
entered on the command line invoking the assembly. Its syntax is:
_____________________________________________________________
| |
| OPTION {-/+}switch{,-/+switch},... |
| |
| -/+] An optional prefix to turn the switch OFF or ON |
| |
| switch Any of the permissable assembler switches. |
|_____________________________________________________________|
Prefix each switch with "-" to turn OFF, or "+" to turn ON (i.e. +NL
suppresses the listing - sets the NO LISTING switch to TRUE). If "+" is
omitted, it is assumed. The COMMA separator is mandatory if you omit the "+".
OPTION switches over-ride command line switches. Pseudo-OP REF
REF may be used to force a reference to the symbol(s) identified in the
argument list. Its syntax is:
_____________________________________________________________
| |
| REF symbol1{,symbol2},... |
| |
| symboln A "name" to be force-referenced. |
|_____________________________________________________________|
This function may be useful to force references to macros so that they may be
loaded via a '*SEARCH' operation.
Listing Pseudo-OPs
Four pseudo-OPs are available to control the assembler listings. These are:
PAGE, SPACE, SUBTTL, and TITLE. Their syntax is:
_____________________________________________________________
| |
| PAGE |
| |
| SPACE n |
| |
| SUBTTL <string> |
| |
| TITLE <string> |
| |
| n Specifies how many line feeds to generate. |
| |
| <string> Is the title or sub-title string to appear in |
| the listing headings. |
|_____________________________________________________________|
A new page can be forced to provide separation of routines, functions, etc. by
using the PAGE pseudo-op. This pseudo-OP will be ignored if it appears between
*LIST OFF and *LIST ON. PAGE statements are automatically suppressed from the
listing. PAGE will output a FORM FEED character only during the listing pass.
TITLE '<This is an UC/lc title>'
The first TITLE pseudo-OP found in the text will be used for titling.
All other TITLE pseudo-ops will be ignored.
Assembler Directives
MRAS supports seven assembler directives. In contrast to source statements
which are translated to machine language, these directives are "conversation"
to the assembler. Each directs the assembler to behave in a particular manner
or perform a specific function. The directives do not generate any machine
language code by themselves, they merely act as "commands" to the assembler.
Each "command" must start in column one of a source statement line, and must
start with either an asterisk "*" or a period ".". The entire directive word
may be entered, or it may be abbreviated to its minimum unique character
string. The assembler directives are:
_____________________________________________________________
| |
| *Get file Causes the assembler to begin reading source |
| code from the "file". |
| |
| *Inc file Causes the assembler to begin reading source |
| code from the file identified on the command |
| line via "+I=filespec". Treated as *GET if no |
| "+I=filespec" was specified. |
| |
| *List OFF Causes the assembler listing to be suspended, |
| starting with the next line. |
| |
| *List ON Causes assembler listing to resume, starting |
| with this line. |
| |
| *Mod exp Advances the "module" character substitution |
| string. |
| |
| *RAdix exp Changes the default radix to expression which |
| must evaluate to the range <1-16>. |
| |
| *REquest Generates a Special Link Item to request a |
| search by the linker of the library file |
| identified in the *REQUEST directive. |
| |
| *Search lib Invokes an automatic search of the Partitioned |
| Data Set (PaDS) "lib" to resolve any undefined |
| references capable of being resolved by PaDS |
| assembler source member modules. |
|_____________________________________________________________|
*GET filespec
This directive invokes assembly from a source disk file. Its syntax is:
_____________________________________________________________
| |
| *Get filespec/ASM |
| |
| filespec Causes the assembler to begin reading source |
| code from the file, "filespec". |
|_____________________________________________________________|
This directive tells the assembler to temporarily switch its source assembly
to the file identified as "filespec", and use it to continue the assembly. A
default file extension of "ASM" will be used if none is provided in the
directive statement. The file itself can be headered and/or numbered, as MRAS
will automatically detect its type and adjust accordingly; however, all source
files must be similarly structured. When the end-of-file is reached, or an
assembly language "END" statement is read, assembly resumes from the next
statement following the statement which invoked the "*GET". *INCLUDE filespec
This directive invokes assembly from a source disk file. Its syntax is:
_____________________________________________________________
| |
| *Include filespec/ASM |
| |
| filespec Causes the assembler to begin reading source |
| code from the file identified on the command |
| line via "+I=include" |
|_____________________________________________________________|
This directive tells the assembler to temporarily switch its source assembly
to the file identified on the MRAS command line via the "+I=include" file
switch. If no "+I=" file switch was entered, the *Include is treated exactly
as if it were a "*Get filespec."
LIST ON/OFF
This is used to suppress the listing of blocks of code. Its syntax is:
_____________________________________________________________
| |
| *List off/on |
| |
| OFF Causes the assembler listing to be suspended, |
| starting with the next statement. |
| |
| ON Causes assembler listing to resume, starting |
| with this statement. |
|_____________________________________________________________|
The pair of directives, "*LIST OFF" and "LIST ON", can be used to suppress the
listing of a block of code. All statements which follow a "*LIST OFF" will be
suppressed during the listing pass. The "*LIST ON" will resume standard
listing. An exception to the suppression is that any assembler source
statement containing an assembly error will be listed along with its
appropriate error message. In this manner, you can use an "*LIST OFF"
directive at the beginning of your assembly source (to suppress all listing)
and lines containing errors will be forced to be displayed.
*MOD
This directive increments a character substitution string to simulate local
labels in blocks within one module. Its syntax is:
_____________________________________________________________
| |
| *MOD |
| Advances the "module" character substitution |
| string. |
|_____________________________________________________________|
The *MOD directive will increment a string replacement variable each time the
directive is executed. The string will replace the question mark, "?",
character in labels and label references found in any statement. Its use is
essentially applicable to subroutine libraries where duplication of labels
could occur. By specifying the *MOD directive as the first statement of each
module of code and by using a question mark in labels, you can construct
source subroutine libraries for use in your programs without having to worry
about duplicate labels occuring. Unless at least one *MOD statement is
specified, the question mark will not be translated. *RADIX expression
This directive sets the default radix for all numeric terms except for "*RADIX
expressions" which always default to 10. Its syntax is:
_____________________________________________________________
| |
| *RAdix expression |
| |
| expression Is evaluated and becomes the new default radix |
| for all numeric terms. The value of expression |
| must be in the range <1-16>. |
|_____________________________________________________________|
Note that in the evaluation of the expression for the *RADIX directive, the
assembler will always use a radix default of 10. The assembler defaults to a
radix of 10 unless overridden by a *RADIX directive.
*REQUEST lib1{,lib2},...
This is used to convey information to the linker. It will generate a "Request
Library Search" special link item for use by MLINK. The syntax is:
_____________________________________________________________
| |
| *REquest lib1{,lib2},... |
| |
| libn The 1-7 character name of the REL library to |
| be searched by the linker. |
|_____________________________________________________________|
*REQUEST will generate the link item to the linker for each library name
identifed in the argument list.
*SEARCH filespec
This directive is used to invoke an automatic search of a Partitioned Data Set
(PaDS) source library, "filename/LIB", for all members that will resolve
undefined references in the source stream. This provides a source library
structure. *SEARCH will require two (2) levels of "*GET" nesting. Also, a
*SEARCH member cannot use a *GET directive or another *SEARCH directive. The
default file extension for searched files is "LIB". The syntax of *SEARCH
filespec is:
_____________________________________________________________
| |
| *Search filespec/LIB |
| |
| filespec Invokes an automatic search of the PaDS |
| "filespec/LIB" to resolve any undefined |
| references capable of being resolved by |
| PaDS assembler source member modules. |
|_____________________________________________________________|
The PaDS source library constitutes members composed of one or more routines.
Each routine should have its routine name (the label field entry) in the PaDS
member directory. This is accomplished by naming the source file to be
appended to the library the same name as the routine or by appending using a
MAP. Details on constructing and using Partitioned Data Sets is included with
PaDS documentation. The PaDS utility is available separately.
Member definition error: filespec(member)
After the member's source code is read, MRAS will continue to search the PaDS
library until it exhausts all members. There are no restrictions on the order
of members. Routines in one member can reference other members with complete
disregard as to any ordering of entries in the PaDS.
; Entry for routine entitled "MOVE"
IFREF MOVE
MOVE . ;Routine of code
.
ENDIF
; Entry for routine entitled "SHIFT"
IFREF SHIFT
SHIFT . ;Routine of code
.
ENDIF
If your source code references "SHIFT" but not "MOVE", as long as both "SHIFT"
and "MOVE" are member entries in the PaDS library, a *SEARCH of the library
will access the member and assemble only the SHIFT routine.
What is a MACRO?
In virtually all programs, you find particular sequences of code that are
repeated. These sequences may be termed routines. They could be so short that
the overhead needed to set them up as CALLable routines is ineffective. Or,
they could be longer routines that just cannot be constructed as CALLable
segments. You may even want a code sequence to be an in-line assembly in
contrast to a CALLable routine for the purpose of fast execution. The most
useful function is to be able to have parameterized routines - algorithms that
operate on different values each time the algorithm is invoked.
LD HL,VALUE
LD (MEMORY),HL
How many times is this little sequence repeated in your programs? Five? Ten?
If we set up a macro near the beginning of our program that looked something
like this:
STOR MACRO #VAL,#MEM ;Macro to store "VAL" into memory
LD HL,#VAL ;Get value into HL
LD (#MEM),HL ;Load value into memory
ENDM ;End of the macro
we could perform the above two statements with one macro call as follows:
STOR VALUE,MEMORY ;Invoke the macro
The first part of the example, defines a macro called "STOR". This is done
exactly once per program! If we save our macros in a macro source file, each
of our programs could "*GET MACROS"; thus, we would not have to even manually
enter the macro into each program. MACRO Definition
The format for a macro definition is illustrated as:
_____________________________________________________________
| |
| MOVE MACRO #parm1,#parm2=dflt2,#parm3 |
| LD HL,#parm1 |
| LD DE,#parm2 |
| LD BC,#parm3 |
| LDIR |
| ENDM |
|_____________________________________________________________|
The macro definition consists of three parts: a macro prototype, a macro
model, and the ENDM statement. The prototype is used to specify the macro name
and the dummy parameter names used in the model. Default substitutions may be
specified in the prototype to be used if the corresponding parameter is not
passed in the macro invocation. The macro model contains all of the assembler
statements to be generated when the macro is invoked. The model is sometimes
called the macro skeleton or template. The dummy parameter names occupy the
positions where the actual parameters will be placed by the macro processor in
MRAS. The third part, the ENDM statement, is used to indicate the end of the
macro model. Macro Prototype
Macros are named just like symbolic labels. The same rules apply. The number
sign "#" is used to denote a parameter in the macro prototype; however, its
use is optional. It is still required in the macro model to indicate the start
of a parameter name. The length of macro names can range from <1-15>.
Special characters <@, $, _> may be used in the name construct. Do not
use the question mark in macro names as it would conflict with the symbol
substitution string use made of "?".
_____________________________________________________________
| |
| mname MACRO {#parm1}{=dflt1}{,#parm2{=dflt2}}{,...} |
| |
| mname is the macro name used to invoke the macro. |
| |
| #parmn are dummy parameters of the macro which will |
| be replaced by actual parameters during the |
| macro invocation. "#" is an optional prefix. |
| |
| dfltn are optional default strings to be used for |
| the dummy parameters when a parameter is not |
| provided in the macro invocation. |
|_____________________________________________________________|
The upper limit on the number of macro parameters is 127; however, you can not
exceed the length of a standard assembler source statement. Thus, the
statement length becomes the limiting factor. As is the case with macro names,
the rules for naming dummy parameters are identical to the rules for labels.
If a macro parameter is enclosed in angle brackets, the entire string which is
enclosed within brackets will be treated as one parameter - even if it
contains separator characters. Neither the macro names nor the "dummy" names
are included in the symbol table generated by MRAS, thus there is no
restriction on reusing the same name as a "dummy" for a label; however, to
avoid confusion, it is recommended that you avoid using dummy names as
symbolic label names.
5200 00002 FEED MACRO #STRING
5200 00003 $?1 JR $?2
5200 00004 LABEL? IRPC XX,#STRING
5200 00005 LABXX DB '&XX'
5200 00006 IFGT $-LABEL?,3
5200 00007 EXITM
5200 00008 ENDIF
5200 00009 ENDM
5200 00010 $?2 LD HL,LABEL?
5200 00011 ENDM
5200 00012 FEED 012345
5200+1806 00013 $A1 JR $A2
00014 LABELA IRPC XX,012345
5202+ 00015 LABXX DB '&XX'
5202+ 00016 IFGT $-LABELA,2
5202+ 00017 EXITM
5202+ 00018 ENDIF
5202+ 00019 ENDM
5202+30 00020 LAB0 DB '0'
00021 IFGT $-LABELA,2
00022 EXITM
00023 ENDIF
5203+31 00024 LAB1 DB '1'
00025 IFGT $-LABELA,2
00026 EXITM
00027 ENDIF
5204+32 00028 LAB2 DB '2'
00029 IFGT $-LABELA,2
00030 EXITM
00031 ENDIF
5205+210252 00036 $A2 LD HL,LABELA
0000 00037 END
Macro Model
Any valid Z-80 statement, MRAS pseudo-OP, or assembler directive (except *GET
or *SEARCH) is valid in the macro model.
ENDM pseudo-OP
This pseudo-OP is used to specify the scope of a macro model. It is used much
like ENDIF. Its syntax is:
_____________________________________________________________
| |
| mname MACRO parms |
| model statements |
| ENDM |
|_____________________________________________________________|
The ENDM pseudo-OP must be used to let the macro processor know what is the
last macro model statement. If macros are nested, each must have an ENDM.
EXITM Pseudo-OP
This pseudo-OP can be used to prematurely exit from a MACRO expansion. This is
normally used within a conditional clause. One level of conditional nesting
will be removed (if any are present). See the example for IRP.
Macro Definition Examples
This macro will move a block of memory from one location to another. If the
"length" parameter is omitted, then a value of "255" will be used:
MOVBLK MACRO #FM,#TO,#LEN=255
LD HL,#FM
LD DE,#TO
LD BC,#LEN
LDIR
ENDM
This is a macro to clear a region of memory (i.e. set to 0). This macro will
invoke the MOVBLK macro in a nested invocation:
CLRMEM MACRO #BUF,#LEN=255
LD HL,#BUF
LD (HL),0
MOVBLK #BUF,#BUF+1,#LEN
ENDM
This macro will add the 8-bit register "A" to 16-bit register pair "HL":
ADDHLA MACRO
ADD A,L
LD L,A
ADC A,H
SUB L
LD H,A
ENDM
A macro is not required to contain dummy parameters as is evidenced by the
last example.
Incorporating Conditionals
Conditional pseudo-OPs can be specified in macro models. For instance, say you
want the MOVBLK macro to be able to perform a non-destructive move (a
destructive move would be where the destination is an address between "from"
and "from+length-1"). You can insert conditional pseudo-OPs to test the
parameters during the assembly of the expansion. Don't forget that the actual
labels substituted for parameters must be defined prior to invoking the MACRO!
Then, only certain segments of the macro will be assembled according to the
result of the evaluation. Analyze the following example:
MOVBLK MACRO #FM,#TO,#LEN=255
IFNE #FM,#TO ;Don't expand if #FM=#TO
LD BC,#LEN ;Establish the length
IFGT #FM,#TO ;Do we LDIR or LDDR?
LD HL,#FM ;#FM > #TO => LDIR
LD DE,#TO
LDIR
ELSE
LD HL,#FM+#LEN-1 ;#TO > #FM => LDDR
LD DE,#TO+#LEN-1
LDDR
ENDIF
ENDIF
ENDM
MACRO Nesting
The CLRMEM example depicts a macro that nests a macro invocation. Macros may
be nested to seven (7) levels. That is, at any time, macro expansions for 7
macros called in a chain can be pending. For example:
ABC MACRO #PARMS,...
(model statements)
MOVE parm,parm ;call macro "MOVE"
(model statements)
ENDM
MOVE MACRO #parm1,#parm2,#parm3
(model statements)
ENDM
is perfectly legal. The expansion of the "MOVE" macro is not performed during
the definition of the "ABC" macro but rather during the invocation of "ABC".
ABC MACRO #PARM
(model statements)
XYZ MACRO #PARMs,...
(model statements)
ENDM
ENDM
is a legal macro definition. The inner macro (XYZ) will not be defined until
the outer macro (ABC) is invoked. Note the two ENDM statements. MACRO Invocation
The invocation of a macro is termed a macro "call". The macro processor then
proceeds to replace the call with the model statements specified when the
macro was defined. The replacement of the macro call by the macro model
statements is termed the macro "expansion". Positional Parameters
"Positional" parameters are correlated by the position they appear in the
macro call. For example, if the "MOVBLK" macro was called with:
MOVBLK VIDEO,CRT_BUFFER,CRT_SIZE
then the substitution string "VIDEO" would replace every appearance of "#FM",
the string "CRT_BUFFER" would replace every appearance of "#TO", and
"CRT_SIZE" would replace the dummy parameter, "#LEN". Note that actual strings
are positionally correlated with the positions of the dummy parameters in the
macro prototype.
SHIFT 4200H,,100H
omits the middle of three parameters. Generally, a default would have been
provided in the macro definition.
Keyword Parameters
If the number of parameters is large, it is sometimes burdensome to remember
the order of the parameters, or to provide the correct number of commas if a
series of parameters are omitted. These drawbacks are remedied by the use of
"keyword" parameters. The macro call parameter list can identify the actual
parameters by using the name of the dummy parameter as well. The keyword
syntax is:
_____________________________________________________________
| |
| #dummy=actual parameter |
| |
| mname #parm2=actual2,#parm3=actual3 |
|_____________________________________________________________|
If the previous macro call was invoked by keyword parameter specification, it
could look something like this:
SHIFT #LEN=100H,#FM=4200H
Mixing Positional and Keyword Parameters
A single macro invocation can intermix both positional and keyword parameters.
The point that needs clarification, is what positions are actually denoted in
the parameter list. It is simply treated. In a mixed parameter list, keyword
parameters are ignored when considering place positions. For example, in the
following macro call:
SHIFT #LEN=100,BLOCK,BUF_START
even though the length parameter appeared first in the parameter list, since
it was designated as a keyword, it is ignored from the positional count and
"BLOCK" is the first parameter with "BUF_START" second. In a similar manner:
COMP PARM1,#P6=2,,PARM3,#P8=38,PARM4
"PARM1" is in position one, the second parameter is omitted (the double
comma), "PARM3" and PARM4" are in the third and fourth positions respectively.
The sixth and eighth parameters have been entered by keyword.