From e53d997c93907a3064f8cd75808b58b48e295f89 Mon Sep 17 00:00:00 2001 From: Adam Sampson Date: Sun, 30 Aug 2020 17:52:44 +0100 Subject: [PATCH] Remove MIDAS; MIDAS MACRO. This is a slightly older copy of INFO; MIDAS >. The differences in the newer version all look like improvements. --- doc/midas/midas.macro | 4398 ----------------------------------------- 1 file changed, 4398 deletions(-) delete mode 100755 doc/midas/midas.macro diff --git a/doc/midas/midas.macro b/doc/midas/midas.macro deleted file mode 100755 index 2af03d6b..00000000 --- a/doc/midas/midas.macro +++ /dev/null @@ -1,4398 +0,0 @@ --*-Text-*- - -MIDAS Node: Top, Up: (DIR), Next: Invoke - -Overview of MIDAS - - MIDAS is a PDP-10 assembler. It takes as its input an ASCII file, -and produces a binary file in any of several formats (*Note Out: Output.) - -NOTE: Numbers used in this document are assumed to be octal, unless -followed by a "." in which case they are decimal. E.G. 12 = 10. = ten. - -* Menu: - -* Invoke:: How to invoke MIDAS. Commands strings. -* Switches:: MIDAS command string switches. -* Interrupts:: Terminal Interrupt Characters. -* Basic:: Introduction to MIDAS input syntax. -* Example:: Simple example of MIDAS code. -* Frame:: The beginning and end of a MIDAS program. -* Words:: Syntax of the "Word" -- the fundamental MIDAS construct. -* Fields:: Words are made up of fields, which are made of syllables. -* Syllables:: A syllable is a number, symbol, etc. -* LocnCtr:: The "location counter" is used to assign storage locations - to the words which MIDAS assembled. -* Output:: Output formats. -* Relocation:: Relocatable assemblies. -* Symbols:: Defining symbols. -* DDT:: Communicating to DDT. -* Numbers:: Hairy ways of writing numbers. -* LIterals:: Generating constants in memory where you want to use them. -* BYtes:: Pseudos for working with bytes and byte pointers. -* FIleinfo:: How filenames can be accessed at assembly time. -* Terminal:: Typing on the terminal. Reading from the terminal. -* Macros:: MIDAS macros: definition and use. -* LOOps:: Assembly-time iterations for use with macros. -* Cond:: Assembly conditionals. -* Arithmetic:: .I and .F: the "arithmetic assignment" statements. -* FASL:: Assembling code to be loaded by MacLisp. -* Blocks:: Symbol table block structure. -* Constructs:: Alphabetical index of constructs (special characters). -* Pseudos:: Alphabetical index of pseudo-ops. -* LIB: (LIB) The subroutine libraries for MIDAS programs. -* Outformats:: More obscure details about output formats (RIM, etc) -* Changes: (MIDAS ARCHIV)* MIDAS changes in chronological order. - - -MIDAS Node: Invoke, Up: Top, Previous: Top, Next: Switches - -MIDAS Command Strings - - Once you have run the program MIDAS, it will ask for a command line -on which you must specify the names of the input and output files. In -addition to the filenames, the command line usually contains switches. -*Note Switches: Switches. - - MIDAS can write four output files for each assembly: a binary -output file, an error file containing whatever would normally appear on the -terminal, a listing file, and a cross-reference table file. The -cross-reference table file (a compact binary file, not a DEC cref listing) -is not really useful now that the @ program exists (*Note @: (@)Top.). -The listing output file is also inferior to an @ listing, but it is -sometimes useful for debugging hairy macros. To facilitate this use, it is -possible to ask for a listing of both passes (some macros cause fatal -errors on the first pass). The binary output file is essential; an error -output file is also very useful as a permanent record of the assembly -errors. - - Normally, one specifies either just the input file or the input -file and the binary output file. The error output file name is allowed to -default from them. MIDAS tries hard to default all filename components so -as to minimize your type-in. Not specifying the binary file name is -equivalent to letting each component of the name default based on the input -file name. - - Defaulting in MIDAS works bidirectionally; the input file name can -default from the binary file name, and the binary file name can default -from the input file name. This is actually useful. Note how the Twenex -GTJFN-from-the-terminal scheme of things cannot provide this! - - The binary file's device defaults to DSK. The directory defaults -to your working directory. The second filename defaults based on the type -of output format used: BIN for SBLK files, FASL for FASL output files, or -REL for relocatable output files. The first filename defaults to the input -files's first filename. One exception: if TTY: is specified as the input -file, and the binary file name is not specified, no binary file is made. - - The input file's device and directory default to those of the -binary file. The second filename defaults to ">" for ITS and "MID" on DEC -systems. The first filename defaults to that of the binary file. If -no first filename is specified for either file, the default is "PROG". -This becomes relevant sometimes when TTY: is specified as the input device. -Exception: if the binary file was on device PTP or NUL, the default is DSK. - - These defaulting rules make common things very convenient. -To assemble a file FOO;BAR > onto the same directory, you can use - - FOO;BAR_ - -letting the input file names default. To assemble it onto your directory, -just say - - FOO;BAR - -letting the binary file names default. - -* Menu: - -* Switches:: Command line switches. -* Interrupts:: Terminal interrupt characters. - -MIDAS Node: Switches, Previous: Invoke, Up: Top, Next: Interrupts - -Switches: - - Switches should be enclosed in parentheses or preceded by slashes, -and may go anywhere in the command string. The effects of a switch in no -way depend on where it appears, although it should not appear in the middle -of a file name as that may confuse the filename parser. Any number of -switches may be enclosed by one pair of parentheses, as in (ET) which is -equivalent to (E)(T) or /E/T. Each slash is good for just one switch. -It is sometimes significant whether a switch occurs once or twice: (TT) is -not the same as (T). - -/C Produce a CREF file. -/E Produce an error output file. -/L Produce a listing. -(LL) List on 1st pass as well as 2nd. -/T Read assembly input from the terminal after the TITLE - statement, on pass 1. You can type in parameter assignments - to control conditional assembly. -(TT) Read from the terminal on both passes. -/W Do not print on the terminal. - This implies the (E) switch, so your errors are not lost. - /W works by setting the .TTYFLG variable initially to 1. - -MIDAS Node: Interrupts, Previous: Switches, Up: Top, Next: Basic - -Terminal Interrupt Characters. - -In the ITS and Twenex (I believe) versions, the characters ^H, ^V and ^W -have an instantaneous effect if typed on the terminal while MIDAS is -running. - -^H Causes an error message "^H-BREAK" - (which says where the assembly has reached) - followed by the .INSRTion of TTY:. - Thus, this is a sort of "break-loop" you can use - to debug runaway macros. To exit, cause an end-of-file - on the terminal input. - -^V Decrements .TTYFLG. - Since type-out on the terminal happens only when .TTYFLG is - negative or zero, this undoes the effect of one ^W. - (some very bad errors that .INSRT TTY: - also zero .TTYFLG before typing an error message.) - -^W Increments .TTYFLG, suppressing terminal type-out. - It is not wise to do this if you don't have an error - output file (since after the assembly has been started - it is too late to start writing one). - - -In the Bottoms-10 version, you can get a ^H-break by typing -^C and then Reenter. - -MIDAS Node: Basic, Previous: Interrupts, Up: Top, Next: Example - -Machine Instructions in MIDAS - - The main body of a MIDAS program is composed primarily of machine -instructions -- just as you would expect. - - The PDP-10 machine language instruction breaks down into five -fields of bits: a nine bit opcode field, a four bit accumulator (AC) field, -a one bit indirect field, a four bit index register field, and an 18 bit -memory address field. The instruction set is documented very clearly in -the "DecSystem-10 System Reference Manual" (DEC-10-HGAC-D, and the later -versions), which is published by the manufacturer, Digital Equiptment Corp. -("DecSystem-10" is a pretentious salesman's name for the PDP-10). - - In MIDAS, the fundamental syntactic construct is the word. Its -components parallel the fields of a machine instruction, but it is flexible -enough to be used for all other purposes as well. This is because the -subunits or "fields" which compose a word are simply added together, into -parts of the 36-bit word determined by the pattern of spaces and commas -that separate them. Every word of data assembled into the binary program -is written in MIDAS as a syntactical word of some sort or other, with the -sole exception of multi-word text strings. *Note Words: Words, for full -details. - - Words are terminated and separated by the "line terminators", which -are Return, Linefeed, and "?". Return and Linefeed should always be used -together, to prevent confusion when editing the program. Strictly -speaking, Return Linefeed contains a blank line, but blank lines are -ignored anyway. - - The value of the words that appear in a MIDAS program become the -words of the binary program output. Each word is assembled at the -address specified by the MIDAS "location counter", which increments by one -after each word to put consecutive words in consecutive locations. This is -called "assembling a storage word". The ultimate goal of assembling a -program is to assemble storage words, but word quantities can appear in -other contexts such as to be passed as arguments to functions. Before -each word in the MIDAS input, at the beginning of the line, there may be -one or more "labels", which are symbols which are defined to equal the -current value of the location counter. Thus, a label preceding a word is -defined to be the address of that word. *Note LocnCtr: LocnCtr. - - The other most important constituent of a MIDAS program is the -comment. A comment starts with a semicolon ";" and ends with the following -Return. The whole thing is equivalent to a single Return. Another way to -think of it is that you can put a comment at the end of any line in the -file; but "lines" terminated by the "?" character do not count. - - A few other MIDAS constructs may appear in place of a word. One is -the parameter assignment, which defines a symbol with an explicitly -specified value at assembly time. *Note Assign: Symbols. Another is the -"Statement". Everything that must be specified in a MIDAS program aside -from the contents of words to be loaded and the values of symbols is -specified by means of statements. A statement begins with a symbol which -is the name of a "pseudo-op"; it is a sort of escape which directs MIDAS -to perform some special function. Some pseudo-ops read arguments. The -syntax of the arguments depends on which pseudo-op it is. An example of a -statement is the END statement, which must appear at the end of every -program. It starts with the symbol END. After that comes the program's -starting address, which is syntactically a word (and thus, terminated by a -"?" or Return or Linefeed). If a Return immediately follows the symbol -END, then there is no argument (and no starting address). - - The separation into lines should not be thought of as a -hard-and-fast rule. The "line-separating" characters USUALLY have that -effect, but in some contexts (such as text-string constants) they may have -NO special effect. and "?" are both "line-separators", but in a -semicolon-comment they do not act the same: a ends the comment, but a -"?" is ignored as "part" of the comment. Semicolon usually starts a -comment, but not inside a text string. Thus, - - MOVE A,B ;COMMENT ? MOVE C,D - -assembles only a single instruction. The moral is that the meaning of a -character depends on its context, which depends on the characters IN FRONT -of it. MIDAS does not work by BNF-like grammatical rules ("a MUMBLE can be -either a FOO or three BARs in a row") although a few constructs can be -approximated by them. It works like a finite-state machine: "In the normal -input-reading state, if a is read, terminate the line and process it; -if a question-mark is read, terminate the line and process it; if a -semicolon is read, enter the comment-reading state. In the comment-reading -state, if anything but a is read, ignore it; if a is read, return -to the normal input-reading state and terminate the line and process it." - -MIDAS Node: Example, Previous: Basic, Up: Top, Next: Frame - -Simple examples of MIDAS code - - MOVE C,COUNTA - TLNE B,100 - SETZ C, - JUMPGE A,@DISTAB(B) - JRST LABEL1 - -Each of these lines will generate one storage word in the output. -The first line will generate a MOVE instruction that will load the -contents of memory location COUNTA into accumulator C. This is accomplished -by putting the value of the symbol C in the instruction's AC field, -and the value of the symbol COUNTA in the address field, and then adding -the value of the symbol MOVE (which supplies the appropriate value in the -op-code field). The second line is similar, except that the address field -is specified by the octal number 100 instead of a symbol. That is a -common thing to do with instructions like TLNE which use the address -as a bit-mask. The third line is a SETZ instruction. The address field -has been omitted, because the SETZ instruction ignores its address. -In fact, the address field will be assembled as zero. The SETZ has been -indented one space as a note to humans that the preceding TLNE instruction -can skip over it. The fourth line -is a JUMPGE instruction which demonstrates indexing and indirect addressing. -The "@" turns on the instruction's indirect-bit, selecting indirect -addressing. The "(B)" puts B's value in the index field. Presumably, -B is the number of an accumulator which is to be used as an index register. -The fifth line shows a JRST instruction, for which it is not necessary -to specify an accumulator. In fact, the accumulator field of the instruction -will be assembled as zero; but instructions that actually use accumulator -zero should say so explicitly. - So in the simple cases, MIDAS agrees with the format used in the -"DecSystem-10 System Reference Manual." - -MIDAS Node: Frame, Previous: Example, Up: Top, Next: Words - -The Framework of Every MIDAS Program - - A MIDAS program consists primarily of PDP-10 instructions and -data, together with labels and comments. But other things are usually -or always needed at the beginning and end of the program. - - The first thing in every MIDAS program (or every subfile of -one, for that matter) is a line containing ";-*-MIDAS-*-" to tell -EMACS how the file is to be edited. - - The second thing in a MIDAS program, which is not actually -needed for small programs, is a .SYMTAB statement which says how large -a symbol table is required. The argument to .SYMTAB is the desired -number of entries in the symbol table. This must include the -predefined symbols, the user-defined symbols, and some extra to make -hashing efficient. It should also be prime. To help you set up your -.SYMTAB, MIDAS prints the symbol table size and the number of entries -used at the end of the assembly. - - Next, in every MIDAS program, should come the TITLE statement, -which consists of TITLE followed by a line of text, and performs these -functions: -1) for relocatable assemblies, the first symbol following TITLE -becomes the name of the relocatable program being assembled; -2) the text following TITLE is printed on the terminal on each pass. -3) when the /T switch is used to request input from the terminal, -this input is read when the TITLE statement is reached. -Because of 3), it is sometimes useful to define a few symbols before -the TITLE statement so that they can be used when giving input on the -terminal. If there is no TITLE statement, /T won't do anything! - - After the TITLE statement, you should define names for the -accumulators. Single letters starting with A=1 are best. Accumulator -0 should also have a name, but not in sequence with 1, since 0 can -only be used for special purposes. But don't ever write an -instruction which actually USES accumulator 0 without putting in the -name of that accumulator. The stack pointer should be in accumulator -17, which should be named P. Putting the accumulator definitions on -page 1 will produce the best results in @ listings. - - After this point, you are on your own. But at the end of the -program, you need an END statement. The END statement consists of END -followed by the starting address of the program (this is an old assembler -tradition). You can omit the starting address if you don't want your -program to have one (in a relocatable program, this is often the case). If -you don't have an END statement, you get an error. This catches many -errors in assembly conditionals and macro definitions which cause the -END statement not to be recognized as such. Any text which follows the END -statement will be ignored completely by MIDAS. - -MIDAS Node: Words, Previous: Frame, Up: Top, Next: Fields - -Words, and Their Syntax - - The "word" is the most commonly used MIDAS construct, as a storage -word to be assembled must be, syntactically, a word, and an ordinary PDP-10 -instruction is an example of a word. However, the word construct includes -other things than instructions, and is used in other contexts besides that -of storage words. This section of the manual describes how to put a WORD -together. The concept of a WORD is tied closely to those of SYLLABLES and -FIELDS, out of which WORDS are made. Loosely, a syllable is a number or -symbol, and a field is an arithmetic expression. Words are made up of -fields, and fields are made up of syllables. Do not confuse a MIDAS field -with a "field" of bits in a PDP-10 machine language word. - - A word is one or more fields connected by field separators, with -optionally an indirect bit or index field anywhere among them. There -are two field separators, space (or horizontal tab) and comma. (Space and -horizontal tab are identical and will both be referred to as space.) To -improve readability, spaces before and after a word and spaces adjacent to -a comma are ignored, and more than one space in a row are treated as one. - The values of the fields are combined to form the values of the -word according to the number of fields and the pattern of separators. These -formats are described in the following table, in which A, B, and C are -fields. "TR(x)" is used to represent the result of truncating x to 18. bits. - - -pattern format # value - in octal -====== ======= ===== - -,,C 13 TR(C) -,B 14 TR(B) -,B C 15 unassigned -,B, 16 unassigned -,B,C 17 unassigned -A 20 A - 21,22,23 not possible -A B 24 A++TR(B) -A B C 25 A++TR(B)++TR(C) -A B, 26 A+<_23.> -A B,C 27 A+<_23.>++TR(C) -A, 30 A - 31 not possible -A,, 32 _18. -A,,C 33 _18.+TR(C) -A,B 34 A++TR(B) -A,B C 35 unassigned -A,B, 36 unassigned -A,B,C 37 unassigned - - Here are some examples of what these formats are most useful for: - -A B,C This is the normal instruction format, e.g., CAMN A,FOO -A B This is good for instructions with no accumulator field, - e.g., JRST BAR -A B, and this is for instructions with no address field, e.g., - SETZ D, -A,,C This is the standard way to specify the contents of a - storage word by half-words, e.g., - BLETCH: -PDL,,PDB - -NOTES: - -1) "+" means normal 36-bit addition, but "++" addition is special in -that carry from bit 18 to bit 17 is suppressed. In other words, when the -user specifies a field which is supposed to be a right half-word field, he -can normally rest assured that his quantity didn't carry over into the left -half. - -2) A word may have more than three fields. In that case, the -fourth and following fields are added in with the third field. Thus, -if the third field is truncated to 18. bits and added in, so are the -following fields. Only spaces may be used for separating fields after -the third field; a comma after the third field is an error, but will -be treated as a space. Commas are flagged so as to catch places where -the accidental omission of a has run two lines together. - -4) The user can redefine these formats by using the .FORMAT pseudo-op. -That is what the "Format number" of a format is used for, and the pseudo -is documented here: -.FORMA fno,fval - Inserts an entry in the format table (ie replaces old entry) for -format number "fno". The numeric value of field fval is taken as three -12-bit bytes referring to the (up to) three distinctly handled fields in a -word: the left 12 bits refer to the rightmost field, the middle 12 bits to -the field next to the rightmost (if any) and the right 12 bits to the field -2 from the right and any additional fields. (If there is only one field in -a given format it is the rightmost regardless of punctuation which may be -required after it.) - A 12-bit byte describing a particular field is in turn treated as -two 6-bit bytes. The right 6-bit byte specifies a mask and the left 6-bit -byte specifies a shift. The mask number (say M) directs that only the -right M bits of the field value be taken. The shift number (say S) directs -that the bits remaining after masking be shifted left S bits. The fields, -after this masking and shifting are added to give the value of the word. -(Example: the 12-bit specification 2704 describes an accumulator field: -_23.) - There are three exceptions to the above procedure. (1) If a field -is specified as 0022 (right half, not shifted) the carry out of bit 18 is -suppressed as the field is added into the word. (2) A virtual quantity may -only occur in a field specified 0044, 0022, 2222, 0504, or 2704. (3) If as -a syllable in the leftmost field of a word appears any of the eight I/O -instructions (DATAO, DATAI, CONO, CONI, BLKO, BLKI, CONSZ, CONSO) then any -field in that word specified 2704 is instead taken as if specified 3211 -(I/O device field) - - - In addition to the fields and separators that make up a word, there -can be an indirect bit and an index field. These subconstructs resemble -the fields of the word in that their values are merged into the value of -the word. They differ from the fields in that they are marked out by their -own special syntax, and are interpreted in the same way no matter where in -the word they appear (unlike fields, which are all the same and are -interpreted according to their position in sequence). - - a. The Indirect bit - - The character @ (atsign) is a special character. It may occur -anywhere inside a word. Whenever MIDAS encounters an @ inside a word, a 1 -is ORed into bit 22. of the word, i.e., the indirect bit. The @ does not -terminate syllables or fields, nor is it taken as part of a syllable or -field. - Its position in the word is totally irrelevant. However, the -normal convention is to put it in front of the field specifying the right -half of the word (the address) if there is one; if not, put the @ where the -address would go. - - b. The Index field - - To get a certain quantity into the index field, the easy, convntional -way is to use a bracketed word of the parentheses type. For example, - MOVE A,FOO(D) -will put the value of D into the storage word's index field. As explained -in section C.2.d, the parenthesis bracketed word works in its strange way -because the index field of the machine word is the lowest four bits in the -left halfword. - The index field, used this way, may appear anywhere in the word -except in the middle of a syllable or following an arithmetic operator, but -the normal convention is to put it at the end of the field specifying the -right half of the word (the address) if there is one. When "(" appears -following an arithmetic operator, it signifies a type of bracketed word, -rather than an index field. - -MIDAS Node: Fields, Previous: Words, Up: Top, Next: Syllables - -Fields - - A "field" in MIDAS is essentially an arithmetic expression. A -field may be either a single syllable, or two or more syllables combined -arithmetic operators. Many MIDAS pseudo-ops take arguments that are -syntactically fields. These are the arithmetic operators, in their order -by priority: - - char. operator - ===== ======== -highest _ left shift 1st operand by # of bits specified by 2nd - operand. (Negative 2nd operand shifts right) - & bitwise AND - # bitwise XOR - \ bitwise OR - * and / 36. bit integer multiplication and subtraction -lowest + and - 36. bit integer addition and subtraction - - - Thus all _'s are done first, then &'s, then #'s, then \'s, then *'s -and /'s, and finally +'s and -'s. Operators of the same priority will be -performed in left-to-right order. Examples: (assuming that A, B and FOO -are numerically defined symbols with the values 1, 2, and 53 respectively.) - - Field Value - ===== ===== - 3+4 7 - 1+4&FOO+1 2 - 1+4& 5 - - The first example is rather trivial. The second and third -demonstrate the use of angle brackets as algebraic parentheses (actually, -part of the syntax of syllables). In the second, 4 is anded with FOO, -giving zero, then 1+0+1 equals 2. In the third example, first FOO is added -to 1, giving 54. Then 54&4 gives 4, and then the 4 is added to the 1, -giving 5. - - Note that there may NOT be spaces within a field; so "4 * 5" is -not the same as "4*5". - -MIDAS Node: Syllables, Previous: Fields, Up: Top, Next: LocnCtr - -Syllables - - There are several types of MIDAS syllables. A symbol may be a -NUMBER, a NUMERICALLY DEFINED SYMBOL, a QUOTED CHARACTER, a BRACKETED WORD, -or a call to a PSEUDO-OP (but see *Note MACROS:macros) -(Note: only "value-returning" pseudo-ops can be used to make syllables. -Other pseudo-ops will either be ignored by the process of building words -and fields out of syllables (except for their side effects), or illegal to -be used except alone on a line). - - Each syllable has a value, which is a 36.-bit quantity. - - a. NUMBERS - - The simplest form of number is an octal integer, which is just a -string of digits. Following them with a "." makes it a decimal integer -instead. - - *Note Numbers: Numbers, for other sorts of numbers, which you won't -need very often. - - - b. SYMBOLS - - A symbol is a string of SQUOZE characters which is not a -number. More precisely, it is a string of characters from the -SQUOZE character set of length 1 or greater which contains at -least one letter, or at least one % (percent) or $ (dollarsign), -or at least two .'s (periods). The SQUOZE set includes all 26. -letters, all 10. digits, and the characters $ (dollar sign), % -(percent sign), and "." (period). (Note that the symbol "." (a -single period) is special; *Note LocnCtr: LocnCtr.). - - Here are some examples of symbols: - - LOC3 - GOHERE - $END - A%LOCATION - 35X - 1.2.3 - .$Z%.G - -(The last example is NOT considered an example of good programming style.) -A symbol has no length restriction, but MIDAS only looks at the first six -characters, so the symbols THISLOCN and THISLO, for example, are -effectively identical. - - MIDAS symbols can have several sorts of definitions. The symbols -that can appear as syllables are those with numeric definitions (other -sorts of symbols might appear at the same places, but they would be -interpreted differently and would constitute different constructs). MIDAS -provides many predefined numeric symbols (including all the PDP-10 -instructions, and others specific to the operating system), and programmer -can define others (*Note Define: Symbols.). - - An example of numerically defined symbols: -In the word MOVE B,FOO , there are three symbols: MOVE, B, and FOO. -The symbol MOVE is predefined; the other two must be defined by the -programmer. - - c. Quoted Characters: - - A quoted character starts with any one of the characters ' (single -quote), " (double quote), or ^ (uparrow) followed by a character. The -quote or uparrow and the character following are taken as a syllable. A ' -followed by a character has the value of the SIXBIT representation of the -character. A " followed by a character has as its value the ASCII -representation of the character. ^ works the same way as " except that the -ASCII value is ANDed with 77 octal; that is, only the low six bits are -kept. ^ is used for generating the ASCII code for "control" characters. - Examples of quoted characters: - - Syllable Value - ======== ===== - - 'A 41 octal - "+ 53 octal - ^C 3 octal - - d. Bracketed words: - - A word surrounded by ( ) (parentheses), < > (angle brackets), or [ -] (square brackets) is a syllable called a BRACKETED WORD. Each works in -its own way: - - is simply a syllable whose value is that of the word between the - brackets. Angle brackets act much like algebra's parentheses, - and are usually used that way. - -(word) works two different ways. If the preceeding character is an - arithmetic operator, the value of the word has its halves swapped, - and this becomes the value of the syllable, on which the arithmetic - operator acts. If the preceeding character is not an arithmetic - operation, the value of the word is swapped and saved, and at the - end of the outer word, it is added into the word being formed. - This quirk is so that (5) stuck at most places in a word will put 5 - in the index field. - -[word] is a LITERAL, or CONSTANT. *Note Literals: Literals. The value of - the syllable is the location where MIDAS put the literal. - - It is hard to give examples of ( ) and < > until some further -concepts have been introduced, so these have been delayed. - - e. Pseudo-ops which return a value: - - Pseudo-ops are instruction given by the programmer to MIDAS in the -input ASCII file about how to assemble various things. They are described -in section E, "Pseudo-ops that every programmer needs," and in the section -on pseudo-ops. - They are the "built-in functions" of the MIDAS assembly-time -programming language. Some pseudo-ops are used for their side-effects; -some, to compute values. Calls to value-returning pseudo-ops constitute -syllables, whose value, of course, is the value returned by the pseudo-op. - -MIDAS Node: LocnCtr, Previous: Syllables, Up: Top, Next: Output - -The Location Counter - - Normally, when MIDAS finishes reading a Word at top level in the -input file, the value of that word is assembled into the binary program -output. The place where it will be loaded is specified by the location -counter, which is normally an 18.-bit number. After assembling each such -word, MIDAS increments the location counter. - - The value of location counter is explicitly available as the value -of the symbol ".". It refers to the address of the current word, not the -following one. A label defines a symbol to equal the current value of ".". - - The location counter can be set with a LOC statement, or by -assigning a value to the symbol "." (*Note .=: Symbols, for how to do -that). These have slightly different effects when an offset is in effect. -In a relocatable program, the location counter can be set to a relocatable -value or to an absolute value. - - The usual way to leave space for non-constant data in a program is -the BLOCK statement. - - BLOCK 200 - -leaves 200 words of space, by incrementing the location counter by 200 . -It is an error to ask for a block of negative length. - - In relocatable assemblies, the location counter starts out at -relocatable zero. In absolute assemblies, it starts out at absolute 100 -octal. - - Sometimes it is necessary to assemble code at one location and copy -it to another before using it. When that is done, all references to labels -in the code (whether from within it or outside it) should be arranged so as -to be correct when the code has been moved to its ultimate position. This -can be done by defining an offset. The statement - - OFFSET 200 - -causes all references to the location counter -- the symbol ".", labels, -etc. -- to add 200 to the real value of the location counter. If the code -being assembled is moved 200 words upward, it will be at the addresses at -which the program will refer to it. - - Offsets do not affect the actual location counter, which is the -place at which code will actually be loaded. They affect the value of the -location counter as seen by references to it from within the program. -The difference between LOC and assigning a value to "." is that LOC sets -the real location counter, whereas assigning "." sets the value of ".": -that is, it subtracts the offset and then sets the real location counter, -so that when the offset is added in again to get the value of "." it will -equal the value assigned. - - An offset can be cancelled by setting the offset to zero. - - A frequent use of the offset is for error checking. If there are a -series of symbols FOO, BAR, QUUX ... with values 0, 1, 2 ... intended to be -the values of a particular table index, with MAX being 1 larger than the -largest legal index, the table can be defined with - - TABLE: OFFSET -. - FOO:: - BAR::
- QUUX::
, and the format of the -SBLK file symbol table in .INFO.;DDTORD >. - -MIDAS Node: Relocation, Previous: Output, Up: Top, Next: Symbols - -Relocatable Assemblies. Specifying the Type of Output. - - Like MACRO-10, MIDAS is capable of making both relocatable and -absolute assemblies. The type of assembly is controlled by pseudos -appearing in the program, with a default which varies with the operating -system. In an absolute assembly, all location counter values (and all -expression values, in fact) are completely known at assembly time, or else -are undefined. In a relocatable assembly, while some location counter -values and expression values may be known at assembly time, most depend on -an unknown relocation which will be determined only by the linking loader. -The location counter value is likely to be a known quantity plus the -unknown relocation. Symbol values can also have that form (and will, when -the symbol is defined as a label when the location counter has that form). -Expression values can take the form of a known quantity plus any number -times the relocation that number being the "relocation factor". Values -completely known at assembly time are called "absolute", and have a -relocation factor of 0. Simply relocatable quantities, such as typical -location counter values, have relocation factors of 1. MIDAS can handle -higher or negative relocation factors internally but cannot write them into -the output file except in STINK format output. - - Whether an assembly is absolute or relocatable is tied closely to -what output format is used. The formats that exist are - - SBLK Standard ITS absolute format. - This is the default on ITS. - RELOCATABLE STINK format (relocatable). - Used only on ITS, and not much. - .DECREL Standard DEC relocatable, for LINK10. - This is the default on non-ITS systems. - .DECTWO Standard DEC two-segment relocatable. - is the segment boundary, usually 400000 . - .DECSAV Standard DEC SAV file format. Absolute. - .FASL MACLISP FASL file format. Relocatable. - RIM Read-In Mode format for PDP-6. Absolute. - RIM10 Read-In Mode format for PDP-10. Absolute. - - The names of the formats are all pseudo-ops which you can put in -the program to specify those formats. If the format you want is the -default for your particular system, you don't need to specify it, but if -you can anticipate that your program will be assembled on other systems it -might be wise to do so anyway. - - A few functions are available for manipulation of relocatable -quantities. These include .ABSP, .RELP, and .RL1. .ABSP and .RELP return -the absolute and relocatable parts of a quantity (the relocatable part is -the relocation factor. .RL1 is a symbol whose value is a pure -relocatability of 1; that is, a relocatable zero. You can think of these -as analogous to the the complex number functions Re, Im and the constant i. -.RELP .RL1 is nonzero if the asembly is relocatable. - -MIDAS Node: Symbols, Previous: Relocation, Up: Top, Next: DDT - -Defining Symbols - - You have already been told how to use symbols and what names they -are allowed to have. Here is how to define them. - - A symbol can have these types of definition (or none at all): -numerically defined symbols, pseudo-op names (*Note Pseudos:Pseudos.), and -macroinstruction names (*Note Macros: Macros.). Here we are concerned only -with numerically defined symbols. New pseudo-ops cannot be defined by the -user, so the initial supply is all you get, but pseudo-op definitions can -be copied from one symbol to another using EQUALS. - - There are basically two ways to define a symbol numerically: as a -LABEL, and as a PARAMETER. - - 1. Labels. - - The primary use of symbols is to hold the address of an instruction -or variable in the program. MIDAS has a special construct, the LABEL, for -defining such symbols. A label is simply a symbol followed by a colon, and it -can appear at the beginning of any line. Its effect is to give the -symbol a value equal to the address where the next storage word will go. -A line can have several labels in it, but a label may not appear after -any other construct has begun. A label may be followed by anything at all, -or it may be the only thing on its line. An example is: - - FOO: MOVE A,TABLE(C) - -which assembles a storage word containing a MOVE instruction, and -also defines FOO as the address of that instruction. - - If a symbol is defined as a label, it can have only one value. -If anything in the program tries to define the symbol with a different -value, either before or after the symbol's appearance as a label, an -error message will be typed. It is legal to define the symbol again -with the SAME value. In fact, that happens to every label, since it -is seen on both passes of the assembly. - - The parameter assignment "=:." has the exact same -effect as the label ":", which is allowed for convenience's sake. - - 2. Parameters. - - There are other uses of numerically defined symbols besides -their use as labels. MIDAS also allows definition of symbols by -PARAMETER ASSIGNMENT. A parameter assignment is a line of the form - = or == -which tells MIDAS to compute the value of and make that the value -of . This is similar to the "assignment" statement of most -mathematical languages, such as FORTRAN. Using the == construction -makes the symbol half-killed in DDT (this is explained in the section -on OUTPUT; for now, suffice to say that the == form is the one you -probably want to use.) Here is one of the ways to use this feature: - - Say a programmer is writing a program which knows how to handle -four FOOBAR's. If in the future he should want to modify the program -to handle five or six FOOBAR's, there might be many places where the -program would have to be changed. Now if he had made the number of -FOOBAR's an assembly parameter, by defining a symbol as in: - NFOOBR==4 -and writing all of the program to work for NFOOBR FOOBAR's -Whenever there is a table or block of data whose length must -be referred to by the program, that length should be expressed -by a numeric symbol. - - Symbol definitions actually have a static scoping or block -structure as in Algol or PL/I. *Note Blocks: Blocks. - -MIDAS Node: DDT, Previous: Symbols, Up: Top, Next: Numbers - -Communicating Information about Symbols to DDT - - One of the most important things about symbols in assembler -programs is that they are passed to DDT. MIDAS has several features -designed specifically for communicating with DDT. - - If DDT, needing to print the value 205, chose at random a symbol -whose value was close to 205, it would be likely to find several names for -bits in various registers. It is essential to have a way to tell DDT which -symbols ought to be used for such type-out. This is done by "half-killing" -the symbols which ought not to be used. - - The most common way to half-kill a symbol is to duplicate the colon -or equal sign used to define it. Thus, FOO==200 says that FOO is to be -half-killed and should never be printed out, while FOO=200 allows FOO to be -printed out. FOO:: defines FOO as a half-killed label. - - If those methods of half-killing are not convenient, the .HKILL -statement is available. .HKILL followed by a list of symbols half-kills -those symbols. If the symbol .HKALL is nonzero, then all labels defined -are half-killed. - - .KILL can be used to avoid sending a symbol to DDT at all. It is -followed by a list of symbols to kill. MIDAS does not forget the value of -a symbol when you .KILL it, so .KILL is not the same as EXPUNGE. .KILL -causes the symbol to be forgotten only when the symbol table is written -into the output file. - - The NOSYMS statement can be used to avoid outputting any symbol -table at all. - -MIDAS Node: Numbers, Previous: DDT, Up: Top, Next: Literals - -Details of the Syntax of Numbers - - A string of digits in which no digit is preceeded by a period -forms an INTEGER, a type of syllable whose value is the value of the -number interpreted in the CURRENT RADIX (octal by default, but see -*Note PSEUDO-OPS:pseudo-ops.). - -However, an integer followed by ' (single quote) is interpreted as octal, -and one followed by . (period) is interpreted as decimal, regardless of -the current radix. A string of digits with a . (period) to the left of -some digit forms a FLOATING-POINT NUMBER, interpreted in decimal. - - Either of these may be followed by a ^ (uparrow) which works -something like scientific notation. An integer may be followed by an -integer as - - A^B - - which would have the value of - - B - A*R - -where R is the radix in which A is expressed. The result is fixed-point. -A floating point number may also be followed by a ^ and an integer, as in - - X.Y^A - -which is interpreted as - - A - X.Y*10. - -that is, as scientific notation. The result is still floating-point. - - Also, any of the preceeding numeric formats may be followed by a _ -(backarrow, or underscore) and an integer, which multiplies the value by - integer - 2 - The integer is interpreted in the current radix, but may -be forced to decimal or octal by terminating it with . or ' as explained -above. The result is always a fixed-point number, even if the first number -was floating-point! - -Examples of NUMBERS: - (the current radix is taken to be octal) - - Syllable Value - ======== ===== - - 23 23 octal - 23. 27 octal - 3^3 3000 octal - 3.^3 5760 octal (3000. decimal) - 1_3 10 octal - 23_10. 46000 octal - 3.5 3.5 floating-point - 3.5^4 35000.0 floating-point - 3^3_4 60000 octal - 1.5_3 14 octal (Note: NOT floating point!) - -MIDAS Node: Literals, Previous: Numbers, Up: Top, Next: Bytes - -Literals - - Normally, when you write a machine instruction in an assembler, you -specify the memory operand by its address. Sometimes, it is desirable to -refer to "a word containing X" without worrying about where that word is -going to be stored. The LITERAL is a construct that permits just this. - - A literal consists of any number of lines enclosed in square -brackets ("[" and "]"). MIDAS assembles the lines enclosed into locations -of its own choosing. The value of the literal, where it appears, is the -address of the location chosen by MIDAS to hold the first word of the -literal. For example, - - MOVEI A,[1 ? 2 ? 3] - -would load accumulator A with the address of a three-word table whose -contents are 1, 2 and 3 in successive words. It is equivalent to - - MOVEI A,FOO1 - .... -FOO1: 1 ? 2 ? 3 - -where FOO1 is a non-existent label by which you can imagine that MIDAS -connects the usage of the literal with the location of its contents. - - Unless you request otherwise, all literals will actually appear at -the end of your program (that is, at wherever the location counter was set -when the END statement was encountered). However, you can alter this with -the pseudo-op CONSTANTS. Whenever CONSTANTS appears, all saved-up literals -will be "dumped out" or assigned locations starting at the current location -counter. CONSTANTS may appear any number of times (up to 75 or so), but -must appear the same number of times and at the same locations on both -passes. - - On pass 1, MIDAS doesn't know where a literal is going to be -located until the CONSTANTS statement is seen. On pass 2, the location of -the CONSTANTS statement is known in advance (remember, it must be the same -as on pass 1), but the location of the literal is still not known until the -end of the literal (so that recursive literals can work). For these -reasons, labels inside literals cannot work, so they are not allowed. -The symbol "." inside a literal refers to the location from which the -literal is being referred to, not the location where the literal will -appear. - - If you set the variable .LITSW nonzero, any use of a literal is an -error (until you set the symbol to zero again). - -MIDAS Node: Bytes, Previous: Literals, Up: Top, Next: FileInfo - -Manipulating Bytes and Byte Pointers. - - MIDAS provides several built-in functions for making and using byte -pointers of the form suitable for the LDB and DPB instructions. - - When you want to make a byte pointer from a given numeric position and -size, simply write the byte pointer left half as an octal constant. There -is really no way to improve on that, given that you are going to be using -numbers. For example, 440700,,FOO is suitable for ILDB'ing the ASCII -string starting at word FOO. It is common practice to define symbols for -byte pointer left halves and then use them to represent fields, as in - -ASCBP==440700 -... - MOVE A,[ASCBP,,FOO] - - A more sophisticated symbolic way of referring to fields uses the .BP -function. .BP takes as an argument a mask for a field in a word, and -returns a byte pointer to that field (in address zero). Thus, <.BP 7770> -would return 031100,,000000. When the argument to .BP is terminated with a -comma, the comma is not eaten, as it would be with most functions. -Instead, the comma turns into a space. Thus, .BP 7770,FOO returns -031100,,FOO, a byte pointer to the 7770 field in address FOO. In addition, -parentheses inside the argument to .BP are part of the argument to .BP, not -part of the word in which .BP occurs. .BP is most useful with symbolic -names for fields or bits in a word. For example, - LDB A,[.BP (%TOERS),TTYOPT] -would get into A the contents of the %TOERS bit in the left half of TTYOPT -(%TOERS being a bit symbol suitable for use in a TLNE instruction). - - The reverse of .BP is .BM. It takes a byte pointer (ignoring the -address) and produces a mask for the specified byte. The left half of a -byte pointer may be passed in the right half of the argument word. This -Is useful when you have defined a symbol for a byte pointer left half and -want the corresponding mask. Unlike .BP, .BM follows the ordinary -conventions for arguments. Example: .BM 030600 returns 770. - - Bytes can be extracted from and deposited into quantities at assembly -time using the .LDB and .DPB functions. .LDB takes a byte pointer -(ignoring the address) or a byte pointer left half in the right half, and -also a quantity as second argument. It returns the contents in that -quantity of the specified byte. .LDB 030600,1234 returns 23. -.DPB takes as arguments a byte value, a byte pointer (or left half in right -half, etc) and a quantity, and returns a new quantity made by changing the -specified byte of the old quantity to contant the byte value. For example, -.DPB 11,030600,4444 returns 4114. - - The .IBP function increments a byte pointer. It accepts a byte pointer -and returns the incremented pointer. .IBP <440700,,> returns <350700,,>. -The address supplied with the byte pointer is part of the incrementing -process; thus, .IBP <440700,,FOO> returns <350700,,FOO> and -.IBP <010700,,FOO> returns <350700,,FOO+1>. If the left half of the -argument is zero, the argument is swapped, so .IBP 440700 returns -<350700,,>. - - Two functions related two byte manipulation are .LZ and .TZ, which return -the number of leading zero bits and trailing zero bits, respectively, in -their arguments. .LZ SETZ is 0 and .TZ SETZ is <35.>. When applied to -zero, both return <36.>. - - For assembling words into memory made by packing bytes together, you -could use .DPB, but a special feature exists for this purpose, called -.BYTE. .BYTE takes a list of byte sizes, and enters a special mode in -which "words" assembled at top level are stored, not into successive whole -words, but into successive bytes of the specified sizes. The sizes are -used in the order specified, over and over cyclically. Here is an example: - -.BYTE 12.,6 - 2222 - 33 - 1111 - 44 -.BYTE - -would assemble a single word, made up of a 12. bit byte, a 6 bit byte, a -12. bit byte, and a 6 bit byte. The contents would be 222233,,111144. -Note that .BYTE with no arguments is used to return to ordinary non-byte -mode. - - Byte mode inside literals and other bracketed groupings is independent -of what is going on outside the grouping. That is, groupings always start -out in ordinary (non-byte) mode, even if byte mode was in effect outside; -byte mode may be turned on inside the grouping, but when the grouping ends -the state of byte mode will be restored to what it was before the grouping. -For example, <.BYTE 7 ? ^M ? ^J> is a quantity whose value is a CRLF in -ASCII. It is equivalent to ASCII/ -/. - - While byte mode is in effect, the location counter is a byte pointer. -Its value is such that an ILDB instruction on it would fetch the next byte -to be assembled. This is historic; it may well be that a better -convention would be that the location counter be such that a LDB would -fetch the next byte to be assembled. As it is, you must use .IBP to get -such a byte pointer. It works to set the location counter to a different -byte pointer, though it is recommended that you make the size correct. -If the byte pointer is inconvenient for you, .BYTC may be more useful. Its -value is the total number of bytes assembled since byte mode was entered. -The insides of literals and groupings do not count. - - .WALGN (word-align, not wall-generate) in byte mode advances the location -counter to the beginning of a fresh word. It does nothing in normal -non-byte mode. .BYTE with no arguments automatically does a .WALGN. - -MIDAS Node: FileInfo, Previous: Bytes, Up: Top, Next: Terminal - -Obtaining Information on Filenames at Assembly Time. - - One of the most common things one wants to do is to assemble a program's -version number into the program. This can be done, on ITS and Twenex, -using the symbol .FVERS, whose value is the version number of the main -input file, and .IFVRS, whose value is the version number of the current -input file if that file has done no .INSRTs, or the version number of the -last file .INSRTed by the current input file. - - More information is available in the variables .FNAM1 and .FNAM2, which -hold the sixbit filenames 1 and 2 of the main input file, and .IFNM1 and -.IFNM2, which hold similar information for the same file as .IFVRS. -These variables are available on Bottoms-10, where there are no version -numbers, as well as on other systems. On ITS, the version number is a -function of the filename 2, made by taking all the digits in it and -converting them using base ten to a number. - - The names of the output file (in sixbit) can be found in .OFNM1 and -.OFNM2. The version number is not available, since on ITS it does not -exist. - -MIDAS Node: Terminal, Previous: FileInfo, Up: Top, Next: Macros - -Interaction with the Terminal. - - The simplest and standard way to print a message on the terminal is with -the PRINTX operation. It takes a string, delimited as for ASCII, and types -it out. For example, PRINTX /FOO/ will type FOO, with no carriage return. -.TYO is a function that takes a single character, as a number, and types -it. .TYO 101 will print an A. - - Another useful function is .TYO6, which takes an argument which is -interpreted as sixbit and printed out. .TYO6 is useful primarily with -.FNAM1 and .FNAM2. - - Error messages are printed on the terminal, of course. The .ERR function -signals an error, taking the rest of the line as error message. Along with -the error message will go the usual information of filenames, page and line -number, location counter both absolute and relative, and macro depth. -There are no special facilities for putting any variable information in the -error message because the macro features can be used to do this. - - There are two ways to request input from the terminal. You can ask a -specific question, or you can give the user the opportunity to enter any -MIDAS code he wants. To allow him to enter arbitrary text, do - .INSRT TTY: -which reads input from the terminal, ended by ^C or ^Z. If you want it to -be done only on pass 1, you must put it in an IF1 conditional. -The /T switch can be used in the command line to cause a .INSRT TTY: to be -done in a program which does not actually contain one. It will be done -right after the TITLE statement. - - To ask a specific question, use .TTYMAC, which a sort of macro that reads -its arguments from the terminal. .TTYMAC looks like a macro definition -except that there is no macro name in the define line; just an argument -list, followed of course by the macro body and a TERMIN. Instead of -defining a macro which must be called later with arguments specified -explicitly, .TTYMAC defines a nameless macro which is called immediately, -getting the arguments by reading as many lines as are necessary from the -terminal. *Note TTYMAC: Macros, for more information. Here is an example: - -PRINTX /Value of BAR = / -.TTYMAC FOO -BAR=FOO -TERMIN - -MIDAS Node: Macros, Up:Top, Previous:Terminal, Next:Loops - -MIDAS MACROS - -It is often useful, when the text to be assembled -has some pattern, to cause it to be computed, rather than -putting it all in the file to be assembled. This reduces the number -of possible typos and makes it easy to change all occurrences -of a particular construct. - -To do this, one needs to be able to define a function which will -be evaluated at assembly time, with the result being text to be assembled -in place of the call to the function. Such a function is called a MACRO. - -In this document, "EOL" means either CR or LF; -"open" means "<", "(", "{" or "["; "close" means ">", ")", "}" or "]". -"the EOL or CRLF is thrown away" means that the EOL encountered as -should have been previously described is thrown away, and if the EOL -is a CR and the following character is a LF, the LF is also thrown away. -Thus, either a CR alone, a LF alone, or a crlf may be used, and will be -flushed at that point. - -* Menu: - -* Definitions:: Macro Definitions. -* Calls:: Macro Calls. -* Examples:: Examples of macro definitions and calls. -* Remote:: The "REMOTE MACRO" construction. - -MIDAS Node: Definitions, Up: Macros, Next:Calls - -Macro Definitions - -A function definition must specify the name of the function, the -formal parameters (called DUMMY ARGUMENTS when macros are concerned) -and the expression to be evaluated when the function is -called - or in the case of a macro, the text to be assembled when -the macro is called. - -In MIDAS, a macro definition is introduced by the pseudoop -DEFINE, which should be followed by the macro name. -After that, on the same line, come the names of the dummy -arguments, perhaps followed by a comment. -The text of the macro starts on the next line, and continues -until the DEFINE is matched be a TERMIN. -The character that ends the TERMIN is gobbled up. - -* Menu: - -* Example: Macro Definition Example -* Define:: The Macro Define Line -* Body:: The Macro Body - -MIDAS Node: Macro Definition Example, Up: Definitions - -Macro Definition Example - -DEFINE FOOBR AA,B - MOVE A,AA - CAIL A,B - POPJ P, -TERMIN - -A call to that macro might be: - - FOOBR ZZZ,10 - -which would assemble into - - MOVE A,ZZZ - CAIL A,10 - POPJ P, - -MIDAS Node: Define, Up: Definitions - -THE MACRO DEFINE LINE - -The "DEFINE" line is the first component of a macro definition. -It begins with the "DEFINE" pseudo (which needn't actually be at the -beginning of a line). Next comes the name of the macro to be defined, -optionally preceded by an explicit block name (eg DEFINE FOO"BAR to -define a macro BAR in the block named FOO, rather than in the -current block). After the macro name come the dummy argument names, -followed optionally by a comment. In any case, the define line -extends through the first CRLF or EOL after the DEFINE. - - a. bindclasses - semantics. - -Most higher level languages have several bind classes. The function -definition specifies one of the bind classes for each formal parameter, -which is used in decoding a call to the function, to decide what value to -give to the formal parameter. Macro dummy arguments also have bind -classes, which say three things: -what to do if the dummy is UNSPECIFIED (that is, if, in a particular call, -the argument list runs out before this dummy is reached) or NULLSPECIFIED -(the argument for this dummy is left out), the alternatives being -NULLIFIED, GENSYMMED and DEFAULTED (see *Note UNSPEC:calls-8, for the -meanings of the three options); -which argument syntax to use for the dummy when processing calls to the -macro (There are 6 different argument syntaxes available in MIDAS: NORMAL, -WHOLELINE, BALANCED, STRUNG, KEEPSTRUNG, and EVALUATED. -See *Note SYNTAX:syntax-footnote, for descriptions of them.); -and how the actual arguments are to be associated with the dummies, the -alternatives being by ORDER and by KEYWORD. - - b. bindclasses - syntax. - -In MIDAS, it is not necessary to specify the complete bindclass -of each dummy with that dummy's name. Only the ways in which its -bindclass differs from that of the preceding dummy are specified, -by means of special delimiters between the names of the dummies. -The first dummy is given the default bindclass (nullified normal by order) -unless special delimiters precede it. The delimiters are: - {[(< which cause following dummies to be balanced, - >)]} which cause following dummies to have normal syntax, - * which causes following dummies to be strung, or, if - strung was already the selected syntax, causes them to - be normal (This is called "turning strungness on or off"), - & which turns keepstrungness on or off, - # which turns evaluatedness on or off, - ? which turns balancedness on or off, - - which turns wholelineness on or off, - \ which complements gensymmedness, - + which switches between by order and by keyword, - : which reverts to the default in all ways (normal syntax, - by order (not keyword), and not gensymmed). -"/" is a delimiter which is like "-" except that if it follows -a dummy immediately, wholelineness is complemented before the dummy -rather than after. That is, "FOO/" is equivalent to "-FOO". -This is mainly for compatability with older versions of MIDAS. -A dummy is defaulted iff its name is followed by "=". -The "=" should be followed by the desired default value, -whose syntax is that of a normal macro argument. -Beware: the dummy argument delimiters do not terminate default values, -and default values are read in with the normal argument syntax -regardless of the specified syntax of the dummy being defaulted. -Thus, DEFINE FOO \(A,B=100)C makes B's default value be 100)C, which -is probably not what you wanted. -If a dummy is specified as gensymmed, and is also given an explicit -default value, the explicit default overrides the gensymming. - - c. DEFINE line example. - -DEFINE FOBR \A#B\C:D,+E=BAR,F,G(H,I=X,)*J*+-K - -would give FOBR the dummies A,B,C,D,E,F,G,H,I,J,K as follows: - -dummy bindclass (argument syntax, what to do if unspecified). - the first few dummies are by order: - A normal, gensymmed - B evaluated, gensymmed - C evaluated, nullified - D normal, nullified - the next few dummies are by keyword: - E normal, defaulted to "bar" - F normal, nullified - G normal, nullified - H balanced, nullified - I balanced, defaulted to "X" - (note that the comma after "I=X" is necessary because - the ")" would otherwise be part of the default - value of I. after dummy names not given default values - a comma is not necessary, although an extra one can't hurt.) - J strung, nullified - the next dummy is by order. - K wholeline, nullified - -MIDAS Node: Body, Previous:Define, Up: Definitions - -THE MACRO BODY - -The macro body is the text string to be substituted in place -of a call to the macro. The macro body specified in a macro -definition starts with the first character after the CRLF or EOL -that ends the define line, and continues through the character -before the TERMIN that ends the macro definition. Remember that -the character ending the symbol "TERMIN" is thrown away. - -WARNING: ANY occurrence of "DEFINE" or "TERMIN" inside a macro body -will affect MIDAS's determination of where the body ends. This is -true regardless of whether you intended them to or not. Just because -the "DEFINE" was in a text string or a comment does not change this. -"Terminate" and "Terminal" must also be avoided. If you need to put a -"DEFINE" or "Terminal" into a macro body, use .QUOTE (*Note quote:quote.). -The same holds for any other MIDAS pseudo-ops that require a matching -TERMIN, such as IRP and .TTYMAC. - -* Menu: - -* Parameters:: Dummy Argument Substitution. -* Concatenation:: Concatenation. -* Quote:: The .QUOTE pseudo. -* Inner:: Inner Macro Definitions. -* Stopping:: The .STOP pseudo. -* Jumping:: The .TAG and .GO pseudos. - -MIDAS Node: Parameters, Up: Body, Next: Concatenation - -DUMMY ARGUMENT SUBSTITUTION. - -Whenever the name of one of the dummy arguments appears in the macro -body specified in the definition, it represents a request for the value -of that dummy to be inserted at that point when a macro call -is expanded. Dummy argument names are recognized only when surrounded -by non-squoze characters, so neither of the dummy names "A" and "B" occurs -in the string " AB ", but both occur in " A B ". The way dummy -argument substitution is implemented is that the dummy argument names -are recognized when the macro is defined, and replaced by special -characters. Therefore, if the name of a dummy argument is created by -the expansion of a macro call (perhaps part of the name came from the -substitution of the value of another dummy) that dummy-name will -not be replaced by the dummy's value. In other words, text produced -by substitution for dummy arguments is not rescanned for occurrences -of dummy argument names. - -MIDAS Node: Concatenation, Previous: Parameters, Up: Body, Next: Quote - -CONCATENATION. - -Suppose it is desired to have the substituted value of the dummy -argument FOO followed immediately by the squoze character X. -It will not do to put "FOOX" in the macro body, because "FOO" is -not considered to occur in "FOOX". "FOO X" will cause the value -of FOO to be substituted, but the space will remain between it -and the "X". The way to win is to use the concatenation -character "!". "!" can delimit the names of dummy arguments, as -any other non-squoze character can, but it alone is thrown away after -doing so. For example, "FOO!X" will cause FOO to be recognized, -but followed immediately by an "X". -Similarly, the TERMIN that ends the macro definition must be -preceded by a non-squoze character, which normally becomes part -of the macro definition. If it is desired for the macro definiton -to end with a squoze character, separate it from the TERMIN with -an "!", which will be thrown away. "!"'s that appear in the macro -body not adjacent to a dummy agument name, a .QUOTE, or the final TERMIN -are not thrown away; this makes it possible to put "!"'s in macros. - -MIDAS Node: Quote, Previous: Concatenation, Up: Body, Next: Inner - -.QUOTE - -It is possible to prevent recognition of dummy argument names -in a part of the macro body by using the .QUOTE pseudoop. The -pseudo is followed by a text string like the argument to ASCII et al., -which is not scanned for dummy argument names. The first character -of the text string will follow the character before the "." of the -.QUOTE, and the last character before the closing delimiter will -come before the character after tht delimiter, in the macro as it -will be defined. The .QUOTE, to be recognized, must be -preceded by a non-squoze character, so in order to make it -possible for a quoted string to follow a squoze character, an "!" -before a .QUOTE is deleted. -Not only dummy names, but TERMIN, .QUOTE, and the pseudos -matched by TERMINs (DEFINE, .TTYMAC, and the various flavors of IRP) -are not detected or treated specially when within a .QUOTE . - -MIDAS Node: Inner, Previous: Quote, Up: Body, Next: Stopping - -INNER MACRO DEFINITIONS. - -In order to make it possible to define a macro which will, when -called, define another macro, it is possible to insert matching -DEFINE - TERMIN pairs in a macro definition. A definition is -ended not by the first TERMIN after the DEFINE, but by the first -TERMIN that is unmatched by previous DEFINEs (or other pseudos -such as IRP and .TTYMAC that also expect to be matched by TERMINs). -(DEFINEs, TERMINs, etc. within .QUOTEs are ignored in the matching-up.) -Remember that when the outer macro is called and the inner one is -defined, its TERMIN will gobble up one character. -For that reason, when a macro definition ends with an inner -macro definition or an IRP, "TERMIN TERMIN" should be used, -rather than "TERMIN!TERMIN". If the latter is used, the main -macro will end with "TERMIN", so when it is called the inner -"TERMIN" will gobble an extra character after the call. -Using the space gives the inner TERMIN a character to gobble, -thus protecting all the other characters from being gobbled. - -MIDAS Node: Stopping, Previous: Inner, Up: Body, Next: Jumping - -.STOP - -The .STOP pseudo is used to exit from a macro. -At macro expansion time, when .STOP is executed, the -rest of the macro body will be ignored that time through. -execution will continue with the first character after the macro -call. For example, - - DEFINE FOO A,B - 1 - IFE A,.STOP - 2 - TERMIN - - FOO 1 -; 1 -; 2 ;note the .STOP isn't exectuted. - FOO 0 -; 1 ;and that's all, because of the .STOP. - -Beware of putting a .STOP inside brackets ("[" and "]"). -Because brackets are used for both literals and conditionals, -MIDAS must keep a stack with an entry for each unmatched "[" -saying what is was for. If a .STOP, which is like a jump to -the end of the macro body, is within brackets inside the macro, -then although those bracket pairs will be exited, the bracket -stack will not be updated because the closebrackets will -not be encountered. When a "]" is next seen, MIDAS may -treat it the wrong way (eg, may think it closes a literal -when it was supposed to close a conditional). -The way to win is to use braces -("{" and "}") instead of brackets when conditionalizing -a .STOP. Since braces are not used for anything but -conditionals, there is no need for MIDAS to maintain such -a stack, and thus no data base is invalidated if -the brace depth is changed. -Thus, this macro may cause problems: - - DEFINE FOO A,B - 1 - IFE A,[.STOP ] - 2 - TERMIN - -and this one should be preferred: - - DEFINE FOO A,B - 1 - IFE A,{.STOP } - 2 - TERMIN - -MIDAS Node: Jumping, Previous: Stopping, Up: Body - -.TAG and .GO - -These two pseudos provide arbitrary transfers at macro -expansion time. That is, they do not assemble into jump -instructions; rather, they tell MIDAS to jump around -while expanding the macro. That can cause parts of the -macro to be expanded more than once or not at all. -The way to use them is to put .GO at the place -MIDAS should transfer from, and .TAG at the -place it should transfer to. Thus, .GO FOO will -transfer to a .TAG FOO . Nonlocal transfers are -allowed; if a .GO does not find a matching TAG in the -macro it is in, it will exit that macro and search the macro -which called the macro containing the .GO. Any number -of levels may be popped up this way but popping into a -file will cause lossage. There should be a space after the - in both the .GO and the .TAG to prevent lossage. -Note that .GO and .TAG may be used in REPEAT's and -IRP's just as in macros, and nonlocal .GO's in macros -are allowed to find .TAG's in IRP's and REPEAT's, etc. -Transfering from one level in brackets to another has dangers -associated with it, just as with .STOP - see the detailed -explanation under *Note STOP:Stopping. -For example, - - DEFINE FOO - BAR==5 - .TAG BARF - BAR==BAR-1 - BLETCH - IFN BAR,.GO BARF - TERMIN - -when called, will do BLETCH 5 times -(of course, a REPEAT could have been used in this -case, and would have meant a simpler macro). - -MIDAS Node: Calls, Previous: Definitions, Up: Macros, Next: Examples - -MACRO CALLS. - -A macro call is a request for the body of a macro to be substituted -into the text to be assembled. The call must specify the name of the -macro and the values to be given to the macro's dummy arguments -(if it has any) - -* Menu: - -* Call: calls-1 Macro Call Syntax. -* Normal: calls-2 The "Normal" Argument Syntax. -* Balanced: calls-3 The "Balanced" Argument Syntax. -* Wholeline: calls-4 The "Wholeline" Argument Syntax. -* Strung: calls-5 The "Strung" Argument Syntax. -* Keepstrung: calls-6 The "Keepstrung" Argument Syntax. -* Evaluated: calls-7 The "Evaluated" Argument Syntax. -* Unspecified: calls-8 What Happens To Dummies That Are Unspecified. - -MIDAS Node: Calls-1, Up: Calls, Next: Calls-2 - -MACRO CALL SYNTAX. - -Every macro call begins with name of the macro. In order for -the macro name to be recognized as such, it must be evaluated. -Therefore, macro calls are possible only in those places where -a symbol will be evaluated. (For example, putting the macro's name -in the middle of an ASCII will not cause the macro to be called). - -* Menu: - -* Simple: calls-1a: Macros With No Dummies. -* Degenerate: calls-1b: Degenerate Calls. -* Normal: calls-1c: Normal Calls. -* Parens: calls-1d: Parenthesized Calls. - -MIDAS Node: Calls-1a, Up: Calls-1, Next: Calls-1b - -MACROS WITH NO DUMMIES. - -A call to a macro without dummies consists of just the macro name. -The character that terminates the name is left to be reprocessed after -the text of the macro is processed. - -MIDAS Node: Calls-1b, Previous: Calls-1a, Up: Calls-1, Next: Calls-1c - -DEGENERATE CALLS. - -A degenerate call to a macro with dummies consists of the macro -name followed by an EOL. The EOL or CRLF will be thrown away. -All the dummies of the macro will be unspecified (*Note UNSPEC:calls-8.). - -MIDAS Node: Calls-1c, Previous: Calls-1b, Up: Calls-1, Next: Calls-1d - -NORMAL CALLS. - -A normal call to a macro with dummies follows the macro name with -anything but an EOL or OPEN. The character immediately after the macro -name will be ignored. After it, the scanning for the values of the dummies -will commence. -MIDAS considers "by order" dummies one at a time, in the order -they appeared in the macro definition. Each dummy is given a value -obtained by scanning the text of the macro call according to the -argument syntax determined by the dummy's bindclass (which is -one of normal, balanced and wholeline). -(*Note SYNTAX:syntax-footnote, for descriptions of the argument syntaxes). -When a run of "by keyword" dummies is reached, MIDAS expects to -see in the macro call expressions of the form =. -MIDAS reads the dummy name and checks that the "=" is there; it then -finds the dummy with that name and reads in the using that -dummy's bindclass. When, instead of a dummy name, a terminator -(comma, EOL, semicolon, CLOSE, etc) is seen, all the "by keyword" -dummies in that particular run of them which have not been specified -in the macro call are considered to be unspecified. If there are -by order dummies after the run of by keyword ones, MIDAS then -proceeds to read in their values. If the scan for one dummy detects -the "end of the call" (*Note EOL/SEMI:calls-2d,) then the scan for -all following dummies becomes trivial: they are all unspecified, -regardless of their designated argument syntaxes, and no more -characters will be read from the input stream for any of them. -If a normal call is ended in this fashion by an EOL, -the EOL or CRLF is thrown away. - -MIDAS Node: syntax-footnote, Up: Calls-1c - -MACRO ARGUMENT SYNTAX - -* Menu - -* Normal: calls-2 -* Balanced: calls-3 -* Wholeline: calls-4 -* Strung: calls-5 -* Keepstrung: calls-6 -* Evaluated: calls-7 - -MIDAS Node: Calls-1d, Previous: Calls-1c, Up: Calls-1 - -PARENTHESIZED CALLS. - -In these calls, the macro name is followed by an OPEN. The assignment -of values to dummies procedes as in a normal call. At the end, though, -characters are thrown away until and including a CLOSE that matches the -OPEN. In the matching, parens and brackets within the values of -dummies are not considered. Also, only the number of brackets seen is -remembered - not what kind. There is nothing to stop a "(" from matching -a ">" at this stage. Parenthesized calls are most useful with macros whose -dummies are balanced - then the macro call is guaranteed -to terminate precisely at that closeparen that matches the initial -openparen, regardless of whether enough or too many argumentss -are present in between. Note that where. below, the macro call is said -to be "ended", in a parenthesized call that really means -that scanning for the matching closeparen will begin. - -MIDAS Node: Calls-2, Previous: Calls-1, Up: Calls, Next: Calls-3 - -THE "NORMAL" ARGUMENT SYNTAX. - -MIDAS begins scanning for a normal argument by examining -the first character. - -* Menu: - -* Bracket: calls-2a First Character is "[". -* Slash: calls-2b First Character is "\". -* Comma: calls-2c First Character is ",". -* EOL/SEMI: calls-2d First Character is an EOL or semicolon. -* Otherwise: calls-2e Otherwise. - -MIDAS Node: Calls-2a, Up: Calls-2, Next: Calls-2b - -FIRST CHARACTER IS "[". - -All the text up to the matching "]", not including either of them, is part -of the dummy's value, and the scanning of the next dummy -begins with the character after the "]". -If a normal argument is delimited by squarebrackets, -it is never unspecified or nullspecified, even if the value -between the squarebrackets is the null string. -Thus, when a dummy has a default value, it is possible to specify -the null string explicitly in the call, overriding the default. - -MIDAS Node: Calls-2b, Previous: Calls-2a, Up: Calls-2, Next: Calls-2c - -FIRST CHARACTER IS "\". - -A field is read (leading spaces ignored) -and the field's value, converted to a string using MIDAS's current -radix, is used as the value of the dummy. In this case the scan -of the next argument begins with the character after the field terminator. -Arguments specified in this way are never unspecified or nullspecified. - -MIDAS Node: Calls-2c, Previous: Calls-2b, Up: Calls-2, Next: Calls-2d - -FIRST CHAR IS ",". - -In this case, the dummy is nullspecified (see *Note UNSPEC:calls-8.). -The scan for the next dummy, or the text to be handled after -the macro call if there are no more dummies, starts after the comma. - -MIDAS Node: Calls-2d, Previous: Calls-2c, Up: Calls-2, Next: Calls-2e - -FIRST CHARACTER IS AN EOL OR SEMICOLON. - -This dummy is unspecified (*Note UNSPEC:calls-8,) and so are all -remaining dummies. The scan for the remaining dummies will not -attempt to read any characters. If the terminator was an EOL, -and the call is a normal one, the EOL or CRLF will be thrown away -at the end of macro call processing (*Note NORMAL:calls-1c.). - -MIDAS Node: Calls-2e, Previous: Calls-2d, Up: Calls-2 - -OTHERWISE. - -All text, including the first character, -up to the first comma, semicolon or EOL goes into the argument, -except that tabs and spaces before a semicolon are ignored. -Then, depending on the terminating character, action is taken as -in *Note COMMA:calls-2c, or *Note SEMI/EOL:calls-2d, except that in -neither case is the present dummy nullspecified or unspecified, -since a nonnull value has already been specified for it. - -MIDAS Node: Calls-3, Previous: Calls-2, Up: Calls, Next: Calls-4 - -THE "BALANCED" ARGUMENT SYNTAX. - -When a dummy uses the balanced syntax, MIDAS insists that its -value contain no unbalanced brackets. -That is, while scanning for the end of the argument, MIDAS counts -opens and closes, and will not let anything terminate the argument -when the count is nonzero. Also, unmatched closes will not be allowed -into the argument - they will terminate the argument and the macro -call. When the bracket count is zero - that is, when it is permissible -for the argument to terminate - a comma, semicolon, or EOL will -do it, just as if the dummy used the normal syntax. -That is, unspecification or nullspecification of the present dummy -or the remaining dummies may happen, as described in B.2.c-B.2.e. -Termination by an unmatched close is like termination by an EOL (B.2.d). -For balanced dummies, "[" or "\" as the first character have -no special significance. - -MIDAS Node: Calls-4, Previous: Calls-3, Up: Calls, Next: Calls-5 - -THE "WHOLELINE" ARGUMENT SYNTAX. - -The scan for a wholeline argument stops only when an EOL is -encountered. Thus, the value of a wholeline argument is everything -up to but not including the first eol. While an EOL that -terminates a normal or balanced argument ends the macro call, thus -making all remaining dummies unspecified, the EOL that ends a -wholeline argument does not do so. The EOL or CRLF is thrown away, -and scanning for the next dummy starts on the next line. -A wholeline dummy is never unspecified or nullspecified (except -that it will of course be unspecified if the macro call is terminated -by an EOL ending some previous non-wholeline dummy). - -MIDAS Node: Calls-5, Previous: Calls-4, Up: Calls, Next: Calls-6 - -THE "STRUNG" ARGUMENT SYNTAX. - -A strung argument looks just like the argument to ASCII or SIXBIT: -it is bounded on both sides by an arbitrarily chosen delimiter. -When the argument is scanned, first non-space character is taken -to be the delimiter, and everything up to the second occurrence -of that character is part of the argument's value. Semicolon, -EOL, comma, and closebrackets of various kinds, cannot be used as -the delimiter, because if they are seen when the opening delimiter -is expected they will nullspecify the argument and (except for comma) -end the macro call, as they would in the balanced syntax. The -closing delimiter should be followed by an appropriate argument -terminator such as comma, semicolon, EOL, or a closebracket (but -spaces and tabs may intervene); all except comma end the macro -call, while comma allows more arguments to follow. - -MIDAS Node: Calls-6, Previous: Calls-5, Up: Calls, Next: Calls-7 - -THE "KEEPSTRUNG" ARGUMENT SYNTAX. - -A keepstrung argument is exactly like a strung argument, except that the -delimiters are retained. This is useful for passing on such arguments -to other macros or pseudos, without having to worry about -what delimiters to use, since appropriate ones will be included with -the argument itself. - -MIDAS Node: Calls-7, Previous: Calls-6, Up: Calls, Next: Calls-8 - -THE "EVALUATED" ARGUMENT SYNTAX. - -An evaluated argument is passed by value instead of by name. -When it is time to scan for such an argument, a field is read -in and evaluated, and the value is converted to a string by -expressing it as a number in the current radix. This is exactly -like the treatment of a normal argument whose value starts with -"\", except that the "\" is not present itself in the call -(see *Note SLASH:calls-2b.). - -MIDAS Node: Calls-8, Previous: Calls-7, Up: Calls, - -WHAT HAPPENS TO DUMMIES THAT ARE UNSPECIFIED. - -Whether a dummy is unspecified in a particular -call depends on what came in the call before the place -where the dummy's value should have been, and on the variety of -argument syntax used by the dummy. Similarly, the criterion for -being nullspecified depends on the argument syntax used. However, -the consequences of being unspecified or nullspecified are independent of -the argument syntax used. Instead, they depend on the other part -of the bindclass of the dummy: whether it is to be nullified, -gensymmed, or defaulted to a pre-specified value. - -MIDAS Node: Calls-8a, Up: Calls-8, Next: Calls-8b - -nullified dummies. - -When a dummy defined as nullified is unspecified or nullspecified, -it is given the null string as its value. Most dummies of most macros -used are of bindclass nullified. - -MIDAS Node: Calls-8b, Previous: Calls-8a, Up: Calls-8, Next: Calls-8c - -gensymmed dummies. - -If a gensymmed dummy is unspecified, -its value will be a GENERATED SYMBOL -6 characters long - the first character "G"; the rest, -a number in the current radix whose value equals that of .GSCNT, -which starts out as 0 and is incremented before each gensymming. -Thus, in each call, an unspecified gensymmed dummy -will provide a unique label. -If nullspecified, a gensymmed dummy has the null string as a value. -Gensymmed dummies are treated differently when nullspecified -or unspecified for compatability with old versions of MIDAS. -In fact, the distinction between unspecification and nullspecification -is made only to handle this case. - -MIDAS Node: Calls-8c, Previous: Calls-8b, Up: Calls-8 - -defaulted dummies. - -If a defaulted dummy is nullspecified or unspecified, - its default value will be used as its value in that call. - - -MIDAS Node: Examples, Previous: Calls, Up: Macros, Next: Remote - -EXAMPLES OF MACRO DEFINITIONS AND CALLS. - -* Menu: - -* Normal: Example-1 Normal (Nullified And Defaulted) Arguments. -* Balanced: Example-2 Balanced Arguments. -* Gensymming: Example-3 Gensymming. -* Wholeline: Example-4 Wholeline Arguments. -* Keyword: Example-5 "By Keyword" Dummies. -* Strung: Example-6 Strung And Keepstrung Dummies. -* Evaluated: Example-7 Evaluated Dummies. - -MIDAS Node: Example-1, Up: Examples, Next: Example-2 - -NORMAL (NULLIFIED AND DEFAULTED) ARGUMENTS. - -DEFINE MACRO1 A,B=FOO,C ;3 DUMMIES; SECOND DEFAULTED. - A ? B ? C TERMIN - -MACRO1 1,2,3 -; 1 ? 2 ? 3 - -MACRO1 [FOO,,BAR]2,3 -; FOO,,BAR ? 2 ? 3 - ;Showing how to put commas, etc. in args. - -MACRO1 1,,3 ;2nd arg nullspecified and defaulted. -; 1 ? FOO ? 3 - -MACRO1 1,[]3 ;2nd specified as null, not nullspecified. -; 1 ? ? 3 - -MACRO1 1,2 ;3rd arg unspecified. -; 1 ? 2 ? - -MACRO1 1 ;2nd and 3rd args unspecified; 2nd defaulted. -; 1 ? FOO ? - -MIDAS Node: Example-2, Previous: Example-1, Up: Examples, Next: Example-3 - -BALANCED ARGUMENTS. - -DEFINE MAC2 ?A,B ;2 BALANCED DUMMIES. - A ? B ? BLETCH -TERMIN - -DEFINE MAC2(A,,B,,),, ;another way to define the same macro. - A ? B ? BLETCH -TERMIN - -DEFINE MAC2A A,B ;SIMILAR BUT DUMMIES NOT BALANCED. - A ? B ? BLETCH -TERMIN - -MAC2 , -; ? ? BLETCH - -MAC2A , -; ? BLETCH -; - ;Note that the first dummy was bound to "". - ;The "" wasn't even part of the call. - -MAC2(FOO,-1(P))+1 -; FOO ? -1(P) ? BLETCH+1 - ;A parenthesized call. Note that the closeparen - ;ends the second arg and the macro call, and is thrown away. - -MAC2 FOO,-1(P)+1 -; FOO ? -1(P)+1 ? BLETCH - -DEFINE SQR (X) -<*>TERMIN ;this macro squares its arg. - -1+SQR(2)*3 ;a parenthesized call. -;1+<<2>*<2>>*3 -;note that 1+SQR(2>*3 would have the same effect. - -3*<1+SQR 2>-4 -;3*<1+<<2>*<2>>>-4 - ;Here we have, not a parenthesized call, - ;but an ordinary call within parens. - ;The ">" ends the argument to SQR and is not thrown away. - -MIDAS Node: Example-3, Previous: Example-2, Up: Examples, Next: Example-4 - -GENSYMMING. - -DEFINE GENMAC \FOO,BAR - FOO,,BAR -TERMIN - -GENMAC X+1,Y ;Both args specified nonnull. -; X+1,,Y - -GENMAC X+1,, ;Second arg nullspecified. -; X+1,, ;Nullspecified args are not gensymmed. - -GENMAC X+1 ;Second arg unspecified. -; X+1,,G00001 - -GENMAC X+1 ;Note uniqueness of gensyms. -; X+1,,G00002 - -GENMAC() ;Both args unspecified -; G00003,,G00004 - - -GENMAC(,) ;First arg nullspecified; second, unspecified. -; ,,G00005 - -MIDAS Node: Example-4, Previous: Example-3, Up: Examples, Next: Example-5 - -WHOLELINE ARGUMENTS. - -DEFINE FOOWH A-B ;first arg normal; second, wholeline. - A - B -TERMIN - -FOOWH 1,2,3,4 -; 1 -; 2,3,4 - -FOOWH 1 -; 1 -; - -DEFINE BARWH -A B ;both args wholeline. - A - B -TERMIN - -BARWH 1,2,3 ;note that each arg requires a line. -4,5,6 ;a comment on the line is part of the arg. - ;that is, semicolon isn't special. -; 1,2,3 ;note that each arg requires a line. -; 4,5,6 ;a comment on the line is part of the arg. - -MIDAS Node: Example-5, Previous: Example-4, Up: Examples, Next: Example-6 - -"BY KEYWORD" DUMMIES. - -DEFINE KWDM +A,B,C=FOO,+ ;all three arguments by keyword. - A - B - C -TERMIN - -KWDM B=1, A =2 -; 1 -; 2 -; FOO - -KWDM C=1 -; -; -; 1 - -DEFINE KWD1 A=1,+B=2,C=3,+D=4 ;B and C are by keyword; A and D are by order. - A ? B ? C ? D -TERMIN - -KWD1 100,,200 ;both A and D but neither B nor C specified. -; 100 ? 2 ? 3 ? 200 - -KWD1 10,C=11 ;A and C specified. -; 10 ? 2 ? 11 ? 4 - -KWD1 ,B=20,C=21,,40 ;B, C and D specified; A was nullspecified. -; 1 ? 20 ? 21 ? 40 - -MIDAS Node: Example-6, Previous: Example-5, Up: Examples, Next: Example-7 - -STRUNG AND KEEPSTRUNG DUMMIES. - -DEFINE TYPEZ *STR* ;STR is strung. - OUTUUO [ASCIZ ^@STR -^@]TERMIN ;note ctrl-@ used as delimiter of ASCIZ. - -TYPEZ /UNDEFINED SYMBOL/ -; OUTUUO [ASCIZ ^@UNDEFINED SYMBOL -;^@] - -FOO== ;Here a closebracket follows the string. -;FOO==< OUTUUO [ASCIZ ^@WHY FOO? -;^@]> - -TYPEZ(:MYSTERIOUS ERROR:) ;A parenthesized call, and a strange delimiter. -; OUTUUO [ASCIZ ^@MYSTERIOUS ERROR -;^@] - -DEFINE ASCNT &KSTR& ; KSTR is keepstrung. -.LENGTH KSTR,,[ASCII KSTR]!TERMIN - -OUTUUO [ASCNT "String=^@"] ; Note that delimiters are kept with argument. -;OUTUUO [.LENGTH "String=^@",,[ASCII "String=^@"]] - - -DEFINE 2STRS *A=UGH,B* ;Two strung arguments, one defaulted. - ASCIZ /A,B/ -TERMIN - -2STRS =FOO= ;Call ended after 1st string -; ASCIZ /FOO,/ - -2STRS .FOO.,-BAR- -; ASCIZ /FOO,BAR/ - -2STRS ,/BAR/ ;Here no 1st argument is given -; ASCIZ /UGH,BAR/ - -2STRS //,/BAR/ ;Here an explicit null string is given. -; ASCIZ /,BAR/ - -MIDAS Node: Example-7, Previous: Example-6, Up: Examples - -EVALUATED DUMMIES. - -DEFINE TYPECH #CHAR ;CHAR is evaluated. - MOVEI A,CHAR - PUSHJ P,TYO -TERMIN - -TYPECH 40 ;Print a space. -; MOVEI A,40 -; PUSHJ P,TYO - -TYPECH "; ;Print a semicolon -; MOVEI A,73 ;73 is the value of ";. -; PUSHJ P,TYO ;This would not be possible with normal - ;or balanced syntax, since the ";" would - ;be an argument terminator. - -DEFINE TYPEI (CHAR) ;CHAR balanced instead of evaluated - MOVEI A,CHAR - PUSHJ P,TYO -TERMIN - -TYPECH "0(B) ;Print C(B) as a digit. -; MOVEI A,"0(B) ;This would not work with TYPECH, -; PUSHJ P,TYO ;Since CHAR would evaluate to B,,"0 - ;giving MOVEI A, = MOVEI A,"0. - -MIDAS Node: Remote, Previous: Examples, Up: Macros - -The "REMOTE MACRO" construction. - -It is often desirable to use a macro as if it were a string variable, -appending text to it little by little and then accessing the whole -text as accumulated at some time. A way to do this is as follows: - -;initialization: - - IF1 [DEFINE BNKBLK OP - OP - TERMIN ] ;BNKBLK accumulates text. - - DEFINE BLCODE NEWCFT - BNKBLK [DEFINE BNKBLK OP - OP]NEWCFT - TERMIN - TERMIN ;BLCODE adds its arg to the end of BNKBLK. - -;add some text: - - BLCODE [FOO] ;add FOO. - BLCODE [BAR] ;add BAR (note BLCODE inserts CRLF's, too). - -;assemble what has been accumulated: - - BNKBLK ;which expands into ... -; FOO -; BAR - -In understanding this example, it is necessary to realize that MIDAS -is a string-processing language that just happens to produce binary -output as a side effect. It does not matter whether an expression -appears to be properly nested with the various sorts of syntactic -bracket (such as [-] and DEFINE-TERMIN) because the order the brackets -are processed in may not be the order they appear in - especially -since not all phases of processing look for all types of bracket. -For example, when BLCODE is called, it calls BNKBLK with argument -"DEFINE BNKBLK OPOP". That there is an unmatched DEFINE in that -argument does not matter because DEFINE is not special at macro -call time or macro expansion time. Since BNKBLK substitutes its arg -in, there will be an unmatched DEFINE in the expansion of BNKBLK. -So, when MIDAS expands BNKBLK, it will begin processing the DEFINE, -and it will keep on reading for the new macro definition past the -end of BNKBLK. That is not a problem, because AFTER the call to -BNKBLK, within BLCODE, there is a TERMIN that will make MIDAS -end the new macro definition. The inner DEFINE and TERMIN appear -to match in a simple minded way, which is necessary since otherwise -it would be difficult to define BLCODE containing them, but when -BLCODE is called they actually match up in a much more complicated way. -To get a full understanding of exactly what expands into what, -assemble such a segment of program with the (L) switch. The listing -will show not only macro calls but what they expand into. - -Two other examples using this construct follow. -They use a modification of the remote-macro hack -to accumulate things in the reverse -of the order they are put in. - -;Backwards IRP: to get the backwards version of -;IRP FO,BA,[mumble] -; body!TERMIN -;use -;IRPB FO,BA,[mumble][body] - - DEFINE IRPB X,Y,Z,BODY ;IRP BACKWARDS - DEFINE 1IRPB1 FOO - FOO!TERMIN - DEFINE 2IRPB2 BAR - 1IRPB1 [DEFINE 1IRPB1 FOO - FOO - BAR]TERMIN - TERMIN - IRP X,Y,[Z] - 2IRPB2 [BODY] - TERMIN - 1IRPB1 - TERMIN - -;LISP-style PROGs in MIDAS - use these macros as follows: -; PROG [X,Y,Z] ;X, Y, and Z are the locals. -; body of subroutine -; ENDPROG - - DEFINE PROG VARS - IRP X,,[VARS] - PUSH P,X - TERMIN - DEFINE ENDPROG FOO - FOO - TERMIN - DEFINE 2PROG2 BAR - ENDPROG [DEFINE ENDPROG FOO - FOO - BAR]TERMIN - TERMIN - IRP X,,[VARS] - 2PROG2 [POP P,X] - TERMIN - TERMIN - -MIDAS Node: Loops, Up: Top, Previous: Macros, Next: Cond - -Midas Assembly-time Loops - -Loops are useful for many reasons. One might merely wish to -initialize the contents of a table in a simple pattern. -One might also use a loop in conjuntion with macros, in -all the ways loops are used in other programming languages. -The loops that exist in MIDAS are REPEAT and -the various kinds of IRP. Because MIDAS canned loops -all begin with pseudoops, they will only be recognized and -expanded where a symbol would be evaluated -(not within comments, failing conditionals, macro definitions, -text strings, etc.). - -* Menu: - -* REPEAT: loops-A -* IRP: loops-B -* Particulars: loops-C Particular Types Of IRP. - -Node: loops-A, Up: loops, Next: loops-B - -REPEAT. - -REPEAT is used to assemble a single string (called the REPEAT string) -several times - like a DO in PL-1 or MACLISP. The REPEAT string need -not assemble into the same thing each time, however, because each -assembly of the string may have side effects that alter the action of -the next. - -* Menu: - -* Syntax: loops-A1 Syntax of REPEAT -* Expansion: loops-A2 -* RPCNT: loops-A3 -* STOP: loops-A4 -* ISTOP: loops-A5 -* Jumping: loops-A6 .GO and .TAG inside REPEAT - -Node: loops-A1, Up: loops-A, Next: loops-A2 - -SYNTAX. - -The REPEAT pseudoop should be followed by a field whose -value is the number of times the REPEAT string is to -be repeated. That string follows immediately after the field. -The syntax of the REPEAT string is the same as that -of the string in a conditional. If the first character after -the space or comma that ends the field is a "[", then all -characters up to the matching "]", not including either of the -brackets, make up the string to be repeated. Otherwise, that -first character itself and all characters up to the next EOL -make up the REPEAT string. The EOL or CRLF is -thrown away, and a CRLF is added to the end of the REPEAT -string, in the case that square brackets are not used. - -Node: loops-A2, Previous: loops-A1, Up: loops-A, Next: loops-A3 - -EXPANSION. - -A REPEAT expands by substituting the REPEAT string -into the assembler input stream appropriately many times. For example, - - REPEAT 5, SETZ ? 500 - -is equivalent to - - SETZ ? 500 - SETZ ? 500 - SETZ ? 500 - SETZ ? 500 - SETZ ? 500 - -where the REPEAT string is "SETZ ? 500 ". -Each time through except the last, the last character -of the string will be followed immediately by the first character -of the string. To illustrate, - - 0,,REPEAT 3,[.+1 - 10,,]0 - -expands into - - 0,,.+1 - 10,,.+1 - 10,,.+1 - 10,,0 - -This example also shows that there is no need for the -boundary between one pass through the string and the -next to coincide with any logical -division in the resulting concatenated text (such as a word -or field boundary); the several passes through the string may -all be part of one syllable if they do not contain any syllable -separators! (for example, REPEAT 3,['A] = 'A'A'A = (SIXBIT/AAA/)). - -Node: loops-A3, Previous: loops-A2, Up: loops-A, Next: loops-A4 - -.RPCNT. - -During the expansion of a REPEAT, the symbol .RPCNT -has the value of the number of completed passes through the REPEAT; -that is, it is 0 the first time through, 1 the second, etc. -When nested REPEATs are used, .RPCNT always refers to the innermost REPEAT. -For example, - - REPEAT X,[.RPCNT+]0 is X*/2 for X >= 0. - REPEAT X,[<.RPCNT+1>*]1 is FACTORIAL(X). - -Node: loops-A4, Previous: loops-A3, Up: loops-A, Next: loops-A5 - -.STOP. - -When the pseudoop .STOP is executed in a REPEAT, the -pass through the REPEAT then in progress is ended. .STOP -is like a jump to the label on the END of a DO in PL-1. -The character after the "P" of .STOP is ignored; the next -character asembled will be the first character of the REPEAT -string (if there are more repetitions to go) or the one after -the "]", EOL or CRLF that ended the REPEAT string. -Thus, - - REPEAT 5,[ - FOO - IFE BAR,.STOP - - ] - -is equivalent to (but assembles faster if BAR is 0 than) - - REPEAT 5,[ - FOO - IFN BAR,[ - - ]] - -Note that it currently loses to put .STOP (or .ISTOP) inside a -bracketed conditional within the REPEAT. For details and reasons, -see *Note MACROS:macros. The way to avoid this problem is to use -braces instead of brackets in conditionals that surround .STOP's. -The same applies to .ISTOP, .GO and .TAG. - -Node: loops-A5, Previous: loops-A4, Up: loops-A, Next: loops-A6 - -.ISTOP. - -.ISTOP is like .STOP, but also inhibits all further -repetitions of the REPEAT string. It is like a jump to a -label after the END of a DO in PL-1. The character after -the "P" is ignored; the next character assembled is the one after -the "]", EOL or CRLF that ended the REPEAT string. -For example, - - REPEAT 36.,[ - FOO==.RPCNT - IFN BAR&<1_.RPCNT>,.ISTOP - ] - -sets FOO to the number of trailing zeros in BAR. - -Node: loops-A6, Previous: loops-A5, Up: loops-A - -.GO AND .TAG - -The pseudos .GO and .TAG may be used inside REPEAT's -just as in macros. See *Note JUMPING:jumping. - -Node: loops-B, Previous: loops-A, Up: loops, Next: loops-C - -IRP'S IN GENERAL. - -IRP's in MIDAS are somewhat analogous to MAPCAR -in LISP. In an IRP, a dummy name is supplied and also -a string to repeat (called the IRP BODY) and a string -(called the IRP STRING) to -take substrings from according to a prespecified syntactical -rule which depends on which IRP pseudoop is used. The IRP -body is assembled several times, with the dummy name bound to -successive substrings of the string being IRP'ed over. -For example, - - IRP X,,[1,4,5] - FOO+X ? TERMIN - -expands into - - FOO+1 ? FOO+4 ? FOO+5 - -X is the dummy, "1,4,5" is the IRP string, -"1", "4", and "5" are the substrings, -and "FOO+X ? " is the IRP body. - -Node: loops-B1, Up: loops-B, Next: loops-B2 - -SYNTAX OF IRP'S. - -All kinds of IRP have the same syntax (except that IRPNC is slightly -different). After the pseudoop itself come any number of IRP GROUPS, -which make up the IRP HEADER (most IRP's have only one group) then comes -the IRP body, which is just like a macro body (see *Note BODY:Body.). - -Node: loops-B2, Previous: loops-B1, Up: loops-B, Next: loops-B3 - -IRP GROUPS. - -Each IRP group specifies one repetition to be done. -It contains one string to take substrings from, and two -dummies to put them in. The dummy names come first, and -should be terminated by commas. If one of the dummies -would not be referred to in the IRP body, it may be omitted -from the IRP group, but the comma in its position may not -be omitted (if a comma is missing, MIDAS will sometimes be -able to detect that fact, in which case MIDAS will print an -error message and assume there is no second dummy. However, -a missing comma is not always detectable). The string to take -substrings from comes after the second comma, -and its syntax is that of a normal macro argument, -except that "\" is not special as the first character. -f the first character encountered after the string is read is -a squoze character or a comma, MIDAS assumes that it begins -another group. Otherwise, the group just ended is the last one. -This means that if the string is terminated by a "]" or comma, -the character following determines whether another group follows, -while if the string is ended by an EOL or ";", there are -automatically no more groups. -The EOL or ";", or whatever character follows the comma or "]", -is thrown away. If the next character is a LF, it too is discarded. -A comment following the IRP header will lose. The best possibility is -that it will merely go in the IRP body. The worst is that the ";" -will be one of the characters thrown away and, causing total lossage. -An example of an IRP with several groups is - - IRP X,,[1,2,3]Y,,[4,5] - ASCIZ \X+Y\ - TERMIN - -which expands into - - ASCIZ \1+4\ - ASCIZ \2+5\ - ASCIZ \3+\ - -Node: loops-B3, Previous: loops-B2, Up: loops-B, Next: loops-B4 - -THE IRP BODY. - -The body of an IRP is just like the body of a macro definition. -The dummy arguments mentioned in the IRP header may be used -in the IRP body, representing requests for the corresponding -substrings of the IRP strings to be substituted in. -Concatenation with "!", and .QUOTE, may be used as in -macro definitions. The IRP body is ended by a TERMIN, -just like a macro body. Because of this, the character after -the "N" of the TERMIN wil be discarded. Also for that reason, -IRP's are expected to be matched by TERMIN's within macro -bodies and IRP bodies. For example, in - - DEFINE INSIRP INSN,ADDR - IRP X,,[ADDR] - INSN,ADDR - TERMIN - TERMIN - -the first TERMIN matches the IRP; the second, the DEFINE. -When the DEFINE executes, it increments its counter on seeing -the IRP, and decrements it on seeing the first TERMIN, so the -second TERMIN ends the macro body. A call to INSIRP -expands into a string containing the IRP and the first TERMIN, -which closes the IRP body when the IRP executes. The result is that in - - INSIRP PUSH P,[A,B,C] - -NSN's value is "PUSH P" and ADDR's is "A,B,C". -The macro call expands into - - IRP X,,[A,B,C] - PUSH P,X - TERMIN - -which expands into - - PUSH P,A - PUSH P,B - PUSH P,C - -Node: loops-B4, Previous: loops-B3, Up: loops-B, Next: loops-B5 - -IRP EXPANSION - -An IRP should be thought of as first defining an internal -macro whose body is the IRP body, and whose dummy args are -the dummies mentioned in the IRP header, and then calling that -macro repeatedly with arguments which are substrings -of the IRP strings, chosen according to the rule for -the particular IRP pseudoop that was used. -Each call made to the internal macro constitutes one pass -through the IRP. -When an IRP has several groups, on every pass through the IRP -each group is stepped to its next substring, independently of -the other groups. The expansion of the IRP stops (that is, no -more passes through it are made) only when ALL of the groups -are exhausted (the ends of all the IRP strings have been -reached). - -Node: loops-B5, Previous: loops-B4, Up: loops-B, Next: loops-B6 - -.STOP, .ISTOP, .GO AND .TAG. - -These pseudoops, when executed in an IRP expansion, act the way they -do in REPEAT's. That is, .STOP ends only the current pass of the IRP, -while .ISTOP also prevents any future passes from starting. -See *Note WHOLELINE:Body-4(A.4) and *Note STRUNG:Body-5(A.5). - -Node: loops-B6, Previous: loops-B5, Up: loops-B - -.IRPCNT. - -While an IRP is being expanded, .IRPCNT has the value -of the number of completed passes through the IRP -(0 the first pass, 1 on the next, etc.). When nested -IRP's are used, .IRPCNT refers to the innermost one. Thus, - - IRP AC,,[NIL,A,B,C,D,E,F,G,H,I,J,K,L,M,N,P] - AC==.IRPCNT - TERMIN - -defines all the ACs with the specified names. - -Node: loops-C, Previous: loops-B, Up: loops - -PARTICULAR TYPES OF IRP. - -The previous section described what all the IRP pseudoops -have in common. This section describes the peculiar details -of each IRP pseudoop. The IRP pseudoops differ in how -they divide the IRP strings into substrings, and in how they -choose the values to be given to the two dummies of each group. - -* Menu: - -* C: loops-C1 IRPC (Indefinite Repeat on Characters). -* W: loops-C2 IRPW (Indefinite Repeat on Words). -* S: loops-C3 IRPS (Indefinite Repeat on Syllables). -* IRP: loops-C4 IRP (Indefinite Repeat (on elements)). -* NC: loops-C5 IRPNC (Indefinite Repeat on Characters). -* Example: loops-C6 A Complicated IRP Example. - -Node: loops-C1, Up: loops-C, Next: loops-C2 - -IRPC (INDEFINITE REPEAT ON CHARACTERS). - -IRPC scans the IRP strings a character at a time. -Each time through the IRP body, the first dummy of each group -is set to the next successive character of the group's IRP string, -(or to the null string if the IRP string is exhausted), and -the second dummy is set to the remainder of the IRP string - -the part that follows the character that the first dummy is set to. -For example, in - - IRPC X,Y,[ABCDE]A,B,1234,U,,[+-+-] - ASCIZ /X,Y,A!U!B/ - TERMIN - -the dummies are X and Y in the first group, A and B in -the second, and U in the third (which has no second dummy). -The IRP strings are "ABCDE", "1234", and "+-+-". -The expansion is - - ASCIZ /A,BCDE,1+234/ - ASCIZ /B,CDE,2-34/ - ASCIZ /C,DE,3+4/ - ASCIZ /D,E,4-/ - ASCIZ /E,,/ - -Node: loops-C2, Previous: loops-C1, Up: loops-C, Next: loops-C3 - -IRPW (INDEFINITE REPEAT ON WORDS). - -IRPW takes the IRP strings a line at a time (ignoring null lines). -On each pass, the next nonnull line of every IRP string is used up. -The first dummy of each group is set to the part of the line -up to the first semicolon, and the second dummy is set -to the part that follows the semicolon (or to the -null string if there is no semicolon on the line). -The semicolon, if any, does not become part of either dummy. -Unfortunately there -is no way to tell whether the line contained no semicolon, or there -was only one semicolon and it was the last character - in either case -the second dummy will be null. For example, - - IRPW X,Y,[ - FOO ;BAR - FOO1 ;MUMBLE - ] - [X] ;; Y - TERMIN - -expands into - - [ FOO ] ;; BAR - [ FOO1 ] ;; MUMBLE - -Node: loops-C3, Previous: loops-C2, Up: loops-C, Next: loops-C4 - -IRPS (INDEFINITE REPEAT ON SYLLABLES). - -IRPS attempts to scan the IRP strings a syllable at a time. -However, it is not smart enough to duplicate the actions of the -MIDAS syllable reader perfectly. In actuality, it divides the IRP -string into syllables which are strings of consecutive squoze characters separated -by strings of consecutive nonsquoze characters. On each pass, -the first dummy of each group is set to the next string of -consecutive squoze characters found in the IRP string of the group, -or to the null string if the group's IRP string is exhausted, -and the second dummy is set to the non-squoze character that -terminates the run of squoze characters (or to the null string -if there is none, because the first dummy's value reaches to the -end of the IRP string or the IRP string is exhausted). For example, - - IRPS X,Y,[A+B+C+ D+,E+ ,, &/!,F-G- H-I+] - X==Y!100 - TERMIN - -sets A, B, C, D, E, and I to +100 and F, G, and H to -100. -The extra spaces, commas, and "&/!" in the IRP string do not matter, because -only the first non-squoze character after each syllable becomes the -value of the second dummy Y. Extra CRLF's or + or - signs -could also have been inserted at the same places without effect. - -Node: loops-C4, Previous: loops-C3, Up: loops-C, Next: loops-C5 - -IRP (INDEFINITE REPEAT (ON ELEMENTS)). - -IRP regards the IRP string as a list of elements -separated by commas, and scans the IRP string an element at -a time. An EOL or CRLF will also separate elements but since -null elements are not ignored the CRLF or EOL should be used -instead of a comma, not in addition to one. -Square brackets are also special in the scan of the IRP string. -The actual algorithm used by IRP to find the end of the next -element is that a comma, EOL or CRLF (or the end of the IRP string) -ends the element, and an "[" -is flushed but causes commas and EOLs (and therefore CRLFs) -not to be special until the matching "]", which is flushed. -Note that this resembles but is distinctly different from the -normal macro argument syntax rules. -On each pass through the IRP, the first dummy of each group is set -to the next element in the IRP string of that group, and the second -dummy is set to the rest of the IRP string (starting after the -comma, EOL or CRLF that ended the element). Note that the commas, EOLs and -CRLFs that separate the remaining elements will be present in the second -dummy's value, as will square brackets that are doomed to be flushed when -the elements they are part of are reached by the scan. -For example, - - IRP X,Y,[123 4,56789 - ABCD[EF]GH,[IJ,],K] - ASCIZ /X:Y/ - TERMIN - -expands into - - ASCIZ /123 4:56789 - ABCD[EF]GH,[IJ,],K/ - ASCIZ /56789:ABCD[EF]GH,[IJ,],K/ - ASCIZ /ABCDEFGH:[IJ,],K/ - ASCIZ /IJ,:K/ - ASCIZ /K/ - -Node: loops-C5, Previous: loops-C4, Up: loops-C - -IRPNC (INDEFINITE REPEAT ON CHARACTERS). - -IRPNC is similar to IRPC, but more general. It allows the -characters of the IRP strings to be taken not only one at a time, -but any fixed number at a time. Also, it may be told to -ignore any number of characters at the beginning of each of the IRP -strings, or to limit the number of passes to be made to -a specified maximum value. IRPNC may be used to take an arbitrary -substring of a string, or to index into a string. - -* Menu: - -* Syntax: loops-C5a Syntactic Differences between IRPNC and Other IRP's -* Expansion: loops-C5b Expansion. -* Applications: loops-C5c Applications. - -Node: loops-C5a, Up: loops-C5, Next: loops-C5b - -Syntactic Differences between IRPNC and Other IRP's - -IRPNC's syntax differs from that described in B.1 in that after -the IRPNC pseudoop itself, before the first IRP group, there come -three numeric arguments, terminated by commas. -They specify the number of characters -to ignore at the beginning of each IRP string (to be referred to as -), the number of characters to take from each IRP string per pass -(to be referred to as ), and the maximum number of passes allowed -(to be referred to as

).

may be -1, meaning that the -number of passes is not numerically limited. If

is 0, -the IRPNC is not expanded at all. If is less than 1, it is -defaulted to 1. If is negative, it is defaulted to 0. - -Node: loops-C5b, Previous: loops-C5a, Up: loops-C5, Next: loops-C5c - -Expansion. - -On each pass, the first dummy of each group is set to the next - characters of the group's IRP string (or the whole remainder -of the IRP string if fewer than characters remain). -On the first pass, instead of using the first characters of -the IRP string, which would be like all the other kinds of IRP, - characters are skipped and the next are used. (If the IRP string -contained fewer than characters to begin with, it is considered to -be exhausted starting from the first pass). The second dummy -is set to the remainder of the IRP string, following the characters -forming the first dummy's value, but containing only those -characters that will eventually get into the first dummy. That is, if -the number of passes has been limited, the characters of the IRP -string that will never appear in the first dummy because it -would take too many passes to get that far, will not appear in the -value of the second dummy on any pass. - -Node: loops-C5c, Previous: loops-C5b, Up: loops-C5 - -Applications. - -To take an arbitrary substring of a string, limit the IRPNC to -a single pass. To select characters -FOO through FOO+10 of the dummy name BAR, - - IRPNC FOO,11,1,X,,[BAR] - ;in here, use X to refer to the desired substring - TERMIN - -To convert a SIXBIT value to text, index into a string of all -the SIXBIT characters in order. This IRPNC will -type on the terminal the version number of the program (using .FNAM2). - - REPEAT 6,[ - IFE .FNAM2_<6*.RPCNT>,.ISTOP - ;GIVE UP IF ONLY SPACES REMAIN. - TEMP==77&<.FNAM2_<6*<5-.RPCNT>>> - ;ISOLATE THE NEXT CHAR TO BE TYPED - IRPNC TEMP,1,1,X,,[ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_] - PRINTX aXa ;NOTE LOWER CASE "a" IS NOT SIXBIT - TERMIN - ] - -To XOR together all the words of an ASCII string, -use this macro: - - DEFINE FOO STRING - < - IRPNC 0,5,-1,BAR,,[STRING] - ASCII /BAR/#TERMIN - >TERMIN - -Node: loops-C6, Previous: loops-C5, Up: loops-C - -A COMPLICATED IRP EXAMPLE - -This shows how to assign several symbols default values (that is, -set them only if they haven't already been set). It allows -each symbol to accompany its value, and either = or == may be -used for each symbol independently. - - IRPW X,,[ - FOO==1 ;mumble - BAR==500 ;bletch - ] - IRPS Y,,[X] - IFNDEF Y,X - .ISTOP - TERMIN TERMIN - -expands into - - IRPS Y,,[ FOO==1 ] - IFNDEF Y, FOO==1 - .ISTOP - TERMIN - IRPS Y,,[ BAR==500 ] - IFNDEF Y, BAR==500 - .ISTOP - TERMIN - -which expands into - - IFNDEF FOO, FOO==1 - IFNDEF BAR, BAR==500 - -Note that the expansion is described as a two-step process only -to make it easier to understand the effects of the various IRP's. -In fact, it all goes on at once, coroutine-style. The flow of -control is approximately: read in the IRPW's arguments, -set up the first pass through the IRPW, encounter the IRPS -and read its arguments (which come out of the IRPW's body), -begin the first pass through the IRPS, perform the IFNDEF, -hit the .ISTOP which exits from the IRPS, preventing further -passes through it, try again to read from the IRPW body, reach -the end of it and then set up for the next pass through the IRPW. - -MIDAS Node: Cond, Up: Top, Previous: Loops, Next: Arithmetic - -Conditional Assembly in MIDAS - -Maybe someday this node will be INFO-ized. - -@. OVERVIEW. - -It is often desirable to decide at assembly time, rather than at -editing time, whether a particular piece of code is to be -assembled. One might wish to assemble different versions of a -program, usually based on the value of some symbol. Also, in -order for arbitrary functions to be expressed by macros, -conditionals are needed. When thinking about MIDAS conditionals, -one should always remember that MIDAS is a string-processing -language which simply happens to output the values of most -expressions evaluated into the binary file. - - -A. CONDITIONALS IN GENERAL. - - 1. SYNTAX OF CONDITIONALS. - -Every MIDAS conditional construct begins with a pseudo which -introduces the condition. This pseudo may require arguments -which are part of the condition - a given conditionalizing -pseudo always requires a particular number of arguments. After -those arguments, if any, comes the text to be conditionalized, -in a format independent of which condition was tested. - - 2. WHERE CONDITIONALS MAY BE USED. - -Because the constructs begin with pseudos, they are only -recognized as such in places where symbols' values are being -examined. Those are exactly the places in which macro calls will -be recognized. explicitly, something that looks like a -conditional but appears inside a macro definition, a text -string, a comment, a macro call, etc. will not be treated as a -conditional but as part of the macro body, text string, comment, -or macro argument, etc. Of course, if the conditional appears -inside a macro definition, when the macro is called the -conditional will be recognized unless there is something else to -stop it. The point is that in - - DEFINE FOO - IFN 0,TERMIN - -the TERMIN shown does end the definition of FOO even though it -is inside what appears to be a failing conditional, because that -conditional is not recognized at macro definition time. The -definition of FOO is "IFN 0,". When the macro FOO is called, it -will expand into a conditional, which WILL be recognized that -time. Thus, - - FOO BAR - -will not assemble the BAR because the BAR will be inside a -failing conditional. - - 3. SYNTAX OF THE CONDITIONALIZED TEXT. - -The conditional pseudo, together with arguments if any, are -usually arranged to end with a field-terminator (SPACE or -COMMA). The first character after that field-terminator is the -beginning of the conditionalized text. The extent of the -conditionalized text is determined in one of three ways, depending -on whether that first character is one of "[" and "{". - - a. one line conditionals. - -If the first character is not "[" or "{", then the -conditionalized text is the rest of the line containing the -conditional. For example, - - IFN X,FOO+BAR - -conditionalizes the string "FOO+BAR" on the value of X. It does -not matter how many "["'s or "]"'s there are in the line. There -may be other conditionals in the line, but it isn't wise to have -any multi-line bracketed ones start in the conditionalized line. - - b. bracketed conditionals. - -If the first character is "[", the conditional is called -"bracketed". In this case, the conditionalized text runs up to -the "]" that matches the "[". The opening "[" and the closing -"]" are ignored except for their function as delimiters of the -conditionalized text. Other "["'s and "]"'s in the -conditionalized text act as normal, as well as being counted to -find the end of the conditional. The conditional may span many -lines, or may be only a part of a line. For example, - - IFN X,[BAR-]FOO - -assembles either FOO or BAR-FOO depending on the value of X. -However, - - IFN X, [BAR-]FOO - -conditionalizes the string " [BAR-]FOO" because the first -character of the conditionalized text is not a "[". - -Note that though when the conditional fails, the brackets inside -the conditional are just those that are visible, since macros, -etc., are not expanded if the condition fails, if the condition -succeeds the expansion of macros may cause other brackets to -appear inside the conditionalized text. If such brackets are -unbalanced, they may cause the opening "[" of the conditional to -match a bracket other than the intended one, which may in -obscure circumstances ruin the assembly. - -If the "]" of a failing bracketed conditional is missing, the -assembly will by a complete loss. In that case, the error -message will say where the beginning of the conditional was -located. If the "]" of a successful bracketed conditional is -missing, no harm results unless a literal was in progress. -However, it means that if in another assembly the same -conditional failed (perhaps due to different parameter -settings), lossage would occur. Therefore, MIDAS prints a -message at the end of the assembly stating that there was -an unterminated successful conditional, and says where the -first one was. Fixing that one and reassembling will cause -MIDAS to find the second one, if there are any more. - -The reason that MIDAS must remember unterminated successful -bracketed conditionals is that a "]" in MIDAS may terminate -a literal or a conditional, and MIDAS has to be able to -decide which whenever a "]" is seen. This means that when -a .STOP, .ISTOP, .GO or .TAG is inside "[" - "]" pairs, -lossage can result because brackets are skipped over, -causing the "[" stack to get out of phase with the position -in the macro or loop. For this reason, bracketed conditionals -should never be used to conditionalize those four pseudos. -Braced conditionals should be used instead. - - c. braced conditionals. - -Braced conditionals look just like bracketed conditionals -except that braces ("{" and "}") are used instead of brackets. -Braced conditionals count ONLY braces when matching up - -brackets have no effect on them. - -Semantically, braced -conditionals are almost the same as bracketed conditionals -but the few differences are important in some situations. -The differences come from the fact that MIDAS does not keep -a stack of all unterminated successful braced conditionals, -whereas for bracketed conditionals it does. MIDAS can get away -without such a stack because braced conditionals cannot be -confused with literals, unlike brackets. This has two -consequences: first, MIDAS cannot warn the user about -unintentionally unterminated successful braced conditionals; -second, intentionally unterminated braced conditionals are -possible. If that boggles your mind, note that in - - IFE X,{.STOP } - -the conditional is unterminated if it is successful. -Also, because brackets do not interfere with braced -conditionals, constructions such as - - IFE X,{ASCII/ - [/} - -are possible. While overall unbalanced brackets are unwise, -it may be reasonable to have such constructions -in parts of a macro which as a whole has balanced brackets. - -There are reasonable constructions which can sometimes -result in unmatched braces/brackets, and for which therefore -only braces should be used. An example is the hack for OR'ing -two condions: - - IFN X,{IFNDEF A,} - -If the IFN succeeds but the IFNDEF fails, the "}" will not -be assembled. If brackets were used, that might cause trouble. - - 4. .SUCCESS, .ALSO, .ELSE. - -After the testing of the condition, when it has been decided -whether the conditional has succeeded or failed, the symbol -.SUCCESS is given a value automatically - 0 if the conditional -failed, and -1 if it suceeded. Also, after the "]" terminating a -bracketed conditional, .SUCCESS is again set to the same value. -The conditionals .ALSO and .ELSE test the symbol .SUCCESS's -value, and may be used to generate IF-THEN-ELSE constructs as -follows: - - IFN X,FOO - .ELSE BAR ;assembles either FOO or BAR. - - IFN X,[ FOO ] - .ELSE [ BAR ] - ;similar, but now it works even if - ;"FOO" is a macro containing conditionals - ;that clobber .SUCCESS. - - IFN X,IFN Y,FOO - .ELSE BAR - ;assembles FOO if both X and Y are nonzero. - ;assembles BAR otherwise - - IFN X,[IFN Y,[FOO]] - .ELSE BAR ;if X=1 and Y=0, assembles nothing. - - IFN X,FOO ;assembles either FOO and MUMBLE, or BAR - .ELSE BAR ;because .ELSE sets .SUCCESS. - .ELSE MUMBLE - - IFN X,FOO - .ALSO BAR ;assembles FOO and BAR, or nothing. - -B. THE CONDITIONS AVAILABLE. - -This section describes all the conditional pseudos in MIDAS and -their conditions and arguments. - - 1. ARITHMETIC CONDITIONALS. - -These conditionals all test the sign of an expression. They are: - - IFN X,FOO ;assemble FOO if X is nonzero - IFG X,FOO ;assemble FOO if X is positive - IFGE X,FOO ;assemble FOO if X is nonnegative - IFL X,FOO ;assemble FOO if X is negative - IFLE X,FOO ;assemble FOO if X is nonpositive - IFE X,FOO ;assemble FOO if X is zero - - 2. STRING CONDITIONALS. - -These take two string arguments and compare them for equality. -IFSE succeeds if the strings are equal; IFSN, if they are not. -The case of alphabetic characters is ignored, so "a" and "A" match. -The syntax of the string arguments is the same as that of normal -macro arguments except that "\" is not special as the first -character. Examples: - - IFSE FOO,BAR,[BLETCH] - ;assembles BLETCH if FOO and BAR are equal - ;strings (which obviously can't be the case - ;unless either FOO or BAR is a macro dummy - ;argument which will be replaced by something). - - IFSE FOO,[BAR][BLETCH] - ;has the same meaning, but now "[]" are used to - ;delimit the second string argument. This makes - ;it possible to win if BAR contains commas or - ;CRLF's. Note that, as with bracketed macro - ;arguments, a comma is not needed after [BAR]. - ;In fact, a comma there would be wrong: - - IFSE FOO,[BAR],[BLETCH] - ;conditionalizes the string ",[BLETCH]", because - ;the first character of the conditionalized text - ;is the comma, so the "[" in front of the - ;"BLETCH" is not recognized. - - IFSE [FOO][BAR][BLETCH] - ;this is just like the first example, but now - ;FOO and BAR may contain commas or CRLF's. - - 3. CONDITIONALS ON SYMBOL DEFINITION. - -These conditionals test whether a specified symbol is defined. -The symbol should follow the conditional name, ended by a -field-terminator, which is followed by the conditionalized text. -The pseudos are IFDEF, which succeeds if the symbol is defined, -and IFNDEF, which has the opposite sense. For example, - - IFNDEF FOO,FOO=1 - ;defines FOO to be 1 if it isn't defined - ;already. it is a good idea to define all the - ;assembly parameters of a program in this way so - ;that it is not necessary to edit the program to - ;assemble it with different settings - instead, - ;just assemble the program with the "T" switch - ;in the command string and then type the desired - ;definitions in from the TTY. - - IFNDEF FOO,.M"FOO=1 - ;if FOO isn't defined, defines it in the main - ;block (the previous example would define it in - ;the current block. - - IFNDEF XX"FOO,XX"FOO=1 - ;if FOO isn't defined in block XX, defines it to - ;be 1. - - IFDEF FOOBAR,PUSHJ P,FOOBAR - .ELSE JFCL - ;call the FOOBAR routine if the user has one. - ;this might appear in a package that is - ;.INSRT'ed by several programs. - ;The .ELSE is needed because on pass 1 it will - ;not in general be known yet whether the user - ;has a FOOBAR routine. - - 4. "BLANKNESS" CONDITIONALS. - -These conditionals take a single string argument, using macro -argument syntax (just like IFSE), and test whether it contains -any SQUOZE characters (letters, digits, and ".", "$", "%"). The -string is "blank" if it has no SQUOZE characters. The -conditionals are IFB "If Blank" and IFNB "If Not Blank". -Examples: - - IFB X,FOO - ;assembles FOO unless X contains a SQUOZE - ;character. Since "X" IS a SQUOZE character, the - ;conditional will always fail unless X is a - ;macro dummy argument. - - IFB [X]FOO - ;has the same semantics, but X may now contain - ;commas, CRLF's, etc. - - 5. SQUOZENESS CONDITIONALS. - -These conditionals are somewhat like the blankness conditionals, -but instead of testing whether any of the characters in the argument -is squoze, they test whether all of the characters are squoze. The -conditionals are IFSQ "If all SQuoze" and IFNSQ "If Not all SQuoze". -Examples: - - DEFINE FOO X - 1+< IFSQ X,[1] > - TERMIN - - FOO BAR ;assembles 2 - FOO BAR BLETCH ;assembles 1 - - 6. PASS CONDITIONALS. - -These two conditionals allow different things to be assembled on -pass 1 and pass 2. IF1 succeeds only on pass 1, and IF2 only on -pass 2. Note that the conditionalized text starts with the -character after the space or comma that ends the name of the -pseudo. One use is to avoid defining macros on pass 2: if a -macro is never to be redefined, there is no need to define it on -pass 2, because it already has the correct definition, given to -it on pass 1. Thus, - - IF1 [ DEFINE FOO - .... - TERMIN ] - -Another use might be: have a macro to make entries in the FOO -table. On pass 1, simply have the macro count up the number of -times it is called. Then, at the end of the file, allocate -enough words for the table. From then on, the address of the -table is known, so on pass 2 the macro can actually assemble -values into the words of the table. -Caution is needed when using pass conditionals, because, by -assembling more words on one pass than on the other, it is easy -to cause all the labels in the rest of the program to yield -"MDT" errors, because their addresses on pass 2 are not the same -as they were on pass 1. Also, one should avoid using any literals -on pass 2 that were not used on pass 1 (but doing the opposite -can't do worse than make the constants area waste some space). - - 7. .ELSE AND .ALSO. - -.ELSE and .ALSO exist to make a generalized IF-THEN-ELSE -construction possible. They act just like "IFE .SUCCESS" and -"IFN .SUCCESS" respectively. The conditionalized text starts -after the space or comma that terminates the pseudo itself. See -section A.4. for more details. - -MIDAS Node: Arithmetic, Up: Top, Previous: Cond, Next: FASL - -The arithmetic-statement pseudo-ops: .I and .F - B.K.P. Horn - - This is a feature of MIDAS which facilitates the rapid writing - and debugging of programs involving much nmerical calculation. - The statements used are ALGOL-like and easy to interpret. - -[ Note: This was originally written as AI Memo #179, Aug 1969, and -has been copied into this file with as much versimilitude as possible] ---------------------------------------------------------------------------- - -An arithmetic-statement expander: - -Since the Incompatible Timesharing System (ITS) does not support an ALGOL -style compiler, it is very tedious to perform even the simplest algorithms -of numerical analysis. To alleviate this problem without an inordinate -amount of effort, two pseudo-ops were added to MIDAS (the macro-assembly -language). - -The pseudo-ops are .F and .I. The first of these will have the arithmetic -in the arithmetic statement following it performed in floating point, -the latter in fixed point. - -Each statement is treated without reference to any of the others. Spaces -may apear in a statement almost everywhere and are ignored. Exceptions are -in the continue part of a continuation statement and in a subscript. (see later -on) - -Arithmetic statements are combinations of variable names, numbers, function -names and operators. Normally each statement specifies the calculation of -one or more values and where they are to be stored. - -The operators are: - = ( ) < > ^ / * + - # $ , - -A number is a character-string starting with a numberic character (0, 1 ... 9) -followed by non-operators. This number should make sense to MIDAS. The -operator ^ is permitted to appear in the number, being the separator used -in MIDAS for the exponent of a number. - -A variable (or function) name is a character-string starting with a character -which is neither numeric nor a operator and consists of up to six non- -operators. - -/ * + - have the usual meaning of divide, multiply, add and subtract. ^ is -used for exponentiation. ( and ) are used to force the precedence as usual, -ie normal evalutaion proceeds from left to right, with exponentiation -being performed first, then multiplications and divisions, and additions and -subtractions last, except that expressions in parentheses are evaluated first. -This is strictly adhered to and thus A^B^C = (A^B)^C unlike the FORTRAN -convention A**B**C = A**(B**C). Nested pairs of parentheses are evaluated from -the inside out. - -Intermediate results are kept in a stack which has to be in the accumulators -and is defined by the user. These accumulators are called A0, A1, ... A9. -If fixed point arithmetic is used, Ai must not be = Aj+1 if i surround the arguments of a function. The arguments are separated by -commas. Thus a name as defined above is a function name if it is followed by -a <. For example: - - MAX and RANDOM<> - -If used not directly following a name, < and > act exactly like ( and ). - -Functions return a single value in A0. The assembled code includes a PUSHJ P, -to the function, the user being responsible for providing a subroutine which -accepts the arguments as presented in A0, A1, etc., does not disturb any -accumulators other than those in which the arguments were passed and returns -the result in A0 before executing a POPJ P, . - -A variable name followed directly by a ( is considered to be a vector. The -subscript between the ( and the matching ) can be of the following form: - - ACxNUM - xNUM+AC where "x" is either "+" or "-". - -Where AC is the variable name of an accumulator in which the subscript is -assumed to have been loaded. NUM is a number, acting as a displacement. - -= indicates that the value available at this point (as calculated by the -portion of the arithmetic statement to he right) is to be stored as the -value of the variable name to its left. More than one = may thus appear -in one arithmetic statement. Fo example: - -.F A=B=ARM-LOSS=FOO*BARF - -This invokes the multiplication of FOO by BARF, storage of the result in LOSS. -Next LOSS is subtracted from ARM and the result stored in both A and B. More -complicated constructs are possible by making use of parentheses. Some care -is required in arranging the right sequence of storage operations so as not -to overwrite values needed further on. (perhaps a more intuitive structure -could be given to multiple equals if one did not adopt the FORTRAN like -convention of having the statement follow the equals). - -= permits the passing of arguments by name rather than value, ie it performs -a quoting action. This is particularly useful for subroutines operating on -vectors (dotproduct for example), or subroutines executed for their effect -rather than their value. It also permits the passing of a function address -as a argument. This is achieved by surrounding the variable name with [ and ]. - -$ indicates a continuation and must be directly followed by a carriage-return -and linefeed (usually supplied by TECO anyway) and either .I or .F -(which is ignored), a space or tab and the continuation of the statement. -For example: - -.F ZANSWER=273.0/T $ -.F -IN*VEST*MENT - -Unitary + and * are ignored. Unitary / and - are interpreted as 1.0/ and 0.0- -respectively. = and ^ may not appear unitarily. - -Since @ and ' may be part of a variable name, one can make full use of MIDAS's -indirect addressing and automatic variable storage assignment conventions. The -use of @ comes in very handy when working with multi-dimensional arrays -addressed through margin-arrays. - -^ normally generates a call to a function called EXPLOG, which gets two -arguments. To facilitate generation of fast inline exponentiation one may -follow the ^ directly by the single digits 1, 2, 3, or 4. For example: - -.F R=SQRT - -MIDAS Node: FASL, Up: Top, Previous: Arithmetic, Next: Blocks - -Assembling Files to be Loaded by MacLisp - - Midas can now assemble FASL files that can be loaded -by LISP in the same manner as LAP FASL output. This mode is -entered by the .FASL pseudo op, which must appear at the -beginning of the file before any storage words. - After .FASL has been seen, the assembly becomes a -two pass relocatable assembly. However, certain -restrictions and "changes of interpretation" apply. - Global symbols (declared as usual with " or .GLOBAL) -are persmissible. However, since the output is to be loaded -with FASLOAD using DDT's symbol table instead of STINK, -there are quite a few differences in detail. - For symbols defined within the current assembly, the -only effect of being declared GLOBAL is that the GLOBAL -information is passed on to FASL when the symbol table is -written at the end of pass 2. This in combination with the -SYMBOLS switch in FASLOAD determines whether the symbol gets -loaded into DDT's symbol table. If SYMBOLS is NIL, no -symbols will be loaded; if SYMBOLS is EQ to SYMBOLS, only -globals will be loaded; and if SYMBOLS is T, all symbols -(local and global) will be loaded. Once the symbol is -loaded (or not), the information as to its GLOBALness is -lost and, of course, makes no further difference. The -initial state when LISP is loaded is NIL. - GLOBAL symbols not defined in the current assembly -are also legal, but there are additional restrictions as to -where in a storage word they may appear and what masking may -be specified (as compared to a normal relocatable assembly). -Briefly, they may appear as in a storage word as a full -word, a right half, a left half, or an accumulator. They may -be negated, but can not be operated on with any other -operator. Error printouts will be produced if they appear -elsewhere. When the symbol is encountered by FASLOAD, DDT's -symbol table is consulted. If it is defined at that time, -OK, otherwise FASLOAD will generate an error. - Any sort of global parameter assignment or location -assignment is Forbidden. .LOP, .LVAL1, .LVAL2, etc are not -available. - - -New Pseudo OPs Available only in FASL assemblies. - - The following pseudos are available to facilitate -the communication between MIDAS assembled programs and LISP -(particularily with regard to list structure). - -.ENTRY function type args - - Function is an atom and is taken as the name of - a function beginning at the current location. Type - should be one of SUBR, FSUBR or LSUBR, and has the - obvious interpretation. Args is a numeric-valued field - which is passed thru to FASLOAD and used to construct - the args property of the function. If it is zero, no - args property is created. Otherwise it is considered to - be a halfword divided into two 9 bit bytes, each of - which is converted as follows: - byte result - 0 nil - 777 777 - otherwise n n-1 - These two items are then CONSed and from the - args property. - -The following pseudos may appear in constants!! - -.ATOM atom - - followed by a LISP atom in "MIDAS" format (see below). - May only appear in right half (or entire word) of a - storage word. Assembles into a pointer to the atom - header of the specified atom. - -.SPECI atom - - similar to .ATOM but assembles into a pointer to the - SPECIAL value cell of the specified atom. - -.FUNCT atom - - similar to .ATOM, but invokes special action by FASLOAD - in case the PURESW is on. Normally used in function - calls. Briefly, if FASLOAD is going to purify the - function it is loading, it must "snap the links" first. - If .FUNCT is used, the location will be examined by - FASLOAD and the link snapped if possible before - purification. - Typical usage: - CALL 2,.FUNCT EQUAL ;calls equal as a function of 2 args - ; note: the CALL is not defined - ; or treated specially by MIDAS. - -.ARRAY atom - - similar to .ATOM, but assembles into a pointer to the - Array SAR. - -.SX S-expression - - similar to .ATOM, but handles a LISP S-expression. - (See below). - -.SXEVA S-expression - - reads S expression. This S expression is EVALed (for - effect presumably) at FASLOAD time. The resulting - value is thrown away. Does not form part of storage - word. - -.SXE S-expression - - Similar to .SX but list is EVALed at FASLOAD time. The - resulting value is assembled into storage word. - - -The MIDAS "LISP READER" - - By a conspiracy between MIDAS and FASLOAD, a version -of the LISP reader is available. However, due to historical -reasons (mostly, i.e. the FASLOAD format was originally -intended only to deal with COMPLR type output), there are a -number of "glitches" (see below for list). These will -probably tend to go away in the fullness of time. - -a) numeric ATOM - - The first character of a LISP atom is examined -specially. If it is a # or &, the atom is declared to be -numeric and either fixed (#) or floating (&). Midas then -proceeds to input a normal numberic field (terminated, note, -by either space or comma). This value is then "stored" in -the appropriate "space" (fixnum space or flonum space). - -b) other ATOMs (also known as PNAME atoms or (LISP) SYMBOLS) - - If the first character of the atom is not # or &, -the atom is a "PNAME" atom. / becomes a single character -quote character as in LISP. The atom may be indefinitely -long. The atom will be terminated by an unquoted space, -carrige return, tab, (, ), or semicolon. Unquoted linefeeds -are ignored and do not become part of the atom. The -character that terminates the atom is "used up" unless it is -a ( or ). Note that period is a legal constituent of a atom -and does not terminate it or act specially. - -c) lists. - - Work normally, but note following caution relative -to dot notation: . does not terminate atoms. Thus, to -invoke dot notation, the dot must be left delimited by a -space, tab, parenthesis, or other character that does -terminate atoms. - -Glitches: - - 1) Restriction on pass dependant list - structure -- In any list reading operation, no new - atoms not previously encountered may be - encountered for the first time on pass 2. - However, this restriction does not apply to - atom-only reading operations (.ATOM, .SPECI, - .FUNCT etc). - 2) Single quote for quoting does not exist (no - other macro characters exist either.) - 3) Numbers must be flagged as above always. - MOVEI A,.ATOM 123 ;LOSES - gives pointer - ; to PNAME type atom - ; with PNAME 123. it is - ; not numeric. - use: - MOVEI A,.ATOM #123 ;WINS - 4) No provision exists to reference "GLOBALSYMS" - in FASLOAD. This mostly means only that DDT must - be present to load a MIDAS assembled FASL file. - (some simple COMPLR and LAP FASL files can - successfully be FASLOADed by, for example, a - disowned LISP running without a DDT. - 5) LOC is illegal in a FASL assembly. BLOCK of a - non-relocatable quantity is ok. - 6) Currently, symbol loading is VERY slow. Thus - use SYMBOLS nil, (the initial state) unless - symbols are necessary. - 7) Midas does not know about any LISP symbols or - UUOs specially. Use them as globals until someone - gets around to fixing up a .INSRT file with the - appropriate defs. - 8) .ATOM "should" be a special case of .SX . - However, it is handled separately because of the - following "reasons": - a) The previously noted restriction on pass - dependent LISTS. - b) Midas can do constants optimization on - atoms ppearing in constants (on both pass one - and pass two) but not on LISTS. Therefore, - each list is guaranteed to take a separate - word in the constants area even if it is - identical to some other list which also - appears in a constant. - c) Each list takes an additional entry in - FASLOAD's "atom" table. This is a temporary - table that is flushed after the FASLOADing is - complete. Of course, .SX still works for - atoms modulo the above noted restrictions and - inefficencies. - -MIDAS Node: Blocks, Up: Top, Previous: FASL, Next: Constructs - -Symbol Table Block Structure - - The MIDAS symbol table allows blocks of code to be defined within -which local definitions of symbols can be made. Local definitions are -normally visible within the blocks they belong to, including other smaller -blocks included in them, but are normally invisible outside. However, it -is possible to examine or set the local value of any symbol in any block -explicitly, whether inside the block or outside it. The intended -application of block structure is for libraries that are to be assembled -into other programs with .INSRT. Because there is a natural tendency to -use block structure in assemblers for purposes that do not merit it, any -temptation to use block structure for any other reason should be -entertained only with great self-restraint. - - A block is entered with a .BEGIN and exited with a .END. Both the -.BEGIN and the .END should be followed by the name of the block. It is -not usually wise for two blocks to have the same name, although it is legal -if the two are contained in different blocks. .BEGINs and .ENDs must -match. .BEGINs and .ENDs serve as a sort of parentheses, and impose a tree -structure on all blocks, so that each block has a direct superior and any -number of direct inferiors. Initially, even if you never use .BEGIN and -.END, there are two blocks in the structure: .INIT, which contains the -predefined MIDAS symbols, and .MAIN, which is the one which your program is -in. .MAIN is a subblock of .INIT, and any other blocks you .BEGIN are -direct or indirect inferiors of .MAIN. .END should not be confused with -END, which ends the whole assembly. Block names do not conflict with any -other kinds of names. - - A simple example of block structure will explain much: - - A=1 - A ;Value of A is now 1. - .BEGIN FOO ;Enter a block named FOO. - A ;Value of A is 1 on pass 1, but 2 on pass 2. - A=2 - A ;Value of A is now 2. - .END FOO ;Exit block FOO. Now back in main block. - A ;Value of A is now 1 again. - END - -This program will assemble four words: 1, 2, 2 and 1. This is because, on -pass 2, the local definition of A in block FOO becomes visible as soon as -the .BEGIN FOO is passed, and ceases to be visible when the .END FOO is -passed. The definition of A as 1 in the main block is always visible, -except that within FOO it is "shadowed" by a more local one. - - Whenever a symbol's value is used, the most local definition which -is visible determines the value. That is, within block FOO, where both the -local definition in FOO and the definition in the main block are visible, -the more local one (in FOO) wins out. When a symbol is defined, however, -it is always defined in the current block unless you specify otherwise. -All operations that affect the symbol's value in any way are counted as -definitions in this regard; this includes such things as .HKILL, .KILL, -EQUALS, DEFINE, :, and =. - - When you wish explicit control of shadowing, you can use .BIND. -.BIND is followed by a list of symbols, and forcibly markes them as local -to the current block, if they were not already defined locally therein. -Definitions in outer blocks are hidden by this, so that a symbol defined -outside the current block can become undefined inside it, after a .BIND, -until a definition in that block is seen. .BIND can be used to force -shadowing of some predefined symbols which it is normally an error to -shadow. - - One use of .BIND is to force forward references in a one pass -assembly to a symbol defined in an outer block which is going to be defined -locally in the current block later on. One pass assemblies and block -structure are a can of worms anyway. Normally, a symbol defined in an -outer block is NOT visible in lower blocks, unless it is a macro or pseudo, -or you mention it in a .DOWN statement. If it is a macro, and you don't -want to see it in an inner block, you must .BIND it. - - The distinctive feature of MIDAS block structure is the ability to -look at or set the definition of any symbol in any block at any time. This -makes it possible for a block to define symbols in its containing block, or -in the main block (a practice whose wisdom is currently a subject of -debate). It also allows an outer block to define and refer to symbols in -an inner block, which is the main way of communicating with .INSRTed -libraries, and is essential. - - The way to refer to a symbol in a specific block is to prefix the -symbol's name with the block name and a doublequote. Thus, FOO"BAR means -the value of BAR in block FOO. This construct can be used wherever a -symbol name can appear, in both references and definitions. If there is or -might be more than one block named FOO, it can be qualified by the name of -the containing block, as in UGH"FOO"BAR, which means the value of BAR in -that block named FOO which is directy inside a block named UGH. In -addition, there are a few special "block names": .C signifies the current -block, and .U signifies the direct superior of the current or specified -block. Thus, .U"BAR means the value of BAR in the block containing the -current one. FOO".U"BAR means the value of BAR in the direct superior of -the block FOO. .U"FOO"BAR means the value of BAR in the block FOO which is -a sibling of the current one (that is, it and the current one have the same -direct superior). - -MIDAS Node: Constructs, Up: Top, Previous: Blocks, Next: Pseudos - -MIDAS constructs, in alphabetical order: - -! is the concatenation character inside macro definitions, - IRP bodies, and .TTYMAC's. An ! next to either a dummy name - or the final TERMIN will be thrown away. For example, - inside DEFINE FOO A,B, A!!B will concatenate A's value and B's, - as will just A!B. A!!!B will leave one ! between them (the - middle ! is not adjacent to either A or B). That may be what - you want to do if you are expanding an inner macro definition - and A or B wil expand into one of that definition's dummies. - -" has four constructs: - - " - makes the global, as well as referring - to the 's value. - " - refers to the value of in the specified - block. Also, .C refers to the current block, - .M to the main block, and .U to the block containing - the current one. Multiple use of this construct is - allowed: FOO".U"BAR"BLETCH refers to BLETCH - in the block named BAR which is contained in the - block which is the father of the block FOO. - " - assembles right-justified ASCII for . - contains at least one character in any case, - and all following squoze characters. - This construct exists only if .QMTCH is zero - (as it initially is); otherwise, the next construct - exists instead: - "" - assembles right-justified ASCII for . - may contain anything; doublequotes may be - put in using the PL/1 quoting convention - ("""" gives the ASCII for a doublequote). - -# XOR operator. - - # gives the XOR of and . - # gives the complement of . - ## therefore gives "neither nor ". - -& AND operator. - -' has several constructs, syntactically distinguished. - - ' - makes a variable; like - < .SCALAR ? > - This construction is a bad one because it makes - it easy to assign a storage word without commenting - what its contents will mean. It exists for historical - reasons. - - ' - forces the use of base 8 in the number, regardless - of the current radix. - - ' - like ", but generates SIXBIT instead of ASCII. - - '' - like "", but generates SIXBIT instead of ASCII. - -(,) () has the value of with its halves - swapped, if preceded by an arithmetic operator. - Otherwise, it takes that halves-swapped value and adds it into - the current word, and is invisible to its neighbors. - For example, 1(2)+3 == 1+3(2) == 4(2), and all are the same as - 4 except that 2 is added to the left half of the current word. - -* Multiplication operator. - -+ Addition operator. - -, Field terminator. It is used for separating the fields of a word, - and also terminates the arguments to many pseudos and macros. - -- Subtraction operator, and unary negation operator. - -/ Division operator. - -: indicates a label. - - : - defined to be equal to the current value of ".", - which is equal to the location being loaded into - plus the offset (normally 0, but see .OFFSET). - There may not be any spaces before the colon. - Once a symbol has been defined as a label, it is an error - to give it a different value in any way. - :: - is similar but "half-kills" , so DDT will not - use it for type-out. - -; begins a comment, which is ended by the following carriage return. - That carriage return is not gobbled; it has its normal effect. - ";", like all other MIDAS constructs, is not recognized inside - of text strings; also, it is recognized in macro argument scanning - only in certain specific situations (see MACROS >). - -<,> in MIDAS are like parentheses in algebra. - They for a "grouping" (other groupings are made by (,) and [,]). - They are generalized to allow more than one expression to be - within them; the last one's value is the value of the grouping. - This makes it possible to do assignments, etc. before computing - the ultimate value. - -= is the assignment operator. - - = - sets 's value to 's. - If there are undefined symbols in the - assignment is not performed. - This construct is illegal where a value is needed, - but if it is the last thing in a grouping it does - supply the value of the grouping. Thus, - FOO= is legal, though FOO=BAR=1 is not. - == - is similar but half-kills - =: - is like "=" but makes it an error if ever - gets (or previously had) a different value (this is - what labels do; =:. is just like :). - ==: - makes half-killed and unredefinable. - -? separates words. ? is just as good as a carriage-return - for most purposes, the exceptions being termination of - macro arguments and conditionals (? does not terminate them). - That facilitates constructs like - IFN FOO, MOVE A,B ? JRST BAR - which conditionalizes both instructions. - -@ sets the indirect bit of the word it is in. - -[,] delimit a literal. Their value is the address of the space - MIDAS allocates to contain whatever is assembled inside them. - There may be any number of lines or words in the literal. - Example: MOVEI A,[.BYTE 7 ? ^M ? ^J] - loads A with the address of a word containing the ASCII - for carriage-return linefeed. - -\ Inclusive-or operator. - -^ has several constructs: - - ^ - has the value of the control-character associated - with . Thus, ^M is 15 . - - ^ - - multiplies by 's own radix to the - power. Thus, 1.^6 is 1 million. - 777^11 is the op-code field. - This construct works for floating point numbers as well: - 1.0^6 = 1000000.0 . - -_ left-shift operator. - NOTE: this is an arithmetical, not logical, shift! - -MIDAS Node: Pseudos, Up: Top, Previous: Constructs, Next: Outformats - -Alphabetical list of MIDAS pseudo-ops - -$. Location being loaded into. Works only via STINK. -$L. REAL LOCATION (WITHOUT OFFSET) (only in STINK format) -$O. GLOBAL OFFSET (only in STINK format) -$R. The relocation factor (only in STINK format) -. = address of current code word. In a literal, . refers - to the location of the word containing the literal, not the - word in the literal. - The offset is included in the value of .. -.1STWD put before a text-generating pseudo (SIXBIT, ASCII, - ASCIZ, ASCIC, .ASCII) to throw away all but the first - word of text. -.ABSP , - returns the "absolute part" of . -.ALSO conditional: "If the previous conditional succeeded". - (See *Note Cond: Cond, for conditional info) -.AOP is like .OP, but returns no value. However, all the - information is still available in .AVAL1 and .AVAL2. -.ARRAY reference a lisp array (.FASL feature) -.ASCII /text/ - Like ASCIZ, but when the character "!" is encountered in the - text, the following it is evaluated and the value - inserted into the assembled string as a sequence of digits in - the current radix, replacing the "!" and the expression. - Terminate with a space or comma, which unfortunately will become - part of the assembled string. -.ASCVL / - (Yes, only one "/") returns the ascii value of . -.ASKIP -1 if instruction executed by most recent .OP or .AOP - skipped; 0 if it didn't skip. -.ATOM - refer to header of named LISP atom (see *Note Fasl: Fasl.) -.AUXIL does nothing - it exists for the sake of the listing program "@". -.AVAL1 What was left in the ac by the instruction executed by - the most recent .OP or .AOP -.AVAL2 What was left in the memory location by the .OP or .AOP. -.BEGIN - begin a symbol-scope block. defaults to - most recent label. -.BIND ,... - Create bindings for these symbols in the current block. - Must be used when it is desired to shadow a built-in - symbol under certain circumstances. Also sometimes needed - in 1-pass assemblies when symbol is defined in higher block - and will be defined later in current block, to force a - forward reference to be made. -.BM , - returns a mask to the byte pointed to by the specified - byte pointer (address field ignored). If arg's LH is 0, - the arg will be swapped first to get a byte pointer. - The comma is thrown away except for ending the arg. -.BP , - returns a byte pointer to the byte which the argument is - a mask to. The address field of the value is 0. The comma - which terminates the argument is not flushed, so that - .BP , will produce a byte pointer to in - location . For those who understand .FORMAT, that - contrives to use the format field-space-field rather than - the problematic field-comma-field format, which many users - like to redefine. -.BYTC The number of bytes assembled since .BYTE mode was entered. -.BYTE N assemble N bit bytes. That is, take the assembled "words" - and pack them into N-bit bytes to get what is really output. - When another byte won't fit in the current word, the word is - output and a new one is started. -.BYTE M,N,O,P,... - assemble an M bit byte, then an N bit one, then an O bit one, etc., - returning to an M bit one after using the last of the specified sizes. - If a negative "byte size" is specified, it causes a block of zero bits - to be assembled right after the previous byte; the number of zero bits - is the abs. value of the specified number. This can cause an extra - zero word to be assembled if .byte mode is left right away. - In byte mode, "." is a byte pointer which could be ILDB'd to get - the next byte. -.BYTE with no arg leaves byte mode, returning to the initial state. -.C Current block (as in .C"FOO). -.CRFIL -.CRFOFF CREF off -.CRFON CREF on -.CURLN current line number minus 1 -.CURPG current page number minus 1 -.DECREL selects DEC relocatable output format -.DECSAV selects DEC/TNX SAV output format. Symbols are deposited - where the location counter points when END is reached, - and location 116 (.JBSYM) given a pointer to them. - Location 120 (.JBSA) is given the start address unless - the instruction furnished to the END pseudo has something - in the LH, in which case it is treated as an entry vector pointer - (only meaningful on TNX systems). -.DECTW - Two-segment DEC relocatable output format. - Arg is address of bottom of high segment (normally 400000). -.DECTXT /text/ - Like .TEXT in MACRO. .DECREL format only, outputs an ASCIZ REL - block consisting of the given text, which LINK interprets as a - command string. -.DOWN ,... - Causes the symbols to be visible in subblocks in 1PASS mode. - In 2-pass assemblies, symbols are always visible in subblocks - of the blocks they are defined in. In 1PASS mode, they are - usually not (except for macros), in case the same name is - defined later on in the subblock itself. -.DPB ,,, - deposits into the byte in specified by , - and returns the result. Thus, .DPB 0,30300,-1, returns -1,,777707 -.ELDC End a load-time conditional - STINK format only. - Any storage words appearing between a load-time conditional (e.g. - .LIFS, .LIFE, etc) and its matching .ELDC are passed on to the - loader, which will load them only if the conditional is true at - the time it is encountered during loading. .ELDC should always - be followed by a location assignment (eg LOC pseudo). Sometimes - if there is a series of load-time conditionals with no intervening - non-conditional words the LOC need only be used after the last. - Notice that LOC $." may be used to continue loading storage words - into subsequent locations where the effect of the load-time conditional - is not necessarily known. Load-time conditionals may be nested. -.ELSE conditional: "If the previous conditional failed". (*Note Cond:Cond.) -.END - terminate symbol-scope block, if its name is . Error - if the current block's name isn't . -.ENTRY .FASL feature - declare a LISP entry point (SUBR beginning, etc). -.ERR - Causes an error with error message -.ERRCNT Number of errors seen in entire assembly thus far. -.F floating mode Fortran arithmetic statement. - *Note .F: Arithmetic, for details. -.FASL Selects FASL output format, loadable by MACLISP. -.FATAL - Causes a fatal error with as the error code. - The output buffers are written out and the output files - are closed, though only the error output file is renamed. -.FNAM1 numeric value of sixbit for first file name of main input file. -.FNAM2 numeric value of sixbit for second file name of main input file. -.FORMAT fno,fval Specify interpretation of fields in a word. - See description in *Note Forma: Words. -.FUNCT - refers to the specified function, in FASL format. *Note Fasl: Fasl -.FVERS version number of main input file. -.GLOBAL ,... - Makes the specified symbols global. -.GO - assembly continues at .TAG tag (within macro body) - Non-local .GO's outward are allowed. -.GSCNT The value of the generated symbol counter - may be read or set. -.GSSET - same as .GSCNT= -.HKALL If nonzero, causes ":" to be treated as "::". -.HKILL ,... - Half-kills the specified symbols. Does not define them. - Acts only on the last pass. - Does shadow definitions in outer blocks, like .BIND. -.I integer mode Fortran arithmetic statement - *Note .I: Arithmetic, for details. -.IBP - returns incremented a la IBP instruction. -.IFNM1 numeric value of sixbit for first file name of insert file - (the file most recently .INSRT'ed by the current input file, - or the current file's name if it hasn't .INSRT'ed any others yet). -.IFNM2 numeric value of sixbit for second file name of insert file -.IFVRS version number of insert file. -.INEOF In an .INSRT file, acts just like EOF. -.INIT The outermost block (as in .INIT"MOVE). All the predefined - symbols are defined in this block. Symbol definitions in this - block are not output to the binary file. -.INSRT - Pushes the current input file and begins reading from the - specified file. After the end of that file, reading from - the inserting file will resume. If the sname of the file to - be inserted is not specified, that of the file being read - will be used. If the file is not found, the user will be - asked to respecify the names. .INSRT'ing the TTY is a - good way to let the user make arbitrary redefinitions at - some point in the assembly. -.IRPCNT # of completed iterations of innermost indefinite repeat -.ISTOP stop REPEAT or IRP - see *Note loops: Loops -.KILL ,... - The specified symbols will not go in the symbol table. -.LDB ,, - returns as a value the contents of the byte in - specified by . may be either a byte pointer - or the left half of one, as in .BM. -.LENGTH /text/ - returns the number of characters in the specified string. -.LIBRA namelist (linking loader pseudo - STINK format only) - This must occur before any storage words. It tells the loader - that the program to follow is a "library program". The entries - in the namelist, separated by commas, are either (a) names, or - (b) groups of names separated by space, +, and -. An entry is - said to be "satisfied" by a list of symbols if either (a) the entry - is a name and that name appears in the list of symbols; or (b) the - entry is a group of names, ALL of which names preceded by space or - + are in the lst of symbols, and NONE of which names preceded by - = are. STINK will omit to load a library program unless one or - more entries in its namelist are satisfied by the list of - undefined global symbols used in programs already loaded. -.LIBRQ nam1,nam2,... (linking loader pseudo - STINK format only) - This will output the given names to STINK such that the loader - "sees" them in this program when queried by load-time conditionals. - No definition is given to the loader, and a use of .LIBRQ does not - cause the names to be seen at all by the assembler. -.LIFE word Load if word = 0. (Load-time conditional, see .ELDC) -.LIFG word Load if word > 0. (Load-time conditional, see .ELDC) -.LIFGE word Load if word >= 0. (Load-time conditional, see .ELDC) -.LIFL word Load if word < 0. (Load-time conditional, see .ELDC) -.LIFLE word Load if word =< 0. (Load-time conditional, see .ELDC) -.LIFN word Load if word not 0. (Load-time conditional, see .ELDC) -.LIFS namelist Load If Seen. (Load-time conditional, see .ELDC) - This conditional is true only if one or more entries in the namelist - are satisfied by the list of defined AND undefined global symbols - used in programs already loaded. See .LIBRA for an explanation of - the namelist. -.LITSW if nonzero, using a literal causes an error message. -.LNKOT (linking loader pseudo - STINK format only) - If output is relocatable (STINK) format, causes immediate output - of all accumulated linking pointers. -.LOP ,, - like .OP, but the instruction is executed in STINK rather - than in MIDAS. Has no value in MIDAS. The loader sets the value - of the global symbols .LVAL1 and .LVAL2 to the resulting contents - of AC and memory respectively. (Initially .LVAL1 and .LVAL2 have - value 0). -.LSTOF listing off -.LSTON listing on -.LVAL1 .LOP value left in accumulator. -.LVAL2 .LOP value in memory location. -.LZ , - the number of leading zeros in the value of . - The comma serves only to terminate . -.M Main block (as in .M"FOO) -.MLLIT set positive to allow multi-line [], (), and <>. - Set negative for the old-fashioned mode where they didn't - need to be terminated. Zero selects "error mode" useful - in converting an old-fashioned program to multi-line mode. - Now initially positive. -.MRUNT MIDAS's runtime so far, in milliseconds. -.NSTGW sets .STGSW to cause error message if any storage words are assembled. -.NTHWD , - returns the 'th word of the text string. - Thus, .NTHWD 1, is equivalent to .1STWD. By - is meant an invocation of ASCIZ, ASCII, ASCIC, .ASCII or SIXBIT. -.OFNM1 = SIXBIT// -.OFNM2 = SIXBIT// -.OP ,, - executes on an AC containing and a memory - location containing , and returns what this leaves - in the AC. Thus, <.OP SUB,5,2> equals 3. This value is also - made the value of .AVAL1, while .AVAL2 contains what was left - in the memory location: .OP SUBM,5,2 sets .AVAL2 to 3, and - returns 5. .ASKIP will be nonzero if the instruction skipped. - If an instruction is supplied with a nonzero AC field, that - AC field will be used unchanged, and the number of the AC - used for the argument and value will not be substituted. - Similarly, if the address field or index field in is - nonzero, the address of .AVAL2 will not be substituted. - This is useful for immediate instructions, including such - ITS UUOs as .RDATE which equals .OPER 46: ASDATE=.OP .RDATE - sets ASDATE to today's date in SIXBIT. - Note that is read in as a field, and thus cannot contain - any spaces or commas (unless they are inside brackets). -.OSMIDAS - is the sixbit name of the operating system MIDAS is running - under. It is SIXBIT of ITS, TENEX, SAIL, CMU or DEC. - Twenex is considered the same as Tenex. - Programs that have versions for more than one operating - system should by default assemble to run on the one - in .OSMIDAS, but they should make it possible to override - that default with the use of the T switch: - IFNDEF RUNOS, RUNOS==.OSMIDAS - DEFINE IFITS - IFE RUNOS-SIXBIT/ITS/TERMIN -.PASS is 1 or 2, depending on which pass MIDAS is in. -.PPASS is 1 in a 1-pass assembly; 2, in a 2-pass assembly. -.QMTCH if set nonzero, causes ' and " text constants to use the newer - fail-style syntax. -.QUOTE /text/ inhibit checking for TERMIN and macro dummies. -.RADIX ,, - evaluates , using as the radix. -.RELP , - returns 's relocation. Always 0 in an absolute - assembly. - For any X, X = .ABSP X,+.RL1*.RELP X, -.RL1 in a relocatable assembly, returns a relocatable 0. - In an absolute assembly, returns 0. - .ABSP .RL1 is always 0. .RELP RL1 is 0 iff the assembly is - absolute. -.RPCNT = # iterations of REPEAT completed -.RSQZ , - generates right-justified SQUOZE such as the DEC system likes. -.SBLK Specifies ITS SBLK output format. Same as SBLK but doesn't type - warning message. For details on format, see ITSDOC;BINFMT > - and the "Symbol table format" section of .INFO.;DDTORD >. -.SCALAR (),,... - makes the symbols "variables", like the ' construct, - causing them to have storage words allocated for them later - (at the time of the next VARIAB or END). An optional - may be specified in parentheses after a symbol, reserving that - many words for it rather than the default of just one. - See also .VECTOR, which is identical except for the way sizes default. -.SEE ,... - Has no effect except to make cref entries for the specified symbols. -.SITE - returns word (origin 0) of a SIXBIT string that says - the name of the machine MIDAS is running on. If is - out of range 0 is returned. The format of the string is - operating system dependent; on I.T.S. .SITE 0, will return - the standard I.T.S. "machine name" which is SIXBIT of - "AI", "ML", "DM", or "MC". - Programs with different versions for different sites should - by default assemble to run on the one specified by .SITE, - but they should make it possible to override that default - using the T switch: - IFNDEF RUNSITE,RUNSITE==.SITE 0, - then later on - IFE RUNSITE-SIXBIT/ML/,... -.SLDR selects SBLK output format, but outputs a loader in front - of the file. -.SPECI .FASL special variable reference. -.STGSW set nonzero => it is illegal to generate storage words. - .NSTGW and .YSTGW act by setting this flag. -.STOP stop current iteration of REPEAT or IRP, go on to next. -.STPLN Set to line # to break assembly at (see below) -.STPPG Set to page # to break assembly at. By setting .STPLN and .STPPG - you can break assembly (i.e. .INSRT the TTY) at an arbitrary point. -.SUCCESS - flag, used to make .ELSE and .ALSO work. -.SX .FASL quoted S-expression reference. -.SXE .FASL S-expression load time evaluated and value assembled in. -.SXEVA .FASL S-expression load time evaluated and value thrown away. -.SYMCNT returns the number of symbol table entries in use. This is the - number of user-defined symbols plus the number of initial symbols - (not counting symbols that have been expunged). It is useful for - determining what argument to give to .SYMTAB (below); -.SYMTAB , - makes sure the symbol table can hold symbols - and the literal table can hold words of literal. - If either table actually needs to be enlarged, both are - re-initialized, so that all user symbol definitions are lost. - For this reason, a .SYMTAB should come at the beginning of the - program. If both tables are already big enough (for example, - when the same .SYMTAB is seen on pass 2), .SYMTAB is a no-op. - The normal version of MIDAS starts out with space for 2700. - symbols, and has about 1200. initial symbols, so only - programs using more than 1500. symbols need a .SYMTAB. - To decide what symtab you need, try a very large value (10000.). - The number of symbols including initial symbols, printed at - the end of the assembly, is the minimum value you can use; - for best results choose an arg at least 20% larger. - The literal table size you need is usually the size of the largest - constants area; this can be computed from the constants - area addresses printed at the end of the assembly. - Sometimes, that size may cause a "Constants Global Table Full" - error, and a larger size must be used. -.TAG see .GO -.TTYFLG if greater than zero, TTY typeout is inhibited - (but not output to error output file if any). -.TTYMAC allows the program to read a few arguments from the TTY at - assembly time, and refer to them as dummy arguments. - .TTYMAC is used the way DEFINE is used (see *Note macros: Macros.) - but without a macro name; the macro definition is read in and - then immediately evaluated, with arguments read in from the TTY. - Try .TTYMAC FOO - BAR=FOO TERMIN -.TYO , - Like TYO n MACLISP; prints on the TTY the character whose ASCII - code is . Thus, .TYO 61 prints a "1". -.TYO6 , - Prints the word, regarded as a sixbit. - Try .TYO6 .FNAM1,.TYO 40,.TYO6 .FNAM2,PRINTX/ - / -.TYPE , Find definition status of symbol. - Value is one of the following: - -1 is really a number - 0 common - 1 pseudo or macro - 17 not seen (except in this .TYPE) - 12-16 either impossible or not documented yet. - - Defined/Undefined - 2 3 Local symbol (not global, not a var) - 4 5 Local variable - 6 7 Global variable - 10 11 Global symbol (not a var) -.TZ , - is the number of trailing zeros in the value of . -.U containing block (as in .U"FOO) -.VECTOR (), (),... - Makes be the name of a vector words long. - The space is actually allocated by the next VARIAB, or by - the END statement. Like .SCALAR, more than one vector can - be specified at a time. If no size is specified, or size is zero, - the default size is used (initially 1, always set to last size used). - e.g. in ".VECTOR FOO(3),BAR" the vector BAR will have size 3. - This defaulting scheme is the only difference from .SCALAR. -.WALGN word-align; in byte mode, move up to a word boundary. -.XCREF ,... - Suppress creffing of the specified symbols. -.YSTGW OK to generate storage words -1PASS one pass assembly. Implies RELOCA -ASCIC /text/ like ASCIZ but fill with ^C. -ASCII /text/ generate ascii character string. -ASCIZ /text/ ascii character string, 0 byte at end. -BLOCK - reserve words - increment "." by . -COMMEN /text/ - ignores the text. -CONSTA dump out literals seen so far. -DEFINE define a macro. See *Note macros: Macros -END - terminates tha assembly, and sets the program starting address - to the argument (which is optional). -EQUALS , - sym1 gets same meaning as sym2. -EXPUNGE ,... - forgets the definitions of the specified symbols. The symbols are - actually deleted from the symbol table altogether. -IF1 ifbody Assemble if pass 1. -IF2 ifbody Assemble if pass 2. -IFB string,ifbody Assemble if string blank (has no squoze chars). -IFDEF sym, ifbody Assemble if sym defined. -IFE exp, ifbody Assemble if = 0. -IFG exp, ifbody Assemble if > 0. -IFGE exp, ifbody Assemble if >= 0. -IFL exp, ifbody Assemble if < 0. -IFLE exp, ifbody Assemble if <= 0. -IFN exp, ifbody Assemble if ^= 0. -IFNB string, ifbody Assemble if string not blank. -IFNDEF sym, ifbody Assemble if sym not defined. -IFNSQ string, ifbody Assemble if string is not all squoze chars. -IFSE string,string,ifbody Assemble if strings equal. -IFSN string,string,ifbody Assemble if strings not equal. -IFSQ string, ifbody Assemble if string is all squoze chars. -IRP indefinite repeat (like macro args sort of). See *Note loops: Loops -IRPC indefinite repeat (characters). -IRPNC indefinite repeat (groups of characters). -IRPS indefinite repeat (symbols). -IRPW indefinite repeat (words - i.e. code lines). -LOC - set value of "." to . -NOSYMS don't put symbols in output. -NULL ifbody - This a "conditional" that always fails. -OFFSET - offset . and labels by specified amt (code to be moved before run). -PRINTC /text/ type out the text. -PRINTX /text/ Same as PRINTC, but ignores any "!" chars in the text. -RADIX - set number radix to . -RELOCA relocatable assembly. -REPEAT ,[] repeat times. See *Note loops: Loops -RIM Readin mode output format. This is what the PDP-6 used. - A series of 2-wd pairs (DATAI PTR,loc ? val); last pair is a - transfer block with 1st wd an instruction taken from END stmt - and executed when transfer block is read. 2nd wd is a dummy. -RIM10 Readin mode output format, for KA-10 hardware bootstrap readin. - RIM10 format is a single block where the 1st word is IOWD n,,loc and - n = # words in rest of block, loc = location to load these words at. - Last loaded word is executed after readin is complete, so it should be - a JRST somewhere. MIDAS makes it unnecessary to do anything about - this as its strategy for RIM10 is to first output a - RIM10-format SBLK loader, followed by the code in normal SBLK format, - except that no symbols are provided. -SBLK Simple Block loader output format (this is the default). - Starts with a SBLK loader in RIM (not RIM10) format, followed by - code in SBLK format. -SIXBIT /text/ generate sixbit character string. -SQUOZE , - value is a word containing the squoze-code for - with /4 put in the top 4 bits. -SUBTTL - ignores the line. This pseudo is for @'s sake. -TERMIN terminate macro body or indefinite repeat. -TITLE - specify name of program as (relocatable only). - Types and on the TTY. - It is at the TITLE that TTY will be .INSRT'ed by - the (T) switch. -VARIAB leave space for, and define, the "variables" seen so far. - "Variables" are symbols not defined and seen with singlequotes - and symbols seen in .SCALAR and .VECTOR pseudos. -WORD - outputs the argument directly to the binary file. - Allows writing of nonstandard binary formats. -XWD , - returns a word with the specified halfwords. - -MIDAS Node: Outformats, Up: Top, Previous: Pseudos, Next: Changes - -This node documents some obscure details of assembler output formats. -Much of the wording is taken from old DEC manuals. - ------------------ RIM ----------------- - - This format is (was) primarily used in PDP-6 systems and -consists of a series of paired words. The first word of each pair is -a paper-tape read instruction giving the memory address of the second -word. E.g. - DATAI PTR, - -The last pair of words is a transfer block; the first is an -instruction obtained from the END statement and executed when the -transfer block is read, and the second is a dummy word to stop the reader. - -The loader that reads this format is normally toggled into memory and -started at location 20: - LOC 20 - CONO PTR,60 - A: CONSO PTR,10 - JRST .-1 - DATAI PTR,B - CONSO PTR,10 - JRST .-1 - B: 0 - JRST A - ------------------ RIM10 ----------------- - - The PDP-10 has a hardware readin mode which can read in one -block of data. Programs which can be loaded using this readin mode -are said to use RIM10 format. The format of this block is: - -n,,loc-1 ; equiv to IOWD n,,loc - ; the last data word is executed after readin. - -In MIDAS, "RIM10" causes the output binary to start with a RIM10-format -SBLK loader provided by MIDAS. The assembled code then follows in SBLK -format. Only data blocks and the final transfer block are output (no -symbol blocks or anything else). This is very similar to MACRO's "RIM10B" -(see below). The RIM10 loader code can be found at label LDR10 in MIDAS. - -In MACRO, "RIM10" causes the assembled code to be output exactly as it -is produced; i.e. the first data word is the first output word. No -blocking, checksumming, or anything else is done; in particular, no -loader is furnished by MACRO. This functionality can be achieved in -MIDAS by means of the WORD pseudo-op, which writes an arbitrary word -to the output file. - ------------------ RIM10B ----------------- - - This is a MACRO format, not MIDAS, but is documented here anyway. -It is very similar to what MIDAS produces for "RIM10". That is, MACRO will -first output a loader in RIM10 format, followed by the assembled code in a -"simple-block" format. This simple-block format is identical to DECSAV -except that there is a checksum word following each block. In this respect -it is similar to SBLK, however it also differs in the way the checksum is -computed; RIM10B just adds words, whereas SBLK rotates the checksum 1 bit -before each add. - -The following is the loader inserted by MACRO for RIM10B: - R1BLDR: - PHASE 0 - IOWD $ADR,$ST - $ST: CONO PTR,60 - HRRI $A,$RD+1 - $RD: CONSO PTR,10 - JRST .-1 - DATAI PTR,@$TBL1-$RD+1($A) - XCT $TBL1-$RD+1($A) - XCT $TBL2-$RD+1($A) - $A: SOJA $A, - $TBL1: CAME $CKSM,$ADR - ADD $CKSM,1($ADR) - SKIPL $CKSM,$ADR - $TBL2: JRST 4,$ST - AOBJN $ADR,$RD - $ADR: JRST $ST+1 - $CKSM: - DEPHASE - ------------------ SBLK ----------------- - - When SBLK format is selected, MIDAS will (presumably for historical -reasons) first output a SBLK loader in RIM (not RIM10!) format, followed by -the assembled code in SBLK format. The latter consists of data blocks, a -transfer block, symbol table blocks, and any extra blocks. - SBLK is to ITS what DECSAV is to DEC systems. - SBLK format is documented in ITSDOC;BINFMT >, and the format of the -SBLK file symbol table in .INFO.;DDTORD >. The RIM loader code can -be found at label SLOAD in MIDAS. - ------------------ DECSAV ----------------- - - DECSAV is a simple absolute format which can be used for -immediately executable programs on TOPS-10, TENEX, and TOPS-20. -It consists only of data blocks followed by a 2 word transfer block. -Each data block has the format: - IOWD n,,loc - -The transfer block is: - JRST start-address ; This word is specified by END - JRST reenter-address ; MIDAS always leaves this 0 - ------------------ DECREL ----------------- - - This format produces DEC relocatable format (.REL) files -which the DEC linking loader (LINK) can then use to put a program -together. It is not necessary to use this unless you need to load -in some already assembled modules or use other loader features; if the -MIDAS program is self-contained it is easier to use DECSAV format. - DEC relocatable format is documented in the DEC LINK Reference -Manual (TOPS-20 version is AD-4183C-T1). - ------------------ STINK ----------------- - - The MIDAS "RELOCA" pseudo generates ITS relocatable format, -also known as STINK format because STINK is the name of the ITS linking -loader. This format is not well documented anywhere, which is partly -why very few people use STINK or RELOCA any more, especially when MIDAS -is fast enough that it is much easier and simpler to always produce -self-contained absolute assemblies. (Library routines are shared by -using .INSRT) - -MIDAS Node: Changes, Up: Top, Previous: Outformats, Next: (MIDAS ARCHIV)* - -Changes are catalogued in an uninfo-ized file. Do "L" to get back here. - -* Menu: - -* Changes: (MIDAS ARCHIV)* MIDAS changes in chronological order. - - - -Local Modes: -Fill Column:75 -Page Delimiter:  -End: