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:
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 generatorAll 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).
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:
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".
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.
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: ENDMethod (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.
________________________________________________________________ | | | 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. | |________________________________________________________________|
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!
_____________________________________________________________ | | | 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 @@3then 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.
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:
blank - absolute ' - code relative " - data relative ! - common relative C - named common * - extern symbolAt 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.
_____________________________________________________________ | | | {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.
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.
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
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.
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 | |_____________________________________________________________|
ENTRY @OPEN BUFFER$ BYTE_POINTER WHAT? SELECT_CODE $$CORE @ CARRIAGE_RETURN @EXITA 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.
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:
_____________________________________________________________ | | | 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.
Operands may also be constructed as complicated expressions using the mathematical and logical operators. These are described in the section on "Expressions".
_____________________________________________________________ | | | 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 | |_____________________________________________________________|
001E CON30 EQU 30 0010 CON16 EQU +10H 0003 CON3 EQU 3 002E A2 EQU CON30+CON16
000E A2 EQU CON30-CON16 FFF2 A4 EQU -A2
01E0 A5 EQU CON30*CON16 BF20 A6 EQU 60000*3 ;this overflows
0002 A7 EQU 5/2 1B4D A8 EQU 48928/7
0001 A9 EQU 5.MOD.2 0005 A10 EQU 48928.MOD.7
____________________________________________________________ | | | 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
3C00 A1 EQU 3C00H&0FFH 0000 A2 EQU 0&15 0000 A3 EQU 0AAAAH.AND.5555H
3CFF A1 EQU 3C00H!0FFH 000F A2 EQU 0.OR.15 FFFF A3 EQU 0AAAAH.OR.5555H
3CF8 A1 EQU 3C07H.XOR.0FFH 0007 A2 EQU 8.XOR.15 FFFF A3 EQU 0AAAAH.XOR.5555H
FFFE T1 EQU .NOT.1 FFFF T2 EQU .NOT.0 0000 T3 EQU .NOT.-1
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
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
0000 T1 EQU 1.GE.2 FFFF T2 EQU 2.GE.2
0000 T1 EQU 1.GT.2 0000 T2 EQU 2.GT.2
FFFF T1 EQU 1.LE.2 FFFF T2 EQU 2.LE.2
FFFF T1 EQU 1.LT.2 0000 T2 EQU 2.LT.2
2340 T1 EQU 1234H.SHL.4
0123 T1 EQU 1234H.SHR.4
0012 T1 EQU .HIGH.1234H
0034 T1 EQU .LOW.1234H
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.
________________________________________________________________ | 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 | |________________________________________________________________|
_____________________________________________________________ | | | 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.
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:
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.
The following are valid declaration statements:
DB 1,2,'buckle your shoe',3,4,'close the door' DB 'This is a tes','t'!80H,CRThe 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.
_____________________________________________________________ | | | 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,0The latter is much shorter, easier to enter as text, more readable, and takes up less space in its source form.
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,
DC 100,0and 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".
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.
_____________________________________________________________ | | | 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".
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,
FCB DS 32will 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_WIDTHwill reserve a quantity of storage locations equal to the result of multiplying the two terms, TABLE_LENGTH and TABLE_WIDTH.
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:
FCB DC 32,0 TABLE DC TABLE_LENGTH * TABLE_WIDTH,0
_____________________________________________________________ | | | 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".
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.
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.
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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.
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).
_____________________________________________________________ | | | 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.
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.
_____________________________________________________________ | | | 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.
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.
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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).
_____________________________________________________________ | | | 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.
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:
--------method 1------- --------method 2------- PUBLIC TRUST TRUST LD HL,VALUE TRUST:: LD HL,VALUESymbols 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.
_____________________________________________________________ | | | 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.
An "EQU" can occur only once for any label. A multiple "EQU" with different values will result in the MULTIPLY DEFINED SYMBOL error.
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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 7000Hwill 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.
If you want to switch off the offsetting operation of LORG, add the statement:
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.
LORG is usable only when generating CMD files directly from the assembler via the -GC switch. LORG cannot be used when generating REL output.
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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.
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.
_____________________________________________________________ | | | 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 FALSEConditional 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 ENDIFis a two-level conditional. Conditional clauses can be nested to sixteen (16) levels although you will rarely find a need for more than three.
The conditional construct of IF-ELSE-ENDIF may be used. It is coded as:
IF expression clause_1. ELSE clause_2. ENDIFwhich 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.
As mentioned earlier, the IF argument can take one of three forms. The conditional structures of these are as follows:
_____________________________________________________________ | | | ---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. | |_____________________________________________________________|
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:
IFGT $,MAXADDRESS ERR Program is too long! ENDIFwhich 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.
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".
*LIST OFF IF expression *LIST ON clause *LIST OFF ENDIF *LIST ONWith 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.
_____________________________________________________________ | | | 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.is the information to be placed as a comment. | |_____________________________________________________________|
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:
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.'
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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.
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.
_____________________________________________________________ | | | 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.
_____________________________________________________________ | | | 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.
"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.
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.
_____________________________________________________________ | | | *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/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".
"*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.
_____________________________________________________________ | | | *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 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 | | 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.
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.
_____________________________________________________________ | | | *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},... | | | | 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/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.
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:
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.
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.
; Entry for routine entitled "MOVE" IFREF MOVE MOVE . ;Routine of code . ENDIF ; Entry for routine entitled "SHIFT" IFREF SHIFT SHIFT . ;Routine of code . ENDIFIf 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.
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:
LD HL,VALUE LD (MEMORY),HLHow 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 macrowe could perform the above two statements with one macro call as follows:
STOR VALUE,MEMORY ;Invoke the macroThe 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.
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.
_____________________________________________________________ | | | 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.
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:
_____________________________________________________________ | | | 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.
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.
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
_____________________________________________________________ | | | 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.
MOVBLK MACRO #FM,#TO,#LEN=255 LD HL,#FM LD DE,#TO LD BC,#LEN LDIR ENDMThis 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 ENDMThis 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 ENDMA macro is not required to contain dummy parameters as is evidenced by the last 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
ABC MACRO #PARMS,... (model statements) MOVE parm,parm ;call macro "MOVE" (model statements) ENDM MOVE MACRO #parm1,#parm2,#parm3 (model statements) ENDMis 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".
Macro definitions also may be nested. The inner macro will not be defined until the outer macro is expanded. For instance:
ABC MACRO #PARM (model statements) XYZ MACRO #PARMs,... (model statements) ENDM ENDMis a legal macro definition. The inner macro (XYZ) will not be defined until the outer macro (ABC) is invoked. Note the two ENDM statements.
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.
MOVBLK VIDEO,CRT_BUFFER,CRT_SIZEthen 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.
If you wish to omit an actual parameter in a macro call, then you must supply the comma to denote its place. For instance:
SHIFT 4200H,,100Homits the middle of three parameters. Generally, a default would have been provided in the macro definition.
_____________________________________________________________ | | | #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
SHIFT #LEN=100,BLOCK,BUF_STARTeven 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.
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 call ("%%" is described later), it would return a value of five.
FILL MACRO #CHAR,#NUM LD B,#NUM FLP LD (HL),#CHAR INC HL DJNZ FLP ENDMWe would have a problem because every time the macro was called, the label, "FLP", would be used. If "FILL" was invoked more than once, the assembler would generate MULTIPLY DEFINED SYMBOL errors on each expansion. We have to be able to use labels, but we need to find a way to be able to make "unique" labels on each macro expansion.
MRAS provides a facility for doing this by keeping a substitution string which
is changed each time a macro is expanded. The string replaces the question
mark character, "?", during a macro expansion whenever it appears outside of
single quotes in a macro model statement. Each time a macro is expanded, the
string will be changed. The string starts with the single letter "A", changes
to "B", ..., "Z", then increments to the two-letter strings, "AA", "AB", ...,
"ZZ", then to three letter strings, AAA-ZZZ each time a macro call is made. By
using the question mark as one of the characters in symbols of a macro model
statement, it will uniquely identify labels local to a macro. You may want to
standardize the way you create labels to ensure that uniqueness is maintained.
For example, you may use macro labels of the form, "$$?1", "$$?2", ... You can
repeat the use of "$$?1", "$$?2", ... in another macro since the substituted
string will be unique for each macro expansion.
The substitution string will be different from the *MOD directive substitution
but is similarly used. Macro expansion substitution of "?" takes precedence
over *MOD substitution. In the case of nested macros, each nest level will
have its own unique substitution.
By using the question mark string substitution specifier, the previous macro would be defined like this: FILL MACRO #CHAR,#NUM LD B,#NUM $$?1 LD (HL),#CHAR INC HL DJNZ $$?1 ENDM
_____________________________________________________________ | | | IFLT$ string1,string2 TRUE if string1 < string2 | | | | IFEQ$ string1,string2 TRUE if string1 = string2 | | | | IFGT$ string1,string2 TRUE if string1 > string2 | | | | IFNE$ string1,string2 TRUE if string1 <> string2 | |_____________________________________________________________|These pseudo-OPs provide TRUE/FALSE evaluation in the comparison of string1 to string2 (like the non-"$" pseudo-OPs do with mathematical expressions). Obviously, hard encoding of both string1 and string2 would be nonsense! Aha, he said... If we use a macro dummy parameter, it will be substituted by the actual parameter string passed in the macro call expansion. This means that the macro itself can test the parameter string in a limited manner. For example:
IFNE$ #TO,(DE) LD DE,#TO ENDIFas part of a macro model, will have the "#TO" replaced during the expansion. The test becomes dynamic! The dummy parameter can be either string1 or string2 - it doesn't matter.
These string conditional pseudo-OPs can only be useful in macros. That's because the evaluation, to make sense, has to be dynamic.
LD B,%#PARM ;loads B with the length of #PARM IFGT %#PARM1,6 ;Restricts parm1 to a length <1-6> ERR Parm too long! ENDIF IFLT %%,4 ;This macro requires 4 actual parms ERR Missing required parameters! ENDIFThe "%%" operator will return the number of parameters passed in the current Macro call. When a dummy parameter name (including the "#" prefix) follows the per cent operator, the length of the parameter string is returned.
These values can be tested arithmetically to produce a TRUE/FALSE result (as was just demonstrated), or they can be used directly to represent logic TRUE/FALSE conditions. Realizing that if a parameter was not passed in the parameter list of the macro call, its length would be zero. A zero is also a logical FALSE. MRAS will accept as TRUE, any non-zero value (in normal use of TRUE/FALSE specifications, "-1" is recommended for TRUE to maintain proper evaluation of the ".NOT." operation). Thus, the string lengths can be minimally used to test if the parameter was not passed (%#parm=0=FALSE) or the parameter was passed (%#parm<>0=TRUE).
IFREF #NAME%&Lwill have the "#NAME" replaced by the MACRO call substitution string appended with the letter "L".
label REPT <expression> statements ENDMIn the prototype statement, the angle brackets are not required. See the following example which generates values from 1 through n where "n" is controlled by the value passed as "#COUNT" in the DOIT invocation.
5200 00002 DOIT MACRO #COUNT 5200 00003 T DEFL 0 5200 00004 REPT #COUNT 5200 00005 T DEFL T+1 5200 00006 DB T 5200 00007 ENDM 5200 00008 ENDM 5200 00009 DOIT 3 0000+ 00010 T DEFL 0 00011 REPT 3 5200+ 00012 T DEFL T+1 5200+ 00013 DB T 5200+ 00014 ENDM 0001+ 00015 T DEFL T+1 5200+01 00016 DB T 0002+ 00017 T DEFL T+1 5201+02 00018 DB T 0003+ 00019 T DEFL T+1 5202+03 00020 DB T
label IRPC identifier,character-list statements ENDMSee the following example which generates values from 1 to 3.
00002 IRPC X,123 5200 00003 DB X 5200+ 00004 ENDM 5200+01 00005 DB 1 5201+02 00006 DB 2 5202+03 00007 DB 3
label IRP <dummy>,<arg1,arg2,...,argn> statements ENDMwhere label is an optional statement label. See the following example which generates values from 1 to 3 and makes use of the EXITM escape.
00003 LABEL IRP XX,<1,2,3,4,5> 5200 00004 LABXX DB XX 5200 00005 IFGT $-LABEL,3 5200 00006 EXITM 5200 00007 ENDIF 5200+ 00008 ENDM 5200+01 00009 LAB1 DB 1 00010 IFGT $-LABEL,3 00011 EXITM 00012 ENDIF 5201+02 00013 LAB2 DB 2 00014 IFGT $-LABEL,3 00015 EXITM 00016 ENDIF 5202+03 00017 LAB3 DB 3 00018 IFGT $-LABEL,3 00019 EXITM 00020 ENDIF
_____________________________________________________________ | | | DOS This is an operating system disk I/O error. | | The error message is displayed and control is | | returned to DOS. | | | | Assembler These errors may occur while executing an | | Assemble command. There are three types: | | terminal, fatal, and warning. | |_____________________________________________________________|Disk I/O errors can be received during an assembly. When an I/O error occurs, the assembly will be aborted and control will be returned to DOS.
Three different types of assembler errors can occur. The types relate to the severity of the error. These types are:
_____________________________________________________________ | | | Terminal Assembly is terminated and control is returned | | to command mode. | | | | Fatal Processing of the line containing the error is | | immediately stopped and no object code is | | generated for that line. Assembly proceeds | | with the next statement. | | | | Warning The error message is displayed and assembly of | | the line containing the warning continues. The | | resulting object code may not be what the | | programmer intended. | |_____________________________________________________________|Following is a list of all error messages and an explanation of each.
Any attempt to load or *GET a file that has a line longer than 128 characters
will result in "Load file format error".
If you attempt to assemble a file that is not a valid source code file, the message, "Bad parameter(s)" may be displayed.
________________________________________________________________ | | | MLINK {filespec}{,filespec}... {switch}{switch}... | | | | filespec - One or more relocatable modules to load. | | | | switch - any valid MLINK switch as follows: | | | | -A={y/N} - Specify that MLINK is to abort or not abort | | upon an error in the command processing. | | Default=N. | | | | -C=address - Specify the hexadecimal origin of the common | | blocks for succeeding modules loaded. | | | | -D=address - Specify the hexadecimal origin of the data | | segment for succeeding modules loaded. | | | | -E - Exit to DOS; Save CMD file if modules loaded. | | -E=symbol - Same as -E but use symbol as entry point. | | | | -H={y/N} - Generate 05 record header from 1st module's | | name. Default=N. | | | | -I={y/n} - Generate a core-image '/CIM' file. Default=N. | | | | -L=address - Specify the hexadecimal link origin of all | | blocks not switched by -P, -D, or -C | | | | -M - List all defined symbols (3 per line). | | -M=filespec - List defined symbols to filespec (1 per line).| | | | -N=filespec - Specify /CMD file generation. | | -N=:d - Specify /CMD file generation. Use default | | filename for filespec. | | | | -O - Handling for overlays - See overlay section. | | | | -P=address - Specify the hexadecimal origin of the program | | segment for succeeding modules loaded. | | | | -Q={wxyz} - Specify generation order of segment classes | | in the /CMD file generated [A,P,D,C]. | | -Q - Reset segment classes to link origin. | | | | -R - Reset and clear all tables. | |________________________________________________________________|
________________________________________________________________ | | | -S=filespec - Search referenced library to resolve any | | undefined globals. | | | | -U - List undefined symbols. | | | | -V=filespec - Use virtual memory file for stream buffering. | | -V=:d - ditto; filename generated is MLINK/VMF:d. | | | | -X - Equivalent to -E | | | | -Y=<text> - Used to specify the text for a 1F load module | | record (a comment record). | | | | -Z={y/N} - Generate hex zeroes for DS regions in DSEGs | | and COMMONs. This switch defaults to N. | |________________________________________________________________|
At the conclusion of processing a complete command input line, you will be
prompted via '?' to enter another command line. A <BREAK> is an
immediate exit to DOS. Command line entry uses the KEYIN handler and is thus
usable from Job Control Language.
If any error is detected in an input, it will result in an appropriate error message and any remaining input fragment(s) from that entry will be ignored. File I/O errors may result in MLINK aborting.
ddddd free space (ddddd in decimal)The segment origin address, end address, and length (all in hexadecimal) will also be listed for any segment chains loaded. Segment chains are either Program (P), Data (D), or Common (C) for segments loaded after a -P, -D, or -C switch respectively. The "Program" segment results from a CSEG or code segment. "P" is used in the linker so as to be able to differentiate from the single letter "C" used to designate the COMMON segment. All other segments loaded without a respective switch will be stored classified as being in the Link Origin chain and will be designated by the letter, "L". The format of the status will be:
awhere "a" = L, P, D, or C; "ssss" = the chain's lowest origin; "eeee" = the chain's highest load address; "llll" = the chain's length calculated from "llll=eeee-ssss+1".
The '-E' switch will also display this status prior to generation of any specified output file.
The action of the -Q switch may be restored to the default mode of module segment order by entering the -Q switch without a parameter [-Q].
If you specify the -V=filespec switch, all modules subsequently loaded will be
buffered through the virtual memory file specified. If you enter the switch
with only a drivespec as the parameter (as in -V=:d), the filename generated
will be MLINK/VMF:d. Note that the VM file is deleted during processing of the
-E switch.
If you are using virtual memory buffering and still get a "Symbol table overflow" error, attempt to reclaim any high memory used by filters, drivers, or resident programs so as to increase the size of the buffer are available to the linker. Once you have exhausted that procedure, examine the memory usage requirements of the linker and then attempt to "compact" some of the modules making up your program.
DSEGs and COMMONs, Specify "-Z=Y". All space skipped over by DS/DEFS in CSEGs
will be set to zero in the output object file.
An output file is only generated when the -E switch is invoked if the -N
switch has been specified. The -E command will first check for any multiply
defined symbols and abort the operation if at least one symbol is defined at
more than one address. Any "Request library search" requests will be first
satisfied by searching the referenced libraries. If any symbols are left
undefined, they will be displayed and the request will be aborted. The linker
will recycle to request another command. Otherwise, next, the chain external
requests will be handled. Finally, the extern+offset requests will be handled.
If $MEMRY is defined, it will be loaded with the address of the first free
byte. The loaded modules are now ready for object code generation.
If you specified "-H=y", a 05 header record will be generated using the module
name of the first file loaded. After the header record, a record type 1F will
be generated if you specified the "-Y=<text>" switch.
Note: MLINK handles the module bit stream on a segment record basis which incurs a great deal of overhead in the linker compared to a memory-fixed linker such as L-80. The method was chosen for MLINK so as to minimize the size of the resulting /CMD file. This is important for TRS-80 systems.
Each chain external requires 8 bytes of storage.
Each extern+offset requires 8 bytes of storage.
Each entry symbol requires 5 bytes of storage plus the length of the symbol.
Each request library search takes 3 bytes plus the name length.
Each -O switch takes 20 bytes.
When the -O switch is entered, MLINK will perform a fixup of the current chain of modules loaded. The fixup process will:
1) Search all libraries specified via a REQUEST assembler instruction, 2) Fix all chain externals, 3) Fix all extern+offset, 4) Prepare MLINK for a new program chain. This resets the -Y switch for the next chain (the -H switch is global). This also establishes the transfer address (entry point) for all overlays to be the next available LINK address after the root. That LINK address will be used for the overlay's entry and not a -P switched origin. It is therefore the proper procedure to not use the -P, -D, and -C switches if you want to use the overlay handling scheme of MLINK.All modules loaded after an -O switch will be partitioned into a new chain. PUBLIC symbols in one overlay chain of modules do NOT interfere with PUBLIC symbols in other overlay chains; however, they must be distinct from the ROOT. The terminating -E switch will fixup the last chain loaded and prepare for the object file generation, if requested. Prior to its generation, the linker will store the address of the first available byte following all modules into the address of $MEMRY, if defined. The file specification of the overlays will also be added to $OVLNAM if defined (this is part of the OVERLAY/REL subroutine which has been provided).
MLINK provides support for up to 35 overlays. Each overlay is automatically assigned a file specification which consists of the filename assigned by the -N switch and an extension of /OVx: x = 1,2,...,9,A,B,...,Z. MLINK provides a subroutine to automatically invoke a desired overlay. The protocol for its use is as follows:
1) Load reg_HL with any root program data, 2) Load reg_DE with a pointer to a File Control Block (This is normally a 32-byte space under all systems except TRSDOS 1.3), 3) Load reg_A with the desired overlay in ASCII (i,e, LD A,'1'), 4) Invoke the OVERLAY handler via a CALL OVERLAY assembler instruction.Note that return is not made from this overlay handler routine unless an error is detected in loading the requested overlay! However, the RETurn address to OVERLAY is in register DE at the time control is passed to the overlay. You therefore may find it useful to CALL a routine which CALLs OVERLAY. This is illustrated in the following set of programs coded for operation under TRSDOS 6:
;TESTOVER/ASM CSEG BEGIN LD HL,START$ LD A,10 ;@DSPLY line handler RST 40 LD A,'1' CALL GETOVER LD A,'2' CALL GETOVER LD A,'3' CALL GETOVER LD HL,FIN$ LD A,10 ;@DSPLY line handler RST 40 RET GETOVER LD DE,FCB CALL OVERLAY## ;OVERLAY doesn't return unless error OR 80H ;Set ABORT bit LD C,A LD A,26 ;@ERROR handler in DOS RST 40 START$ DB 'This is the root executing',13 FIN$ DB 'End of processing',13 DSEG FCB DS 32 END BEGIN ;TESTO1/ASM CSEG LD HL,MESS$ LD A,10 RST 40 RET MESS$ DB 'This is overlay 1',13 END
;TESTO2/ASM CSEG LD HL,MESS$ LD A,10 RST 40 RET MESS$ DB 'This is overlay 2',13 END
;TESTO3/ASM CSEG LD HL,MESS$ LD A,10 RST 40 RET MESS$ DB 'This is overlay 3',13 ENDThe following MLINK session will create the root and overlay /CMD files as DOOVER/CMD, DOOVER/OV1, DOOVER/OV2, and DOOVER/OV3 respectively:
mlink testover:1,overlay:2 -o,testo1:1 -o,testo2:1 -o,testo3:1 -n=doover:1 -e
From "DOS Ready", the librarian is invoked simply by entering:
_______________________________________________________ | | | MLIB (JCL,PAGE=nn) | | MLIB * | | | | JCL - is used to specify BATCH mode. | | | | PAGE=nn - specifies page length for listings and can | | range from 30-255 [make entry in decimal]. | | If PAGE is omitted, it will default to 66. | | | | * - indicates a re-entry to MLIB (see text) | | | | Abbreviations: J=JCL, P=PAGE | |_______________________________________________________|Upon successful loading and execution of MLIB, a command menu similar to the following is displayed:
_____ ________________________________________________ ___|__ |TM | | | | | MLIB 3.1L - Relocatable Object File Librarian | | Ri|cl|in| (C) Copyright 1983 Riclin Computer Products | | |__|__| | |______| | X Load library Save Library | | Add module Module map | | Purge module DOS Command | | Replace module Clear buffer | | Extract module eXit program | | Insert before module | | | | Bytes used: 0, free: 29736 | | | |____________________________________________________________|To execute a command, enter the first letter of the command (e.g. to select "<L>oad library", enter the letter <L>). The only exception to this is the "e<X>it program" command, which is selected by typing the letter <X>. Alternatively, you may find it simpler to move the blinking cursor until it is next to the desired command, and then depress <ENTER> to execute that function. This is accomplished by using either the <DOWN-ARROW> and <UP-ARROW> keys, or equivalently, the <SPACE> and <BACKSPACE> keys. The blinking cursor will reappear as a solid block next to the selected command, as a visual indication of which command is executing.
MLIB will accept either uppercase or lowercase for all keyboard input.
Whenever MLIB asks you to enter a file specification, you do not normally have
to enter an extension; it will default to either "/IRL" or "/REL", depending
on whether you request Indexed ReLocatable modules or RELocatable modules at
the "IRL or REL ?" prompt.
Key entry Key function ------------------- ----------------------------------------- <LEFT-ARROW> non-destructive backspace <RIGHT-ARROW> non-destructive forward space <SHIFT-CLEAR> erase from cursor position to end of line <SHIFT-LEFT-ARROW> restart from scratch <SHIFT-RIGHT-ARROW> move cursor to end of line <BREAK> cancel this command <ENTER> invoke your entry.If an error has occurred, MLIB will "beep" the console speaker if your machine is so equipped (on a Model I/III computer, a short beep tone will be directed to the cassette port which can be audible if you have an audio amplifier and speaker hooked up). An error message will appear at the bottom of the screen, and will remain there until you enter any keystroke, indicating that you have acknowledged the error.
Listing to printer (Y,N) ?You can print a module map, if desired, by responding <Y>. Printed output is paginated at a page length of 66 lines unless changed by use of the PAGE command line parameter. In either interactive or batch mode, <BREAK> will cancel a printout at any time.
In interactive mode, with certain exceptions, MLIB will prompt you to set your
printer to the top of a page - do so and then depress any keystroke to
continue. If you are running MLIB under LDOS, you can use the system spooler,
or you can have printer output routed to a file. In either case, output will
begin with a form feed, and there will be no prompt for top-of-form.
In batch mode, the module map will always go to the printer, and will begin
with an automatic form feed and no prompt for top-of-form.
The detailed format option is available in both interactive and batch modes. The attributes of each module are displayed as shown in the following illustration:
____________________________________________________________ | | | Module name Module size Program size Data area size | | DSKDRV 1417 996 76 | | | | Entries: $FLBUF $FLCNT $FLFCB $FLFLG $GTFCB $GTFLG | | 0000" 0014" 0032" 0028" 0024" 0018" | | $MEMRY DSKDRV OPEN | | 0048" 000A' 033C' | | | | Externals: $BF $BL $CLSFL $ERR $IOERR $IOINI | | $LUNTB $REC $UN | | | | Commons: | | | | Hit <ENTER> for next screen, Hit <BREAK> to exit | |____________________________________________________________|
{space} absolute segment ' program relative (code) segment " data relative segment ! COMMON area
The summary format option lists all modules, by name only, in the order they exist in memory (from left to right, top to bottom, on the CRT screen). Summary format is available only in interactive mode and would look like:
____________________________________________________________ | | | RAN INT4 DSQRT DMOD DSIGN DABS DATAN2 | | DATAN DLOG10 DCOS DSIN DBLEXP DEXP DLOG | | DMIN1 DMAX1 DCOMP DBLDIV DBLFLR DBLPLY DBLUTL | | DMLDV DSHR DBLCON MFM AMIN0 MIN0 AMAX0 | | TANH SQRT MIN1 MAX1 MAX0 IFIX FLOAT | | EXP DIM COSIN ATAN2 ATAN AMOD AMIN1 | | AMAX1 AINT ABS ALOG10 ALOG MOD RIEXP | | NEGF RREXP NEG NEG EXPB LOG2 POLY | | FADD IIEXP FDIV STOP FMUL ADE FLR | | FCP FLT CMPGTO IDIV SIGN RAT DAT | | ISIGN IABS NEGATE XAR IDIM FAT2 IMUL | | POKE UNPACK PSPLAC ICP FORMIO NORM SHIFT | | RNDOVF ZAC IOINIT LUNTB IAT2 LODSTR SAF | | | | Hitfor next screen, Hit to exit | |____________________________________________________________|
_______________________________________________________ | | | MLIB (JCL,PAGE=nn) | | | | JCL - specifies BATCH mode. | | | | PAGE=nn - as shown earlier. | | | | Abbreviations: J=JCL, P=PAGE | |_______________________________________________________|In batch mode, MLIB will take its commands from a batch file, whose extension is usually '/JCL'. Under some systems, the extension may be '/BLD'.
MLIB will request each command with the prompt "Enter option:". The valid
responses to this prompt are: Add, Clear, Extract, Insert, Load, Map, Purge,
Replace, Save, or Xit. Only the first letter of each command is significant;
the remaining letters are ignored and may be left out of the command line.
Command lines may also be commented. Each command line must be terminated with
a carriage return.
The "Clear buffer" and "eXit program" commands will do just that, with no
opportunity to abort.
Batch command Comment ------------- -------------------------------- mlib (jcl) execute MLIB in batch mode load load a library... irl designate an "IRL" funcs2 this one is FUNCS2/REL add add a new module... rel designate a "REL" shelsort SHELSORT/REL replace replace a module... index module name is INDEX rel designate a "REL" index replace it with INDEX/REL save save the new version of... irl designate an "IRL" funcs2 FUNCS2/REL xit and exit to DOS
____________________________________________________________ | | | SAID [filespec] (parm1,parm2,...) | | | | SAID * Used to re-enter SAID immediately after | | exiting so as to reclaim the text buffers. | | | | filespec The name of the file to edit. If filespec is | | not found, SAID prompts to create it. | | Command line filespec entry is optional. | | | | ASM Tabs default to 8. File extension defaults | | to "/ASM". X'1A' stripped from end of file | | on read and replaced on write. | | | | CCC Tabs default to 4. File extension defaults | | to "/CCC". X'1A' stripped from end of file | | on read and replaced on write. | | | | EXT=string Sets the default file extension. | | | | TAB=nn Set default tab width. | | | | Abbreviations: A=ASM, C=CCC, E=EXT, T=TAB | | | | Note: EXT parameter not usable under TRSDOS 1.3 and 2.3. | | TRSDOS 1.3 users must enter ASM and CCC parms as | | parm=0FFFF and TAB entry in hexadecimal, 0xx. | |____________________________________________________________|Unless altered by SAIDINS, SAID command functions are invoked with the keyboard depressions as shown in the SAID menu. In the following text, multiple key depressions are shown as connected sequences of keys within angle brackets, i.e. <CLEAR><4> means simultaneously depress the <CLEAR> key and the <4> key.
--------+-------+-------+-------+-------+-------+-------+-------+-------+------- Srch Repl Again All Rev Hex Quote Copy Move Cmd Print Exit ==1== ==2== ==3== ==4== ==5== ==6== ==7== ==8== ==9== ==0== ==:== ==-== Ins Line Del Word Block Load Save Macro File Meta Pg Dn Pg Up File:aaaaaaaaaaaaaa Len:bbbbb/ccccc Ln:ddddd Col:ee = x'ff' ggg% Banks: hhhhhhh Srch:iiiiiiiiiiiiiiiiii Repl:jjjjjjjjjjjjjjjjjj Dir:kkk Cnt:lll "Messages and prompts..." SAID Version 1.1The top line will be a rule of dashes with a plus sign "+" denoting each TAB stop as established by either the default tabbing for the file type [ASM=8, CCC=4] or that set via the TAB parameter.
The next three-line menu is optional. Its display mode is established when
SAID is invoked by the MENU setting during the SAIDINS installation. The META
command also permits you to toggle the display of this menu. It is recommended
that you keep the menu displayed until you get proficient at using SAID's
editing commands. The menu displays the command function activated when the
key identified by the second line is pressed simultaneously with the
<CLEAR> key. The first line designates shifted keys and the third line
designates unshifted keys.
The next line contains a great deal of information. The file specification of
the file currently being edited in the context buffer is identified by
"aaaaaaaaaaaaaa". The current length of the text is shown as "bbbbb" while the
total length of the editing buffer is shown as "ccccc". SAID keeps track of a
logical line number for the text. For line numbering purposes, a line is
considered to be all characters up to and including a carriage return. The
number of the line to which the cursor is positioned to is shown as "ddddd".
The video column number to which the cursor is positioned is shown as "ee".
This value will range from column 00 to column 79 (63 in the case of a 64
column screen). The character which the cursor is positioned over has its
value shown in hexadecimal as "ff". This value is useful for determining the
text character for undisplayable character values. SAID also keeps a ratio of
where the cursor is positioned relative to the end of the text. This is shown
as a percentage by the "ggg" value. It is accurate only when the text exceeds
99 characters.
The last field of the status line shows the availability of editing buffers as
"hhhhhhh". When SAID is invoked under those systems supporting banked
switching, SAID scans for the availability of up to seven editing buffers.
SAID will display a dash for each buffer that is available. These are selected
by you with the assignments 1, 2, 3, ..., 7. Anytime that you have entered
text into one of these buffers, its corresponding dash will be changed to a
plus sign.
The next line of status shows the current search string: "iiiiii..."; the
current replacement string: "jjjjjj..."; the search direction, "kkk":
"For=forward", "Rev=reverse"; and the macro repeat count: "lll".
The last line will be used to display prompting messages or error messages on an as required basis.
Left one position <LEFT ARROW> Right one position <RIGHT ARROW> Up one line <UP ARROW> Down one line <DOWN ARROW> Beginning of next word <CLEAR><4> Next Screen Page <CLEAR><-> Previous Screen Page <CLEAR><:> Start of line <SHIFT><LEFT ARROW> End of line <SHIFT><RIGHT ARROW> Start of file <CLEAR><UP ARROW> End of file <CLEAR><DOWN ARROW> Insert a tab <CLEAR><RIGHT ARROW>
Insert/overtype mode <CLEAR><1> Line insert <CLEAR><2> - <Break> to cancel Hex insert <CLEAR><SHIFT><6> - <Break> to cancel Quote insert <CLEAR><SHIFT><7> - <Break> to cancel
Delete character <CLEAR><3>. Delete word <CLEAR><3> followed by <CLEAR><4> or just <CLEAR><4> if in delete mode. Delete line <CLEAR><3> followed by <CLEAR><2> or just <CLEAR><2> if in delete mode. Delete block Mark the block, position cursor inside, then <CLEAR><3> followed by <CLEAR><5> Delete to top <CLEAR><3> followed by <CLEAR><UP ARROW> or just <CLEAR><UP ARROW> if in delete mode. Delete to end <CLEAR><3> followed by <CLEAR><DOWN ARROW> or just <CLEAR><DNARW> if in delete mode. Delete all <CLEAR><3> followed by <CLEAR><SHIFT><4>. Deletes entire context except macro. Undelete [oops function] <CLEAR><SHIFT><5> followed by <CLEAR><3> which is "reverse" followed by "delete".
Invoke current macro <CLEAR><8> Store a macro <CLEAR><6> followed by <CLEAR><8>; The Macro will be saved until the next <CLEAR><8> or until 64 characters are entered.
Print a block Mark block, then <CLEAR><SHIFT><:>, followed by <CLEAR><5> followed by <0-9> Print a file [in memory] <CLEAR><SHIFT><:> followed by <CLEAR><9> Load file at cursor position <CLEAR><6> followed by <CLEAR><9> then the filespec in response to the prompt. Save file under current name <CLEAR><7> followed by <CLEAR><9> Save block Mark block, then <CLEAR><7> followed by <CLEAR><5> followed by filespec, then <0-9>. Exit <CLEAR><SHIFT><-> Change filespec <CLEAR><9> followed by the filespec.
Block start <CLEAR><5> followed by <0-9> Block end <CLEAR><5> followed by <CLEAR><DOWN ARROW> or <CLEAR><5> followed by <E>. Copy block Mark block, position to destination, then <CLEAR><SHIFT><8> followed by <0-9>. Note that this command duplicates the contents of the block at the new position. The marked block is retained in its marked position. Move block Mark block, position to destination, then <CLEAR><SHIFT><9> followed by <0-9>. Note that this command deletes the marked block after inserting the block text into the designated position. Unmark all blocks <CLEAR><SHIFT><5> followed by <CLEAR><5>. Use before saving assembler source.
Search <CLEAR><SHIFT><1> followed by the string. Reverse search <CLEAR><SHIFT><5> followed by <CLEAR><SHIFT><1> followed by the search string. Replace Invoke a SEARCH, then <CLEAR><SHIFT><2> followed by the replacement string. Again <CLEAR><SHIFT><3> All <CLEAR><SHIFT><4>
C Calculator E External memory [TRSDOS 6.x version only] S swap memory bank and full context C copy a block from an external memory bank G Go to the start of a line via its line number H Toggle the help display M Set macro repeat count O Set SAID options A set ASM mode in current buffer C set CCC mode in current buffer T set default extension in current buffer R Replace options: query before replace T Set tabs position (i.e. every nth column) 7 Strip bit 7 off all text in buffer <UP ARROW> Uppercase next word <DOWN ARROW> Lowercase next word
xxxxB - Binary (i.e. 101101) xxxxD - Decimal (default, i.e. 45) xxxxH - Hexadecimal (i.e. 2d)The following functions are supported:
* Multiplication / Division + Addition - Subtraction (negation is not supported) & Logical AND | Logical OR ^ Logical XOR . Used to denote the previous resultIf you wish to output the answer in any base other than decimal then follow the '=' with a 'B' or an 'H' to specify binary or hexadecimal. Entering a period will cause the last result to be substituted. Note the following sample calculation which multiplies 22 base 16 by 1111 base 2, then adds 2 base 10 and outputs the result in decimal:
22h 1111b * 2 +To output the same result in binary, specify ". =b".
SAIDINS filespecwhere "filespec" should be SAID/CMD - the name of the screen editor - unless you renamed SAID/CMD to some other name. SAID is supplied to support all of the SAID functions mapped to the keyboard, with the exceptions of functions 34, 35, and 36. This mapping can be tailored to your specifications during the installation of SAID while SAIDINS/CMD is running. This installation program must be used first to establish certain DOS interfacing needed before SAID can be used. The following function codes are used during the installation of SAID. They designate the function numbers corresponding to the thirty-six separate command functions in SAID.
1 Cursor left 19 Meta 2 Cursor right 20 Previous Page 3 Cursor up 21 Next Page 4 Cursor down 22 Find 5 Beginning of line 23 Replace 6 End of line 24 Again 7 Top of file 25 All 8 End of file 26 Unmark 9 Insert a tab 27 Hex 10 Insert mode toggle 28 Quote 11 Line 29 Copy block 12 Delete 30 Move block 13 Word 31 DOS command 14 Block 32 Print 15 Load 33 Exit 16 Save 34 Delete previous character 17 Macro 35 Swap buffer with external buffer # 1 18 File 36 Swap buffer with external buffer # 2The TRSDOS 6.x version of SAID uses the DOS keyboard driver and makes use of the type-ahead supported by the DOS. The Model I/III version of SAID contains a built in keyboard driver which supports type-ahead as well as a complete ASCII keyboard. The installation program can be used to override this built-in keyboard driver. For LDOS users who are using the DOS KI/DVR, you must either override the SAID driver or not use the LDOS KI/DVR (meaning that type-ahead must be off). The Model I/III keyboard driver uses various key combinations to produce the extra characters not available on the TRS-80 keyboard. These are as follows:
<CLEAR>, plus: <CLEAR><SHIFT>, plus: <,> [ (left bracket) <,> { (left brace) </> \ (reverse slash) </> | (vertical bar) <.> ] (right bracket) <.> } (right brace) <;> ^ (carat) <;> (tilde) <ENTER> _ (underline) <ENTER> (delete) <SHIFT><DOWN ARROW> (control - use with A-Z)
_____________________________________________________________ | | | XREF filespec/REF {(LEN=val,PAGE=val,LINES=val,EQU,LIMIT)} | | | | filespec is the specification of the reference data | | file generated by the -XR switch of MRAS. If | | the file extension is omitted, "REF" is used. | | | | LEN is the length of your print line (the default | | value is 80). | | | | PAGE is the maximum number of lines per page (the | | default is 66 for Mod I, 67 for Mod III). | | | | LINES is the number of lines to print on a page (the | | default is 56 for Mod I, 57 for Mod III). | | | | EQU is used to generate a file of EQUates instead | | of the cross reference listing. | | | | LIMIT is used to limit the file of EQUates to those | | symbols containing a special character. | | | | Note: the format of "value" is PARM=ddd or PARM=X'hhhh'. | | | | PAGE is not supported under TRSDOS 6.x | | | | There are no parameter abbreviations. | |_____________________________________________________________|The XREF/CMD utility generates a symbolic cross-reference listing which includes a sorted list of all defined labels, the file of origin of the definition, the line number of the definition, the value of the definition, and the line numbers of all statements referencing the label. XREF will also identify the filename of the file containing the references. XREF will not identify unresolved labels. Therefore, make sure that either all labels are resolved during the assembly that generates the XREF data file, or you do not need the line numbers of those unresolved references appearing in the cross reference listing.
XREF can also be used to generate an assembler source file of EQUates of all
symbols used in the program being assembled or a subset of all symbols used.
The LIMIT parameter is used to limit the EQUates to only those symbols having
at least one special character in the symbol name.
XREF uses, as input, the reference data file which is optionally generated by
the -XR switch during the LISTING pass of MRAS (phase 2). XREF cannot function
without this data file. You need not enter the file extension, /REF, as it
will be assumed if omitted.
The XREF command line parameters enclosed in parentheses are entirely optional. The may be used as follows:
XREF (LEN=132)
XREF filespec (PAGE=51,LINES=41)will set the page length to 51 lines per page and initialize to print 41 lines.
The listing will contain a heading on each page composed of the system DATE and TIME, the TITLE pseudo-op text, and a page number. The heading needs a minimum of 74 columns. Thus, you should not specify a LEN parameter of less than 74. The reference columns will include:
Avoid writing modules with multiple entry points. Modules written in this way
can often lead to confusion and inefficient programming.
Library sizes are absolutely limited by the size of MLIB's memory buffer. In
practice, however, a smaller library size of about 10K bytes is most useful
for three reasons: (a) MLINK library searches will take less time; (b) the
library will fit into MLIB's buffer even if you have a lot of things in high
memory; (c) you will have some room for library growth.
Build special purpose libraries (e.g. communications, graphics, string
processing, disk I/O).
Use MRAS's CSEG (code segment), DSEG (data segment), and COMMON pseudo-OPs
only! DO NOT use ASEG (absolute segment), as this produces object code which
is not relocatable and thus not usable in a general purpose library.
Libraries of related routines must be constructed in a particular order. This
order is determined by each module's external references. If, for instance,
module A references module B, then module B MUST FOLLOW module A in the
library. Otherwise, a backward reference will occur, and MLINK may force you
to search the library TWICE in order to satisfy the reference. If the library
is constructed as an IRL, MLINK will perform multiple searches automatically;
however, minimum processing time will occur in searching an IRL when no
external reference is to be resolved by a module which is stored before the
module having the extern.
You may encounter a problem if you try to use MLIB on libraries not created
with MLIB. This is because the end-of-file marker in these files may not match
the EOF in the directory. There is a simple solution: create a text file using
SAID which contains a single character of value 9EH; append this file to the
problem file; load the /REL file into MLIB, and immediately resave it. This
caveat also applies to any /REL files constructed under CP/M which have been
transferred over to your system.
Let's look at an example of absolute assembly. The following program has been assembled at an ORIGIN of 0100H. Notice especially the values assigned to the memory addresses @DATE, @EXIT, @DSPLY, START, and BUFFER:
0100 00100 ORG 0100H 4470 00110 @DATE EQU 4470H 402D 00120 @EXIT EQU 402DH 4467 00130 @DSPLY EQU 4467H 000D 00140 CR EQU 0DH 0100 211401 00150 START: LD HL,BUFFER 0103 CD7044 00160 CALL @DATE 0106 3E0D 00170 LD A,CR 0108 321C01 00180 LD (BUFFER+8),A 010B 211401 00190 LD HL,BUFFER 010E CD6744 00200 CALL @DSPLY 0111 C32D40 00210 JP @EXIT 0114 00220 BUFFER: DS 9 0100 00230 END START @DATE 4470 @DSPLY 4467 @EXIT 402D BUFFER 0114 CR 000D START 0100The program has been reassembled below at a new origin, 0200H. Some of the addresses for the above labels have changed, while some remain the same:
0200 00100 ORG 0200H 4470 00110 @DATE EQU 4470H 402D 00120 @EXIT EQU 402DH 4467 00130 @DSPLY EQU 4467H 000D 00140 CR EQU 0DH 0200 211402 00150 START: LD HL,BUFFER 0203 CD7044 00160 CALL @DATE 0206 3E0D 00170 LD A,CR 0208 321C02 00180 LD (BUFFER+8),A 020B 211402 00190 LD HL,BUFFER 020E CD6744 00200 CALL @DSPLY 0211 C32D40 00210 JP @EXIT 0214 00220 BUFFER: DS 9 0200 00230 END START @DATE 4470 @DSPLY 4467 @EXIT 402D BUFFER 0214 CR 000D START 0200To be specific, START and BUFFER have changed, while the others are unchanged. Both START and BUFFER have been relocated! START, instead of being at 0100H is now at 0200H, and BUFFER has moved from 0114H to 0214H. This offset of 0100H is due to the changed origin, 0100H versus 0200H. START and BUFFER are therefore internally relocatable values, while @DATE, for example, will always be 4470H, and is thus known as an absolute value.
The same program, as assembled using relocation looks like this:
4470 @DATE EQU 4470H 402D @EXIT EQU 402DH 4467 @DSPLY EQU 4467H 000D CR EQU 0DH 0000' 21 0014' START: LD HL,BUFFER 0003' CD 4470 CALL @DATE 0006' 3E 0D LD A,CR 0008' 32 001C' LD (BUFFER+8),A 000B' 21 0014' LD HL,BUFFER 000E' CD 4467 CALL @DSPLY 0011' C3 402D JP @EXIT 0014' BUFFER: DS 9 END START @DATE 4470 @DSPLY 4467 @EXIT 402D BUFFER 0014' CR 000D START 0000'All of the internal program addresses have been assembled as if the program had an origin of 0000H, and are noted with a following single-quote ('). This is relocation at work. The binary output of this assembly (a /REL file) cannot be executed by the Z80 until you choose an origin for the program; this is done by the MISOSYS linker, MLINK), and can be ANY address in the Z80 memory space. MLINK will determine, from the origin you have selected, where START and BUFFER really will be when the program is run. If you choose 0100H as the origin, then START will be located at 0100H, and BUFFER at 0114H. Other origins will produce similar results; START and BUFFER will be at different addresses, but the offset between them (0014H) will always be the same.
This characteristic of relocatable object files, that they can be LINKED at
any origin, is extended by a further capability: relocatable object files may
be linked TOGETHER to form a complete program from many smaller pieces. This
allows you to write a very large program in lesser chunks which are easier to
edit and to understand. In addition, you can develop libraries of standard and
useful subroutines, each thoroughly tested and debugged, which any main
program may call upon when necessary. The Microsoft FORTRAN library
(FORLIB/REL), for example, thus contains many subroutines which can be used by
any FORTRAN or Z80 assembler program.
The mechanism of program and subroutine linkage that is often used is implemented by the ENTRY and EXTERNAL attributes. A label which is declared ENTRY (or GLOBAL or PUBLIC) in one module can be accessed by another module in the following way:
;Module 1 ENTRY LABEL1 ;this is an entry point LABEL1: {code follows} END ;end of module 1 ;Module 2 EXTRN LABEL1 ;this is an EXTERNAL declaration ;could also be EXT. CALL LABEL1 ;and this is a reference to the ;external END ;end of module 2The relocatable format also allows you to do other things. In many applications, program code and data areas must be separated. This most often occurs when code must be placed in ROM, such as the BASIC interpreter in a TRS-80. However, the data areas cannot be in ROM; they must be in writeable memory (RAM), and thus must be separated from the code areas. This can be accomplished by use of the CSEG and DSEG commands to the MRAS assembler. A CSEG pseudo-operation signals the start of a code area, while a DSEG indicates the start of a data area. Code and data SEGMENTS may be intermixed in a program source file, and the assembler will automatically keep them separate by the use of two distinct program or location counters, one for each segment. When you link the program with MLINK, you may tell the linker at what address to place the code, and also where to place the data. Thus the two segments are separated. The above example is shown below using this technique:
4470 @DATE EQU 4470H 402D @EXIT EQU 402DH 4467 @DSPLY EQU 4467H 000D CR EQU 0DH 0000' CSEG ;code starts here 0000' 21 0000" START: LD HL,BUFFER 0003' CD 4470 CALL @DATE 0006' 3E 0D LD A,CR 0008' 32 0008" LD (BUFFER+8),A 000B' 21 0000" LD HL,BUFFER 000E' CD 4467 CALL @DSPLY 0011' C3 402D JP @EXIT DSEG ;data starts here 0000" BUFFER: DS 9 END START @DATE 4470 @DSPLY 4467 @EXIT 402D BUFFER 0000" CR 000D START 0000'Notice how the label BUFFER is now located at 0000H, but in the data segment, as indicated by the double-quote (") following the address. Am MLINK session could then be as follows with user entries in BOLDFACE:
DOS Ready MLINK MLINK - Ver 1.0a Copyright 1985 MISOSYS, Inc., All rights reserved ?-p=100 ?-d=1000 ?test 27937 Free space P <0100-0113 0014> D <1000-1008 0009> *test-n-e DOS ReadyThe -p command to the linker established the program (or code) segment origin, while the -d command did the same for the data segment. After loading TEST/REL with the next command, the linker then tells us where the two segments are located and how long they are. The final command writes out an executable command file (/CMD). If we were to disassemble TEST/CMD, we would find that START is located at 0100H and BUFFER at 1000H. Thus the program is separated into ROM and RAM sections.
MLINK has other capabilities, such as the use of COMMON blocks, which are
explained in sections on MRAS and MLINK. MRAS can also generate absolute code,
if you use the ASEG command.
NAME ('TEST') 4470 @DATE EQU 4470H 402D @EXIT EQU 402DH 4467 @DSPLY EQU 4467H 000D CR EQU 0DH CSEG ;code starts here ENTRY START EXT MESSAGE 0000' 21 0000" START: LD HL,BUFFER 0003' CD 4470 CALL @DATE 0006' 3E 0D LD A,CR 0008' 32 0008" LD (BUFFER+8),A 000B' 21 0000" LD HL,BUFFER 000E' 11 0000* LD DE,MESSAGE 0011' 01 0009 LD BC,BUFFLEN 0014' ED B0 LDIR 0016' 21 0000* LD HL,MESSAGE 0019' CD 4467 CALL @DSPLY 001C' C3 402D JP @EXIT DSEG ;data starts here ENTRY BUFFER 0000" BUFFER: DS 9 0009 BUFFLEN EQU $-BUFFER END START @DATE 4470 @DSPLY 4467 @EXIT 402D BUFFER 0000" BUFFLEN 0009 CR 000D MESSAGE 0017* START 0000'Notice how the external label, MESSAGE, is defined in the symbol table; the value 0017H represents the relative location of the LAST reference to MESSAGE in the assembled code, and the trailing asterisk (*) denotes an external symbol both in this table and in the assembled code listing.
The following is a tabular picture of the decoded /REL file. Each column represents:
(1) Absolute [0] or relocatable [1] item [1 bit]. If absolute, column (2) shows the value in hex [8 bits]. (2) Relocation type [0 = special link item; 1, 2, or 3 = segment relative] [2 bits]. See column (8). (3) Special link item control field in decimal [4 bits]. See column (8). (4) "A-field" address type, same as column (2) [2 bits]. (5) "A-field" value, displayed as high/low, but reversed in file [16 bits]. (6) "B-field" length [3 bits]. (7) "B-field" symbol in ASCII [8 bits each character]. (8) Description of the object file record as decoded. (1) (2) (3) (4) (5) (6) (7) (8) --- --- --- --- ------ -- ------- ----------------------------------- 1 0 2 4 TEST program name 1 0 0 5 START entry symbol for library search 1 0 0 6 BUFFER entry symbol for library search 1 0 10 0 00 09 define data area size 1 0 13 1 00 1F define program size 1 0 11 1 00 00 set loading location counter (code) 0 21 absolute (1st byte in code segment) 1 2 00 00 data relative (ref. to BUFFER) 0 CD absolute 0 70 absolute 0 44 absolute 0 3E absolute 0 0D absolute 0 32 absolute 1 2 00 08 data relative (ref. to BUFFER+8) 0 21 absolute 1 2 00 00 data relative (ref. to BUFFER) 0 11 absolute (ref. to MESSAGE follows) 0 00 absolute (this plus next byte are 0 00 absolute end of external chain) 0 01 absolute 0 09 absolute 0 00 absolute 0 ED absolute 0 B0 absolute 0 21 absolute (ref. to MESSAGE follows) 1 1 00 0F program relative (link in chain) 0 CD absolute 0 67 absolute
0 44 absolute 0 C3 absolute 0 2D absolute 0 40 absolute 1 0 11 2 00 00 set loading location counter (data) 1 0 11 2 00 09 set loading location counter (data) 1 0 7 2 00 00 6 BUFFER define entry point (data) 1 0 6 1 00 17 7 MESSAGE chain external (head of list) 1 0 7 1 00 00 5 START define entry point (code) 1 0 14 1 00 00 end program (force to next byte) 1 0 15 end file marker
1) IF the next bit is a zero, THEN the following eight bits are loaded
according to the value of the location counter currently in effect, THEN
recycle to 1).
ELSE IF the next bit is a one, THEN the next two bits represent a code which is interpreted as follows:
01 - indicates a code relative value follows. The next 16 bits are loaded after being offset by the code segment origin, THEN recycle to 1). 10 - indicates a data relative value follows. The next 16 bits are loaded after being offset by the data segment origin, THEN recycle to 1). 11 - indicates a common relative value follows. The next 16 bits are loaded after being offset by the selected common segment origin, THEN recycle to 1). 00 - Indicates a Special Link item. The SL item consists of the following four bits which are interpreted as one of 16 different items described below; an optional VALUE field which consists of a 2-bit address type [00 = absolute, 01 = code relative, 10 = data relative, 11 = common relative] and a 16-bit address; and an optional NAME field that consists of a 3-bit name length followed by the name in 8-bit bytes. SLs 0000-0100 use only a NAME field; SLs 0101-1000 use both a VALUE field and a NAME field; SLs 1001-1110 use only a VALUE field; SL 1111 has neither a NAME nor a VALUE field. Unless otherwise specified, at the conclusion of processing a special link item, processing recycles to 1). The Special Link items are as follows:
0000 - indicates an entry symbol. This is used by the linker only when searching a library to see if the module is needed to satisfy an undefined extern. 0001 - Select Common Block. Used to specify the NAMEd Common Block for subsequent common relative references. 0010 - Module name. This is the name of the module. The first one encountered is saved by MLINK for use in generating the optional HEADER record of the /CMD file. 0011 - Request Library Search. The library designated by the NAME field will be searched to resolve undefined externals prior to any object code generation. An REL will be first assumed. If one is not found, an IRL will then be assumed. 0100 - This item is not supported by MLINK. 0101 - Define Common Size. This is used by MLINK to establish the size of the common block designated by the NAME field. 0110 - Chain External. The VALUE field contains a pointer to the head of a chain which ends with an absolute zero. Each 16-bit element of the chain will be replaced with the value of the external symbol described in the NAME field. 0111 - Define Entry Point. The VALUE field specifies the value of the symbol described by the NAME field. 1000 - This item is not supported by MLINK. 1001 - External plus Offset. This specifies that the VALUE field must be added to the following two bytes in the current segment after all chain externals have been processed. 1010 - Define Data Size. The VALUE field is used by MLINK to establish the size of the data segment of the current module. 1011 - Set Location Counter. The location counter is set to the value identified by the VALUE field. 1100 - This item is not supported by MLINK. 1101 - Define Code Size. The VALUE field is used by MLINK to establish the size of the code segment of the current module. 1110 - End of Module. The VALUE field defines the transfer address for the module if other than absolute zero. This item denotes the end of the module. The bit stream is also advanced to a byte boundary. Recycle to 1) if loading a module from other than a library search. 1111 - End of File. This is used to indicate the end of the file. It is used when searching libraries or when loading modules to detect the end of the file.