c71e249a4e
First substantive commit: the entire Sprinter C compiler tree on top of
the bare README+gitignore initial commit.
What's in here:
bin/sprinter-cc — driver script invoking SDCC + linker + mkexe
libc/ — Sprinter-specific libc layer over ESTEX/BIOS
(conio, gfx, io, mem, stdio + headers)
runtime/ — crt0 variants (default/small/banked/minimal)
+ heap + bank trampolines
toolchain/ — mkexe (SprintEXE packer, C + tests)
examples/ — 30 demo programs (gfx, file I/O, env, time, …)
lib/Makefile — builds the libc archive (sprinter.lib)
docs/ — converted Sprinter manuals + asm reference samples
third_party/ — solid-c reference compiler dump + sdcc setup script
release_docs/ — packaging / release notes
gitignore overhaul:
• Drop dangerous blanket patterns: *.asm (would hide docs/samples/*.asm)
and *.exe (case-insensitive match was hiding third_party/solid-c/*.EXE
on macOS APFS). Replaced with examples/*/*.{asm,exe,…} and lib/*.lib.
• Restore tracking of toolchain/mkexe/tests/{one,big}.bin — those are
INPUT fixtures, not build outputs.
• Collapse the duplicated SDCC/C/Sdcc sections into one section per
concern (build outputs / vendored / OS-junk).
• Add .sprinter-cc-*/, build/ (catches lib/build/ too), .claude/.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1732 lines
57 KiB
Plaintext
1732 lines
57 KiB
Plaintext
MACRO-80 Assembler
|
|
|
|
|
|
2.1 Running MACRO-80
|
|
2.2 Command Format
|
|
2.2.1 Devices
|
|
2.2.2 Switches
|
|
2.3 Format of MACRO-80 Source Files
|
|
2.3.1 Statements
|
|
2.3.2 Symbols
|
|
2.3.3 Numeric Constants
|
|
2.3.4 Strings
|
|
2.4 Expression Evaluation
|
|
2.4.1 Arithmetic and Logical Operators
|
|
2.4.2 Modes
|
|
2.4.3 Externals
|
|
2.5 Opcodes as Operands
|
|
2.6 Pseudo Operations
|
|
2.6.1 ASEG
|
|
2.6.2 COMMON
|
|
2.6.3 CSEG
|
|
2.6.4 DB - Define Byte
|
|
2.6.5 DC - Define Character
|
|
2.6.6 DS - Define Space
|
|
2.6.7 DSEG
|
|
2.6.8 DW - Define Word
|
|
2.6.9 END
|
|
2.6.10 ENTRY/PUBLIC
|
|
2.6.11 EQU
|
|
2.6.12 EXT/EXTRN
|
|
2.6.13 INCLUDE
|
|
2.6.14 NAME
|
|
2.6.15 ORG - Define Origin
|
|
2.6.16 PAGE
|
|
2.6.17 ASET
|
|
2.6.18 SUBTTL
|
|
2.6.19 TITLE
|
|
2.6.20 .COMMENT
|
|
2.6.21 .PRINTX
|
|
2.6.22 .RADIX
|
|
2.6.23 .Z80
|
|
2.6.24 .8080
|
|
2.6.25 .REQUEST
|
|
2.6.26 Conditional Pseudo Operations
|
|
2.6.26.1 ELSE
|
|
2.6.26.2 ENDIF
|
|
2.6.27 Listing Control Pseudo Operations
|
|
2.6.28 Relocation Pseudo Operations
|
|
2.6.28.1 ORG Pseudo-op
|
|
2.6.29.2 LINK-80
|
|
2.6.29 Relocation Before Loading
|
|
2.7 Macros and Block Pseudo Operations
|
|
2.7.1 Terms
|
|
2.7.2 REPT-ENDM
|
|
2.7.3 IRP-ENDM
|
|
2.7.4 IRPC-ENDM
|
|
2.7.5 MACRO
|
|
2.7.6 ENDM
|
|
2.7.7 EXITM
|
|
2.7.8 LOCAL
|
|
2.7.9 Special Macro Operators and Forms
|
|
2.8 Using z80 Pseudo-ops
|
|
2.9 Sample Assembly
|
|
2.10 MACRO-80 Errors
|
|
2.11 Compatability with Other Assemblers
|
|
2.12 Format of Listings
|
|
2.12.1 Symbol Table Listing
|
|
|
|
|
|
CHAPTER 2
|
|
|
|
MACRO-80 ASSEMBLER
|
|
|
|
|
|
|
|
2.1 RUNNING MACRO-80
|
|
|
|
The command to run MACRO-80 is
|
|
|
|
M80
|
|
|
|
MACRO-80 returns the prompt "*", indicating it is ready to accept
|
|
commands.
|
|
|
|
|
|
NOTE
|
|
|
|
If you are using the TEKDOS
|
|
operating system, see Appendix
|
|
A for proper command formats.
|
|
|
|
|
|
|
|
|
|
2.2 COMMAND FORMAT
|
|
|
|
A command to MACRO-80 consists of a string of filenames with optional
|
|
switches. All filenames should follow the operating system's
|
|
conventions for filenames and extensions. The default extensions
|
|
supplied by Microsoft software are as follows:
|
|
|
|
File CP/M ISIS-II
|
|
|
|
Relocatable object file REL REL
|
|
Listing file PRN LST
|
|
MACRO-80 source file MAC MAC
|
|
FORTRAN source file FOR FOR
|
|
COBOL source file COB COB
|
|
Absolute file COM
|
|
|
|
|
|
2.2.1 Devices
|
|
|
|
Any field in the MACRO-80 command string can also specify a device
|
|
name. The default device name with the CP/M operating system is the
|
|
currently logged disk. The default device name with the ISIS-II
|
|
operating system is disk drive 0. The command format is:
|
|
|
|
dev:objfile,dev:lstfile=dev:source file
|
|
|
|
The device names are as follows:
|
|
|
|
Device CP/M ISIS-II
|
|
|
|
Disk drives A:, B:, C:,... :F0:, :F1:, :F2:, ...
|
|
Line printer LST: LST:
|
|
Teletype or CRT TTY: TTY:
|
|
High speed reader HSR
|
|
|
|
Examples:
|
|
|
|
*,TTY:=TEST Assemble the source file TEST.MAC
|
|
and list the program on the
|
|
console. No object code is
|
|
generated. Useful for error check.
|
|
|
|
*SMALL,TTY:=B:TEST Assemble TEST.MAC (found
|
|
on disk drive B), place
|
|
the object file in SMALL.REL
|
|
and list the program on the console.
|
|
|
|
|
|
|
|
2.2.2 Switches
|
|
|
|
A switch is a letter that is appended to the command string, preceded
|
|
by a slash. It specifies an optional task to be performed during
|
|
assembly. More than one switch can be used, but each must be preceded
|
|
by a slash. (With the TEKDOS operating system, switches are preceded by
|
|
commas or spaces. See Appendix A.) All switches are optional. The
|
|
available switches are:
|
|
|
|
Switch Action
|
|
|
|
O Octal lising
|
|
|
|
H Hexadecimal listing (default)
|
|
|
|
R Force generation of an object file
|
|
|
|
L Force generation of a lising file
|
|
|
|
C Force generation of a cross reference file
|
|
|
|
Z Assemble Z80 opcodes (default for Z80 operating systems)
|
|
|
|
I Assemble 8080 opcodes (default for 8080 operating systems)
|
|
|
|
P Each /P allocates an extra 256 bytes of stack space for use
|
|
during assembly. Use /P if stack overflow occurs during
|
|
assembly. Otherwise, not needed.
|
|
|
|
M Initialize Block Data Areas. If the programmer wants the
|
|
area that is defined by the DS (Define Space) pseudo-op
|
|
initialized to zeros, then the programmer should use the /M
|
|
switch in the command line. Otherwise, the space is not
|
|
guaranteed to contain zeros. That is, DS does not
|
|
automattically initialize the space to zeros.
|
|
|
|
X Usually used to suppress the listing of false conditionals.
|
|
The following paragraph describes the /X switch more
|
|
completely but in very technical terms.
|
|
|
|
The presence or absence of /X in the command line sets the
|
|
initial current mode and the initial value of the default
|
|
for listing or suppressing lines in false conditional
|
|
blocks. /X sets the current mode and initial value of
|
|
default to not-to-list. No /X sets current mode and initial
|
|
value of default to list. Current mode determines whether
|
|
false conditionals will be listed or suppressed. The
|
|
initial value of the default is used with the .TFCOND
|
|
pseudo-op so that .TFCOND is independent of .SFCOND and
|
|
.LFCOND. If the program contains .SFCOND or .LFCOND, /X has
|
|
no effect after .SFCOND or .LFCOND is encountered until a
|
|
.TFCOND is encountered in the file. So /X has an effect
|
|
only when used with a file that contains no conditional
|
|
listing psuedo-ops or when used with .TFCOND.
|
|
|
|
|
|
Examples:
|
|
|
|
*=TEST/L Assemble TEST.MAC, places the object file in TEST.REL
|
|
and a listing file in TEST.PRN. (With ISIS-II, the
|
|
listing file is TEST.LST.)
|
|
|
|
*=TEST/L/O Same as above, but listing file addresses will be in
|
|
octal.
|
|
|
|
*LAST=TEST/C Assemble TEST.MAC, place the object file in LAST.REL
|
|
and cross reference file in TEST.CRF. (See Chapter 3.)
|
|
|
|
|
|
|
|
2.3 FORMAT OF MACRO-80 SOURCE FILES
|
|
|
|
Input source lines of up to 132 characters in length are acceptable.
|
|
|
|
MACRO-80 preserves lower case letters in quoted strings and comments.
|
|
All symbols, opcodes and pseudo-opcodes typed in lower case will be
|
|
converted to upper case.
|
|
|
|
If the source file includes line numbers from an editor, each byte of
|
|
th eline number must have the high bit on. Line numbers from
|
|
Microsoft's EDIT-80 are acceptable.
|
|
|
|
|
|
2.3.1 Statements
|
|
|
|
Source files input to MACRO-80 consist of statements of the form:
|
|
|
|
[label:[:]] [operator] [arguments] [;comment]
|
|
|
|
With the exception of the ISIS assembler $ controls (see Section 2.11),
|
|
it is nog necessary that statements begin in column 1. Multiple blanks
|
|
or tabs may be used to improve readability.
|
|
|
|
If a label is present, it is the first item in the statement and is
|
|
immediately followed by a colon. If it is followed by two colons, it is
|
|
declared as PUBLIC (seen ENTRY/PUBLIC, Section 2.6.10). For example:
|
|
|
|
FOO:: RET
|
|
|
|
is equivalent to
|
|
|
|
PUBLIC FOO
|
|
FOO: RET
|
|
|
|
The next item after the label, or the first item on the line if no
|
|
label is present, is an operator. An operator may be an 8080 mnemonic,
|
|
pseudo-op, macro call or expression. The evaluation is as follows:
|
|
|
|
1. Macro call
|
|
|
|
2. Mnemonic/Pseudo operation
|
|
|
|
3. Expression
|
|
|
|
Instead of flagging an expression as an error, the assembler treats it
|
|
as if it were a DB statement (see Section 2.6.4).
|
|
|
|
The arguments following the operator will, of course, vary in form
|
|
according to the operator.
|
|
|
|
A comment always begins with a semicolon and ends with a carriage
|
|
return. A comment may be a line by itself or it may be appended to a
|
|
line that contains a statement. Extended comments can be entered using
|
|
the .COMMENT pseudo operation (see Section 2.6.20).
|
|
|
|
|
|
2.3.2 Symbols
|
|
|
|
MACRO-80 symbols may be of any length, however, only the first six
|
|
characters are significant. The following characters are legal in a
|
|
symbol:
|
|
|
|
A-Z 0-9 $ . ? @
|
|
|
|
With Microsoft's 8080/Z80/8086 assemblers, the underline character is
|
|
also legal in a symbol. A symbol may not start with a digit. When a
|
|
symbol is read, lower case is translated into upper case. If a symbol
|
|
reference is followed by ## it is declared external (see also the
|
|
EXT/EXTRN pseudo-op, Section 2.6.12).
|
|
|
|
|
|
2.3.3 Numeric Constants
|
|
|
|
The default base for numeric constants is decimal. This may be changed
|
|
by the .RADIX pseudo-op (see Section 2.6.22). Any base from 2 (binary)
|
|
to 16 (hexadecimal) may be selected. When the base is greater than 10,
|
|
A-F are the digits following 9. If the first digit of a number is not
|
|
numeric the number must be preceeded by a zero.
|
|
|
|
Numbers are 16-bit unsigned quantities. A number is always evaluated in
|
|
the current radix unless one of the following special notations is
|
|
used:
|
|
|
|
nnnnB Binary
|
|
nnnnD Decimal
|
|
nnnnO Octal
|
|
nnnnQ Octal
|
|
nnnnH Hexadecimal
|
|
X'nnnn' Hexadecimal
|
|
|
|
Overflow of a number beyond two bytes is ignored and the result is the
|
|
low order 16-bits.
|
|
|
|
A character constant is a string comprised of zero, one or two ASCII
|
|
characters, delimited by quotation marks, and used in a non-simple
|
|
expression. For example, in the statement
|
|
|
|
DB 'A' + 1
|
|
|
|
'A' is a character constant. But the statement
|
|
|
|
DB 'A'
|
|
|
|
uses 'A' as a string because it is in a simple expression. The rules
|
|
for character constant delimiters are the same as for strings.
|
|
|
|
A character constant comprised of one character has as its value the
|
|
ASCII value of that character. That is, the high order byte of the
|
|
value is zero, and the low order byte is the ASCII value of the
|
|
character. For example, the value of the constant 'A' is 41H.
|
|
|
|
A character constant comprised of two characters has as its value the
|
|
ASCII value of the first character in the high order byte and the ASCII
|
|
value of the second character in the low order byte. For example, the
|
|
value of the character constant 'AB' is 41H*256+42H
|
|
|
|
|
|
2.3.4 Strings
|
|
|
|
A string is comprised of zero or more characters delimited by quotation
|
|
marks. Either single or double quotes may be used as string delimiters.
|
|
The delimiter quotes may be used as characters if they appear twice for
|
|
every character occurrence desired. For example, the statement
|
|
|
|
DB "I am ""great"" today"
|
|
|
|
stores the string
|
|
I am "great" today
|
|
|
|
If there are zero characters between the delimiters, the string is a
|
|
null string.
|
|
|
|
|
|
|
|
2.4 EXPRESSION EVALUATION
|
|
|
|
2.4.1 Arithmetic And Logical Operators
|
|
|
|
The following operators are allowed in expressions. The operators are
|
|
listed in order of precedence.
|
|
|
|
NUL
|
|
|
|
LOW, HIGH
|
|
|
|
*, /, MOD, SHR, SHL
|
|
|
|
Unary Minus
|
|
|
|
+, -
|
|
|
|
EQ, NE, LT, LE, GT, GE
|
|
|
|
NOT
|
|
|
|
AND
|
|
|
|
OR, XOR
|
|
|
|
Parantheses are used to change the order of precedence. During
|
|
evaluation of an expression, as soon as a new operator is encountered
|
|
that has precedence less than or equal to the last operator
|
|
encountered, all operations up to the new operator are performed. That
|
|
is, subexpressions involving operators of higher precedence are
|
|
computed first.
|
|
|
|
All operators except +, -, *, / must be separated from their operands
|
|
by at least one space.
|
|
|
|
The byte isolation operators (HIGH, LOW) isolate the high or low order
|
|
8 bits of an Absolute 16-bit value. If a relocatable value is supplied
|
|
as an operand, HIGH and LOW will treat it as if it were relative to
|
|
location zero.
|
|
|
|
|
|
2.4.2 Modes
|
|
|
|
All symbols used as operands in expressions are in one of the following
|
|
modes: Absolute, Data Relative, Program (Code) Relative or COMMON. (See
|
|
Section 2.6 for the ASEG, CSEG, DSEG and COMMON pseudo-ops.) Symbols
|
|
assembled under the ASEG, CSEG (default), or DSEG pseudo-ops are in
|
|
Absolute, Code Relative or Data Relative mode respectively.
|
|
|
|
The number of COMMON modes in a program is determined by the number of
|
|
COMMON blocks that have been named with the COMMON pseudo-op. Two
|
|
COMMON symbols are not in the same mode unless they are in the same
|
|
COMMON block. In any operation other than addition or subtraction, the
|
|
mode of both operands must be Absolute.
|
|
|
|
If the operation is addition, the following rules apply:
|
|
|
|
1 At least one of the operands must be Absolute.
|
|
|
|
2 Absolute + <mode> = <mode>
|
|
|
|
If the operation is subtraction, the following rules apply:
|
|
|
|
1 <mode> - Absolute = <mode>
|
|
|
|
1 <mode> - <mode> = Absolute
|
|
where the two <mode>s are the same.
|
|
|
|
Each intermediate step in the evaluation of an expression must conform
|
|
to the above rules for modes, or an error will be generated. For
|
|
example, if FOO, BAZ and ZAZ are three Program Relative symbols, the
|
|
expression
|
|
|
|
FOO + (BAZ -ZAZ)
|
|
|
|
if legal because the first step (BAZ - ZAZ) generates an Absolute value
|
|
that is then added to the Program Relative value, FOO.
|
|
|
|
|
|
2.4.3 Externals
|
|
|
|
Aside from its classification by mode, a symbol is either External or
|
|
not External. (See EXT/EXTRN, Section 2.6.12.) An External value must
|
|
be assembled into a two-byte field. (Singe-byte Externals are not
|
|
supported.) The following rules apply to the use of Externals in
|
|
expressions:
|
|
|
|
1. Externals are legal only in addition and subtraction.
|
|
|
|
2. If an External symbol is used in an expression, the result of
|
|
the expression is always External.
|
|
|
|
3. When the operation is addition, either operand (but not both)
|
|
may be External.
|
|
|
|
4. When the operation is subtraction, only the first operand may
|
|
be External.
|
|
|
|
|
|
|
|
2.5 OPCODES AS OPERANDS
|
|
|
|
8080 opcodes are valid one-byte operands. Note that only the first byte
|
|
is a valid operand. For example:
|
|
|
|
MVI A,(JMP)
|
|
ADI (CPI)
|
|
MVI B,(RNZ)
|
|
CPI (INX H)
|
|
ACI (LXI B)
|
|
MVI C,MOV A,B
|
|
|
|
Errors will be generated if more than one byte is included in the
|
|
operand -- such as (CPI 5), LXI B,LABEL1 or (JMP LABEL2).
|
|
|
|
Opcodes used as one-byte operands need not be enclosed in parentheses.
|
|
|
|
|
|
NOTE
|
|
|
|
Opcodes are not valid operands
|
|
in Z80 mode.
|
|
|
|
|
|
2.6 PSEUDO OPERATIONS
|
|
|
|
2.6.1 ASEG
|
|
|
|
ASEG
|
|
|
|
ASEG sets the location counter to an absolute segment of memory. The
|
|
location of the absolute counter will be that of the last ASEG (default
|
|
is 0), unless an ORG is done after the ASEG to change the location. The
|
|
effect of ASEG is also achieved by using the code segment (CSEG) pseudo
|
|
operation and the /P switch in LINK-80. See also section 2.6.28
|
|
|
|
|
|
2.6.2 COMMON
|
|
|
|
COMMON /<block name>/
|
|
|
|
COMMON sets the location counter to the selected common block in
|
|
memory. The location is always the beginning of the area so that
|
|
compatibility with the FORTRAN COMMON statement is maintained. If
|
|
<block name> is omitted or consists of spaces, it is considered to be
|
|
blank common. See also Section 2.6.28.
|
|
|
|
|
|
2.6.3 CSEG
|
|
|
|
CSEG
|
|
|
|
CSEG sets the location counter to the code relative segment of memory.
|
|
The location will be that of the last CSEG (default is 0), unless an
|
|
ORG is done after the CSEG to change the location. CSEG is the default
|
|
condition of the assembler (the INTEL assembler defaults to ASEG). See
|
|
also Section 2.6.28.
|
|
|
|
|
|
2.6.4 DB - Define Byte
|
|
|
|
DB <exp>[,<exp>...]
|
|
|
|
DB <string>[<string>...]
|
|
|
|
The arguments to DB are either expressions or strings. DB stores the
|
|
values of the expressions or the characters of the strings in
|
|
successive memory locations beginning with the current location
|
|
counter.
|
|
|
|
Expressions must evaluate to one byte. (if the high byte of the result
|
|
is 0 or 255, no error is given; otherwise, an A error results.)
|
|
|
|
Strings of three or more characters may not be used in expressions
|
|
(i.e., they must be immediately followed by a comma or the end of the
|
|
line). The characters in a string are stored in the order of
|
|
appearance, each as a one-byte value with the high order bit set to
|
|
zero.
|
|
|
|
Example:
|
|
|
|
0000' 41 42 DB 'AB'
|
|
0002' 42 DB 'AB' AND 0FFH
|
|
0003' 41 42 43 DB 'ABC'
|
|
|
|
|
|
2.6.5 DC - Define Character
|
|
|
|
DC <string>
|
|
|
|
DC stores the characters in <string> in successive memory locations
|
|
beginning with the current location counter. As with DB, characters are
|
|
stored in order of appearance, each as a one-byte value with the high
|
|
order bit set to zero. However, DC stores the last character of the
|
|
string with the high order bit set to one. An error will result if the
|
|
argument to DC is a null string.
|
|
|
|
|
|
2.6.6 DS - Define Space
|
|
|
|
DS <exp>
|
|
|
|
DS reserves an area of memory. The value of <exp> gives the number of
|
|
bytes to be allocated. All names used in <exp> must be previously
|
|
defined (i.e., all names known at that point on pass 1). Otherwise, a V
|
|
error is generated during pass 1 and a U error may be generated during
|
|
pass 2. If a U error is nog generated during pass 2, a phase error will
|
|
probably be generated because the DS generated no code on pass 1.
|
|
|
|
|
|
2.6.7 DSEG
|
|
|
|
DSEG
|
|
|
|
DSEG sets the location counter to the Data Relative segment of memory.
|
|
The location of the data relative counter wil be that of the last DSEG
|
|
(default is 0), unless an ORG is done after the DSEG to change the
|
|
location. See also Section 2.6.28.
|
|
|
|
|
|
2.6.8 DW - Define Word
|
|
|
|
DW <exp>[,<exp>...]
|
|
|
|
DW stores the values of the expressions in successive memory locations
|
|
beginning with the current location counter. Expressions are evaluated
|
|
as 2-byte (word) values.
|
|
|
|
|
|
2.6.9 END
|
|
|
|
END [<exp>]
|
|
|
|
The END statement specifies the end of the program. If <exp> is
|
|
present, it is the start address of the program. If <exp> is not
|
|
present, then no start address is passed to LINK-80 for that program.
|
|
|
|
|
|
NOTE
|
|
|
|
If an assembly language program
|
|
is the main program, a start
|
|
address (label) must be
|
|
specified. If not, LINK-80 will
|
|
issue a "no start address"
|
|
error. If the program is a
|
|
subroutine to a FORTRAN program
|
|
(for example), the start
|
|
address is nog required because
|
|
FORTRAN has supplied one.
|
|
|
|
|
|
|
|
2.6.10 ENTRY/PUBLIC
|
|
|
|
ENTRY <name>[,<name>...]
|
|
or
|
|
PUBLIC <name>[,<name>...]
|
|
|
|
ENTRY or PUBLIC declares each name in the list as internal and
|
|
therefore available for use by this program and other programs to be
|
|
loaded concurrently. All of the names in the list must be defined in
|
|
the current program or a U error results. An M error is generated if
|
|
the name is an external name or common-blockname.
|
|
|
|
|
|
2.6.11 EQU
|
|
|
|
<name> EQU <exp>
|
|
|
|
EQU assigns the value of <exp> to <name>. If <exp> is external, an
|
|
error is generated. If <name> already has a value other than <exp>, an
|
|
M error is generated.
|
|
|
|
|
|
2.6.12 EXT/EXTRN
|
|
|
|
EXT <name>[,<name>...]
|
|
or
|
|
EXTRN <name>[,<name>...]
|
|
|
|
EXT or EXTRN declares that the name(s) in the list are external (i.e.,
|
|
defined in a different program). If any item in the list references a
|
|
name that is defined in the current program, an M error results. A
|
|
reference to a name where the name is followed immediately by two pound
|
|
signs (e.g., NAME##) also declares the name as external.
|
|
|
|
|
|
2.6.13 INCLUDE
|
|
|
|
INCLUDE <filename>
|
|
|
|
The INCLUDE pseudo-op applies only to CP/M versions of MACRO-80. The
|
|
pseudo-ops INCLUDE, $INCLUDE and MACLIB are synonymous.
|
|
|
|
The INCLUDE pseudo-op assembles source statements from an alternate
|
|
source file into the current source file. Use of INCLUDE eliminates the
|
|
need to repeat an often-used sequence of statements in the current
|
|
source file.
|
|
|
|
<filename> is any valid specification, as determined by the operating
|
|
system. Defaults for filename extensions and device names are the same
|
|
as those in a MACRO-80 command line.
|
|
|
|
The INCLUDE file is opened and assembled into the current source file
|
|
immediately following the INCLUDE statement. When end-of-file is
|
|
reached, assembly resumes with the statement following INCLUDE.
|
|
|
|
On a MACRO-80 listing, a plus sign is printed between the assembled
|
|
code and the source line on each line assembled from an INCLUDE file.
|
|
(See Section 2.12.)
|
|
|
|
Nested INCLUDEs are not allowed. If encountered, they will result in an
|
|
objectionable syntax error 'O'.
|
|
|
|
The file specified in the operand field must exist. If the file is not
|
|
found, the error 'V' (value error) is given, and the INCLUDE is
|
|
ignored.
|
|
|
|
|
|
2.6.14 NAME
|
|
|
|
NAME ('modname')
|
|
|
|
NAME defines a name for the module. Only the first six characters are
|
|
significant in a module name. A module name may also be defined with
|
|
the TITLE pseudo-op. In the absence of both the NAME and TITLE
|
|
pseudo-ops, the module name is created from the source file name.
|
|
|
|
|
|
2.6.15 ORG - Define Origin
|
|
|
|
ORG <exp>
|
|
|
|
The location counter is set to the value of <exp> and the assembler
|
|
assigns code starting with that value. All names used in <exp> must be
|
|
known on pass 1, and the value must either be absolute or in the same
|
|
area as the location counter.
|
|
|
|
|
|
2.6.16 PAGE
|
|
|
|
PAGE [<exp>]
|
|
|
|
PAGE causes the assembler to start a new output page. The value of
|
|
<exp>, if included, becomes the new page size (measured in lines per
|
|
page) and must be in the range 10 to 255. The default page size is 50
|
|
lines per page. The assembler puts a form feed character in the listing
|
|
file at the end of a page.
|
|
|
|
|
|
2.6.17 ASET
|
|
|
|
<name> ASET <exp>
|
|
|
|
ASET is the same as EQU, except no error is generated if <name> is
|
|
already defined.
|
|
|
|
|
|
2.6.18 SUBTTL
|
|
|
|
SUBTTL <text>
|
|
|
|
SUBTTL specifies a subtitle to be listed on the line after the title
|
|
(see TITLE, Section 2.6.19) on each page heading. <text> is truncated
|
|
after 60 characters. Any number of SUBTTLs may be given in a program.
|
|
|
|
|
|
2.6.19 TITLE
|
|
|
|
TITLE <text>
|
|
|
|
TITLE specifies a title to be listed on the first line of each page. If
|
|
more than one TITLE is given, a Q error results. The first six
|
|
characters of the title are used as the module name unless a NAME
|
|
pseudo operation is used. If neither a NAME or TITLE pseudo-op is used,
|
|
the module name is created from the source filename.
|
|
|
|
|
|
2.6.20 .COMMENT
|
|
|
|
.COMMENT <delim><text><delim>
|
|
|
|
The first non-blank character encountered after .COMMENT is the
|
|
delimiter. The following <text> comprises a comment block which
|
|
continues until the next occurence of <delimiter> is encountered. For
|
|
example, using an asterisk as the delimiter, the format of the comment
|
|
block would be:
|
|
|
|
.COMMENT *
|
|
any amount of text entered
|
|
here as the comment block
|
|
.
|
|
.
|
|
. *
|
|
;return to normal mode
|
|
|
|
|
|
2.6.21 .PRINTX
|
|
|
|
.PRINTX <delim><text><delim>
|
|
|
|
The first non-blank character encountered after .PRINTX is the
|
|
delimiter. The following text is listed on the terminal during assembly
|
|
until another occurence of the delimiter is encountered. .PRINTX is
|
|
useful for displaying progress through a long assembly or for
|
|
displaying the value of conditional assembly switches. For example:
|
|
|
|
IF CPM
|
|
.PRINTX /CPM version/
|
|
ENDIF
|
|
|
|
|
|
NOTE
|
|
|
|
.PRINTX will output on both
|
|
passes. If only one printout
|
|
is desired, use the IF1 or
|
|
IF2 pseudo-op. For example:
|
|
|
|
IF2
|
|
IF CPM
|
|
.PRINTX /CPM version/
|
|
ENDIF
|
|
ENDIF
|
|
|
|
will only print if CPM is
|
|
true and M80 is in pass 2.
|
|
|
|
|
|
2.6.22 .RADIX
|
|
|
|
.RADIX <exp>
|
|
|
|
The default base (or radix) for all constants is decimal. The .RADIX
|
|
statement allows the default radix to be changed to any base in the
|
|
range of 2 to 16. For example:
|
|
|
|
MOVI BX,0FFH
|
|
.RADIX 16
|
|
MOVI BC,0FF
|
|
|
|
The two MOVIs in the example are indentical. The <exp> in a .RADIX
|
|
statement is always in decimal radix, regardless of the current radix.
|
|
|
|
|
|
2.6.23 .Z80
|
|
|
|
.Z80 enables the assembler to accept Z80 opcodes. This is the default
|
|
condition when the assembler is running on a Z80 operating system. Z80
|
|
mode may also be set by appending the Z switch to the MACRO-80 command
|
|
string -- see Section 2.2.2.
|
|
|
|
|
|
2.6.24 .8080
|
|
|
|
.8080 enables the assembler to accept 8080 opcodes. This is the default
|
|
condition when the assembler is running on an 8080 operating system.
|
|
8080 mode may also be set by appending the I switch to the MACRO-80
|
|
command string -- see Section 2.2.2.
|
|
|
|
|
|
2.6.25 REQUEST
|
|
|
|
.REQUEST <filename>[,<filename>...]
|
|
|
|
.REQUEST sends a request to the LINK-80 loader to search the filenames
|
|
in the list for undefined globals. The filenames in the list should be
|
|
in the form of legal symbols. They should not include filename
|
|
extensions or disk specifications. LINK-80 supplies a default extension
|
|
and assumes the default disk drive.
|
|
|
|
|
|
2.6.26 Conditional Pseudo Operations
|
|
|
|
The conditional pseudo operations are:
|
|
|
|
IF/IFT <exp> True if <exp> is no 0.
|
|
|
|
IFE/IFF <exp> True if <exp> is 0.
|
|
|
|
IF1 True if pass 1.
|
|
|
|
IF2 True if pass 2.
|
|
|
|
IFDEF <symbol> True if <symbol> is defined or has been
|
|
declared External.
|
|
|
|
IFNDEF <symbol> True if <symbol> is undefined or not
|
|
declared External.
|
|
|
|
IFB <arg> True if <arg> is blank. The angle
|
|
brackets around <arg> are required.
|
|
|
|
IFNB <arg> True if <arg> is not blank. Used for
|
|
testing when dummy parameters are
|
|
supplied. The angle brackets around <arg>
|
|
are required.
|
|
|
|
IFIDN <arg1>,<arg2> True if the string <arg1> is IDeNtical to
|
|
the string <arg2>.
|
|
The angle brackets around <arg1> and
|
|
<arg2> are required.
|
|
|
|
IFDIF <arg1>,<arg2> True if the string <arg1> is DIFferent
|
|
from the string <arg2>.
|
|
The angle brackets around <arg1> and
|
|
<arg2> are required.
|
|
|
|
All conditionals use the following format:
|
|
|
|
IFxx [argument]
|
|
.
|
|
.
|
|
.
|
|
[ELSE
|
|
.
|
|
.
|
|
. ]
|
|
ENDIF
|
|
|
|
Conditionals may be nested to any level. Any argument to a conditional
|
|
must be known on pass 1 to avoid V errors and incorrect evaluation. For
|
|
IF, IFT, IFF, and IFE the expression must involve values which were
|
|
previously defined and the expression must be absolute. If the name is
|
|
defined after an IFDEF or IFNDEF, pass 1 considers the name to be
|
|
undefined, but it will be defined on pass 2.
|
|
|
|
|
|
2.6.26.1 ELSE - Each conditional pseudo operation may optionally be
|
|
used with the ELSE pseudo operation which allows alternate code to be
|
|
generated when the opposite condition exists. Only one ELSE if
|
|
permitted for a given IF, and an ELSE is always bound to the most
|
|
recent, open IF. A conditional with more than one ELSE or an ELSE
|
|
without a conditional will cause a C error.
|
|
|
|
|
|
2.6.26.2 ENDIF - Each IF must have a matching ENDIF to terminate the
|
|
conditional. Otherwise, an 'Unterminated conditional' message is
|
|
generated at the end of each pass. An ENDIF without a matching IF
|
|
causes a C error.
|
|
|
|
|
|
2.6.27 Listing Control Pseudo Operations
|
|
|
|
Output to the listing file can be controlled by two pseudo-ops:
|
|
|
|
.LIST and .XLIST
|
|
|
|
If a listing is nog being made, these pseudo-ops have no effect. .LIST
|
|
is the default condition. When a .XLIST is encountered, source and
|
|
object code fill not be listed until a .LIST is encountered.
|
|
|
|
The output of false conditional blocks is controlled by three
|
|
pseudo-ops: .SFCOND, .LFCOND, and .TFCOND.
|
|
|
|
These pseudo-ops give the programmer control over four cases.
|
|
|
|
1. Normally list false conditionals.
|
|
For this case, the programmer simply allows the default mode
|
|
to control the listing. The default mode is list false
|
|
conditionals. If the programmer decides to suppress false
|
|
conditionals, the /X switch can be issued in the command line
|
|
instead of editing the source file.
|
|
|
|
2. Normally surpress false conditionals.
|
|
For this case, the programmer issues the .TFCOND pseudo-op in
|
|
the program file. .TFCOND reverses (toggles) the default,
|
|
causing false conditionals to be suppressed. If the programmer
|
|
decides to list false conditionals, the /X switch can be
|
|
issued in the command line instead of editing the source file.
|
|
|
|
3. Always suppress/list false conditionals.
|
|
For this case, the programmer has decided for most false
|
|
conditionals whether to list or suppress, but for some false
|
|
conditionals the programmer has not yet decided. For the false
|
|
conditionals decided about, use .SFCOND or .LFCOND. For those
|
|
not yet decided, use .TFCOND. .TFCOND sets the current and
|
|
default settings to the opposite of the default. Initially,
|
|
the default is set by giving /X or no /X in the command line.
|
|
Two subcases exist:
|
|
|
|
1. The programmer wants some false conditionals not to list
|
|
unless /X is given. The programmer uses the .SFCOND and
|
|
.LFCOND pseudo-ops to control which areas always suppress
|
|
or list false conditionals. To selectively suppress some
|
|
false conditionals, the programmer issues .TFCOND at the
|
|
beginning of the conditional block and again at the end of
|
|
the conditional block. (NOTE: The second .TFCOND should be
|
|
issued so that the default setting will be the same as the
|
|
initial setting. Leaving the default equal to the initial
|
|
setting makes it easier to keep track of the default mode
|
|
if there are many such areas.) If the conditional block
|
|
evaluates as false, the lines will be suppressed. In this
|
|
subcase, issuing the /X switch in the command line causes
|
|
the conditional block affected by .TFCOND to list even if
|
|
it evaluates as false.
|
|
|
|
2. The programmer want some false conditionals to list unless
|
|
/X is given. Two consecutive .TFCONDs places the
|
|
conditional listing setting in initial state which is
|
|
determined by the presence or absence of the /X switch in
|
|
the command line (the first .TFCOND sets the default to
|
|
not initial; the second to initial). The selected
|
|
conditional block then responds to the /X switch: if a /X
|
|
switch is issued in the command line, the conditional
|
|
block is suppressed if false; if no /X switch is issued in
|
|
the command line, the conditional block is listed even if
|
|
false.
|
|
|
|
The three conditional listing pseudo-ops are summarized below.
|
|
|
|
PSEUDO-OP DEFINITION
|
|
|
|
.SFCOND Suppresses the listing of conditional blocks that
|
|
evaluate as false.
|
|
|
|
.LFCOND Restores the listing of conditional blocks that
|
|
evaluate as false.
|
|
|
|
.TFCOND Toggles the current setting which controls the listing
|
|
false conditionals. .TFCOND sets the current and
|
|
default setting to not default. If a /X switch is given
|
|
in the MACRO-80 run command line for a file which
|
|
contains .TFCOND, /X reverses the effect of .TFCOND.
|
|
|
|
The following chart illustrates the effects of the three pseudo-ops
|
|
when encountered under /X and under no /X.
|
|
|
|
PSEUDO-OP NO /X /X
|
|
|
|
(none) ON OFF
|
|
. . .
|
|
. . .
|
|
. . .
|
|
.SFCOND OFF OFF
|
|
. . .
|
|
. . .
|
|
. . .
|
|
.LFCOND ON ON
|
|
. . .
|
|
. . .
|
|
. . .
|
|
.TFCOND OFF ON
|
|
. . .
|
|
. . .
|
|
. . .
|
|
.TFCOND ON OFF
|
|
. . .
|
|
. . .
|
|
. . .
|
|
.SFCOND OFF OFF
|
|
. . .
|
|
. . .
|
|
. . .
|
|
.TFCOND OFF ON
|
|
.TFCOND ON OFF
|
|
. . .
|
|
. . .
|
|
. . .
|
|
.TFCOND OFF ON
|
|
|
|
|
|
The output of cross reference information is controlled by .CREF and
|
|
.XCREF. If the cross reference facility (see Chapter 3) has not been
|
|
invoked, .CREF and .XCREF have no effect. The default condition is
|
|
.CREF. When a .XCREF is encountered, no cross reference information is
|
|
output until .CREF is encountered.
|
|
|
|
The output of MACRO/REPT/IRP/IRPC expansions is controlled by three
|
|
pseudo-ops: .LALL, .SALL and .XALL. .LALL lists the complete macro text
|
|
for all expansions. .SALL suppresses listing of all text and object
|
|
code produced by macros. .XALL is the default condition; a source line
|
|
is listed only if it generates object code.
|
|
|
|
|
|
2.6.28 Relocation Pseudo Operations
|
|
|
|
The ability to create relocatable modules is one of the major features
|
|
of Microsoft assemblers. Relocatable modules offer the advantages of
|
|
easier coding and faster testing, debugging and modifying. In addition,
|
|
it is possible to specify segments of assembled code that will later be
|
|
loaded into RAM (the Data Relative segment) and ROM/PROM (the Code
|
|
Relative segment). The pseudo operations that select relocatable areas
|
|
are CSEG and DSEG. The ASEG pseudo-op is used to generate
|
|
non-relocatable (absolute) code. The COMMON pseudo-op creates a common
|
|
data area for every COMMON block that is named in the program.
|
|
|
|
The default mode for the assembler is Code Relative. That is, assembly
|
|
begins with a CSEG automatically executed and the location counter in
|
|
the Code Relative mode, pointing to location 0 in the Code Relative
|
|
segment of memory. All subsequent instructions will be assembled into
|
|
the Code Relative segment of memory until a ASEG or DSEG or COMMON
|
|
pseudo-op is executed. For example, the first DSEG encountered sets the
|
|
location counter to location zero in the Data Relative segment of
|
|
memory. The following code is assembled in the Data Relative segment of
|
|
memory. If a subsequent CSEG is encountered, the location counter will
|
|
return to the next free location in the Code Relative segment and so
|
|
on.
|
|
|
|
The ASEG, DSEG, CSEG pseudo-ops never have operands. If you wish to
|
|
alter the current value of the location counter, use the ORG pseudo-op.
|
|
|
|
|
|
2.6.28.1 ORG Pseudo-op - At any time, the value of the location
|
|
counter may be changed by use of the ORG pseudo-op. The form of the ORG
|
|
statement is:
|
|
|
|
ORG <exp>
|
|
|
|
where the value of <exp> will be the new value of the location counter
|
|
in the current mode. All names used in <exp> must be known on pass 1
|
|
and the value of <exp> must be either Absolute or in the current mode
|
|
of the location counter. For example, the statements
|
|
|
|
DSEG
|
|
ORG 50
|
|
|
|
set the Data Relative counter to 50, relative to the start of the Data
|
|
Relative segment of memory.
|
|
|
|
|
|
2.6.28.2 LINK-80 - The LINK-80 linking loader (see Chapter 4 of this
|
|
manual) combines the segments and creates each relocatable module in
|
|
memory when the program is loaded. The origins of the relocatable
|
|
segments are not fixed until the program is loaded and the origins are
|
|
assigned by LINK-80. The command to LINK-80 may contain user-specified
|
|
origins through the use of the /P (for Code Relative) and /D (for Data
|
|
and COMMON segments) switches.
|
|
|
|
For example, a program that begins with the statements
|
|
|
|
ASEG
|
|
ORG 800H
|
|
|
|
and is assembled entirely in Absolute mode will always load beginning
|
|
at 800 unless the ORG statement is changed in the source file. However,
|
|
the same program, assembled in Code Relative mode with no ORG
|
|
statement, may be loaded at any specified address by appending the
|
|
/P:<address> switch to the LINK-80 command string.
|
|
|
|
|
|
2.6.29 Relocation Before Loading
|
|
|
|
Two pseudo-ops, .PHASE and .DEPHASE, allow code to be located in one
|
|
area, but executed only at a different, specified area.
|
|
|
|
For example:
|
|
|
|
0000' .PHASE 100H
|
|
0100 E8 0003 FOO: CALL BAZ
|
|
0103 E9 FF01 JMP ZOO
|
|
0106 C3 BAZ: RET
|
|
.DEPHASE
|
|
0007' E9 FFFB ZOO: JMP 5
|
|
|
|
All labels within a .PHASE block are defined as the absolute value from
|
|
the origin of the phase area. The code, however, is loaded in the
|
|
current area (i.e., from 0' in this example). The code within the block
|
|
can later be moved to 100H and executed.
|
|
|
|
|
|
|
|
|
|
2.7 MACROS AND BLOCK PSEUDO OPERATIONS
|
|
|
|
The macro facilites provided by MACRO-80 include three repeat pseudo
|
|
operations: reapeat (REPT), indefinite repeat (IRP), and indefinite
|
|
repeat character (IRPC). A macro definition operation (MACRO) is also
|
|
provided. Each of these four macro operations is terminated by the ENDM
|
|
pseudo operation.
|
|
|
|
|
|
2.7.1 Terms
|
|
|
|
For the purposes of discussion of macros and block operations, the
|
|
following terms will be used:
|
|
|
|
1. <dummy> is used to represent a dummy parameter. All dummy
|
|
paramters are legal symbols that appear in the body of a
|
|
macro expansion.
|
|
|
|
2. <dummylist> is a list of <dummy>s separated by commas.
|
|
|
|
3. <arglist> is a list of arguments separated by commas.
|
|
<arglist> must be delimited by angle brackets. Two angle
|
|
brackets with no intervening characters (<>) or two commas
|
|
with no intervening characters enter a null argument in the
|
|
list. Otherwise an argument is a character or series of
|
|
characters terminated by a comma or >. With angle brackets
|
|
that are nested inside an <arglist>, one level of brackets is
|
|
removed each time the bracketed argument is used in an
|
|
<arglist>. (See example, Section 2.7.5.) A quoted string is
|
|
an acceptable argument and is passed as such. Unless enclosed
|
|
in brackets or a quoted string, leading and trailing spaces
|
|
are deleted from arguments.
|
|
|
|
4. <paramlist> is used to represent a list of actual parameters
|
|
separated by commas. No delimiters are required (the list is
|
|
terminated by the end of line or a comment), but the rules
|
|
for entering null parameters and nesting brackets are the
|
|
same as described for <arglist>. (See example, Section
|
|
2.7.5.)
|
|
|
|
|
|
2.7.2 REPT-ENDM
|
|
|
|
REPT <exp>
|
|
.
|
|
.
|
|
.
|
|
ENDM
|
|
|
|
The block of statements between REPT and ENDM is repeated <exp> times.
|
|
<exp> is evaluated as a 16-bit unsigned number. If <exp> contains any
|
|
external or undefined terms, an error is generated. Example:
|
|
|
|
ASET 0
|
|
REPT 10 ;generates DB 1 - DB 10
|
|
ASET X+1
|
|
DB X
|
|
ENDM
|
|
|
|
|
|
2.7.3 IRP-ENDM
|
|
|
|
IRP <dummy>,<arglist>
|
|
.
|
|
.
|
|
.
|
|
ENDM
|
|
|
|
The <arglist> must be enclosed in angle brackets. The number of
|
|
arguments in the <arglist> determines the number of times the block of
|
|
statements is repeated. Each repetition substitutes the next item in
|
|
the <arglist> for every occurrence of <dummy> in the block. If the
|
|
<arglist> is null (i.e., <>), the block is processed once with each
|
|
occurence of <dummy> removed. For example:
|
|
|
|
IRP X,<1,2,3,4,5,6,7,8,9,10>
|
|
DB X
|
|
ENDM
|
|
|
|
gernerates the same bytes as the REPT example.
|
|
|
|
|
|
2.7.4 IRPC-ENDM
|
|
|
|
IRPC <dummy>,string (or <string>)
|
|
.
|
|
.
|
|
.
|
|
ENDM
|
|
|
|
IRPC is similar to IRP but the arglist is replaced by a string of text
|
|
and the angle brackets around the string are optional. The statements
|
|
in the block are repeated once for each character in the string. Each
|
|
repetition substitutes the next character in the string for every
|
|
occurrence of <dummy> in the block. For example:
|
|
|
|
IRPC X,0123456789
|
|
DB X+1
|
|
ENDM
|
|
|
|
generates the same code as the two previous examples.
|
|
|
|
|
|
2.7.5 MACRO
|
|
|
|
Often it is convenient to be able to generate a given sequence of
|
|
statements from various places in a program, even though different
|
|
parameters may be required each time the sequence is used. This
|
|
capability is provided by the MACRO statement.
|
|
The form is
|
|
|
|
<name> MACRO <dummylist>
|
|
.
|
|
.
|
|
.
|
|
ENDM
|
|
|
|
where <name> conforms to the rules for forming symbols. <name> is the
|
|
name that will be used to invoke the macro. The <dummy>s in <dummylist>
|
|
are the parameters that will be changed (replaced) each time the MACRO
|
|
is invoked. The statements before the ENDM comprise the body of the
|
|
macro. During assembly, the macro is expanded every time it is invoked
|
|
but, unlike REPT/IRP/IRPC, the macro is not expanded when it is
|
|
encountered.
|
|
|
|
The form of a macro call is
|
|
|
|
<name> <paramlist>
|
|
|
|
where <name> is the name supplied in the MACRO definition, and the
|
|
parameters in <paramlist> will replace the <dummy>s in the MACRO
|
|
<dummylist> on a one-to-one basis. The number of items in <dummylist>
|
|
and <paramlist> is limited only by the length of a line. The number of
|
|
parameters used when the macro is called need not be the same as the
|
|
number of <dummy>s in <dummylist>. If there are more parameters than
|
|
<dummy>s, the extras are ignored. If there are fewer, the extra
|
|
<dummy>s will be made null. The assembled code will contain the macro
|
|
expansion code after each macro call.
|
|
|
|
NOTE
|
|
|
|
A dummy parameter in a MACRO/REPT/IRP/IRPC
|
|
is always recognized exclusively as a dummy
|
|
parameter. Register names such as A and B
|
|
will be changed in the expansion if they
|
|
were used as dummy parameters.
|
|
|
|
Here is an example of a MACRO definition that defines a macro called
|
|
FOO:
|
|
|
|
FOO MACRO X
|
|
Y ASET 0
|
|
REPT X
|
|
Y ASET Y+1
|
|
DB Y
|
|
ENDM
|
|
ENDM
|
|
|
|
This macro generates the same code as the previous three examples when
|
|
the call
|
|
|
|
FOO 10
|
|
|
|
is executed.
|
|
|
|
Another example, which generates the same code, illustrates the removal
|
|
of one level of brackets when an argument is used as an arglist:
|
|
|
|
FOO MACRO X
|
|
IRP Y,<X>
|
|
DB Y
|
|
ENDM
|
|
ENDM
|
|
|
|
When the call
|
|
|
|
FOO <1,2,3,4,5,6,7,8,9,10>
|
|
|
|
is made, the macro expansion looks like this:
|
|
|
|
IRP Y,<1,2,3,4,5,6,7,8,9,10>
|
|
DB Y
|
|
ENDM
|
|
|
|
|
|
2.7.6 ENDM
|
|
|
|
Every REPT, IRP, IRPC and MACRO pseudo-op must be terminated with the
|
|
ENDM pseudo-op. Otherwise the 'Unterminated REPT/IRP/IRPC/MACRO'
|
|
message is generated at the end of each pass. An unmatched ENDM causes
|
|
an O error.
|
|
|
|
|
|
2.7.7 EXITM
|
|
|
|
The EXITM pseudo-op is used to terminate a REPT/IRP/IRPC or MACRO call.
|
|
When an EXITM is executed, the expansion is exited immediately and any
|
|
remaining expansion or repetition is not generated. If the block
|
|
containing the EXITM is nested within another block, the outer level
|
|
continues to be expanded.
|
|
|
|
|
|
2.7.8 LOCAL
|
|
|
|
LOCAL <dummylist>
|
|
|
|
The LOCAL pseudo-op is allowed only inside a MACRO definition. When
|
|
LOCAL is executed, the assembler creates a unique symbol for each
|
|
<dummy> in <dummylist> and substitutes that symbol for each occurence
|
|
of the <dummy> in the expansion. These unique symbols are usually used
|
|
to define a label within a macro, thus eliminating multiply-defined
|
|
labels on successive expansions of the macro. The symbols created by
|
|
the assembler range from ..0001 to ..FFFF. Users will therefore want to
|
|
avoid the term ..nnnn for their own symbols. If LOCAL statements are
|
|
used, they must be the first statements in the macro definition.
|
|
|
|
|
|
2.7.9 Special Macro Operators And Forms
|
|
|
|
& The ampersand is used in a macro expansion to concatenate text
|
|
or symbols. A dummy parameter that is in a quoted string will
|
|
not be substituted in the expansion unless it is immediately
|
|
preceded by &. To form a symbol from text and a dummy, put &
|
|
between them. For example:
|
|
|
|
ERRGEN MACRO X
|
|
ERROR&X:PUSH BX
|
|
MOVI BX,'&X'
|
|
JMP ERROR
|
|
ENDM
|
|
|
|
In this example, the call ERRGEN A will generate:
|
|
|
|
ERRORA: PUSH BX
|
|
MOVI BX,'A'
|
|
JMP ERROR
|
|
|
|
;; In a block operation, a comment preceded by two
|
|
semicolons is not saved as part of the expansion (i.e.,
|
|
it will not appear on the listing even under .LALL). A
|
|
comment preceded by one semicolon, however, will be
|
|
preserved and appear in the expansion.
|
|
|
|
! When an exclamation point is used in an argument, the
|
|
next character is entered literally (i.e., !; and <;>
|
|
are equivalent).
|
|
|
|
NUL NULL is an operator that returns true if its argument (a
|
|
parameter) is null. The remainder of a line after NUL is
|
|
considered to be the argument to NUL. The conditional
|
|
|
|
IF NUL argument
|
|
|
|
is false if, during the expansion, the first character
|
|
of the argument is anything other than a semicolon or
|
|
carriage return. It is recommended that testing for null
|
|
parameters be done using the IFB and IFNB conditionals.
|
|
|
|
% The percent sign is used only in a macro argument. %
|
|
converts the expression that follows it (usually a
|
|
symbol) to a number in the current radix. During macro
|
|
expansion, the number derived from converting the
|
|
expression is substituted for the dummy. Using the %
|
|
special operator allows a macro call by value. (Usually,
|
|
a macro call is a call by reference with the text of the
|
|
macro argument substituting exactly for the dummy.)
|
|
|
|
The expression following the % must conform to the same
|
|
rules as the DS (Define Space) pseudo-op. A valid
|
|
expression returning a non-relocatable constant is
|
|
required.
|
|
|
|
EXAMPLE: Normally, LB, the argument to MAKLAB, would be
|
|
substituted for Y, the argument to MACRO, as a string.
|
|
The % causes LB to be converted to a non-relocatable
|
|
constant which is then substituted for Y. Without the %
|
|
special operator, the result of assembly would be 'Error
|
|
LB' rather than 'Error 1', etc.
|
|
|
|
MAKLAB MACRO Y
|
|
ERR&Y: DB 'Error &Y',0
|
|
ENDM
|
|
MAKERR MACRO X
|
|
LB ASET 0
|
|
REPT X
|
|
LB ASET LB+1
|
|
MAKLAB %LB
|
|
ENDM
|
|
ENDM
|
|
|
|
When called by MAKERR 3, the assembler will generate:
|
|
|
|
ERR1: DB 'Error 1',0
|
|
ERR2: DB 'Error 2',0
|
|
ERR3: DB 'Error 3',0
|
|
|
|
TYPE The TYPE operator returns a byte that describes two
|
|
characteristics of its argument: 1) the mode, and 2)
|
|
whether it is External or not. The argument to TYPE may
|
|
be any expression (string, numeric, logical). If the
|
|
expression is invalid, TYPE returns zero.
|
|
|
|
The byte that is returned is configured as follows:
|
|
|
|
The lower two bits are the mode. If the lower two bits
|
|
are:
|
|
|
|
0 the mode is Absolute
|
|
1 the mode is Program Relative
|
|
2 the mode is Data Relative
|
|
3 the mode is Common Relative
|
|
|
|
The high bit (80H) is the External bit. If the high bit
|
|
is on, the expression contains an External. If the high
|
|
bit is off, the expression is local (not External).
|
|
|
|
The Defined bit is 20H. This bit is on if the expression
|
|
is locally defined, and it is off if the expression is
|
|
undefined or external. If neither bit is on, the
|
|
expression is invalid.
|
|
|
|
TYPE is usually used inside macros, where an argument
|
|
type may need to be tested to make a decision regarding
|
|
program flow. For example:
|
|
|
|
FOO MACRO X
|
|
LOCAL Z
|
|
Z ASET TYPE X
|
|
IF Z...
|
|
|
|
|
|
|
|
2.8 USING Z80 PSEUDO-OPS
|
|
|
|
When using the MACRO-80 assembler, the following Z80 pseudo-ops are
|
|
valid. The function of each pseudo-op is equivalent to that of its
|
|
counterpart.
|
|
|
|
Z80 pseudo-op Equivalent pseudo-op
|
|
|
|
COND IFT
|
|
ENDC ENDIF
|
|
*EJECT PAGE
|
|
DEFB DB
|
|
DEFS DS
|
|
DEFW DW
|
|
DEFM DB
|
|
DEFL ASET
|
|
GLOBAL PUBLIC
|
|
EXTERNAL EXTRN
|
|
|
|
The formats, where different, conform to the previous format. That is,
|
|
DEFB and DEFW are permitted a list of arguments (as are DB and DW), and
|
|
DEFM is permitted a string or numeric argument (as is DB).
|
|
|
|
|
|
|
|
|
|
|
|
2.9 SAMPLE ASSEMBLY
|
|
|
|
|
|
A>M80
|
|
|
|
*EXMPL1,TTY:=EXMPL1
|
|
|
|
MAC80 3.2 PAGE 1
|
|
|
|
|
|
00100 ;CSL3(P1,P2)
|
|
00200 ;SHIFT P1 LEFT CIRCULARY 3 BITS
|
|
00300 ;RETURN RESULT IN P2
|
|
00400 ENTRY CSL3
|
|
00450 ;GET VALUE OF FIRST PARAMETER
|
|
00500 CSL3:
|
|
0000' 7E 00600 MOV A,M
|
|
0001' 23 00700 INX H
|
|
0002' 66 00800 MOV H,M
|
|
0003' 6F 00900 MOV L,A
|
|
01000 ;SHIFT COUNT
|
|
0004' 06 03 01100 MVI B,3
|
|
0006' AF 01200 LOOP: XRA A
|
|
01300 ;SHIFT LEFT
|
|
0007' 29 01400 DAD H
|
|
01500 ;ROTATE IN CY BIT
|
|
0008' 17 01600 RAL
|
|
0009' 85 01700 ADD L
|
|
000A' 6F 01800 MOV L,A
|
|
01900 ;DECREMENT COUNT
|
|
000B' 05 02000 DCR B
|
|
02100 ;ONE MORE TIME
|
|
000C' C2 0006' 02200 JNZ LOOP
|
|
000F' EB 02300 XCHG
|
|
02400 ;SAVE RESULT IN SECOND PARAMETER
|
|
0010' 71 02500 MOV M,E
|
|
0011' 23 02600 INX H
|
|
0012' 72 02700 MOV M,D
|
|
0013' C9 02800 RET
|
|
02900 END
|
|
|
|
|
|
MAC80 3.2 PAGE S
|
|
|
|
|
|
CSL3 0000I' LOOP 0006'
|
|
|
|
|
|
No Fatal error(s)
|
|
|
|
|
|
|
|
2.10 MACRO-80 ERRORS
|
|
|
|
MACRO-80 errors are indicated by a one-character flag in column one of
|
|
the listing file. If a listing file is not being printed on the
|
|
terminal, each erroneous line is also printed or displayed on the
|
|
terminal. Below is a list of the MACRO-80 Error Codes:
|
|
|
|
A Argument error
|
|
Argument to pseudo-op is not in correct format or is out of
|
|
range (.PAGE 1; .RADIX 1; PUBLIC 1; JMPS TOOFAR).
|
|
|
|
C Conditional nesting error
|
|
ELSE without IF, ENDIF without IF, two ELSEs on one IF.
|
|
|
|
D Double Defined symbol
|
|
Reference to a symbol which is multiply defined.
|
|
|
|
E External error
|
|
Use of an external illigal in context (e.g., FOO SET NAME##;
|
|
MOVI AX,2-NAME##).
|
|
|
|
M Multiply Defined symbol
|
|
Definition of a symbol which is multiply defined.
|
|
|
|
N Number error
|
|
Error in a number, usually a bad digit (e.g., 8Q).
|
|
|
|
O Bad opcode or objectionable syntax
|
|
ENDM, LOCAL outside a block; ASET, EQU or MACRO without a
|
|
name; bad syntax in an opcode; or bad syntax in an expression
|
|
(mismatched parenthesis, quotes, consecutive operators,
|
|
etc.).
|
|
|
|
P Phase error
|
|
Value of a Label or EQU name is different on pass 2.
|
|
|
|
Q Questionable
|
|
Usually means a line is not terminated properly. This is a
|
|
warning error (e.g. MOV AX,BX,).
|
|
|
|
R Relocation
|
|
Illigal use of relocation in expression, such as abs-rel.
|
|
Data, code and COMMON areas are relocatable.
|
|
|
|
U Undefined symbol
|
|
A symbol referenced in an expression is not defined. (For
|
|
certain pseudo-ops, a V error is printed on pass 1 and a U on
|
|
pass 2.)
|
|
|
|
V Value error
|
|
On pass 1 a pseudo-op which must have its value known on pass
|
|
1 (e.g., .RADIX, .PAGE, DS, IF, IFE, etc.), has a value which
|
|
is undefined. If the symbol is defined later in the program,
|
|
a U error will not appear on the pass 2 listing.
|
|
|
|
|
|
Error Messages:
|
|
|
|
'No END statement encountered on input file'
|
|
No END statement; either it is missing or it is not parsed
|
|
due to being in a false conditional, unterminated
|
|
IRP/IRPC/REPT block or terminated macro.
|
|
|
|
'Unterminated conditional'
|
|
At least one conditional is unterminated at the end of the
|
|
file.
|
|
|
|
'Unterminated REPT/IRP/IRPC/MACRO'
|
|
At least one block is unterminated.
|
|
|
|
[xx] [No] Fatal error(s) [,xx warnings]
|
|
The number of fatal errors and warnings. The message is
|
|
listed on the CRT and in the list file.
|
|
|
|
|
|
|
|
2.11 COMPATIBILITY WITH OTHER ASSEMBLERS
|
|
|
|
The $EJECT and $TITLE controls are provided for compatability with
|
|
INTEL's ISIS assembler. The dollar sign must appear in column 1 only if
|
|
spaces or tabs separate the dollar sign from the control word. The
|
|
control
|
|
|
|
$EJECT
|
|
|
|
is the same as the MACRO-80 PAGE pseudo-op.
|
|
The control
|
|
|
|
$TITLE('text')
|
|
|
|
is the same as the MACRO-80 SUBTTL <text> pseudo-op.
|
|
|
|
The INTEL operands PAGE and INPAGE generate Q errors when used with the
|
|
MACRO-80 CSEG or DSEG pseudo-ops. These errors are warnings: the
|
|
assembler ignores the operands.
|
|
|
|
When MACRO-80 is entered, the default for the origin is Code Relative
|
|
0.
|
|
|
|
With the INTEL ISIS assembler, the default is Absolute 0.
|
|
|
|
With MACRO-80, the dollar sign ($) is a defined constant that indicates
|
|
the value of the location counter at the start of the statement. Other
|
|
assemblers may use a decimal point or an asterisk. Other constants are
|
|
defined by MACRO-80 to have the following values:
|
|
|
|
A-7 B-0 C-1 D-2 E-3
|
|
H-4 L-5 M-6 SP-6 PSW-6
|
|
|
|
|
|
|
|
2.12 FORMAT OF LISTINGS
|
|
|
|
On each page of a MACRO-80 listing, the first two lines have the form:
|
|
|
|
[TITLE text] M80 3.3 PAGE x[-y]
|
|
[SUBTTL text]
|
|
|
|
where:
|
|
|
|
1. TITLE text is the text supplied with the TITLE pseudo-op, if
|
|
one was given in the source program.
|
|
|
|
2. x is the major page number, which is incremented only when a
|
|
form feed is encountered in the source file. (When using
|
|
Microsoft's EDIT-80 text editor, a form feed is inserted
|
|
whenever a page mark is done.) When the symbol table is being
|
|
printed, x = S.
|
|
|
|
3. y is the minor page number, which is incremented whenever the
|
|
.PAGE pseudo-op is encountered in the source file, or
|
|
whenever the current page size has been filled.
|
|
|
|
4. SUBTTL text is the text supplied with the SUBTTL pseudo-op,
|
|
if one was given in the source program.
|
|
|
|
Next, a blank line is printed, followed by the first line of output.
|
|
|
|
A line of output on a MACRO-80 listing has the following form:
|
|
|
|
[crf#] [error] loc#m |xx | xxxx|... source
|
|
|
|
If cross reference information is being output, the first item on the
|
|
line is the cross reference number, followed by a tab.
|
|
|
|
A one-letter error code followed by a space appears next on the line,
|
|
if the line contains an error. If there is no error, a space is
|
|
printed. If there is no cross reference number, the error code column
|
|
is the first column on the listing.
|
|
|
|
The value of the location counter appears next on the line. It is a
|
|
4-digit hexadecimal number or 6-digit octal numer, depending on whether
|
|
the /O or /H switch was given in the MACRO-80 command string.
|
|
|
|
The character at the end of the location counter value is the mode
|
|
indicator. It will be one of the following symbols:
|
|
|
|
' Code Relative
|
|
" Data Relative
|
|
! COMMON Relative
|
|
<space> Absolute
|
|
* External
|
|
|
|
Next, three spaces are printed followed by the assembled code. One-byte
|
|
values are followed by a space. Two-byte values are followed by a mode
|
|
indicator. Two-byte values are printed in the opposite order the are
|
|
stored in, i.e., the high order byte is printed first. Externals are
|
|
either the offset or the value of the pointer to the next External in
|
|
the chain.
|
|
|
|
If a line of output on a MACRO-80 listing is from an INCLUDE file, the
|
|
character 'C' is printed after the assembled code on that line. If a
|
|
line of output is part of a text expansion (MACRO, REPT, IRP, IRPC) a
|
|
plus sign '+' is printed after the assembled code on that line.
|
|
|
|
The remainder of the line contains the line of source code, as it was
|
|
input.
|
|
|
|
Example:
|
|
|
|
0C49 3A A912' C+ LDA LCOUNT
|
|
|
|
'C+' indicates this line is from an INCLUDE file and part of a macro
|
|
expansion.
|
|
|
|
|
|
2.12.1 Symbol Table Listing
|
|
|
|
In the symbol table listing, all the macro names in the program are
|
|
listed alphabetically, followed by all the symbols in the program,
|
|
listed alphabetically. After each symbol, a tab is printed, followed by
|
|
the value of the symbol. If the symbol is Public, an I is printed
|
|
immediately after the value. The next character printed will be one of
|
|
the following:
|
|
|
|
U Undefined symbol.
|
|
|
|
C COMMON block name. (The "value" of the COMMON block is
|
|
its length (number of bytes) in hexadecimal or octal.)
|
|
|
|
* External symbol.
|
|
|
|
'space' Absolute value.
|
|
|
|
' Program Relative value.
|
|
|
|
" Data Relative value.
|
|
|
|
! COMMON Relative value.
|